1 |
/** Z80: portable Z80 emulator *******************************/ |
2 |
/** **/ |
3 |
/** Debug.c **/ |
4 |
/** **/ |
5 |
/** This file contains the built-in debugging routine for **/ |
6 |
/** the Z80 emulator which is called on each Z80 step when **/ |
7 |
/** Trap!=0. **/ |
8 |
/** **/ |
9 |
/** Copyright (C) Marat Fayzullin 1995-2007 **/ |
10 |
/** You are not allowed to distribute this software **/ |
11 |
/** commercially. Please, notify me, if you make any **/ |
12 |
/** changes to this file. **/ |
13 |
/*************************************************************/ |
14 |
#ifdef DEBUG |
15 |
|
16 |
#include "Z80.h" |
17 |
|
18 |
#include <stdio.h> |
19 |
#include <ctype.h> |
20 |
#include <string.h> |
21 |
|
22 |
#ifdef FMSX |
23 |
#include "AY8910.h" |
24 |
extern AY8910 PSG; |
25 |
#endif |
26 |
|
27 |
static const char *Mnemonics[256] = |
28 |
{ |
29 |
"NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA", |
30 |
"EX AF,AF'","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA", |
31 |
"DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA", |
32 |
"JR @h","ADD HL,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA", |
33 |
"JR NZ,@h","LD HL,#h","LD (#h),HL","INC HL","INC H","DEC H","LD H,*h","DAA", |
34 |
"JR Z,@h","ADD HL,HL","LD HL,(#h)","DEC HL","INC L","DEC L","LD L,*h","CPL", |
35 |
"JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (HL)","DEC (HL)","LD (HL),*h","SCF", |
36 |
"JR C,@h","ADD HL,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF", |
37 |
"LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A", |
38 |
"LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A", |
39 |
"LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A", |
40 |
"LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A", |
41 |
"LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A", |
42 |
"LD L,B","LD L,C","LD L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A", |
43 |
"LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A", |
44 |
"LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A", |
45 |
"ADD B","ADD C","ADD D","ADD E","ADD H","ADD L","ADD (HL)","ADD A", |
46 |
"ADC B","ADC C","ADC D","ADC E","ADC H","ADC L","ADC (HL)","ADC A", |
47 |
"SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A", |
48 |
"SBC B","SBC C","SBC D","SBC E","SBC H","SBC L","SBC (HL)","SBC A", |
49 |
"AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A", |
50 |
"XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A", |
51 |
"OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)","OR A", |
52 |
"CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A", |
53 |
"RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h", |
54 |
"RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h", |
55 |
"RET NC","POP DE","JP NC,#h","OUTA (*h)","CALL NC,#h","PUSH DE","SUB *h","RST 10h", |
56 |
"RET C","EXX","JP C,#h","INA (*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h", |
57 |
"RET PO","POP HL","JP PO,#h","EX HL,(SP)","CALL PO,#h","PUSH HL","AND *h","RST 20h", |
58 |
"RET PE","LD PC,HL","JP PE,#h","EX DE,HL","CALL PE,#h","PFX_ED","XOR *h","RST 28h", |
59 |
"RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h", |
60 |
"RET M","LD SP,HL","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h" |
61 |
}; |
62 |
|
63 |
static const char *MnemonicsCB[256] = |
64 |
{ |
65 |
"RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (HL)","RLC A", |
66 |
"RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (HL)","RRC A", |
67 |
"RL B","RL C","RL D","RL E","RL H","RL L","RL (HL)","RL A", |
68 |
"RR B","RR C","RR D","RR E","RR H","RR L","RR (HL)","RR A", |
69 |
"SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (HL)","SLA A", |
70 |
"SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (HL)","SRA A", |
71 |
"SLL B","SLL C","SLL D","SLL E","SLL H","SLL L","SLL (HL)","SLL A", |
72 |
"SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (HL)","SRL A", |
73 |
"BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(HL)","BIT 0,A", |
74 |
"BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(HL)","BIT 1,A", |
75 |
"BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(HL)","BIT 2,A", |
76 |
"BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(HL)","BIT 3,A", |
77 |
"BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(HL)","BIT 4,A", |
78 |
"BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(HL)","BIT 5,A", |
79 |
"BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(HL)","BIT 6,A", |
80 |
"BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(HL)","BIT 7,A", |
81 |
"RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(HL)","RES 0,A", |
82 |
"RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(HL)","RES 1,A", |
83 |
"RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(HL)","RES 2,A", |
84 |
"RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(HL)","RES 3,A", |
85 |
"RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(HL)","RES 4,A", |
86 |
"RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(HL)","RES 5,A", |
87 |
"RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(HL)","RES 6,A", |
88 |
"RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(HL)","RES 7,A", |
89 |
"SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(HL)","SET 0,A", |
90 |
"SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(HL)","SET 1,A", |
91 |
"SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(HL)","SET 2,A", |
92 |
"SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(HL)","SET 3,A", |
93 |
"SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(HL)","SET 4,A", |
94 |
"SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(HL)","SET 5,A", |
95 |
"SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(HL)","SET 6,A", |
96 |
"SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(HL)","SET 7,A" |
97 |
}; |
98 |
|
99 |
static const char *MnemonicsED[256] = |
100 |
{ |
101 |
"DB EDh,00h","DB EDh,01h","DB EDh,02h","DB EDh,03h", |
102 |
"DB EDh,04h","DB EDh,05h","DB EDh,06h","DB EDh,07h", |
103 |
"DB EDh,08h","DB EDh,09h","DB EDh,0Ah","DB EDh,0Bh", |
104 |
"DB EDh,0Ch","DB EDh,0Dh","DB EDh,0Eh","DB EDh,0Fh", |
105 |
"DB EDh,10h","DB EDh,11h","DB EDh,12h","DB EDh,13h", |
106 |
"DB EDh,14h","DB EDh,15h","DB EDh,16h","DB EDh,17h", |
107 |
"DB EDh,18h","DB EDh,19h","DB EDh,1Ah","DB EDh,1Bh", |
108 |
"DB EDh,1Ch","DB EDh,1Dh","DB EDh,1Eh","DB EDh,1Fh", |
109 |
"DB EDh,20h","DB EDh,21h","DB EDh,22h","DB EDh,23h", |
110 |
"DB EDh,24h","DB EDh,25h","DB EDh,26h","DB EDh,27h", |
111 |
"DB EDh,28h","DB EDh,29h","DB EDh,2Ah","DB EDh,2Bh", |
112 |
"DB EDh,2Ch","DB EDh,2Dh","DB EDh,2Eh","DB EDh,2Fh", |
113 |
"DB EDh,30h","DB EDh,31h","DB EDh,32h","DB EDh,33h", |
114 |
"DB EDh,34h","DB EDh,35h","DB EDh,36h","DB EDh,37h", |
115 |
"DB EDh,38h","DB EDh,39h","DB EDh,3Ah","DB EDh,3Bh", |
116 |
"DB EDh,3Ch","DB EDh,3Dh","DB EDh,3Eh","DB EDh,3Fh", |
117 |
"IN B,(C)","OUT (C),B","SBC HL,BC","LD (#h),BC", |
118 |
"NEG","RETN","IM 0","LD I,A", |
119 |
"IN C,(C)","OUT (C),C","ADC HL,BC","LD BC,(#h)", |
120 |
"DB EDh,4Ch","RETI","DB EDh,4Eh","LD R,A", |
121 |
"IN D,(C)","OUT (C),D","SBC HL,DE","LD (#h),DE", |
122 |
"DB EDh,54h","DB EDh,55h","IM 1","LD A,I", |
123 |
"IN E,(C)","OUT (C),E","ADC HL,DE","LD DE,(#h)", |
124 |
"DB EDh,5Ch","DB EDh,5Dh","IM 2","LD A,R", |
125 |
"IN H,(C)","OUT (C),H","SBC HL,HL","LD (#h),HL", |
126 |
"DB EDh,64h","DB EDh,65h","DB EDh,66h","RRD", |
127 |
"IN L,(C)","OUT (C),L","ADC HL,HL","LD HL,(#h)", |
128 |
"DB EDh,6Ch","DB EDh,6Dh","DB EDh,6Eh","RLD", |
129 |
"IN F,(C)","DB EDh,71h","SBC HL,SP","LD (#h),SP", |
130 |
"DB EDh,74h","DB EDh,75h","DB EDh,76h","DB EDh,77h", |
131 |
"IN A,(C)","OUT (C),A","ADC HL,SP","LD SP,(#h)", |
132 |
"DB EDh,7Ch","DB EDh,7Dh","DB EDh,7Eh","DB EDh,7Fh", |
133 |
"DB EDh,80h","DB EDh,81h","DB EDh,82h","DB EDh,83h", |
134 |
"DB EDh,84h","DB EDh,85h","DB EDh,86h","DB EDh,87h", |
135 |
"DB EDh,88h","DB EDh,89h","DB EDh,8Ah","DB EDh,8Bh", |
136 |
"DB EDh,8Ch","DB EDh,8Dh","DB EDh,8Eh","DB EDh,8Fh", |
137 |
"DB EDh,90h","DB EDh,91h","DB EDh,92h","DB EDh,93h", |
138 |
"DB EDh,94h","DB EDh,95h","DB EDh,96h","DB EDh,97h", |
139 |
"DB EDh,98h","DB EDh,99h","DB EDh,9Ah","DB EDh,9Bh", |
140 |
"DB EDh,9Ch","DB EDh,9Dh","DB EDh,9Eh","DB EDh,9Fh", |
141 |
"LDI","CPI","INI","OUTI", |
142 |
"DB EDh,A4h","DB EDh,A5h","DB EDh,A6h","DB EDh,A7h", |
143 |
"LDD","CPD","IND","OUTD", |
144 |
"DB EDh,ACh","DB EDh,ADh","DB EDh,AEh","DB EDh,AFh", |
145 |
"LDIR","CPIR","INIR","OTIR", |
146 |
"DB EDh,B4h","DB EDh,B5h","DB EDh,B6h","DB EDh,B7h", |
147 |
"LDDR","CPDR","INDR","OTDR", |
148 |
"DB EDh,BCh","DB EDh,BDh","DB EDh,BEh","DB EDh,BFh", |
149 |
"DB EDh,C0h","DB EDh,C1h","DB EDh,C2h","DB EDh,C3h", |
150 |
"DB EDh,C4h","DB EDh,C5h","DB EDh,C6h","DB EDh,C7h", |
151 |
"DB EDh,C8h","DB EDh,C9h","DB EDh,CAh","DB EDh,CBh", |
152 |
"DB EDh,CCh","DB EDh,CDh","DB EDh,CEh","DB EDh,CFh", |
153 |
"DB EDh,D0h","DB EDh,D1h","DB EDh,D2h","DB EDh,D3h", |
154 |
"DB EDh,D4h","DB EDh,D5h","DB EDh,D6h","DB EDh,D7h", |
155 |
"DB EDh,D8h","DB EDh,D9h","DB EDh,DAh","DB EDh,DBh", |
156 |
"DB EDh,DCh","DB EDh,DDh","DB EDh,DEh","DB EDh,DFh", |
157 |
"DB EDh,E0h","DB EDh,E1h","DB EDh,E2h","DB EDh,E3h", |
158 |
"DB EDh,E4h","DB EDh,E5h","DB EDh,E6h","DB EDh,E7h", |
159 |
"DB EDh,E8h","DB EDh,E9h","DB EDh,EAh","DB EDh,EBh", |
160 |
"DB EDh,ECh","DB EDh,EDh","DB EDh,EEh","DB EDh,EFh", |
161 |
"DB EDh,F0h","DB EDh,F1h","DB EDh,F2h","DB EDh,F3h", |
162 |
"DB EDh,F4h","DB EDh,F5h","DB EDh,F6h","DB EDh,F7h", |
163 |
"DB EDh,F8h","DB EDh,F9h","DB EDh,FAh","DB EDh,FBh", |
164 |
"DB EDh,FCh","DB EDh,FDh","DB EDh,FEh","DB EDh,FFh" |
165 |
}; |
166 |
|
167 |
static const char *MnemonicsXX[256] = |
168 |
{ |
169 |
"NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA", |
170 |
"EX AF,AF'","ADD I%,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA", |
171 |
"DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA", |
172 |
"JR @h","ADD I%,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA", |
173 |
"JR NZ,@h","LD I%,#h","LD (#h),I%","INC I%","INC I%h","DEC I%h","LD I%h,*h","DAA", |
174 |
"JR Z,@h","ADD I%,I%","LD I%,(#h)","DEC I%","INC I%l","DEC I%l","LD I%l,*h","CPL", |
175 |
"JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (I%+^h)","DEC (I%+^h)","LD (I%+^h),*h","SCF", |
176 |
"JR C,@h","ADD I%,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF", |
177 |
"LD B,B","LD B,C","LD B,D","LD B,E","LD B,I%h","LD B,I%l","LD B,(I%+^h)","LD B,A", |
178 |
"LD C,B","LD C,C","LD C,D","LD C,E","LD C,I%h","LD C,I%l","LD C,(I%+^h)","LD C,A", |
179 |
"LD D,B","LD D,C","LD D,D","LD D,E","LD D,I%h","LD D,I%l","LD D,(I%+^h)","LD D,A", |
180 |
"LD E,B","LD E,C","LD E,D","LD E,E","LD E,I%h","LD E,I%l","LD E,(I%+^h)","LD E,A", |
181 |
"LD I%h,B","LD I%h,C","LD I%h,D","LD I%h,E","LD I%h,I%h","LD I%h,I%l","LD H,(I%+^h)","LD I%h,A", |
182 |
"LD I%l,B","LD I%l,C","LD I%l,D","LD I%l,E","LD I%l,I%h","LD I%l,I%l","LD L,(I%+^h)","LD I%l,A", |
183 |
"LD (I%+^h),B","LD (I%+^h),C","LD (I%+^h),D","LD (I%+^h),E","LD (I%+^h),H","LD (I%+^h),L","HALT","LD (I%+^h),A", |
184 |
"LD A,B","LD A,C","LD A,D","LD A,E","LD A,I%h","LD A,I%l","LD A,(I%+^h)","LD A,A", |
185 |
"ADD B","ADD C","ADD D","ADD E","ADD I%h","ADD I%l","ADD (I%+^h)","ADD A", |
186 |
"ADC B","ADC C","ADC D","ADC E","ADC I%h","ADC I%l","ADC (I%+^h)","ADC,A", |
187 |
"SUB B","SUB C","SUB D","SUB E","SUB I%h","SUB I%l","SUB (I%+^h)","SUB A", |
188 |
"SBC B","SBC C","SBC D","SBC E","SBC I%h","SBC I%l","SBC (I%+^h)","SBC A", |
189 |
"AND B","AND C","AND D","AND E","AND I%h","AND I%l","AND (I%+^h)","AND A", |
190 |
"XOR B","XOR C","XOR D","XOR E","XOR I%h","XOR I%l","XOR (I%+^h)","XOR A", |
191 |
"OR B","OR C","OR D","OR E","OR I%h","OR I%l","OR (I%+^h)","OR A", |
192 |
"CP B","CP C","CP D","CP E","CP I%h","CP I%l","CP (I%+^h)","CP A", |
193 |
"RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h", |
194 |
"RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h", |
195 |
"RET NC","POP DE","JP NC,#h","OUTA (*h)","CALL NC,#h","PUSH DE","SUB *h","RST 10h", |
196 |
"RET C","EXX","JP C,#h","INA (*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h", |
197 |
"RET PO","POP I%","JP PO,#h","EX I%,(SP)","CALL PO,#h","PUSH I%","AND *h","RST 20h", |
198 |
"RET PE","LD PC,I%","JP PE,#h","EX DE,I%","CALL PE,#h","PFX_ED","XOR *h","RST 28h", |
199 |
"RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h", |
200 |
"RET M","LD SP,I%","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h" |
201 |
}; |
202 |
|
203 |
static const char *MnemonicsXCB[256] = |
204 |
{ |
205 |
"RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (I%@h)","RLC A", |
206 |
"RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (I%@h)","RRC A", |
207 |
"RL B","RL C","RL D","RL E","RL H","RL L","RL (I%@h)","RL A", |
208 |
"RR B","RR C","RR D","RR E","RR H","RR L","RR (I%@h)","RR A", |
209 |
"SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (I%@h)","SLA A", |
210 |
"SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (I%@h)","SRA A", |
211 |
"SLL B","SLL C","SLL D","SLL E","SLL H","SLL L","SLL (I%@h)","SLL A", |
212 |
"SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (I%@h)","SRL A", |
213 |
"BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(I%@h)","BIT 0,A", |
214 |
"BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(I%@h)","BIT 1,A", |
215 |
"BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(I%@h)","BIT 2,A", |
216 |
"BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(I%@h)","BIT 3,A", |
217 |
"BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(I%@h)","BIT 4,A", |
218 |
"BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(I%@h)","BIT 5,A", |
219 |
"BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(I%@h)","BIT 6,A", |
220 |
"BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(I%@h)","BIT 7,A", |
221 |
"RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(I%@h)","RES 0,A", |
222 |
"RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(I%@h)","RES 1,A", |
223 |
"RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(I%@h)","RES 2,A", |
224 |
"RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(I%@h)","RES 3,A", |
225 |
"RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(I%@h)","RES 4,A", |
226 |
"RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(I%@h)","RES 5,A", |
227 |
"RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(I%@h)","RES 6,A", |
228 |
"RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(I%@h)","RES 7,A", |
229 |
"SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(I%@h)","SET 0,A", |
230 |
"SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(I%@h)","SET 1,A", |
231 |
"SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(I%@h)","SET 2,A", |
232 |
"SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(I%@h)","SET 3,A", |
233 |
"SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(I%@h)","SET 4,A", |
234 |
"SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(I%@h)","SET 5,A", |
235 |
"SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(I%@h)","SET 6,A", |
236 |
"SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(I%@h)","SET 7,A" |
237 |
}; |
238 |
|
239 |
/** DAsm() ***************************************************/ |
240 |
/** DAsm() will disassemble the code at adress A and put **/ |
241 |
/** the output text into S. It will return the number of **/ |
242 |
/** bytes disassembled. **/ |
243 |
/*************************************************************/ |
244 |
static int DAsm(char *S,word A) |
245 |
{ |
246 |
char R[128],H[10],C,*P; |
247 |
const char *T; |
248 |
byte J,Offset; |
249 |
word B; |
250 |
|
251 |
Offset=0; |
252 |
B=A; |
253 |
C='\0'; |
254 |
J=0; |
255 |
|
256 |
switch(RdZ80(B)) |
257 |
{ |
258 |
case 0xCB: B++;T=MnemonicsCB[RdZ80(B++)];break; |
259 |
case 0xED: B++;T=MnemonicsED[RdZ80(B++)];break; |
260 |
case 0xDD: B++;C='X'; |
261 |
if(RdZ80(B)!=0xCB) T=MnemonicsXX[RdZ80(B++)]; |
262 |
else |
263 |
{ B++;Offset=RdZ80(B++);J=1;T=MnemonicsXCB[RdZ80(B++)]; } |
264 |
break; |
265 |
case 0xFD: B++;C='Y'; |
266 |
if(RdZ80(B)!=0xCB) T=MnemonicsXX[RdZ80(B++)]; |
267 |
else |
268 |
{ B++;Offset=RdZ80(B++);J=1;T=MnemonicsXCB[RdZ80(B++)]; } |
269 |
break; |
270 |
default: T=Mnemonics[RdZ80(B++)]; |
271 |
} |
272 |
|
273 |
if(P=strchr(T,'^')) |
274 |
{ |
275 |
strncpy(R,T,P-T);R[P-T]='\0'; |
276 |
sprintf(H,"%02X",RdZ80(B++)); |
277 |
strcat(R,H);strcat(R,P+1); |
278 |
} |
279 |
else strcpy(R,T); |
280 |
if(P=strchr(R,'%')) *P=C; |
281 |
|
282 |
if(P=strchr(R,'*')) |
283 |
{ |
284 |
strncpy(S,R,P-R);S[P-R]='\0'; |
285 |
sprintf(H,"%02X",RdZ80(B++)); |
286 |
strcat(S,H);strcat(S,P+1); |
287 |
} |
288 |
else |
289 |
if(P=strchr(R,'@')) |
290 |
{ |
291 |
strncpy(S,R,P-R);S[P-R]='\0'; |
292 |
if(!J) Offset=RdZ80(B++); |
293 |
strcat(S,Offset&0x80? "-":"+"); |
294 |
J=Offset&0x80? 256-Offset:Offset; |
295 |
sprintf(H,"%02X",J); |
296 |
strcat(S,H);strcat(S,P+1); |
297 |
} |
298 |
else |
299 |
if(P=strchr(R,'#')) |
300 |
{ |
301 |
strncpy(S,R,P-R);S[P-R]='\0'; |
302 |
sprintf(H,"%04X",RdZ80(B)+256*RdZ80(B+1)); |
303 |
strcat(S,H);strcat(S,P+1); |
304 |
B+=2; |
305 |
} |
306 |
else strcpy(S,R); |
307 |
|
308 |
return(B-A); |
309 |
} |
310 |
|
311 |
/** DebugZ80() ***********************************************/ |
312 |
/** This function should exist if DEBUG is #defined. When **/ |
313 |
/** Trace!=0, it is called after each command executed by **/ |
314 |
/** the CPU, and given the Z80 registers. **/ |
315 |
/*************************************************************/ |
316 |
byte DebugZ80(Z80 *R) |
317 |
{ |
318 |
static const char Flags[9] = "SZ.H.PNC"; |
319 |
char S[128],T[10]; |
320 |
byte J,I; |
321 |
|
322 |
DAsm(S,R->PC.W); |
323 |
for(J=0,I=R->AF.B.l;J<8;J++,I<<=1) T[J]=I&0x80? Flags[J]:'.'; |
324 |
T[8]='\0'; |
325 |
|
326 |
printf |
327 |
( |
328 |
"AF:%04X HL:%04X DE:%04X BC:%04X PC:%04X SP:%04X IX:%04X IY:%04X I:%02X\n", |
329 |
R->AF.W,R->HL.W,R->DE.W,R->BC.W,R->PC.W,R->SP.W,R->IX.W,R->IY.W,R->I |
330 |
); |
331 |
printf |
332 |
( |
333 |
"AT PC: [%02X - %s] AT SP: [%04X] FLAGS: [%s] %s: %s\n\n", |
334 |
RdZ80(R->PC.W),S,RdZ80(R->SP.W)+RdZ80(R->SP.W+1)*256,T, |
335 |
R->IFF&0x04? "IM2":R->IFF&0x02? "IM1":"IM0", |
336 |
R->IFF&0x01? "EI":"DI" |
337 |
); |
338 |
|
339 |
while(1) |
340 |
{ |
341 |
printf("\n[Command,'?']-> "); |
342 |
fflush(stdout);fflush(stdin); |
343 |
|
344 |
fgets(S,50,stdin); |
345 |
for(J=0;S[J]>=' ';J++) |
346 |
S[J]=toupper(S[J]); |
347 |
S[J]='\0'; |
348 |
|
349 |
switch(S[0]) |
350 |
{ |
351 |
case 'H': |
352 |
case '?': |
353 |
puts("\n***** Built-in Z80 Debugger Commands *****"); |
354 |
puts("<CR> : Break at next instruction"); |
355 |
puts("= <addr> : Break at addr"); |
356 |
puts("+ <offset> : Break at PC + offset"); |
357 |
puts("c : Continue without break"); |
358 |
puts("j <addr> : Continue from addr"); |
359 |
puts("m <addr> : Memory dump at addr"); |
360 |
puts("d <addr> : Disassembly at addr"); |
361 |
puts("?,h : Show this help text"); |
362 |
puts("q : Exit Z80 emulation"); |
363 |
break; |
364 |
|
365 |
case '\0': return(1); |
366 |
case '=': if(strlen(S)>=2) |
367 |
{ sscanf(S+1,"%hX",&(R->Trap));R->Trace=0;return(1); } |
368 |
break; |
369 |
case '+': if(strlen(S)>=2) |
370 |
{ |
371 |
sscanf(S+1,"%hX",&(R->Trap)); |
372 |
R->Trap+=R->PC.W;R->Trace=0; |
373 |
return(1); |
374 |
} |
375 |
break; |
376 |
case 'J': if(strlen(S)>=2) |
377 |
{ sscanf(S+1,"%hX",&(R->PC.W));R->Trace=0;return(1); } |
378 |
break; |
379 |
case 'C': R->Trap=0xFFFF;R->Trace=0;return(1); |
380 |
case 'Q': return(0); |
381 |
|
382 |
case 'M': |
383 |
{ |
384 |
word Addr; |
385 |
|
386 |
if(strlen(S)>1) sscanf(S+1,"%hX",&Addr); else Addr=R->PC.W; |
387 |
puts(""); |
388 |
for(J=0;J<16;J++) |
389 |
{ |
390 |
printf("%04X: ",Addr); |
391 |
for(I=0;I<16;I++,Addr++) |
392 |
printf("%02X ",RdZ80(Addr)); |
393 |
printf(" | ");Addr-=16; |
394 |
for(I=0;I<16;I++,Addr++) |
395 |
putchar(isprint(RdZ80(Addr))? RdZ80(Addr):'.'); |
396 |
puts(""); |
397 |
} |
398 |
} |
399 |
break; |
400 |
|
401 |
case 'D': |
402 |
{ |
403 |
word Addr; |
404 |
|
405 |
if(strlen(S)>1) sscanf(S+1,"%hX",&Addr); else Addr=R->PC.W; |
406 |
puts(""); |
407 |
for(J=0;J<16;J++) |
408 |
{ |
409 |
printf("%04X: ",Addr); |
410 |
Addr+=DAsm(S,Addr); |
411 |
puts(S); |
412 |
} |
413 |
} |
414 |
break; |
415 |
|
416 |
#ifdef FMSX |
417 |
case 'S': |
418 |
for(J=0;J<AY8910_CHANNELS;J++) |
419 |
{ |
420 |
printf("Channel %d: Volume %d, Frequency %dHz",J,PSG.Volume[J],PSG.Freq[J]); |
421 |
if(!(PSG.R[8+(J%3)]&0x10)) printf("\n"); |
422 |
else printf(", Envelope %d\n",PSG.R[8+(J%3)]&0x0F); |
423 |
} |
424 |
printf("Envelope period %dms\n",PSG.EPeriod); |
425 |
break; |
426 |
#endif /* FMSX */ |
427 |
} |
428 |
} |
429 |
|
430 |
/* Continue emulation */ |
431 |
return(1); |
432 |
} |
433 |
|
434 |
#endif /* DEBUG */ |