📄 eval_disasm.c
字号:
"MOV R5, A",
"MOV R6, A",
"MOV R7, A"
};
/* Addressing Mode look-up-table...
*
* 0 = undefined opcode
* 1 = no operands
* 2 = one immediate operand
* 3 = one direct operand
* 4 = one bit-addressed operand
* 5 = one relative address operand
* 6 = one absolute address operand
* 7 = two-byte immediate operand
* 8 = two operands: direct, immediate
* 9 = two operands: direct, direct
* 10 = two operands: immediate, relative address
* 11 = two operands: direct, relative address
* 12 = two operands: bit address, relative address
* 13 = two-byte long address operand
*/
const uint8 kabOperandType[256] =
{
1, 6, 13, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */
12, 6, 13, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
12, 6, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */
12, 6, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */
5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */
5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */
5, 6, 3, 8, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
5, 6, 4, 1, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 7 */
5, 6, 4, 1, 1, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 8 */
7, 6, 4, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */
4, 6, 4, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* A */
4, 6, 4, 1, 10, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, /* B */
3, 6, 4, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C */
3, 6, 4, 1, 1, 11, 1, 1, 5, 5, 5, 5, 5, 5, 5, 5, /* D */
1, 6, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E */
1, 6, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* F */
};
const char * pkszSFRbitname[128] =
{
/* 80 */
"P0.0", "P0.1", "P0.2", "P0.3", "P0.4", "P0.5", "P0.6", "P0.7",
/* 88 */
"IT0", "IE0", "IT1", "IE1", "TR0", "TF0", "TR1", "TF1",
/* 90 */
"P1.0", "P1.1", "P1.2", "P1.3", "P1.4", "P1.5", "P1.6", "P1.7",
/* 98 */
"RI", "TI", "RB8", "TB8", "REN", "SM2", "SM1", "SM0",
/* A0 */
"P2.0", "P2.1", "P2.2", "P2.3", "P2.4", "P2.5", "P2.6", "P2.7",
/* A8 */
"EX0", "ET0", "EX1", "ET1", "ES", "0ADh", "0AEh", "EA",
/* B0 */
"P3.0", "P3.1", "P3.2", "P3.3", "P3.4", "P3.5", "P3.6", "P3.7",
/* B8 */
"PX0", "PT0", "PX1", "PT1", "PS", "0BDh", "0BEh", "0BFh",
/* C0 */
"0C0h", "0C1h", "0C2h", "0C3h", "0C4h", "0C5h", "0C6h", "0C7h",
/* C8 */
"0C8h", "0C9h", "0CAh", "0CBh", "0CCh", "0CDh", "0CEh", "0CFh",
/* D0 */
"P", "0D1h", "OV", "RS0", "RS1", "F0", "AC", "CY",
/* D8 */
"0D8h", "0D9h", "0DAh", "0DBh", "0DCh", "0DDh", "0DEh", "0DFh",
/* E0 */
"ACC.0", "ACC.1", "ACC.2", "ACC.3", "ACC.4", "ACC.5", "ACC.6", "ACC.7",
/* E8 */
"0E8h", "0E9h", "0EAh", "0EBh", "0ECh", "0EDh", "0EEh", "0EFh",
/* F0 */
"B.0", "B.1", "B.2", "B.3", "B.4", "B.5", "B.6", "B.7",
/* F8 */
"0F8h", "0F9h", "0FAh", "0FBh", "0FCh", "0FDh", "0FEh", "0FFh"
};
const char * pkszSFRname[128] =
{
/* 80 */
"P0", "SP", "DPL", "DPH", "84h", "85h", "86h", "PCON",
/* 88 */
"TCON", "TMOD", "TL0", "TL1", "TH0", "TH1", "8Eh", "8Fh",
/* 90 */
"P1", "91h", "92h", "93h", "94h", "95h", "96h", "97h",
/* 98 */
"SCON", "SBUF", "9Ah", "9Bh", "9Ch", "9Dh", "9Eh", "9Fh",
/* A0 */
"P2", "0A1h", "0A2h", "0A3h", "0A4h", "0A5h", "0A6h", "0A7h",
/* A8 */
"IE", "0A9h", "0AAh", "0ABh", "0ACh", "0ADh", "0AEh", "0AFh",
/* B0 */
"P3", "0B1h", "0B2h", "0B3h", "0B4h", "0B5h", "0B6h", "0B7h",
/* B8 */
"IP", "0B9h", "0BAh", "0BBh", "0BCh", "0BDh", "0BEh", "0BFh",
/* C0 */
"0C0h", "0C1h", "0C2h", "0C3h", "0C4h", "0C5h", "0C6h", "0C7h",
/* C8 */
"0C8h", "0C9h", "0CAh", "0CBh", "0CCh", "0CDh", "0CEh", "0CFh",
/* D0 */
"PSW", "0D1h", "0D2h", "0D3h", "0D4h", "0D5h", "0D6h", "0D7h",
/* D8 */
"0D8h", "0D9h", "0DAh", "0DBh", "0DCh", "0DDh", "0DEh", "0DFh",
/* E0 */
"ACC", "0E1h", "0E2h", "0E3h", "0E4h", "0E5h", "0E6h", "0E7h",
/* E8 */
"0E8h", "0E9h", "0EAh", "0EBh", "0ECh", "0EDh", "0EEh", "0EFh",
/* F0 */
"B", "0F1h", "0F2h", "0F3h", "0F4h", "0F5h", "0F6h", "0F7h",
/* F8 */
"0F8h", "0F9h", "0FAh", "0FBh", "0FCh", "0FDh", "0FEh", "0FFh"
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Command function 'DA': Disassemble program code at specified address.
*
* The disassembler is invoked by the command line "DA aaaa [x]"
* where 'aaaa' is the starting address of the code to be disassembled and
* 'x' is an optional parameter (any char) to request continuous output.
*
* If 'x' is omitted, 20 lines (max) are output at a time, followed by a pause,
* thereupon which the user can press Escape to quit or any other key to continue.
* If 'x' is present, disassembly stops if an undefined opcode ($A5) is found,
* or if the user hits any key.
*
* Arg1 @ CmdLine[3] is code addr (0000..FFFF)
* Arg2 @ CmdLine[8] is switch to disable pause (optional)
*/
void
disassemble_cmd( void )
{
const char * pkszNextBlurb; // Pointer to next part of line to be output
uint16 uwFetchAddr; // Address of next code byte to fetch
uint8 bLinesOutput = 0; // Lines output on current "page" (20 lines)
bool yOptNoPause = FALSE; // TRUE if "no pause" option is selected
bool yContinue = TRUE;
int8 ibRelAddr;
uint8 bOpcode;
uint8 bOperand;
uint16 uwOperand;
uint8 bAddrMode;
uwFetchAddr = hexatoi( &gacCmdLine[3] ); // Start addr
if ( isprint( gacCmdLine[8] ) ) yOptNoPause = TRUE;
while ( yContinue )
{
putch( '\t' );
putHexword( uwFetchAddr );
putch( '\t' );
bOpcode = peek_code_byte( uwFetchAddr++ );
pkszNextBlurb = put_assembler( pkszMnemonic[bOpcode] );
bAddrMode = kabOperandType[bOpcode];
switch ( bAddrMode )
{
case 0: // Illegal opcode
yContinue = FALSE;
break;
case 1: // No operands
break;
case 2: // one immediate operand
putch( '$' ); putHexbyte( peek_code_byte( uwFetchAddr++ ) );
break;
case 3: // one direct operand (use SFR name if oprnd addr >= $80)
bOperand = peek_code_byte( uwFetchAddr++ );
if ( bOperand >= 0x80 ) putconstr( pkszSFRname[bOperand - 0x80] );
else { putch( '$' ); putHexbyte( bOperand ); }
put_assembler( pkszNextBlurb );
break;
case 4: // one bit-addressed operand (use SFR bit name if oprnd addr >= $80)
bOperand = peek_code_byte( uwFetchAddr++ );
if ( bOperand >= 0x80 ) putconstr( pkszSFRbitname[bOperand - 0x80] );
else { putch( '$' ); putHexbyte( bOperand ); }
put_assembler( pkszNextBlurb );
break;
case 5: // one relative address operand (8 bits, signed)
ibRelAddr = peek_code_byte( uwFetchAddr++ );
uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
putch( '$' ); putHexword( uwOperand );
break;
case 6: // one absolute address operand (11 bits)
uwOperand = ((uint16)(bOpcode & 0xE0)) << 3; // bits 10,9,8 (from opcode)
uwOperand |= peek_code_byte( uwFetchAddr++ ); // bits 7..0 (from operand byte)
uwOperand |= (uwFetchAddr & 0xF800); // bits 15..11 (from PCH)
putch( '$' ); putHexword( uwOperand );
break;
case 7: // two-byte immediate operand (MSB first)
case 13: // two-byte long address operand
uwOperand = (uint16)peek_code_byte( uwFetchAddr++ ) << 8; // MSB
uwOperand |= peek_code_byte( uwFetchAddr++ ); // LSB
putch( '$' ); putHexword( uwOperand );
break;
case 8: // two 1-byte operands: direct, immediate
bOperand = peek_code_byte( uwFetchAddr++ ); // operand 1
if ( bOperand >= 0x80 ) putconstr( pkszSFRname[bOperand - 0x80] );
else { putch( '$' ); putHexbyte( bOperand ); }
put_assembler( pkszNextBlurb );
bOperand = peek_code_byte( uwFetchAddr++ ); // operand 2
putch( '$' ); putHexbyte( bOperand );
break;
case 9: // two 1-byte operands: direct, direct
bOperand = peek_code_byte( uwFetchAddr++ ); // operand 1
if ( bOperand >= 0x80 ) putconstr( pkszSFRname[bOperand - 0x80] );
else { putch( '$' ); putHexbyte( bOperand ); }
put_assembler( pkszNextBlurb );
bOperand = peek_code_byte( uwFetchAddr++ ); // operand 2
if ( bOperand >= 0x80 ) putconstr( pkszSFRname[bOperand - 0x80] );
else { putch( '$' ); putHexbyte( bOperand ); }
break;
case 10: // two operands: immediate, relative address
bOperand = peek_code_byte( uwFetchAddr++ ); // operand 1
putch( '$' ); putHexbyte( bOperand );
put_assembler( pkszNextBlurb );
ibRelAddr = peek_code_byte( uwFetchAddr++ ); // operand 2
uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
putch( '$' ); putHexword( uwOperand );
break;
case 11: // two operands: direct, relative address
bOperand = peek_code_byte( uwFetchAddr++ ); // operand 1
if ( bOperand >= 0x80 ) putconstr( pkszSFRname[bOperand - 0x80] );
else { putch( '$' ); putHexbyte( bOperand ); }
put_assembler( pkszNextBlurb );
ibRelAddr = peek_code_byte( uwFetchAddr++ ); // operand 2
uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
putch( '$' ); putHexword( uwOperand );
break;
case 12: // two operands: bit address, relative address
bOperand = peek_code_byte( uwFetchAddr++ ); // operand 1
if ( bOperand >= 0x80 ) putconstr( pkszSFRbitname[bOperand - 0x80] );
else { putch( '$' ); putHexbyte( bOperand ); }
put_assembler( pkszNextBlurb );
ibRelAddr = peek_code_byte( uwFetchAddr++ ); // operand 2
uwOperand = (uint16) ((int16)uwFetchAddr + (int16)ibRelAddr);
putch( '$' ); putHexword( uwOperand );
break;
default: // corrupted look-up table?
yContinue = FALSE;
break;
} // end switch
putNewLine();
bLinesOutput++ ;
if ( yOptNoPause && hci_data_avail() ) { getch(); break; } // quit
if ( !yOptNoPause && bLinesOutput >= 20 ) // pause
{
if ( getch() == ESC ) break;
bLinesOutput = 0;
}
}
}
/*
* Function: put_assembler
*
* The function outputs characters at pkcSourcePtr until either a place marker "%s" is
* found or a NUL is found (end of string). The place marker "%s" is not output, but the
* pointer is advanced so that it points to the next char after "%s" before returning.
* If a NUL is found, the pointer remains at the NUL.
*
* Entry Arg: (char *) pkcSourcePtr = pointer to somewhere in a string from pkszMnemonic;
* Returns: (char *) pkcSourcePtr = pointer advanced to char after place marker (%s);
*/
const char *
put_assembler( const char * pkcSourcePtr )
{
char c;
while ( (c = *pkcSourcePtr) != NUL )
{
if ( c == '%' ) { pkcSourcePtr += 2; break; }
putch( c );
pkcSourcePtr++ ;
}
return pkcSourcePtr;
}
#endif // DISASM_INCLUDED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -