2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
15 #include "../fileio.h"
17 /***************************************************************************
21 Intel MCS-48/UPI-41 Portable Emulator
23 Copyright Mirko Buffoni
24 Based on the original work Copyright Dan Boris, an 8048 emulator
25 You are not allowed to distribute this software commercially
27 ****************************************************************************
29 Note that the default internal divisor for this chip is by 3 and
30 then again by 5, or by 15 total.
32 ***************************************************************************/
34 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
35 #pragma warning( disable : 4244 )
40 /***************************************************************************
42 ***************************************************************************/
44 /* timer/counter enable bits */
45 #define TIMER_ENABLED 0x01
46 #define COUNTER_ENABLED 0x02
54 /* status bits (UPI-41) */
58 /* 8243 expander operations */
61 MCS48_EXPANDER_OP_READ = 0,
62 MCS48_EXPANDER_OP_WRITE = 1,
63 MCS48_EXPANDER_OP_OR = 2,
64 MCS48_EXPANDER_OP_AND = 3
67 /***************************************************************************
69 ***************************************************************************/
71 /* live processor state */
74 UINT16 prevpc; /* 16-bit previous program counter */
75 UINT16 pc; /* 16-bit program counter */
77 UINT8 a; /* 8-bit accumulator */
78 int regptr; /* offset of r0-r7 */
79 UINT8 psw; /* 8-bit cpustate->psw */
80 UINT8 p1; /* 8-bit latched port 1 */
81 UINT8 p2; /* 8-bit latched port 2 */
82 UINT8 timer; /* 8-bit timer */
83 UINT8 prescaler; /* 5-bit timer prescaler */
84 UINT8 t1_history; /* 8-bit history of the T1 input */
85 UINT8 sts; /* 8-bit status register */
87 UINT8 int_state; /* INT signal status */
88 UINT8 irq_state; /* TRUE if an IRQ is pending */
89 UINT8 irq_in_progress; /* TRUE if an IRQ is in progress */
90 UINT8 timer_overflow; /* TRUE on a timer overflow; cleared by taking interrupt */
91 UINT8 timer_flag; /* TRUE on a timer overflow; cleared on JTF */
92 UINT8 tirq_enabled; /* TRUE if the timer IRQ is enabled */
93 UINT8 xirq_enabled; /* TRUE if the external IRQ is enabled */
94 UINT8 t0_clk_enabled; /* TRUE if ent0_clk is called */
95 UINT8 timecount_enabled; /* bitmask of timer/counter enabled */
97 UINT16 a11; /* A11 value, either 0x000 or 0x800 */
109 /* opcode table entry */
110 typedef int (*mcs48_ophandler)(mcs48_state *state);
112 /***************************************************************************
114 ***************************************************************************/
116 #define program_r(a) cpustate->rom[(a) & 0xfff]
118 #define ram_r(a) cpustate->mem->read_data8(a)
119 #define ram_w(a,V) cpustate->mem->write_data8(a, V)
120 #define reg_r(a) cpustate->mem->read_data8(cpustate->regptr + a)
121 #define reg_w(a,V) cpustate->mem->write_data8(cpustate->regptr + a, V)
123 #define ext_r(a) cpustate->io->read_io8(a)
124 #define ext_w(a,V) cpustate->io->write_io8(a, V)
125 #define port_r(a) cpustate->io->read_io8(MCS48_PORT_P0 + a)
126 #define port_w(a,V) cpustate->io->write_io8(MCS48_PORT_P0 + a, V)
127 #define test_r(a) cpustate->io->read_io8(MCS48_PORT_T0 + a)
128 #define test_w(a,V) cpustate->io->write_io8(MCS48_PORT_T0 + a, V)
129 #define bus_r() cpustate->io->read_io8(MCS48_PORT_BUS)
130 #define bus_w(V) cpustate->io->write_io8(MCS48_PORT_BUS, V)
131 #define prog_w(V) cpustate->io->write_io8(MCS48_PORT_PROG, V)
133 /***************************************************************************
135 ***************************************************************************/
137 static int check_irqs(mcs48_state *cpustate);
139 /***************************************************************************
141 ***************************************************************************/
143 /*-------------------------------------------------
144 opcode_fetch - fetch an opcode byte
145 -------------------------------------------------*/
147 INLINE UINT8 opcode_fetch(mcs48_state *cpustate)
149 return cpustate->rom[cpustate->pc++ & 0xfff];
152 /*-------------------------------------------------
153 argument_fetch - fetch an opcode argument
155 -------------------------------------------------*/
157 INLINE UINT8 argument_fetch(mcs48_state *cpustate)
159 return cpustate->rom[cpustate->pc++ & 0xfff];
162 /*-------------------------------------------------
163 update_regptr - update the regptr member to
164 point to the appropriate register bank
165 -------------------------------------------------*/
167 INLINE void update_regptr(mcs48_state *cpustate)
169 cpustate->regptr = ((cpustate->psw & B_FLAG) ? 24 : 0);
172 /*-------------------------------------------------
173 push_pc_psw - push the cpustate->pc and cpustate->psw values onto
175 -------------------------------------------------*/
177 INLINE void push_pc_psw(mcs48_state *cpustate)
179 UINT8 sp = cpustate->psw & 0x07;
180 ram_w(8 + 2*sp, cpustate->pc);
181 ram_w(9 + 2*sp, ((cpustate->pc >> 8) & 0x0f) | (cpustate->psw & 0xf0));
182 cpustate->psw = (cpustate->psw & 0xf8) | ((sp + 1) & 0x07);
185 /*-------------------------------------------------
186 pull_pc_psw - pull the PC and PSW values from
188 -------------------------------------------------*/
190 INLINE void pull_pc_psw(mcs48_state *cpustate)
192 UINT8 sp = (cpustate->psw - 1) & 0x07;
193 cpustate->pc = ram_r(8 + 2*sp);
194 cpustate->pc |= ram_r(9 + 2*sp) << 8;
195 cpustate->psw = ((cpustate->pc >> 8) & 0xf0) | 0x08 | sp;
196 cpustate->pc &= 0xfff;
197 update_regptr(cpustate);
200 /*-------------------------------------------------
201 pull_pc - pull the PC value from the stack,
202 leaving the upper part of PSW intact
203 -------------------------------------------------*/
205 INLINE void pull_pc(mcs48_state *cpustate)
207 UINT8 sp = (cpustate->psw - 1) & 0x07;
208 cpustate->pc = ram_r(8 + 2*sp);
209 cpustate->pc |= ram_r(9 + 2*sp) << 8;
210 cpustate->pc &= 0xfff;
211 cpustate->psw = (cpustate->psw & 0xf0) | 0x08 | sp;
214 /*-------------------------------------------------
215 execute_add - perform the logic of an ADD
217 -------------------------------------------------*/
219 INLINE void execute_add(mcs48_state *cpustate, UINT8 dat)
221 UINT16 temp = cpustate->a + dat;
222 UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f);
224 cpustate->psw &= ~(C_FLAG | A_FLAG);
225 cpustate->psw |= (temp4 << 2) & A_FLAG;
226 cpustate->psw |= (temp >> 1) & C_FLAG;
230 /*-------------------------------------------------
231 execute_addc - perform the logic of an ADDC
233 -------------------------------------------------*/
235 INLINE void execute_addc(mcs48_state *cpustate, UINT8 dat)
237 UINT8 carryin = (cpustate->psw & C_FLAG) >> 7;
238 UINT16 temp = cpustate->a + dat + carryin;
239 UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f) + carryin;
241 cpustate->psw &= ~(C_FLAG | A_FLAG);
242 cpustate->psw |= (temp4 << 2) & A_FLAG;
243 cpustate->psw |= (temp >> 1) & C_FLAG;
247 /*-------------------------------------------------
248 execute_jmp - perform the logic of a JMP
250 -------------------------------------------------*/
252 INLINE void execute_jmp(mcs48_state *cpustate, UINT16 address)
254 UINT16 a11 = (cpustate->irq_in_progress) ? 0 : cpustate->a11;
255 cpustate->pc = address | a11;
258 /*-------------------------------------------------
259 execute_call - perform the logic of a CALL
261 -------------------------------------------------*/
263 INLINE void execute_call(mcs48_state *cpustate, UINT16 address)
265 push_pc_psw(cpustate);
266 execute_jmp(cpustate, address);
269 /*-------------------------------------------------
270 execute_jcc - perform the logic of a
271 conditional jump instruction
272 -------------------------------------------------*/
274 INLINE void execute_jcc(mcs48_state *cpustate, UINT8 result)
276 UINT8 offset = argument_fetch(cpustate);
278 cpustate->pc = ((cpustate->pc - 1) & 0xf00) | offset;
281 /*-------------------------------------------------
282 expander_operation - perform an operation via
283 the 8243 expander chip
284 -------------------------------------------------*/
286 INLINE void expander_operation(mcs48_state *cpustate, UINT8 operation, UINT8 port)
288 /* put opcode/data on low 4 bits of P2 */
289 port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (operation << 2) | (port & 3));
291 /* generate high-to-low transition on PROG line */
294 /* put data on low 4 bits of P2 */
296 port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (cpustate->a & 0x0f));
298 cpustate->a = port_r(2) | 0x0f;
300 /* generate low-to-high transition on PROG line */
304 /***************************************************************************
306 ***************************************************************************/
308 #define OPHANDLER(_name) static int _name(mcs48_state *cpustate)
312 // logerror("MCS-48 PC:%04X - Illegal opcode = %02x\n", cpustate->pc - 1, program_r(cpustate->pc - 1));
316 OPHANDLER( add_a_r0 ) { execute_add(cpustate, reg_r(0)); return 1; }
317 OPHANDLER( add_a_r1 ) { execute_add(cpustate, reg_r(1)); return 1; }
318 OPHANDLER( add_a_r2 ) { execute_add(cpustate, reg_r(2)); return 1; }
319 OPHANDLER( add_a_r3 ) { execute_add(cpustate, reg_r(3)); return 1; }
320 OPHANDLER( add_a_r4 ) { execute_add(cpustate, reg_r(4)); return 1; }
321 OPHANDLER( add_a_r5 ) { execute_add(cpustate, reg_r(5)); return 1; }
322 OPHANDLER( add_a_r6 ) { execute_add(cpustate, reg_r(6)); return 1; }
323 OPHANDLER( add_a_r7 ) { execute_add(cpustate, reg_r(7)); return 1; }
324 OPHANDLER( add_a_xr0 ) { execute_add(cpustate, ram_r(reg_r(0))); return 1; }
325 OPHANDLER( add_a_xr1 ) { execute_add(cpustate, ram_r(reg_r(1))); return 1; }
326 OPHANDLER( add_a_n ) { execute_add(cpustate, argument_fetch(cpustate)); return 2; }
328 OPHANDLER( adc_a_r0 ) { execute_addc(cpustate, reg_r(0)); return 1; }
329 OPHANDLER( adc_a_r1 ) { execute_addc(cpustate, reg_r(1)); return 1; }
330 OPHANDLER( adc_a_r2 ) { execute_addc(cpustate, reg_r(2)); return 1; }
331 OPHANDLER( adc_a_r3 ) { execute_addc(cpustate, reg_r(3)); return 1; }
332 OPHANDLER( adc_a_r4 ) { execute_addc(cpustate, reg_r(4)); return 1; }
333 OPHANDLER( adc_a_r5 ) { execute_addc(cpustate, reg_r(5)); return 1; }
334 OPHANDLER( adc_a_r6 ) { execute_addc(cpustate, reg_r(6)); return 1; }
335 OPHANDLER( adc_a_r7 ) { execute_addc(cpustate, reg_r(7)); return 1; }
336 OPHANDLER( adc_a_xr0 ) { execute_addc(cpustate, ram_r(reg_r(0))); return 1; }
337 OPHANDLER( adc_a_xr1 ) { execute_addc(cpustate, ram_r(reg_r(1))); return 1; }
338 OPHANDLER( adc_a_n ) { execute_addc(cpustate, argument_fetch(cpustate)); return 2; }
340 OPHANDLER( anl_a_r0 ) { cpustate->a &= reg_r(0); return 1; }
341 OPHANDLER( anl_a_r1 ) { cpustate->a &= reg_r(1); return 1; }
342 OPHANDLER( anl_a_r2 ) { cpustate->a &= reg_r(2); return 1; }
343 OPHANDLER( anl_a_r3 ) { cpustate->a &= reg_r(3); return 1; }
344 OPHANDLER( anl_a_r4 ) { cpustate->a &= reg_r(4); return 1; }
345 OPHANDLER( anl_a_r5 ) { cpustate->a &= reg_r(5); return 1; }
346 OPHANDLER( anl_a_r6 ) { cpustate->a &= reg_r(6); return 1; }
347 OPHANDLER( anl_a_r7 ) { cpustate->a &= reg_r(7); return 1; }
348 OPHANDLER( anl_a_xr0 ) { cpustate->a &= ram_r(reg_r(0)); return 1; }
349 OPHANDLER( anl_a_xr1 ) { cpustate->a &= ram_r(reg_r(1)); return 1; }
350 OPHANDLER( anl_a_n ) { cpustate->a &= argument_fetch(cpustate); return 2; }
352 OPHANDLER( anl_bus_n ) { bus_w(bus_r() & argument_fetch(cpustate)); return 2; }
353 OPHANDLER( anl_p1_n ) { port_w(1, cpustate->p1 &= argument_fetch(cpustate)); return 2; }
354 OPHANDLER( anl_p2_n ) { port_w(2, cpustate->p2 &= argument_fetch(cpustate)); return 2; }
355 OPHANDLER( anld_p4_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 4); return 2; }
356 OPHANDLER( anld_p5_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 5); return 2; }
357 OPHANDLER( anld_p6_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 6); return 2; }
358 OPHANDLER( anld_p7_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_AND, 7); return 2; }
360 OPHANDLER( call_0 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x000); return 2; }
361 OPHANDLER( call_1 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x100); return 2; }
362 OPHANDLER( call_2 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x200); return 2; }
363 OPHANDLER( call_3 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x300); return 2; }
364 OPHANDLER( call_4 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x400); return 2; }
365 OPHANDLER( call_5 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x500); return 2; }
366 OPHANDLER( call_6 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x600); return 2; }
367 OPHANDLER( call_7 ) { execute_call(cpustate, argument_fetch(cpustate) | 0x700); return 2; }
369 OPHANDLER( clr_a ) { cpustate->a = 0; return 1; }
370 OPHANDLER( clr_c ) { cpustate->psw &= ~C_FLAG; return 1; }
371 OPHANDLER( clr_f0 ) { cpustate->psw &= ~F_FLAG; cpustate->sts &= ~STS_F0; return 1; }
372 OPHANDLER( clr_f1 ) { cpustate->sts &= ~STS_F1; return 1; }
374 OPHANDLER( cpl_a ) { cpustate->a ^= 0xff; return 1; }
375 OPHANDLER( cpl_c ) { cpustate->psw ^= C_FLAG; return 1; }
376 OPHANDLER( cpl_f0 ) { cpustate->psw ^= F_FLAG; cpustate->sts ^= STS_F0; return 1; }
377 OPHANDLER( cpl_f1 ) { cpustate->sts ^= STS_F1; return 1; }
381 if ((cpustate->a & 0x0f) > 0x09 || (cpustate->psw & A_FLAG))
384 if ((cpustate->a & 0xf0) == 0x00)
385 cpustate->psw |= C_FLAG;
387 if ((cpustate->a & 0xf0) > 0x90 || (cpustate->psw & C_FLAG))
390 cpustate->psw |= C_FLAG;
393 cpustate->psw &= ~C_FLAG;
397 OPHANDLER( dec_a ) { cpustate->a--; return 1; }
398 OPHANDLER( dec_r0 ) { reg_w(0, reg_r(0) - 1); return 1; }
399 OPHANDLER( dec_r1 ) { reg_w(1, reg_r(1) - 1); return 1; }
400 OPHANDLER( dec_r2 ) { reg_w(2, reg_r(2) - 1); return 1; }
401 OPHANDLER( dec_r3 ) { reg_w(3, reg_r(3) - 1); return 1; }
402 OPHANDLER( dec_r4 ) { reg_w(4, reg_r(4) - 1); return 1; }
403 OPHANDLER( dec_r5 ) { reg_w(5, reg_r(5) - 1); return 1; }
404 OPHANDLER( dec_r6 ) { reg_w(6, reg_r(6) - 1); return 1; }
405 OPHANDLER( dec_r7 ) { reg_w(7, reg_r(7) - 1); return 1; }
407 OPHANDLER( dis_i ) { cpustate->xirq_enabled = FALSE; return 1; }
408 OPHANDLER( dis_tcnti ) { cpustate->tirq_enabled = FALSE; cpustate->timer_overflow = FALSE; return 1; }
410 OPHANDLER( djnz_r0 ) { UINT8 r0 = reg_r(0); reg_w(0, --r0); execute_jcc(cpustate, r0 != 0); return 2; }
411 OPHANDLER( djnz_r1 ) { UINT8 r1 = reg_r(1); reg_w(1, --r1); execute_jcc(cpustate, r1 != 0); return 2; }
412 OPHANDLER( djnz_r2 ) { UINT8 r2 = reg_r(2); reg_w(2, --r2); execute_jcc(cpustate, r2 != 0); return 2; }
413 OPHANDLER( djnz_r3 ) { UINT8 r3 = reg_r(3); reg_w(3, --r3); execute_jcc(cpustate, r3 != 0); return 2; }
414 OPHANDLER( djnz_r4 ) { UINT8 r4 = reg_r(4); reg_w(4, --r4); execute_jcc(cpustate, r4 != 0); return 2; }
415 OPHANDLER( djnz_r5 ) { UINT8 r5 = reg_r(5); reg_w(5, --r5); execute_jcc(cpustate, r5 != 0); return 2; }
416 OPHANDLER( djnz_r6 ) { UINT8 r6 = reg_r(6); reg_w(6, --r6); execute_jcc(cpustate, r6 != 0); return 2; }
417 OPHANDLER( djnz_r7 ) { UINT8 r7 = reg_r(7); reg_w(7, --r7); execute_jcc(cpustate, r7 != 0); return 2; }
419 OPHANDLER( en_i ) { cpustate->xirq_enabled = TRUE; return 1 + check_irqs(cpustate); }
420 OPHANDLER( en_tcnti ) { cpustate->tirq_enabled = TRUE; return 1 + check_irqs(cpustate); }
421 OPHANDLER( ent0_clk ) { cpustate->t0_clk_enabled = TRUE; return 1; }
423 OPHANDLER( in_a_p1 ) { cpustate->a = port_r(1) & cpustate->p1; return 2; }
424 OPHANDLER( in_a_p2 ) { cpustate->a = port_r(2) & cpustate->p2; return 2; }
425 OPHANDLER( ins_a_bus ) { cpustate->a = bus_r(); return 2; }
427 OPHANDLER( inc_a ) { cpustate->a++; return 1; }
428 OPHANDLER( inc_r0 ) { reg_w(0, reg_r(0) + 1); return 1; }
429 OPHANDLER( inc_r1 ) { reg_w(1, reg_r(1) + 1); return 1; }
430 OPHANDLER( inc_r2 ) { reg_w(2, reg_r(2) + 1); return 1; }
431 OPHANDLER( inc_r3 ) { reg_w(3, reg_r(3) + 1); return 1; }
432 OPHANDLER( inc_r4 ) { reg_w(4, reg_r(4) + 1); return 1; }
433 OPHANDLER( inc_r5 ) { reg_w(5, reg_r(5) + 1); return 1; }
434 OPHANDLER( inc_r6 ) { reg_w(6, reg_r(6) + 1); return 1; }
435 OPHANDLER( inc_r7 ) { reg_w(7, reg_r(7) + 1); return 1; }
436 OPHANDLER( inc_xr0 ) { UINT8 r0 = reg_r(0); ram_w(r0, ram_r(r0) + 1); return 1; }
437 OPHANDLER( inc_xr1 ) { UINT8 r1 = reg_r(1); ram_w(r1, ram_r(r1) + 1); return 1; }
439 OPHANDLER( jb_0 ) { execute_jcc(cpustate, (cpustate->a & 0x01) != 0); return 2; }
440 OPHANDLER( jb_1 ) { execute_jcc(cpustate, (cpustate->a & 0x02) != 0); return 2; }
441 OPHANDLER( jb_2 ) { execute_jcc(cpustate, (cpustate->a & 0x04) != 0); return 2; }
442 OPHANDLER( jb_3 ) { execute_jcc(cpustate, (cpustate->a & 0x08) != 0); return 2; }
443 OPHANDLER( jb_4 ) { execute_jcc(cpustate, (cpustate->a & 0x10) != 0); return 2; }
444 OPHANDLER( jb_5 ) { execute_jcc(cpustate, (cpustate->a & 0x20) != 0); return 2; }
445 OPHANDLER( jb_6 ) { execute_jcc(cpustate, (cpustate->a & 0x40) != 0); return 2; }
446 OPHANDLER( jb_7 ) { execute_jcc(cpustate, (cpustate->a & 0x80) != 0); return 2; }
447 OPHANDLER( jc ) { execute_jcc(cpustate, (cpustate->psw & C_FLAG) != 0); return 2; }
448 OPHANDLER( jf0 ) { execute_jcc(cpustate, (cpustate->psw & F_FLAG) != 0); return 2; }
449 OPHANDLER( jf1 ) { execute_jcc(cpustate, (cpustate->sts & STS_F1) != 0); return 2; }
450 OPHANDLER( jnc ) { execute_jcc(cpustate, (cpustate->psw & C_FLAG) == 0); return 2; }
451 OPHANDLER( jni ) { execute_jcc(cpustate, cpustate->int_state == 0); return 2; }
452 OPHANDLER( jnt_0 ) { execute_jcc(cpustate, test_r(0) == 0); return 2; }
453 OPHANDLER( jnt_1 ) { execute_jcc(cpustate, test_r(1) == 0); return 2; }
454 OPHANDLER( jnz ) { execute_jcc(cpustate, cpustate->a != 0); return 2; }
455 OPHANDLER( jtf ) { execute_jcc(cpustate, cpustate->timer_flag); cpustate->timer_flag = FALSE; return 2; }
456 OPHANDLER( jt_0 ) { execute_jcc(cpustate, test_r(0) != 0); return 2; }
457 OPHANDLER( jt_1 ) { execute_jcc(cpustate, test_r(1) != 0); return 2; }
458 OPHANDLER( jz ) { execute_jcc(cpustate, cpustate->a == 0); return 2; }
460 OPHANDLER( jmp_0 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x000); return 2; }
461 OPHANDLER( jmp_1 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x100); return 2; }
462 OPHANDLER( jmp_2 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x200); return 2; }
463 OPHANDLER( jmp_3 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x300); return 2; }
464 OPHANDLER( jmp_4 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x400); return 2; }
465 OPHANDLER( jmp_5 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x500); return 2; }
466 OPHANDLER( jmp_6 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x600); return 2; }
467 OPHANDLER( jmp_7 ) { execute_jmp(cpustate, argument_fetch(cpustate) | 0x700); return 2; }
468 OPHANDLER( jmpp_xa ) { cpustate->pc &= 0xf00; cpustate->pc |= program_r(cpustate->pc | cpustate->a); return 2; }
470 OPHANDLER( mov_a_n ) { cpustate->a = argument_fetch(cpustate); return 2; }
471 OPHANDLER( mov_a_psw ) { cpustate->a = cpustate->psw; return 1; }
472 OPHANDLER( mov_a_r0 ) { cpustate->a = reg_r(0); return 1; }
473 OPHANDLER( mov_a_r1 ) { cpustate->a = reg_r(1); return 1; }
474 OPHANDLER( mov_a_r2 ) { cpustate->a = reg_r(2); return 1; }
475 OPHANDLER( mov_a_r3 ) { cpustate->a = reg_r(3); return 1; }
476 OPHANDLER( mov_a_r4 ) { cpustate->a = reg_r(4); return 1; }
477 OPHANDLER( mov_a_r5 ) { cpustate->a = reg_r(5); return 1; }
478 OPHANDLER( mov_a_r6 ) { cpustate->a = reg_r(6); return 1; }
479 OPHANDLER( mov_a_r7 ) { cpustate->a = reg_r(7); return 1; }
480 OPHANDLER( mov_a_xr0 ) { cpustate->a = ram_r(reg_r(0)); return 1; }
481 OPHANDLER( mov_a_xr1 ) { cpustate->a = ram_r(reg_r(1)); return 1; }
482 OPHANDLER( mov_a_t ) { cpustate->a = cpustate->timer; return 1; }
484 OPHANDLER( mov_psw_a ) { cpustate->psw = cpustate->a; update_regptr(cpustate); return 1; }
485 OPHANDLER( mov_r0_a ) { reg_w(0, cpustate->a); return 1; }
486 OPHANDLER( mov_r1_a ) { reg_w(1, cpustate->a); return 1; }
487 OPHANDLER( mov_r2_a ) { reg_w(2, cpustate->a); return 1; }
488 OPHANDLER( mov_r3_a ) { reg_w(3, cpustate->a); return 1; }
489 OPHANDLER( mov_r4_a ) { reg_w(4, cpustate->a); return 1; }
490 OPHANDLER( mov_r5_a ) { reg_w(5, cpustate->a); return 1; }
491 OPHANDLER( mov_r6_a ) { reg_w(6, cpustate->a); return 1; }
492 OPHANDLER( mov_r7_a ) { reg_w(7, cpustate->a); return 1; }
493 OPHANDLER( mov_r0_n ) { reg_w(0, argument_fetch(cpustate)); return 2; }
494 OPHANDLER( mov_r1_n ) { reg_w(1, argument_fetch(cpustate)); return 2; }
495 OPHANDLER( mov_r2_n ) { reg_w(2, argument_fetch(cpustate)); return 2; }
496 OPHANDLER( mov_r3_n ) { reg_w(3, argument_fetch(cpustate)); return 2; }
497 OPHANDLER( mov_r4_n ) { reg_w(4, argument_fetch(cpustate)); return 2; }
498 OPHANDLER( mov_r5_n ) { reg_w(5, argument_fetch(cpustate)); return 2; }
499 OPHANDLER( mov_r6_n ) { reg_w(6, argument_fetch(cpustate)); return 2; }
500 OPHANDLER( mov_r7_n ) { reg_w(7, argument_fetch(cpustate)); return 2; }
501 OPHANDLER( mov_t_a ) { cpustate->timer = cpustate->a; return 1; }
502 OPHANDLER( mov_xr0_a ) { ram_w(reg_r(0), cpustate->a); return 1; }
503 OPHANDLER( mov_xr1_a ) { ram_w(reg_r(1), cpustate->a); return 1; }
504 OPHANDLER( mov_xr0_n ) { ram_w(reg_r(0), argument_fetch(cpustate)); return 2; }
505 OPHANDLER( mov_xr1_n ) { ram_w(reg_r(1), argument_fetch(cpustate)); return 2; }
507 OPHANDLER( movd_a_p4 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 4); return 2; }
508 OPHANDLER( movd_a_p5 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 5); return 2; }
509 OPHANDLER( movd_a_p6 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 6); return 2; }
510 OPHANDLER( movd_a_p7 ) { expander_operation(cpustate, MCS48_EXPANDER_OP_READ, 7); return 2; }
511 OPHANDLER( movd_p4_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 4); return 2; }
512 OPHANDLER( movd_p5_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 5); return 2; }
513 OPHANDLER( movd_p6_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 6); return 2; }
514 OPHANDLER( movd_p7_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_WRITE, 7); return 2; }
516 OPHANDLER( movp_a_xa ) { cpustate->a = program_r((cpustate->pc & 0xf00) | cpustate->a); return 2; }
517 OPHANDLER( movp3_a_xa ) { cpustate->a = program_r(0x300 | cpustate->a); return 2; }
519 OPHANDLER( movx_a_xr0 ) { cpustate->a = ext_r(reg_r(0)); return 2; }
520 OPHANDLER( movx_a_xr1 ) { cpustate->a = ext_r(reg_r(1)); return 2; }
521 OPHANDLER( movx_xr0_a ) { ext_w(reg_r(0), cpustate->a); return 2; }
522 OPHANDLER( movx_xr1_a ) { ext_w(reg_r(1), cpustate->a); return 2; }
524 OPHANDLER( nop ) { return 1; }
526 OPHANDLER( orl_a_r0 ) { cpustate->a |= reg_r(0); return 1; }
527 OPHANDLER( orl_a_r1 ) { cpustate->a |= reg_r(1); return 1; }
528 OPHANDLER( orl_a_r2 ) { cpustate->a |= reg_r(2); return 1; }
529 OPHANDLER( orl_a_r3 ) { cpustate->a |= reg_r(3); return 1; }
530 OPHANDLER( orl_a_r4 ) { cpustate->a |= reg_r(4); return 1; }
531 OPHANDLER( orl_a_r5 ) { cpustate->a |= reg_r(5); return 1; }
532 OPHANDLER( orl_a_r6 ) { cpustate->a |= reg_r(6); return 1; }
533 OPHANDLER( orl_a_r7 ) { cpustate->a |= reg_r(7); return 1; }
534 OPHANDLER( orl_a_xr0 ) { cpustate->a |= ram_r(reg_r(0)); return 1; }
535 OPHANDLER( orl_a_xr1 ) { cpustate->a |= ram_r(reg_r(1)); return 1; }
536 OPHANDLER( orl_a_n ) { cpustate->a |= argument_fetch(cpustate); return 2; }
538 OPHANDLER( orl_bus_n ) { bus_w(bus_r() | argument_fetch(cpustate)); return 2; }
539 OPHANDLER( orl_p1_n ) { port_w(1, cpustate->p1 |= argument_fetch(cpustate)); return 2; }
540 OPHANDLER( orl_p2_n ) { port_w(2, cpustate->p2 |= argument_fetch(cpustate)); return 2; }
541 OPHANDLER( orld_p4_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 4); return 2; }
542 OPHANDLER( orld_p5_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 5); return 2; }
543 OPHANDLER( orld_p6_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 6); return 2; }
544 OPHANDLER( orld_p7_a ) { expander_operation(cpustate, MCS48_EXPANDER_OP_OR, 7); return 2; }
546 OPHANDLER( outl_bus_a ) { bus_w(cpustate->a); return 2; }
547 OPHANDLER( outl_p1_a ) { port_w(1, cpustate->p1 = cpustate->a); return 2; }
548 OPHANDLER( outl_p2_a ) { port_w(2, cpustate->p2 = cpustate->a); return 2; }
550 OPHANDLER( ret ) { pull_pc(cpustate); return 2; }
553 pull_pc_psw(cpustate);
555 /* implicitly clear the IRQ in progress flip flop and re-check interrupts */
556 cpustate->irq_in_progress = FALSE;
557 return 2 + check_irqs(cpustate);
560 OPHANDLER( rl_a ) { cpustate->a = (cpustate->a << 1) | (cpustate->a >> 7); return 1; }
561 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; }
563 OPHANDLER( rr_a ) { cpustate->a = (cpustate->a >> 1) | (cpustate->a << 7); return 1; }
564 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; }
566 OPHANDLER( sel_mb0 ) { cpustate->a11 = 0x000; return 1; }
567 OPHANDLER( sel_mb1 ) { cpustate->a11 = 0x800; return 1; }
569 OPHANDLER( sel_rb0 ) { cpustate->psw &= ~B_FLAG; update_regptr(cpustate); return 1; }
570 OPHANDLER( sel_rb1 ) { cpustate->psw |= B_FLAG; update_regptr(cpustate); return 1; }
572 OPHANDLER( stop_tcnt ) { cpustate->timecount_enabled = 0; return 1; }
574 OPHANDLER( strt_cnt ) { cpustate->timecount_enabled = COUNTER_ENABLED; cpustate->t1_history = test_r(1); return 1; }
575 OPHANDLER( strt_t ) { cpustate->timecount_enabled = TIMER_ENABLED; cpustate->prescaler = 0; return 1; }
577 OPHANDLER( swap_a ) { cpustate->a = (cpustate->a << 4) | (cpustate->a >> 4); return 1; }
579 OPHANDLER( xch_a_r0 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(0); reg_w(0, tmp); return 1; }
580 OPHANDLER( xch_a_r1 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(1); reg_w(1, tmp); return 1; }
581 OPHANDLER( xch_a_r2 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(2); reg_w(2, tmp); return 1; }
582 OPHANDLER( xch_a_r3 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(3); reg_w(3, tmp); return 1; }
583 OPHANDLER( xch_a_r4 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(4); reg_w(4, tmp); return 1; }
584 OPHANDLER( xch_a_r5 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(5); reg_w(5, tmp); return 1; }
585 OPHANDLER( xch_a_r6 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(6); reg_w(6, tmp); return 1; }
586 OPHANDLER( xch_a_r7 ) { UINT8 tmp = cpustate->a; cpustate->a = reg_r(7); reg_w(7, tmp); return 1; }
587 OPHANDLER( xch_a_xr0 ) { UINT8 r0 = reg_r(0); UINT8 tmp = cpustate->a; cpustate->a = ram_r(r0); ram_w(r0, tmp); return 1; }
588 OPHANDLER( xch_a_xr1 ) { UINT8 r1 = reg_r(1); UINT8 tmp = cpustate->a; cpustate->a = ram_r(r1); ram_w(r1, tmp); return 1; }
590 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; }
591 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; }
593 OPHANDLER( xrl_a_r0 ) { cpustate->a ^= reg_r(0); return 1; }
594 OPHANDLER( xrl_a_r1 ) { cpustate->a ^= reg_r(1); return 1; }
595 OPHANDLER( xrl_a_r2 ) { cpustate->a ^= reg_r(2); return 1; }
596 OPHANDLER( xrl_a_r3 ) { cpustate->a ^= reg_r(3); return 1; }
597 OPHANDLER( xrl_a_r4 ) { cpustate->a ^= reg_r(4); return 1; }
598 OPHANDLER( xrl_a_r5 ) { cpustate->a ^= reg_r(5); return 1; }
599 OPHANDLER( xrl_a_r6 ) { cpustate->a ^= reg_r(6); return 1; }
600 OPHANDLER( xrl_a_r7 ) { cpustate->a ^= reg_r(7); return 1; }
601 OPHANDLER( xrl_a_xr0 ) { cpustate->a ^= ram_r(reg_r(0)); return 1; }
602 OPHANDLER( xrl_a_xr1 ) { cpustate->a ^= ram_r(reg_r(1)); return 1; }
603 OPHANDLER( xrl_a_n ) { cpustate->a ^= argument_fetch(cpustate); return 2; }
605 /***************************************************************************
607 ***************************************************************************/
609 static const mcs48_ophandler opcode_table[256]=
611 nop, illegal, outl_bus_a,add_a_n, jmp_0, en_i, illegal, dec_a, /* 00 */
612 ins_a_bus, in_a_p1, in_a_p2, illegal, movd_a_p4, movd_a_p5, movd_a_p6, movd_a_p7,
613 inc_xr0, inc_xr1, jb_0, adc_a_n, call_0, dis_i, jtf, inc_a, /* 10 */
614 inc_r0, inc_r1, inc_r2, inc_r3, inc_r4, inc_r5, inc_r6, inc_r7,
615 xch_a_xr0, xch_a_xr1, illegal, mov_a_n, jmp_1, en_tcnti, jnt_0, clr_a, /* 20 */
616 xch_a_r0, xch_a_r1, xch_a_r2, xch_a_r3, xch_a_r4, xch_a_r5, xch_a_r6, xch_a_r7,
617 xchd_a_xr0, xchd_a_xr1, jb_1, illegal, call_1, dis_tcnti, jt_0, cpl_a, /* 30 */
618 illegal, outl_p1_a, outl_p2_a, illegal, movd_p4_a, movd_p5_a, movd_p6_a, movd_p7_a,
619 orl_a_xr0, orl_a_xr1, mov_a_t, orl_a_n, jmp_2, strt_cnt, jnt_1, swap_a, /* 40 */
620 orl_a_r0, orl_a_r1, orl_a_r2, orl_a_r3, orl_a_r4, orl_a_r5, orl_a_r6, orl_a_r7,
621 anl_a_xr0, anl_a_xr1, jb_2, anl_a_n, call_2, strt_t, jt_1, da_a, /* 50 */
622 anl_a_r0, anl_a_r1, anl_a_r2, anl_a_r3, anl_a_r4, anl_a_r5, anl_a_r6, anl_a_r7,
623 add_a_xr0, add_a_xr1, mov_t_a, illegal, jmp_3, stop_tcnt, illegal, rrc_a, /* 60 */
624 add_a_r0, add_a_r1, add_a_r2, add_a_r3, add_a_r4, add_a_r5, add_a_r6, add_a_r7,
625 adc_a_xr0, adc_a_xr1, jb_3, illegal, call_3, ent0_clk, jf1, rr_a, /* 70 */
626 adc_a_r0, adc_a_r1, adc_a_r2, adc_a_r3, adc_a_r4, adc_a_r5, adc_a_r6, adc_a_r7,
627 movx_a_xr0, movx_a_xr1, illegal, ret, jmp_4, clr_f0, jni, illegal, /* 80 */
628 orl_bus_n, orl_p1_n, orl_p2_n, illegal, orld_p4_a, orld_p5_a, orld_p6_a, orld_p7_a,
629 movx_xr0_a, movx_xr1_a, jb_4, retr, call_4, cpl_f0, jnz, clr_c, /* 90 */
630 anl_bus_n, anl_p1_n, anl_p2_n, illegal, anld_p4_a, anld_p5_a, anld_p6_a, anld_p7_a,
631 mov_xr0_a, mov_xr1_a, illegal, movp_a_xa, jmp_5, clr_f1, illegal, cpl_c, /* A0 */
632 mov_r0_a, mov_r1_a, mov_r2_a, mov_r3_a, mov_r4_a, mov_r5_a, mov_r6_a, mov_r7_a,
633 mov_xr0_n, mov_xr1_n, jb_5, jmpp_xa, call_5, cpl_f1, jf0, illegal, /* B0 */
634 mov_r0_n, mov_r1_n, mov_r2_n, mov_r3_n, mov_r4_n, mov_r5_n, mov_r6_n, mov_r7_n,
635 illegal, illegal, illegal, illegal, jmp_6, sel_rb0, jz, mov_a_psw, /* C0 */
636 dec_r0, dec_r1, dec_r2, dec_r3, dec_r4, dec_r5, dec_r6, dec_r7,
637 xrl_a_xr0, xrl_a_xr1, jb_6, xrl_a_n, call_6, sel_rb1, illegal, mov_psw_a, /* D0 */
638 xrl_a_r0, xrl_a_r1, xrl_a_r2, xrl_a_r3, xrl_a_r4, xrl_a_r5, xrl_a_r6, xrl_a_r7,
639 illegal, illegal, illegal, movp3_a_xa,jmp_7, sel_mb0, jnc, rl_a, /* E0 */
640 djnz_r0, djnz_r1, djnz_r2, djnz_r3, djnz_r4, djnz_r5, djnz_r6, djnz_r7,
641 mov_a_xr0, mov_a_xr1, jb_7, illegal, call_7, sel_mb1, jc, rlc_a, /* F0 */
642 mov_a_r0, mov_a_r1, mov_a_r2, mov_a_r3, mov_a_r4, mov_a_r5, mov_a_r6, mov_a_r7
645 /***************************************************************************
647 ***************************************************************************/
649 void MCS48::initialize()
651 opaque = calloc(1, sizeof(mcs48_state));
653 mcs48_state *cpustate = (mcs48_state *)opaque;
655 cpustate->mem = d_mem;
657 cpustate->intr = d_intr;
659 d_mem_stored = d_mem;
661 d_debugger->set_context_mem(d_mem);
662 d_debugger->set_context_io(d_io);
666 void MCS48::release()
673 mcs48_state *cpustate = (mcs48_state *)opaque;
675 /* confirmed from reset description */
677 cpustate->psw = (cpustate->psw & (C_FLAG | A_FLAG)) | 0x08;
678 cpustate->a11 = 0x000;
682 // port_w(1, cpustate->p1);
683 // port_w(2, cpustate->p2);
684 cpustate->tirq_enabled = FALSE;
685 cpustate->xirq_enabled = FALSE;
686 cpustate->t0_clk_enabled = FALSE;
687 cpustate->timecount_enabled = 0;
688 cpustate->timer_flag = FALSE;
691 cpustate->icount = 0;
693 /* confirmed from interrupt logic description */
694 cpustate->int_state = TRUE;
695 cpustate->irq_state = cpustate->irq_in_progress = FALSE;
696 cpustate->timer_overflow = FALSE;
699 void MCS48::load_rom_image(_TCHAR *file_path)
701 mcs48_state *cpustate = (mcs48_state *)opaque;
703 memset(cpustate->rom, 0, sizeof(cpustate->rom));
705 FILEIO* fio = new FILEIO();
706 if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
707 fio->Fread(cpustate->rom, sizeof(cpustate->rom), 1);
713 uint8 *MCS48::get_rom_ptr()
715 mcs48_state *cpustate = (mcs48_state *)opaque;
716 return cpustate->rom;
719 /***************************************************************************
721 ***************************************************************************/
723 /*-------------------------------------------------
724 check_irqs - check for and process IRQs
725 -------------------------------------------------*/
727 static int check_irqs(mcs48_state *cpustate)
729 /* if something is in progress, we do nothing */
730 if (cpustate->irq_in_progress)
733 /* external interrupts take priority */
734 if (cpustate->irq_state && cpustate->xirq_enabled)
736 cpustate->irq_state = FALSE;
737 cpustate->irq_in_progress = TRUE;
739 /* transfer to location 0x03 */
740 push_pc_psw(cpustate);
743 /* indicate we took the external IRQ */
744 if (cpustate->intr != NULL)
745 cpustate->intr->intr_ack();
749 /* timer overflow interrupts follow */
750 if (cpustate->timer_overflow && cpustate->tirq_enabled)
752 cpustate->irq_in_progress = TRUE;
754 /* transfer to location 0x07 */
755 push_pc_psw(cpustate);
758 /* timer overflow flip-flop is reset once taken */
759 cpustate->timer_overflow = FALSE;
765 /*-------------------------------------------------
766 burn_cycles - burn cycles, processing timers
768 -------------------------------------------------*/
770 static void burn_cycles(mcs48_state *cpustate, int count)
772 int timerover = FALSE;
774 /* output (clock*15/3) hz to t0 */
775 if (cpustate->t0_clk_enabled)
777 for(int i = 0; i < count * 5; i++)
784 /* if the timer is enabled, accumulate prescaler cycles */
785 if (cpustate->timecount_enabled & TIMER_ENABLED)
787 UINT8 oldtimer = cpustate->timer;
788 cpustate->prescaler += count;
789 cpustate->timer += cpustate->prescaler >> 5;
790 cpustate->prescaler &= 0x1f;
791 timerover = (oldtimer != 0 && cpustate->timer == 0);
794 /* if the counter is enabled, poll the T1 test input once for each cycle */
795 else if (cpustate->timecount_enabled & COUNTER_ENABLED)
796 for ( ; count > 0; count--)
798 cpustate->t1_history = (cpustate->t1_history << 1) | (test_r(1) & 1);
799 if ((cpustate->t1_history & 3) == 2)
800 timerover = (++cpustate->timer == 0);
803 /* if either source caused a timer overflow, set the flags and check IRQs */
806 cpustate->timer_flag = TRUE;
808 /* according to the docs, if an overflow occurs with interrupts disabled, the overflow is not stored */
809 if (cpustate->tirq_enabled)
811 cpustate->timer_overflow = TRUE;
812 check_irqs(cpustate);
817 int MCS48::run(int icount)
819 mcs48_state *cpustate = (mcs48_state *)opaque;
823 cpustate->icount = 1;
825 cpustate->icount += icount;
826 if (cpustate->icount < 0) {
831 int base_icount = cpustate->icount;
833 update_regptr(cpustate);
835 /* external interrupts may have been set since we last checked */
836 curcycles = check_irqs(cpustate);
837 cpustate->icount -= curcycles * 15;
838 if (cpustate->timecount_enabled != 0)
839 burn_cycles(cpustate, curcycles);
841 /* iterate over remaining cycles, guaranteeing at least one instruction */
845 bool now_debugging = d_debugger->now_debugging;
847 d_debugger->check_break_points(cpustate->pc);
848 if(d_debugger->now_suspended) {
850 while(d_debugger->now_debugging && d_debugger->now_suspended) {
854 if(d_debugger->now_debugging) {
855 d_mem = d_io = d_debugger;
857 now_debugging = false;
860 /* fetch next opcode */
861 cpustate->prevpc = cpustate->pc;
862 unsigned opcode = opcode_fetch(cpustate);
864 /* process opcode and count cycles */
865 curcycles = (*opcode_table[opcode])(cpustate);
867 /* burn the cycles */
868 cpustate->icount -= curcycles * 15;
869 if (cpustate->timecount_enabled != 0)
870 burn_cycles(cpustate, curcycles);
873 if(!d_debugger->now_going) {
874 d_debugger->now_suspended = true;
876 d_mem = d_mem_stored;
881 /* fetch next opcode */
882 cpustate->prevpc = cpustate->pc;
883 unsigned opcode = opcode_fetch(cpustate);
885 /* process opcode and count cycles */
886 curcycles = (*opcode_table[opcode])(cpustate);
888 /* burn the cycles */
889 cpustate->icount -= curcycles * 15;
890 if (cpustate->timecount_enabled != 0)
891 burn_cycles(cpustate, curcycles);
895 } while (cpustate->icount > 0);
897 return base_icount - cpustate->icount;
900 uint32 MCS48::get_pc()
902 mcs48_state *cpustate = (mcs48_state *)opaque;
903 return cpustate->prevpc;
906 uint32 MCS48::get_next_pc()
908 mcs48_state *cpustate = (mcs48_state *)opaque;
912 /***************************************************************************
913 GENERAL CONTEXT ACCESS
914 ***************************************************************************/
916 void MCS48::write_signal(int id, uint32 data, uint32 mask)
918 mcs48_state *cpustate = (mcs48_state *)opaque;
920 if(id == SIG_CPU_IRQ) {
921 UINT8 prev = cpustate->int_state;
922 cpustate->int_state = ((data & mask) != 0);
924 if(prev && !cpustate->int_state) {
925 cpustate->irq_state = TRUE;
931 void MCS48::debug_write_data8(uint32 addr, uint32 data)
933 d_mem_stored->write_data8(addr, data);
936 uint32 MCS48::debug_read_data8(uint32 addr)
938 return d_mem_stored->read_data8(addr);
941 void MCS48::debug_write_io8(uint32 addr, uint32 data)
943 d_io_stored->write_io8(addr, data);
946 uint32 MCS48::debug_read_io8(uint32 addr)
948 return d_io_stored->read_io8(addr);
951 bool MCS48::debug_write_reg(_TCHAR *reg, uint32 data)
953 mcs48_state *cpustate = (mcs48_state *)opaque;
955 if(_tcsicmp(reg, _T("R0")) == 0) {
957 } else if(_tcsicmp(reg, _T("R1")) == 0) {
959 } else if(_tcsicmp(reg, _T("R2")) == 0) {
961 } else if(_tcsicmp(reg, _T("R3")) == 0) {
963 } else if(_tcsicmp(reg, _T("R4")) == 0) {
965 } else if(_tcsicmp(reg, _T("R5")) == 0) {
967 } else if(_tcsicmp(reg, _T("R6")) == 0) {
969 } else if(_tcsicmp(reg, _T("R7")) == 0) {
977 void MCS48::debug_regs_info(_TCHAR *buffer, size_t buffer_len)
980 R0 = 00 R1 = 00 R2 = 00 R3 = 00 (R0)= 00 (R1)= 00 (SP-1)= 0000 PC = 0000
981 R4 = 00 R5 = 00 R6 = 00 R7 = 00 AC = 00 SP = 00 [MB F1 C AC F0 BS]
983 mcs48_state *cpustate = (mcs48_state *)opaque;
984 UINT8 sp = 8 + 2 * (cpustate->psw & 7);
985 UINT8 prev_sp = 8 + 2 * ((cpustate->psw - 1) & 7);
987 _stprintf_s(buffer, buffer_len,
988 _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]"),
989 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)),
990 d_mem_stored->read_data8(prev_sp) | (d_mem_stored->read_data8(prev_sp + 1) << 8), cpustate->pc,
991 reg_r(4), reg_r(5), reg_r(6), reg_r(7), cpustate->a, sp,
992 (cpustate->a11 == 0x800) ? _T("MB") : _T("--"), (cpustate->sts & STS_F1) ? _T("F1") : _T("--"),
993 (cpustate->psw & C_FLAG) ? _T("C" ) : _T("-" ), (cpustate->psw & A_FLAG) ? _T("AC") : _T("--"),
994 (cpustate->psw & F_FLAG) ? _T("F0") : _T("--"), (cpustate->psw & B_FLAG) ? _T("BS") : _T("--"));
997 // license:BSD-3-Clause
998 // copyright-holders:Aaron Giles
999 /***************************************************************************
1003 Simple MCS-48/UPI-41 disassembler.
1004 Written by Aaron Giles
1006 ***************************************************************************/
1008 int MCS48::debug_dasm(uint32 pc, _TCHAR *buffer, size_t buffer_len)
1010 mcs48_state *cpustate = (mcs48_state *)opaque;
1015 switch (program_r(ptr++))
1017 case 0x00: _stprintf_s(buffer, buffer_len, _T("nop")); break;
1018 case 0x02: if (!upi41)
1019 _stprintf_s(buffer, buffer_len, _T("out bus,a"));
1021 _stprintf_s(buffer, buffer_len, _T("out dbb,a")); break;
1022 case 0x03: _stprintf_s(buffer, buffer_len, _T("add a,#$%02X"), program_r(ptr++)); break;
1023 case 0x04: _stprintf_s(buffer, buffer_len, _T("jmp $0%02X"), program_r(ptr++)); break;
1024 case 0x05: _stprintf_s(buffer, buffer_len, _T("en i")); break;
1025 case 0x07: _stprintf_s(buffer, buffer_len, _T("dec a")); break;
1026 case 0x08: if (!upi41)
1027 _stprintf_s(buffer, buffer_len, _T("in a,bus"));
1029 _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1030 case 0x09: _stprintf_s(buffer, buffer_len, _T("in a,p1")); break;
1031 case 0x0a: _stprintf_s(buffer, buffer_len, _T("in a,p2")); break;
1032 case 0x0c: _stprintf_s(buffer, buffer_len, _T("movd a,p4")); break;
1033 case 0x0d: _stprintf_s(buffer, buffer_len, _T("movd a,p5")); break;
1034 case 0x0e: _stprintf_s(buffer, buffer_len, _T("movd a,p6")); break;
1035 case 0x0f: _stprintf_s(buffer, buffer_len, _T("movd a,p7")); break;
1036 case 0x10: _stprintf_s(buffer, buffer_len, _T("inc @r0")); break;
1037 case 0x11: _stprintf_s(buffer, buffer_len, _T("inc @r1")); break;
1038 case 0x12: _stprintf_s(buffer, buffer_len, _T("jb0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1039 case 0x13: _stprintf_s(buffer, buffer_len, _T("addc a,#$%02X"), program_r(ptr++)); break;
1040 case 0x14: _stprintf_s(buffer, buffer_len, _T("call $0%02X"), program_r(ptr++)); break;
1041 case 0x15: _stprintf_s(buffer, buffer_len, _T("dis i")); break;
1042 case 0x16: _stprintf_s(buffer, buffer_len, _T("jtf $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1043 case 0x17: _stprintf_s(buffer, buffer_len, _T("inc a")); break;
1044 case 0x18: _stprintf_s(buffer, buffer_len, _T("inc r0")); break;
1045 case 0x19: _stprintf_s(buffer, buffer_len, _T("inc r1")); break;
1046 case 0x1a: _stprintf_s(buffer, buffer_len, _T("inc r2")); break;
1047 case 0x1b: _stprintf_s(buffer, buffer_len, _T("inc r3")); break;
1048 case 0x1c: _stprintf_s(buffer, buffer_len, _T("inc r4")); break;
1049 case 0x1d: _stprintf_s(buffer, buffer_len, _T("inc r5")); break;
1050 case 0x1e: _stprintf_s(buffer, buffer_len, _T("inc r6")); break;
1051 case 0x1f: _stprintf_s(buffer, buffer_len, _T("inc r7")); break;
1052 case 0x20: _stprintf_s(buffer, buffer_len, _T("xch a,@r0")); break;
1053 case 0x21: _stprintf_s(buffer, buffer_len, _T("xch a,@r1")); break;
1054 case 0x22: if (!upi41)
1055 _stprintf_s(buffer, buffer_len, _T("illegal"));
1057 _stprintf_s(buffer, buffer_len, _T("in a,dbb")); break;
1058 case 0x23: _stprintf_s(buffer, buffer_len, _T("mov a,#$%02X"), program_r(ptr++)); break;
1059 case 0x24: _stprintf_s(buffer, buffer_len, _T("jmp $1%02X"), program_r(ptr++)); break;
1060 case 0x25: _stprintf_s(buffer, buffer_len, _T("en tcnti")); break;
1061 case 0x26: _stprintf_s(buffer, buffer_len, _T("jnt0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1062 case 0x27: _stprintf_s(buffer, buffer_len, _T("clr a")); break;
1063 case 0x28: _stprintf_s(buffer, buffer_len, _T("xch a,r0")); break;
1064 case 0x29: _stprintf_s(buffer, buffer_len, _T("xch a,r1")); break;
1065 case 0x2a: _stprintf_s(buffer, buffer_len, _T("xch a,r2")); break;
1066 case 0x2b: _stprintf_s(buffer, buffer_len, _T("xch a,r3")); break;
1067 case 0x2c: _stprintf_s(buffer, buffer_len, _T("xch a,r4")); break;
1068 case 0x2d: _stprintf_s(buffer, buffer_len, _T("xch a,r5")); break;
1069 case 0x2e: _stprintf_s(buffer, buffer_len, _T("xch a,r6")); break;
1070 case 0x2f: _stprintf_s(buffer, buffer_len, _T("xch a,r7")); break;
1071 case 0x30: _stprintf_s(buffer, buffer_len, _T("xchd a,@r0")); break;
1072 case 0x31: _stprintf_s(buffer, buffer_len, _T("xchd a,@r1")); break;
1073 case 0x32: _stprintf_s(buffer, buffer_len, _T("jb1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1074 case 0x34: _stprintf_s(buffer, buffer_len, _T("call $1%02X"), program_r(ptr++)); break;
1075 case 0x35: _stprintf_s(buffer, buffer_len, _T("dis tcnti")); break;
1076 case 0x36: _stprintf_s(buffer, buffer_len, _T("jt0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1077 case 0x37: _stprintf_s(buffer, buffer_len, _T("cpl a")); break;
1078 case 0x39: _stprintf_s(buffer, buffer_len, _T("outl p1,a")); break;
1079 case 0x3a: _stprintf_s(buffer, buffer_len, _T("outl p2,a")); break;
1080 case 0x3c: _stprintf_s(buffer, buffer_len, _T("movd p4,a")); break;
1081 case 0x3d: _stprintf_s(buffer, buffer_len, _T("movd p5,a")); break;
1082 case 0x3e: _stprintf_s(buffer, buffer_len, _T("movd p6,a")); break;
1083 case 0x3f: _stprintf_s(buffer, buffer_len, _T("movd p7,a")); break;
1084 case 0x40: _stprintf_s(buffer, buffer_len, _T("orl a,@r0")); break;
1085 case 0x41: _stprintf_s(buffer, buffer_len, _T("orl a,@r1")); break;
1086 case 0x42: _stprintf_s(buffer, buffer_len, _T("mov a,t")); break;
1087 case 0x43: _stprintf_s(buffer, buffer_len, _T("orl a,#$%02X"), program_r(ptr++)); break;
1088 case 0x44: _stprintf_s(buffer, buffer_len, _T("jmp $2%02X"), program_r(ptr++)); break;
1089 case 0x45: _stprintf_s(buffer, buffer_len, _T("strt cnt")); break;
1090 case 0x46: _stprintf_s(buffer, buffer_len, _T("jnt1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1091 case 0x47: _stprintf_s(buffer, buffer_len, _T("swap a")); break;
1092 case 0x48: _stprintf_s(buffer, buffer_len, _T("orl a,r0")); break;
1093 case 0x49: _stprintf_s(buffer, buffer_len, _T("orl a,r1")); break;
1094 case 0x4a: _stprintf_s(buffer, buffer_len, _T("orl a,r2")); break;
1095 case 0x4b: _stprintf_s(buffer, buffer_len, _T("orl a,r3")); break;
1096 case 0x4c: _stprintf_s(buffer, buffer_len, _T("orl a,r4")); break;
1097 case 0x4d: _stprintf_s(buffer, buffer_len, _T("orl a,r5")); break;
1098 case 0x4e: _stprintf_s(buffer, buffer_len, _T("orl a,r6")); break;
1099 case 0x4f: _stprintf_s(buffer, buffer_len, _T("orl a,r7")); break;
1100 case 0x50: _stprintf_s(buffer, buffer_len, _T("anl a,@r0")); break;
1101 case 0x51: _stprintf_s(buffer, buffer_len, _T("anl a,@r1")); break;
1102 case 0x52: _stprintf_s(buffer, buffer_len, _T("jb2 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1103 case 0x53: _stprintf_s(buffer, buffer_len, _T("anl a,#$%02X"), program_r(ptr++)); break;
1104 case 0x54: _stprintf_s(buffer, buffer_len, _T("call $2%02X"), program_r(ptr++)); break;
1105 case 0x55: _stprintf_s(buffer, buffer_len, _T("strt t")); break;
1106 case 0x56: _stprintf_s(buffer, buffer_len, _T("jt1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1107 case 0x57: _stprintf_s(buffer, buffer_len, _T("da a")); break;
1108 case 0x58: _stprintf_s(buffer, buffer_len, _T("anl a,r0")); break;
1109 case 0x59: _stprintf_s(buffer, buffer_len, _T("anl a,r1")); break;
1110 case 0x5a: _stprintf_s(buffer, buffer_len, _T("anl a,r2")); break;
1111 case 0x5b: _stprintf_s(buffer, buffer_len, _T("anl a,r3")); break;
1112 case 0x5c: _stprintf_s(buffer, buffer_len, _T("anl a,r4")); break;
1113 case 0x5d: _stprintf_s(buffer, buffer_len, _T("anl a,r5")); break;
1114 case 0x5e: _stprintf_s(buffer, buffer_len, _T("anl a,r6")); break;
1115 case 0x5f: _stprintf_s(buffer, buffer_len, _T("anl a,r7")); break;
1116 case 0x60: _stprintf_s(buffer, buffer_len, _T("add a,@r0")); break;
1117 case 0x61: _stprintf_s(buffer, buffer_len, _T("add a,@r1")); break;
1118 case 0x62: _stprintf_s(buffer, buffer_len, _T("mov t,a")); break;
1119 case 0x64: _stprintf_s(buffer, buffer_len, _T("jmp $3%02X"), program_r(ptr++)); break;
1120 case 0x65: _stprintf_s(buffer, buffer_len, _T("stop tcnt")); break;
1121 case 0x67: _stprintf_s(buffer, buffer_len, _T("rrc a")); break;
1122 case 0x68: _stprintf_s(buffer, buffer_len, _T("add a,r0")); break;
1123 case 0x69: _stprintf_s(buffer, buffer_len, _T("add a,r1")); break;
1124 case 0x6a: _stprintf_s(buffer, buffer_len, _T("add a,r2")); break;
1125 case 0x6b: _stprintf_s(buffer, buffer_len, _T("add a,r3")); break;
1126 case 0x6c: _stprintf_s(buffer, buffer_len, _T("add a,r4")); break;
1127 case 0x6d: _stprintf_s(buffer, buffer_len, _T("add a,r5")); break;
1128 case 0x6e: _stprintf_s(buffer, buffer_len, _T("add a,r6")); break;
1129 case 0x6f: _stprintf_s(buffer, buffer_len, _T("add a,r7")); break;
1130 case 0x70: _stprintf_s(buffer, buffer_len, _T("addc a,@r0")); break;
1131 case 0x71: _stprintf_s(buffer, buffer_len, _T("addc a,@r1")); break;
1132 case 0x72: _stprintf_s(buffer, buffer_len, _T("jb3 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1133 case 0x74: _stprintf_s(buffer, buffer_len, _T("call $3%02X"), program_r(ptr++)); break;
1134 case 0x75: if (!upi41)
1135 _stprintf_s(buffer, buffer_len, _T("ent0 clk"));
1137 _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1138 case 0x76: _stprintf_s(buffer, buffer_len, _T("jf1 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1139 case 0x77: _stprintf_s(buffer, buffer_len, _T("rr a")); break;
1140 case 0x78: _stprintf_s(buffer, buffer_len, _T("addc a,r0")); break;
1141 case 0x79: _stprintf_s(buffer, buffer_len, _T("addc a,r1")); break;
1142 case 0x7a: _stprintf_s(buffer, buffer_len, _T("addc a,r2")); break;
1143 case 0x7b: _stprintf_s(buffer, buffer_len, _T("addc a,r3")); break;
1144 case 0x7c: _stprintf_s(buffer, buffer_len, _T("addc a,r4")); break;
1145 case 0x7d: _stprintf_s(buffer, buffer_len, _T("addc a,r5")); break;
1146 case 0x7e: _stprintf_s(buffer, buffer_len, _T("addc a,r6")); break;
1147 case 0x7f: _stprintf_s(buffer, buffer_len, _T("addc a,r7")); break;
1148 case 0x80: if (!upi41)
1149 _stprintf_s(buffer, buffer_len, _T("movx a,@r0"));
1151 _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1152 case 0x81: if (!upi41)
1153 _stprintf_s(buffer, buffer_len, _T("movx a,@r1"));
1155 _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1156 case 0x83: _stprintf_s(buffer, buffer_len, _T("ret")); break;
1157 case 0x84: _stprintf_s(buffer, buffer_len, _T("jmp $4%02X"), program_r(ptr++)); break;
1158 case 0x85: _stprintf_s(buffer, buffer_len, _T("clr f0")); break;
1159 case 0x86: if (!upi41)
1160 _stprintf_s(buffer, buffer_len, _T("jni $%03X"), (pc & 0xf00) | program_r(ptr++));
1162 _stprintf_s(buffer, buffer_len, _T("jobf $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1163 case 0x88: if (!upi41)
1164 _stprintf_s(buffer, buffer_len, _T("orl bus,#$%02X"), program_r(ptr++));
1166 _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1167 case 0x89: _stprintf_s(buffer, buffer_len, _T("orl p1,#$%02X"), program_r(ptr++)); break;
1168 case 0x8a: _stprintf_s(buffer, buffer_len, _T("orl p2,#$%02X"), program_r(ptr++)); break;
1169 case 0x8c: _stprintf_s(buffer, buffer_len, _T("orld p4,a")); break;
1170 case 0x8d: _stprintf_s(buffer, buffer_len, _T("orld p5,a")); break;
1171 case 0x8e: _stprintf_s(buffer, buffer_len, _T("orld p6,a")); break;
1172 case 0x8f: _stprintf_s(buffer, buffer_len, _T("orld p7,a")); break;
1173 case 0x90: if (!upi41)
1174 _stprintf_s(buffer, buffer_len, _T("movx @r0,a"));
1176 _stprintf_s(buffer, buffer_len, _T("mov sts,a")); break;
1177 case 0x91: if (!upi41)
1178 _stprintf_s(buffer, buffer_len, _T("movx @r1,a"));
1180 _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1181 case 0x92: _stprintf_s(buffer, buffer_len, _T("jb4 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1182 case 0x93: _stprintf_s(buffer, buffer_len, _T("retr")); break;
1183 case 0x94: _stprintf_s(buffer, buffer_len, _T("call $4%02X"), program_r(ptr++)); break;
1184 case 0x95: _stprintf_s(buffer, buffer_len, _T("cpl f0")); break;
1185 case 0x96: _stprintf_s(buffer, buffer_len, _T("jnz $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1186 case 0x97: _stprintf_s(buffer, buffer_len, _T("clr c")); break;
1187 case 0x98: if (!upi41)
1188 _stprintf_s(buffer, buffer_len, _T("anl bus,#$%02X"), program_r(ptr++));
1190 _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1191 case 0x99: _stprintf_s(buffer, buffer_len, _T("anl p1,#$%02X"), program_r(ptr++)); break;
1192 case 0x9a: _stprintf_s(buffer, buffer_len, _T("anl p2,#$%02X"), program_r(ptr++)); break;
1193 case 0x9c: _stprintf_s(buffer, buffer_len, _T("anld p4,a")); break;
1194 case 0x9d: _stprintf_s(buffer, buffer_len, _T("anld p5,a")); break;
1195 case 0x9e: _stprintf_s(buffer, buffer_len, _T("anld p6,a")); break;
1196 case 0x9f: _stprintf_s(buffer, buffer_len, _T("anld p7,a")); break;
1197 case 0xa0: _stprintf_s(buffer, buffer_len, _T("mov @r0,a")); break;
1198 case 0xa1: _stprintf_s(buffer, buffer_len, _T("mov @r1,a")); break;
1199 case 0xa3: _stprintf_s(buffer, buffer_len, _T("movp a,@a")); break;
1200 case 0xa4: _stprintf_s(buffer, buffer_len, _T("jmp $5%02X"), program_r(ptr++)); break;
1201 case 0xa5: _stprintf_s(buffer, buffer_len, _T("clr f1")); break;
1202 case 0xa7: _stprintf_s(buffer, buffer_len, _T("cpl c")); break;
1203 case 0xa8: _stprintf_s(buffer, buffer_len, _T("mov r0,a")); break;
1204 case 0xa9: _stprintf_s(buffer, buffer_len, _T("mov r1,a")); break;
1205 case 0xaa: _stprintf_s(buffer, buffer_len, _T("mov r2,a")); break;
1206 case 0xab: _stprintf_s(buffer, buffer_len, _T("mov r3,a")); break;
1207 case 0xac: _stprintf_s(buffer, buffer_len, _T("mov r4,a")); break;
1208 case 0xad: _stprintf_s(buffer, buffer_len, _T("mov r5,a")); break;
1209 case 0xae: _stprintf_s(buffer, buffer_len, _T("mov r6,a")); break;
1210 case 0xaf: _stprintf_s(buffer, buffer_len, _T("mov r7,a")); break;
1211 case 0xb0: _stprintf_s(buffer, buffer_len, _T("mov @r0,#$%02X"), program_r(ptr++)); break;
1212 case 0xb1: _stprintf_s(buffer, buffer_len, _T("mov @r1,#$%02X"), program_r(ptr++)); break;
1213 case 0xb2: _stprintf_s(buffer, buffer_len, _T("jb5 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1214 case 0xb3: _stprintf_s(buffer, buffer_len, _T("jmpp @a")); break;
1215 case 0xb4: _stprintf_s(buffer, buffer_len, _T("call $5%02X"), program_r(ptr++)); break;
1216 case 0xb5: _stprintf_s(buffer, buffer_len, _T("cpl f1")); break;
1217 case 0xb6: _stprintf_s(buffer, buffer_len, _T("jf0 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1218 case 0xb8: _stprintf_s(buffer, buffer_len, _T("mov r0,#$%02X"), program_r(ptr++)); break;
1219 case 0xb9: _stprintf_s(buffer, buffer_len, _T("mov r1,#$%02X"), program_r(ptr++)); break;
1220 case 0xba: _stprintf_s(buffer, buffer_len, _T("mov r2,#$%02X"), program_r(ptr++)); break;
1221 case 0xbb: _stprintf_s(buffer, buffer_len, _T("mov r3,#$%02X"), program_r(ptr++)); break;
1222 case 0xbc: _stprintf_s(buffer, buffer_len, _T("mov r4,#$%02X"), program_r(ptr++)); break;
1223 case 0xbd: _stprintf_s(buffer, buffer_len, _T("mov r5,#$%02X"), program_r(ptr++)); break;
1224 case 0xbe: _stprintf_s(buffer, buffer_len, _T("mov r6,#$%02X"), program_r(ptr++)); break;
1225 case 0xbf: _stprintf_s(buffer, buffer_len, _T("mov r7,#$%02X"), program_r(ptr++)); break;
1226 case 0xc4: _stprintf_s(buffer, buffer_len, _T("jmp $6%02X"), program_r(ptr++)); break;
1227 case 0xc5: _stprintf_s(buffer, buffer_len, _T("sel rb0")); break;
1228 case 0xc6: _stprintf_s(buffer, buffer_len, _T("jz $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1229 case 0xc7: _stprintf_s(buffer, buffer_len, _T("mov a,psw")); break;
1230 case 0xc8: _stprintf_s(buffer, buffer_len, _T("dec r0")); break;
1231 case 0xc9: _stprintf_s(buffer, buffer_len, _T("dec r1")); break;
1232 case 0xca: _stprintf_s(buffer, buffer_len, _T("dec r2")); break;
1233 case 0xcb: _stprintf_s(buffer, buffer_len, _T("dec r3")); break;
1234 case 0xcc: _stprintf_s(buffer, buffer_len, _T("dec r4")); break;
1235 case 0xcd: _stprintf_s(buffer, buffer_len, _T("dec r5")); break;
1236 case 0xce: _stprintf_s(buffer, buffer_len, _T("dec r6")); break;
1237 case 0xcf: _stprintf_s(buffer, buffer_len, _T("dec r7")); break;
1238 case 0xd0: _stprintf_s(buffer, buffer_len, _T("xrl a,@r0")); break;
1239 case 0xd1: _stprintf_s(buffer, buffer_len, _T("xrl a,@r1")); break;
1240 case 0xd2: _stprintf_s(buffer, buffer_len, _T("jb6 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1241 case 0xd3: _stprintf_s(buffer, buffer_len, _T("xrl a,#$%02X"), program_r(ptr++)); break;
1242 case 0xd4: _stprintf_s(buffer, buffer_len, _T("call $6%02X"), program_r(ptr++)); break;
1243 case 0xd5: _stprintf_s(buffer, buffer_len, _T("sel rb1")); break;
1244 case 0xd6: if (!upi41)
1245 _stprintf_s(buffer, buffer_len, _T("illegal"));
1247 _stprintf_s(buffer, buffer_len, _T("jnibf $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1248 case 0xd7: _stprintf_s(buffer, buffer_len, _T("mov psw,a")); break;
1249 case 0xd8: _stprintf_s(buffer, buffer_len, _T("xrl a,r0")); break;
1250 case 0xd9: _stprintf_s(buffer, buffer_len, _T("xrl a,r1")); break;
1251 case 0xda: _stprintf_s(buffer, buffer_len, _T("xrl a,r2")); break;
1252 case 0xdb: _stprintf_s(buffer, buffer_len, _T("xrl a,r3")); break;
1253 case 0xdc: _stprintf_s(buffer, buffer_len, _T("xrl a,r4")); break;
1254 case 0xdd: _stprintf_s(buffer, buffer_len, _T("xrl a,r5")); break;
1255 case 0xde: _stprintf_s(buffer, buffer_len, _T("xrl a,r6")); break;
1256 case 0xdf: _stprintf_s(buffer, buffer_len, _T("xrl a,r7")); break;
1257 case 0xe3: _stprintf_s(buffer, buffer_len, _T("movp3 a,@a")); break;
1258 case 0xe4: _stprintf_s(buffer, buffer_len, _T("jmp $7%02X"), program_r(ptr++)); break;
1259 case 0xe5: if (!upi41)
1260 _stprintf_s(buffer, buffer_len, _T("sel mb0"));
1262 _stprintf_s(buffer, buffer_len, _T("en dma")); break;
1263 case 0xe6: _stprintf_s(buffer, buffer_len, _T("jnc $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1264 case 0xe7: _stprintf_s(buffer, buffer_len, _T("rl a")); break;
1265 case 0xe8: _stprintf_s(buffer, buffer_len, _T("djnz r0,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1266 case 0xe9: _stprintf_s(buffer, buffer_len, _T("djnz r1,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1267 case 0xea: _stprintf_s(buffer, buffer_len, _T("djnz r2,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1268 case 0xeb: _stprintf_s(buffer, buffer_len, _T("djnz r3,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1269 case 0xec: _stprintf_s(buffer, buffer_len, _T("djnz r4,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1270 case 0xed: _stprintf_s(buffer, buffer_len, _T("djnz r5,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1271 case 0xee: _stprintf_s(buffer, buffer_len, _T("djnz r6,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1272 case 0xef: _stprintf_s(buffer, buffer_len, _T("djnz r7,$%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1273 case 0xf0: _stprintf_s(buffer, buffer_len, _T("mov a,@r0")); break;
1274 case 0xf1: _stprintf_s(buffer, buffer_len, _T("mov a,@r1")); break;
1275 case 0xf2: _stprintf_s(buffer, buffer_len, _T("jb7 $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1276 case 0xf4: _stprintf_s(buffer, buffer_len, _T("call $7%02X"), program_r(ptr++)); break;
1277 case 0xf5: if (!upi41)
1278 _stprintf_s(buffer, buffer_len, _T("sel mb1"));
1280 _stprintf_s(buffer, buffer_len, _T("en flags")); break;
1281 case 0xf6: _stprintf_s(buffer, buffer_len, _T("jc $%03X"), (pc & 0xf00) | program_r(ptr++)); break;
1282 case 0xf7: _stprintf_s(buffer, buffer_len, _T("rlc a")); break;
1283 case 0xf8: _stprintf_s(buffer, buffer_len, _T("mov a,r0")); break;
1284 case 0xf9: _stprintf_s(buffer, buffer_len, _T("mov a,r1")); break;
1285 case 0xfa: _stprintf_s(buffer, buffer_len, _T("mov a,r2")); break;
1286 case 0xfb: _stprintf_s(buffer, buffer_len, _T("mov a,r3")); break;
1287 case 0xfc: _stprintf_s(buffer, buffer_len, _T("mov a,r4")); break;
1288 case 0xfd: _stprintf_s(buffer, buffer_len, _T("mov a,r5")); break;
1289 case 0xfe: _stprintf_s(buffer, buffer_len, _T("mov a,r6")); break;
1290 case 0xff: _stprintf_s(buffer, buffer_len, _T("mov a,r7")); break;
1291 default: _stprintf_s(buffer, buffer_len, _T("illegal")); break;
1297 #define STATE_VERSION 1
1299 void MCS48MEM::save_state(FILEIO* state_fio)
1301 state_fio->FputUint32(STATE_VERSION);
1302 state_fio->FputInt32(this_device_id);
1304 state_fio->Fwrite(ram, sizeof(ram), 1);
1307 bool MCS48MEM::load_state(FILEIO* state_fio)
1309 if(state_fio->FgetUint32() != STATE_VERSION) {
1312 if(state_fio->FgetInt32() != this_device_id) {
1315 state_fio->Fread(ram, sizeof(ram), 1);
1319 void MCS48::save_state(FILEIO* state_fio)
1321 state_fio->FputUint32(STATE_VERSION);
1322 state_fio->FputInt32(this_device_id);
1324 state_fio->Fwrite(opaque, sizeof(mcs48_state), 1);
1327 bool MCS48::load_state(FILEIO* state_fio)
1329 if(state_fio->FgetUint32() != STATE_VERSION) {
1332 if(state_fio->FgetInt32() != this_device_id) {
1335 state_fio->Fread(opaque, sizeof(mcs48_state), 1);
1338 mcs48_state *cpustate = (mcs48_state *)opaque;
1339 cpustate->mem = d_mem;
1340 cpustate->io = d_io;
1341 cpustate->intr = d_intr;