1 |
2 |
jsauermann |
|
2 |
|
|
#include <stdio.h>
|
3 |
|
|
#include <assert.h>
|
4 |
|
|
#include <conio.h>
|
5 |
|
|
|
6 |
7 |
jsauermann |
const bool do_log = false;
|
7 |
2 |
jsauermann |
|
8 |
|
|
typedef signed char sc;
|
9 |
|
|
typedef signed short ss;
|
10 |
|
|
typedef unsigned char uc;
|
11 |
|
|
typedef unsigned short us;
|
12 |
|
|
|
13 |
|
|
int simulate();
|
14 |
|
|
void print_txt(const char * txt, int imm, us op, us l, us h);
|
15 |
|
|
|
16 |
|
|
enum { SIZE = 0x10000 };
|
17 |
|
|
|
18 |
|
|
uc mem[SIZE];
|
19 |
|
|
const char * labels[SIZE];
|
20 |
|
|
|
21 |
|
|
FILE * out = 0;
|
22 |
|
|
FILE * log = 0;
|
23 |
|
|
|
24 |
|
|
int clock = 4;
|
25 |
|
|
|
26 |
|
|
//-----------------------------------------------------------------------------
|
27 |
|
|
int main(int argc, char *argv[])
|
28 |
|
|
{
|
29 |
|
|
for (int i = 0; i < sizeof(mem); i++)
|
30 |
|
|
{
|
31 |
|
|
mem[i] = 0x00;
|
32 |
|
|
labels[i] = 0;
|
33 |
|
|
}
|
34 |
|
|
|
35 |
|
|
assert(argc == 3 && "Too few arguments");
|
36 |
|
|
|
37 |
|
|
fprintf(stderr, "Input file is %s\n", argv[1]);
|
38 |
|
|
FILE * in = fopen(argv[1], "rb");
|
39 |
|
|
assert(in && "No binary input file");
|
40 |
|
|
|
41 |
|
|
fprintf(stderr, "Symbol file is %s\n", argv[2]);
|
42 |
|
|
FILE * sym = fopen(argv[2], "r");
|
43 |
|
|
assert(in && "No symbol file");
|
44 |
|
|
|
45 |
|
|
log = fopen("..\\simulate.log", "w");
|
46 |
|
|
assert(log);
|
47 |
|
|
// out = fopen("..\\simulate.out", "w");
|
48 |
|
|
out = stdout;
|
49 |
|
|
assert(out);
|
50 |
|
|
|
51 |
|
|
unsigned int sval;
|
52 |
|
|
char snam[256];
|
53 |
|
|
while (2 == fscanf(sym, "%X %s", &sval, snam))
|
54 |
|
|
{
|
55 |
|
|
fprintf(log, "Symbol %4.4X = %s\n", sval, snam);
|
56 |
|
|
|
57 |
|
|
if (labels[sval]) continue;
|
58 |
|
|
|
59 |
|
|
char * cp = new char[strlen(snam) + 1];
|
60 |
|
|
strcpy(cp, snam);
|
61 |
|
|
labels[sval] = cp;
|
62 |
|
|
}
|
63 |
|
|
|
64 |
|
|
const int l = fread(mem, 1, sizeof(mem), in);
|
65 |
|
|
fprintf(stderr, "%d bytes read\n", l);
|
66 |
|
|
assert(l > 0 && "Empty binary input file");
|
67 |
|
|
assert(l < sizeof(mem) && "Binary input file too big");
|
68 |
|
|
|
69 |
|
|
fclose(in);
|
70 |
|
|
|
71 |
|
|
fprintf(stderr, "Simulation started\n");
|
72 |
|
|
|
73 |
|
|
const int steps = simulate();
|
74 |
|
|
fprintf(stderr,
|
75 |
|
|
"\nSimulation done (processor halted) after %d steps\n",
|
76 |
|
|
steps);
|
77 |
|
|
fclose(log);
|
78 |
|
|
}
|
79 |
|
|
//-----------------------------------------------------------------------------
|
80 |
|
|
class CPU
|
81 |
|
|
{
|
82 |
|
|
public:
|
83 |
|
|
CPU()
|
84 |
|
|
: PC(0), SP(0), LL(0), RR(0)
|
85 |
|
|
{};
|
86 |
|
|
|
87 |
|
|
bool Step();
|
88 |
|
|
|
89 |
|
|
private:
|
90 |
|
|
static us _16(us h, us l) { return (h << 8) | l; };
|
91 |
|
|
|
92 |
|
|
uc u8() { imm++; return mem[PC++]; };
|
93 |
|
|
sc s8() { return u8(); };
|
94 |
|
|
us u16() { uc l = u8(); return _16(u8(), l); };
|
95 |
|
|
ss s16() { return u16(); }
|
96 |
|
|
void push8(uc v) { mem[--SP] = v; };
|
97 |
|
|
void push16(us v) { mem[--SP] = v>>8; mem[--SP] = v; };
|
98 |
|
|
us pop16() { us l = mem[SP++]; return _16(mem[SP++], l); };
|
99 |
|
|
us pop8u() { return (us)(uc)mem[SP++]; };
|
100 |
|
|
ss pop8s() { return (ss)(sc)mem[SP++]; };
|
101 |
|
|
us mem16(us a) { return _16(mem[a + 1], mem[a]); };
|
102 |
|
|
void mem16(us a, us v) { mem[a] = v; mem[a+1] = v >> 8; };
|
103 |
|
|
static us yes(us x) { if (x) return 0xFFFF; return 0; };
|
104 |
|
|
|
105 |
|
|
bool input(uc port);
|
106 |
|
|
bool output(uc port);
|
107 |
|
|
bool serout(uc c);
|
108 |
|
|
|
109 |
|
|
us PC;
|
110 |
|
|
us SP;
|
111 |
|
|
us RR;
|
112 |
|
|
us LL;
|
113 |
|
|
uc opc;
|
114 |
|
|
us prq;
|
115 |
|
|
us rem;
|
116 |
|
|
uc imm;
|
117 |
|
|
};
|
118 |
|
|
//-----------------------------------------------------------------------------
|
119 |
|
|
bool CPU::input(uc port)
|
120 |
|
|
{
|
121 |
|
|
switch(port)
|
122 |
|
|
{
|
123 |
|
|
case 0x00: RR = _getch() & 0xFF;
|
124 |
|
|
return false; // serial in
|
125 |
|
|
case 0x01: RR = 0x01;
|
126 |
|
|
return false; // serial status: !TxBusy | RxRdy
|
127 |
|
|
case 0x02: RR = 37;
|
128 |
|
|
return false; // temperature
|
129 |
|
|
}
|
130 |
|
|
|
131 |
|
|
return true; // error
|
132 |
|
|
}
|
133 |
|
|
//-----------------------------------------------------------------------------
|
134 |
|
|
bool CPU::output(uc port)
|
135 |
|
|
{
|
136 |
|
|
switch(port)
|
137 |
|
|
{
|
138 |
|
|
case 0x00: return serout(RR); ; // serial out
|
139 |
|
|
case 0x02: return false;
|
140 |
|
|
case 0x03: return false;
|
141 |
|
|
case 0x04: return false;
|
142 |
|
|
}
|
143 |
|
|
|
144 |
|
|
return true; // error
|
145 |
|
|
}
|
146 |
|
|
//-----------------------------------------------------------------------------
|
147 |
|
|
bool CPU::serout(uc c)
|
148 |
|
|
{
|
149 |
|
|
char cc[20];
|
150 |
|
|
|
151 |
|
|
if (c == '\n') sprintf(cc, "\n");
|
152 |
|
|
else if (c == '\r') sprintf(cc, "\\r");
|
153 |
|
|
else if (c < ' ') sprintf(cc, "\\x%2.2X", c);
|
154 |
|
|
else if (c > 0x7E) sprintf(cc, "\\x%2.2X", c);
|
155 |
|
|
else sprintf(cc, "%c", c);
|
156 |
|
|
|
157 |
|
|
fprintf(out, "%s", cc);
|
158 |
|
|
fprintf(log, "-> %s (0x%2.2X)\n", cc, c);
|
159 |
|
|
|
160 |
|
|
return false; // no error
|
161 |
|
|
}
|
162 |
|
|
//-----------------------------------------------------------------------------
|
163 |
|
|
int simulate()
|
164 |
|
|
{
|
165 |
|
|
CPU cpu;
|
166 |
|
|
int steps = 1;
|
167 |
|
|
|
168 |
|
|
for (;;steps++) if (cpu.Step()) return steps;
|
169 |
|
|
}
|
170 |
|
|
//-----------------------------------------------------------------------------
|
171 |
|
|
|
172 |
|
|
#define OP(_op, _act, _txt) case _op: _act txt = _txt; break;
|
173 |
|
|
|
174 |
|
|
bool CPU::Step()
|
175 |
|
|
{
|
176 |
|
|
clock++;
|
177 |
|
|
if (labels[PC]) fprintf(log, "%s:\n", labels[PC]);
|
178 |
|
|
|
179 |
|
|
const unsigned short lpc = PC;
|
180 |
|
|
const char * txt = "???";
|
181 |
|
|
bool done = false;
|
182 |
|
|
|
183 |
|
|
imm = 0;
|
184 |
|
|
opc = u8();
|
185 |
|
|
|
186 |
|
|
us tmp;
|
187 |
|
|
us uquick = opc & 0x0F;
|
188 |
|
|
us squick = opc & 0x0F; if (squick & 0x08) squick |= 0xFFF0;
|
189 |
|
|
|
190 |
|
|
switch(opc)
|
191 |
|
|
{
|
192 |
|
|
OP(0x00, { done = true; }, "HALT" )
|
193 |
|
|
OP(0x01, { }, "NOP" )
|
194 |
|
|
OP(0x02, { PC = u16(); }, "JMP j" )
|
195 |
|
|
OP(0x03, { tmp = u16(); if ( RR) PC = tmp; }, "JMP RRNZ, j" )
|
196 |
|
|
OP(0x04, { tmp = u16(); if (!RR) PC = tmp; }, "JMP RRZ, j" )
|
197 |
|
|
OP(0x05, { push16(lpc + 3); PC = u16(); }, "CALL j" )
|
198 |
|
|
OP(0x06, { push16(lpc + 3); PC = RR; }, "CALL (RR)" )
|
199 |
|
|
OP(0x07, { PC = pop16(); }, "RET" )
|
200 |
|
|
OP(0x08, { RR = pop16(); }, "MOVE (SP)+, RR" )
|
201 |
|
|
OP(0x09, { RR = pop8s(); }, "MOVE (SP)+, RS" )
|
202 |
|
|
OP(0x0A, { RR = pop8u(); }, "MOVE (SP)+, RU" )
|
203 |
|
|
OP(0x0B, { LL = pop16(); }, "MOVE (SP)+, LL" )
|
204 |
|
|
OP(0x0C, { LL = pop8s(); }, "MOVE (SP)+, LS" )
|
205 |
|
|
OP(0x0D, { LL = pop8u(); }, "MOVE (SP)+, LU" )
|
206 |
|
|
OP(0x0E, { push16(RR); }, "MOVE RR, -(SP)" )
|
207 |
|
|
OP(0x0F, { push8(RR); }, "MOVE R, -(SP)" )
|
208 |
|
|
|
209 |
|
|
OP(0x10, { RR = RR & u16(); }, "AND RR, #u" )
|
210 |
|
|
OP(0x11, { RR = RR & u8(); }, "AND RR, #u" )
|
211 |
|
|
OP(0x12, { RR = RR | u16(); }, "OR RR, #u" )
|
212 |
|
|
OP(0x13, { RR = RR | u8(); }, "OR RR, #u" )
|
213 |
|
|
OP(0x14, { RR = RR ^ u16(); }, "XOR RR, #u" )
|
214 |
|
|
OP(0x15, { RR = RR ^ u8(); }, "XOR RR, #u" )
|
215 |
|
|
OP(0x16, { RR = yes((ss)RR == s16()); }, "SEQ RR, #s" )
|
216 |
|
|
OP(0x17, { RR = yes((ss)RR == s8() ); }, "SEQ RR, #s" )
|
217 |
|
|
OP(0x18, { RR = yes((ss)RR != s16()); }, "SNE RR, #s" )
|
218 |
|
|
OP(0x19, { RR = yes((ss)RR != s8() ); }, "SNE RR, #s" )
|
219 |
|
|
OP(0x1A, { RR = yes((ss)RR >= s16()); }, "SGE RR, #s" )
|
220 |
|
|
OP(0x1B, { RR = yes((ss)RR >= s8() ); }, "SGE RR, #s" )
|
221 |
|
|
OP(0x1C, { RR = yes((ss)RR > s16()); }, "SGT RR, #s" )
|
222 |
|
|
OP(0x1D, { RR = yes((ss)RR > s8() ); }, "SGT RR, #s" )
|
223 |
|
|
OP(0x1E, { RR = yes((ss)RR <= s16()); }, "SLE RR, #s" )
|
224 |
|
|
OP(0x1F, { RR = yes((ss)RR <= s8() ); }, "SLE RR, #s" )
|
225 |
|
|
|
226 |
|
|
OP(0x20, { RR = yes((ss)RR < s16()); }, "SLT RR, #s" )
|
227 |
|
|
OP(0x21, { RR = yes((ss)RR < s8() ); }, "SLT RR, #s" )
|
228 |
|
|
OP(0x22, { RR = yes((us)RR >= u16()); }, "SHS RR, #u" )
|
229 |
|
|
OP(0x23, { RR = yes((us)RR >= u8() ); }, "SHS RR, #u" )
|
230 |
|
|
OP(0x24, { RR = yes((us)RR > u16()); }, "SHI RR, #u" )
|
231 |
|
|
OP(0x25, { RR = yes((us)RR > u8() ); }, "SHI RR, #u" )
|
232 |
|
|
OP(0x26, { RR = yes((us)RR <= u16()); }, "SLS RR, #u" )
|
233 |
|
|
OP(0x27, { RR = yes((us)RR <= u8() ); }, "SLS RR, #u" )
|
234 |
|
|
OP(0x28, { RR = yes((us)RR < u16()); }, "SLO RR, #u" )
|
235 |
|
|
OP(0x29, { RR = yes((us)RR < u8() ); }, "SLO RR, #u" )
|
236 |
|
|
OP(0x2A, { SP = SP + u16(); }, "ADD SP, #u" )
|
237 |
|
|
OP(0x2B, { SP = SP + u8(); }, "ADD SP, #u" )
|
238 |
|
|
OP(0x2C, { push16(0); }, "CLRW -(SP)" )
|
239 |
|
|
OP(0x2D, { push8(0); }, "CLRB -(SP)" )
|
240 |
|
|
OP(0x2E, { done = input(u8()); }, "IN (u), RU" )
|
241 |
|
|
OP(0x2F, { done = output(u8()); }, "OUT R, (u)" )
|
242 |
|
|
|
243 |
|
|
OP(0x30, { RR = LL & RR; }, "AND LL, RR" )
|
244 |
|
|
OP(0x31, { RR = LL | RR; }, "OR LL, RR" )
|
245 |
|
|
OP(0x32, { RR = LL ^ RR; }, "XOR LL, RR" )
|
246 |
|
|
OP(0x33, { RR = yes((ss)LL == (ss)RR); }, "SEQ LL, RR" )
|
247 |
|
|
OP(0x34, { RR = yes((ss)LL != (ss)RR); }, "SNE LL, RR" )
|
248 |
|
|
OP(0x35, { RR = yes((ss)LL >= (ss)RR); }, "SGE LL, RR" )
|
249 |
|
|
OP(0x36, { RR = yes((ss)LL > (ss)RR); }, "SGT LL, RR" )
|
250 |
|
|
OP(0x37, { RR = yes((ss)LL <= (ss)RR); }, "SLE LL, RR" )
|
251 |
|
|
OP(0x38, { RR = yes((ss)LL < (ss)RR); }, "SLT LL, RR" )
|
252 |
|
|
OP(0x39, { RR = yes((us)LL >= (us)RR); }, "SHS LL, RR" )
|
253 |
|
|
OP(0x3A, { RR = yes((us)LL > (us)RR); }, "SHI LL, RR" )
|
254 |
|
|
OP(0x3B, { RR = yes((us)LL <= (us)RR); }, "SLS LL, RR" )
|
255 |
|
|
OP(0x3C, { RR = yes((us)LL < (us)RR); }, "SLO LL, RR" )
|
256 |
|
|
OP(0x3D, { RR = yes(! RR); }, "LNOT RR" )
|
257 |
|
|
OP(0x3E, { RR = - RR; }, "NEG RR" )
|
258 |
|
|
OP(0x3F, { RR = ~ RR; }, "NOT RR" )
|
259 |
|
|
|
260 |
|
|
OP(0x40, { RR = LL; }, "MOVE LL, RR" )
|
261 |
|
|
OP(0x41, { mem[RR] = LL; mem[RR+1] = LL>>8; }, "MOVE LL, (RR)" )
|
262 |
|
|
OP(0x42, { mem[RR] = LL; }, "MOVE L, (RR)" )
|
263 |
|
|
OP(0x43, { LL = RR; }, "MOVE RR, LL" )
|
264 |
|
|
OP(0x44, { mem[LL] = RR; mem[LL+1] = RR>>8; }, "MOVE RR, (LL)" )
|
265 |
|
|
OP(0x45, { mem[LL] = RR; }, "MOVE R, (LL)" )
|
266 |
|
|
OP(0x46, { RR = mem16(RR); }, "MOVE (RR), RR" )
|
267 |
|
|
OP(0x47, { RR = (ss)(sc)mem[RR]; }, "MOVE (RR), RS" )
|
268 |
|
|
OP(0x48, { RR = (us)(uc)mem[RR]; }, "MOVE (RR), RU" )
|
269 |
|
|
OP(0x49, { RR = mem16(u16()); }, "MOVE (u), RR" )
|
270 |
|
|
OP(0x4A, { RR = (ss)(sc)mem[u16()]; }, "MOVE (u), RS" )
|
271 |
|
|
OP(0x4B, { RR = (us)(us)mem[u16()]; }, "MOVE (u), RU" )
|
272 |
|
|
OP(0x4C, { LL = mem16(u16()); }, "MOVE (u), LL" )
|
273 |
|
|
OP(0x4D, { LL = (ss)(sc)mem[u16()]; }, "MOVE (u), LS" )
|
274 |
|
|
OP(0x4E, { LL = (us)(us)mem[u16()]; }, "MOVE (u), LU" )
|
275 |
|
|
OP(0x4F, { SP = RR; }, "MOVE RR, SP" )
|
276 |
|
|
|
277 |
|
|
OP(0x52, { RR = RR << u8(); }, "LSL RR, #u" )
|
278 |
|
|
OP(0x53, { RR = ((ss)RR) >> u8(); }, "ASR RR, #u" )
|
279 |
|
|
OP(0x54, { RR = ((us)RR) >> u8(); }, "LSR RR, #u" )
|
280 |
|
|
OP(0x55, { RR = LL << RR; }, "LSL LL, RR" )
|
281 |
|
|
OP(0x56, { RR = ((ss)LL) >> RR; }, "ASR LL, RR" )
|
282 |
|
|
OP(0x57, { RR = ((us)LL) >> RR; }, "LSR LL, RR" )
|
283 |
|
|
OP(0x58, { RR = LL + RR; }, "ADD LL, RR" )
|
284 |
|
|
OP(0x59, { RR = LL - RR; }, "SUB LL, RR" )
|
285 |
|
|
OP(0x5A, { mem[tmp = u16()] = RR;
|
286 |
|
|
mem[tmp + 1] = RR >> 8; }, "MOVE RR, (u)" )
|
287 |
|
|
OP(0x5B, { mem[u16()] = RR; }, "MOVE R, (u)" )
|
288 |
|
|
OP(0x5C, { mem16(SP + u16(), RR); }, "MOVE RR, u(SP)" )
|
289 |
|
|
OP(0x5D, { mem16(SP + u8(), RR); }, "MOVE RR, u(SP)" )
|
290 |
|
|
OP(0x5E, { mem[SP + u16()] = RR; }, "MOVE R, u(SP)" )
|
291 |
|
|
OP(0x5F, { mem[SP + u8()] = RR; }, "MOVE R, u(SP)" )
|
292 |
|
|
|
293 |
|
|
OP(0x60, { RR = mem16(SP + u16()); }, "MOVE u(SP), RR" )
|
294 |
|
|
OP(0x61, { RR = mem16(SP + u8()); }, "MOVE u(SP), RR" )
|
295 |
|
|
OP(0x62, { RR = (ss)(sc)mem[SP + u16()]; }, "MOVE u(SP), RS" )
|
296 |
|
|
OP(0x63, { RR = (ss)(sc)mem[SP + u8()]; }, "MOVE u(SP), RS" )
|
297 |
|
|
OP(0x64, { RR = (us)(uc)mem[SP + u16()]; }, "MOVE u(SP), RU" )
|
298 |
|
|
OP(0x65, { RR = (us)(uc)mem[SP + u8()]; }, "MOVE u(SP), RU" )
|
299 |
|
|
OP(0x66, { LL = mem16(SP + u16()); }, "MOVE u(SP), LL" )
|
300 |
|
|
OP(0x67, { LL = mem16(SP + u8()); }, "MOVE u(SP), LL" )
|
301 |
|
|
OP(0x68, { LL = (ss)(sc)mem[SP + u16()]; }, "MOVE u(SP), LS" )
|
302 |
|
|
OP(0x69, { LL = (ss)(sc)mem[SP + u8() ]; }, "MOVE u(SP), LS" )
|
303 |
|
|
OP(0x6A, { LL = (us)(uc)mem[SP + u16()]; }, "MOVE u(SP), LU" )
|
304 |
|
|
OP(0x6B, { LL = (us)(uc)mem[SP + u8() ]; }, "MOVE u(SP), LU" )
|
305 |
|
|
OP(0x6C, { RR = SP + u16(); }, "LEA u(SP), RR" )
|
306 |
|
|
OP(0x6D, { RR = SP + u8(); }, "LEA u(SP), RR" )
|
307 |
|
|
OP(0x6E, { mem[--LL] = mem[--RR]; }, "MOVE -(RR), -(LL)")
|
308 |
|
|
OP(0x6F, { mem[LL++] = mem[RR++]; }, "MOVE (RR)+, (LL)+")
|
309 |
|
|
|
310 |
|
|
OP(0x70, { prq = (ss)LL * (ss)RR; }, "MUL_IS" )
|
311 |
|
|
OP(0x71, { prq = (us)LL * (us)RR; }, "MUL_IU" )
|
312 |
|
|
OP(0x72, { prq = (ss)LL / (ss)RR;
|
313 |
|
|
rem = (ss)LL % (ss)RR; }, "DIV_IS" )
|
314 |
|
|
OP(0x73, { prq = (us)LL / (us)RR;
|
315 |
|
|
rem = (us)LL % (us)RR; }, "DIV_IU" )
|
316 |
|
|
OP(0x74, { }, "MD_STP" )
|
317 |
|
|
OP(0x75, { RR = prq; }, "MD_FIN" )
|
318 |
|
|
OP(0x76, { RR = rem; }, "MOD_FIN" )
|
319 |
|
|
OP(0x77, { }, "EI" )
|
320 |
|
|
OP(0x78, { PC = pop16(); }, "RETI" )
|
321 |
|
|
OP(0x79, { }, "DI" )
|
322 |
|
|
|
323 |
|
|
OP(0xA0 ... 0xAF, { RR = RR + uquick; }, "ADD RR, #u" )
|
324 |
|
|
OP(0xB0 ... 0xBF, { RR = RR - uquick; }, "SUB RR, #u" )
|
325 |
|
|
OP(0xC0 ... 0xCF, { RR = squick; }, "MOVE #s, RR" )
|
326 |
|
|
OP(0xD0 ... 0xDF, { RR = yes(LL == squick); }, "SEQ LL, #s" )
|
327 |
|
|
OP(0xE0 ... 0xEF, { LL = squick; }, "MOVE #s, LL" )
|
328 |
|
|
|
329 |
|
|
OP(0xF4, { RR = RR + u16(); }, "ADD RR, #u" )
|
330 |
|
|
OP(0xF5, { RR = RR + u8(); }, "ADD RU, #u" )
|
331 |
|
|
OP(0xF6, { RR = RR - u16(); }, "SUB RR, #u" )
|
332 |
|
|
OP(0xF7, { RR = RR - u8(); }, "SUB RU, #u" )
|
333 |
|
|
OP(0xF8, { RR = s16(); }, "MOVE #s, RR" )
|
334 |
|
|
OP(0xF9, { RR = s8(); }, "MOVE #s, RS" )
|
335 |
|
|
OP(0xFA, { RR = yes(LL == s16()); }, "SEQ LL, #s" )
|
336 |
|
|
OP(0xFB, { RR = yes(LL == s8()); }, "SEQ LL, #s" )
|
337 |
|
|
OP(0xFC, { LL = s16(); }, "MOVE #s, LL" )
|
338 |
|
|
OP(0xFD, { LL = s8(); }, "MOVE #s, LL" )
|
339 |
|
|
|
340 |
|
|
default: fprintf(log, "%4.4X: Bad Opcode 0x%2.2X\n", lpc, opc);
|
341 |
|
|
txt = "???"; done = true;
|
342 |
|
|
}
|
343 |
|
|
|
344 |
|
|
if (do_log)
|
345 |
|
|
{
|
346 |
|
|
fprintf(log, "%4.4X %4.4X : ", clock, lpc);
|
347 |
|
|
|
348 |
|
|
fprintf(log, "%2.2X ", mem[lpc]);
|
349 |
|
|
if (imm == 1) fprintf(log, " ");
|
350 |
|
|
else if (imm == 2) fprintf(log, "%2.2X ", mem[lpc + 1]);
|
351 |
|
|
else if (imm == 3) fprintf(log, "%2.2X%2.2X",
|
352 |
|
|
mem[lpc + 2], mem[lpc + 1]);
|
353 |
|
|
else assert(0);
|
354 |
|
|
|
355 |
|
|
fprintf(log, " ");
|
356 |
|
|
print_txt(txt, imm, mem[lpc], mem[lpc + 1], mem[lpc + 2]);
|
357 |
|
|
|
358 |
|
|
fprintf(log, "-> SP=%4.4X (%4.4X) ", SP, _16(mem[SP+1], mem[SP]));
|
359 |
|
|
|
360 |
|
|
fprintf(log, "LL=%4.4X ", LL);
|
361 |
|
|
fprintf(log, "RR=%4.4X\n", RR);
|
362 |
|
|
|
363 |
|
|
if (PC != lpc + imm) fprintf(log, "\n");
|
364 |
|
|
}
|
365 |
|
|
|
366 |
|
|
if (PC > 0xA000)
|
367 |
|
|
{
|
368 |
|
|
fprintf(log, "Bad PC %d\n", PC);
|
369 |
|
|
fclose(log);
|
370 |
|
|
assert(0 && "Bad PC");
|
371 |
|
|
}
|
372 |
|
|
|
373 |
|
|
if (SP > 0xA000)
|
374 |
|
|
{
|
375 |
|
|
fprintf(log, "Bad SP %d\n", SP);
|
376 |
|
|
fclose(log);
|
377 |
|
|
assert(0 && "Bad SP");
|
378 |
|
|
}
|
379 |
|
|
|
380 |
|
|
return done;
|
381 |
|
|
}
|
382 |
|
|
//-----------------------------------------------------------------------------
|
383 |
|
|
void print_txt(const char * txt, int imm, us op, us l, us h)
|
384 |
|
|
{
|
385 |
|
|
int len = 0;
|
386 |
|
|
us hl = (h << 8) | l;
|
387 |
|
|
|
388 |
|
|
for (; *txt; txt++)
|
389 |
|
|
{
|
390 |
|
|
if (*txt == 'u')
|
391 |
|
|
{
|
392 |
|
|
if (imm == 1) len += fprintf(log, "%d", op & 0x0F);
|
393 |
|
|
else if (imm == 2) len += fprintf(log, "%d", l);
|
394 |
|
|
else if (imm == 3) len += fprintf(log, "%d", hl);
|
395 |
|
|
else assert(0);
|
396 |
|
|
}
|
397 |
|
|
else if (*txt == 's')
|
398 |
|
|
{
|
399 |
|
|
if (imm == 1)
|
400 |
|
|
{
|
401 |
|
|
|
402 |
|
|
if (imm & 0x08) len += fprintf(log, "%d", op | 0xFFFFFFF8);
|
403 |
|
|
else len += fprintf(log, "%d", op & 0x00000007);
|
404 |
|
|
}
|
405 |
|
|
else if (imm == 2)
|
406 |
|
|
{
|
407 |
|
|
if (imm & 0x80) len += fprintf(log, "%d", l | 0xFFFFFF80);
|
408 |
|
|
else len += fprintf(log, "%d", l & 0x0000007F);
|
409 |
|
|
}
|
410 |
|
|
else if (imm == 3) len += fprintf(log, "%d", (ss)hl);
|
411 |
|
|
else assert(0);
|
412 |
|
|
}
|
413 |
|
|
else if (*txt == 'j')
|
414 |
|
|
{
|
415 |
|
|
if (labels[hl]) len += fprintf(log, "%s", labels[hl]);
|
416 |
|
|
else len += fprintf(log, "%X", hl);
|
417 |
|
|
}
|
418 |
|
|
else len += fprintf(log, "%c", *txt);
|
419 |
|
|
}
|
420 |
|
|
|
421 |
|
|
while (len < 28) len += fprintf(log, " ");
|
422 |
|
|
}
|
423 |
|
|
//-----------------------------------------------------------------------------
|