title	ldebuasm
;	SCCSID = @(#)ldebuasm.asm	11.1 87/10/29

; Code for the UASSEMble command in the debugger

.xlist
.xcref
include ldebequ.inc
.cref
.list

include ldebseg.inc

DBDATA	segment

	extrn	_DISADD:byte, _AWORD:byte
	extrn	_MIDFLD:byte, _MODE:byte, _REGMEM:byte
	extrn	_OPCODE:word, _OPBUF:byte
	extrn	_INDEX:word

	extrn	_NSEG:word
	extrn	_REG8:byte
	extrn	_REG16:byte, _SREG:byte, _SEGTAB:word
	extrn	_RegSA:word

BYTCNT		db	?
DISCNT		dw	?

M8087_TAB	db "ADD$MUL$COM$COMP$SUB$SUBR$DIV$DIVR$"
FI_TAB		db "F$FI$F$FI$"
SIZE_TAB	db "DWord Ptr $DWord Ptr $QWord Ptr $Word Ptr $"
		db "byte ptr $TByte Ptr $"

MD9_TAB 	db "LD$@$ST$STP$LDENV$LDCW$STENV$STCW$"
MD9_TAB2	db "CHS$ABS$@$@$TST$XAM$@$@$LD1$LDL2T$LDL2E$"
		db "LDPI$LDLG2$LDLN2$LDZ$@$2XM1$YL2X$PTAN$PATAN$XTRACT$"
		db "@$DECSTP$INCSTP$PREM$YL2XP1$SQRT$@$RNDINT$SCALE$@$@$"

MDB_TAB 	db  "ILD$@$IST$ISTP$@$LD$@$STP$"
MDB_TAB2	db  "ENI$DISI$CLEX$INIT$"

MDD_TAB 	db "LD$@$ST$STP$RSTOR$@$SAVE$STSW$"
MDD_TAB2	db "FREE$XCH$ST$STP$"

MDF_TAB 	db "ILD$@$IST$ISTP$BLD$ILD$BSTP$ISTP$"

bComnt		db	0		; Comment  character byte (DEBUASM)
		db	"'"		; Terminates comment byte (;'cmnt')

DBDATA	ends

include ldebuasm.inc

DBCODE	segment

	public	_UNASSEM
	public	_DISASLN

	extrn	_CRLF:near, _PRINTMES:near
	extrn	_BLANK:near, _TAB:near, _OUT:near
	extrn	_HEX:near, _DEFAULT:near, _OUTSI:near

_UNASSEM:
	MOV	BP,[_RegSA.CSSAV]	; Default code segment
	MOV	DI,OFFSET ds:_DISADD	; Default address
	MOV	CX,128			; Default length
	SHR	CX,1
	SHR	CX,1
	CALL	_DEFAULT
	MOV	word ptr [_DISADD],DX	; Displacement of disassembly
	MOV	word ptr [_DISADD+2],AX ; Segment
	MOV	word ptr [DISCNT],CX	; No. of bytes (but whole instructions)
DISLP:
	MOV	[_NSEG],-1
	CALL	_DISASLN		; Disassemble one line
	MOV	SI,OFFSET ds:_OPBUF
	CALL	_PRINTMES		; and the operand buffer
	CALL	_CRLF
	CMP	[DISCNT],0		; See if we've used up the range
	JNZ	DISLP
	RET

GOTDIS: PUSH	DS			; RE-GET LAST BYTE
	PUSH	SI
	LDS	SI,dword ptr [_DISADD]
	MOV	AL,[SI-1]
	POP	SI
	POP	DS
	RET

GETDIS:
	PUSH	DS
	LDS	SI,dword ptr [_DISADD]
	LODSB				; Get the next byte of code
	POP	DS
	MOV	word ptr [_DISADD],SI	; Update pointer
	PUSH	AX
	CALL	_HEX			; Display each code byte
	MOV	SI,[DISCNT]
	OR	SI,SI			; Check if range exhausted
	JZ	ENDRNG			; If so, don't wrap around
	DEC	SI			; Count off the bytes
	MOV	[DISCNT],SI
ENDRNG:
	INC	byte ptr[BYTCNT]	; Keep track of no. of bytes per line
	POP	AX
	RET

DSPRE:	INC	byte ptr [_NSEG+1]
SSPRE:	INC	byte ptr [_NSEG+1]
CSPRE:	INC	byte ptr [_NSEG+1]
ESPRE:	INC	byte ptr [_NSEG+1]

PREFIX:
	POP	BX			; Dump off return address
	CALL	FINLN
	CALL	_CRLF
_DISASLN:
if  SID
	MOV	AX,word ptr [_DISADD+2]
	MOV	DX,word ptr [_DISADD]
	CALL	DspDisAdr		; Show disasm symbol [AX:DX]
else
	PUSH	DS
	LDS	SI,dword ptr [_DISADD]
	CALL	_OUTSI			; Show disassembly address
	POP	DS
endif
	CALL	_BLANK
	MOV	byte ptr [BYTCNT],0	; Count of code bytes per line
	MOV	DI,OFFSET ds:_OPBUF	; Point to operand buffer
	MOV	AL," "
	MOV	CX,OPBUFLEN-1		; Don't do last byte which has end marker
	REP	STOSB			; Initialize operand buffer to blanks
	MOV	[_OPBUF+34]," "+80h
	CALL	GETDIS			; Get opcode
	MOV	AH,0
	MOV	BX,AX
	AND	AL,1			; Mask to "W" bit
	MOV	[_AWORD],AL
	MOV	AL,BL			; Restore opcode
	SHL	BX,1
	SHL	BX,1			; Multiply opcode by 4
	ADD	BX,OFFSET ds:DISTAB
	MOV	DX,[BX] 		; Get pointer to mnemonic from table
	MOV	[_OPCODE],DX		; Save it until line is complete
	MOV	DI,OFFSET ds:_OPBUF	; Initialize for opcode routines
	CALL	word ptr [BX+2] 	; Dispatch to opcode routine
FINLN:
	CALL	DoComment		; Try ASCII byte comment
	MOV	byte ptr [DI]," "+80H
	PUSH	DI
	MOV	SI,OFFSET ds:_DISADD
	MOV	AH,[BYTCNT]		; See how many bytes in this instruction
	ADD	AH,AH			; Each uses two characters
	MOV	AL,14			; Amount of space we want to use
	SUB	AL,AH			; See how many fill characters needed
	CBW
	XCHG	CX,AX			; Parameter for TAB needed in CX
	CALL	_TAB
	MOV	SI,[_OPCODE]
	OR	SI,SI			; MAKE SURE THERE IS SOMETHING TO PRINT
	JZ	NOOPC
	CALL	_PRINTMES		; Print opcode mnemonic
	MOV	AL,9
	CALL	_OUT			; and a tab
NOOPC:
	POP	DI
	RET

DoComment:
	MOV	AL,[bComnt]
	CMP	AL," "
	JB	DoCmntx
	CMP	AL,7Fh
	JNB	DoCmntx
	MOV	AX,OFFSET ds:_OPBUF+29
	CMP	DI,AX
	JAE	DoCmnt1
	MOV	DI,AX
DoCmnt1:
	MOV	AL," "
	STOSB
	MOV	AX,"'"*256+";"
	STOSW
	MOV	AX,word ptr [bComnt]
	STOSW
	MOV	byte ptr [bComnt],0
DoCmntx:
	RET

GETMODE:
	CALL	GETDIS			; Get the address mode byte
	MOV	AH,AL
	AND	AL,7			; Mask to "r/m" field
	MOV	[_REGMEM],AL
	SHR	AH,1
	SHR	AH,1
	SHR	AH,1
	MOV	AL,AH
	AND	AL,7			; Mask to center 3-bit field
	MOV	[_MIDFLD],AL
	SHR	AH,1
	SHR	AH,1
	SHR	AH,1
	MOV	[_MODE],AH		; Leaving 2-bit "MOD" field
	RET

IMMED:
	MOV	BX,OFFSET ds:IMMTAB
	CALL	GETMNE
FINIMM:
	CALL	TESTREG
	JMP	SHORT IMM

MEMIMM:
	CALL	GETMODE
	JMP	SHORT FINIMM

ACCIMM:
	XOR	AL,AL
IMM1:
	CALL	SAVREG
IMM:
	MOV	AL,","
	STOSB
	TEST	byte ptr [_AWORD],-1
	JNZ	SAV16
SAV8:
	CALL	GETDIS
if  SID
	XOR	DX,DX
	MOV	[bComnt],AL		; Save for ASCII comment
	MOV	DL,AL			; [DX] = 8 bit value
	CALL	GetAbsAdr		; Move symbol [DX] if found
	MOV	AL,DL			; [AL] = 8 bit value
	JB	SAVHEX			; Brif not found
	RET
else
	JMP	SHORT SAVHEX
endif

LONGJMP:
	CALL	GETDIS			; Get low byte
	MOV	DL,AL
	CALL	GETDIS			; Get high byte
	MOV	DH,AL
	PUSH	DX			; Save Offset
	CALL	GETDIS			; Get low byte
	MOV	DL,AL
	CALL	GETDIS			; Get high byte
	MOV	DH,AL
if  SID
	PUSH	DX			; Save Segment
	CALL	GetSegAdr		; Move segment [DX] if found
	PUSHF
	JNB	Longjmp2		; Brif match
	CALL	SAV16DX
Longjmp2:
	MOV	AL,":"
	STOSB
	POPF
	POP	AX			; Segment
	POP	DX			; Offset
	JB	SAV16DX 		; Brif not our segment
	CALL	GetSymAdr		; Move symbol [DX] if found
	JB	SAV16DX 		; Brif no match
	RET
else
	CALL	SAV16DX
	MOV	AL,":"
	STOSB
	POP	DX
	JMP	SHORT SAV16DX
endif

if  SID
SAV16:
	CALL	GETDIS			; Get low byte
	MOV	DL,AL
	CALL	GETDIS			; Get high byte
	MOV	DH,AL
SAV16DX:
	XOR	AX,AX			;Default is constants
	PUSH	BX
	MOV	BX,[_NSEG]
	CMP	BL,-1
	JZ	SAV16cs
	CMP	BH,-1
	JZ	NOOVER
	MOV	BL,BH
NOOVER:
	XOR	BH,BH
	SHL	BX,1
	MOV	BX,[_SEGTAB+BX]
	MOV	AX,[BX]
SAV16cs:
	CALL	GetSymAdr		; Move symbol [AX:DX] if found
	JB	SAV16val		; Brif no matching symbol
	POP	BX
	RET
SAV16val:
	POP	BX
	MOV	AL,DH
	CALL	SAVHEX			; Convert and store high byte
	MOV	AL,DL
endif
if not SID
SAV16_8:
	call	SAV16
	mov	al,','
	stosb
	jmp	short SAV8

SAV16:
	CALL	GETDIS			; Get low byte
	MOV	DL,AL
	CALL	GETDIS			; Get high byte
	MOV	DH,AL
SAV16DX:
	MOV	AL,DH
	CALL	SAVHEX			; Convert and store high byte
	MOV	AL,DL
endif
SAVHEX:
	MOV	AH,AL
	SHR	AL,1
	SHR	AL,1
	SHR	AL,1
	SHR	AL,1
	CALL	SAVDIG
	MOV	AL,AH
SAVDIG:
	AND	AL,0FH
	ADD	AL,90H
	DAA
	ADC	AL,40H
	DAA
	STOSB
	RET

CHK10:
	CALL	GETDIS
	CMP	AL,10
	JNZ	SAVHEX
	RET

SIGNIMM:
	MOV	BX,OFFSET ds:IMMTAB
	CALL	GETMNE
	CALL	TESTREG
	MOV	AL,","
	STOSB
SAVD8:
	CALL	GETDIS			; Get signed 8-bit number
	CBW
	MOV	DX,AX			; Save true 16-bit value in DX
	MOV	AH,AL
	MOV	AL,"+"
	OR	AH,AH
;	JZ	nosign
	JNS	POSITIV 		; OK if positive
	MOV	AL,"-"
	NEG	AH			; Get magnitude if negative
POSITIV:
	STOSB
; nosign:
	MOV	AL,AH
	JMP	SHORT SAVHEX

ALUFROMREG:
	CALL	GETADDR
	MOV	AL,","
	STOSB
REGFLD:
	MOV	AL,[_MIDFLD]
SAVREG:
	MOV	SI,OFFSET ds:_REG8
	CMP	byte ptr [_AWORD],1
	JNE	FNDREG
SAVREG16:
	MOV	SI,OFFSET ds:_REG16
FNDREG:
	CBW
	ADD	SI,AX
	ADD	SI,AX
	MOVSW
	RET

SEGOP:
	SHR	AL,1
	SHR	AL,1
	SHR	AL,1
SAVSEG:
	AND	AL,3
	MOV	SI,OFFSET ds:_SREG
	JMP	SHORT FNDREG

REGOP:
	AND	AL,7
	JMP	SHORT SAVREG16

MOVSEGTO:
	MOV	byte ptr [_AWORD],1
	CALL	GETADDR
	MOV	AL,","
	STOSB
	MOV	AL,[_MIDFLD]
	JMP	SHORT SAVSEG

MOVSEGFROM:
	CALL	GETMODE
	CALL	SAVSEG
	MOV	byte ptr [_AWORD],1
	JMP	SHORT MEMOP2

GETADDR:
	CALL	GETMODE
	JMP	SHORT ADDRMOD

WORDTOALU:
	MOV	byte ptr [_AWORD],1
ALUTOREG:
	CALL	GETMODE
	CALL	REGFLD
MEMOP2:
	MOV	AL,","
	STOSB
ADDRMOD:
	CMP	byte ptr [_MODE],3
	MOV	AL,[_REGMEM]
	JE	SAVREG
	XOR	BX,BX
	MOV	byte ptr [_NSEG],3
	MOV	byte ptr [DI],"["
	INC	DI
	CMP	AL,6
	JNE	NODRCT
	CMP	byte ptr [_MODE],0
	JE	DIRECT			; Mode=0 and R/M=6 means direct addr.
NODRCT:
	MOV	DL,AL
	CMP	AL,1
	JBE	USEBX
	CMP	AL,7
	JE	USEBX
	CMP	AL,3
	JBE	USEBP
	CMP	AL,6
	JNE	CHKPLS
USEBP:
	MOV	BX,[_RegSA.BPSAV]
	MOV	byte ptr [_NSEG],2	; Change default to Stack Segment
	MOV	AX,BPREG
SAVBASE:
	STOSW
CHKPLS:
	CMP	DL,4
	JAE	NOPLUS
	MOV	AL,"+"
	STOSB
NOPLUS:
	CMP	DL,6
	JAE	DOMODE			; No index register
	AND	DL,1			; Even for SI, odd for DI
	JZ	USESI
	ADD	BX,[_RegSA.DISAV]
	MOV	AX,DIREG
SAVINDX:
	STOSW
DOMODE:
	MOV	AL,[_MODE]
	OR	AL,AL
	JZ	CLOSADD 		; If no displacement, then done
	CMP	AL,2
	JZ	ADDDIR
	CALL	SAVD8			; Signed 8-bit displacement
ADDCLOS:
	ADD	BX,DX
CLOSADD:
	MOV	AL,"]"
	STOSB
	MOV	[_INDEX],BX
NOOPERANDS:
	RET

ADDDIR:
	MOV	AL,"+"
	STOSB
DIRECT:
	CALL	SAV16
	JMP	SHORT ADDCLOS

USEBX:
	MOV	BX,[_RegSA.BXSAV]
	MOV	AX,BXREG
	JMP	SHORT SAVBASE

USESI:
	ADD	BX,[_RegSA.SISAV]
	MOV	AX,SIREG
	JMP	SHORT SAVINDX

SHORTJMP:
	CALL	GETDIS
	CBW
	ADD	AX,word ptr [_DISADD]
	XCHG	DX,AX
SAVJMP:
	MOV	byte ptr [_NSEG],1
	JMP	SAV16DX

JMPCALL:
	CALL	GETDIS
	MOV	DL,AL
	CALL	GETDIS
	MOV	DH,AL
	ADD	DX,word ptr [_DISADD]
	JMP	SHORT SAVJMP

XCHGAX:
	AND	AL,7
	CALL	SAVREG16
	MOV	AL,","
	STOSB
	XOR	AL,AL
	JMP	SAVREG16

LOADACC:
	XOR	AL,AL
	CALL	SAVREG
	MOV	AL,","
	STOSB
MEMDIR:
	MOV	AL,"["
	STOSB
	XOR	BX,BX
	MOV	byte ptr [_NSEG],3
	JMP	DIRECT

STOREACC:
	CALL	MEMDIR
	MOV	AL,","
	STOSB
	XOR	AL,AL
	JMP	SAVREG

REGIMMB:
	MOV	byte ptr [_AWORD],0
	JMP	SHORT REGIMM
REGIMMW:
	MOV	byte ptr [_AWORD],1
REGIMM:
	AND	AL,7
	JMP	IMM1

INT3:
	MOV	byte ptr [DI],"3"
	INC	DI
	RET
;
;  8087 instructions whose first byte is 0dfh
;
M8087_DF:
	CALL	GET64F
	JZ	ISDD3
	MOV	SI,OFFSET ds:MDF_TAB
	JMP	NODB3
;
;  8087 instructions whose first byte is 0ddh
;
M8087_DD:
	CALL	GET64F
	JZ	ISDD3
	MOV	SI,OFFSET ds:MDD_TAB
	JMP	NOD93

ISDD3:
	MOV	AL,DL
	TEST	AL,100B
	JZ	ISSTI
	JMP	ESC0
ISSTI:	AND	AL,11B
	MOV	SI,OFFSET ds:MDD_TAB2
	MOV	CL,AL
	CALL	MOVBYT
	JMP	PUTRST
;
;  8087 instructions whose first byte is 0dbh
;
M8087_DB:
	CALL	GET64F
	JZ	ISDB3
	MOV	SI,OFFSET ds:MDB_TAB
NODB3:	CALL	PUTOP
	CALL	PUTSIZE
	JMP	ADDRMOD

ISDB3:
	MOV	AL,DL
	TEST	AL,100B
	JNZ	ISDBIG
ESC0V:	JMP	ESC0
ISDBIG: CALL	GOTDIS
	AND	AL,11111B
	CMP	AL,4
	JAE	ESC0V
	MOV	SI,OFFSET ds:MDB_TAB2
	JMP	DOBIG
;
;  8087 instructions whose first byte is 0d9h
;
M8087_D9:
	CALL	GET64F
	JZ	ISD93

	MOV	SI,OFFSET ds:MD9_TAB
NOD93:	CALL	PUTOP
	AND	AL,111B
	CMP	AL,3
	JA	NOSHO
	MOV	AL,DL
	CALL	PUTSIZE
NOSHO:	JMP	ADDRMOD

ISD93:	MOV	AL,DL
	TEST	AL,100B
	JNZ	ISD9BIG
	AND	AL,111B
	OR	AL,AL
	JNZ	NOTFLD
	MOV	AX,"DL"
	STOSW
	JMP	SHORT PUTRST
NOTFLD: CMP	AL,1
	JNZ	NOTFXCH
	MOV	AX,"CX"
	STOSW
	MOV	AL,"H"
	JMP	SHORT PUTRST1
NOTFXCH:CMP	AL,3
	JNZ	NOTFSTP
	MOV	AX,"TS"
	STOSW
	MOV	AL,"P"
PUTRST1:STOSB
PUTRST: MOV	AL,9
	STOSB
	JMP	PUTST0

NOTFSTP:CALL	GOTDIS
	CMP	AL,11010000B		; CHECK FOR FNOP
	JZ	GOTFNOP
	JMP	ESC0
GOTFNOP:MOV	AX,"ON"
	STOSW
	MOV	AL,"P"
	STOSB
	RET

ISD9BIG:
	CALL	GOTDIS			; GET THE MODE BYTE
	MOV	SI,OFFSET ds:MD9_TAB2
DOBIG:	AND	AL,11111B
	MOV	CL,AL
	JMP	MOVBYT
;
; entry point for the remaining 8087 instructions
;
M8087:
	CALL	GET64
	CALL	PUTFI			; PUT FIRST PART OF OPCODE
	MOV	AL,DL
	CMP	byte ptr [_MODE],11B	; CHECK FOR REGISTER MODE
	JZ	MODEIS3
	CALL	PUTMN			; PUT MIDDLE PART OF OPCODE
NO3:	MOV	AL,9			; OUTPUT A TAB
	STOSB
	MOV	AL,DL
	CALL	PUTSIZE 		; OUTPUT THE OPERAND SIZE
	JMP	ADDRMOD

MODEIS3:
	TEST	AL,100000B		; D BIT SET?
	JZ	MPUT			; NOPE...
	TEST	AL,000100B		; FDIV OR FSUB?
	JZ	MPUT			; NOPE...
	XOR	AL,1			; REVERSE SENSE OF R
	MOV	DL,AL			; SAVE CHANGE
MPUT:	CALL	PUTMN			; PUT MIDDLE PART OF OPCODE
	MOV	AL,DL
	TEST	AL,010000B
	JZ	NOPSH
	MOV	AL,"P"
	STOSB
NOPSH:	MOV	AL,9
	STOSB
	MOV	AL,DL
	AND	AL,00000111B
	CMP	AL,2			; FCOM
	JZ	PUTST0
	CMP	AL,3			; FCOMP
	JZ	PUTST0
	MOV	AL,DL
	TEST	AL,100000B
	JZ	PUTSTST0
;
; output 8087 registers in the form st(n),st
;
PUTST0ST:
	CALL	PUTST0
	MOV	AL,','
ISCOMP: STOSB

PUTST:	MOV	AX,"TS"
	STOSW
	RET
;
; output 8087 registers in the form st,st(n)
;
PUTSTST0:
	CALL	PUTST
	MOV	AL,','
	STOSB

PUTST0: CALL	PUTST
	MOV	AL,"("
	STOSB
	MOV	AL,[_REGMEM]
	ADD	AL,"0"
	STOSB
	MOV	AL,")"
	STOSB
	RET
;
; output an 8087 mnemonic
;
PUTMN:	MOV	SI,OFFSET ds:M8087_TAB
	MOV	CL,AL
	AND	CL,00000111B
	JMP	SHORT MOVBYT
;
; output either 'FI' or 'F' for first byte of opcode
;
PUTFI:	MOV	SI,OFFSET ds:FI_TAB
	JMP	SHORT PUTFI2
;
; output size (dword, tbyte, etc.)
;
PUTSIZE:MOV	SI,OFFSET ds:SIZE_TAB
PUTFI2: CMP	byte ptr [_MODE],11B	; check if 8087 register
	JNZ	PUTFI3
	AND	AL,111000B		; LOOK FOR INVALID FORM OF 0DAH OPERANDS
	CMP	AL,010000B
	JZ	ESC0PJ
	MOV	AL,DL
	CMP	AL,110011B		; FCOMPP
	JNZ	GOFI
	CMP	byte ptr [_REGMEM],1
	JZ	GOFI
ESC0PJ: JMP	ESC0P
GOFI:	XOR	CL,CL
	JMP	SHORT MOVBYT
;
;  Look for qword
;
PUTFI3: CMP	AL,111101B
	JZ	GOTQU
	CMP	AL,111111B
	JNZ	NOTQU
GOTQU:	MOV	CL,2
	JMP	SHORT MOVBYT
;
;  look for tbyte
;
NOTQU:	CMP	AL,011101B
	JZ	GOTTB
	CMP	AL,111100B
	JZ	GOTTB
	CMP	AL,111110B
	JZ	GOTTB
	CMP	AL,011111B
	JNZ	NOTTB
GOTTB:	MOV	CL,5
	JMP	SHORT MOVBYT

NOTTB:	MOV	CL,4
	SHR	AL,CL
	MOV	CL,AL
;
; SI POINTS TO A TABLE OF TEXT SEPARATED BY "$"
; CL = WHICH ELEMENT IN THE TABLE YOU WISH TO COPY TO [DI]
;
MOVBYT: PUSH	AX
	INC	CL
MOVBYT1:DEC	CL
	JZ	MOVBYT3
MOVBYT2:LODSB
	CMP	AL,'$'
	JZ	MOVBYT1
	JMP	MOVBYT2
MOVBYT3:LODSB
	CMP	AL,'$'
	JZ	MOVBYT5
	CMP	AL,'@'			; THIS MEANS RESVERED OP-CODE
	JNZ	MOVBYT4
	POP	AX
	JMP	SHORT ESC0P		; GO DO AN ESCAPE COMMAND
MOVBYT4:STOSB
	JMP	MOVBYT3
MOVBYT5:POP	AX
	RET

PUTOP:	AND	AL,111B
	MOV	CL,AL
	CALL	MOVBYT
	MOV	AL,9
	STOSB
	MOV	AL,DL
	RET

GET64F: CALL	GET64
	MOV	AL,"F"
	STOSB
	CMP	byte ptr [_MODE],3
	MOV	AL,DL
	RET

GET64:
	AND	AL,7
	MOV	DL,AL
	CALL	GETMODE
	SHL	DL,1
	SHL	DL,1
	SHL	DL,1
	OR	AL,DL
	MOV	DL,AL			; SAVE RESULT
	RET

ESC0P:	POP	DI			; CLEAN UP STACK
ESC0:	MOV	word ptr [_OPCODE],OFFSET ds:ESCMN
	MOV	AL,DL
	MOV	DI,OFFSET ds:_OPBUF
	JMP	SHORT ESC1

ESC_:	CALL	GET64
ESC1:	CALL	SAVHEX
	CMP	byte ptr [_MODE],3
	JZ	SHRTESC
	MOV	byte ptr  [_AWORD],1
	JMP	MEMOP2

SHRTESC:
	MOV	AL,","
	STOSB
	MOV	AL,[_REGMEM]
	AND	AL,7
	JMP	SAVREG

INVARW:
	CALL	PUTAX
	JMP	SHORT INVAR
INVARB:
	CALL	PUTAL
INVAR:	MOV	AL,','
	STOSB
	JMP	PUTDX

INFIXW:
	CALL	PUTAX
	JMP	SHORT INFIX
INFIXB:
	CALL	PUTAL
INFIX:	MOV	AL,','
	STOSB
	JMP	SAV8
	STOSW
	RET

OUTVARB:
	MOV	BX,"LA"
	JMP	SHORT OUTVAR
OUTVARW:
	MOV	BX,"XA"
OUTVAR: CALL	PUTDX
OUTFV:	MOV	AL,','
	STOSB
	MOV	AX,BX
	STOSW
	RET

OUTFIXB:
	MOV	BX,"LA"
	JMP	SHORT OUTFIX
OUTFIXW:
	MOV	BX,"XA"
OUTFIX: CALL	SAV8
	JMP	OUTFV

PUTAL:	MOV	AX,"LA" 		; "AL"
	JMP	SHORT PUTX
PUTAX:	MOV	AX,"XA" 		; "AX"
	JMP	SHORT PUTX
PUTDX:	MOV	AX,"XD" 		; "DX"
PUTX:	STOSW
	RET

SHIFTV:
	CALL	SHFT
	MOV	AL,","
	STOSB
	MOV	AX,"LC" 		; "CL"
	JMP	PUTX

SHIFT:
	CALL	SHFT
	MOV	AX,"1,"
	JMP	PUTX

SHFT:
	MOV	BX,OFFSET ds:SHFTAB
	CALL	GETMNE
TESTREG:
	CMP	byte ptr [_MODE],3
	JZ	NOFLG
	MOV	SI,OFFSET ds:SIZE_TAB
	MOV	CL,3
	TEST	byte ptr [_AWORD],-1
	JNZ	TEST_1
	INC	CL
TEST_1: CALL	MOVBYT
NOFLG:
	JMP	ADDRMOD

GETMNE:
	CALL	GETMODE
	MOV	DL,AL
	CBW
	SHL	AX,1
	ADD	BX,AX
	MOV	AX,[BX]
	MOV	[_OPCODE],AX
	MOV	AL,DL
	RET

GRP1:
	MOV	BX,OFFSET ds:GRP1TAB
	CALL	GETMNE
	OR	AL,AL
	JZ	FINIMMJ
	JMP	TESTREG
FINIMMJ:
	JMP	FINIMM

GRP2:
	MOV	BX,OFFSET ds:GRP2TAB
	CALL	GETMNE
	CMP	AL,2
	JB	TESTREG
	CMP	AL,6
	JAE	INDIRECT
	TEST	AL,1
	JZ	INDIRECT
	MOV	AX,"AF" 		; "FAR"
	STOSW
	MOV	AX," R"
	STOSW
INDIRECT:
	JMP	ADDRMOD

DBCODE	ends
	end
