--- /dev/null
+//
+// 6809 disassembler
+//
+// by James L. Hammons
+//
+// (c) 2004 Underground Software
+//
+
+#include "dis6809.h"
+
+#include <stdio.h>
+#include <string.h>
+//#include "v6809.h"
+#include "log.h"
+
+using namespace std;
+
+// External shit
+
+//NO MORE!!! extern V6809REGS mainCPU;//Hm.
+
+static char op_mat1[256] = {
+ 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 0, 0, 5, 5, 0, 0, 4, 4, 0, 5, 8, 0, 8, 5, 6, 6,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 7, 7, 7, 7, 6, 6, 6, 6, 0, 5, 5, 5, 8, 5, 5, 5,
+ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
+ 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
+ 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7,
+ 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2,
+ 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 0, 9, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+},
+
+op_mat2[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1,
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2
+},
+
+op_mat3[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static char mnemonics[256][6] = {
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "PAGE1","PAGE2","NOP ","SYNC ","??? ","??? ","LBRA ","LBSR ",
+ "??? ","DAA ","ORCC ","??? ","ANDCC","SEX ","EXG ","TFR ",
+ "BRA ","BRN ","BHI ","BLS ","BHS ","BLO ","BNE ","BEQ ",
+ "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ",
+ "LEAX ","LEAY ","LEAS ","LEAU ","PSHS ","PULS ","PSHU ","PULU ",
+ "??? ","RTS ","ABX ","RTI ","CWAI ","MUL ","RESET","SWI ",
+ "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ",
+ "LSLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ",
+ "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ",
+ "LSLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ",
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ",
+ "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ",
+ "SUBA ","CMPA ","SCBA ","SUBD ","ANDA ","BITA ","LDA ","??? ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","BSR ","LDX ","??? ",
+ "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ",
+ "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ",
+ "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ",
+ "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ",
+ "SUBB ","CMPB ","SCBB ","ADDD ","ANDB ","BITB ","LDB ","??? ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","??? ","LDU ","??? ",
+ "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ",
+ "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ",
+ "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ",
+ "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU "
+},
+
+mnemonics2[256][6] = {
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","LBRN ","LBHI ","LBLS ","LBHS ","LBLO ","LBNE ","LBEQ ",
+ "LBVC ","LBVS ","LBPL ","LBMI ","LBGE ","LBLT ","LBGT ","LBLE ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI2 ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","??? ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ",
+ "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS "
+},
+
+mnemonics3[256][6] = {
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI3 ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ",
+ "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? "
+},
+
+tregs[16][3] = {
+ "D", "X", "Y", "U", "S", "PC", "??", "??",
+ "A", "B", "CC", "DP", "??", "??", "??", "??"
+},
+
+iregs[4][2] = {"X", "Y", "U", "S" };
+
+//
+// Display bytes in mem in hex
+//
+static void DisplayBytes(V6809REGS regs, uint16 src, uint32 dst)
+{
+ WriteLog("%04X: ", src);
+ uint8 cnt = 0; // Init counter...
+
+ if (src > dst)
+ dst += 0x10000; // That should fix the FFFF bug...
+
+ for(uint32 i=src; i<dst; i++)
+ {
+ WriteLog("%02X ", regs.RdMem(i));
+ cnt++; // Bump counter...
+ }
+
+ for(int i=cnt; i<5; i++) // Pad the leftover spaces...
+ WriteLog(" ");
+}
+
+//
+// Decode a 6809 instruction at 'addr'
+//
+//int Decode6809(uint16 pc)
+int Decode6809(V6809REGS regs)
+{
+ char outbuf[80], mnem[6], tmp[30];
+ uint8 opcode2, operand;
+
+ uint16 addr = regs.pc, offset;
+
+ uint8 opcode = regs.RdMem(addr++); // Get the opcode
+ uint8 admode = op_mat1[opcode]; // addressing mode
+ strcpy(mnem, mnemonics[opcode]); // Copy page 1 opcode
+
+ if (opcode == 0x10) // Extended opcode?
+ {
+ opcode2 = regs.RdMem(addr++); // Then get next byte
+ admode = op_mat2[opcode2]; // And use it as index into 'op_mat2'
+ strcpy(mnem, mnemonics2[opcode2]); // Overwrite mnemonic
+ }
+ else if (opcode == 0x11) // Same as above...
+ {
+ opcode2 = regs.RdMem(addr++);
+ admode = op_mat3[opcode2];
+ strcpy(mnem, mnemonics3[opcode2]); // Overwrite mnemonic
+ }
+
+ switch (admode) // Decode it...
+ {
+ case 0: // Illegal
+ sprintf(outbuf, "???");
+ break;
+ case 1: // Zero page
+ sprintf(outbuf, "%s $%02X", mnem, regs.RdMem(addr++));
+ break;
+ case 2: // Absolute
+// sprintf(outbuf, "%s $%04X", mnem, (regs.RdMem(addr++) << 8) | regs.RdMem(addr++));
+ offset = (regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+ addr += 2;
+ sprintf(outbuf, "%s $%04X", mnem, offset);
+ break;
+ case 3: // Relative
+//DISNOWOK--FIX
+// sprintf(outbuf, "%s $%04X", mnem, ++addr + (int16)((int8)regs.RdMem(addr)));
+ offset = addr + 1 + (int16)(int8)regs.RdMem(addr);
+ addr++;
+ sprintf(outbuf, "%s $%04X", mnem, offset);
+ break;
+ case 4: // Long Relative
+// sprintf(outbuf, "%s $%04X", mnem, addr + (int16)((regs.RdMem(addr++) << 8) | regs.RdMem(addr++)) + 2);
+ offset = addr + (int16)((regs.RdMem(addr) << 8) | regs.RdMem(addr + 1)) + 2;
+ addr += 2;
+ sprintf(outbuf, "%s $%04X", mnem, offset);
+ break;
+ case 5: // Inherent
+ sprintf(outbuf, "%s ", mnem);
+ break;
+ case 6: // Txfr/exchg/push/pull
+ operand = regs.RdMem(addr++); // Get txfr/exg/push/pull byte
+ if ((opcode == 0x1E) || (opcode == 0x1F)) // Is it TXF/EXG?
+ sprintf(tmp, "%s,%s", tregs[operand >> 4], tregs[operand & 0x0F]);
+ else
+ {
+ tmp[0] = 0;
+ if (operand & 0x01) strcat(tmp, "CC ");
+ if (operand & 0x02) strcat(tmp, "A ");
+ if (operand & 0x04) strcat(tmp, "B ");
+ if (operand & 0x08) strcat(tmp, "DP ");
+ if (operand & 0x10) strcat(tmp, "X ");
+ if (operand & 0x20) strcat(tmp, "Y ");
+ if (operand & 0x40) (((opcode == 0x34) || (opcode == 0x35)) ? strcat(tmp, "U ") : strcat(tmp, "S "));
+ if (operand & 0x80) strcat(tmp, "PC");
+ }
+
+ sprintf(outbuf, "%s %s", mnem, tmp);
+ break;
+ case 7: // Indexed (the tough one!)
+ {
+ operand = regs.RdMem(addr++); // Get IDX byte
+ uint8 reg = ((operand & 0x60) >> 5), idxind = ((operand & 0x10) >> 4),
+ lo_nyb = (operand & 0x0F), boff;
+ uint16 woff;
+
+ strcpy(tmp, "??");
+ if (!(operand & 0x80)) // Hi bit set? Then decode 4 bit offset
+ sprintf(tmp, "(%d),%s", (idxind ? -(16-lo_nyb) : lo_nyb), iregs[reg]);
+ else // Add the ($nnnn,R) code dude...
+ {
+ if (idxind)
+ {
+ switch(lo_nyb)
+ {
+ case 1: sprintf(tmp, "(,%s++)", iregs[reg]); break;
+ case 3: sprintf(tmp, "(,--%s)", iregs[reg]); break;
+ case 4: sprintf(tmp, "(,%s)", iregs[reg]); break;
+ case 5: sprintf(tmp, "(B,%s)", iregs[reg]); break;
+ case 6: sprintf(tmp, "(A,%s)", iregs[reg]); break;
+ case 8:
+ boff = regs.RdMem(addr++);
+ sprintf(tmp, "($%02X,%s)", boff, iregs[reg]);
+ break;
+ case 9:
+ woff = (regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+ addr += 2;
+ sprintf(tmp, "($%04X,%s)", woff, iregs[reg]);
+ break;
+ case 11: sprintf(tmp, "(D,%s)", iregs[reg]); break;
+ case 12:
+ boff = regs.RdMem(addr++);
+ sprintf(tmp, "($%02X,PC)", boff);
+ break;
+ case 13:
+ woff = (regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+ addr += 2;
+ sprintf(tmp, "($%04X,PC)", woff);
+ break;
+ case 15:
+ woff = (regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+ addr += 2;
+ sprintf(tmp, "[$%04X]", woff);
+ break;
+ default:
+ strcpy(tmp, "??");
+ }
+ }
+ else
+ {
+ switch(lo_nyb)
+ {
+ case 0: sprintf(tmp, ",%s+", iregs[reg]); break;
+ case 1: sprintf(tmp, ",%s++", iregs[reg]); break;
+ case 2: sprintf(tmp, ",-%s", iregs[reg]); break;
+ case 3: sprintf(tmp, ",--%s", iregs[reg]); break;
+ case 4: sprintf(tmp, ",%s", iregs[reg]); break;
+ case 5: sprintf(tmp, "(B),%s", iregs[reg]); break;
+ case 6: sprintf(tmp, "(A),%s", iregs[reg]); break;
+ case 8:
+ boff = regs.RdMem(addr++);
+ sprintf(tmp, "($%02X),%s", boff, iregs[reg]);
+ break;
+ case 9:
+ woff = (regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+ addr += 2;
+ sprintf(tmp, "($%04X),%s", woff, iregs[reg]);
+ break;
+ case 11:
+ sprintf(tmp, "(D),%s", iregs[reg]);
+ break;
+ case 12:
+ boff = regs.RdMem(addr++);
+ sprintf(tmp, "($%02X),PC", boff);
+ break;
+ case 13:
+ woff = (regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+ addr += 2;
+ sprintf(tmp, "($%04X),PC", woff);
+ break;
+ default:
+ strcpy(tmp, "??");
+ }
+ }
+ }
+ sprintf(outbuf, "%s %s", mnem, tmp);
+ break;
+ }
+ case 8: // Immediate
+ sprintf(outbuf, "%s #$%02X", mnem, regs.RdMem(addr++));
+ break;
+ case 9: // Long Immediate
+// sprintf(outbuf, "%s #$%04X", mnem, (regs.RdMem(addr++) << 8) | regs.RdMem(addr++));
+ offset = (regs.RdMem(addr) << 8) | regs.RdMem(addr + 1);
+ addr += 2;
+ sprintf(outbuf, "%s #$%04X", mnem, offset);
+ break;
+ }
+
+ DisplayBytes(regs, regs.pc, addr); // Show bytes
+ WriteLog("%s", outbuf); // Display opcode & addressing, etc.
+
+ return addr - regs.pc;
+}