2019-04-06 17:38:14 -04:00
# include "stdafx.h"
# include "SpcDisUtils.h"
2019-04-07 17:57:30 -04:00
# include "Console.h"
# include "DummySpc.h"
2019-04-06 17:38:14 -04:00
# include "DisassemblyInfo.h"
# include "../Utilities/FastString.h"
# include "../Utilities/HexUtilities.h"
2019-04-07 12:25:14 -04:00
/*constexpr const char* _opTemplate[256] = {
2019-04-06 17:38:14 -04:00
" NOP " , " TCALL 0 " , " SET1 d.0 " , " BBS d.0, q " , " OR A, d " , " OR A, !a " , " OR A, (X) " , " OR A, [d+X] " , " OR A, #i " , " OR t, s " , " OR1 C, m.b " , " ASL d " , " ASL !a " , " PUSH PSW " , " TSET1 !a " , " BRK " ,
" BPL r " , " TCALL 1 " , " CLR1 d.0 " , " BBC d.0, q " , " OR A, d+X " , " OR A, !a+X " , " OR A, !a+Y " , " OR A, [d]+Y " , " OR e, #i " , " OR (X), (Y) " , " DECW d " , " ASL d+X " , " ASL A " , " DEC X " , " CMP X, !a " , " JMP [!a+X] " ,
" CLRP " , " TCALL 2 " , " SET1 d.1 " , " BBS d.1, q " , " AND A, d " , " AND A, !a " , " AND A, (X) " , " AND A, [d+X] " , " AND A, #i " , " AND t, s " , " OR1 C, /m.b " , " ROL d " , " ROL !a " , " PUSH A " , " CBNE d, q " , " BRA r " ,
" BMI r " , " TCALL 3 " , " CLR1 d.1 " , " BBC d.1, q " , " AND A, d+X " , " AND A, !a+X " , " AND A, !a+Y " , " AND A, [d]+Y " , " AND e, #i " , " AND (X), (Y) " , " INCW d " , " ROL d+X " , " ROL A " , " INC X " , " CMP X, d " , " CALL !a " ,
" SETP " , " TCALL 4 " , " SET1 d.2 " , " BBS d.2, q " , " EOR A, d " , " EOR A, !a " , " EOR A, (X) " , " EOR A, [d+X] " , " EOR A, #i " , " EOR t, s " , " AND1 C, m.b " , " LSR d " , " LSR !a " , " PUSH X " , " TCLR1 !a " , " PCALL u " ,
" BVC r " , " TCALL 5 " , " CLR1 d.2 " , " BBC d.2, q " , " EOR A, d+X " , " EOR A, !a+X " , " EOR A, !a+Y " , " EOR A, [d]+Y " , " EOR e, #i " , " EOR (X), (Y) " , " CMPW YA, d " , " LSR d+X " , " LSR A " , " MOV X, A " , " CMP Y, !a " , " JMP !a " ,
" CLRC " , " TCALL 6 " , " SET1 d.3 " , " BBS d.3, q " , " CMP A, d " , " CMP A, !a " , " CMP A, (X) " , " CMP A, [d+X] " , " CMP A, #i " , " CMP t, s " , " AND1 C, /m.b " , " ROR d " , " ROR !a " , " PUSH Y " , " DBNZ d, q " , " RET " ,
" BVS r " , " TCALL 7 " , " CLR1 d.3 " , " BBC d.3, q " , " CMP A, d+X " , " CMP A, !a+X " , " CMP A, !a+Y " , " CMP A, [d]+Y " , " CMP e, #i " , " CMP (X), (Y) " , " ADDW YA, d " , " ROR d+X " , " ROR A " , " MOV A, X " , " CMP Y, d " , " RET1 " ,
" SETC " , " TCALL 8 " , " SET1 d.4 " , " BBS d.4, q " , " ADC A, d " , " ADC A, !a " , " ADC A, (X) " , " ADC A, [d+X] " , " ADC A, #i " , " ADC t, s " , " EOR1 C, m.b " , " DEC d " , " DEC !a " , " MOV Y, #i " , " POP PSW " , " MOV e, #i " ,
" BCC r " , " TCALL 9 " , " CLR1 d.4 " , " BBC d.4, q " , " ADC A, d+X " , " ADC A, !a+X " , " ADC A, !a+Y " , " ADC A, [d]+Y " , " ADC e, #i " , " ADC (X), (Y) " , " SUBW YA, d " , " DEC d+X " , " DEC A " , " MOV X, SP " , " DIV YA, X " , " XCN A " ,
" EI " , " TCALL 10 " , " SET1 d.5 " , " BBS d.5, q " , " SBC A, d " , " SBC A, !a " , " SBC A, (X) " , " SBC A, [d+X] " , " SBC A, #i " , " SBC t, s " , " MOV1 C, m.b " , " INC d " , " INC !a " , " CMP Y, #i " , " POP A " , " MOV (X)+, A " ,
" BCS r " , " TCALL 11 " , " CLR1 d.5 " , " BBC d.5, q " , " SBC A, d+X " , " SBC A, !a+X " , " SBC A, !a+Y " , " SBC A, [d]+Y " , " SBC e, #i " , " SBC (X), (Y) " , " MOVW YA, d " , " INC d+X " , " INC A " , " MOV SP, X " , " DAS A " , " MOV A, (X)+ " ,
" DI " , " TCALL 12 " , " SET1 d.6 " , " BBS d.6, q " , " MOV d, A " , " MOV !a, A " , " MOV (X), A " , " MOV [d+X], A " , " CMP X, #i " , " MOV !a, X " , " MOV1 m.b, C " , " MOV d, Y " , " MOV !a, Y " , " MOV X, #i " , " POP X " , " MUL YA " ,
" BNE r " , " TCALL 13 " , " CLR1 d.6 " , " BBC d.6, q " , " MOV d+X, A " , " MOV !a+X, A " , " MOV !a+Y, A " , " MOV [d]+Y, A " , " MOV e, X " , " MOV d+Y, X " , " MOVW d, YA " , " MOV d+X, Y " , " DEC Y " , " MOV A, Y " , " CBNE d+X, q " , " DAA A " ,
" CLRV " , " TCALL 14 " , " SET1 d.7 " , " BBS d.7, q " , " MOV A, d " , " MOV A, !a " , " MOV A, (X) " , " MOV A, [d+X] " , " MOV A, #i " , " MOV X, !a " , " NOT1 m.b " , " MOV Y, d " , " MOV Y, !a " , " NOTC " , " POP Y " , " SLEEP " ,
" BEQ r " , " TCALL 15 " , " CLR1 d.7 " , " BBC d.7, q " , " MOV A, d+X " , " MOV A, !a+X " , " MOV A, !a+Y " , " MOV A, [d]+Y " , " MOV X, d " , " MOV X, d+Y " , " MOV t, s " , " MOV Y, d+X " , " INC Y " , " MOV Y, A " , " DBNZ Y, q " , " STOP "
2019-04-07 12:25:14 -04:00
} ; */
constexpr const char * _opTemplate [ 256 ] = {
" NOP " , " JST0 " , " SET1 d.0 " , " BBS d.0, q " , " ORA d " , " ORA a " , " ORA (X) " , " ORA [d,X] " , " ORA #i " , " OR t, s " , " ORC m.b " , " ASL d " , " ASL a " , " PHP " , " SET1 a " , " BRK " ,
" BPL r " , " JST1 " , " CLR1 d.0 " , " BBC d.0, q " , " ORA d,X " , " ORA a,X " , " ORA a,Y " , " ORA [d],Y " , " OR e, #i " , " OR (X), (Y) " , " DEW d " , " ASL d,X " , " ASL A " , " DEX " , " CPX a " , " JMP [a,X] " ,
" CLP " , " JST2 " , " SET1 d.1 " , " BBS d.1, q " , " AND d " , " AND a " , " AND (X) " , " AND [d,X] " , " AND #i " , " AND t, s " , " ORC /m.b " , " ROL d " , " ROL a " , " PHA " , " CBNE d, q " , " BRA r " ,
" BMI r " , " JST3 " , " CLR1 d.1 " , " BBC d.1, q " , " AND d,X " , " AND a,X " , " AND a,Y " , " AND [d],Y " , " AND e, #i " , " AND (X), (Y) " , " INW d " , " ROL d,X " , " ROL A " , " INX " , " CPX d " , " JSR a " ,
2019-04-07 17:57:30 -04:00
" SEP " , " JST4 " , " SET1 d.2 " , " BBS d.2, q " , " EOR d " , " EOR a " , " EOR (X) " , " EOR [d,X] " , " EOR #i " , " EOR t, s " , " ANDC m.b " , " LSR d " , " LSR a " , " PHX " , " CLR1 a " , " JSP u " ,
2019-04-07 12:25:14 -04:00
" BVC r " , " JST5 " , " CLR1 d.2 " , " BBC d.2, q " , " EOR d,X " , " EOR a,X " , " EOR a,Y " , " EOR [d],Y " , " EOR e, #i " , " EOR (X), (Y) " , " CPW d " , " LSR d,X " , " LSR A " , " TAX " , " CPY a " , " JMP a " ,
2019-04-07 17:57:30 -04:00
" CLC " , " JST6 " , " SET1 d.3 " , " BBS d.3, q " , " CMP d " , " CMP a " , " CMP (X) " , " CMP [d,X] " , " CMP #i " , " CMP t, s " , " ANDC /m.b " , " ROR d " , " ROR a " , " PHY " , " DBNZ d, q " , " RTS " ,
" BVS r " , " JST7 " , " CLR1 d.3 " , " BBC d.3, q " , " CMP d,X " , " CMP a,X " , " CMP a,Y " , " CMP [d],Y " , " CMP e, #i " , " CMP (X), (Y) " , " ADW d " , " ROR d,X " , " ROR A " , " TXA " , " CPY d " , " RTI " ,
" SEC " , " JST8 " , " SET1 d.4 " , " BBS d.4, q " , " ADC d " , " ADC a " , " ADC (X) " , " ADC [d,X] " , " ADC #i " , " ADC t, s " , " EORC m.b " , " DEC d " , " DEC a " , " LDY #i " , " PLP " , " MOV e, #i " ,
2019-04-07 12:25:14 -04:00
" BCC r " , " JST9 " , " CLR1 d.4 " , " BBC d.4, q " , " ADC d,X " , " ADC a,X " , " ADC a,Y " , " ADC [d],Y " , " ADC e, #i " , " ADC (X), (Y) " , " SBW d " , " DEC d,X " , " DEC A " , " TSX " , " DIV YA, X " , " XCN A " ,
" CLI " , " JSTA " , " SET1 d.5 " , " BBS d.5, q " , " SBC d " , " SBC a " , " SBC (X) " , " SBC [d,X] " , " SBC #i " , " SBC t, s " , " LDC m.b " , " INC d " , " INC a " , " CMY #i " , " PLA " , " STA (X)+, A " ,
" BCS r " , " JSTB " , " CLR1 d.5 " , " BBC d.5, q " , " SBC d,X " , " SBC a,X " , " SBC a,Y " , " SBC [d],Y " , " SBC e, #i " , " SBC (X), (Y) " , " LDW d " , " INC d,X " , " INC A " , " TXS " , " DAS A " , " LDA (X)+ " ,
" SEI " , " JSTC " , " SET1 d.6 " , " BBS d.6, q " , " STA d " , " STA a " , " STA (X) " , " STA [d,X] " , " CPX #i " , " STX a " , " STC m.b " , " STY d " , " STY a " , " LDX #i " , " PLX " , " MUL YA " ,
" BNE r " , " JSTD " , " CLR1 d.6 " , " BBC d.6, q " , " STA d,X " , " STA a,X " , " STA a,Y " , " STA [d],Y " , " STX e " , " STX d,Y " , " STW d " , " STY d,X " , " DEY " , " TYA " , " CBNE d,X, q " , " DAA A " ,
2019-04-07 17:57:30 -04:00
" CLV " , " JSTE " , " SET1 d.7 " , " BBS d.7, q " , " LDA d " , " LDA a " , " LDA (X) " , " LDA [d,X] " , " LDA #i " , " LDX a " , " NOT m.b " , " LDY d " , " LDY a " , " NOTC " , " PLY " , " WAI " ,
2019-04-07 12:25:14 -04:00
" BEQ r " , " JSTF " , " CLR1 d.7 " , " BBC d.7, q " , " LDA d,X " , " LDA a,X " , " LDA a,Y " , " LDA [d],Y " , " LDX d " , " LDX d,Y " , " MOV t, s " , " LDY d,X " , " INC Y " , " TAY " , " DBNZ Y, q " , " HLT "
2019-04-06 17:38:14 -04:00
} ;
constexpr const uint8_t _opSize [ 256 ] = {
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 1 , 3 , 1 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 3 , 1 , 2 , 2 , 1 , 1 , 3 , 3 ,
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 1 , 3 , 2 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 3 , 1 , 2 , 2 , 1 , 1 , 2 , 3 ,
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 1 , 3 , 2 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 3 , 1 , 2 , 2 , 1 , 1 , 3 , 3 ,
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 1 , 3 , 1 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 3 , 1 , 2 , 2 , 1 , 1 , 2 , 1 ,
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 2 , 1 , 3 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 3 , 1 , 2 , 2 , 1 , 1 , 1 , 1 ,
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 2 , 1 , 1 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 3 , 1 , 2 , 2 , 1 , 1 , 1 , 1 ,
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 2 , 1 , 1 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 2 , 2 , 2 , 2 , 1 , 1 , 3 , 1 ,
1 , 1 , 2 , 3 , 2 , 3 , 1 , 2 , 2 , 3 , 3 , 2 , 3 , 1 , 1 , 1 ,
2 , 1 , 2 , 3 , 2 , 3 , 3 , 2 , 2 , 2 , 3 , 2 , 1 , 1 , 2 , 1 ,
} ;
2019-04-07 17:57:30 -04:00
constexpr bool _needAddress [ 256 ] = {
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , false ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , true ,
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , false ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , false ,
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , false ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , false ,
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , false ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , false ,
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , false ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , false ,
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , true ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , true ,
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , false ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , false ,
false , true , false , false , false , false , true , true , false , false , false , false , false , false , false , false ,
false , true , false , false , true , true , true , true , false , false , false , true , false , false , false , false
} ;
2019-04-06 17:38:14 -04:00
void SpcDisUtils : : GetDisassembly ( DisassemblyInfo & info , string & out , uint32_t memoryAddr )
{
FastString str ;
uint8_t * byteCode = info . GetByteCode ( ) ;
const char * op = _opTemplate [ byteCode [ 0 ] ] ;
int i = 0 ;
while ( op [ i ] ) {
switch ( op [ i ] ) {
2019-04-07 12:25:14 -04:00
case ' r ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( memoryAddr + ( int8_t ) byteCode [ 1 ] + GetOpSize ( byteCode [ 0 ] ) ) ) ; break ;
case ' q ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( memoryAddr + ( int8_t ) byteCode [ 2 ] + GetOpSize ( byteCode [ 0 ] ) ) ) ; break ; //relative 2nd byte
2019-04-06 17:38:14 -04:00
case ' a ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( byteCode [ 1 ] | ( byteCode [ 2 ] < < 8 ) ) ) ; break ;
case ' d ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( byteCode [ 1 ] ) ) ; break ;
case ' e ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( byteCode [ 2 ] ) ) ; break ; //direct 2nd byte
case ' s ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( byteCode [ 1 ] ) ) ; break ;
case ' t ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( byteCode [ 2 ] ) ) ; break ;
case ' i ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( byteCode [ 1 ] ) ) ; break ;
case ' m ' : str . Write ( ' $ ' , HexUtilities : : ToHex ( ( byteCode [ 1 ] | ( byteCode [ 2 ] < < 8 ) ) & 0x1FFF ) ) ; break ;
case ' b ' : str . Write ( ' $ ' , ( char ) ( ' 0 ' + ( byteCode [ 2 ] > > 5 ) ) ) ; break ;
default : str . Write ( op [ i ] ) ;
}
i + + ;
}
out + = str . ToString ( ) ;
}
2019-04-07 17:57:30 -04:00
int32_t SpcDisUtils : : GetEffectiveAddress ( DisassemblyInfo & info , Console * console , SpcState & state )
{
if ( _needAddress [ info . GetOpCode ( ) ] ) {
Spc * spc = console - > GetSpc ( ) . get ( ) ;
DummySpc dummySpc ( spc - > GetSpcRam ( ) , spc - > GetSpcRom ( ) , state ) ;
dummySpc . Step ( ) ;
uint32_t addr ;
uint8_t value ;
uint32_t writeCount = dummySpc . GetWriteCount ( ) ;
if ( writeCount > 0 ) {
dummySpc . GetWriteInfo ( writeCount - 1 , addr , value ) ;
} else {
uint32_t readCount = dummySpc . GetReadCount ( ) ;
dummySpc . GetReadInfo ( readCount - 1 , addr , value ) ;
}
return addr ;
}
return - 1 ;
}
2019-04-06 17:38:14 -04:00
uint8_t SpcDisUtils : : GetOpSize ( uint8_t opCode )
{
return _opSize [ opCode ] ;
}