663 lines
13 KiB
C++
663 lines
13 KiB
C++
//---------------------------------------------------------------------------
|
|
// 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_reg.c
|
|
|
|
//=========================================================================
|
|
//---------------------------------------------------------------------------
|
|
|
|
History of changes:
|
|
===================
|
|
|
|
20 JUL 2002 - neopop_uk
|
|
=======================================
|
|
- Cleaned and tidied up for the source release
|
|
|
|
22 JUL 2002 - neopop_uk
|
|
=======================================
|
|
- Fixed disassembly of Link, it's second operand is signed.
|
|
|
|
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 LDi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "LD %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "LD %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "LD %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void PUSH()
|
|
{
|
|
sprintf(instr, "PUSH %s", str_r);
|
|
}
|
|
|
|
static void POP()
|
|
{
|
|
sprintf(instr, "POP %s", str_r);
|
|
}
|
|
|
|
static void CPL()
|
|
{
|
|
sprintf(instr, "CPL %s", str_r);
|
|
}
|
|
|
|
static void NEG()
|
|
{
|
|
sprintf(instr, "NEG %s", str_r);
|
|
}
|
|
|
|
static void MULi()
|
|
{
|
|
get_rr_Name();
|
|
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "MUL.b %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "MUL.w %s,0x%04X", str_r, get16_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void MULSi()
|
|
{
|
|
get_rr_Name();
|
|
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "MULS.b %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "MULS.w %s,0x%04X", str_r, get16_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void DIVi()
|
|
{
|
|
get_rr_Name();
|
|
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "DIV.b %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "DIV.w %s,0x%04X", str_r, get16_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void DIVSi()
|
|
{
|
|
get_rr_Name();
|
|
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "DIVS.b %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "DIVS.w %s,0x%04X", str_r, get16_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void LINK()
|
|
{
|
|
sprintf(instr, "LINK %s, %d", str_r, (int16)get16_dis());
|
|
}
|
|
|
|
static void UNLK()
|
|
{
|
|
sprintf(instr, "UNLK %s", str_r);
|
|
}
|
|
|
|
static void BS1F()
|
|
{
|
|
sprintf(instr, "BS1F A,%s", str_r);
|
|
}
|
|
|
|
static void BS1B()
|
|
{
|
|
sprintf(instr, "BS1B A,%s", str_r);
|
|
}
|
|
|
|
static void DAA()
|
|
{
|
|
sprintf(instr, "DAA %s", str_r);
|
|
}
|
|
|
|
static void EXTZ()
|
|
{
|
|
sprintf(instr, "EXTZ %s", str_r);
|
|
}
|
|
|
|
static void EXTS()
|
|
{
|
|
sprintf(instr, "EXTS %s", str_r);
|
|
}
|
|
|
|
static void PAA()
|
|
{
|
|
sprintf(instr, "PAA %s", str_r);
|
|
}
|
|
|
|
static void MIRR()
|
|
{
|
|
sprintf(instr, "MIRR %s", str_r);
|
|
}
|
|
|
|
static void MULA()
|
|
{
|
|
sprintf(instr, "MULA %s", str_r);
|
|
}
|
|
|
|
static void DJNZ()
|
|
{
|
|
sprintf(instr, "DJNZ %s,0x%06X", str_r, (int8)get8_dis() + pc);
|
|
}
|
|
|
|
static void ANDCFi()
|
|
{
|
|
sprintf(instr, "ANDCF %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void ORCFi()
|
|
{
|
|
sprintf(instr, "ORCF %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void XORCFi()
|
|
{
|
|
sprintf(instr, "XORCF %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void LDCFi()
|
|
{
|
|
sprintf(instr, "LDCF %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void STCFi()
|
|
{
|
|
sprintf(instr, "STCF %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void ANDCFA()
|
|
{
|
|
sprintf(instr, "ANDCF A,%s", str_r);
|
|
}
|
|
|
|
static void ORCFA()
|
|
{
|
|
sprintf(instr, "ORCF A,%s", str_r);
|
|
}
|
|
|
|
static void XORCFA()
|
|
{
|
|
sprintf(instr, "XORCF A,%s", str_r);
|
|
}
|
|
|
|
static void LDCFA()
|
|
{
|
|
sprintf(instr, "LDCF A,%s", str_r);
|
|
}
|
|
|
|
static void STCFA()
|
|
{
|
|
sprintf(instr, "STCF A,%s", str_r);
|
|
}
|
|
|
|
static void LDCcrr()
|
|
{
|
|
uint8 cr = get8_dis();
|
|
sprintf(instr, "LDC %s,%s", crName[size][cr >> size], str_r);
|
|
}
|
|
|
|
static void LDCrcr()
|
|
{
|
|
uint8 cr = get8_dis();
|
|
sprintf(instr, "LDC %s,%s", str_r, crName[size][cr >> size]);
|
|
}
|
|
|
|
static void RES()
|
|
{
|
|
sprintf(instr, "RES %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void SET()
|
|
{
|
|
sprintf(instr, "SET %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void CHG()
|
|
{
|
|
sprintf(instr, "CHG %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void BIT()
|
|
{
|
|
sprintf(instr, "BIT %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void TSET()
|
|
{
|
|
sprintf(instr, "TSET %d,%s", get8_dis() & 0xF, str_r);
|
|
}
|
|
|
|
static void MINC1()
|
|
{
|
|
sprintf(instr, "MINC1 %d,%s", get16_dis()+1, str_r);
|
|
}
|
|
|
|
static void MINC2()
|
|
{
|
|
sprintf(instr, "MINC2 %d,%s", get16_dis()+2, str_r);
|
|
}
|
|
|
|
static void MINC4()
|
|
{
|
|
sprintf(instr, "MINC4 %d,%s", get16_dis()+4, str_r);
|
|
}
|
|
|
|
static void MDEC1()
|
|
{
|
|
sprintf(instr, "MDEC1 %d,%s", get16_dis()+1, str_r);
|
|
}
|
|
|
|
static void MDEC2()
|
|
{
|
|
sprintf(instr, "MDEC2 %d,%s", get16_dis()+2, str_r);
|
|
}
|
|
|
|
static void MDEC4()
|
|
{
|
|
sprintf(instr, "MDEC4 %d,%s", get16_dis()+4, str_r);
|
|
}
|
|
|
|
static void MUL()
|
|
{
|
|
get_RR_Name();
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "MUL.b %s,%s", str_R, str_r); break;
|
|
case 1: sprintf(instr, "MUL.w %s,%s", str_R, str_r); break;
|
|
}
|
|
}
|
|
|
|
static void MULS()
|
|
{
|
|
get_RR_Name();
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "MULS.b %s,%s", str_R, str_r); break;
|
|
case 1: sprintf(instr, "MULS.w %s,%s", str_R, str_r); break;
|
|
}
|
|
}
|
|
|
|
static void DIV()
|
|
{
|
|
get_RR_Name();
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "DIV.b %s,%s", str_R, str_r); break;
|
|
case 1: sprintf(instr, "DIV.w %s,%s", str_R, str_r); break;
|
|
}
|
|
}
|
|
|
|
static void DIVS()
|
|
{
|
|
get_RR_Name();
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "DIVS.b %s,%s", str_R, str_r); break;
|
|
case 1: sprintf(instr, "DIVS.w %s,%s", str_R, str_r); break;
|
|
}
|
|
}
|
|
|
|
static void INC()
|
|
{
|
|
uint8 val = (second & 7);
|
|
if (val == 0)
|
|
val = 8;
|
|
|
|
sprintf(instr, "INC %d,%s", val, str_r);
|
|
}
|
|
|
|
static void DEC()
|
|
{
|
|
uint8 val = (second & 7);
|
|
if (val == 0)
|
|
val = 8;
|
|
|
|
sprintf(instr, "DEC %d,%s", val, str_r);
|
|
}
|
|
|
|
static void SCC()
|
|
{
|
|
sprintf(instr, "SCC %s,%s", ccName[second & 0xF], str_r);
|
|
}
|
|
|
|
static void ADD()
|
|
{
|
|
sprintf(instr, "ADD %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void LDRr()
|
|
{
|
|
sprintf(instr, "LD %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void LDrR()
|
|
{
|
|
sprintf(instr, "LD %s,%s", str_r, str_R);
|
|
}
|
|
|
|
static void ADC()
|
|
{
|
|
sprintf(instr, "ADC %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void SUB()
|
|
{
|
|
sprintf(instr, "SUB %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void SBC()
|
|
{
|
|
sprintf(instr, "SBC %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void LDr3()
|
|
{
|
|
sprintf(instr, "LD %s,%d", str_r, second & 7);
|
|
}
|
|
|
|
static void EX()
|
|
{
|
|
sprintf(instr, "EX %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void AND()
|
|
{
|
|
sprintf(instr, "AND %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void ADDi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "ADD %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "ADD %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "ADD %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void ADCi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "ADC %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "ADC %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "ADC %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void SUBi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "SUB %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "SUB %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "SUB %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void SBCi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "SBC %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "SBC %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "SBC %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void ANDi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "AND %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "AND %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "AND %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void XORi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "XOR %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "XOR %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "XOR %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void ORi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "OR %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "OR %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "OR %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void CPi()
|
|
{
|
|
switch(size)
|
|
{
|
|
case 0: sprintf(instr, "CP %s,0x%02X", str_r, get8_dis()); break;
|
|
case 1: sprintf(instr, "CP %s,0x%04X", str_r, get16_dis()); break;
|
|
case 2: sprintf(instr, "CP %s,0x%08X", str_r, get32_dis()); break;
|
|
}
|
|
}
|
|
|
|
static void XOR()
|
|
{
|
|
sprintf(instr, "XOR %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void CPr3()
|
|
{
|
|
sprintf(instr,"CP %s,%d", str_r, second&7);
|
|
}
|
|
|
|
static void OR()
|
|
{
|
|
sprintf(instr, "OR %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void RLCi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "RLC %d,%s", val, str_r);
|
|
}
|
|
|
|
static void RRCi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "RRC %d,%s", val, str_r);
|
|
}
|
|
|
|
static void RLi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "RL %d,%s", val, str_r);
|
|
}
|
|
|
|
static void RRi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "RR %d,%s", val, str_r);
|
|
}
|
|
|
|
static void SLAi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "SLA %d,%s", val, str_r);
|
|
}
|
|
|
|
static void SRAi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "SRA %d,%s", val, str_r);
|
|
}
|
|
|
|
static void SLLi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "SLL %d,%s", val, str_r);
|
|
}
|
|
|
|
static void SRLi()
|
|
{
|
|
uint8 val = get8_dis() & 0xF;
|
|
if (val == 0) val = 16;
|
|
sprintf(instr, "SRL %d,%s", val, str_r);
|
|
}
|
|
|
|
static void CP()
|
|
{
|
|
sprintf(instr, "CP %s,%s", str_R, str_r);
|
|
}
|
|
|
|
static void RLCA()
|
|
{
|
|
sprintf(instr, "RLC A,%s", str_r);
|
|
}
|
|
|
|
static void RRCA()
|
|
{
|
|
sprintf(instr, "RRC A,%s", str_r);
|
|
}
|
|
|
|
static void RLA()
|
|
{
|
|
sprintf(instr, "RL A,%s", str_r);
|
|
}
|
|
|
|
static void RRA()
|
|
{
|
|
sprintf(instr, "RR A,%s", str_r);
|
|
}
|
|
|
|
static void SLAA()
|
|
{
|
|
sprintf(instr, "SLA A,%s", str_r);
|
|
}
|
|
|
|
static void SRAA()
|
|
{
|
|
sprintf(instr, "SRA A,%s", str_r);
|
|
}
|
|
|
|
static void SLLA()
|
|
{
|
|
sprintf(instr, "SLL A,%s", str_r);
|
|
}
|
|
|
|
static void SRLA()
|
|
{
|
|
sprintf(instr, "SRL A,%s", str_r);
|
|
}
|
|
|
|
//=========================================================================
|
|
|
|
//Secondary (REG) Instruction decode
|
|
static void (*decode[256])() =
|
|
{
|
|
/*0*/ 0, 0, 0, LDi, PUSH, POP, CPL, NEG,
|
|
MULi, MULSi, DIVi, DIVSi, LINK, UNLK, BS1F, BS1B,
|
|
/*1*/ DAA, 0, EXTZ, EXTS, PAA, 0, MIRR, 0,
|
|
0, MULA, 0, 0, DJNZ, 0, 0, 0,
|
|
/*2*/ ANDCFi, ORCFi, XORCFi, LDCFi, STCFi, 0, 0, 0,
|
|
ANDCFA, ORCFA, XORCFA, LDCFA, STCFA, 0, LDCcrr, LDCrcr,
|
|
/*3*/ RES, SET, CHG, BIT, TSET, 0, 0, 0,
|
|
MINC1, MINC2, MINC4, 0, MDEC1, MDEC2, MDEC4, 0,
|
|
/*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*/ SCC, SCC, SCC, SCC, SCC, SCC, SCC, SCC,
|
|
SCC, SCC, SCC, SCC, SCC, SCC, SCC, SCC,
|
|
/*8*/ ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD,
|
|
LDRr, LDRr, LDRr, LDRr, LDRr, LDRr, LDRr, LDRr,
|
|
/*9*/ ADC, ADC, ADC, ADC, ADC, ADC, ADC, ADC,
|
|
LDrR, LDrR, LDrR, LDrR, LDrR, LDrR, LDrR, LDrR,
|
|
/*A*/ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
|
|
LDr3, LDr3, LDr3, LDr3, LDr3, LDr3, LDr3, LDr3,
|
|
/*B*/ SBC, SBC, SBC, SBC, SBC, SBC, SBC, SBC,
|
|
EX, EX, EX, EX, EX, EX, EX, EX,
|
|
/*C*/ AND, AND, AND, AND, AND, AND, AND, AND,
|
|
ADDi, ADCi, SUBi, SBCi, ANDi, XORi, ORi, CPi,
|
|
/*D*/ XOR, XOR, XOR, XOR, XOR, XOR, XOR, XOR,
|
|
CPr3, CPr3, CPr3, CPr3, CPr3, CPr3, CPr3, CPr3,
|
|
/*E*/ OR, OR, OR, OR, OR, OR, OR, OR,
|
|
RLCi, RRCi, RLi, RRi, SLAi, SRAi, SLLi, SRLi,
|
|
/*F*/ CP, CP, CP, CP, CP, CP, CP, CP,
|
|
RLCA, RRCA, RLA, RRA, SLAA, SRAA, SLLA, SRLA
|
|
};
|
|
|
|
//=============================================================================
|
|
|
|
void TLCS900h_disassemble_reg(int opsize)
|
|
{
|
|
second = get8_dis(); //Get the second opcode
|
|
size = opsize;
|
|
|
|
//Prepare 'Big R'
|
|
sprintf(str_R, "%s", gprName[second & 7][size]);
|
|
|
|
//Prepare 'little r'
|
|
if (brCode)
|
|
sprintf(str_r, "%s", extra);
|
|
else
|
|
sprintf(str_r, "%s", gprName[first & 7][opsize]);
|
|
|
|
if (decode[second])
|
|
(*decode[second])();
|
|
else
|
|
sprintf(instr, "unknown reg instr. %02X", second);
|
|
}
|
|
};
|