2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
16 /***************************************************************************
20 Intel MCS-48/UPI-41 Portable Emulator
22 Copyright Mirko Buffoni
23 Based on the original work Copyright Dan Boris, an 8048 emulator
24 You are not allowed to distribute this software commercially
26 ****************************************************************************
28 Note that the default internal divisor for this chip is by 3 and
29 then again by 5, or by 15 total.
31 ***************************************************************************/
33 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
34 #pragma warning( disable : 4244 )
39 /***************************************************************************
41 ***************************************************************************/
43 /* timer/counter enable bits */
44 #define TIMER_ENABLED 0x01
45 #define COUNTER_ENABLED 0x02
53 /* status bits (UPI-41) */
57 /* 8243 expander operations */
60 MCS48_EXPANDER_OP_READ = 0,
61 MCS48_EXPANDER_OP_WRITE = 1,
62 MCS48_EXPANDER_OP_OR = 2,
63 MCS48_EXPANDER_OP_AND = 3
66 /***************************************************************************
68 ***************************************************************************/
70 /* live processor state */
73 UINT16 prevpc; /* 16-bit previous program counter */
74 UINT16 pc; /* 16-bit program counter */
76 UINT8 a; /* 8-bit accumulator */
77 int regptr; /* offset of r0-r7 */
78 UINT8 psw; /* 8-bit cpustate->psw */
79 UINT8 p1; /* 8-bit latched port 1 */
80 UINT8 p2; /* 8-bit latched port 2 */
81 UINT8 timer; /* 8-bit timer */
82 UINT8 prescaler; /* 5-bit timer prescaler */
83 UINT8 t1_history; /* 8-bit history of the T1 input */
84 UINT8 sts; /* 8-bit status register */
86 UINT8 int_state; /* INT signal status */
87 UINT8 irq_state; /* TRUE if an IRQ is pending */
88 UINT8 irq_in_progress; /* TRUE if an IRQ is in progress */
89 UINT8 timer_overflow; /* TRUE on a timer overflow; cleared by taking interrupt */
90 UINT8 timer_flag; /* TRUE on a timer overflow; cleared on JTF */
91 UINT8 tirq_enabled; /* TRUE if the timer IRQ is enabled */
92 UINT8 xirq_enabled; /* TRUE if the external IRQ is enabled */
93 UINT8 t0_clk_enabled; /* TRUE if ent0_clk is called */
94 UINT8 timecount_enabled; /* bitmask of timer/counter enabled */
96 UINT16 a11; /* A11 value, either 0x000 or 0x800 */
108 /* opcode table entry */
109 typedef int (*mcs48_ophandler)(mcs48_state *state);
111 /***************************************************************************
113 ***************************************************************************/
115 #define program_r(a) cpustate->rom[(a) & 0xfff]
117 #define ram_r(a) cpustate->mem->read_data8(a)
118 #define ram_w(a,V) cpustate->mem->write_data8(a, V)
119 #define reg_r(a) cpustate->mem->read_data8(cpustate->regptr + a)
120 #define reg_w(a,V) cpustate->mem->write_data8(cpustate->regptr + a, V)
122 #define ext_r(a) cpustate->io->read_io8(a)
123 #define ext_w(a,V) cpustate->io->write_io8(a, V)
124 #define port_r(a) cpustate->io->read_io8(MCS48_PORT_P0 + a)
125 #define port_w(a,V) cpustate->io->write_io8(MCS48_PORT_P0 + a, V)
126 #define test_r(a) cpustate->io->read_io8(MCS48_PORT_T0 + a)
127 #define test_w(a,V) cpustate->io->write_io8(MCS48_PORT_T0 + a, V)
128 #define bus_r() cpustate->io->read_io8(MCS48_PORT_BUS)
129 #define bus_w(V) cpustate->io->write_io8(MCS48_PORT_BUS, V)
130 #define prog_w(V) cpustate->io->write_io8(MCS48_PORT_PROG, V)
132 /***************************************************************************
134 ***************************************************************************/
136 static int check_irqs(mcs48_state *cpustate);
138 /***************************************************************************
140 ***************************************************************************/
142 /*-------------------------------------------------
143 opcode_fetch - fetch an opcode byte
144 -------------------------------------------------*/
146 INLINE UINT8 opcode_fetch(mcs48_state *cpustate)
148 return cpustate->rom[cpustate->pc++ & 0xfff];
151 /*-------------------------------------------------
152 argument_fetch - fetch an opcode argument
154 -------------------------------------------------*/
156 INLINE UINT8 argument_fetch(mcs48_state *cpustate)
158 return cpustate->rom[cpustate->pc++ & 0xfff];
161 /*-------------------------------------------------
162 update_regptr - update the regptr member to
163 point to the appropriate register bank
164 -------------------------------------------------*/
166 INLINE void update_regptr(mcs48_state *cpustate)
168 cpustate->regptr = ((cpustate->psw & B_FLAG) ? 24 : 0);
171 /*-------------------------------------------------
172 push_pc_psw - push the cpustate->pc and cpustate->psw values onto
174 -------------------------------------------------*/
176 INLINE void push_pc_psw(mcs48_state *cpustate)
178 UINT8 sp = cpustate->psw & 0x07;
179 ram_w(8 + 2*sp, cpustate->pc);
180 ram_w(9 + 2*sp, ((cpustate->pc >> 8) & 0x0f) | (cpustate->psw & 0xf0));
181 cpustate->psw = (cpustate->psw & 0xf8) | ((sp + 1) & 0x07);
184 /*-------------------------------------------------
185 pull_pc_psw - pull the PC and PSW values from
187 -------------------------------------------------*/
189 INLINE void pull_pc_psw(mcs48_state *cpustate)
191 UINT8 sp = (cpustate->psw - 1) & 0x07;
192 cpustate->pc = ram_r(8 + 2*sp);
193 cpustate->pc |= ram_r(9 + 2*sp) << 8;
194 cpustate->psw = ((cpustate->pc >> 8) & 0xf0) | 0x08 | sp;
195 cpustate->pc &= 0xfff;
196 update_regptr(cpustate);
199 /*-------------------------------------------------
200 pull_pc - pull the PC value from the stack,
201 leaving the upper part of PSW intact
202 -------------------------------------------------*/
204 INLINE void pull_pc(mcs48_state *cpustate)
206 UINT8 sp = (cpustate->psw - 1) & 0x07;
207 cpustate->pc = ram_r(8 + 2*sp);
208 cpustate->pc |= ram_r(9 + 2*sp) << 8;
209 cpustate->pc &= 0xfff;
210 cpustate->psw = (cpustate->psw & 0xf0) | 0x08 | sp;
213 /*-------------------------------------------------
214 execute_add - perform the logic of an ADD
216 -------------------------------------------------*/
218 INLINE void execute_add(mcs48_state *cpustate, UINT8 dat)
220 UINT16 temp = cpustate->a + dat;
221 UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f);
223 cpustate->psw &= ~(C_FLAG | A_FLAG);
224 cpustate->psw |= (temp4 << 2) & A_FLAG;
225 cpustate->psw |= (temp >> 1) & C_FLAG;
229 /*-------------------------------------------------
230 execute_addc - perform the logic of an ADDC
232 -------------------------------------------------*/
234 INLINE void execute_addc(mcs48_state *cpustate, UINT8 dat)
236 UINT8 carryin = (cpustate->psw & C_FLAG) >> 7;
237 UINT16 temp = cpustate->a + dat + carryin;
238 UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f) + carryin;
240 cpustate->psw &= ~(C_FLAG | A_FLAG);
241 cpustate->psw |= (temp4 << 2) & A_FLAG;
242 cpustate->psw |= (temp >> 1) & C_FLAG;
246 /*-------------------------------------------------
247 execute_jmp - perform the logic of a JMP
249 -------------------------------------------------*/
251 INLINE void execute_jmp(mcs48_state *cpustate, UINT16 address)
253 UINT16 a11 = (cpustate->irq_in_progress) ? 0 : cpustate->a11;
254 cpustate->pc = address | a11;
257 /*-------------------------------------------------
258 execute_call - perform the logic of a CALL
260 -------------------------------------------------*/
262 INLINE void execute_call(mcs48_state *cpustate, UINT16 address)
264 push_pc_psw(cpustate);
265 execute_jmp(cpustate, address);
268 /*-------------------------------------------------
269 execute_jcc - perform the logic of a
270 conditional jump instruction
271 -------------------------------------------------*/
273 INLINE void execute_jcc(mcs48_state *cpustate, UINT8 result)
275 UINT8 offset = argument_fetch(cpustate);
277 cpustate->pc = ((cpustate->pc - 1) & 0xf00) | offset;
280 /*-------------------------------------------------
281 expander_operation - perform an operation via
282 the 8243 expander chip
283 -------------------------------------------------*/
285 INLINE void expander_operation(mcs48_state *cpustate, UINT8 operation, UINT8 port)
287 /* put opcode/data on low 4 bits of P2 */
288 port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (operation << 2) | (port & 3));
290 /* generate high-to-low transition on PROG line */
293 /* put data on low 4 bits of P2 */
295 port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (cpustate->a & 0x0f));
297 cpustate->a = port_r(2) | 0x0f;
299 /* generate low-to-high transition on PROG line */
303 /***************************************************************************
305 ***************************************************************************/
307 #define OPHANDLER(_name) static int _name(mcs48_state *cpustate)
311 // logerror("MCS-48 PC:%04X - Illegal opcode = %02x\n", cpustate->pc - 1, program_r(cpustate->pc - 1));
315 OPHANDLER( add_a_r0 ) { execute_add(cpustate, reg_r(0)); return 1; }
316 OPHANDLER( add_a_r1 ) { execute_add(cpustate, reg_r(1)); return 1; }
317 OPHANDLER( add_a_r2 ) { execute_add(cpustate, reg_r(2)); return 1; }
318 OPHANDLER( add_a_r3 ) { execute_add(cpustate, reg_r(3)); return 1; }
319 OPHANDLER( add_a_r4 ) { execute_add(cpustate, reg_r(4)); return 1; }
320 OPHANDLER( add_a_r5 ) { execute_add(cpustate, reg_r(5)); return 1; }
321 OPHANDLER( add_a_r6 ) { execute_add(cpustate, reg_r(6)); return 1; }
322 OPHANDLER( add_a_r7 ) { execute_add(cpustate, reg_r(7)); return 1; }
323 OPHANDLER( add_a_xr0 ) { execute_add(cpustate, ram_r(reg_r(0))); return 1; }
324 OPHANDLER( add_a_xr1 ) { execute_add(cpustate, ram_r(reg_r(1))); return 1; }
325 OPHANDLER( add_a_n ) { execute_add(cpustate, argument_fetch(cpustate)); return 2; }
327 OPHANDLER( adc_a_r0 ) { execute_addc(cpustate, reg_r(0)); return 1; }
328 OPHANDLER( adc_a_r1 ) { execute_addc(cpustate, reg_r(1)); return 1; }
329 OPHANDLER( adc_a_r2 ) { execute_addc(cpustate, reg_r(2)); return 1; }
330 OPHANDLER( adc_a_r3 ) { execute_addc(cpustate, reg_r(3)); return 1; }
331 OPHANDLER( adc_a_r4 ) { execute_addc(cpustate, reg_r(4)); return 1; }
332 OPHANDLER( adc_a_r5 ) { execute_addc(cpustate, reg_r(5)); return 1; }
333 OPHANDLER( adc_a_r6 ) { execute_addc(cpustate, reg_r(6)); return 1; }
334 OPHANDLER( adc_a_r7 ) { execute_addc(cpustate, reg_r(7)); return 1; }
335 OPHANDLER( adc_a_xr0 ) { execute_addc(cpustate, ram_r(reg_r(0))); return 1; }
336 OPHANDLER( adc_a_xr1 ) { execute_addc(cpustate, ram_r(reg_r(1))); return 1; }
337 OPHANDLER( adc_a_n ) { execute_addc(cpustate, argument_fetch(cpustate)); return 2; }
339 OPHANDLER( anl_a_r0 ) { cpustate->a &= reg_r(0); return 1; }
340 OPHANDLER( anl_a_r1 ) { cpustate->a &= reg_r(1); return 1; }
341 OPHANDLER( anl_a_r2 ) { cpustate->a &= reg_r(2); return 1; }
342 OPHANDLER( anl_a_r3 ) { cpustate->a &= reg_r(3); return 1; }
343 OPHANDLER( anl_a_r4 ) { cpustate->a &= reg_r(4); return 1; }
344 OPHANDLER( anl_a_r5 ) { cpustate->a &= reg_r(5); return 1; }
345 OPHANDLER( anl_a_r6 ) { cpustate->a &= reg_r(6); return 1; }
346 OPHANDLER( anl_a_r7 ) { cpustate->a &= reg_r(7); return 1; }
347 OPHANDLER( anl_a_xr0 ) { cpustate->a &= ram_r(reg_r(0)); return 1; }
348 OPHANDLER( anl_a_xr1 ) { cpustate->a &= ram_r(reg_r(1)); return 1; }
349 OPHANDLER( anl_a_n ) { cpustate->a &= argument_fetch(cpustate); return 2; }
351 OPHANDLER( anl_bus_n ) { bus_w(bus_r() & argument_fetch(cpustate)); return 2; }
352 OPHANDLER( anl_p1_n ) { port_w(1, cpustate->p1 &= argument_fetch(cpustate)); return 2; }
353 OPHANDLER( anl_p2_n ) { port_w(2, cpustate->p2 &= argument_fetch(cpustate)); return 2; }
354 OPHANDLER( anld_p4_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 4); return 2; }
355 OPHANDLER( anld_p5_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 5); return 2; }
356 OPHANDLER( anld_p6_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 6); return 2; }
357 OPHANDLER( anld_p7_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 7); return 2; }
359 OPHANDLER( call_0 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x000); return 2; }
360 OPHANDLER( call_1 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x100); return 2; }
361 OPHANDLER( call_2 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x200); return 2; }
362 OPHANDLER( call_3 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x300); return 2; }
363 OPHANDLER( call_4 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x400); return 2; }
364 OPHANDLER( call_5 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x500); return 2; }
365 OPHANDLER( call_6 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x600); return 2; }
366 OPHANDLER( call_7 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x700); return 2; }
368 OPHANDLER( clr_a ) { cpustate->a = 0; return 1; }
369 OPHANDLER( clr_c ) { cpustate->psw &= ~C_FLAG; return 1; }
370 OPHANDLER( clr_f0 ) { cpustate->psw &= ~F_FLAG; cpustate->sts &= ~STS_F0; return 1; }
371 OPHANDLER( clr_f1 ) { cpustate->sts &= ~STS_F1; return 1; }
373 OPHANDLER( cpl_a ) { cpustate->a ^= 0xff; return 1; }
374 OPHANDLER( cpl_c ) { cpustate->psw ^= C_FLAG; return 1; }
375 OPHANDLER( cpl_f0 ) { cpustate->psw ^= F_FLAG; cpustate->sts ^= STS_F0; return 1; }
376 OPHANDLER( cpl_f1 ) { cpustate->sts ^= STS_F1; return 1; }
380 if ((cpustate->a & 0x0f) > 0x09 || (cpustate->psw & A_FLAG))
383 if ((cpustate->a & 0xf0) == 0x00)
384 cpustate->psw |= C_FLAG;
386 if ((cpustate->a & 0xf0) > 0x90 || (cpustate->psw & C_FLAG))
389 cpustate->psw |= C_FLAG;
392 cpustate->psw &= ~C_FLAG;
396 OPHANDLER( dec_a ) { cpustate->a--; return 1; }
397 OPHANDLER( dec_r0 ) { reg_w(0, reg_r(0) - 1); return 1; }
398 OPHANDLER( dec_r1 ) { reg_w(1, reg_r(1) - 1); return 1; }
399 OPHANDLER( dec_r2 ) { reg_w(2, reg_r(2) - 1); return 1; }
400 OPHANDLER( dec_r3 ) { reg_w(3, reg_r(3) - 1); return 1; }
401 OPHANDLER( dec_r4 ) { reg_w(4, reg_r(4) - 1); return 1; }
402 OPHANDLER( dec_r5 ) { reg_w(5, reg_r(5) - 1); return 1; }
403 OPHANDLER( dec_r6 ) { reg_w(6, reg_r(6) - 1); return 1; }
404 OPHANDLER( dec_r7 ) { reg_w(7, reg_r(7) - 1); return 1; }
406 OPHANDLER( dis_i ) { cpustate->xirq_enabled = FALSE; return 1; }
407 OPHANDLER( dis_tcnti ) { cpustate->tirq_enabled = FALSE; cpustate->timer_overflow = FALSE; return 1; }
409 OPHANDLER( djnz_r0 ) { UINT8 r0 = reg_r(0); reg_w(0, --r0); execute_jcc(cpustate, r0 != 0); return 2; }
410 OPHANDLER( djnz_r1 ) { UINT8 r1 = reg_r(1); reg_w(1, --r1); execute_jcc(cpustate, r1 != 0); return 2; }
411 OPHANDLER( djnz_r2 ) { UINT8 r2 = reg_r(2); reg_w(2, --r2); execute_jcc(cpustate, r2 != 0); return 2; }
412 OPHANDLER( djnz_r3 ) { UINT8 r3 = reg_r(3); reg_w(3, --r3); execute_jcc(cpustate, r3 != 0); return 2; }
413 OPHANDLER( djnz_r4 ) { UINT8 r4 = reg_r(4); reg_w(4, --r4); execute_jcc(cpustate, r4 != 0); return 2; }
414 OPHANDLER( djnz_r5 ) { UINT8 r5 = reg_r(5); reg_w(5, --r5); execute_jcc(cpustate, r5 != 0); return 2; }
415 OPHANDLER( djnz_r6 ) { UINT8 r6 = reg_r(6); reg_w(6, --r6); execute_jcc(cpustate, r6 != 0); return 2; }
416 OPHANDLER( djnz_r7 ) { UINT8 r7 = reg_r(7); reg_w(7, --r7); execute_jcc(cpustate, r7 != 0); return 2; }
418 OPHANDLER( en_i ) { cpustate->xirq_enabled = TRUE; return 1 + check_irqs(cpustate); }
419 OPHANDLER( en_tcnti ) { cpustate->tirq_enabled = TRUE; return 1 + check_irqs(cpustate); }
420 OPHANDLER( ent0_clk ) { cpustate->t0_clk_enabled = TRUE; return 1; }
422 OPHANDLER( in_a_p1 ) { cpustate->a = port_r(1) & cpustate->p1; return 2; }
423 OPHANDLER( in_a_p2 ) { cpustate->a = port_r(2) & cpustate->p2; return 2; }
424 OPHANDLER( ins_a_bus ) { cpustate->a = bus_r(); return 2; }
426 OPHANDLER( inc_a ) { cpustate->a++; return 1; }
427 OPHANDLER( inc_r0 ) { reg_w(0, reg_r(0) + 1); return 1; }
428 OPHANDLER( inc_r1 ) { reg_w(1, reg_r(1) + 1); return 1; }
429 OPHANDLER( inc_r2 ) { reg_w(2, reg_r(2) + 1); return 1; }
430 OPHANDLER( inc_r3 ) { reg_w(3, reg_r(3) + 1); return 1; }
431 OPHANDLER( inc_r4 ) { reg_w(4, reg_r(4) + 1); return 1; }
432 OPHANDLER( inc_r5 ) { reg_w(5, reg_r(5) + 1); return 1; }
433 OPHANDLER( inc_r6 ) { reg_w(6, reg_r(6) + 1); return 1; }
434 OPHANDLER( inc_r7 ) { reg_w(7, reg_r(7) + 1); return 1; }
435 OPHANDLER( inc_xr0 ) { UINT8 r0 = reg_r(0); ram_w(r0, ram_r(r0) + 1); return 1; }
436 OPHANDLER( inc_xr1 ) { UINT8 r1 = reg_r(1); ram_w(r1, ram_r(r1) + 1); return 1; }
438 OPHANDLER( jb_0 ) { execute_jcc(cpustate, (cpustate->a & 0x01) != 0); return 2; }
439 OPHANDLER( jb_1 ) { execute_jcc(cpustate, (cpustate->a & 0x02) != 0); return 2; }
440 OPHANDLER( jb_2 ) { execute_jcc(cpustate, (cpustate->a & 0x04) != 0); return 2; }
441 OPHANDLER( jb_3 ) { execute_jcc(cpustate, (cpustate->a & 0x08) != 0); return 2; }
442 OPHANDLER( jb_4 ) { execute_jcc(cpustate, (cpustate->a & 0x10) != 0); return 2; }
443 OPHANDLER( jb_5 ) { execute_jcc(cpustate, (cpustate->a & 0x20) != 0); return 2; }
444 OPHANDLER( jb_6 ) { execute_jcc(cpustate, (cpustate->a & 0x40) != 0); return 2; }
445 OPHANDLER( jb_7 ) { execute_jcc(cpustate, (cpustate->a & 0x80) != 0); return 2; }
446 OPHANDLER( jc ) { execute_jcc(cpustate, (cpustate->psw & C_FLAG) != 0); return 2; }
447 OPHANDLER( jf0 ) { execute_jcc(cpustate, (cpustate->psw & F_FLAG) != 0); return 2; }
448 OPHANDLER( jf1 ) { execute_jcc(cpustate, (cpustate->sts & STS_F1) != 0); return 2; }
449 OPHANDLER( jnc ) { execute_jcc(cpustate, (cpustate->psw & C_FLAG) == 0); return 2; }
450 OPHANDLER( jni ) { execute_jcc(cpustate, cpustate->int_state == 0); return 2; }
451 OPHANDLER( jnt_0 ) { execute_jcc(cpustate, test_r(0) == 0); return 2; }
452 OPHANDLER( jnt_1 ) { execute_jcc(cpustate, test_r(1) == 0); return 2; }
453 OPHANDLER( jnz ) { execute_jcc(cpustate, cpustate->a != 0); return 2; }
454 OPHANDLER( jtf ) { execute_jcc(cpustate, cpustate->timer_flag); cpustate->timer_flag = FALSE; return 2; }
455 OPHANDLER( jt_0 ) { execute_jcc(cpustate, test_r(0) != 0); return 2; }
456 OPHANDLER( jt_1 ) { execute_jcc(cpustate, test_r(1) != 0); return 2; }
457 OPHANDLER( jz ) { execute_jcc(cpustate, cpustate->a == 0); return 2; }
459 OPHANDLER( jmp_0 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x000); return 2; }
460 OPHANDLER( jmp_1 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x100); return 2; }
461 OPHANDLER( jmp_2 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x200); return 2; }
462 OPHANDLER( jmp_3 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x300); return 2; }
463 OPHANDLER( jmp_4 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x400); return 2; }
464 OPHANDLER( jmp_5 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x500); return 2; }
465 OPHANDLER( jmp_6 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x600); return 2; }
466 OPHANDLER( jmp_7 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x700); return 2; }
467 OPHANDLER( jmpp_xa ) { cpustate->pc &= 0xf00; cpustate->pc |= program_r(cpustate->pc | cpustate->a); return 2; }
469 OPHANDLER( mov_a_n ) { cpustate->a = argument_fetch(cpustate); return 2; }
470 OPHANDLER( mov_a_psw ) { cpustate->a = cpustate->psw; return 1; }
471 OPHANDLER( mov_a_r0 ) { cpustate->a = reg_r(0); return 1; }
472 OPHANDLER( mov_a_r1 ) { cpustate->a = reg_r(1); return 1; }
473 OPHANDLER( mov_a_r2 ) { cpustate->a = reg_r(2); return 1; }
474 OPHANDLER( mov_a_r3 ) { cpustate->a = reg_r(3); return 1; }
475 OPHANDLER( mov_a_r4 ) { cpustate->a = reg_r(4); return 1; }
476 OPHANDLER( mov_a_r5 ) { cpustate->a = reg_r(5); return 1; }
477 OPHANDLER( mov_a_r6 ) { cpustate->a = reg_r(6); return 1; }
478 OPHANDLER( mov_a_r7 ) { cpustate->a = reg_r(7); return 1; }
479 OPHANDLER( mov_a_xr0 ) { cpustate->a = ram_r(reg_r(0)); return 1; }
480 OPHANDLER( mov_a_xr1 ) { cpustate->a = ram_r(reg_r(1)); return 1; }
481 OPHANDLER( mov_a_t ) { cpustate->a = cpustate->timer; return 1; }
483 OPHANDLER( mov_psw_a ) { cpustate->psw = cpustate->a; update_regptr(cpustate); return 1; }
484 OPHANDLER( mov_r0_a ) { reg_w(0, cpustate->a); return 1; }
485 OPHANDLER( mov_r1_a ) { reg_w(1, cpustate->a); return 1; }
486 OPHANDLER( mov_r2_a ) { reg_w(2, cpustate->a); return 1; }
487 OPHANDLER( mov_r3_a ) { reg_w(3, cpustate->a); return 1; }
488 OPHANDLER( mov_r4_a ) { reg_w(4, cpustate->a); return 1; }
489 OPHANDLER( mov_r5_a ) { reg_w(5, cpustate->a); return 1; }
490 OPHANDLER( mov_r6_a ) { reg_w(6, cpustate->a); return 1; }
491 OPHANDLER( mov_r7_a ) { reg_w(7, cpustate->a); return 1; }
492 OPHANDLER( mov_r0_n ) { reg_w(0, argument_fetch(cpustate)); return 2; }
493 OPHANDLER( mov_r1_n ) { reg_w(1, argument_fetch(cpustate)); return 2; }
494 OPHANDLER( mov_r2_n ) { reg_w(2, argument_fetch(cpustate)); return 2; }
495 OPHANDLER( mov_r3_n ) { reg_w(3, argument_fetch(cpustate)); return 2; }
496 OPHANDLER( mov_r4_n ) { reg_w(4, argument_fetch(cpustate)); return 2; }
497 OPHANDLER( mov_r5_n ) { reg_w(5, argument_fetch(cpustate)); return 2; }
498 OPHANDLER( mov_r6_n ) { reg_w(6, argument_fetch(cpustate)); return 2; }
499 OPHANDLER( mov_r7_n ) { reg_w(7, argument_fetch(cpustate)); return 2; }
500 OPHANDLER( mov_t_a ) { cpustate->timer = cpustate->a; return 1; }
501 OPHANDLER( mov_xr0_a ) { ram_w(reg_r(0), cpustate->a); return 1; }
502 OPHANDLER( mov_xr1_a ) { ram_w(reg_r(1), cpustate->a); return 1; }
503 OPHANDLER( mov_xr0_n ) { ram_w(reg_r(0), argument_fetch(cpustate)); return 2; }
504 OPHANDLER( mov_xr1_n ) { ram_w(reg_r(1), argument_fetch(cpustate)); return 2; }
506 OPHANDLER( movd_a_p4 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 4); return 2; }
507 OPHANDLER( movd_a_p5 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 5); return 2; }
508 OPHANDLER( movd_a_p6 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 6); return 2; }
509 OPHANDLER( movd_a_p7 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 7); return 2; }
510 OPHANDLER( movd_p4_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 4); return 2; }
511 OPHANDLER( movd_p5_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 5); return 2; }
512 OPHANDLER( movd_p6_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 6); return 2; }
513 OPHANDLER( movd_p7_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 7); return 2; }
515 OPHANDLER( movp_a_xa ) { cpustate->a = program_r((cpustate->pc & 0xf00) | cpustate->a); return 2; }
516 OPHANDLER( movp3_a_xa ) { cpustate->a = program_r(0x300 | cpustate->a); return 2; }
518 OPHANDLER( movx_a_xr0 ) { cpustate->a = ext_r(reg_r(0)); return 2; }
519 OPHANDLER( movx_a_xr1 ) { cpustate->a = ext_r(reg_r(1)); return 2; }
520 OPHANDLER( movx_xr0_a ) { ext_w(reg_r(0), cpustate->a); return 2; }
521 OPHANDLER( movx_xr1_a ) { ext_w(reg_r(1), cpustate->a); return 2; }
523 OPHANDLER( nop ) { return 1; }
525 OPHANDLER( orl_a_r0 ) { cpustate->a |= reg_r(0); return 1; }
526 OPHANDLER( orl_a_r1 ) { cpustate->a |= reg_r(1); return 1; }
527 OPHANDLER( orl_a_r2 ) { cpustate->a |= reg_r(2); return 1; }
528 OPHANDLER( orl_a_r3 ) { cpustate->a |= reg_r(3); return 1; }
529 OPHANDLER( orl_a_r4 ) { cpustate->a |= reg_r(4); return 1; }
530 OPHANDLER( orl_a_r5 ) { cpustate->a |= reg_r(5); return 1; }
531 OPHANDLER( orl_a_r6 ) { cpustate->a |= reg_r(6); return 1; }
532 OPHANDLER( orl_a_r7 ) { cpustate->a |= reg_r(7); return 1; }
533 OPHANDLER( orl_a_xr0 ) { cpustate->a |= ram_r(reg_r(0)); return 1; }
534 OPHANDLER( orl_a_xr1 ) { cpustate->a |= ram_r(reg_r(1)); return 1; }
535 OPHANDLER( orl_a_n ) { cpustate->a |= argument_fetch(cpustate); return 2; }
537 OPHANDLER( orl_bus_n ) { bus_w(bus_r() | argument_fetch(cpustate)); return 2; }
538 OPHANDLER( orl_p1_n ) { port_w(1, cpustate->p1 |= argument_fetch(cpustate)); return 2; }
539 OPHANDLER( orl_p2_n ) { port_w(2, cpustate->p2 |= argument_fetch(cpustate)); return 2; }
540 OPHANDLER( orld_p4_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 4); return 2; }
541 OPHANDLER( orld_p5_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 5); return 2; }
542 OPHANDLER( orld_p6_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 6); return 2; }
543 OPHANDLER( orld_p7_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 7); return 2; }
545 OPHANDLER( outl_bus_a ) { bus_w(cpustate->a); return 2; }
546 OPHANDLER( outl_p1_a ) { port_w(1, cpustate->p1 = cpustate->a); return 2; }
547 OPHANDLER( outl_p2_a ) { port_w(2, cpustate->p2 = cpustate->a); return 2; }
549 OPHANDLER( ret ) { pull_pc(cpustate); return 2; }
552 pull_pc_psw(cpustate);
554 /* implicitly clear the IRQ in progress flip flop and re-check interrupts */
555 cpustate->irq_in_progress = FALSE;
556 return 2 + check_irqs(cpustate);
559 OPHANDLER( rl_a ) { cpustate->a = (cpustate->a << 1) | (cpustate->a >> 7); return 1; }
560 OPHANDLER( rlc_a ) { UINT8 newc = cpustate->a & C_FLAG; cpustate->a = (cpustate->a << 1) | (cpustate->psw >> 7); cpustate->psw = (cpustate->psw & ~C_FLAG) | newc; return 1; }
562 OPHANDLER( rr_a ) { cpustate->a = (cpustate->a >> 1) | (cpustate->a << 7); return 1; }
563 OPHANDLER( rrc_a ) { UINT8 newc = (cpustate->a << 7) & C_FLAG; cpustate->a = (cpustate->a >> 1) | (cpustate->psw & C_FLAG); cpustate->psw = (cpustate->psw & ~C_FLAG) | newc; return 1; }
565 OPHANDLER( sel_mb0 ) { cpustate->a11 = 0x000; return 1; }
566 OPHANDLER( sel_mb1 ) { cpustate->a11 = 0x800; return 1; }
568 OPHANDLER( sel_rb0 ) { cpustate->psw &= ~B_FLAG; update_regptr(cpustate); return 1; }
569 OPHANDLER( sel_rb1 ) { cpustate->psw |= B_FLAG; update_regptr(cpustate); return 1; }
571 OPHANDLER( stop_tcnt ) { cpustate->timecount_enabled = 0; return 1; }
573 OPHANDLER( strt_cnt ) { cpustate->timecount_enabled = COUNTER_ENABLED; cpustate->t1_history = test_r(1); return 1; }
574 OPHANDLER( strt_t ) { cpustate->timecount_enabled = TIMER_ENABLED; cpustate->prescaler = 0; return 1; }
576 OPHANDLER( swap_a ) { cpustate->a = (cpustate->a << 4) | (cpustate->a >> 4); return 1; }
578 OPHANDLER( xch_a_r0 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(0); reg_w(0, tmp); return 1; }
579 OPHANDLER( xch_a_r1 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(1); reg_w(1, tmp); return 1; }
580 OPHANDLER( xch_a_r2 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(2); reg_w(2, tmp); return 1; }
581 OPHANDLER( xch_a_r3 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(3); reg_w(3, tmp); return 1; }
582 OPHANDLER( xch_a_r4 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(4); reg_w(4, tmp); return 1; }
583 OPHANDLER( xch_a_r5 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(5); reg_w(5, tmp); return 1; }
584 OPHANDLER( xch_a_r6 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(6); reg_w(6, tmp); return 1; }
585 OPHANDLER( xch_a_r7 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(7); reg_w(7, tmp); return 1; }
586 OPHANDLER( xch_a_xr0 ) { UINT8 r0 = reg_r(0); UINT8 tmp = cpustate->a; cpustate->a = ram_r(r0); ram_w(r0, tmp); return 1; }
587 OPHANDLER( xch_a_xr1 ) { UINT8 r1 = reg_r(1); UINT8 tmp = cpustate->a; cpustate->a = ram_r(r1); ram_w(r1, tmp); return 1; }
589 OPHANDLER( xchd_a_xr0 ) { UINT8 r0 = reg_r(0); UINT8 oldram = ram_r(r0); ram_w(r0, (oldram & 0xf0) | (cpustate->a & 0x0f)); cpustate->a = (cpustate->a & 0xf0) | (oldram & 0x0f); return 1; }
590 OPHANDLER( xchd_a_xr1 ) { UINT8 r1 = reg_r(1); UINT8 oldram = ram_r(r1); ram_w(r1, (oldram & 0xf0) | (cpustate->a & 0x0f)); cpustate->a = (cpustate->a & 0xf0) | (oldram & 0x0f); return 1; }
592 OPHANDLER( xrl_a_r0 ) { cpustate->a ^= reg_r(0); return 1; }
593 OPHANDLER( xrl_a_r1 ) { cpustate->a ^= reg_r(1); return 1; }
594 OPHANDLER( xrl_a_r2 ) { cpustate->a ^= reg_r(2); return 1; }
595 OPHANDLER( xrl_a_r3 ) { cpustate->a ^= reg_r(3); return 1; }
596 OPHANDLER( xrl_a_r4 ) { cpustate->a ^= reg_r(4); return 1; }
597 OPHANDLER( xrl_a_r5 ) { cpustate->a ^= reg_r(5); return 1; }
598 OPHANDLER( xrl_a_r6 ) { cpustate->a ^= reg_r(6); return 1; }
599 OPHANDLER( xrl_a_r7 ) { cpustate->a ^= reg_r(7); return 1; }
600 OPHANDLER( xrl_a_xr0 ) { cpustate->a ^= ram_r(reg_r(0)); return 1; }
601 OPHANDLER( xrl_a_xr1 ) { cpustate->a ^= ram_r(reg_r(1)); return 1; }
602 OPHANDLER( xrl_a_n ) { cpustate->a ^= argument_fetch(cpustate); return 2; }
604 /***************************************************************************
606 ***************************************************************************/
608 static const mcs48_ophandler opcode_table[256]=
610 nop, illegal, outl_bus_a,add_a_n, jmp_0, en_i, illegal, dec_a, /* 00 */
611 ins_a_bus, in_a_p1, in_a_p2, illegal, movd_a_p4, movd_a_p5, movd_a_p6, movd_a_p7,
612 inc_xr0, inc_xr1, jb_0, adc_a_n, call_0, dis_i, jtf, inc_a, /* 10 */
613 inc_r0, inc_r1, inc_r2, inc_r3, inc_r4, inc_r5, inc_r6, inc_r7,
614 xch_a_xr0, xch_a_xr1, illegal, mov_a_n, jmp_1, en_tcnti, jnt_0, clr_a, /* 20 */
615 xch_a_r0, xch_a_r1, xch_a_r2, xch_a_r3, xch_a_r4, xch_a_r5, xch_a_r6, xch_a_r7,
616 xchd_a_xr0, xchd_a_xr1, jb_1, illegal, call_1, dis_tcnti, jt_0, cpl_a, /* 30 */
617 illegal, outl_p1_a, outl_p2_a, illegal, movd_p4_a, movd_p5_a, movd_p6_a, movd_p7_a,
618 orl_a_xr0, orl_a_xr1, mov_a_t, orl_a_n, jmp_2, strt_cnt, jnt_1, swap_a, /* 40 */
619 orl_a_r0, orl_a_r1, orl_a_r2, orl_a_r3, orl_a_r4, orl_a_r5, orl_a_r6, orl_a_r7,
620 anl_a_xr0, anl_a_xr1, jb_2, anl_a_n, call_2, strt_t, jt_1, da_a, /* 50 */
621 anl_a_r0, anl_a_r1, anl_a_r2, anl_a_r3, anl_a_r4, anl_a_r5, anl_a_r6, anl_a_r7,
622 add_a_xr0, add_a_xr1, mov_t_a, illegal, jmp_3, stop_tcnt, illegal, rrc_a, /* 60 */
623 add_a_r0, add_a_r1, add_a_r2, add_a_r3, add_a_r4, add_a_r5, add_a_r6, add_a_r7,
624 adc_a_xr0, adc_a_xr1, jb_3, illegal, call_3, ent0_clk, jf1, rr_a, /* 70 */
625 adc_a_r0, adc_a_r1, adc_a_r2, adc_a_r3, adc_a_r4, adc_a_r5, adc_a_r6, adc_a_r7,
626 movx_a_xr0, movx_a_xr1, illegal, ret, jmp_4, clr_f0, jni, illegal, /* 80 */
627 orl_bus_n, orl_p1_n, orl_p2_n, illegal, orld_p4_a, orld_p5_a, orld_p6_a, orld_p7_a,
628 movx_xr0_a, movx_xr1_a, jb_4, retr, call_4, cpl_f0, jnz, clr_c, /* 90 */
629 anl_bus_n, anl_p1_n, anl_p2_n, illegal, anld_p4_a, anld_p5_a, anld_p6_a, anld_p7_a,
630 mov_xr0_a, mov_xr1_a, illegal, movp_a_xa, jmp_5, clr_f1, illegal, cpl_c, /* A0 */
631 mov_r0_a, mov_r1_a, mov_r2_a, mov_r3_a, mov_r4_a, mov_r5_a, mov_r6_a, mov_r7_a,
632 mov_xr0_n, mov_xr1_n, jb_5, jmpp_xa, call_5, cpl_f1, jf0, illegal, /* B0 */
633 mov_r0_n, mov_r1_n, mov_r2_n, mov_r3_n, mov_r4_n, mov_r5_n, mov_r6_n, mov_r7_n,
634 illegal, illegal, illegal, illegal, jmp_6, sel_rb0, jz, mov_a_psw, /* C0 */
635 dec_r0, dec_r1, dec_r2, dec_r3, dec_r4, dec_r5, dec_r6, dec_r7,
636 xrl_a_xr0, xrl_a_xr1, jb_6, xrl_a_n, call_6, sel_rb1, illegal, mov_psw_a, /* D0 */
637 xrl_a_r0, xrl_a_r1, xrl_a_r2, xrl_a_r3, xrl_a_r4, xrl_a_r5, xrl_a_r6, xrl_a_r7,
638 illegal, illegal, illegal, movp3_a_xa,jmp_7, sel_mb0, jnc, rl_a, /* E0 */
639 djnz_r0, djnz_r1, djnz_r2, djnz_r3, djnz_r4, djnz_r5, djnz_r6, djnz_r7,
640 mov_a_xr0, mov_a_xr1, jb_7, illegal, call_7, sel_mb1, jc, rlc_a, /* F0 */
641 mov_a_r0, mov_a_r1, mov_a_r2, mov_a_r3, mov_a_r4, mov_a_r5, mov_a_r6, mov_a_r7
644 /***************************************************************************
646 ***************************************************************************/
648 void MCS48::initialize()
650 opaque = calloc(1, sizeof(mcs48_state));
652 mcs48_state *cpustate = (mcs48_state *)opaque;
654 cpustate->mem = d_mem;
656 cpustate->intr = d_intr;
658 d_mem_stored = d_mem;
660 d_debugger->set_context_mem(d_mem);
661 d_debugger->set_context_io(d_io);
665 void MCS48::release()
672 mcs48_state *cpustate = (mcs48_state *)opaque;
674 /* confirmed from reset description */
676 cpustate->psw = (cpustate->psw & (C_FLAG | A_FLAG)) | 0x08;
677 cpustate->a11 = 0x000;
681 // port_w(1, cpustate->p1);
682 // port_w(2, cpustate->p2);
683 cpustate->tirq_enabled = FALSE;
684 cpustate->xirq_enabled = FALSE;
685 cpustate->t0_clk_enabled = FALSE;
686 cpustate->timecount_enabled = 0;
687 cpustate->timer_flag = FALSE;
690 cpustate->icount = 0;
692 /* confirmed from interrupt logic description */
693 cpustate->int_state = TRUE;
694 cpustate->irq_state = cpustate->irq_in_progress = FALSE;
695 cpustate->timer_overflow = FALSE;
698 void MCS48::load_rom_image(const _TCHAR *file_path)
700 mcs48_state *cpustate = (mcs48_state *)opaque;
702 memset(cpustate->rom, 0, sizeof(cpustate->rom));
704 FILEIO* fio = new FILEIO();
705 if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
706 fio->Fread(cpustate->rom, sizeof(cpustate->rom), 1);
712 uint8_t *MCS48::get_rom_ptr()
714 mcs48_state *cpustate = (mcs48_state *)opaque;
715 return cpustate->rom;
718 /***************************************************************************
720 ***************************************************************************/
722 /*-------------------------------------------------
723 check_irqs - check for and process IRQs
724 -------------------------------------------------*/
726 static int check_irqs(mcs48_state *cpustate)
728 /* if something is in progress, we do nothing */
729 if (cpustate->irq_in_progress)
732 /* external interrupts take priority */
733 if (cpustate->irq_state && cpustate->xirq_enabled)
735 cpustate->irq_state = FALSE;
736 cpustate->irq_in_progress = TRUE;
738 /* transfer to location 0x03 */
739 push_pc_psw(cpustate);
742 /* indicate we took the external IRQ */
743 if (cpustate->intr != NULL)
744 cpustate->intr->get_intr_ack();
748 /* timer overflow interrupts follow */
749 if (cpustate->timer_overflow && cpustate->tirq_enabled)
751 cpustate->irq_in_progress = TRUE;
753 /* transfer to location 0x07 */
754 push_pc_psw(cpustate);
757 /* timer overflow flip-flop is reset once taken */
758 cpustate->timer_overflow = FALSE;
764 /*-------------------------------------------------
765 burn_cycles - burn cycles, processing timers
767 -------------------------------------------------*/
769 static void burn_cycles(mcs48_state *cpustate, int count)
771 int timerover = FALSE;
773 /* output (clock*15/3) hz to t0 */
774 if (cpustate->t0_clk_enabled)
776 for(int i = 0; i < count * 5; i++)
783 /* if the timer is enabled, accumulate prescaler cycles */
784 if (cpustate->timecount_enabled & TIMER_ENABLED)
786 UINT8 oldtimer = cpustate->timer;
787 cpustate->prescaler += count;
788 cpustate->timer += cpustate->prescaler >> 5;
789 cpustate->prescaler &= 0x1f;
790 timerover = (oldtimer != 0 && cpustate->timer == 0);
793 /* if the counter is enabled, poll the T1 test input once for each cycle */
794 else if (cpustate->timecount_enabled & COUNTER_ENABLED)
795 for ( ; count > 0; count--)
797 cpustate->t1_history = (cpustate->t1_history << 1) | (test_r(1) & 1);
798 if ((cpustate->t1_history & 3) == 2)
799 timerover = (++cpustate->timer == 0);
802 /* if either source caused a timer overflow, set the flags and check IRQs */
805 cpustate->timer_flag = TRUE;
807 /* according to the docs, if an overflow occurs with interrupts disabled, the overflow is not stored */
808 if (cpustate->tirq_enabled)
810 cpustate->timer_overflow = TRUE;
811 check_irqs(cpustate);
816 int MCS48::run(int icount)
818 mcs48_state *cpustate = (mcs48_state *)opaque;
822 cpustate->icount = 1;
824 cpustate->icount += icount;
825 if (cpustate->icount < 0) {
830 int base_icount = cpustate->icount;
832 update_regptr(cpustate);
834 /* external interrupts may have been set since we last checked */
835 curcycles = check_irqs(cpustate);
836 cpustate->icount -= curcycles * 15;
837 if (cpustate->timecount_enabled != 0)
838 burn_cycles(cpustate, curcycles);
840 /* iterate over remaining cycles, guaranteeing at least one instruction */
844 bool now_debugging = d_debugger->now_debugging;
846 d_debugger->check_break_points(cpustate->pc);
847 if(d_debugger->now_suspended) {
849 while(d_debugger->now_debugging && d_debugger->now_suspended) {
853 if(d_debugger->now_debugging) {
854 d_mem = d_io = d_debugger;
856 now_debugging = false;
859 /* fetch next opcode */
860 cpustate->prevpc = cpustate->pc;
861 unsigned opcode = opcode_fetch(cpustate);
863 /* process opcode and count cycles */
864 curcycles = (*opcode_table[opcode])(cpustate);
866 /* burn the cycles */
867 cpustate->icount -= curcycles * 15;
868 if (cpustate->timecount_enabled != 0)
869 burn_cycles(cpustate, curcycles);
872 if(!d_debugger->now_going) {
873 d_debugger->now_suspended = true;
875 d_mem = d_mem_stored;
880 /* fetch next opcode */
881 cpustate->prevpc = cpustate->pc;
882 unsigned opcode = opcode_fetch(cpustate);
884 /* process opcode and count cycles */
885 curcycles = (*opcode_table[opcode])(cpustate);
887 /* burn the cycles */
888 cpustate->icount -= curcycles * 15;
889 if (cpustate->timecount_enabled != 0)
890 burn_cycles(cpustate, curcycles);
894 } while (cpustate->icount > 0);
896 return base_icount - cpustate->icount;
899 uint32_t MCS48::get_pc()
901 mcs48_state *cpustate = (mcs48_state *)opaque;
902 return cpustate->prevpc;
905 uint32_t MCS48::get_next_pc()
907 mcs48_state *cpustate = (mcs48_state *)opaque;
911 /***************************************************************************
912 GENERAL CONTEXT ACCESS
913 ***************************************************************************/
915 void MCS48::write_signal(int id, uint32_t data, uint32_t mask)
917 mcs48_state *cpustate = (mcs48_state *)opaque;
919 if(id == SIG_CPU_IRQ) {
920 UINT8 prev = cpustate->int_state;
921 cpustate->int_state = ((data & mask) != 0);
923 if(prev && !cpustate->int_state) {
924 cpustate->irq_state = TRUE;
930 void MCS48::write_debug_data8(uint32_t addr, uint32_t data)
932 d_mem_stored->write_data8(addr, data);
935 uint32_t MCS48::read_debug_data8(uint32_t addr)
937 return d_mem_stored->read_data8(addr);
940 void MCS48::write_debug_io8(uint32_t addr, uint32_t data)
942 d_io_stored->write_io8(addr, data);
945 uint32_t MCS48::read_debug_io8(uint32_t addr)
947 return d_io_stored->read_io8(addr);
950 bool MCS48::write_debug_reg(const _TCHAR *reg, uint32_t data)
952 mcs48_state *cpustate = (mcs48_state *)opaque;
954 if(_tcsicmp(reg, _T("R0")) == 0) {
956 } else if(_tcsicmp(reg, _T("R1")) == 0) {
958 } else if(_tcsicmp(reg, _T("R2")) == 0) {
960 } else if(_tcsicmp(reg, _T("R3")) == 0) {
962 } else if(_tcsicmp(reg, _T("R4")) == 0) {
964 } else if(_tcsicmp(reg, _T("R5")) == 0) {
966 } else if(_tcsicmp(reg, _T("R6")) == 0) {
968 } else if(_tcsicmp(reg, _T("R7")) == 0) {
976 void MCS48::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
979 R0 = 00 R1 = 00 R2 = 00 R3 = 00 (R0)= 00 (R1)= 00 (SP-1)= 0000 PC = 0000
980 R4 = 00 R5 = 00 R6 = 00 R7 = 00 AC = 00 SP = 00 [MB F1 C AC F0 BS]
982 mcs48_state *cpustate = (mcs48_state *)opaque;
983 UINT8 sp = 8 + 2 * (cpustate->psw & 7);
984 UINT8 prev_sp = 8 + 2 * ((cpustate->psw - 1) & 7);
986 my_stprintf_s(buffer, buffer_len,
987 _T("R0 = %02X R1 = %02X R2 = %02X R3 = %02X (R0)= %02X (R1)= %02X (SP-1)= %04X PC = %04X\nR4 = %02X R5 = %02X R6 = %02X R7 = %02X AC = %02X SP = %02X [%s %s %s %s %s %s]"),
988 reg_r(0), reg_r(1), reg_r(2), reg_r(3), d_mem_stored->read_data8(reg_r(0)), d_mem_stored->read_data8(reg_r(1)),
989 d_mem_stored->read_data8(prev_sp) | (d_mem_stored->read_data8(prev_sp + 1) << 8), cpustate->pc,
990 reg_r(4), reg_r(5), reg_r(6), reg_r(7), cpustate->a, sp,
991 (cpustate->a11 == 0x800) ? _T("MB") : _T("--"), (cpustate->sts & STS_F1) ? _T("F1") : _T("--"),
992 (cpustate->psw & C_FLAG) ? _T("C" ) : _T("-" ), (cpustate->psw & A_FLAG) ? _T("AC") : _T("--"),
993 (cpustate->psw & F_FLAG) ? _T("F0") : _T("--"), (cpustate->psw & B_FLAG) ? _T("BS") : _T("--"));
996 // license:BSD-3-Clause
997 // copyright-holders:Aaron Giles
998 /***************************************************************************
1002 Simple MCS-48/UPI-41 disassembler.
1003 Written by Aaron Giles
1005 ***************************************************************************/
1007 int MCS48::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
1009 mcs48_state *cpustate = (mcs48_state *)opaque;
1014 switch (program_r(ptr++))
1016 case 0x00: my_stprintf_s(buffer, buffer_len, _T("nop")); break;
1017 case 0x02: if (!upi41)
1018 my_stprintf_s(buffer, buffer_len, _T("out bus,a"));
1020 my_stprintf_s(buffer, buffer_len, _T("out dbb,a")); break;
1021 case 0x03: my_stprintf_s(buffer, buffer_len, _T("add a,#$%02X"), program_r(ptr++)); break;
1022 case 0x04: my_stprintf_s(buffer, buffer_len, _T("jmp $0%02X"), program_r(ptr++)); break;
1023 case 0x05: my_stprintf_s(buffer, buffer_len, _T("en i")); break;
1024 case 0x07: my_stprintf_s(buffer, buffer_len, _T("dec a")); break;
1025 case 0x08: if (!upi41)
1026 my_stprintf_s(buffer, buffer_len, _T("in a,bus"));
1028 my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1029 case 0x09: my_stprintf_s(buffer, buffer_len, _T("in a,p1")); break;
1030 case 0x0a: my_stprintf_s(buffer, buffer_len, _T("in a,p2")); break;
1031 case 0x0c: my_stprintf_s(buffer, buffer_len, _T("movd a,p4")); break;
1032 case 0x0d: my_stprintf_s(buffer, buffer_len, _T("movd a,p5")); break;
1033 case 0x0e: my_stprintf_s(buffer, buffer_len, _T("movd a,p6")); break;
1034 case 0x0f: my_stprintf_s(buffer, buffer_len, _T("movd a,p7")); break;
1035 case 0x10: my_stprintf_s(buffer, buffer_len, _T("inc @r0")); break;
1036 case 0x11: my_stprintf_s(buffer, buffer_len, _T("inc @r1")); break;
1037 case 0x12: my_stprintf_s(buffer, buffer_len, _T("jb0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1038 case 0x13: my_stprintf_s(buffer, buffer_len, _T("addc a,#$%02X"), program_r(ptr++)); break;
1039 case 0x14: my_stprintf_s(buffer, buffer_len, _T("call $0%02X"), program_r(ptr++)); break;
1040 case 0x15: my_stprintf_s(buffer, buffer_len, _T("dis i")); break;
1041 case 0x16: my_stprintf_s(buffer, buffer_len, _T("jtf $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1042 case 0x17: my_stprintf_s(buffer, buffer_len, _T("inc a")); break;
1043 case 0x18: my_stprintf_s(buffer, buffer_len, _T("inc r0")); break;
1044 case 0x19: my_stprintf_s(buffer, buffer_len, _T("inc r1")); break;
1045 case 0x1a: my_stprintf_s(buffer, buffer_len, _T("inc r2")); break;
1046 case 0x1b: my_stprintf_s(buffer, buffer_len, _T("inc r3")); break;
1047 case 0x1c: my_stprintf_s(buffer, buffer_len, _T("inc r4")); break;
1048 case 0x1d: my_stprintf_s(buffer, buffer_len, _T("inc r5")); break;
1049 case 0x1e: my_stprintf_s(buffer, buffer_len, _T("inc r6")); break;
1050 case 0x1f: my_stprintf_s(buffer, buffer_len, _T("inc r7")); break;
1051 case 0x20: my_stprintf_s(buffer, buffer_len, _T("xch a,@r0")); break;
1052 case 0x21: my_stprintf_s(buffer, buffer_len, _T("xch a,@r1")); break;
1053 case 0x22: if (!upi41)
1054 my_stprintf_s(buffer, buffer_len, _T("illegal"));
1056 my_stprintf_s(buffer, buffer_len, _T("in a,dbb")); break;
1057 case 0x23: my_stprintf_s(buffer, buffer_len, _T("mov a,#$%02X"), program_r(ptr++)); break;
1058 case 0x24: my_stprintf_s(buffer, buffer_len, _T("jmp $1%02X"), program_r(ptr++)); break;
1059 case 0x25: my_stprintf_s(buffer, buffer_len, _T("en tcnti")); break;
1060 case 0x26: my_stprintf_s(buffer, buffer_len, _T("jnt0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1061 case 0x27: my_stprintf_s(buffer, buffer_len, _T("clr a")); break;
1062 case 0x28: my_stprintf_s(buffer, buffer_len, _T("xch a,r0")); break;
1063 case 0x29: my_stprintf_s(buffer, buffer_len, _T("xch a,r1")); break;
1064 case 0x2a: my_stprintf_s(buffer, buffer_len, _T("xch a,r2")); break;
1065 case 0x2b: my_stprintf_s(buffer, buffer_len, _T("xch a,r3")); break;
1066 case 0x2c: my_stprintf_s(buffer, buffer_len, _T("xch a,r4")); break;
1067 case 0x2d: my_stprintf_s(buffer, buffer_len, _T("xch a,r5")); break;
1068 case 0x2e: my_stprintf_s(buffer, buffer_len, _T("xch a,r6")); break;
1069 case 0x2f: my_stprintf_s(buffer, buffer_len, _T("xch a,r7")); break;
1070 case 0x30: my_stprintf_s(buffer, buffer_len, _T("xchd a,@r0")); break;
1071 case 0x31: my_stprintf_s(buffer, buffer_len, _T("xchd a,@r1")); break;
1072 case 0x32: my_stprintf_s(buffer, buffer_len, _T("jb1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1073 case 0x34: my_stprintf_s(buffer, buffer_len, _T("call $1%02X"), program_r(ptr++)); break;
1074 case 0x35: my_stprintf_s(buffer, buffer_len, _T("dis tcnti")); break;
1075 case 0x36: my_stprintf_s(buffer, buffer_len, _T("jt0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1076 case 0x37: my_stprintf_s(buffer, buffer_len, _T("cpl a")); break;
1077 case 0x39: my_stprintf_s(buffer, buffer_len, _T("outl p1,a")); break;
1078 case 0x3a: my_stprintf_s(buffer, buffer_len, _T("outl p2,a")); break;
1079 case 0x3c: my_stprintf_s(buffer, buffer_len, _T("movd p4,a")); break;
1080 case 0x3d: my_stprintf_s(buffer, buffer_len, _T("movd p5,a")); break;
1081 case 0x3e: my_stprintf_s(buffer, buffer_len, _T("movd p6,a")); break;
1082 case 0x3f: my_stprintf_s(buffer, buffer_len, _T("movd p7,a")); break;
1083 case 0x40: my_stprintf_s(buffer, buffer_len, _T("orl a,@r0")); break;
1084 case 0x41: my_stprintf_s(buffer, buffer_len, _T("orl a,@r1")); break;
1085 case 0x42: my_stprintf_s(buffer, buffer_len, _T("mov a,t")); break;
1086 case 0x43: my_stprintf_s(buffer, buffer_len, _T("orl a,#$%02X"), program_r(ptr++)); break;
1087 case 0x44: my_stprintf_s(buffer, buffer_len, _T("jmp $2%02X"), program_r(ptr++)); break;
1088 case 0x45: my_stprintf_s(buffer, buffer_len, _T("strt cnt")); break;
1089 case 0x46: my_stprintf_s(buffer, buffer_len, _T("jnt1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1090 case 0x47: my_stprintf_s(buffer, buffer_len, _T("swap a")); break;
1091 case 0x48: my_stprintf_s(buffer, buffer_len, _T("orl a,r0")); break;
1092 case 0x49: my_stprintf_s(buffer, buffer_len, _T("orl a,r1")); break;
1093 case 0x4a: my_stprintf_s(buffer, buffer_len, _T("orl a,r2")); break;
1094 case 0x4b: my_stprintf_s(buffer, buffer_len, _T("orl a,r3")); break;
1095 case 0x4c: my_stprintf_s(buffer, buffer_len, _T("orl a,r4")); break;
1096 case 0x4d: my_stprintf_s(buffer, buffer_len, _T("orl a,r5")); break;
1097 case 0x4e: my_stprintf_s(buffer, buffer_len, _T("orl a,r6")); break;
1098 case 0x4f: my_stprintf_s(buffer, buffer_len, _T("orl a,r7")); break;
1099 case 0x50: my_stprintf_s(buffer, buffer_len, _T("anl a,@r0")); break;
1100 case 0x51: my_stprintf_s(buffer, buffer_len, _T("anl a,@r1")); break;
1101 case 0x52: my_stprintf_s(buffer, buffer_len, _T("jb2 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1102 case 0x53: my_stprintf_s(buffer, buffer_len, _T("anl a,#$%02X"), program_r(ptr++)); break;
1103 case 0x54: my_stprintf_s(buffer, buffer_len, _T("call $2%02X"), program_r(ptr++)); break;
1104 case 0x55: my_stprintf_s(buffer, buffer_len, _T("strt t")); break;
1105 case 0x56: my_stprintf_s(buffer, buffer_len, _T("jt1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1106 case 0x57: my_stprintf_s(buffer, buffer_len, _T("da a")); break;
1107 case 0x58: my_stprintf_s(buffer, buffer_len, _T("anl a,r0")); break;
1108 case 0x59: my_stprintf_s(buffer, buffer_len, _T("anl a,r1")); break;
1109 case 0x5a: my_stprintf_s(buffer, buffer_len, _T("anl a,r2")); break;
1110 case 0x5b: my_stprintf_s(buffer, buffer_len, _T("anl a,r3")); break;
1111 case 0x5c: my_stprintf_s(buffer, buffer_len, _T("anl a,r4")); break;
1112 case 0x5d: my_stprintf_s(buffer, buffer_len, _T("anl a,r5")); break;
1113 case 0x5e: my_stprintf_s(buffer, buffer_len, _T("anl a,r6")); break;
1114 case 0x5f: my_stprintf_s(buffer, buffer_len, _T("anl a,r7")); break;
1115 case 0x60: my_stprintf_s(buffer, buffer_len, _T("add a,@r0")); break;
1116 case 0x61: my_stprintf_s(buffer, buffer_len, _T("add a,@r1")); break;
1117 case 0x62: my_stprintf_s(buffer, buffer_len, _T("mov t,a")); break;
1118 case 0x64: my_stprintf_s(buffer, buffer_len, _T("jmp $3%02X"), program_r(ptr++)); break;
1119 case 0x65: my_stprintf_s(buffer, buffer_len, _T("stop tcnt")); break;
1120 case 0x67: my_stprintf_s(buffer, buffer_len, _T("rrc a")); break;
1121 case 0x68: my_stprintf_s(buffer, buffer_len, _T("add a,r0")); break;
1122 case 0x69: my_stprintf_s(buffer, buffer_len, _T("add a,r1")); break;
1123 case 0x6a: my_stprintf_s(buffer, buffer_len, _T("add a,r2")); break;
1124 case 0x6b: my_stprintf_s(buffer, buffer_len, _T("add a,r3")); break;
1125 case 0x6c: my_stprintf_s(buffer, buffer_len, _T("add a,r4")); break;
1126 case 0x6d: my_stprintf_s(buffer, buffer_len, _T("add a,r5")); break;
1127 case 0x6e: my_stprintf_s(buffer, buffer_len, _T("add a,r6")); break;
1128 case 0x6f: my_stprintf_s(buffer, buffer_len, _T("add a,r7")); break;
1129 case 0x70: my_stprintf_s(buffer, buffer_len, _T("addc a,@r0")); break;
1130 case 0x71: my_stprintf_s(buffer, buffer_len, _T("addc a,@r1")); break;
1131 case 0x72: my_stprintf_s(buffer, buffer_len, _T("jb3 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1132 case 0x74: my_stprintf_s(buffer, buffer_len, _T("call $3%02X"), program_r(ptr++)); break;
1133 case 0x75: if (!upi41)
1134 my_stprintf_s(buffer, buffer_len, _T("ent0 clk"));
1136 my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1137 case 0x76: my_stprintf_s(buffer, buffer_len, _T("jf1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1138 case 0x77: my_stprintf_s(buffer, buffer_len, _T("rr a")); break;
1139 case 0x78: my_stprintf_s(buffer, buffer_len, _T("addc a,r0")); break;
1140 case 0x79: my_stprintf_s(buffer, buffer_len, _T("addc a,r1")); break;
1141 case 0x7a: my_stprintf_s(buffer, buffer_len, _T("addc a,r2")); break;
1142 case 0x7b: my_stprintf_s(buffer, buffer_len, _T("addc a,r3")); break;
1143 case 0x7c: my_stprintf_s(buffer, buffer_len, _T("addc a,r4")); break;
1144 case 0x7d: my_stprintf_s(buffer, buffer_len, _T("addc a,r5")); break;
1145 case 0x7e: my_stprintf_s(buffer, buffer_len, _T("addc a,r6")); break;
1146 case 0x7f: my_stprintf_s(buffer, buffer_len, _T("addc a,r7")); break;
1147 case 0x80: if (!upi41)
1148 my_stprintf_s(buffer, buffer_len, _T("movx a,@r0"));
1150 my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1151 case 0x81: if (!upi41)
1152 my_stprintf_s(buffer, buffer_len, _T("movx a,@r1"));
1154 my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1155 case 0x83: my_stprintf_s(buffer, buffer_len, _T("ret")); break;
1156 case 0x84: my_stprintf_s(buffer, buffer_len, _T("jmp $4%02X"), program_r(ptr++)); break;
1157 case 0x85: my_stprintf_s(buffer, buffer_len, _T("clr f0")); break;
1158 case 0x86: if (!upi41)
1159 my_stprintf_s(buffer, buffer_len, _T("jni $%03X"), (pc & 0xf00) | program_r(ptr++));
1161 my_stprintf_s(buffer, buffer_len, _T("jobf $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1162 case 0x88: if (!upi41)
1163 my_stprintf_s(buffer, buffer_len, _T("orl bus,#$%02X"), program_r(ptr++));
1165 my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1166 case 0x89: my_stprintf_s(buffer, buffer_len, _T("orl p1,#$%02X"), program_r(ptr++)); break;
1167 case 0x8a: my_stprintf_s(buffer, buffer_len, _T("orl p2,#$%02X"), program_r(ptr++)); break;
1168 case 0x8c: my_stprintf_s(buffer, buffer_len, _T("orld p4,a")); break;
1169 case 0x8d: my_stprintf_s(buffer, buffer_len, _T("orld p5,a")); break;
1170 case 0x8e: my_stprintf_s(buffer, buffer_len, _T("orld p6,a")); break;
1171 case 0x8f: my_stprintf_s(buffer, buffer_len, _T("orld p7,a")); break;
1172 case 0x90: if (!upi41)
1173 my_stprintf_s(buffer, buffer_len, _T("movx @r0,a"));
1175 my_stprintf_s(buffer, buffer_len, _T("mov sts,a")); break;
1176 case 0x91: if (!upi41)
1177 my_stprintf_s(buffer, buffer_len, _T("movx @r1,a"));
1179 my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1180 case 0x92: my_stprintf_s(buffer, buffer_len, _T("jb4 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1181 case 0x93: my_stprintf_s(buffer, buffer_len, _T("retr")); break;
1182 case 0x94: my_stprintf_s(buffer, buffer_len, _T("call $4%02X"), program_r(ptr++)); break;
1183 case 0x95: my_stprintf_s(buffer, buffer_len, _T("cpl f0")); break;
1184 case 0x96: my_stprintf_s(buffer, buffer_len, _T("jnz $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1185 case 0x97: my_stprintf_s(buffer, buffer_len, _T("clr c")); break;
1186 case 0x98: if (!upi41)
1187 my_stprintf_s(buffer, buffer_len, _T("anl bus,#$%02X"), program_r(ptr++));
1189 my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1190 case 0x99: my_stprintf_s(buffer, buffer_len, _T("anl p1,#$%02X"), program_r(ptr++)); break;
1191 case 0x9a: my_stprintf_s(buffer, buffer_len, _T("anl p2,#$%02X"), program_r(ptr++)); break;
1192 case 0x9c: my_stprintf_s(buffer, buffer_len, _T("anld p4,a")); break;
1193 case 0x9d: my_stprintf_s(buffer, buffer_len, _T("anld p5,a")); break;
1194 case 0x9e: my_stprintf_s(buffer, buffer_len, _T("anld p6,a")); break;
1195 case 0x9f: my_stprintf_s(buffer, buffer_len, _T("anld p7,a")); break;
1196 case 0xa0: my_stprintf_s(buffer, buffer_len, _T("mov @r0,a")); break;
1197 case 0xa1: my_stprintf_s(buffer, buffer_len, _T("mov @r1,a")); break;
1198 case 0xa3: my_stprintf_s(buffer, buffer_len, _T("movp a,@a")); break;
1199 case 0xa4: my_stprintf_s(buffer, buffer_len, _T("jmp $5%02X"), program_r(ptr++)); break;
1200 case 0xa5: my_stprintf_s(buffer, buffer_len, _T("clr f1")); break;
1201 case 0xa7: my_stprintf_s(buffer, buffer_len, _T("cpl c")); break;
1202 case 0xa8: my_stprintf_s(buffer, buffer_len, _T("mov r0,a")); break;
1203 case 0xa9: my_stprintf_s(buffer, buffer_len, _T("mov r1,a")); break;
1204 case 0xaa: my_stprintf_s(buffer, buffer_len, _T("mov r2,a")); break;
1205 case 0xab: my_stprintf_s(buffer, buffer_len, _T("mov r3,a")); break;
1206 case 0xac: my_stprintf_s(buffer, buffer_len, _T("mov r4,a")); break;
1207 case 0xad: my_stprintf_s(buffer, buffer_len, _T("mov r5,a")); break;
1208 case 0xae: my_stprintf_s(buffer, buffer_len, _T("mov r6,a")); break;
1209 case 0xaf: my_stprintf_s(buffer, buffer_len, _T("mov r7,a")); break;
1210 case 0xb0: my_stprintf_s(buffer, buffer_len, _T("mov @r0,#$%02X"), program_r(ptr++)); break;
1211 case 0xb1: my_stprintf_s(buffer, buffer_len, _T("mov @r1,#$%02X"), program_r(ptr++)); break;
1212 case 0xb2: my_stprintf_s(buffer, buffer_len, _T("jb5 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1213 case 0xb3: my_stprintf_s(buffer, buffer_len, _T("jmpp @a")); break;
1214 case 0xb4: my_stprintf_s(buffer, buffer_len, _T("call $5%02X"), program_r(ptr++)); break;
1215 case 0xb5: my_stprintf_s(buffer, buffer_len, _T("cpl f1")); break;
1216 case 0xb6: my_stprintf_s(buffer, buffer_len, _T("jf0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1217 case 0xb8: my_stprintf_s(buffer, buffer_len, _T("mov r0,#$%02X"), program_r(ptr++)); break;
1218 case 0xb9: my_stprintf_s(buffer, buffer_len, _T("mov r1,#$%02X"), program_r(ptr++)); break;
1219 case 0xba: my_stprintf_s(buffer, buffer_len, _T("mov r2,#$%02X"), program_r(ptr++)); break;
1220 case 0xbb: my_stprintf_s(buffer, buffer_len, _T("mov r3,#$%02X"), program_r(ptr++)); break;
1221 case 0xbc: my_stprintf_s(buffer, buffer_len, _T("mov r4,#$%02X"), program_r(ptr++)); break;
1222 case 0xbd: my_stprintf_s(buffer, buffer_len, _T("mov r5,#$%02X"), program_r(ptr++)); break;
1223 case 0xbe: my_stprintf_s(buffer, buffer_len, _T("mov r6,#$%02X"), program_r(ptr++)); break;
1224 case 0xbf: my_stprintf_s(buffer, buffer_len, _T("mov r7,#$%02X"), program_r(ptr++)); break;
1225 case 0xc4: my_stprintf_s(buffer, buffer_len, _T("jmp $6%02X"), program_r(ptr++)); break;
1226 case 0xc5: my_stprintf_s(buffer, buffer_len, _T("sel rb0")); break;
1227 case 0xc6: my_stprintf_s(buffer, buffer_len, _T("jz $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1228 case 0xc7: my_stprintf_s(buffer, buffer_len, _T("mov a,psw")); break;
1229 case 0xc8: my_stprintf_s(buffer, buffer_len, _T("dec r0")); break;
1230 case 0xc9: my_stprintf_s(buffer, buffer_len, _T("dec r1")); break;
1231 case 0xca: my_stprintf_s(buffer, buffer_len, _T("dec r2")); break;
1232 case 0xcb: my_stprintf_s(buffer, buffer_len, _T("dec r3")); break;
1233 case 0xcc: my_stprintf_s(buffer, buffer_len, _T("dec r4")); break;
1234 case 0xcd: my_stprintf_s(buffer, buffer_len, _T("dec r5")); break;
1235 case 0xce: my_stprintf_s(buffer, buffer_len, _T("dec r6")); break;
1236 case 0xcf: my_stprintf_s(buffer, buffer_len, _T("dec r7")); break;
1237 case 0xd0: my_stprintf_s(buffer, buffer_len, _T("xrl a,@r0")); break;
1238 case 0xd1: my_stprintf_s(buffer, buffer_len, _T("xrl a,@r1")); break;
1239 case 0xd2: my_stprintf_s(buffer, buffer_len, _T("jb6 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1240 case 0xd3: my_stprintf_s(buffer, buffer_len, _T("xrl a,#$%02X"), program_r(ptr++)); break;
1241 case 0xd4: my_stprintf_s(buffer, buffer_len, _T("call $6%02X"), program_r(ptr++)); break;
1242 case 0xd5: my_stprintf_s(buffer, buffer_len, _T("sel rb1")); break;
1243 case 0xd6: if (!upi41)
1244 my_stprintf_s(buffer, buffer_len, _T("illegal"));
1246 my_stprintf_s(buffer, buffer_len, _T("jnibf $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1247 case 0xd7: my_stprintf_s(buffer, buffer_len, _T("mov psw,a")); break;
1248 case 0xd8: my_stprintf_s(buffer, buffer_len, _T("xrl a,r0")); break;
1249 case 0xd9: my_stprintf_s(buffer, buffer_len, _T("xrl a,r1")); break;
1250 case 0xda: my_stprintf_s(buffer, buffer_len, _T("xrl a,r2")); break;
1251 case 0xdb: my_stprintf_s(buffer, buffer_len, _T("xrl a,r3")); break;
1252 case 0xdc: my_stprintf_s(buffer, buffer_len, _T("xrl a,r4")); break;
1253 case 0xdd: my_stprintf_s(buffer, buffer_len, _T("xrl a,r5")); break;
1254 case 0xde: my_stprintf_s(buffer, buffer_len, _T("xrl a,r6")); break;
1255 case 0xdf: my_stprintf_s(buffer, buffer_len, _T("xrl a,r7")); break;
1256 case 0xe3: my_stprintf_s(buffer, buffer_len, _T("movp3 a,@a")); break;
1257 case 0xe4: my_stprintf_s(buffer, buffer_len, _T("jmp $7%02X"), program_r(ptr++)); break;
1258 case 0xe5: if (!upi41)
1259 my_stprintf_s(buffer, buffer_len, _T("sel mb0"));
1261 my_stprintf_s(buffer, buffer_len, _T("en dma")); break;
1262 case 0xe6: my_stprintf_s(buffer, buffer_len, _T("jnc $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1263 case 0xe7: my_stprintf_s(buffer, buffer_len, _T("rl a")); break;
1264 case 0xe8: my_stprintf_s(buffer, buffer_len, _T("djnz r0,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1265 case 0xe9: my_stprintf_s(buffer, buffer_len, _T("djnz r1,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1266 case 0xea: my_stprintf_s(buffer, buffer_len, _T("djnz r2,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1267 case 0xeb: my_stprintf_s(buffer, buffer_len, _T("djnz r3,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1268 case 0xec: my_stprintf_s(buffer, buffer_len, _T("djnz r4,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1269 case 0xed: my_stprintf_s(buffer, buffer_len, _T("djnz r5,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1270 case 0xee: my_stprintf_s(buffer, buffer_len, _T("djnz r6,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1271 case 0xef: my_stprintf_s(buffer, buffer_len, _T("djnz r7,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1272 case 0xf0: my_stprintf_s(buffer, buffer_len, _T("mov a,@r0")); break;
1273 case 0xf1: my_stprintf_s(buffer, buffer_len, _T("mov a,@r1")); break;
1274 case 0xf2: my_stprintf_s(buffer, buffer_len, _T("jb7 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1275 case 0xf4: my_stprintf_s(buffer, buffer_len, _T("call $7%02X"), program_r(ptr++)); break;
1276 case 0xf5: if (!upi41)
1277 my_stprintf_s(buffer, buffer_len, _T("sel mb1"));
1279 my_stprintf_s(buffer, buffer_len, _T("en flags")); break;
1280 case 0xf6: my_stprintf_s(buffer, buffer_len, _T("jc $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1281 case 0xf7: my_stprintf_s(buffer, buffer_len, _T("rlc a")); break;
1282 case 0xf8: my_stprintf_s(buffer, buffer_len, _T("mov a,r0")); break;
1283 case 0xf9: my_stprintf_s(buffer, buffer_len, _T("mov a,r1")); break;
1284 case 0xfa: my_stprintf_s(buffer, buffer_len, _T("mov a,r2")); break;
1285 case 0xfb: my_stprintf_s(buffer, buffer_len, _T("mov a,r3")); break;
1286 case 0xfc: my_stprintf_s(buffer, buffer_len, _T("mov a,r4")); break;
1287 case 0xfd: my_stprintf_s(buffer, buffer_len, _T("mov a,r5")); break;
1288 case 0xfe: my_stprintf_s(buffer, buffer_len, _T("mov a,r6")); break;
1289 case 0xff: my_stprintf_s(buffer, buffer_len, _T("mov a,r7")); break;
1290 default: my_stprintf_s(buffer, buffer_len, _T("illegal")); break;
1296 #define STATE_VERSION 1
1298 void MCS48MEM::save_state(FILEIO* state_fio)
1300 state_fio->FputUint32(STATE_VERSION);
1301 state_fio->FputInt32(this_device_id);
1303 state_fio->Fwrite(ram, sizeof(ram), 1);
1306 bool MCS48MEM::load_state(FILEIO* state_fio)
1308 if(state_fio->FgetUint32() != STATE_VERSION) {
1311 if(state_fio->FgetInt32() != this_device_id) {
1314 state_fio->Fread(ram, sizeof(ram), 1);
1318 void MCS48::save_state(FILEIO* state_fio)
1320 state_fio->FputUint32(STATE_VERSION);
1321 state_fio->FputInt32(this_device_id);
1323 state_fio->Fwrite(opaque, sizeof(mcs48_state), 1);
1326 bool MCS48::load_state(FILEIO* state_fio)
1328 if(state_fio->FgetUint32() != STATE_VERSION) {
1331 if(state_fio->FgetInt32() != this_device_id) {
1334 state_fio->Fread(opaque, sizeof(mcs48_state), 1);
1337 mcs48_state *cpustate = (mcs48_state *)opaque;
1338 cpustate->mem = d_mem;
1339 cpustate->io = d_io;
1340 cpustate->intr = d_intr;