Metropoli BBS
VIEWER: disasm.asm MODE: TEXT (ASCII)
; =========================================================================== ;
; Dawn disassembler v1.1, UnCopyright 1995-97 Sami Kantoluoto.		      ;
; --------------------------------------------------------------------------- ;
;									      ;
;	 file: disasm.asm						      ;
; description: That's it.                                                     ;
;      coding: Sami Kantoluoto						      ;
; last update: 25/09/1997 (dd/mm/yyyy)					      ;
;									      ;
; =========================================================================== ;
		.386P
; =========================================================================== ;
PMODE_TEXT	Segment Para Public Use16 'PMODE'
		.MODEL	TPASCAL
		assume	CS:PMODE_TEXT,DS:PMODE_TEXT
; --------------------------------------------------------------------------- ;
extrn		_OpMap1:Word, _Second:Word, _Groups:Word, _fspecial:Word
extrn		_floatops:Word
public		UnAssemble, Instruction_Off, Instruction_Len, UBuf,SegSize
public		Real_Offset
; --------------------------------------------------------------------------- ;
o		equ	offset
Extrn		HexTable:Byte
SegSize 	db	16,0		; Code segment size
Instruction_Off dd	0		; Instruction offset (EIP)
Real_Offset	dd	0
Instruction_Len db	0,0		; Instruction length (after disasm)
OpSize		db	0,0
AddrSize	db	0,0
modRMV		dw	0
SIBV		dw	0
Prefix		db	0,0
WordOp		db	0,0
ShowZero	db	0,0		; <>0=[eax+ebx+0], 0=[eax+ebx]
R		db	0,0
Extend		db	0
SExt		db	0
flags		db	0

UBufP		dw	0
UBuf		db	128 dup (0)

PrefixStr	db	"%p:[",0
EF_Str		db	" %EF",0
Invalid 	db	"(Invalid)",0
Illegal 	db	"<Illegal instruction>",0
BytePtr 	db	"byte ptr ",0
WordPtr 	db	"word ptr ",0
DWordPtr	db	"dword ptr ",0
FWordPtr	db	"fword ptr ",0
QWordPtr	db	"qword ptr ",0
;ShortPtr	 db	 "short ptr ",0
;NearPtr	 db	 "near ptr ",0
;FarPtr 	 db	 "far ptr ",0

		Align	4
RegTable8	label	word
		db	"al","cl","dl","bl"
		db	"ah","ch","dh","bh"
RegTable16	label	word
		db	"ax","cx","dx","bx"
		db	"sp","bp","si","di"
SRegTable	label	word
		db	"es","cs","ss","ds"
		db	"fs","gs","?s","!s"
_Goto		Macro	A
		dw	(A-(($-o Per_Table) shr 1)-'1') dup (o Per_Illegal)
		EndM
Per_Table	label	word
		;_Goto	 '1'
		dw	o Per_Type_1,o Per_Type_2
		dw	o Per_Type_3
		_Goto	'A'
		dw	o Per_Type_A_,o Per_Illegal
		dw	o Per_Type_C_,o Per_Type_D_
		dw	o Per_Type_E_,o Per_Illegal
		dw	o Per_Type_G_,o Per_Illegal
		dw	o Per_Type_I_,o Per_Type_J_
		dw	o Per_Illegal,o Per_Illegal
		dw	o Per_Type_M_,o Per_Illegal
		dw	o Per_Type_O_,o Per_Type_P_
		dw	o Per_Type_Q_,o Per_Type_R_
		dw	o Per_Type_S_,o Per_Type_T_
		_Goto	'X'
		dw	o Per_Type_X_,o Per_Type_Y_
		_Goto	'a'
		dw	o Per_Type_a
		dw	o Per_Type_b,o Per_Illegal
		dw	o Per_Type_d,o Per_Type_e
		dw	o Per_Type_f,o Per_Type_g
		_Goto	'p'
		dw	o Per_Type_p,o Per_Type_q
		dw	o Per_Type_r,o Per_Type_s
		_Goto	'w'
		dw	o Per_Type_w

RMRegTable32	dw	o REAX,o RECX,o REDX,o REBX,o RNOT,o REBP,o RESI,o REDI
RMRegTable16	dw	o BXSI,o BXDI,o BPSI,o BPDI,o RSI,o RDI,o RBP,o RBX
SIB_RegTable	dw	o REAX,o RECX,o REDX,o REBX,o RESP,o REBP,o RESI,o REDI

REAX		db	"eax",0
RECX		db	"ecx",0
REDX		db	"edx",0
REBX		db	"ebx"
RNOT		db	0
RESP		db	"esp",0
REBP		db	"ebp",0
RESI		db	"esi",0
REDI		db	"edi",0
BXSI		db	"bx+si",0
BXDI		db	"bx+di",0
BPSI		db	"bp+si",0
BPDI		db	"bp+di",0
RSI		db	"si",0
RDI		db	"di",0
RBP		db	"bp",0
RBX		db	"bx",0
; --------------------------------------------------------------------------- ;
@MOD		Macro	A
		shr	A,6
		and	A,3
		EndM
; --------------------------------------------------------------------------- ;
@REG		Macro	A
		shr	A,3
		and	A,7
		EndM
; --------------------------------------------------------------------------- ;
@RM		Macro	A
		and	A,7
		EndM
; --------------------------------------------------------------------------- ;
@SCALE		equ	@MOD
@INDEX		equ	@REG
@BASE		equ	@RM
; --------------------------------------------------------------------------- ;
GetByteRS	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		inc	Instruction_Len
		inc	Instruction_Off
		inc	Real_Offset
		movsx	A,byte ptr fs:[esi]
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
GetByteR	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		inc	Instruction_Len
		inc	Instruction_Off
		inc	Real_Offset
		mov	A,fs:[esi]
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
GetByte 	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		inc	Instruction_Len
		inc	Instruction_Off
		inc	Real_Offset
		mov	al,fs:[esi]
		IFNB	<A>
		mov	A,al
		ENDIF
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
GetWordRS	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		add	Instruction_Len,2
		add	Instruction_Off,2
		add	Real_Offset,2
		movsx	A,word ptr fs:[esi]
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
GetWordR	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		add	Instruction_Len,2
		add	Instruction_Off,2
		add	Real_Offset,2
		mov	A,fs:[esi]
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
GetWord 	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		add	Instruction_Len,2
		add	Instruction_Off,2
		add	Real_Offset,2
		mov	ax,fs:[esi]
		IFNB	<A>
		mov	A,ax
		ENDIF
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
GetDWordR	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		add	Instruction_Len,4
		add	Instruction_Off,4
		add	Real_Offset,4
		mov	A,fs:[esi]
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
GetDWord	Macro	A,B
		IFNB	<B>
		push	esi
		ENDIF
		mov	esi,Instruction_Off
		add	Instruction_Len,4
		add	Instruction_Off,4
		add	Real_Offset,4
		mov	eax,fs:[esi]
		INFB	<A>
		mov	a,eax
		ENDIF
		IFNB	<B>
		pop	esi
		ENDIF
		EndM
; --------------------------------------------------------------------------- ;
ModRM		Proc	near
		mov	ax,modRMV
		cmp	ax,-1
		jne	ModRM_Exit
		xor	ah,ah
		GetByte
		mov	modRMV,ax
ModRM_Exit:	ret
ModRM		EndP
; --------------------------------------------------------------------------- ;
SIB		Proc	near
		mov	ax,SIBV
		cmp	ax,-1
		jne	SIB_Exit
		xor	ah,ah
		GetByte
		mov	SIBV,ax
SIB_Exit:	ret
SIB		EndP
; --------------------------------------------------------------------------- ;
Percent 	Proc	Pascal Near
		ARG	_Type:DWORD,SubType:DWORD

		mov	al,byte ptr SubType
		mov	bx,word ptr _Type
		cmp	bx,'w'
		ja	Per_Illegal
		cmp	bx,'1'
		jb	Per_Illegal
		add	bx,bx
		jmp	ds:Per_Table[bx-62h]

Per_Type_A_:	cmp	OpSize,32
		jne	Per_A_16
		GetDWordR ebx
		GetWordR dx
		mov	di,UBufP
		add	UBufP,13
		mov	cl,4
		call	PrintHex
		mov	byte ptr ds:[di],':'
		inc	di
		mov	edx,ebx
		mov	cl,8
		call	PrintHex
		jmp	Per_Exit
Per_A_16:	GetWordR bx
		GetWordR dx
		mov	di,UBufP
		add	UBufP,9
		mov	cl,4
		call	PrintHex
		mov	byte ptr ds:[di],':'
		inc	di
		mov	dx,bx
		mov	cl,4
		call	PrintHex
		jmp	Per_Exit

Per_Type_C_:	mov	di,UBufP
		add	UBufP,3
		mov	word ptr ds:[di],'rc'
		call	ModRM
		@REG	al
		add	al,'0'
		mov	ds:[di+2],al
		jmp	Per_Exit

Per_Type_D_:	mov	di,UBufP
		add	UBufP,3
		mov	word ptr ds:[di],'rd'
		call	ModRM
		@REG	al
		add	al,'0'
		mov	ds:[di+2],al
		jmp	Per_Exit

Per_Type_E_:	cmp	al,'r'
		jne	Per_E_Call
		push	dword ptr R
		call	do_modRM
		jmp	Per_Exit
Per_E_Call:	push	dword ptr SubType
		call	do_modRM
		jmp	Per_Exit

Per_Type_G_:	cmp	al,'F'
		jne	Per_G_Cont
Per_FloatReg:	call	ModRM
		@RM	al
		mov	ah,')'
		add	al,'0'
		mov	di,UBufP
		add	UBufP,5
		mov	dword ptr ds:[di],' (ts'
		mov	word ptr ds:[di+3],ax
		jmp	Per_Exit
Per_G_Cont:	call	ModRM
		mov	bx,ax
		@REG	bl
		add	bl,bl
		mov	al,byte ptr SubType
		cmp	al,'b'
		je	Per_G_Sub_b
		or	WordOp,0
		jnz	Per_G_WOP
		cmp	al,'c'
		jne	Per_G_WOP
Per_G_Sub_b:	mov	di,UBufP
		add	UBufP,2
		mov	ax,RegTable8[bx]
		mov	ds:[di],ax
		jmp	Per_Exit
Per_G_WOP:	cmp	al,'d'
		je	Per_G_Ext
		cmp	OpSize,32
		jne	Per_G_16
		cmp	al,'v'
		jne	Per_G_16
Per_G_Ext:	mov	di,UBufP
		inc	UBufP
		mov	byte ptr ds:[di],'e'
Per_G_16:	mov	di,UBufP
		add	UBufP,2
		mov	ax,RegTable16[bx]
		mov	ds:[di],ax
		jmp	Per_Exit

Per_Type_I_:	mov	al,byte ptr SubType
		cmp	al,'r'
		jne	Per_I_Cont
		mov	al,R
Per_I_Cont:	cmp	al,'d'
		je	Per_I_DD
		cmp	OpSize,32
		jne	Per_I_Not_DD
		cmp	al,'v'
		je	Per_I_DD
		cmp	al,'c'
		jne	Per_I_Not_DD
		or	WordOp,0
		jnz	Per_I_b
Per_I_DD:	mov	di,UBufP
		add	UBufP,8
		GetDWordR edx
		mov	cl,8
		call	PrintHex
		jmp	Per_Exit
Per_I_Not_DD:	cmp	al,'b'
		je	Per_I_b
		cmp	al,'w'
		je	Per_I_w
		cmp	al,'c'
		je	Per_I_c
		cmp	al,'v'
		jne	Per_Illegal
Per_I_w:	mov	di,UBufP
		add	UBufP,4
		GetWordR dx
		mov	cl,4
		call	PrintHex
		jmp	Per_Exit
Per_I_b:	xor	edx,edx
		GetByteR dl
		or	SExt,0
		jz	Per_I_b_
		movsx	edx,dl
Per_I_b_:	xor	ch,ch
		mov	cl,Extend
		mov	di,UBufP
		add	UBufP,cx
		call	PrintHex
		jmp	Per_Exit
Per_I_c:	or	WordOp,0
		jz	Per_I_b
		jmp	Per_I_w

Per_Type_J_:	xor	eax,eax
		mov	cx,1
		mov	bl,byte ptr SubType
		cmp	bl,'b'
		je	Per_J_N_OK
		add	cl,cl
		cmp	bl,'w'
		je	Per_J_N_OK
		add	cl,cl
		cmp	bl,'d'
		je	Per_J_N_OK
		cmp	bl,'v'
		jne	Per_Illegal
		cmp	OpSize,32
		je	Per_J_N_OK
		mov	cl,2
		jmp	Per_J_N_OK
Per_J_N_OK:	mov	ch,cl
Per_J_Loop:	ror	eax,8
		GetByte
		dec	cl
		jnz	Per_J_Loop
		mov	cl,ch
		dec	cl
		shl	cl,3
		rol	eax,cl
		cmp	ch,1
		ja	Per_J_C1
		cbw
Per_J_C1:	cmp	ch,2
		ja	Per_J_C2
		cwde
Per_J_C2:	add	eax,Real_Offset
		mov	edx,eax
		mov	cx,4
		cmp	SegSize,16
		je	Per_J_C3
		mov	cl,8
Per_J_C3:	mov	di,UBufP
		add	UBufP,cx
		call	PrintHex
		jmp	Per_Exit

;Per_Type_K_:	 mov	 di,UBufP
;		 mov	 al,SubType
;		 mov	 si,offset ShortPtr
;		 cmp	 al,'s'
;		 je	 Per_K_CStr
;		 mov	 si,offset NearPtr
;		 cmp	 al,'n'
;		 je	 Per_K_CStr
;		 mov	 si,offset FarPtr
;Per_K_CStr:	 call	 CopyStr
;		 mov	 UBufP,di
;		 jmp	 Per_Exit

Per_Type_M_:	call	ModRM
		@MOD	al
		cmp	al,3
		jne	Per_M_Call
		call	PrintInv
Per_M_Call:	push	dword ptr SubType
		call	do_modRM
		jmp	Per_Exit

Per_Type_O_:	push	large offset PrefixStr
		call	UA_Str
		mov	di,UBufP
		cmp	AddrSize,32
		jne	Per_O_16
		add	UBufP,9
		GetDWordR edx
		mov	cl,8
		call	PrintHex
		mov	byte ptr ds:[di],']'
		jmp	Per_Exit
Per_O_16:	add	UBufP,5
		GetWordR dx
		mov	cl,4
		call	PrintHex
		mov	byte ptr ds:[di],']'
		jmp	Per_Exit

Per_Type_P_:	call	ModRM
		@REG	al
PTP_MMXR:	add	al,'0'
		mov	di,UBufP
		mov	word ptr ds:[di],'mm'
		mov	byte ptr ds:[di+2],al
		add	UBufP,3
		jmp	Per_Exit

Per_Type_Q_:	call	ModRM
		mov	ah,al
		@MOD	al
		cmp	al,3
		jne	Per_R_Call
		call	ModRM
		mov	al,ah
		@RM	al
		jmp	PTP_MMXR

Per_Type_R_:	call	ModRM
		@MOD	al
		cmp	al,3
		je	Per_R_Call
		call	PrintInv
Per_R_Call:	push	dword ptr SubType
		call	do_modRM
		jmp	Per_Exit

Per_Type_S_:	mov	di,UBufP
		add	UBufP,2
		call	ModRM
		@REG	al
		mov	bx,ax
		add	bx,ax
		mov	ax,ds:SRegTable[bx]
		mov	ds:[di],ax
		jmp	Per_Exit

Per_Type_T_:	mov	di,UBufP
		add	UBufP,3
		call	ModRM
		mov	word ptr ds:[di],'rt'
		@REG	al
		add	al,'0'
		mov	ds:[di+2],al
		jmp	Per_Exit

Per_Type_X_:	mov	di,UBufP
		add	UBufP,7
		mov	eax,'[:sd'
		or	Prefix,0
		jz	Per_X_Cont
		mov	al,Prefix
Per_X_Cont:	mov	ds:[di],eax
		lea	di,[di+4]
		cmp	AddrSize,32
		jne	Per_X_Rest
		inc	UBufP
		mov	byte ptr ds:[di],'e'
		inc	di
Per_X_Rest:	mov	dword ptr ds:[di],']is'
		jmp	Per_Exit

Per_Type_Y_:	mov	di,UBufP
		add	UBufP,7
		mov	dword ptr ds:[di],'[:se'
		lea	di,[di+4]
		cmp	AddrSize,32
		jne	Per_Y_Rest
		inc	UBufP
		mov	byte ptr ds:[di],'e'
		inc	di
Per_Y_Rest:	mov	dword ptr ds:[di],']id'
		jmp	Per_Exit

Per_Type_1:	sub	al,'0'                  ; Fix for AAM/AAD
		movzx	eax,al
		add	Instruction_Off,eax
		add	Real_Offset,eax
		jmp	Per_Exit

Per_Type_2:	xor	bh,bh
		GetByteR bl
		add	bx,bx
		push	dword ptr ds:_Second[bx]
		call	UA_Str
		jmp	Per_Exit

Per_Type_3:	cmp	al,'v'
		je	Per_T_v
		cmp	al,'w'
		jne	Per_T_v
Per_T_w:	mov	ah,OpSize
		shr	ah,2
		mov	Extend,ah
		jmp	Per_Exit
Per_T_v:	mov	ah,OpSize
		shr	ah,2
		mov	Extend,ah
		mov	SExt,1
		jmp	Per_Exit
Per_T_3:	sub	al,'0'
		mov	Extend,al
		mov	SExt,1
		jmp	Per_Exit

Per_Type_a:	cmp	AddrSize,32
		jne	Per_Exit
		mov	di,UBufP
		inc	UBufP
		mov	ds:[di],al
		jmp	Per_Exit

Per_Type_b:	mov	di,UBufP
		inc	UBufP
		mov	byte ptr ds:[di],'b'
		cmp	OpSize,16
		je	Per_Exit
		mov	al,byte ptr SubType
		mov	ds:[di],al
		cmp	al,' '
		jne	Per_Exit
		dec	UBufP
		jmp	Per_Exit

Per_Type_d:	mov	di,UBufP
		cmp	OpSize,32
		jne	Per_Exit
		inc	UBufP
		mov	byte ptr ds:[di],'d'
		jmp	Per_Exit

Per_Type_e:	mov	di,UBufP
		inc	UBufP
		cmp	OpSize,32
		jne	Per_e_c
		inc	UBufP
		mov	byte ptr ds:[di],'e'
		inc	di
Per_e_c:	mov	al,byte ptr SubType
		mov	ds:[di],al
		jmp	Per_Exit

Per_Type_f:	; Floating point Op.
		sub	al,'0'
		shl	al,3
		xor	bh,bh
		mov	bl,al
		call	ModRM
		mov	cx,ax
		@REG	al
		add	bx,ax		; BX = Esc
		add	bx,bx
		@MOD	cl
		cmp	cl,3
		je	Per_f_Special
Per_f_normal:	push	dword ptr _floatops[bx]
		call	UA_Str
		push	large offset EF_Str
		call	UA_Str
		jmp	Per_Exit
Per_f_Special:	or	_fspecial[bx],0
		jz	Per_f_normal
		mov	bx,_fspecial[bx]
		mov	si,[bx]
		test	si,si
		jz	Per_f_spec_nast
		cmp	byte ptr ds:[si],'*'
		jne	Per_f_spec_nast
		inc	si
		push	esi
		call	UA_Str
		jmp	Per_Exit
Per_f_spec_nast:call	ModRM
		@RM	al
		add	al,al
		add	bx,ax
		push	dword ptr [bx]
		call	UA_Str
		jmp	Per_Exit

Per_Type_g:	mov	bx,word ptr SubType
		sub	bl,'0'
		shl	bx,4
		call	ModRM
		@REG	al
		add	ax,ax
		add	bx,ax
		push	dword ptr ds:_Groups[bx]
		call	UA_Str
		jmp	Per_Exit

Per_Type_p:	mov	al,byte ptr SubType
		cmp	al,':'
		je	Per_p_Prefix
		cmp	al,' '
		je	Per_Next_Op
		mov	Prefix,al
		jmp	Per_Next_Op
Per_p_Prefix:	mov	al,Prefix
		or	al,al
		jz	Per_Exit
		mov	di,UBufP
		add	UBufP,3
		mov	ds:[di],al
		mov	word ptr ds:[di+1],':s'
		jmp	Per_Exit
Per_Next_Op:	xor	ah,ah
		GetByte
		mov	bx,ax
		add	bx,ax
		and	al,1
		mov	WordOp,al
		push	dword ptr _OpMap1[bx]
		call	UA_Str
		jmp	Per_Exit

Per_Type_q:	cmp	OpSize,32
		jne	Per_Exit
		mov	al,byte ptr SubType
		mov	di,UBufP
		inc	UBufP
		mov	ds:[di],al
		jmp	Per_Exit

Per_Type_r:	mov	al,byte ptr SubType
		mov	R,al
		jmp	Per_Exit

Per_Type_s:	cmp	SubType,'a'
		je	Per_s_Addr
		or	OpSize+1,0
		jnz	Per_Next_Op
		or	OpSize+1,1
		mov	al,48
		sub	al,OpSize
		mov	OpSize,al
		jmp	Per_Next_Op
Per_s_Addr:	or	AddrSize+1,0
		jnz	Per_Next_Op
		or	AddrSize+1,1
		mov	al,48
		sub	al,AddrSize
		mov	AddrSize,al
		jmp	Per_Next_Op

Per_Type_w:	mov	di,UBufP
		inc	UBufP
		mov	al,byte ptr SubType
		mov	byte ptr ds:[di],'w'
		cmp	OpSize,16
		je	Per_Exit
		mov	byte ptr ds:[di],al
		cmp	al,' '
		jne	Per_Exit
		dec	UBufP
		jmp	Per_Exit

Per_Illegal:	or	flags,1
Per_Exit:	ret
Percent 	EndP
; --------------------------------------------------------------------------- ;
do_modRM	Proc	Pascal Near
		ARG	SubType:DWORD
		LOCAL	_MOD_:Word,_RM_:Word

		call	ModRM
		mov	bx,ax

		@MOD	al
		@RM	bl

		mov	cl,byte ptr SubType

		cmp	al,3
		jne	dmRM_MOD_n3
		; MOD = 3 (Specifies register)
		cmp	cl,'F'
		je	dmRM_FloatReg
		cmp	cl,'b'
		je	dmRM_MOD3_b
		or	WordOp,0
		jnz	dmRM_MOD3_WOP
		cmp	cl,'c'
		jne	dmRM_MOD3_WOP2
dmRM_MOD3_b:	add	bx,bx
		mov	ax,ds:RegTable8[bx]
		mov	di,UBufP
		add	UBufP,2
		mov	ds:[di],ax
		jmp	dmRM_Exit

dmRM_FloatReg:	leave
		pop	ax				; bug!
		jmp	Per_FloatReg

dmRM_MOD3_WOP:	cmp	cl,'c'
		je	dmRM_MOD3_c
dmRM_MOD3_WOP2: cmp	cl,'d'
		je	dmRM_MOD3_Ext
		cmp	cl,'W'
		je	dmRM_MOD3_c
		cmp	cl,'v'
		jne	dmRM_MOD3_PReg
dmRM_MOD3_c:	cmp	OpSize,32
		jne	dmRM_MOD3_PReg
dmRM_MOD3_Ext:	mov	di,UBufP
		inc	UBufP
		mov	byte ptr ds:[di],'e'
dmRM_MOD3_PReg: add	bx,bx
		mov	di,UBufP
		add	UBufP,2
		mov	ax,ds:RegTable16[bx]
		mov	ds:[di],ax
		jmp	dmRM_Exit

dmRM_MOD_n3:	mov	si,offset QWordPtr
		cmp	cl,'q'
		je	dmRM_MOD_n3_ptr
		cmp	cl,'b'
		mov	si,offset BytePtr
		je	dmRM_MOD_n3_ptr
		mov	si,offset WordPtr
		cmp	cl,'W'
		je	dmRM_MOD_n3_ptr
		cmp	cl,'w'
		je	dmRM_MOD_n3_ptr
		mov	si,offset DWordPtr
		cmp	cl,'d'
		je	dmRM_MOD_n3_ptr
		cmp	cl,'s'
		je	dmRM_MOD_n3_fw
		cmp	cl,'p'
		jne	dmRM_MODn3_subv

dmRM_MOD_n3_fw: cmp	OpSize,32
		jne	dmRM_MOD_n3_ptr
		mov	si,offset FWordPtr
		jmp	dmRM_MOD_n3_ptr

dmRM_MODn3_subv:cmp	OpSize,32
		je	dmRM_MOD_n3_ptr
		mov	si,offset WordPtr

dmRM_MOD_n3_ptr:mov	di,UBufP
		call	CopyStr
		mov	UBufP,di

		mov	_MOD_,ax
		mov	_RM_,bx
		push	large offset PrefixStr
		call	UA_Str
		cmp	AddrSize,32
		jne	dmRM_16
		cmp	_RM_,4
		jne	dmRM_32_C
		push	dword ptr _MOD_
		call	do_SIB
		jmp	dmRM_Exit2
dmRM_32_C:	mov	bx,_RM_
		add	bl,bl
		mov	al,byte ptr _MOD_
		or	al,al
		jz	dmRM_32_m0
		cmp	al,1
		je	dmRM_32_m1

dmRM_32_m2:	mov	di,UBufP
		mov	si,RMRegTable32[bx]
		call	CopyStr
		mov	UBufP,di
		GetDWordR edx
		mov	al,'+'
		or	ShowZero,0
		jnz	dmRM_32_m2SNum2
		or	edx,edx
		jz	dmRM_Exit2
dmRM_32_m2SNum2:or	edx,edx
		jns	dmRM_32_m2_SNum
		mov	al,'-'
		neg	edx
dmRM_32_m2_SNum:add	UBufP,9
		mov	ds:[di],al
		inc	di
		mov	cl,8
		call	PrintHex
		jmp	dmRM_Exit2

dmRM_32_m1:	mov	di,UBufP
		mov	si,RMRegTable32[bx]
		call	CopyStr
		mov	UBufP,di
		GetByteR dl
		mov	al,'+'
		or	ShowZero,0
		jnz	dmRM_m1_32SNum2
		or	dl,dl
		jz	dmRM_Exit2
dmRM_m1_32SNum2:or	dl,dl
		jns	dmRM_32_m1_SNum
		mov	al,'-'
		neg	dl
dmRM_32_m1_SNum:add	UBufP,3
		mov	ds:[di],al
		inc	di
		mov	cl,2
		call	PrintHex
		jmp	dmRM_Exit2

dmRM_32_m0:	mov	di,UBufP
		mov	si,RMRegTable32[bx]
		cmp	bl,5*2
		je	dmRM_32_m0_Addr
		call	CopyStr
		mov	UBufP,di
		jmp	dmRM_Exit2
dmRM_32_m0_Addr:add	UBufP,8
		GetDWordR edx
		mov	cl,8
		call	PrintHex
		jmp	dmRM_Exit2

dmRM_16:	mov	ax,_MOD_
		mov	bx,_RM_
		add	bl,bl
		or	al,al
		jz	dmRM_16_m0
		cmp	al,1
		je	dmRM_16_m1

dmRM_16_m2:	mov	di,UBufP
		mov	si,RMRegTable16[bx]
		call	CopyStr
		mov	UBufP,di
		mov	al,'+'
		GetWordR dx
		or	ShowZero,0
		jnz	dmRM_16_m2SNum2
		or	dx,dx
		jz	dmRM_Exit2
dmRM_16_m2SNum2:or	dx,dx
		jns	dmRM_16_m2_SNum
		mov	al,'-'
		neg	dx
dmRM_16_m2_SNum:add	UBufP,5
		mov	ds:[di],al
		inc	di
		mov	cl,4
		call	PrintHex
		jmp	dmRM_Exit2

dmRM_16_m1:	mov	di,UBufP
		mov	si,RMRegTable16[bx]
		call	CopyStr
		mov	UBufP,di
		mov	al,'+'
		GetByteR dl
		or	ShowZero,0
		jnz	dmRM_16_m1SNum2
		or	dl,dl
		jz	dmRM_Exit2
dmRM_16_m1SNum2:or	dl,dl
		jns	dmRM_16_m1_SNum
		mov	al,'-'
		neg	dl
dmRM_16_m1_SNum:add	UBufP,3
		mov	ds:[di],al
		inc	di
		mov	cl,2
		call	PrintHex
		jmp	dmRM_Exit2

dmRM_16_m0:	mov	di,UBufP
		mov	si,RMRegTable16[bx]
		cmp	bx,6*2
		je	dmRM_16_m0_Addr
		call	CopyStr
		mov	UBufP,di
		jmp	dmRM_Exit2
dmRM_16_m0_Addr:add	UBufP,4
		GetWordR dx
		mov	cl,4
		call	PrintHex

dmRM_Exit2:	mov	di,UBufP
		inc	UBufP
		mov	byte ptr ds:[di],']'
dmRM_Exit:	ret
do_modRM	EndP
; --------------------------------------------------------------------------- ;
do_SIB		Proc	Pascal Near
		ARG	_MOD_:DWORD

		call	SIB
		mov	bx,ax
		mov	si,ax

		@SCALE	al
		@INDEX	bl
		@BASE	si

		add	si,si
		add	bx,bx

		mov	dl,byte ptr _MOD_
		or	dl,dl
		jz	dSIB_m0
		cmp	dl,1
		jne	dSIB_m2

dSIB_m1:	mov	di,UBufP
		mov	si,ds:SIB_RegTable[si]
		call	CopyStr
		cmp	bl,4*2
		je	dSIB_m1_In_Done
		mov	byte ptr ds:[di],'+'
		inc	di
		mov	si,ds:SIB_RegTable[bx]
		call	CopyStr
		or	al,al
		jz	dSIB_m1_In_Done
		mov	cl,al
		mov	ah,1
		shl	ah,cl
		add	ah,'0'
		mov	al,'*'
		mov	ds:[di],ax
		lea	di,[di+2]
dSIB_m1_In_Done:mov	UBufP,di
		GetByte dl
		mov	al,'+'
		or	ShowZero,0
		jnz	dSIB_m1_SNum_2
		or	dl,dl
		jz	dSIB_Exit
dSIB_m1_SNum_2: or	dl,dl
		jns	dSIB_m1_SNum
		neg	dl
		mov	al,'-'
dSIB_m1_SNum:	mov	ds:[di],al
		inc	di
		mov	cl,2
		call	PrintHex
		mov	UBufP,di
		jmp	dSIB_Exit

dSIB_m2:	mov	di,UBufP
		mov	si,ds:SIB_RegTable[si]
		call	CopyStr
		cmp	bl,4*2
		je	dSIB_m2_In_Done
		mov	byte ptr ds:[di],'+'
		inc	di
		mov	si,ds:SIB_RegTable[bx]
		call	CopyStr
		or	al,al
		jz	dSIB_m2_In_Done
		mov	cl,al
		mov	ah,1
		shl	ah,cl
		add	ah,'0'
		mov	al,'*'
		mov	ds:[di],ax
		lea	di,[di+2]
dSIB_m2_In_Done:mov	UBufP,di
		GetDWordR edx
		mov	al,'+'
		or	ShowZero,0
		jnz	dSIB_m2_SNum_2
		or	edx,edx
		jz	dSIB_Exit
dSIB_m2_SNum_2: or	edx,edx
		jns	dSIB_m2_SNum
		neg	edx
		mov	al,'-'
dSIB_m2_SNum:	mov	ds:[di],al
		inc	di
		mov	cl,8
		call	PrintHex
		mov	UBufP,di
		jmp	dSIB_Exit

dSIB_m0:	mov	di,UBufP
		cmp	si,5*2
		mov	si,ds:SIB_RegTable[si]
		jne	dSIB_m0_Bn5
		GetDWordR edx
		or	edx,edx
		jnz	dSIB_m0_B5_SNum
		;dec	 di
		cmp	bl,4*2
		jne	dSIB_m0_Sn4_2
dSIB_m0_B5_SNum:mov	cl,8
		mov	ah,al
		call	PrintHex
		mov	al,ah
		jmp	dSIB_m0_Bx
dSIB_m0_Bn5:	call	CopyStr
dSIB_m0_Bx:	mov	UBufP,di
		cmp	bl,4*2
		je	dSIB_Exit
dSIB_m0_Sn4:	mov	byte ptr ds:[di],'+'
		inc	di
dSIB_m0_Sn4_2:	mov	si,ds:SIB_RegTable[bx]
		call	CopyStr
		or	al,al
		jz	dSIB_Exit2
		mov	cl,al
		mov	ah,1
		mov	al,'*'
		shl	ah,cl
		add	ah,'0'
		mov	ds:[di],ax
		lea	di,[di+2]
dSIB_Exit2:	mov	UBufP,di
dSIB_Exit:	ret
do_SIB		EndP
; --------------------------------------------------------------------------- ;
UA_Str		Proc	Pascal Near
		ARG	_Str:DWORD
		mov	bx,word ptr _Str
		or	bx,bx
		jz	UA_Invalid

UA_StartScan:	mov	di,UBufP
		xor	ah,ah
UA_ScanStr:	mov	al,ds:[bx]
		or	al,al
		jz	UA_Exit
		inc	bx
		mov	ds:[di],al
		inc	di
		cmp	al,'%'
		jne	UA_ScanStr
		dec	di
		mov	UBufP,di
		mov	al,ds:[bx]
		inc	bx
		push	eax
		mov	al,ds:[bx]
		inc	bx
		push	eax
		mov	word ptr _Str,bx
		call	Percent
		mov	bx,word ptr _Str
		jmp	UA_StartScan

UA_Invalid:	or	flags,1
UA_Exit:	mov	UBufP,di
		ret
UA_Str		EndP
; --------------------------------------------------------------------------- ;
UnAssemble	Proc	Pascal Near
		ARG	Sel:DWord,Offs:DWord,ROffs:DWord

		;mov	 dx,J
		mov	ax,word ptr Sel

		cld

		push	es
		mov	ax,ds
		mov	es,ax

		mov	ebx,Offs
		mov	fs,word ptr Sel

		mov	eax,Offs
		mov	ebx,ROffs
		mov	Instruction_Off,eax
		mov	Real_Offset,ebx

		xor	ax,ax
		mov	Instruction_Len,al
		mov	Prefix,al
		mov	SExt,al
		mov	flags,al

		mov	OpSize+1,al
		mov	AddrSize+1,al

		mov	al,SegSize
		mov	OpSize,al
		mov	AddrSize,al

		mov	ax,-1
		mov	modRMV,ax
		mov	SIBV,ax

		mov	Extend,2

		mov	UBufP,offset UBuf

		xor	ah,ah
		GetByte
		mov	bx,ax
		add	bx,ax
		mov	bx,_OpMap1[bx]
		or	bx,bx			; Is pointer NULL?
		jz	UnA_NULL		; If so, we don't know the op.
		push	ebx
		call	UA_Str
		test	flags,1
		jz	UnA_Exit
UnA_NULL:	mov	si,offset Illegal
		mov	di,offset UBuf
		call	CopyStr
		mov	UBufP,di

		mov	eax,Offs
		mov	ebx,ROffs
		inc	eax
		inc	ebx
		mov	Instruction_Off,eax
		mov	Real_Offset,ebx
		mov	Instruction_Len,1

UnA_Exit:	mov	di,UBufP
		mov	byte ptr ds:[di],0
		pop	es
		ret
UnAssemble	EndP
; --------------------------------------------------------------------------- ;
PrintInv	Proc	near
		mov	di,UBufP
		mov	si,offset Invalid
		call	CopyStr
		mov	UBufP,di
		ret
PrintInv	EndP
; --------------------------------------------------------------------------- ;
CopyStr 	Proc	near
		; DS:SI = Source (ES & DS must be same and DF must be clear)
		; ES:DI = Dest
		mov	cx,0FFFFh
		mov	ah,al
		xor	al,al
		xchg	si,di
		repne	scas byte ptr es:[di]
		xchg	si,di
		not	cx
		sub	si,cx
		dec	cx
		jz	CStr_Exit
		rep	movs byte ptr es:[di],ds:[si]
CStr_Exit:	mov	al,ah
		ret
CopyStr 	EndP
; --------------------------------------------------------------------------- ;
PrintHex	Proc	near
		;   EDX = Number
		;    CL = Width (# of nibbles)
		; DS:DI = Destination
		push	ebx
		mov	ebx,offset HexTable
		mov	ch,cl
		not	cl
		inc	cl
		and	cl,7
		shl	cl,2
		shl	edx,cl
PH_MainLoop:	rol	edx,4
		mov	al,dl
		and	al,0Fh
		xlat
		mov	ds:[di],al
		inc	di
		dec	ch
		jnz	PH_MainLoop
		pop	ebx
		ret
PrintHex	EndP
; --------------------------------------------------------------------------- ;
PMODE_TEXT	EndS
; =========================================================================== ;
		End
[ RETURN TO DIRECTORY ]