;Software License Agreement (BSD License)
;
;Copyright (c) 1997-2008, David Lindauer, (LADSoft).
;All rights reserved.
;
;Redistribution and use of this software in source and binary forms, with or without modification, are
;permitted provided that the following conditions are met:
;
;* Redistributions of source code must retain the above
;  copyright notice, this list of conditions and the
;  following disclaimer.
;
;* Redistributions in binary form must reproduce the above
;  copyright notice, this list of conditions and the
;  following disclaimer in the documentation and/or other
;  materials provided with the distribution.
;
;* Neither the name of LADSoft nor the names of its
;  contributors may be used to endorse or promote products
;  derived from this software without specific prior
;  written permission of LADSoft.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
;WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
;PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
;ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
;LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
;TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
;ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        ;MASM MODE
	.386
	.model use32 small

include  prints.ase 
include  mtrap.ase 
include  input.ase 
include  dis.ase 
include  fp.ase
include  mmx.ase
	PUBLIC	DisplayRegisters, ModifyRegisters, ReadReg, ReadRegValue
	
	.code
;
; This is a list corresponding ASCII names for general purpose regs
; with the address the value can be found at;
;

peax	dd	offset DGROUP:dreax
	db	13,10,"eax:",0
pebx	dd	offset DGROUP:drebx
	db	"ebx:",0
pecx	dd	offset DGROUP:drecx
	db	"ecx:",0
pedx	dd	offset DGROUP:dredx
	db	"edx:",0
pesi	dd	offset DGROUP:dresi
	db	"esi:",0
pedi	dd	offset DGROUP:dredi
	db	"edi:",0
pebp	dd	offset DGROUP:drebp
	db	13,10,"ebp:",0
pesp	dd	offset DGROUP:dresp
	db	"esp:",0
peip	dd	offset DGROUP:dreip
	db	"eip:",0
	dd	0
;
; a list of 8-bit register names
;
pal	dd	offset DGROUP:dreax
	db	13,10,"al:",0
	dd	offset DGROUP:dreax+1
	db	"ah:",0
	dd	offset DGROUP:drebx
	db	"bl:",0
	dd	offset DGROUP:drebx+1
	db	"bh:",0
	dd	offset DGROUP:drecx
	db	"cl:",0
	dd	offset DGROUP:drecx+1
	db	"ch:",0
	dd	offset DGROUP:dredx
	db	13,10,"dl:",0
	dd	offset DGROUP:dredx+1
	db	"dh:",0
	dd	0
;
; a list of 16-bit register names
;
pax	dd	offset DGROUP:dreax
	db	13,10,"ax:",0
	dd	offset DGROUP:drebx
	db	"bx:",0
	dd	offset DGROUP:drecx
	db	"cx:",0
	dd	offset DGROUP:dredx
	db	"dx:",0
	dd	offset DGROUP:dresi
	db	"si:",0
	dd	offset DGROUP:dredi
	db	"di:",0
	dd	offset DGROUP:drebp
	db	13,10,"bp:",0
	dd	offset DGROUP:dresp
	db	"sp:",0
	dd	offset DGROUP:dreip
	db	"ip:",0
	dd	0
peflags	dd	offset DGROUP:reflags
	db	"eflags:",0
	dd	0
flm	label byte
	db	11
	dd	"NVOV"
	db	10
	dd	"UPDN"
	db	9
	dd	"DIEI"
	db	7
	dd	"PLMI"
	db	6
	dd	"NZZR"
	db	4
	dd	"NAAC"
	db	2
	dd	"POPE"
	db	0
	dd	"NCCY"
	db	-1
	db	0
;
; Print a general purpose reg and it's value
;
PutDword	PROC	
	lods	dword ptr [esi]; Get pointer to val
	push	dword ptr [eax]
	mov	ebx,esi		; Get text pointer
	call	olMessage
	pop	eax		;
	call	PrintDword	; Print value
	call	PrintSpace	;
	ret
PutDword	ENDP	
;
; Print a segment reg and its value
;
PutWord	PROC	
	lods	dword ptr [esi]; Get pointer to value
	push	dword ptr [eax]
	mov	ebx,esi		; Pointer to text
	call	olMessage
	pop	eax		;
	call	PrintWord	; Print value
	call	PrintSpace	;
	ret
PutWord	ENDP	
;
; Print either the GP regs or the SEG regs
;

PrintAFew	PROC	
	call	edx		; Call the print routine
pf_lp:
	lods	byte ptr [esi]; Wade past the text
	or	al,al		;
	jnz	pf_lp		;
	test	dWORD PTR [esi],-1 ; See if trailer found
	jnz	PrintAFew	; Go print another
	ret
PrintAFew	ENDP	
;
; try to find a match for a register spec
;
skimreg PROC
	push	edi
	push	esi
	xchg	esi,edi
	add	esi,4
srlp:
	cmp	byte ptr [esi],32
	jnc	oktry
	inc	esi
	jmp	srlp
oktry:
	cmp	byte ptr [esi],':'
	jz	match
	cmps	byte ptr [esi],es:[edi]
	jz	oktry
	pop	edi
	add	sp,4
srlp2:
	lods	byte ptr [esi]
	or	al,al
	jnz	srlp2
	test 	word ptr [esi],0ffffh
	xchg	esi,edi
	jnz	skimreg
	sub	al,al
	inc	al
	ret
match:
	add	esp,4
	sub	eax,eax	
	xchg	esi,edi
	pop	edi
	mov	edi,[edi]
	stc
	ret
skimreg ENDP
;
; search all the name tables for a match
;
FindRegister	PROC
	mov	edi,offset _TEXT: peax
	call	skimreg
	mov	cl,4
	jc	frnoseg
	mov	edi,offset _TEXT: pal
	call	skimreg
	mov	cl,1
	jc	frnoseg
	mov	edi,offset _TEXT: peflags
	call	skimreg
	mov	cl,4
	jc	frnoseg
	mov	bl,[esi+1]
	mov	edi,offset _TEXT: pax
	call	skimreg
	mov	cl,2
	jnc	frnotfound
	cmp	bl,'s'
	stc
	jnz	frnoseg
	clc
frnoseg:
	mov	al,0ffH
	inc	al
	ret
frnotfound:
	sub	eax,eax
	inc	eax
	stc
	ret
FindRegister	ENDP
;
; read the value of a reg (used by input routines)
;
ReadReg		PROC
	push	ecx
	call	FindRegister
	jnz	notreg
	pushfd
	mov	eax,[edi]
	cmp	cl,4
	jz	rr_exit
	movzx	eax,ax
	cmp	cl,2
	jz	rr_exit
	movzx	eax,al
rr_exit:
	popfd
notreg:
	pop	ecx
	ret
ReadReg	ENDP
;
; Read value for a register back into memory (R) command
;
ReadRegValue	PROC
	call	WadeSpace
	jz	doregprompt
	inc	esi
	cmp	al,':'
	jz	ReadRegValue
	cmp	al,'='
	jz	ReadRegValue
	dec	esi
	call	ReadNumber
	ret
doregprompt:
	push	ebx			; Else put up prompt
	push	ecx			;
	Msg	<13,10,": ">
	call	GetInputLine		; Get input line
	pop	ecx			;
	pop	ebx			;
	call	WadeSpace		; Ignore spaces
	jz	short rr_out		; Quit if so
	call	ReadNumber
	ret
rr_out:
	stc
	ret
ReadRegValue	ENDP	
;
; DisplayFlags command
;
EditFlags PROC
        sub     edx,edx
        inc     esi                      ; past the 'f'
        call    WadeSpace
        jnz     readflags
		call	crlf
        call    putflags
		call	Message
		db	"- ", 0
	call	GetInputLine		; Get input line
        mov     edx,1
readflags:
        call    WadeSpace
        jz      efx
        cmp     al,','
        jz      efskipcomma
        mov     ax,[esi]
        xchg    al,ah
        and     ax,0DFDFh               ; make upper case
        mov     bx,ax
        push    esi
        mov     esi,offset flm
efl:
        lods    byte ptr [esi]
        test    al,al
        jns     efc
        pop     esi
        add     esi,2    ; bump for no prompt mode
        test    edx,1
        jz      efnoadd
        add     esi,24   ; remainder of bump for prompt mode
efnoadd:
        stc
        ret
efc:
        movzx   ecx,al
        lods    dword ptr [esi]
        cmp     ax,bx
        jnz     nosetmatch
        bts     [reflags],ecx
        jmp     short effin
nosetmatch:
        shr     eax,16
        cmp     ax,bx
        jnz     efl
        btr     [reflags],ecx
effin:
        pop     esi
        inc     esi
efskipcomma:
        inc     esi
        jmp     readflags

efx:
        clc
        ret
        
EditFlags ENDP
;
; main 'Reg' command
;
ModifyRegisters	PROC	
	mov		al,[esi]
	cmp		al,'n'
	jz		fpcommand
	cmp		al,'m'
	jz		ModifyMMXRegisters
        cmp     al,'f'
        jnz     nEditFlags
        cmp     byte ptr [si+1],'s'
        jnz     EditFlags
nEditFlags:		
	call	WadeSpace		; Wade through spaces
	jz	DisplayRegisters	; Display regs
	call	FindRegister
	jnz	badreg
	push	edi
	call	ReadRegValue
	pop	edi
	jc	badreg2
	cmp	cl,4
	jnz	wordreg
	mov	[edi],eax
	clc
	ret
wordreg:
	cmp	cl,2
	jnz	bytereg
	mov	[edi],ax
badreg2:
	clc
	ret
badreg:
	stc
	ret
bytereg:
	mov	[edi],al
	clc
	ret
ModifyRegisters ENDP
putflags PROC
	mov	esi,offset _TEXT: flm
putflags2:
	lods	byte ptr [esi]
	or	al,al
	js	pfdone
	movzx	ax,al
	bt	word ptr [reflags],ax
	lods	dword ptr [esi]
	mov	edx,eax
	jc	isclr
	shr	edx,16
isclr:
	xchg	dh,dl
	call	PutChar
	xchg	dl,dh
	call	PutChar
	call	PrintSpace
	jmp	putflags2
pfdone:
	ret
putflags ENDP
;
; Display the processor regs
;
DisplayRegisters	PROC	
	mov	esi, offset _TEXT: peax		; Print GP regs
	mov	edx,offset _TEXT:PutDword	; with the DWORD function
	call	PrintAFew		; Print them
	mov	esi,offset _TEXT: peflags	; Put the flags
	call    PutDword		;
	call	putflags
	mov	ebx,dword ptr [dreip]		; Dissassemble at current code pointer
	call	DisOneLine		;
	clc
	ret
DisplayRegisters	ENDP	
END