gnuboy-for-dfi/debug.c

690 lines
8.9 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include "defs.h"
#include "cpu.h"
#include "mem.h"
#include "fastmem.h"
#include "regs.h"
#include "rc.h"
#include "cpuregs.h"
static char *mnemonic_table[256] =
{
"NOP",
"LD BC,%w",
"LD (BC),A",
"INC BC",
"INC B",
"DEC B",
"LD B,%b",
"RLCA",
"LD (%w),SP",
"ADD HL,BC",
"LD A,(BC)",
"DEC BC",
"INC C",
"DEC C",
"LD C,%b",
"RRCA",
"STOP",
"LD DE,%w",
"LD (DE),A",
"INC DE",
"INC D",
"DEC D",
"LD D,%b",
"RLA",
"JR %o",
"ADD HL,DE",
"LD A,(DE)",
"DEC DE",
"INC E",
"DEC E",
"LD E,%b",
"RRA",
"JR NZ,%o",
"LD HL,%w",
"LD (HLI),A",
"INC HL",
"INC H",
"DEC H",
"LD H,%b",
"DAA",
"JR Z,%o",
"ADD HL,HL",
"LD A,(HLI)",
"DEC HL",
"INC L",
"DEC L",
"LD L,%b",
"CPL",
"JR NC,%o",
"LD SP,%w",
"LD (HLD),A",
"INC SP",
"INC (HL)",
"DEC (HL)",
"LD (HL),%b",
"SCF",
"JR C,%o",
"ADD HL,SP",
"LD A,(HLD)",
"DEC SP",
"INC A",
"DEC A",
"LD A,%b",
"CCF",
"LD B,B",
"LD B,C",
"LD B,D",
"LD B,E",
"LD B,H",
"LD B,L",
"LD B,(HL)",
"LD B,A",
"LD C,B",
"LD C,C",
"LD C,D",
"LD C,E",
"LD C,H",
"LD C,L",
"LD C,(HL)",
"LD C,A",
"LD D,B",
"LD D,C",
"LD D,D",
"LD D,E",
"LD D,H",
"LD D,L",
"LD D,(HL)",
"LD D,A",
"LD E,B",
"LD E,C",
"LD E,D",
"LD E,E",
"LD E,H",
"LD E,L",
"LD E,(HL)",
"LD E,A",
"LD H,B",
"LD H,C",
"LD H,D",
"LD H,E",
"LD H,H",
"LD H,L",
"LD H,(HL)",
"LD H,A",
"LD L,B",
"LD L,C",
"LD L,D",
"LD L,E",
"LD L,H",
"LD L,L",
"LD L,(HL)",
"LD L,A",
"LD (HL),B",
"LD (HL),C",
"LD (HL),D",
"LD (HL),E",
"LD (HL),H",
"LD (HL),L",
"HALT",
"LD (HL),A",
"LD A,B",
"LD A,C",
"LD A,D",
"LD A,E",
"LD A,H",
"LD A,L",
"LD A,(HL)",
"LD A,A",
"ADD A,B",
"ADD A,C",
"ADD A,D",
"ADD A,E",
"ADD A,H",
"ADD A,L",
"ADD A,(HL)",
"ADD A,A",
"ADC A,B",
"ADC A,C",
"ADC A,D",
"ADC A,E",
"ADC A,H",
"ADC A,L",
"ADC A,(HL)",
"ADC A",
"SUB B",
"SUB C",
"SUB D",
"SUB E",
"SUB H",
"SUB L",
"SUB (HL)",
"SUB A",
"SBC A,B",
"SBC A,C",
"SBC A,D",
"SBC A,E",
"SBC A,H",
"SBC A,L",
"SBC A,(HL)",
"SBC A,A",
"AND B",
"AND C",
"AND D",
"AND E",
"AND H",
"AND L",
"AND (HL)",
"AND A",
"XOR B",
"XOR C",
"XOR D",
"XOR E",
"XOR H",
"XOR L",
"XOR (HL)",
"XOR A",
"OR B",
"OR C",
"OR D",
"OR E",
"OR H",
"OR L",
"OR (HL)",
"OR A",
"CP B",
"CP C",
"CP D",
"CP E",
"CP H",
"CP L",
"CP (HL)",
"CP A",
"RET NZ",
"POP BC",
"JP NZ,%w",
"JP %w",
"CALL NZ,%w",
"PUSH BC",
"ADD A,%b",
"RST 0h",
"RET Z",
"RET",
"JP Z,%w",
NULL,
"CALL Z,%w",
"CALL %w",
"ADC A,%b",
"RST 8h",
"RET NC",
"POP DE",
"JP NC,%w",
NULL,
"CALL NC,%w",
"PUSH DE",
"SUB %b",
"RST 10h",
"RET C",
"RETI",
"JP C,%w",
NULL,
"CALL C,%w",
NULL,
"SBC A,%b",
"RST 18h",
"LD (FF00+%b),A",
"POP HL",
"LD (FF00+C),A",
NULL,
NULL,
"PUSH HL",
"AND %b",
"RST 20h",
"ADD SP,%o",
"JP HL",
"LD (%w),A",
NULL,
NULL,
NULL,
"XOR %b",
"RST 28h",
"LD A,(FF00+%b)",
"POP AF",
"LD A,(FF00+C)",
"DI",
NULL,
"PUSH AF",
"OR %b",
"RST 30h",
"LD HL,SP%o",
"LD SP,HL",
"LD A,(%w)",
"EI",
NULL,
NULL,
"CP %b",
"RST 38h"
};
static char *cb_mnemonic_table[256] =
{
"RLC B",
"RLC C",
"RLC D",
"RLC E",
"RLC H",
"RLC L",
"RLC (HL)",
"RLC A",
"RRC B",
"RRC C",
"RRC D",
"RRC E",
"RRC H",
"RRC L",
"RRC (HL)",
"RRC A",
"RL B",
"RL C",
"RL D",
"RL E",
"RL H",
"RL L",
"RL (HL)",
"RL A",
"RR B",
"RR C",
"RR D",
"RR E",
"RR H",
"RR L",
"RR (HL)",
"RR A",
"SLA B",
"SLA C",
"SLA D",
"SLA E",
"SLA H",
"SLA L",
"SLA (HL)",
"SLA A",
"SRA B",
"SRA C",
"SRA D",
"SRA E",
"SRA H",
"SRA L",
"SRA (HL)",
"SRA A",
"SWAP B",
"SWAP C",
"SWAP D",
"SWAP E",
"SWAP H",
"SWAP L",
"SWAP (HL)",
"SWAP A",
"SRL B",
"SRL C",
"SRL D",
"SRL E",
"SRL H",
"SRL L",
"SRL (HL)",
"SRL A",
"BIT 0,B",
"BIT 0,C",
"BIT 0,D",
"BIT 0,E",
"BIT 0,H",
"BIT 0,L",
"BIT 0,(HL)",
"BIT 0,A",
"BIT 1,B",
"BIT 1,C",
"BIT 1,D",
"BIT 1,E",
"BIT 1,H",
"BIT 1,L",
"BIT 1,(HL)",
"BIT 1,A",
"BIT 2,B",
"BIT 2,C",
"BIT 2,D",
"BIT 2,E",
"BIT 2,H",
"BIT 2,L",
"BIT 2,(HL)",
"BIT 2,A",
"BIT 3,B",
"BIT 3,C",
"BIT 3,D",
"BIT 3,E",
"BIT 3,H",
"BIT 3,L",
"BIT 3,(HL)",
"BIT 3,A",
"BIT 4,B",
"BIT 4,C",
"BIT 4,D",
"BIT 4,E",
"BIT 4,H",
"BIT 4,L",
"BIT 4,(HL)",
"BIT 4,A",
"BIT 5,B",
"BIT 5,C",
"BIT 5,D",
"BIT 5,E",
"BIT 5,H",
"BIT 5,L",
"BIT 5,(HL)",
"BIT 5,A",
"BIT 6,B",
"BIT 6,C",
"BIT 6,D",
"BIT 6,E",
"BIT 6,H",
"BIT 6,L",
"BIT 6,(HL)",
"BIT 6,A",
"BIT 7,B",
"BIT 7,C",
"BIT 7,D",
"BIT 7,E",
"BIT 7,H",
"BIT 7,L",
"BIT 7,(HL)",
"BIT 7,A",
"RES 0,B",
"RES 0,C",
"RES 0,D",
"RES 0,E",
"RES 0,H",
"RES 0,L",
"RES 0,(HL)",
"RES 0,A",
"RES 1,B",
"RES 1,C",
"RES 1,D",
"RES 1,E",
"RES 1,H",
"RES 1,L",
"RES 1,(HL)",
"RES 1,A",
"RES 2,B",
"RES 2,C",
"RES 2,D",
"RES 2,E",
"RES 2,H",
"RES 2,L",
"RES 2,(HL)",
"RES 2,A",
"RES 3,B",
"RES 3,C",
"RES 3,D",
"RES 3,E",
"RES 3,H",
"RES 3,L",
"RES 3,(HL)",
"RES 3,A",
"RES 4,B",
"RES 4,C",
"RES 4,D",
"RES 4,E",
"RES 4,H",
"RES 4,L",
"RES 4,(HL)",
"RES 4,A",
"RES 5,B",
"RES 5,C",
"RES 5,D",
"RES 5,E",
"RES 5,H",
"RES 5,L",
"RES 5,(HL)",
"RES 5,A",
"RES 6,B",
"RES 6,C",
"RES 6,D",
"RES 6,E",
"RES 6,H",
"RES 6,L",
"RES 6,(HL)",
"RES 6,A",
"RES 7,B",
"RES 7,C",
"RES 7,D",
"RES 7,E",
"RES 7,H",
"RES 7,L",
"RES 7,(HL)",
"RES 7,A",
"SET 0,B",
"SET 0,C",
"SET 0,D",
"SET 0,E",
"SET 0,H",
"SET 0,L",
"SET 0,(HL)",
"SET 0,A",
"SET 1,B",
"SET 1,C",
"SET 1,D",
"SET 1,E",
"SET 1,H",
"SET 1,L",
"SET 1,(HL)",
"SET 1,A",
"SET 2,B",
"SET 2,C",
"SET 2,D",
"SET 2,E",
"SET 2,H",
"SET 2,L",
"SET 2,(HL)",
"SET 2,A",
"SET 3,B",
"SET 3,C",
"SET 3,D",
"SET 3,E",
"SET 3,H",
"SET 3,L",
"SET 3,(HL)",
"SET 3,A",
"SET 4,B",
"SET 4,C",
"SET 4,D",
"SET 4,E",
"SET 4,H",
"SET 4,L",
"SET 4,(HL)",
"SET 4,A",
"SET 5,B",
"SET 5,C",
"SET 5,D",
"SET 5,E",
"SET 5,H",
"SET 5,L",
"SET 5,(HL)",
"SET 5,A",
"SET 6,B",
"SET 6,C",
"SET 6,D",
"SET 6,E",
"SET 6,H",
"SET 6,L",
"SET 6,(HL)",
"SET 6,A",
"SET 7,B",
"SET 7,C",
"SET 7,D",
"SET 7,E",
"SET 7,H",
"SET 7,L",
"SET 7,(HL)",
"SET 7,A"
};
static byte operand_count[256] =
{
1, 3, 1, 1, 1, 1, 2, 1, 3, 1, 1, 1, 1, 1, 2, 1,
1, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1,
2, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1,
2, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 3, 3, 3, 1, 2, 1, 1, 1, 3, 2, 3, 3, 2, 1,
1, 1, 3, 1, 3, 1, 2, 1, 1, 1, 3, 1, 3, 1, 2, 1,
2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, 2, 1,
2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 1, 1, 2, 1
};
/* replace with a real interactive debugger eventually... */
int debug_trace = 0;
rcvar_t debug_exports[] =
{
RCV_BOOL("trace", &debug_trace),
RCV_END
};
void debug_disassemble(addr a, int c)
{
static int i, j, k;
static byte code;
static byte ops[3];
static int opaddr;
static char mnemonic[256];
static char *pattern;
if (!debug_trace) return;
while (c > 0)
{
k = 0;
opaddr = a;
code = ops[k++] = readb(a); a++;
if (code != 0xCB)
{
pattern = mnemonic_table[code];
if (!pattern)
pattern = "***INVALID***";
}
else
{
code = ops[k++] = readb(a); a++;
pattern = cb_mnemonic_table[code];
}
i = j = 0;
while (pattern[i])
{
if (pattern[i] == '%')
{
switch (pattern[++i])
{
case 'B':
case 'b':
ops[k] = readb(a); a++;
j += sprintf(mnemonic + j,
"%02Xh", ops[k++]);
break;
case 'W':
case 'w':
ops[k] = readb(a); a++;
ops[k+1] = readb(a); a++;
j += sprintf(mnemonic + j, "%04Xh",
((ops[k+1] << 8) | ops[k]));
k += 2;
break;
case 'O':
case 'o':
ops[k] = readb(a); a++;
j += sprintf(mnemonic + j, "%+d",
(n8)(ops[k++]));
break;
}
i++;
}
else
{
mnemonic[j++] = pattern[i++];
}
}
mnemonic[j] = 0;
printf("%04X ", opaddr);
switch (operand_count[ops[0]]) {
case 1:
printf("%02X ", ops[0]);
break;
case 2:
printf("%02X %02X ", ops[0], ops[1]);
break;
case 3:
printf("%02X %02X %02X ", ops[0], ops[1], ops[2]);
break;
}
printf("%-16.16s", mnemonic);
printf(
" SP=%04X.%04X BC=%04X.%02X.%02X DE=%04X.%02X "
"HL=%04X.%02X A=%02X F=%02X %c%c%c%c%c",
SP, readw(SP),
BC, readb(BC), readb(0xFF00 | C),
DE, readb(DE),
HL, readb(HL), A,
F, (IME ? 'I' : '-'),
((F & 0x80) ? 'Z' : '-'),
((F & 0x40) ? 'N' : '-'),
((F & 0x20) ? 'H' : '-'),
((F & 0x10) ? 'C' : '-')
);
printf(
" IE=%02X IF=%02X LCDC=%02X STAT=%02X LY=%02X LYC=%02X",
R_IE, R_IF, R_LCDC, R_STAT, R_LY, R_LYC
);
printf("\n");
fflush(stdout);
c--;
}
}