OSDN Git Service

[VM][FM7] keyboard.cpp : Add implementation ofd RTC, includes within keyboard.
[csp-qt/common_source_project-fm7.git] / source / src / vm / mcs48.cpp
1 /*
2         Skelton for retropc emulator
3
4         Origin : MAME 0.148
5         Author : Takeda.Toshiya
6         Date   : 2013.05.01-
7
8         [ MCS48 ]
9 */
10
11 #include "mcs48.h"
12 #ifdef USE_DEBUGGER
13 #include "debugger.h"
14 #endif
15 #include "../fileio.h"
16
17 /***************************************************************************
18
19     mcs48.c
20
21     Intel MCS-48/UPI-41 Portable Emulator
22
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
26
27 ****************************************************************************
28
29     Note that the default internal divisor for this chip is by 3 and
30     then again by 5, or by 15 total.
31
32 ***************************************************************************/
33
34 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
35 #pragma warning( disable : 4244 )
36 #endif
37
38 #define INLINE inline
39
40 /***************************************************************************
41     CONSTANTS
42 ***************************************************************************/
43
44 /* timer/counter enable bits */
45 #define TIMER_ENABLED   0x01
46 #define COUNTER_ENABLED 0x02
47
48 /* flag bits */
49 #define C_FLAG          0x80
50 #define A_FLAG          0x40
51 #define F_FLAG          0x20
52 #define B_FLAG          0x10
53
54 /* status bits (UPI-41) */
55 #define STS_F1          0x08
56 #define STS_F0          0x04
57
58 /* 8243 expander operations */
59 enum
60 {
61         MCS48_EXPANDER_OP_READ = 0,
62         MCS48_EXPANDER_OP_WRITE = 1,
63         MCS48_EXPANDER_OP_OR = 2,
64         MCS48_EXPANDER_OP_AND = 3
65 };
66
67 /***************************************************************************
68     TYPE DEFINITIONS
69 ***************************************************************************/
70
71 /* live processor state */
72 struct mcs48_state
73 {
74         UINT16      prevpc;             /* 16-bit previous program counter */
75         UINT16      pc;                 /* 16-bit program counter */
76
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 */
86
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 */
96
97         UINT16      a11;                /* A11 value, either 0x000 or 0x800 */
98
99         DEVICE *    mem;
100         DEVICE *    io;
101         DEVICE *    intr;
102
103         int         icount;
104
105         UINT8       rom[0x1000];
106 //      UINT8       ram[0x100];
107 };
108
109 /* opcode table entry */
110 typedef int (*mcs48_ophandler)(mcs48_state *state);
111
112 /***************************************************************************
113     MACROS
114 ***************************************************************************/
115
116 #define program_r(a)    cpustate->rom[(a) & 0xfff]
117
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)
122
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)
132
133 /***************************************************************************
134     FUNCTION PROTOTYPES
135 ***************************************************************************/
136
137 static int check_irqs(mcs48_state *cpustate);
138
139 /***************************************************************************
140     INLINE FUNCTIONS
141 ***************************************************************************/
142
143 /*-------------------------------------------------
144     opcode_fetch - fetch an opcode byte
145 -------------------------------------------------*/
146
147 INLINE UINT8 opcode_fetch(mcs48_state *cpustate)
148 {
149         return cpustate->rom[cpustate->pc++ & 0xfff];
150 }
151
152 /*-------------------------------------------------
153     argument_fetch - fetch an opcode argument
154     byte
155 -------------------------------------------------*/
156
157 INLINE UINT8 argument_fetch(mcs48_state *cpustate)
158 {
159         return cpustate->rom[cpustate->pc++ & 0xfff];
160 }
161
162 /*-------------------------------------------------
163     update_regptr - update the regptr member to
164     point to the appropriate register bank
165 -------------------------------------------------*/
166
167 INLINE void update_regptr(mcs48_state *cpustate)
168 {
169         cpustate->regptr = ((cpustate->psw & B_FLAG) ? 24 : 0);
170 }
171
172 /*-------------------------------------------------
173     push_pc_psw - push the cpustate->pc and cpustate->psw values onto
174     the stack
175 -------------------------------------------------*/
176
177 INLINE void push_pc_psw(mcs48_state *cpustate)
178 {
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);
183 }
184
185 /*-------------------------------------------------
186     pull_pc_psw - pull the PC and PSW values from
187     the stack
188 -------------------------------------------------*/
189
190 INLINE void pull_pc_psw(mcs48_state *cpustate)
191 {
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);
198 }
199
200 /*-------------------------------------------------
201     pull_pc - pull the PC value from the stack,
202     leaving the upper part of PSW intact
203 -------------------------------------------------*/
204
205 INLINE void pull_pc(mcs48_state *cpustate)
206 {
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;
212 }
213
214 /*-------------------------------------------------
215     execute_add - perform the logic of an ADD
216     instruction
217 -------------------------------------------------*/
218
219 INLINE void execute_add(mcs48_state *cpustate, UINT8 dat)
220 {
221         UINT16 temp = cpustate->a + dat;
222         UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f);
223
224         cpustate->psw &= ~(C_FLAG | A_FLAG);
225         cpustate->psw |= (temp4 << 2) & A_FLAG;
226         cpustate->psw |= (temp >> 1) & C_FLAG;
227         cpustate->a = temp;
228 }
229
230 /*-------------------------------------------------
231     execute_addc - perform the logic of an ADDC
232     instruction
233 -------------------------------------------------*/
234
235 INLINE void execute_addc(mcs48_state *cpustate, UINT8 dat)
236 {
237         UINT8 carryin = (cpustate->psw & C_FLAG) >> 7;
238         UINT16 temp = cpustate->a + dat + carryin;
239         UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f) + carryin;
240
241         cpustate->psw &= ~(C_FLAG | A_FLAG);
242         cpustate->psw |= (temp4 << 2) & A_FLAG;
243         cpustate->psw |= (temp >> 1) & C_FLAG;
244         cpustate->a = temp;
245 }
246
247 /*-------------------------------------------------
248     execute_jmp - perform the logic of a JMP
249     instruction
250 -------------------------------------------------*/
251
252 INLINE void execute_jmp(mcs48_state *cpustate, UINT16 address)
253 {
254         UINT16 a11 = (cpustate->irq_in_progress) ? 0 : cpustate->a11;
255         cpustate->pc = address | a11;
256 }
257
258 /*-------------------------------------------------
259     execute_call - perform the logic of a CALL
260     instruction
261 -------------------------------------------------*/
262
263 INLINE void execute_call(mcs48_state *cpustate, UINT16 address)
264 {
265         push_pc_psw(cpustate);
266         execute_jmp(cpustate, address);
267 }
268
269 /*-------------------------------------------------
270     execute_jcc - perform the logic of a
271     conditional jump instruction
272 -------------------------------------------------*/
273
274 INLINE void execute_jcc(mcs48_state *cpustate, UINT8 result)
275 {
276         UINT8 offset = argument_fetch(cpustate);
277         if (result != 0)
278                 cpustate->pc = ((cpustate->pc - 1) & 0xf00) | offset;
279 }
280
281 /*-------------------------------------------------
282     expander_operation - perform an operation via
283     the 8243 expander chip
284 -------------------------------------------------*/
285
286 INLINE void expander_operation(mcs48_state *cpustate, UINT8 operation, UINT8 port)
287 {
288         /* put opcode/data on low 4 bits of P2 */
289         port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (operation << 2) | (port & 3));
290
291         /* generate high-to-low transition on PROG line */
292         prog_w(0);
293
294         /* put data on low 4 bits of P2 */
295         if (operation != 0)
296                 port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (cpustate->a & 0x0f));
297         else
298                 cpustate->a = port_r(2) | 0x0f;
299
300         /* generate low-to-high transition on PROG line */
301         prog_w(1);
302 }
303
304 /***************************************************************************
305     OPCODE HANDLERS
306 ***************************************************************************/
307
308 #define OPHANDLER(_name) static int _name(mcs48_state *cpustate)
309
310 OPHANDLER( illegal )
311 {
312 //      logerror("MCS-48 PC:%04X - Illegal opcode = %02x\n", cpustate->pc - 1, program_r(cpustate->pc - 1));
313         return 1;
314 }
315
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; }
327
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; }
339
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; }
351
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; }
359
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; }
368
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; }
373
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; }
378
379 OPHANDLER( da_a )
380 {
381         if ((cpustate->a & 0x0f) > 0x09 || (cpustate->psw & A_FLAG))
382         {
383                 cpustate->a += 0x06;
384                 if ((cpustate->a & 0xf0) == 0x00)
385                         cpustate->psw |= C_FLAG;
386         }
387         if ((cpustate->a & 0xf0) > 0x90 || (cpustate->psw & C_FLAG))
388         {
389                 cpustate->a += 0x60;
390                 cpustate->psw |= C_FLAG;
391         }
392         else
393                 cpustate->psw &= ~C_FLAG;
394         return 1;
395 }
396
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; }
406
407 OPHANDLER( dis_i )          { cpustate->xirq_enabled = FALSE; return 1; }
408 OPHANDLER( dis_tcnti )      { cpustate->tirq_enabled = FALSE; cpustate->timer_overflow = FALSE; return 1; }
409
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; }
418
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; }
422
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; }
426
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; }
438
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; }
459
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; }
469
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; }
483
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; }
506
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; }
515
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; }
518
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; }
523
524 OPHANDLER( nop )            { return 1; }
525
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; }
537
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; }
545
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; }
549
550 OPHANDLER( ret )            { pull_pc(cpustate); return 2; }
551 OPHANDLER( retr )
552 {
553         pull_pc_psw(cpustate);
554
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);
558 }
559
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; }
562
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; }
565
566 OPHANDLER( sel_mb0 )        { cpustate->a11 = 0x000; return 1; }
567 OPHANDLER( sel_mb1 )        { cpustate->a11 = 0x800; return 1; }
568
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; }
571
572 OPHANDLER( stop_tcnt )      { cpustate->timecount_enabled = 0; return 1; }
573
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; }
576
577 OPHANDLER( swap_a )         { cpustate->a = (cpustate->a << 4) | (cpustate->a >> 4); return 1; }
578
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; }
589
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; }
592
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; }
604
605 /***************************************************************************
606     OPCODE TABLES
607 ***************************************************************************/
608
609 static const mcs48_ophandler opcode_table[256]=
610 {
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
643 };
644
645 /***************************************************************************
646     INITIALIZATION/RESET
647 ***************************************************************************/
648
649 void MCS48::initialize()
650 {
651         opaque = calloc(1, sizeof(mcs48_state));
652         
653         mcs48_state *cpustate = (mcs48_state *)opaque;
654         
655         cpustate->mem = d_mem;
656         cpustate->io = d_io;
657         cpustate->intr = d_intr;
658 #ifdef USE_DEBUGGER
659         d_mem_stored = d_mem;
660         d_io_stored = d_io;
661         d_debugger->set_context_mem(d_mem);
662         d_debugger->set_context_io(d_io);
663 #endif
664 }
665
666 void MCS48::release()
667 {
668         free(opaque);
669 }
670
671 void MCS48::reset()
672 {
673         mcs48_state *cpustate = (mcs48_state *)opaque;
674         
675         /* confirmed from reset description */
676         cpustate->pc = 0;
677         cpustate->psw = (cpustate->psw & (C_FLAG | A_FLAG)) | 0x08;
678         cpustate->a11 = 0x000;
679 //      bus_w(0xff);
680         cpustate->p1 = 0xff;
681         cpustate->p2 = 0xff;
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;
689         cpustate->sts = 0;
690         
691         cpustate->icount = 0;
692         
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;
697 }
698
699 void MCS48::load_rom_image(_TCHAR *file_path)
700 {
701         mcs48_state *cpustate = (mcs48_state *)opaque;
702         
703         memset(cpustate->rom, 0, sizeof(cpustate->rom));
704         
705         FILEIO* fio = new FILEIO();
706         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
707                 fio->Fread(cpustate->rom, sizeof(cpustate->rom), 1);
708                 fio->Fclose();
709         }
710         delete fio;
711 }
712
713 uint8 *MCS48::get_rom_ptr()
714 {
715         mcs48_state *cpustate = (mcs48_state *)opaque;
716         return cpustate->rom;
717 }
718
719 /***************************************************************************
720     EXECUTION
721 ***************************************************************************/
722
723 /*-------------------------------------------------
724     check_irqs - check for and process IRQs
725 -------------------------------------------------*/
726
727 static int check_irqs(mcs48_state *cpustate)
728 {
729         /* if something is in progress, we do nothing */
730         if (cpustate->irq_in_progress)
731                 return 0;
732
733         /* external interrupts take priority */
734         if (cpustate->irq_state && cpustate->xirq_enabled)
735         {
736                 cpustate->irq_state = FALSE;
737                 cpustate->irq_in_progress = TRUE;
738
739                 /* transfer to location 0x03 */
740                 push_pc_psw(cpustate);
741                 cpustate->pc = 0x03;
742
743                 /* indicate we took the external IRQ */
744                 if (cpustate->intr != NULL)
745                         cpustate->intr->intr_ack();
746                 return 2;
747         }
748
749         /* timer overflow interrupts follow */
750         if (cpustate->timer_overflow && cpustate->tirq_enabled)
751         {
752                 cpustate->irq_in_progress = TRUE;
753
754                 /* transfer to location 0x07 */
755                 push_pc_psw(cpustate);
756                 cpustate->pc = 0x07;
757
758                 /* timer overflow flip-flop is reset once taken */
759                 cpustate->timer_overflow = FALSE;
760                 return 2;
761         }
762         return 0;
763 }
764
765 /*-------------------------------------------------
766     burn_cycles - burn cycles, processing timers
767     and counters
768 -------------------------------------------------*/
769
770 static void burn_cycles(mcs48_state *cpustate, int count)
771 {
772         int timerover = FALSE;
773
774         /* output (clock*15/3) hz to t0 */
775         if (cpustate->t0_clk_enabled)
776         {
777                 for(int i = 0; i < count * 5; i++)
778                 {
779                         test_w(0, 1);
780                         test_w(0, 0);
781                 }
782         }
783
784         /* if the timer is enabled, accumulate prescaler cycles */
785         if (cpustate->timecount_enabled & TIMER_ENABLED)
786         {
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);
792         }
793
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--)
797                 {
798                         cpustate->t1_history = (cpustate->t1_history << 1) | (test_r(1) & 1);
799                         if ((cpustate->t1_history & 3) == 2)
800                                 timerover = (++cpustate->timer == 0);
801                 }
802
803         /* if either source caused a timer overflow, set the flags and check IRQs */
804         if (timerover)
805         {
806                 cpustate->timer_flag = TRUE;
807
808                 /* according to the docs, if an overflow occurs with interrupts disabled, the overflow is not stored */
809                 if (cpustate->tirq_enabled)
810                 {
811                         cpustate->timer_overflow = TRUE;
812                         check_irqs(cpustate);
813                 }
814         }
815 }
816
817 int MCS48::run(int icount)
818 {
819         mcs48_state *cpustate = (mcs48_state *)opaque;
820         int curcycles;
821         
822         if (icount == -1) {
823                 cpustate->icount = 1;
824         } else {
825                 cpustate->icount += icount;
826                 if (cpustate->icount < 0) {
827                         return 0;
828                 }
829         }
830         
831         int base_icount = cpustate->icount;
832         
833         update_regptr(cpustate);
834         
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);
840
841         /* iterate over remaining cycles, guaranteeing at least one instruction */
842         do
843         {
844 #ifdef USE_DEBUGGER
845                 bool now_debugging = d_debugger->now_debugging;
846                 if(now_debugging) {
847                         d_debugger->check_break_points(cpustate->pc);
848                         if(d_debugger->now_suspended) {
849                                 emu->mute_sound();
850                                 while(d_debugger->now_debugging && d_debugger->now_suspended) {
851                                         Sleep(10);
852                                 }
853                         }
854                         if(d_debugger->now_debugging) {
855                                 d_mem = d_io = d_debugger;
856                         } else {
857                                 now_debugging = false;
858                         }
859                         
860                         /* fetch next opcode */
861                         cpustate->prevpc = cpustate->pc;
862                         unsigned opcode = opcode_fetch(cpustate);
863
864                         /* process opcode and count cycles */
865                         curcycles = (*opcode_table[opcode])(cpustate);
866
867                         /* burn the cycles */
868                         cpustate->icount -= curcycles * 15;
869                         if (cpustate->timecount_enabled != 0)
870                                 burn_cycles(cpustate, curcycles);
871                         
872                         if(now_debugging) {
873                                 if(!d_debugger->now_going) {
874                                         d_debugger->now_suspended = true;
875                                 }
876                                 d_mem = d_mem_stored;
877                                 d_io = d_io_stored;
878                         }
879                 } else {
880 #endif
881                         /* fetch next opcode */
882                         cpustate->prevpc = cpustate->pc;
883                         unsigned opcode = opcode_fetch(cpustate);
884
885                         /* process opcode and count cycles */
886                         curcycles = (*opcode_table[opcode])(cpustate);
887
888                         /* burn the cycles */
889                         cpustate->icount -= curcycles * 15;
890                         if (cpustate->timecount_enabled != 0)
891                                 burn_cycles(cpustate, curcycles);
892 #ifdef USE_DEBUGGER
893                 }
894 #endif
895         } while (cpustate->icount > 0);
896         
897         return base_icount - cpustate->icount;
898 }
899
900 uint32 MCS48::get_pc()
901 {
902         mcs48_state *cpustate = (mcs48_state *)opaque;
903         return cpustate->prevpc;
904 }
905
906 uint32 MCS48::get_next_pc()
907 {
908         mcs48_state *cpustate = (mcs48_state *)opaque;
909         return cpustate->pc;
910 }
911
912 /***************************************************************************
913     GENERAL CONTEXT ACCESS
914 ***************************************************************************/
915
916 void MCS48::write_signal(int id, uint32 data, uint32 mask)
917 {
918         mcs48_state *cpustate = (mcs48_state *)opaque;
919         
920         if(id == SIG_CPU_IRQ) {
921                 UINT8 prev = cpustate->int_state;
922                 cpustate->int_state = ((data & mask) != 0);
923                 // INT H->L
924                 if(prev && !cpustate->int_state) {
925                         cpustate->irq_state = TRUE;
926                 }
927         }
928 }
929
930 #ifdef USE_DEBUGGER
931 void MCS48::debug_write_data8(uint32 addr, uint32 data)
932 {
933         d_mem_stored->write_data8(addr, data);
934 }
935
936 uint32 MCS48::debug_read_data8(uint32 addr)
937 {
938         return d_mem_stored->read_data8(addr);
939 }
940
941 void MCS48::debug_write_io8(uint32 addr, uint32 data)
942 {
943         d_io_stored->write_io8(addr, data);
944 }
945
946 uint32 MCS48::debug_read_io8(uint32 addr)
947 {
948         return d_io_stored->read_io8(addr);
949 }
950
951 bool MCS48::debug_write_reg(_TCHAR *reg, uint32 data)
952 {
953         mcs48_state *cpustate = (mcs48_state *)opaque;
954         
955         if(_tcsicmp(reg, _T("R0")) == 0) {
956                 reg_w(0, data);
957         } else if(_tcsicmp(reg, _T("R1")) == 0) {
958                 reg_w(1, data);
959         } else if(_tcsicmp(reg, _T("R2")) == 0) {
960                 reg_w(2, data);
961         } else if(_tcsicmp(reg, _T("R3")) == 0) {
962                 reg_w(3, data);
963         } else if(_tcsicmp(reg, _T("R4")) == 0) {
964                 reg_w(4, data);
965         } else if(_tcsicmp(reg, _T("R5")) == 0) {
966                 reg_w(5, data);
967         } else if(_tcsicmp(reg, _T("R6")) == 0) {
968                 reg_w(6, data);
969         } else if(_tcsicmp(reg, _T("R7")) == 0) {
970                 reg_w(7, data);
971         } else {
972                 return false;
973         }
974         return true;
975 }
976
977 void MCS48::debug_regs_info(_TCHAR *buffer, size_t buffer_len)
978 {
979 /*
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]
982 */
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);
986         
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("--"));
995 }
996
997 // license:BSD-3-Clause
998 // copyright-holders:Aaron Giles
999 /***************************************************************************
1000
1001     mcs48dsm.c
1002
1003     Simple MCS-48/UPI-41 disassembler.
1004     Written by Aaron Giles
1005
1006 ***************************************************************************/
1007
1008 int MCS48::debug_dasm(uint32 pc, _TCHAR *buffer, size_t buffer_len)
1009 {
1010         mcs48_state *cpustate = (mcs48_state *)opaque;
1011         uint32 ptr = pc;
1012         
1013         #define upi41 false
1014         
1015         switch (program_r(ptr++))
1016         {
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"));
1020                             else
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"));
1028                             else
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"));
1056                             else
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"));
1136                             else
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"));
1150                             else
1151                                 _stprintf_s(buffer, buffer_len, _T("illegal"));                                             break;
1152                 case 0x81:  if (!upi41)
1153                                 _stprintf_s(buffer, buffer_len, _T("movx a,@r1"));
1154                             else
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++));
1161                             else
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++));
1165                             else
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"));
1175                             else
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"));
1179                             else
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++));
1189                             else
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"));
1246                             else
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"));
1261                             else
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"));
1279                             else
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;
1292         }
1293         return ptr - pc;
1294 }
1295 #endif
1296
1297 #define STATE_VERSION   1
1298
1299 void MCS48MEM::save_state(FILEIO* state_fio)
1300 {
1301         state_fio->FputUint32(STATE_VERSION);
1302         state_fio->FputInt32(this_device_id);
1303         
1304         state_fio->Fwrite(ram, sizeof(ram), 1);
1305 }
1306
1307 bool MCS48MEM::load_state(FILEIO* state_fio)
1308 {
1309         if(state_fio->FgetUint32() != STATE_VERSION) {
1310                 return false;
1311         }
1312         if(state_fio->FgetInt32() != this_device_id) {
1313                 return false;
1314         }
1315         state_fio->Fread(ram, sizeof(ram), 1);
1316         return true;
1317 }
1318
1319 void MCS48::save_state(FILEIO* state_fio)
1320 {
1321         state_fio->FputUint32(STATE_VERSION);
1322         state_fio->FputInt32(this_device_id);
1323         
1324         state_fio->Fwrite(opaque, sizeof(mcs48_state), 1);
1325 }
1326
1327 bool MCS48::load_state(FILEIO* state_fio)
1328 {
1329         if(state_fio->FgetUint32() != STATE_VERSION) {
1330                 return false;
1331         }
1332         if(state_fio->FgetInt32() != this_device_id) {
1333                 return false;
1334         }
1335         state_fio->Fread(opaque, sizeof(mcs48_state), 1);
1336         
1337         // post process
1338         mcs48_state *cpustate = (mcs48_state *)opaque;
1339         cpustate->mem = d_mem;
1340         cpustate->io = d_io;
1341         cpustate->intr = d_intr;
1342         return true;
1343 }
1344