//--------------------------------------------------------------------------- // NEOPOP : Emulator as in Dreamland // // Copyright (c) 2001-2002 by neopop_uk //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. See also the license.txt file for // additional informations. //--------------------------------------------------------------------------- /* //--------------------------------------------------------------------------- //========================================================================= TLCS900h_disassemble_src.c //========================================================================= //--------------------------------------------------------------------------- History of changes: =================== 20 JUL 2002 - neopop_uk ======================================= - Cleaned and tidied up for the source release 28 JUL 2002 - neopop_uk ======================================= - Better disassembly of MUL/MULS/DIV/DIVS - operand size is shown. //--------------------------------------------------------------------------- */ //========================================================================= #include "../neopop.h" #include "TLCS900h_disassemble.h" #include "TLCS900h_registers.h" #include "TLCS900h_interpret.h" //========================================================================= namespace TLCS900H { static void PUSH() { sprintf(instr, "PUSH (%s)", extra); } static void RLD() { sprintf(instr, "RLD A,(%s)", extra); } static void RRD() { sprintf(instr, "RRD A,(%s)", extra); } static void LDI() { if ((first & 0xF) == 3) { switch(size) { case 0: sprintf(instr, "LDI.b (XDE+),(XHL+)"); break; case 1: sprintf(instr, "LDI.w (XDE+),(XHL+)"); break; } } if ((first & 0xF) == 5) { switch(size) { case 0: sprintf(instr, "LDI.b (XIX+),(XIY+)"); break; case 1: sprintf(instr, "LDI.w (XIX+),(XIY+)"); break; } } } static void LDIR() { if ((first & 0xF) == 3) { switch(size) { case 0: sprintf(instr, "LDIR.b (XDE+),(XHL+)"); break; case 1: sprintf(instr, "LDIR.w (XDE+),(XHL+)"); break; } } if ((first & 0xF) == 5) { switch(size) { case 0: sprintf(instr, "LDIR.b (XIX+),(XIY+)"); break; case 1: sprintf(instr, "LDIR.w (XIX+),(XIY+)"); break; } } } static void LDD() { if ((first & 0xF) == 3) { switch(size) { case 0: sprintf(instr, "LDD.b (XDE-),(XHL-)"); break; case 1: sprintf(instr, "LDD.w (XDE-),(XHL-)"); break; } } if ((first & 0xF) == 5) { switch(size) { case 0: sprintf(instr, "LDD.b (XIX-),(XIY-)"); break; case 1: sprintf(instr, "LDD.w (XIX-),(XIY-)"); break; } } } static void LDDR() { if ((first & 0xF) == 3) { switch(size) { case 0: sprintf(instr, "LDDR.b (XDE-),(XHL-)"); break; case 1: sprintf(instr, "LDDR.w (XDE-),(XHL-)"); break; } } if ((first & 0xF) == 5) { switch(size) { case 0: sprintf(instr, "LDDR.b (XIX-),(XIY-)"); break; case 1: sprintf(instr, "LDDR.w (XIX-),(XIY-)"); break; } } } static void CPI() { sprintf(instr, "CPI"); } static void CPIR() { switch(size) { case 0: sprintf(instr, "CPIR.b A,(%s+)", gprName[first & 7][2]); break; case 1: sprintf(instr, "CPIR.w WA,(%s+)", gprName[first & 7][2]); break; } } static void CPD() { switch(size) { case 0: sprintf(instr, "CPD.b A,(%s+)", gprName[first & 7][2]); break; case 1: sprintf(instr, "CPD.w WA,(%s+)", gprName[first & 7][2]); break; } } static void CPDR() { switch(size) { case 0: sprintf(instr, "CPDR.b A,(%s+)", gprName[first & 7][2]); break; case 1: sprintf(instr, "CPDR.w WA,(%s+)", gprName[first & 7][2]); break; } } static void LD16m() { sprintf(instr, "LD (0x%04X),(%s)", get16_dis(), extra); } static void LD() { sprintf(instr, "LD %s,(%s)", str_R, extra); } static void EX() { switch(size) { case 0: sprintf(instr, "EX.b (%s),%s", extra, str_R); break; case 1: sprintf(instr, "EX.w (%s),%s", extra, str_R); break; } } static void ADDi() { switch(size) { case 0: sprintf(instr, "ADD (%s), 0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "ADD (%s), 0x%04X", extra, get16_dis()); break; } } static void ADCi() { switch(size) { case 0: sprintf(instr, "ADC (%s), 0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "ADC (%s), 0x%04X", extra, get16_dis()); break; } } static void SUBi() { switch(size) { case 0: sprintf(instr, "SUB (%s), 0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "SUB (%s), 0x%04X", extra, get16_dis()); break; } } static void SBCi() { switch(size) { case 0: sprintf(instr, "SBC (%s), 0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "SBC (%s), 0x%04X", extra, get16_dis()); break; } } static void ANDi() { switch(size) { case 0: sprintf(instr, "AND (%s), 0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "AND (%s), 0x%04X", extra, get16_dis()); break; } } static void XORi() { switch(size) { case 0: sprintf(instr, "XOR (%s), 0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "XOR (%s), 0x%04X", extra, get16_dis()); break; } } static void ORi() { switch(size) { case 0: sprintf(instr, "OR (%s), 0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "OR (%s), 0x%04X", extra, get16_dis()); break; } } static void CPi() { switch(size) { case 0: sprintf(instr, "CP (%s),0x%02X", extra, get8_dis()); break; case 1: sprintf(instr, "CP (%s),0x%04X", extra, get16_dis()); break; } } static void MUL() { get_RR_Name(); switch(size) { case 0: sprintf(instr, "MUL.b (%s),(%s)",str_R, extra); break; case 1: sprintf(instr, "MUL.w (%s),(%s)",str_R, extra); break; } } static void MULS() { get_RR_Name(); switch(size) { case 0: sprintf(instr, "MULS.b (%s),(%s)",str_R, extra); break; case 1: sprintf(instr, "MULS.w (%s),(%s)",str_R, extra); break; } } static void DIV() { get_RR_Name(); switch(size) { case 0: sprintf(instr, "DIV.b (%s),(%s)",str_R, extra); break; case 1: sprintf(instr, "DIV.w (%s),(%s)",str_R, extra); break; } } static void DIVS() { get_RR_Name(); switch(size) { case 0: sprintf(instr, "DIVS.b (%s),(%s)",str_R, extra); break; case 1: sprintf(instr, "DIVS.w (%s),(%s)",str_R, extra); break; } } static void INC() { uint8 val = (second & 7); if (val == 0) val = 8; sprintf(instr, "INC %d,(%s)", val, extra); } static void DEC() { uint8 val = (second & 7); if (val == 0) val = 8; sprintf(instr, "DEC %d,(%s)", val, extra); } static void RLC() { sprintf(instr, "RLC (%s)", extra); } static void RRC() { sprintf(instr, "RRC (%s)", extra); } static void RL() { sprintf(instr, "RL (%s)", extra); } static void RR() { sprintf(instr, "RR (%s)", extra); } static void SLA() { sprintf(instr, "SLA (%s)", extra); } static void SRA() { sprintf(instr, "SRA (%s)", extra); } static void SLL() { sprintf(instr, "SLL (%s)", extra); } static void SRL() { sprintf(instr, "SRL (%s)", extra); } static void ADDRm() { sprintf(instr, "ADD %s,(%s)", str_R, extra); } static void ADDmR() { sprintf(instr, "ADD (%s),%s", extra, str_R); } static void ADCRm() { sprintf(instr, "ADC %s,(%s)", str_R, extra); } static void ADCmR() { sprintf(instr, "ADC (%s),%s", extra, str_R); } static void SUBRm() { sprintf(instr, "SUB %s,(%s)", str_R, extra); } static void SUBmR() { sprintf(instr, "SUB (%s),%s", extra, str_R); } static void SBCRm() { sprintf(instr, "SBC %s,(%s)", str_R, extra); } static void SBCmR() { sprintf(instr, "SBC (%s),%s", extra, str_R); } static void ANDmR() { sprintf(instr, "AND (%s),%s", extra, str_R); } static void ANDRm() { sprintf(instr, "AND %s,(%s)", str_R, extra); } static void XORmR() { sprintf(instr, "XOR (%s),%s", extra, str_R); } static void XORRm() { sprintf(instr, "XOR %s,(%s)", str_R, extra); } static void ORmR() { sprintf(instr, "OR (%s),%s", extra, str_R); } static void ORRm() { sprintf(instr, "OR %s,(%s)", str_R, extra); } static void CPmR() { sprintf(instr, "CP (%s),%s", extra, str_R); } static void CPRm() { sprintf(instr, "CP %s,(%s)", str_R, extra); } //========================================================================= //Secondary (SRC) Instruction decode static void (*decode[256])() = { /*0*/ 0, 0, 0, 0, PUSH, 0, RLD, RRD, 0, 0, 0, 0, 0, 0, 0, 0, /*1*/ LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR, 0, LD16m, 0, 0, 0, 0, 0, 0, /*2*/ LD, LD, LD, LD, LD, LD, LD, LD, 0, 0, 0, 0, 0, 0, 0, 0, /*3*/ EX, EX, EX, EX, EX, EX, EX, EX, ADDi, ADCi, SUBi, SBCi, ANDi, XORi, ORi, CPi, /*4*/ MUL, MUL, MUL, MUL, MUL, MUL, MUL, MUL, MULS, MULS, MULS, MULS, MULS, MULS, MULS, MULS, /*5*/ DIV, DIV, DIV, DIV, DIV, DIV, DIV, DIV, DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, DIVS, /*6*/ INC, INC, INC, INC, INC, INC, INC, INC, DEC, DEC, DEC, DEC, DEC, DEC, DEC, DEC, /*7*/ 0, 0, 0, 0, 0, 0, 0, 0, RLC, RRC, RL, RR, SLA, SRA, SLL, SRL, /*8*/ ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, ADDRm, ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, ADDmR, /*9*/ ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, ADCRm, ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, ADCmR, /*A*/ SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, SUBRm, SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, SUBmR, /*B*/ SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, SBCRm, SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, SBCmR, /*C*/ ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, ANDRm, ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, ANDmR, /*D*/ XORRm, XORRm, XORRm, XORRm, XORRm, XORRm, XORRm, XORRm, XORmR, XORmR, XORmR, XORmR, XORmR, XORmR, XORmR, XORmR, /*E*/ ORRm, ORRm, ORRm, ORRm, ORRm, ORRm, ORRm, ORRm, ORmR, ORmR, ORmR, ORmR, ORmR, ORmR, ORmR, ORmR, /*F*/ CPRm, CPRm, CPRm, CPRm, CPRm, CPRm, CPRm, CPRm, CPmR, CPmR, CPmR, CPmR, CPmR, CPmR, CPmR, CPmR }; //============================================================================= void TLCS900h_disassemble_src(int opsize) { second = get8_dis(); //Get the second opcode size = opsize; //Prepare 'Big R' sprintf(str_R, "%s", gprName[second & 7][size]); if (decode[second]) (*decode[second])(); else sprintf(instr, "unknown src instr. %02X", second); } }; //=============================================================================