Metropoli BBS
VIEWER: debug.inc MODE: TEXT (LATIN1)
comment ~ ==================================================================

      Copyright (c) Adam Seychell, 1994

 You may use this source code in any way you wish provided that the
 following conditions are met;

 1) Any software what uses any part of this program must be for
    for non-profitable use.

 2)  Send me a copy of improvments you have made to the debugger.


 I have released the source in the hope it will be useful. The debugger
 source code may be used or improved by others who are interested in
 debeloping thier own. This source code is written in MASM 6.1 and by
 no means is it written neatly. If someone wants to write thier
 own debugger then best thing would be to use the instruction decode
 routine ( DEBUG.INC ) since this is a general routine for displaying
 486 instructions as a string. The rest of the debugger could be written
 in 32bit C/C++ and while still using ASM for the exception handlers.


~
;============================================================================
;
;
;         A routine that decodes an instrucion and outputs it in a string
;
;
;
;   FUNCTION:    Decode_instruction
;
;   EXPECTS:      ESI pointing to the instruction
;                 EDI pointing to the output string buffer
;
;
;
;   RETURNS:  *  EDI  pointing the the last character in the string
;                 (string also terminates with zero character).
;             *  ESI  pointing to next instruction.
;             *  If the inscruction was invalid then Carry is set and
;                ESI is unchanged, otherwise carry is clear.
;
;              [MOD_RM_flag]      = non zero if insrcuction contains a
;                                   address operand.
;                [op_seg_overide] = points segment override symbol string.
;                                   or NULL if not exsits
;      [MOD_RM_DefaultSegmentReg] = points default segment override string.
;
;
;=============================================================================




  NoOp                  EQU       99
  Symbol                EQU       100
  NULL                	EQU       0
  NULLL                	EQU       102

immediate_data          EQU       110
unsigned_full_offset    EQU       112
offset_selector         EQU       113
mod_zxreg_rm            EQU       114
reg_eax                 EQU       115
port_DX_IN              EQU       116
port_number_IN          EQU       117
port_DX_OUT             EQU       118
port_number_OUT         EQU       119

mod_reg_rm              EQU       120
mod_sreg3_rm            EQU       121
mod_sreg2_rm            EQU       122


opcode_mask_vlaues LABEL Byte

	TTTTTTTT                EQU       180
db      11111111b
	TTTTTTTw                EQU       181
db      11111110b
        TTTTTTdw                EQU       182
db      11111100b
        TTTTTTsw                EQU       183
db      11111100b
        TTTTTreg                EQU       184
db      11111000b
	TTTTTTsT                EQU       185
db      11111101b
	TTTTwreg                EQU       186
db      11110000b
	TTT_sreg2_TTT           EQU       187
db      11100111b
	TT_sreg3_TTT            EQU       188
db      11000111b
	TTTTTTdT                EQU       189
db      11111101b
	TT_CR0_reg              EQU       190
db      11000000b
	TT_DR0_reg              EQU       191
db      11000000b
	TT_TR0_reg              EQU       192
db      11000000b
	mod_TTT_rm              EQU       193
db      00111000b

the_last_T              EQU       194

REG_CL                  EQU       150
immediate_8bit          EQU       151
SetEndCharTo_W          EQU       152
full_displacement       EQU       153
Short_displacement      EQU       154
full_offset_selector    EQU       155
immediate_16bit         EQU       156
REP_prefix              EQU       157
Set_direc               EQU       158



DS_overide              EQU       200
ES_overide              EQU       201
FS_overide              EQU       202
GS_overide              EQU       203
SS_overide              EQU       204
CS_overide              EQU       205


                 The_486_Instruction_Table             LABEL BYTE
;
; I havn't check to make sure all of these intruction formats are correct,
; but  I was very carful when I typed them in.  It took me bloody days!
;

db     Symbol, 'mov   '
db     TTTTTTdw,  mod_reg_rm                     	,NULLL,NULLL
db     10001000b                                        ,NoOp,NoOp
db     TTTTTTTw,  mod_TTT_rm,  immediate_data           ,NULLL
db     11000110b,   00000000b                           ,NoOp
db     TTTTwreg,   immediate_data                       ,NULLL,NULLL
db     10110000b                                        ,NoOp,NoOp
db     TTTTTTTw,  reg_eax,  Unsigned_full_offset        ,NULLL
db     10100000b                                        ,NoOp,NoOp
db     TTTTTTTw,  Unsigned_full_offset, Reg_eax         ,NULLL
db     10100010b                                        ,NoOp,NoOp
db     TTTTTTdT,  mod_sreg3_rm                          ,NULLL,NULLL
db     10001100b                                        ,NoOp,NoOp
db     TTTTTTTT , TTTTTTdT ,TT_CR0_reg                     ,NULLL
db     00001111b, 00100000b,11000000b
db     TTTTTTTT , TTTTTTdT ,TT_DR0_reg                     ,NULLL
db     00001111b, 00100001b,11000000b
db     TTTTTTTT , TTTTTTdT ,TT_TR0_reg                     ,NULLL
db     00001111b, 00100100b,11000000b



db     Symbol, 'movsx '
db     TTTTTTTT,  TTTTTTTw, mod_zxreg_rm               ,NULLL
db     00001111b, 10111110b                             ,NoOp

db     Symbol, 'movzx '
db     TTTTTTTT,  TTTTTTTw,  mod_zxreg_rm              ,NULLL
db     00001111b, 10110110b                             ,NoOp

db     Symbol, 'push  '
db     TTTTTTTT,  mod_TTT_rm                           ,NULLL,NULLL
db     11111111b,   00110000b                           ,NoOp
db     TTTTTreg                                        ,NULLL,NULLL,NULLL
db     01010000b                                        ,NoOp,NoOp
db     TTT_sreg2_TTT                                   ,NULLL,NULLL,NULLL
db     00000110b                                        ,NoOp,NoOp
db     TTTTTTTT,  TT_sreg3_TTT                         ,NULLL,NULLL
db     00001111b,  10000000b                            ,NoOp
db     TTTTTTsT,  immediate_data                       ,NULLL,NULLL
db     01101000b                                        ,NoOp,NoOp



db     Symbol, 'pushad'
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     01100000b                                        ,NoOp,NoOp

db     Symbol, 'pop   '
db     TTTTTTTT,  mod_TTT_rm                           ,NULLL,NULLL
db     10001111b,   00000000b                           ,NoOp
db     TTTTTreg                                        ,NULLL,NULLL,NULLL
db     01011000b                                        ,NoOp,NoOp
db     TTT_sreg2_TTT                                   ,NULLL,NULLL,NULLL
db     00000111b                                        ,NoOp,NoOp
db     TTTTTTTT,  TT_sreg3_TTT                         ,NULLL,NULLL
db     00001111b,  10000001b                            ,NoOp


db     Symbol, 'popad '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     01100001b                                        ,NoOp,NoOp


db     Symbol, 'in    '
db     TTTTTTTw,  port_number_IN                       ,NULLL,NULLL
db     11100100b                                        ,NoOp,NoOp
db     TTTTTTTw,  port_DX_IN                           ,NULLL,NULLL
db     11101100b                                        ,NoOp,NoOp

db     Symbol, 'out   '
db     TTTTTTTw,  port_number_OUT                      ,NULLL,NULLL
db     11100110b                                        ,NoOp,NoOp
db     TTTTTTTw,  port_DX_OUT                          ,NULLL,NULLL
db     11101110b                                        ,NoOp,NoOp


db     Symbol, 'lea   '
db     TTTTTTTT, Set_direc,  mod_reg_rm               ,NULLL
db     10001101b                                        ,NoOp,NoOp

db     Symbol, 'lds   '
db     TTTTTTTT, Set_direc,  mod_reg_rm               ,NULLL
db     11000101b                                        ,NoOp,NoOp
db     Symbol, 'les   '
db     TTTTTTTT, Set_direc,  mod_reg_rm               ,NULLL
db     11000100b                                        ,NoOp,NoOp
db     Symbol, 'lfs   '
db     TTTTTTTT,  TTTTTTTT, Set_direc, mod_reg_rm
db     00001111b, 10110100b                             ,NoOp
db     Symbol, 'lgs   '
db     TTTTTTTT,  TTTTTTTT, Set_direc, mod_reg_rm
db     00001111b, 10110101b                             ,NoOp
db     Symbol, 'lss   '
db     TTTTTTTT,  TTTTTTTT, Set_direc, mod_reg_rm
db     00001111b, 10110010b                             ,NoOp

db     Symbol, 'clc   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     11111000b                                        ,NoOp,NoOp
db     Symbol, 'cld   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     11111100b                                        ,NoOp,NoOp
db     Symbol, 'cli   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     11111010b                                        ,NoOp,NoOp
db     Symbol, 'clts  '
db     TTTTTTTT, TTTTTTTT                              ,NULLL ,NULLL
db     00001111b,00000110b                              ,NoOp
db     Symbol, 'cmc   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     11110101b                                        ,NoOp,NoOp
db     Symbol, 'lahf  '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     10011111b                                        ,NoOp,NoOp
db     Symbol, 'popf  '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     10011101b                                        ,NoOp,NoOp
db     Symbol, 'pushf '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     10011100b                                        ,NoOp,NoOp
db     Symbol, 'sahf  '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     10011110b                                        ,NoOp,NoOp
db     Symbol, 'stc   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     11111001b                                        ,NoOp,NoOp
db     Symbol, 'std   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     11111101b                                        ,NoOp,NoOp
db     Symbol, 'sti   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     11111011b                                        ,NoOp,NoOp

db     Symbol, 'add   '
db     TTTTTTdw,  mod_reg_rm                           ,NULLL,NULLL
db     00000000b                                        ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,  immediate_data         ,NULLL
db     10000000b,   00000000b                          ,NoOp
db     TTTTTTTw, reg_eax,  immediate_data              ,NULLL
db     00000100b                                       ,NoOp,NoOp

db     Symbol, 'adc   '
db     TTTTTTdw,  mod_reg_rm                           ,NULLL,NULLL
db     00010000b                                       ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,  immediate_data         ,NULLL
db     10000000b,   00010000b                          ,NoOp
db     TTTTTTTw, reg_eax,  immediate_data              ,NULLL
db     00010100b                                       ,NoOp,NoOp

db     Symbol, 'inc   '
db     TTTTTTTw,  mod_TTT_rm                           ,NULLL,NULLL
db     11111110b,   00000000b                          ,NoOp
db     TTTTTreg                                        ,NULLL,NULLL,NULLL
db     01000000b                                       ,NoOp,NoOp

db     Symbol, 'dec   '
db     TTTTTTTw,  mod_TTT_rm                           ,NULLL,NULLL
db     11111110b,   00001000b                          ,NoOp
db     TTTTTreg                                        ,NULLL,NULLL,NULLL
db     01001000b                                       ,NoOp,NoOp

db     Symbol, 'sub   '
db     TTTTTTdw,  mod_reg_rm                           ,NULLL,NULLL
db     00101000b                                       ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,  immediate_data         ,NULLL
db     10000000b,   00101000b                          ,NoOp
db     TTTTTTTw, reg_eax,  immediate_data              ,NULLL
db     00101100b                                       ,NoOp,NoOp

db     Symbol, 'sbb   '
db     TTTTTTdw,  mod_reg_rm                           ,NULLL,NULLL
db     00011000b                                       ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,  immediate_data         ,NULLL
db     10000000b,   00011000b                          ,NoOp
db     TTTTTTTw, reg_eax,  immediate_data              ,NULLL
db     00011100b                                       ,NoOp,NoOp

db     Symbol, 'cmp   '
db     TTTTTTdw,  mod_reg_rm                           ,NULLL,NULLL
db     00111000b                                       ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,  immediate_data         ,NULLL
db     10000000b,   00111000b                          ,NoOp
db     TTTTTTTw, reg_eax,  immediate_data              ,NULLL
db     00111100b                                       ,NoOp,NoOp

db     Symbol, 'neg   '
db     TTTTTTTw,   mod_TTT_rm                          ,NULLL,NULLL
db     11110110b,    00011000b                         ,NoOp

db     Symbol, 'aaa   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     00110111b                                       ,NoOp,NoOp

db     Symbol, 'aas   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     00111111b                                       ,NoOp,NoOp

db     Symbol, 'daa   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     00100111b                                       ,NoOp,NoOp

db     Symbol, 'das   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     00101111b                                       ,NoOp,NoOp

db     Symbol, 'mul   '
db     TTTTTTTw, mod_TTT_rm                            ,NULLL,NULLL
db     11110110b,  00100000b                           ,NoOp

db     Symbol, 'imul  '
db     TTTTTTTw, mod_TTT_rm                            ,NULLL,NULLL
db     11110110b,  00101000b                           ,NoOp
db     TTTTTTTT,   TTTTTTTT, Set_direc,  mod_reg_rm
db     00001111b,  10101111b                           ,NoOp
db     TTTTTTsT,  Set_direc,   mod_reg_rm ,immediate_data
db     01101001b                                       	,NoOp,NoOp


db     Symbol, 'div   '
db     TTTTTTTw, mod_TTT_rm                            ,NULLL,NULLL
db     11110110b,  00110000b                           ,NoOp

db     Symbol, 'idiv  '
db     TTTTTTTw, mod_TTT_rm                            ,NULLL,NULLL
db     11110110b,  00111000b                           ,NoOp

db     Symbol, 'aad   '
db     TTTTTTTT,   TTTTTTTT                            ,NULLL,NULLL
db     11010101b,  00001010b                           ,NoOp

db     Symbol, 'aam   '
db     TTTTTTTT,   TTTTTTTT                            ,NULLL,NULLL
db     11010100b,  00001010b                           ,NoOp

db     Symbol, 'cwde  '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     10011000b                                       ,NoOp,NoOp

db     Symbol, 'cdq   '
db     TTTTTTTT                                        ,NULLL,NULLL,NULLL
db     10011001b                                       ,NoOp,NoOp

db     Symbol, 'rol   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00000000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00000000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00000000b                         ,NoOp

db     Symbol, 'ror   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00001000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00001000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00001000b                         ,NoOp

db     Symbol, 'rcl   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00010000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00010000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00010000b                         ,NoOp

db     Symbol, 'rcr   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00011000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00011000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00011000b                         ,NoOp

db     Symbol, 'shl   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00100000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00100000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00100000b                         ,NoOp

db     Symbol, 'shr   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00101000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00101000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00101000b                         ,NoOp

db     Symbol, 'sal   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00110000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00110000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00110000b                         ,NoOp

db     Symbol, 'sar   '
db     TTTTTTTw,   mod_TTT_rm                           ,NULLL,NULLL
db     11010000b,    00111000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , REG_CL                  ,NULLL
db     11010010b,    00111000b                         ,NoOp
db     TTTTTTTw,   mod_TTT_rm , immediate_8bit          ,NULLL
db     11000000b,    00111000b                         ,NoOp

db     Symbol, 'shld  '
db     TTTTTTTT,  TTTTTTTT, mod_reg_rm, immediate_8bit
db     00001111b, 10100100b                            ,NoOp
db     TTTTTTTT,  TTTTTTTT,  mod_reg_rm ,reg_CL
db     00001111b, 10100101b                            ,NoOp

db     Symbol, 'shrd  '
db     TTTTTTTT,  TTTTTTTT,  mod_reg_rm, immediate_8bit
db     00001111b, 10101100b                            ,NoOp
db     TTTTTTTT,  TTTTTTTT,  mod_reg_rm ,reg_CL
db     00001111b, 10101101b                            ,NoOp

db     Symbol, 'test  '
db     TTTTTTTw,  mod_reg_rm                            ,NULLL ,NULLL
db     10000100b                                       ,NoOp,NoOp
db     TTTTTTTw,  mod_TTT_rm ,immediate_data             ,NULLL
db     11110110b,   00000000b                          ,NoOp
db     TTTTTTTw,  reg_EAX    ,immediate_data             ,NULLL
db     10101000b                                       ,NoOp,NoOp

db     Symbol, 'and   '
db     TTTTTTdw,  mod_reg_rm                             ,NULLL,NULLL
db     00100000b                                       ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,immediate_data             ,NULLL
db     10000000b,   00100000b                          ,NoOp
db     TTTTTTTw,  reg_EAX    ,immediate_data             ,NULLL
db     00100100b                                       ,NoOp,NoOp


db     Symbol, 'or    '
db     TTTTTTdw,  mod_reg_rm                             ,NULLL,NULLL
db     00001000b                                       ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,immediate_data             ,NULLL
db     10000000b,   00001000b                          ,NoOp
db     TTTTTTTw,  reg_EAX    ,immediate_data             ,NULLL
db     00001100b                                       ,NoOp,NoOp

db     Symbol, 'xor   '
db     TTTTTTdw,  mod_reg_rm                             ,NULLL,NULLL
db     00110000b                                       ,NoOp,NoOp
db     TTTTTTsw,  mod_TTT_rm ,immediate_data             ,NULLL
db     10000000b,   00110000b                          ,NoOp
db     TTTTTTTw,  reg_EAX    ,immediate_data             ,NULLL
db     00110100b                                       ,NoOp,NoOp

db     Symbol, 'not   '
db     TTTTTTTw,  mod_TTT_rm                             ,NULLL,NULLL
db     11110110b,   00010000b                          ,NoOp

db     Symbol, 'cmps  '
db     TTTTTTTw  ,SetEndCharTo_W                          ,NULLL,NULLL
db     10100110b                                       ,NoOp,NoOp

db     Symbol, 'ins   '
db     TTTTTTTw  ,SetEndCharTo_W                          ,NULLL,NULLL
db     01101100b                                       ,NoOp,NoOp

db     Symbol, 'lods  '
db     TTTTTTTw  ,SetEndCharTo_W                          ,NULLL,NULLL
db     10101100b                                       ,NoOp,NoOp

db     Symbol, 'movs  '
db     TTTTTTTw  ,SetEndCharTo_W                          ,NULLL,NULLL
db     10100100b                                       ,NoOp,NoOp

db     Symbol, 'outs  '
db     TTTTTTTw  ,SetEndCharTo_W                          ,NULLL,NULLL
db     01101110b                                       ,NoOp,NoOp

db     Symbol, 'scas  '
db     TTTTTTTw  ,SetEndCharTo_W                          ,NULLL,NULLL
db     10101110b                                       ,NoOp,NoOp

db     Symbol, 'stos  '
db     TTTTTTTw  ,SetEndCharTo_W                          ,NULLL,NULLL
db     10101010b                                       ,NoOp,NoOp

db     Symbol, 'xlat  '
db     TTTTTTTT                                           ,NULLL,NULLL,NULLL
db     11010111b                                       ,NoOp,NoOp

;  -----------------  Bit manipulation ------------------------
db     Symbol, 'bsf   '
db     TTTTTTTT , TTTTTTTT, Set_direc,  mod_reg_rm
db     00001111b, 10111100b                            ,NoOp

db     Symbol, 'bsr   '
db     TTTTTTTT , TTTTTTTT, Set_direc,  mod_reg_rm
db     00001111b, 10111101b                            ,NoOp

db     Symbol, 'bt    '
db     TTTTTTTT , TTTTTTTT,   mod_TTT_rm, immediate_8bit
db     00001111b, 10111010b,    00100000b
db     TTTTTTTT , TTTTTTTT,   mod_reg_rm                  ,NULLL
db     00001111b, 10100011b                             ,NoOp

db     Symbol, 'btc   '
db     TTTTTTTT , TTTTTTTT,   mod_TTT_rm, immediate_8bit
db     00001111b, 10111010b,    00111000b
db     TTTTTTTT , TTTTTTTT,   mod_reg_rm                  ,NULLL
db     00001111b, 10111011b                             ,NoOp

db     Symbol, 'btr   '
db     TTTTTTTT , TTTTTTTT,   mod_TTT_rm, immediate_8bit
db     00001111b, 10111010b,    00110000b
db     TTTTTTTT , TTTTTTTT,   mod_reg_rm                  ,NULLL
db     00001111b, 10110011b                              ,NoOp

db     Symbol, 'bts   '
db     TTTTTTTT , TTTTTTTT,   mod_TTT_rm, immediate_8bit
db     00001111b, 10111010b,    00101000b
db     TTTTTTTT , TTTTTTTT,   mod_reg_rm                  ,NULLL
db     00001111b, 10101011b                              ,NoOp


;  -----------------  Controll Transfer ------------------------
db     Symbol, 'call  '
db     TTTTTTTT , full_displacement                       ,NULLL,NULLL
db     11101000b                                       ,NoOp,NoOp
db     TTTTTTTT , mod_TTT_rm                              ,NULLL,NULLL
db     11111111b,   00010000b                          ,NoOp
db     TTTTTTTT , full_offset_selector                    ,NULLL,NULLL
db     10011010b                                       ,NoOp,NoOp

db     Symbol, 'call f'
db     TTTTTTTT ,  mod_TTT_rm                             ,NULLL,NULLL
db     11111111b,    00011000b                         ,NoOp


db     Symbol, 'jmp   '
db     TTTTTTTT , Short_displacement                      ,NULLL,NULLL
db     11101011b                                       ,NoOp,NoOp
db     TTTTTTTT , full_displacement                       ,NULLL,NULLL
db     11101001b                                       ,NoOp,NoOp
db     TTTTTTTT , mod_TTT_rm                              ,NULLL,NULLL
db     11111111b,   00100000b                          ,NoOp
db     TTTTTTTT , full_offset_selector                    ,NULLL,NULLL
db     11101010b                                       ,NoOp,NoOp

db     Symbol, 'jmp  f'
db     TTTTTTTT ,  mod_TTT_rm                             ,NULLL,NULLL
db     11111111b,    00101000b                         ,NoOp

db     Symbol, 'ret   '
db     TTTTTTTT                                           ,NULLL,NULLL,NULLL
db     11000011b                                       ,NoOp,NoOp
db     TTTTTTTT ,  immediate_16bit                        ,NULLL,NULLL
db     11000010b                                       ,NoOp,NoOp

db     Symbol, 'ret  f'
db     TTTTTTTT                                           ,NULLL,NULLL,NULLL
db     11001011b                                       ,NoOp,NoOp
db     TTTTTTTT ,  immediate_16bit                        ,NULLL,NULLL
db     11001010b                                       ,NoOp,NoOp


db     Symbol, 'jo    '
db     TTTTTTTT ,   Short_displacement                    ,NULLL,NULLL
db     01110000b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10000000b                            ,NoOp
db     Symbol, 'jno   '
db     TTTTTTTT ,   Short_displacement                    ,NULLL,NULLL
db     01110001b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement            ,NULLL
db     00001111b, 10000001b                            ,NoOp


db     Symbol, 'jb    '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01110010b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10000010b                            ,NoOp
db     Symbol, 'jae   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01110011b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10000011b                            ,NoOp



db     Symbol, 'jz    '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01110100b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10000100b                            ,NoOp
db     Symbol, 'jnz   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01110101b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10000101b                            ,NoOp


db     Symbol, 'jbe   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01110110b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10000110b                            ,NoOp
db     Symbol, 'ja    '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01110111b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10000111b                            ,NoOp


db     Symbol, 'js    '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111000b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001000b                            ,NoOp
db     Symbol, 'jns   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111001b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001001b                            ,NoOp

db     Symbol, 'jpe   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111010b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001010b                            ,NoOp
db     Symbol, 'jno   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111011b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001011b                            ,NoOp

db     Symbol, 'jl    '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111100b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001100b                            ,NoOp
db     Symbol, 'jge   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111101b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001101b                            ,NoOp

db     Symbol, 'jle   '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111110b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001110b                            ,NoOp
db     Symbol, 'jg    '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     01111111b                                       ,NoOp,NoOp
db     TTTTTTTT , TTTTTTTT,  full_displacement             ,NULLL
db     00001111b, 10001111b                            ,NoOp

db     Symbol, 'jecxz '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     11100011b                                       ,NoOp,NoOp

db     Symbol, 'loopnz'
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     11100000b                                       ,NoOp,NoOp
db     Symbol, 'loop  '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     11100010b                                       ,NoOp,NoOp
db     Symbol, 'loopz '
db     TTTTTTTT ,   Short_displacement                     ,NULLL,NULLL
db     11100001b                                       ,NoOp,NoOp


;-------------- conditional byte set ------------------------
db     Symbol, 'seto  '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010000b,   00000000b
db     Symbol, 'setno '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010001b,   00000000b
db     Symbol, 'setb  '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010010b,   00000000b
db     Symbol, 'setae '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010011b,   00000000b
db     Symbol, 'setz  '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010100b,   00000000b
db     Symbol, 'setnz '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010101b,   00000000b
db     Symbol, 'setbe '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010110b,   00000000b
db     Symbol, 'seta  '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10010111b,   00000000b
db     Symbol, 'sets  '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011000b,   00000000b
db     Symbol, 'setns '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011001b,   00000000b
db     Symbol, 'setpe '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011010b,   00000000b
db     Symbol, 'setpo '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011011b,   00000000b
db     Symbol, 'setl  '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011100b,   00000000b
db     Symbol, 'setge '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011101b,   00000000b
db     Symbol, 'setle '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011110b,   00000000b
db     Symbol, 'setg  '
db     TTTTTTTT , TTTTTTTT,  mod_TTT_rm                    ,NULLL
db     00001111b, 10011111b,   00000000b

db     Symbol, 'enter '
db     TTTTTTTT , immediate_16bit ,immediate_8bit          ,NULLL
db     11001000b                                        ,NoOp,NoOp

db     Symbol, 'leave '
db     TTTTTTTT                                            ,NULLL,NULLL,NULLL
db     11001001b                                        ,NoOp,NoOp

db     Symbol, 'int   '
db     TTTTTTTT , immediate_8bit                           ,NULLL,NULLL
db     11001101b                                        ,NoOp,NoOp
db     Symbol, 'INTĂș3 '
db     TTTTTTTT                                            ,NULLL,NULLL,NULLL
db     11001100b                                        ,NoOp,NoOp
db     Symbol, 'into  '
db     TTTTTTTT                                            ,NULLL,NULLL,NULLL
db     11001110b                                        ,NoOp,NoOp
db     Symbol, 'bound '
db     TTTTTTTT    , Set_Direc,  mod_reg_rm                ,NULLL
db     01100010b                                        ,NoOp,NoOp

db     Symbol, 'iret  '
db     TTTTTTTT    , SetEndCharTo_W                        ,NULLL,NULLL
db     11001111b                                        ,NoOp,NoOp

db     Symbol, 'hlt   '
db     TTTTTTTT                                            ,NULLL,NULLL,NULLL
db     11110100b                                        ,NoOp,NoOp

db     Symbol, 'nop   '
db     TTTTTTTT                                            ,NULLL,NULLL,NULLL
db     10010000b                                        ,NoOp,NoOp

db     Symbol, 'wait  '
db     TTTTTTTT                                            ,NULLL,NULLL,NULLL
db     10011011b                                        ,NoOp,NoOp

db     Symbol, 'arpl  '
db     TTTTTTTT , mod_reg_rm                               ,NULLL,NULLL
db     01100011b                                        ,NoOp,NoOp
db     Symbol, 'lar   '
db     TTTTTTTT , TTTTTTTT ,Set_Direc,  mod_reg_rm
db     00001111b, 00000010b                             ,NoOp
db     Symbol, 'lgdt  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000001b,  00010000b
db     Symbol, 'lidt  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000001b,  00011000b
db     Symbol, 'lldt  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000000b,  00010000b
db     Symbol, 'lmsw  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000001b,  00110000b
db     Symbol, 'lsl   '
db     TTTTTTTT , TTTTTTTT ,Set_Direc,  mod_reg_rm
db     00001111b, 00000011b                             ,NoOp
db     Symbol, 'ltr   '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000000b,  00011000b
db     Symbol, 'sgdt  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000001b,  00000000b
db     Symbol, 'sidt  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000001b,  00001000b
db     Symbol, 'sldt  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000000b,  00000000b
db     Symbol, 'smsw  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000001b,  00100000b
db     Symbol, 'str   '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000000b,  00001000b
db     Symbol, 'verr  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000000b,  00100000b
db     Symbol, 'verw  '
db     TTTTTTTT , TTTTTTTT ,mod_TTT_rm                     ,NULLL
db     00001111b, 00000000b,  00101000b

db     Symbol, 'xchg  '
db     TTTTTTTw,  mod_reg_rm                           ,NULLL,NULLL
db     10000110b                                        ,NoOp,NoOp
db     TTTTTreg,   reg_eax                             ,NULLL,NULLL
db     10010000b                                        ,NoOp,NoOp

;------------- 486 instuctions -----------------------
db     Symbol, 'bswap '
db     TTTTTTTT, TTTTTreg                              ,NULLL,NULLL
db     00001111b,11001000b                              ,NoOp

db     Symbol, 'xadd  '
db     TTTTTTTT,  TTTTTTTw,  mod_reg_rm                 ,NULLL
db     00001111b, 11000000b                             ,NoOp

db     Symbol, 'cmpxch'
db     TTTTTTTT,  TTTTTTTw,  mod_reg_rm                 ,NULLL
db     00001111b, 10110000b                             ,NoOp

;--------------- Floting Point Processor Instuctions ----------------


Instruction_Definitions_End             EQU   $







mod_rm_16bit        LABEL   BYTE
db 'bx+si$  '
db 'bx+di$  '
db 'bp+si$  '
db 'bp+di$  '
db 'si$     '
db 'di$     '
db 'bp$     '
db 'bx$     '

EAX_symb        db 'eax$'
ECX_symb        db 'ecx$'
EDX_symb        db 'edx$'
EBX_symb        db 'ebx$'
ESP_symb        db 'esp$'
EBP_symb        db 'ebp$'
ESI_symb        db 'esi$'
EDI_symb        db 'edi$'
EIP_symb        db 'eip$'

al_symb        db 'al$ '
cl_symb        db 'cl$ '
dl_symb        db 'dl$ '
bl_symb        db 'bl$ '
ah_symb        db 'ah$ '
ch_symb        db 'ch$ '
dh_symb        db 'dh$ '
bh_symb        db 'bh$ '

ES_symb        db 'es$ '
CS_symb        db 'cs$ '
SS_symb        db 'ss$ '
DS_symb        db 'ds$ '
FS_symb        db 'fs$ '
GS_symb        db 'gs$ '
               db '??$ '
               db '??$ '

REPNZ_symb     db 'repnz $'
REPZ_symb      db 'rep   $'
FAR_symb       db 'ar   $'
byte_ptr_symb  db 'byte ptr $'
word_ptr_symb  db 'word ptr $'
CR0_symb       db 'CR0$'
CR1_symb       db 'CR1$'
CR2_symb       db 'CR2$'
CR3_symb       db 'CR3$'
CR4_symb       db 'CR4$'
CR5_symb       db 'CR5$'
CR6_symb       db 'CR6$'
CR7_symb       db 'CR7$'

DR0_symb       db 'DR0$'
DR1_symb       db 'DR1$'
DR2_symb       db 'DR2$'
DR3_symb       db 'DR3$'
DR4_symb       db 'DR4$'
DR5_symb       db 'DR5$'
DR6_symb       db 'DR6$'
DR7_symb       db 'DR7$'

TR0_symb       db 'TR0$'
TR1_symb       db 'TR1$'
TR2_symb       db 'TR2$'
TR3_symb       db 'TR3$'
TR4_symb       db 'TR4$'
TR5_symb       db 'TR5$'
TR6_symb       db 'TR6$'
TR7_symb       db 'TR7$'
instruc_CBW    db 'cbw   $'
instruc_CWD    db 'cwd   $'

op_seg_overide  	dd 0
reg_size        	db 0
op_direc        	db 0
op_sine         	db 0
op_was_done     	db 0
force_16bitReg    	db 0
addr_size_prefix  	db 0
op_size_prefix  	db 0
StringBufferPTR           dd 0
char_position   	db 0




Decode_instruction PROC PRIVATE USES EAX EBX ECX EDX
LOCAL   THE_symbol,old_ESI      :dword
local   format_ends             :Dword



        cld
        mov     StringBufferPTR,edi
        mov     char_position,0
        mov     op_seg_overide,NULL
        mov 	addr_size_prefix,0
        mov     op_size_prefix,0
        mov     op_was_done,0
        mov     reg_size,1
        mov     op_direc,0
        mov     force_16bitreg,0
        mov     op_sine,0
        mov     old_ESI,esi
        mov      MOD_RM_flag,False
        mov     MOD_RM_EffectiveAddress,0
        mov  	MOD_RM_size,2
        mov     MOD_RM_SegmentReg,00111110b
        mov     MOD_RM_DefaultSegmentReg,offset DS_symb

        mov  ecx,5

prefix_find_loop:
        ;------------- Get segment overide prefixes ---------
        mov     al,[esi]
        .if     al == 00101110b
                mov     op_seg_overide,offset CS_symb
                mov     MOD_RM_SegmentReg,al
        .elseif al == 00111110b
                mov     op_seg_overide,offset DS_symb
                mov     MOD_RM_SegmentReg,al
        .elseif al == 00100110b
                mov     op_seg_overide,offset ES_symb
                mov     MOD_RM_SegmentReg,al
        .elseif al == 01100100b
                mov     op_seg_overide,offset FS_symb
                mov     MOD_RM_SegmentReg,al
        .elseif al == 01100101b
                mov     op_seg_overide,offset GS_symb
                mov     MOD_RM_SegmentReg,al
        .elseif al == 00110110b
                mov     op_seg_overide,offset SS_symb
                mov     MOD_RM_SegmentReg,al
        .else
          dec esi
        .endif
          inc  esi
        ;------------ plot REPNZ/REPZ pefixes ------------
        .if     al == 11110010b
                mov     edx,offset REPNZ_symb
                call    string
                inc     esi
        .elseif al == 11110011b
                mov     edx,offset REPZ_symb
                call    string
                inc     esi
        .endif

        ;------------ get size prefixes -------------------
        mov     al,[esi]
        .if     al == 01100111b
            mov    addr_size_prefix,1
            inc    esi
        .elseif al == 01100110b
            mov    op_size_prefix,1
            inc    esi
        .endif
        dec     ecx
        jnz prefix_find_loop


        ;---------- get the instruction ------------

        mov     edi,offset The_486_Instruction_Table
        xor    ebx,ebx
Find_What_Loop:
        .if      edi == Instruction_Definitions_End
                mov    al,'?'
                call   Print_char
                mov     esi,old_ESI
                inc     esi
                movzx   edi,char_position
                add     edi,StringBufferPTR
                mov     byte ptr [edi],0
                stc
                ret
        .endif

        .if     byte ptr [edi] == Symbol
                inc     edi
	        mov     THE_symbol,edi
                add     edi,6
        .endif
         push    edi
         push    esi
CheckInstr_Loop:
         mov    al,[esi]
         mov    BL,[edi]
         sub    bl,TTTTTTTT
         cmp    bl  ,( the_last_T - TTTTTTTT)
         jae finished_it
          and     al,opcode_mask_vlaues[ebx] ; mask the instruction opcode
          cmp     al,[edi+4]                 ; compare with the opcode
          jne contSrch_
        inc     edi                     ; instruction table pointer
        inc     esi                     ; instruction pointer
        jmp checkInstr_Loop

contSrch_: pop     esi
           pop     edi
contSrch:  add    edi,7
           jmp     Find_What_Loop



finished_it:                   ; finishe searching instruction
        pop     esi
        pop     edi
        cmp  byte ptr [esi],0fh
        jne @f
        cmp  byte ptr [edi+1],NULLL
        je contSrch
@@:

;===============================================


        ;--------- plot the instuction symbol on the screen ---------
        push    esi
        mov     esi,THE_symbol

    .IF op_size_prefix == 1
      .IF   dword ptr [esi] == ' qdc'
          mov  edx,offset instruc_CWD
          call   string
          jmp InstPrnted
       .ELSEIF  dword ptr [esi] == 'edwc'
          mov  edx,offset instruc_CBW
          call   string
          jmp InstPrnted
      .ENDIF
    .ENDIF

        mov     ecx,6
        .Repeat
             lodsb
             call    Print_Char
        .UntilCXZ
        .if  byte ptr [edi-1] == 'f'
            mov  edx,offset far_symb
            call   string
            mov MOD_RM_size,3
        .endif
InstPrnted:
        pop     esi

                ; EDI = OFFSET OF THE INSTRUC NULLL

        mov     format_ends,edi
        add     format_ends,4



Operand_decode_loop:
        ;---------- decode the operands ---------------------
        mov     al,[esi]
        mov     bl,[edi]

        .IF     BL   ==      TTTTTTTw
                and     al,1
                mov     reg_size,al
        .ELSEIF BL   ==      TTTTTreg
                call Plot_reg_field

        .ELSEIF BL   ==      TTTTTTdw
                mov     reg_size,al
                and     reg_size,1
                shr     al,1
                and     al,1
                mov     op_direc,al
        .ELSEIF BL   ==      TTTTTTdT
                shr     al,1
                and     al,1
                mov     op_direc,al
        .ELSEIF BL   ==      Set_direc
                mov     op_direc,1
                dec     esi
        .ELSEIF BL   ==      TTTTwreg
                shr     al,3
                and     al,1
                mov     reg_size,al
                mov     al,[esi]
                call Plot_reg_field

        .ELSEIF BL   ==      TTTTTTsT
                shr     al,1
                and     al,1
                mov     op_sine,al

        .ELSEIF BL   ==      TTTTTTsw
                mov     reg_size,al
                and     reg_size,1
                shr     al,1
                and     al,1
                mov     op_sine,al
        .ELSEIF BL   ==      REG_CL
                                call    Print_comma
                                mov     edx,offset CL_symb
                                call string
                                DEC  ESI
        .ELSEIF BL   ==      REG_EAX
                        	call    Print_comma
                        	xor al,al
                        	call Plot_reg_field
                                DEC  ESI
        .ELSEIF BL   ==      SetEndCharTo_W
                               DEC  ESI

                               sub     char_position,2
                               mov al,'b'
                              .if reg_size == 1
                                     .if op_size_prefix == 1
                                       mov al,'w'
                                         .if  byte ptr [esi] == 11001111b
                                          mov al,' '
                                         .endif
                                      .else
                                        mov al,'d'
                                      .endif
                              .endif
                                call    print_char
                                inc     char_position
                              .if op_seg_overide != NULL
                                 mov edx,op_seg_overide
                                 call string
                                 mov  al,':'
                                 call print_char
                              .endif

        .ELSEIF BL   ==      TT_sreg3_TTT
                           	shr  al,3
                           	call Plot_Sreg_field

        .ELSEIF BL   ==      TTT_sreg2_TTT
                           	shr  al,3
                           	and  al,3
                           	call Plot_Sreg_field
        .ELSEIF BL   ==      port_number_IN
                                xor     eax,eax
                                call Plot_reg_field
                                call    Print_comma
                                mov     eax,[esi]
                                call    hex_byte
        .ELSEIF BL   ==      port_number_OUT
                                mov     eax,[esi]
                                call    hex_byte
                                mov     al,','
                                call    Print_char
                                xor     eax,eax
                                call Plot_reg_field
        .ELSEIF BL   ==      port_DX_OUT
                                mov     edx,offset EDX_symb+1
                                call    String
                                mov     al,','
                                call    Print_char
                                xor     eax,eax
                                call Plot_reg_field
                                dec     esi
        .ELSEIF BL   ==      port_DX_IN
                                xor     eax,eax
                                call Plot_reg_field
                                mov     al,','
                                call    Print_char
                                mov     edx,offset EDX_symb+1
                                call    String
                                dec     esi
        .ELSEIF BL   ==      mod_zxreg_rm
                        shr     al,3
	                mov     bl,reg_size
	                mov     reg_size,1
        	        call    Plot_reg_field
                        call    Print_comma
                       .if bl == 1
                        mov   force_16bitreg,1
                         mov  edx,offset word_ptr_symb
                       .else
                         mov  edx,offset byte_ptr_symb
                       .endif
                        shr     al,3
                        .if al != 11b
                          call  string
                        .endif
                        mov     reg_size,0
                        call    extract_mod_rm


        .ELSEIF BL   ==      mod_TTT_rm
                call    extract_mod_rm

        .ELSEIF BL   ==      mod_reg_rm
                         .if op_direc == 1
                                shr    al,3
                                call Plot_reg_field
                                mov     al,','
                                call    print_char
                                call    extract_mod_rm
                         .else
                                push    esi
                                call    extract_mod_rm
                                mov     edx,esi
                                pop     esi
                                mov     al,','
                                call    print_char
                                mov     al,[esi]
                                shr    al,3
                                call Plot_reg_field
                                mov     esi,edx
                         .endif
        .ELSEIF  BL == mod_sreg3_rm
                         mov    force_16bitreg,1
                         .if op_direc == 1
                                shr    al,3
                                call Plot_Sreg_field
                                mov     al,','
                                call    print_char
                                call    extract_mod_rm
                         .else
                                push    esi
                                call    extract_mod_rm
                                mov     edx,esi
                                pop     esi
                                mov     al,','
                                call    print_char
                                mov     al,[esi]
                                shr    al,3
                                call Plot_Sreg_field
                                mov     esi,edx
                         .endif
        .ELSEIF  BL == TT_CR0_reg
                         mov     edx,offset CR0_symb
                         call    plot_special_register
        .ELSEIF  BL == TT_DR0_reg
                         mov     edx,offset DR0_symb
                         call    plot_special_register
        .ELSEIF  BL == TT_TR0_reg
                         mov     edx,offset TR0_symb
                         call    plot_special_register


        .ELSEIF  BL == full_displacement
                         mov    eax,[esi]
                         add    eax,esi
                         add    eax,4
                         call    hex_dword
                      	  add    esi,3

        .ELSEIF  BL == Short_displacement
                         movsx  eax,byte ptr [esi]
                         add    eax,esi
                         inc    eax
                         call   hex_dword

        .ELSEIF  BL == full_offset_selector
                         mov    ax,[esi+4]
                         call   hex_word
                         mov    al,':'
                         call   print_char
                         mov    eax,[esi]
                         call    hex_dword
                         add    esi,5

        .ELSEIF  BL == unsigned_full_offset
	                call    Print_comma
                        mov     op_was_done,1
                        call    plot_seg_reg
	                mov     al,'['
                        call    print_char
                        mov     eax,[esi]
                      .if addr_size_prefix == 1
                         movsx  eax,ax
                         add    MOD_RM_EffectiveAddress,eax
                         call  hex_dword
                         inc   esi
                      .else
                         add    MOD_RM_EffectiveAddress,eax
                         call  hex_dword
                         add    esi,3
                      .endif
                        mov     al,']'
                        call    print_char
                        mov     MOD_RM_flag,True

        .ELSEIF  BL == immediate_8bit
                call    Print_comma
                mov     op_was_done,1
                mov     al,[esi]
                call	hex_byte

        .ELSEIF  BL == immediate_16bit
                call    Print_comma
                mov     op_was_done,1
                mov     eax,[esi]
                call    hex_word
                inc     ESI

        .ELSEIF  BL == immediate_data
                call    Print_comma
                mov      eax,[esi]
               .if op_sine == 1
                    movsx      eax,byte ptr [esi]
                   .if op_size_prefix == 1
                      call  hex_word
                   .else
                      call  hex_dword
                   .endif
               .elseif  reg_size == 1
                  .if op_size_prefix == 1
                     call  hex_word
                     add   esi,1
                   .else
                     call hex_dword
                     add   esi,3
                   .endif
               .else
                 call hex_byte
               .endif
                call    Set_OP_size_flag
        .ENDIF

        inc     edi
        inc     esi
        cmp     byte ptr [edi],NULLL
        je exit
        cmp     edi,format_ends
        jb   Operand_decode_loop
exit:   movzx   edi,char_position
        add     edi,StringBufferPTR
        mov     byte ptr [edi],0
        clc
        ret



Decode_instruction ENDP



;======================================================================
;
; PLOTS A COMMA ON IF NEEDS TO
;
;======================================================================
Print_comma PROC PRIVATE USES EAX
                .if op_was_done == 1
                  mov     al,','
                  call    print_char
               .endif
                ret
Print_comma ENDP

;======================================================================
;
; PLOTS A SPECIAL CPU REGISTER    ( EXPECTS edx -> REGISTER TABLE )
;
;======================================================================
plot_special_register PROC PRIVATE
      .if op_direc == 1
        and     al,00111000B
        shr     al,1
        movzx   eax,al
        add     edx,eax
        call    String
        mov     al,','
        call    print_char
        mov     al,[esi]
        call    Plot_reg_field
     .else
        call Plot_reg_field
        call    print_comma
        and     al,00111000B
        shr     al,1
        movzx   eax,al
        add     edx,eax
        call    String
      .endif
        ret
plot_special_register ENDP

;======================================================================
;
; PLOTS A REGISTER of AL given it's "reg_size"
;
;======================================================================
Plot_reg_field PROC PRIVATE USES EDX EAX
        mov 	op_was_done,1
	and    al,7
        movzx  edx,al
        shl    edx,2
        .if force_16bitreg != 1
 	       .if  reg_size == 1
                   add     edx,offset EAX_symb
	          .if op_size_prefix == 1
                     inc  edx
	          .endif
                .else
                   add     edx,offset AL_symb
	        .endif
        .else
           add     edx,offset EAX_symb+1
        .endif
        call   string
        call    Set_OP_size_flag
        ret
Plot_reg_field  ENDP


;=======================================================================
Set_OP_size_flag        PROC PRIVATE
        .if force_16bitreg != 1
               .if  reg_size == 1
                  .if op_size_prefix == 1
                    mov  MOD_RM_size,1
                  .endif
              .else
                    mov  MOD_RM_size,0
              .endif
        .else
           mov  MOD_RM_size,1
        .endif
        ret
Set_OP_size_flag ENDP

;======================================================================
;
; PLOTS A SEGMENT REGISTER of AL
;
;======================================================================
Plot_Sreg_field PROC PRIVATE USES EDX EAX
        mov     op_was_done,1
	and    al,7
        movzx  edx,al
        shl    edx,2
        add    edx,offset ES_symb
        call   string
        mov  MOD_RM_size,1
        ret
Plot_Sreg_field  ENDP

;=======================================================================
Extract_mod_rm PROC PRIVATE
        .if addr_size_prefix == 1
          call Extract16bit_mod_rm
        .else
          call Extract32bit_mod_rm
        .endif
        call    Set_OP_size_flag
         ret
Extract_mod_rm ENDP




;=======================================================================
;
;   plots the data for the 32bit mod r/m
;
; Expects:  esi -> instruction.
; Returns:  esi -> end byte of address field.
;=======================================================================
Extract32bit_mod_rm PROC PRIVATE USES EDX EAX
LOCAL   op_rm     :byte
LOCAL   op_mod    :byte
LOCAL   sib_base  :byte
LOCAL   sib_index :byte
LOCAL   sib_scale :byte

                mov     op_was_done,1
                mov     al,[esi]
                mov     op_rm,al
                and     op_rm,7
                shr     al,6
                mov     op_mod,al


                .if     op_mod  == 11b
                        mov     al,op_rm
                        call    Plot_reg_field

                .elseif op_rm  != 100b

                        mov     MOD_RM_flag,True
                        call    plot_seg_reg
                        mov     al,'['
                        call    Print_char

                        .if  op_rm == 101b
                         .if     op_mod == 00b
                             jmp @f
                         .endif
                          mov     MOD_RM_DefaultSegmentReg,offset SS_symb
                          mov     MOD_RM_SegmentReg,00110110b
                        .endif

                        mov    al,op_rm
        	        and    al,7
        	        movzx  edx,al
                        shl    edx,2
                        mov     eax,registers_save.prg_eax[edx]
                        add     MOD_RM_EffectiveAddress,eax
                        add     edx,offset EAX_symb
                        call   string
                          mov     al,'+'
                        .if   op_mod == 01b
                          call    print_char
                          inc   esi
                          movsx   eax,byte ptr [esi]
                          add     MOD_RM_EffectiveAddress,eax
                          call   hex_dword
                        .elseif op_mod == 10b
                          call    print_char
@@:                       mov   eax,[esi+1]
                          add     MOD_RM_EffectiveAddress,eax
                          call  hex_dword
                          add   esi,4
                        .endif

                        mov     al,']'
                        call    Print_char

                .ELSE   ;=================  S-I-B  ===========

                        mov      MOD_RM_flag,True
                        inc     esi
                        mov     al,[esi]
                        mov     sib_base,al
                        and     sib_base,7
                        shr     al,3
                        mov     sib_index,al
                        and     sib_index,7
                        shr     al,3
                        mov     sib_scale,al

                        call    plot_seg_reg
                        mov     al,'['
                        call    Print_char



                        .if  sib_base == 101b
                          .if     op_mod == 00b
                             mov eax,[esi+1]
                             add     MOD_RM_EffectiveAddress,eax
                             call  hex_dword
                             add   esi,4
                             jmp @F
                          .endif
                          mov     MOD_RM_DefaultSegmentReg,offset SS_symb
                          mov     MOD_RM_SegmentReg,00110110b
                         .endif

                        .if  sib_base == 100b
                         mov     MOD_RM_DefaultSegmentReg,offset SS_symb
                          mov     MOD_RM_SegmentReg,00110110b
                        .endif

                         ;--------- plot base -------
                         movzx  edx,sib_base
                         shl    edx,2
                         mov     eax,registers_save.prg_eax[edx]
                         add     MOD_RM_EffectiveAddress,eax
                         add    edx,offset EAX_symb
                         call   string
@@:
                         ;--------- plot sacled index -------
                        .if sib_index != 100b
                                mov  al,'+'
                                call print_char
                               .if sib_scale !=0
                                        mov  al,1
	                                mov  cl,sib_scale
	                                shl  al,cl
	                                add  al,'0'
	                                call print_char
                                        mov  al,'*'
	                                call print_char
	                         .endif
                                 movzx  edx,sib_index
	                         shl    edx,2
                                 mov     eax,registers_save.prg_eax[edx]
                                 mov   cl,sib_scale
                                 shl   eax,cl
        	                 add     MOD_RM_EffectiveAddress,eax
                                 add    edx,offset EAX_symb
                                 call   string
                        .endif
                         ;--------- plot displacement -------
                         mov  al,'+'
                        .if   op_mod == 01b
                          call print_char
                          inc   esi
                          movsx  eax,byte ptr [esi]
                          add     MOD_RM_EffectiveAddress,eax
                          call  hex_dword
                        .elseif op_mod == 10b
                          call print_char
                          mov  eax,[esi+1]
                          add     MOD_RM_EffectiveAddress,eax
                          call  hex_dword
                          add   esi,4
                        .endif

	                mov     al,']'
	                call    Print_char
                .endif

        ret
Extract32bit_mod_rm ENDP

;=======================================================================0
;
;   plots the data for the 16bit mod r/m
;
; Expects:  esi -> instruction.
; Returns:  esi -> end byte of address field.
;=======================================================================0
Extract16bit_mod_rm PROC PRIVATE USES EDX EAX
LOCAL   op_rm     :byte
LOCAL   op_mod    :byte
                mov     op_was_done,1
                mov     al,[esi]
                mov     op_rm,al
                and     op_rm,7
                shr     al,6
                mov     op_mod,al
                .IF     op_mod  == 11b
                       ;========== rm = register ===================
                        mov     al,op_rm
                        call    Plot_reg_field

                .ELSE  ;========== rm = memory ===================
                        mov      MOD_RM_flag,True
                        call    plot_seg_reg
                        mov     al,'['
                        call    Print_char

                        .if  op_rm == 110b
                          .if     op_mod == 00b
                             jmp @f
                          .endif
                          mov     MOD_RM_DefaultSegmentReg,offset SS_symb
                          mov     MOD_RM_SegmentReg,00110110b
                        .endif

                        .if  op_rm == 011b
                         mov     MOD_RM_DefaultSegmentReg,offset SS_symb
                          mov     MOD_RM_SegmentReg,00110110b
                        .elseif op_rm == 010b
                         mov     MOD_RM_DefaultSegmentReg,offset SS_symb
                         mov     MOD_RM_SegmentReg,00110110b
                        .endif

                        mov    al,op_rm
        	        and    al,7
                        movzx  edx,al
                        .if al == 0
                           mov     eax,registers_save.prg_ebx
                           add     eax,registers_save.prg_esi
                        .elseif al == 1
                           mov     eax,registers_save.prg_EBX
                           add     eax,registers_save.prg_EDI
                        .elseif al == 2
                           mov     eax,registers_save.prg_EBP
                           add     eax,registers_save.prg_ESI
                        .elseif al == 3
                           mov     eax,registers_save.prg_EBP
                           add     eax,registers_save.prg_EDI
                        .elseif al == 4
                           mov     eax,registers_save.prg_ESI
                        .elseif al == 5
                           mov     eax,registers_save.prg_EDI
                        .elseif al == 6
                           mov     eax,registers_save.prg_EBP
                        .elseif al == 7
                           mov     eax,registers_save.prg_EBX
                        .endif
                        movsx   eax,ax
                        add     MOD_RM_EffectiveAddress,eax
                        shl     edx,3
                        add     edx,offset mod_rm_16bit
                        call   string
                        mov     al,'+'
                        .if   op_mod == 01b
                          call    print_char
                          inc   esi
                          movsx  eax,byte ptr [esi]
                          add    MOD_RM_EffectiveAddress,eax
                          call  hex_word
                        .elseif op_mod == 10b
                          call    print_char
@@:                       movsx  eax,word ptr [esi+1]
                          add     MOD_RM_EffectiveAddress,eax
                          call hex_word
                          add   esi,2
                        .endif

                        mov     al,']'
                        call    Print_char
        .endif
        ret
Extract16bit_mod_rm ENDP




hex_dword        PROC PRIVATE USES ECX EAX
        mov     cl,8
        call    hex_print
        ret
hex_dword       ENDP
hex_byte        PROC PRIVATE USES ECX EAX
        rol     eax,24
        mov     cl,2
        call    hex_print
        ret
hex_byte       ENDP
hex_word        PROC PRIVATE USES ECX EAX
        rol     eax,16
        mov     cl,4
        call    hex_print
        ret
hex_word       ENDP

hex_print        PROC PRIVATE USES EDX
        mov     edx,eax
he_plotloop:
        rol     edx,4
        movzx   eax,dl
        and     al,0fh
        mov     al,HexChars[eax]
        call    print_char
        dec     cl
        jnz he_plotloop
        ret
HexChars       db '0123456789abcdef'
hex_print       ENDP

String  PROC PRIVATE USES EAX
strloop:        mov     al,[edx]
	        cmp     al,'$'
                je exit
                call Print_char
        	inc     edx
	        jmp strloop
exit:           ret
String  ENDP


Print_char    PROC PRIVATE USES EDX
        movzx   edx,char_position
        add     edx,StringBufferPTR
        mov     [edx],al
        inc     char_position
        ret
Print_char      ENDP

;=========================================================================
plot_seg_reg PROC PRIVATE
    .if op_seg_overide != NULL
         mov    edx,op_seg_overide
         call   String
         mov     al,':'
         call    Print_char
     .endif
        ret
plot_seg_reg ENDP
[ RETURN TO DIRECTORY ]