OSDN Git Service

[VM] .
[csp-qt/common_source_project-fm7.git] / source / src / vm / mcs48.h
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 #ifndef _MCS84_H_ 
12 #define _MCS48_H_
13
14 //#include "vm.h"
15 //#include "../emu.h"
16 #include "device.h"
17
18 #include "mcs48_flags.h"
19 #ifndef INLINE
20 #define INLINE inline
21 #endif
22
23 #define MCS48_PORT_P0   0x100   /* Not used */
24 #define MCS48_PORT_P1   0x101   /* P10-P17 */
25 #define MCS48_PORT_P2   0x102   /* P20-P28 */
26 #define MCS48_PORT_T0   0x110
27 #define MCS48_PORT_T1   0x111
28 #define MCS48_PORT_BUS  0x120   /* DB0-DB7 */
29 #define MCS48_PORT_PROG 0x121   /* PROG line to 8243 expander */
30
31 //#ifdef USE_DEBUGGER
32 class DEBUGGER;
33 //#endif
34
35 /***************************************************************************
36     CONSTANTS
37 ***************************************************************************/
38
39 /* timer/counter enable bits */
40 #define __MCS48_TIMER_ENABLED   0x01
41 #define __MCS48_COUNTER_ENABLED 0x02
42
43 /***************************************************************************
44     TYPE DEFINITIONS
45 ***************************************************************************/
46
47 /* live processor state */
48 struct mcs48_state
49 {
50         UINT16      prevpc;             /* 16-bit previous program counter */
51         UINT16      pc;                 /* 16-bit program counter */
52
53         UINT8       a;                  /* 8-bit accumulator */
54         int         regptr;             /* offset of r0-r7 */
55         UINT8       psw;                /* 8-bit cpustate->psw */
56         UINT8       p1;                 /* 8-bit latched port 1 */
57         UINT8       p2;                 /* 8-bit latched port 2 */
58         UINT8       timer;              /* 8-bit timer */
59         UINT8       prescaler;          /* 5-bit timer prescaler */
60         UINT8       t1_history;         /* 8-bit history of the T1 input */
61         UINT8       sts;                /* 8-bit status register */
62
63         UINT8       int_state;          /* INT signal status */
64         UINT8       irq_state;          /* TRUE if an IRQ is pending */
65         UINT8       irq_in_progress;    /* TRUE if an IRQ is in progress */
66         UINT8       timer_overflow;     /* TRUE on a timer overflow; cleared by taking interrupt */
67         UINT8       timer_flag;         /* TRUE on a timer overflow; cleared on JTF */
68         UINT8       tirq_enabled;       /* TRUE if the timer IRQ is enabled */
69         UINT8       xirq_enabled;       /* TRUE if the external IRQ is enabled */
70         UINT8       t0_clk_enabled;     /* TRUE if ent0_clk is called */
71         UINT8       timecount_enabled;  /* bitmask of timer/counter enabled */
72
73         UINT16      a11;                /* A11 value, either 0x000 or 0x800 */
74
75         DEVICE *    mem;
76         DEVICE *    io;
77         DEVICE *    intr;
78
79         int         icount;
80
81         UINT8       rom[0x1000];
82 //      UINT8       ram[0x100];
83 };
84 /***************************************************************************
85     MACROS
86 ***************************************************************************/
87
88 #define __mcs48_program_r(a)    cpustate->rom[(a) & 0xfff]
89
90 #define __mcs48_ram_r(a)        cpustate->mem->read_data8(a)
91 #define __mcs48_ram_w(a,V)      cpustate->mem->write_data8(a, V)
92 #define __mcs48_reg_r(a)        cpustate->mem->read_data8(cpustate->regptr + a)
93 #define __mcs48_reg_w(a,V)      cpustate->mem->write_data8(cpustate->regptr + a, V)
94
95 #define __mcs48_ext_r(a)        cpustate->io->read_io8(a)
96 #define __mcs48_ext_w(a,V)      cpustate->io->write_io8(a, V)
97 #define __mcs48_port_r(a)       cpustate->io->read_io8(MCS48_PORT_P0 + a)
98 #define __mcs48_port_w(a,V)     cpustate->io->write_io8(MCS48_PORT_P0 + a, V)
99 #define __mcs48_test_r(a)       cpustate->io->read_io8(MCS48_PORT_T0 + a)
100 #define __mcs48_test_w(a,V)     cpustate->io->write_io8(MCS48_PORT_T0 + a, V)
101 #define __mcs48_bus_r()         cpustate->io->read_io8(MCS48_PORT_BUS)
102 #define __mcs48_bus_w(V)        cpustate->io->write_io8(MCS48_PORT_BUS, V)
103 #define __mcs48_prog_w(V)       cpustate->io->write_io8(MCS48_PORT_PROG, V)
104
105
106
107 #define __MCS48_OPHANDLER(_name) int MCS48_BASE::_name(mcs48_state *cpustate)
108 #define __MCS48_OPHANDLER_D(_name) int _name(mcs48_state *cpustate)
109
110 class MCS48MEM : public DEVICE
111 {
112 private:
113         uint8_t ram[0x100];
114 public:
115         MCS48MEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
116         {
117                 memset(ram, 0, sizeof(ram));
118                 set_device_name(_T("MCS48 MEMORY BUS"));
119         }
120         ~MCS48MEM() {}
121         
122         uint32_t read_data8(uint32_t addr)
123         {
124                 return ram[addr & 0xff];
125         }
126         void write_data8(uint32_t addr, uint32_t data)
127         {
128                 ram[addr & 0xff] = data;
129         }
130         bool process_state(FILEIO* state_fio, bool loading);
131 };
132
133 class MCS48_BASE : public DEVICE
134 {
135 protected:
136         inline UINT8 argument_fetch(mcs48_state *cpustate);
137         inline void pull_pc(mcs48_state *cpustate);
138         inline void execute_add(mcs48_state *cpustate, UINT8 dat);
139         inline void execute_addc(mcs48_state *cpustate, UINT8 dat);
140         inline void execute_jmp(mcs48_state *cpustate, UINT16 address);
141         inline void execute_call(mcs48_state *cpustate, UINT16 address);
142         inline void execute_jcc(mcs48_state *cpustate, UINT8 result);
143         inline void expander_operation(mcs48_state *cpustate, UINT8 operation, UINT8 port);
144
145         uint64_t total_icount;
146         uint64_t prev_total_icount;
147
148 private:
149         __MCS48_OPHANDLER_D( illegal );
150         __MCS48_OPHANDLER_D( add_a_r0 );
151         __MCS48_OPHANDLER_D( add_a_r1 );
152         __MCS48_OPHANDLER_D( add_a_r2 );
153         __MCS48_OPHANDLER_D( add_a_r3 );
154         __MCS48_OPHANDLER_D( add_a_r4 );
155         __MCS48_OPHANDLER_D( add_a_r5 );
156         __MCS48_OPHANDLER_D( add_a_r6 );
157         __MCS48_OPHANDLER_D( add_a_r7 );
158         __MCS48_OPHANDLER_D( add_a_xr0 );
159         __MCS48_OPHANDLER_D( add_a_xr1 );
160         __MCS48_OPHANDLER_D( add_a_n );
161
162         __MCS48_OPHANDLER_D( adc_a_r0 );
163         __MCS48_OPHANDLER_D( adc_a_r1 );
164         __MCS48_OPHANDLER_D( adc_a_r2 );
165         __MCS48_OPHANDLER_D( adc_a_r3 );
166         __MCS48_OPHANDLER_D( adc_a_r4 );
167         __MCS48_OPHANDLER_D( adc_a_r5 );
168         __MCS48_OPHANDLER_D( adc_a_r6 );
169         __MCS48_OPHANDLER_D( adc_a_r7 );
170         __MCS48_OPHANDLER_D( adc_a_xr0 );
171         __MCS48_OPHANDLER_D( adc_a_xr1 );
172         __MCS48_OPHANDLER_D( adc_a_n );  
173
174         __MCS48_OPHANDLER_D( anl_a_r0 );
175         __MCS48_OPHANDLER_D( anl_a_r1 );
176         __MCS48_OPHANDLER_D( anl_a_r2 );
177         __MCS48_OPHANDLER_D( anl_a_r3 );
178         __MCS48_OPHANDLER_D( anl_a_r4 );
179         __MCS48_OPHANDLER_D( anl_a_r5 );
180         __MCS48_OPHANDLER_D( anl_a_r6 );
181         __MCS48_OPHANDLER_D( anl_a_r7 );
182         __MCS48_OPHANDLER_D( anl_a_xr0 );
183         __MCS48_OPHANDLER_D( anl_a_xr1 );
184         __MCS48_OPHANDLER_D( anl_a_n );
185         
186         __MCS48_OPHANDLER_D( anl_bus_n );
187         __MCS48_OPHANDLER_D( anl_p1_n );
188         __MCS48_OPHANDLER_D( anl_p2_n );
189         __MCS48_OPHANDLER_D( anld_p4_a );
190         __MCS48_OPHANDLER_D( anld_p5_a );
191         __MCS48_OPHANDLER_D( anld_p6_a );
192         __MCS48_OPHANDLER_D( anld_p7_a );
193
194         __MCS48_OPHANDLER_D( call_0 );
195         __MCS48_OPHANDLER_D( call_1 );
196         __MCS48_OPHANDLER_D( call_2 );
197         __MCS48_OPHANDLER_D( call_3 );
198         __MCS48_OPHANDLER_D( call_4 );
199         __MCS48_OPHANDLER_D( call_5 );
200         __MCS48_OPHANDLER_D( call_6 );
201         __MCS48_OPHANDLER_D( call_7 );
202
203         __MCS48_OPHANDLER_D( clr_a );
204         __MCS48_OPHANDLER_D( clr_c );
205         __MCS48_OPHANDLER_D( clr_f0 );
206         __MCS48_OPHANDLER_D( clr_f1 );
207
208         __MCS48_OPHANDLER_D( cpl_a );
209         __MCS48_OPHANDLER_D( cpl_c );
210         __MCS48_OPHANDLER_D( cpl_f0 );
211         __MCS48_OPHANDLER_D( cpl_f1 );
212
213         __MCS48_OPHANDLER_D( da_a );
214
215         __MCS48_OPHANDLER_D( dec_a );
216         __MCS48_OPHANDLER_D( dec_r0 );
217         __MCS48_OPHANDLER_D( dec_r1 );
218         __MCS48_OPHANDLER_D( dec_r2 );
219         __MCS48_OPHANDLER_D( dec_r3 );
220         __MCS48_OPHANDLER_D( dec_r4 );
221         __MCS48_OPHANDLER_D( dec_r5 );
222         __MCS48_OPHANDLER_D( dec_r6 );
223         __MCS48_OPHANDLER_D( dec_r7 );
224
225         __MCS48_OPHANDLER_D( dis_i );
226         __MCS48_OPHANDLER_D( dis_tcnti );
227
228         __MCS48_OPHANDLER_D( djnz_r0 );
229         __MCS48_OPHANDLER_D( djnz_r1 );
230         __MCS48_OPHANDLER_D( djnz_r2 );
231         __MCS48_OPHANDLER_D( djnz_r3 );
232         __MCS48_OPHANDLER_D( djnz_r4 );
233         __MCS48_OPHANDLER_D( djnz_r5 );
234         __MCS48_OPHANDLER_D( djnz_r6 );
235         __MCS48_OPHANDLER_D( djnz_r7 );
236
237         __MCS48_OPHANDLER_D( en_i );
238         __MCS48_OPHANDLER_D( en_tcnti );
239         __MCS48_OPHANDLER_D( ent0_clk );
240
241         __MCS48_OPHANDLER_D( in_a_p1 );
242         __MCS48_OPHANDLER_D( in_a_p2 );
243         __MCS48_OPHANDLER_D( ins_a_bus );
244
245         __MCS48_OPHANDLER_D( inc_a );
246         __MCS48_OPHANDLER_D( inc_r0 );
247         __MCS48_OPHANDLER_D( inc_r1 );
248         __MCS48_OPHANDLER_D( inc_r2 );
249         __MCS48_OPHANDLER_D( inc_r3 );
250         __MCS48_OPHANDLER_D( inc_r4 );
251         __MCS48_OPHANDLER_D( inc_r5 );
252         __MCS48_OPHANDLER_D( inc_r6 );
253         __MCS48_OPHANDLER_D( inc_r7 );
254         __MCS48_OPHANDLER_D( inc_xr0 );
255         __MCS48_OPHANDLER_D( inc_xr1 );
256
257         __MCS48_OPHANDLER_D( jb_0 );
258         __MCS48_OPHANDLER_D( jb_1 );
259         __MCS48_OPHANDLER_D( jb_2 );
260         __MCS48_OPHANDLER_D( jb_3 );
261         __MCS48_OPHANDLER_D( jb_4 );
262         __MCS48_OPHANDLER_D( jb_5 );
263         __MCS48_OPHANDLER_D( jb_6 );
264         __MCS48_OPHANDLER_D( jb_7 );
265         __MCS48_OPHANDLER_D( jc );
266         __MCS48_OPHANDLER_D( jf0 );
267         __MCS48_OPHANDLER_D( jf1 );
268         __MCS48_OPHANDLER_D( jnc );
269         __MCS48_OPHANDLER_D( jni );
270         __MCS48_OPHANDLER_D( jnt_0 );
271         __MCS48_OPHANDLER_D( jnt_1 );
272         __MCS48_OPHANDLER_D( jnz );
273         __MCS48_OPHANDLER_D( jtf );
274         __MCS48_OPHANDLER_D( jt_0 );
275         __MCS48_OPHANDLER_D( jt_1 );
276         __MCS48_OPHANDLER_D( jz );
277
278         __MCS48_OPHANDLER_D( jmp_0 );
279         __MCS48_OPHANDLER_D( jmp_1 );
280         __MCS48_OPHANDLER_D( jmp_2 );
281         __MCS48_OPHANDLER_D( jmp_3 );
282         __MCS48_OPHANDLER_D( jmp_4 );
283         __MCS48_OPHANDLER_D( jmp_5 );
284         __MCS48_OPHANDLER_D( jmp_6 );
285         __MCS48_OPHANDLER_D( jmp_7 );
286         __MCS48_OPHANDLER_D( jmpp_xa );
287
288         __MCS48_OPHANDLER_D( mov_a_n );
289         __MCS48_OPHANDLER_D( mov_a_psw );
290         __MCS48_OPHANDLER_D( mov_a_r0 );
291         __MCS48_OPHANDLER_D( mov_a_r1 );
292         __MCS48_OPHANDLER_D( mov_a_r2 );
293         __MCS48_OPHANDLER_D( mov_a_r3 );
294         __MCS48_OPHANDLER_D( mov_a_r4 );
295         __MCS48_OPHANDLER_D( mov_a_r5 );
296         __MCS48_OPHANDLER_D( mov_a_r6 );
297         __MCS48_OPHANDLER_D( mov_a_r7 );
298         __MCS48_OPHANDLER_D( mov_a_xr0 );
299         __MCS48_OPHANDLER_D( mov_a_xr1 );
300         __MCS48_OPHANDLER_D( mov_a_t );
301
302         __MCS48_OPHANDLER_D( mov_psw_a );
303         __MCS48_OPHANDLER_D( mov_r0_a );
304         __MCS48_OPHANDLER_D( mov_r1_a );
305         __MCS48_OPHANDLER_D( mov_r2_a );
306         __MCS48_OPHANDLER_D( mov_r3_a );
307         __MCS48_OPHANDLER_D( mov_r4_a );
308         __MCS48_OPHANDLER_D( mov_r5_a );
309         __MCS48_OPHANDLER_D( mov_r6_a );
310         __MCS48_OPHANDLER_D( mov_r7_a );
311         __MCS48_OPHANDLER_D( mov_r0_n );
312         __MCS48_OPHANDLER_D( mov_r1_n );
313         __MCS48_OPHANDLER_D( mov_r2_n );
314         __MCS48_OPHANDLER_D( mov_r3_n );
315         __MCS48_OPHANDLER_D( mov_r4_n );
316         __MCS48_OPHANDLER_D( mov_r5_n );
317         __MCS48_OPHANDLER_D( mov_r6_n );
318         __MCS48_OPHANDLER_D( mov_r7_n );
319         __MCS48_OPHANDLER_D( mov_t_a );
320         __MCS48_OPHANDLER_D( mov_xr0_a );
321         __MCS48_OPHANDLER_D( mov_xr1_a );
322         __MCS48_OPHANDLER_D( mov_xr0_n );
323         __MCS48_OPHANDLER_D( mov_xr1_n );
324
325         __MCS48_OPHANDLER_D( movd_a_p4 );
326         __MCS48_OPHANDLER_D( movd_a_p5 );
327         __MCS48_OPHANDLER_D( movd_a_p6 );
328         __MCS48_OPHANDLER_D( movd_a_p7 );
329         __MCS48_OPHANDLER_D( movd_p4_a );
330         __MCS48_OPHANDLER_D( movd_p5_a );
331         __MCS48_OPHANDLER_D( movd_p6_a );
332         __MCS48_OPHANDLER_D( movd_p7_a );
333
334         __MCS48_OPHANDLER_D( movp_a_xa );
335         __MCS48_OPHANDLER_D( movp3_a_xa );
336
337         __MCS48_OPHANDLER_D( movx_a_xr0 );
338         __MCS48_OPHANDLER_D( movx_a_xr1 );
339         __MCS48_OPHANDLER_D( movx_xr0_a );
340         __MCS48_OPHANDLER_D( movx_xr1_a );
341
342         __MCS48_OPHANDLER_D( nop );
343
344         __MCS48_OPHANDLER_D( orl_a_r0 );
345         __MCS48_OPHANDLER_D( orl_a_r1 );
346         __MCS48_OPHANDLER_D( orl_a_r2 );
347         __MCS48_OPHANDLER_D( orl_a_r3 );
348         __MCS48_OPHANDLER_D( orl_a_r4 );
349         __MCS48_OPHANDLER_D( orl_a_r5 );
350         __MCS48_OPHANDLER_D( orl_a_r6 );
351         __MCS48_OPHANDLER_D( orl_a_r7 );
352         __MCS48_OPHANDLER_D( orl_a_xr0 );
353         __MCS48_OPHANDLER_D( orl_a_xr1 );
354         __MCS48_OPHANDLER_D( orl_a_n );
355
356         __MCS48_OPHANDLER_D( orl_bus_n );
357         __MCS48_OPHANDLER_D( orl_p1_n );
358         __MCS48_OPHANDLER_D( orl_p2_n );
359         __MCS48_OPHANDLER_D( orld_p4_a );
360         __MCS48_OPHANDLER_D( orld_p5_a );
361         __MCS48_OPHANDLER_D( orld_p6_a );
362         __MCS48_OPHANDLER_D( orld_p7_a );
363
364         __MCS48_OPHANDLER_D( outl_bus_a );
365         __MCS48_OPHANDLER_D( outl_p1_a );
366         __MCS48_OPHANDLER_D( outl_p2_a );
367
368         __MCS48_OPHANDLER_D( ret );
369         __MCS48_OPHANDLER_D( retr );
370
371         __MCS48_OPHANDLER_D( rl_a );
372         __MCS48_OPHANDLER_D( rlc_a );
373
374         __MCS48_OPHANDLER_D( rr_a );
375         __MCS48_OPHANDLER_D( rrc_a );
376
377         __MCS48_OPHANDLER_D( sel_mb0 );
378         __MCS48_OPHANDLER_D( sel_mb1 );
379
380         __MCS48_OPHANDLER_D( sel_rb0 );
381         __MCS48_OPHANDLER_D( sel_rb1 );
382
383         __MCS48_OPHANDLER_D( stop_tcnt );
384
385         __MCS48_OPHANDLER_D( strt_cnt );
386         __MCS48_OPHANDLER_D( strt_t );
387
388         __MCS48_OPHANDLER_D( swap_a );
389
390         __MCS48_OPHANDLER_D( xch_a_r0 );
391         __MCS48_OPHANDLER_D( xch_a_r1 );
392         __MCS48_OPHANDLER_D( xch_a_r2 );
393         __MCS48_OPHANDLER_D( xch_a_r3 );
394         __MCS48_OPHANDLER_D( xch_a_r4 );
395         __MCS48_OPHANDLER_D( xch_a_r5 );
396         __MCS48_OPHANDLER_D( xch_a_r6 );
397         __MCS48_OPHANDLER_D( xch_a_r7 );
398         __MCS48_OPHANDLER_D( xch_a_xr0 );
399         __MCS48_OPHANDLER_D( xch_a_xr1 );
400
401         __MCS48_OPHANDLER_D( xchd_a_xr0 );
402         __MCS48_OPHANDLER_D( xchd_a_xr1 );
403
404         __MCS48_OPHANDLER_D( xrl_a_r0 );
405         __MCS48_OPHANDLER_D( xrl_a_r1 );
406         __MCS48_OPHANDLER_D( xrl_a_r2 );
407         __MCS48_OPHANDLER_D( xrl_a_r3 );
408         __MCS48_OPHANDLER_D( xrl_a_r4 );
409         __MCS48_OPHANDLER_D( xrl_a_r5 );
410         __MCS48_OPHANDLER_D( xrl_a_r6 );
411         __MCS48_OPHANDLER_D( xrl_a_r7 );
412         __MCS48_OPHANDLER_D( xrl_a_xr0 );
413         __MCS48_OPHANDLER_D( xrl_a_xr1 );
414         __MCS48_OPHANDLER_D( xrl_a_n );
415
416 protected:
417         /* ---------------------------------------------------------------------------
418         contexts
419         --------------------------------------------------------------------------- */
420         
421         DEVICE *d_mem, *d_io, *d_intr;
422 //#ifdef USE_DEBUGGER
423         DEBUGGER *d_debugger;
424         DEVICE *d_mem_stored, *d_io_stored;
425 //#endif
426         void *opaque;
427         /* opcode table entry */
428         typedef int (MCS48_BASE::*mcs48_ophandler)(mcs48_state *state);
429
430         const mcs48_ophandler opcode_table[256] =
431         {
432                 &MCS48_BASE::nop,        &MCS48_BASE::illegal,     &MCS48_BASE::outl_bus_a, &MCS48_BASE::add_a_n,   &MCS48_BASE::jmp_0,     &MCS48_BASE::en_i,      &MCS48_BASE::illegal,   &MCS48_BASE::dec_a,         /* 00 */
433                 &MCS48_BASE::ins_a_bus,  &MCS48_BASE::in_a_p1,     &MCS48_BASE::in_a_p2,    &MCS48_BASE::illegal,   &MCS48_BASE::movd_a_p4, &MCS48_BASE::movd_a_p5, &MCS48_BASE::movd_a_p6, &MCS48_BASE::movd_a_p7,
434                 &MCS48_BASE::inc_xr0,    &MCS48_BASE::inc_xr1,     &MCS48_BASE::jb_0,       &MCS48_BASE::adc_a_n,   &MCS48_BASE::call_0,    &MCS48_BASE::dis_i,     &MCS48_BASE::jtf,       &MCS48_BASE::inc_a,         /* 10 */
435                 &MCS48_BASE::inc_r0,     &MCS48_BASE::inc_r1,      &MCS48_BASE::inc_r2,     &MCS48_BASE::inc_r3,    &MCS48_BASE::inc_r4,    &MCS48_BASE::inc_r5,    &MCS48_BASE::inc_r6,    &MCS48_BASE::inc_r7,
436                 &MCS48_BASE::xch_a_xr0,  &MCS48_BASE::xch_a_xr1,   &MCS48_BASE::illegal,    &MCS48_BASE::mov_a_n,   &MCS48_BASE::jmp_1,     &MCS48_BASE::en_tcnti,  &MCS48_BASE::jnt_0,     &MCS48_BASE::clr_a,         /* 20 */
437                 &MCS48_BASE::xch_a_r0,   &MCS48_BASE::xch_a_r1,    &MCS48_BASE::xch_a_r2,   &MCS48_BASE::xch_a_r3,  &MCS48_BASE::xch_a_r4,  &MCS48_BASE::xch_a_r5,  &MCS48_BASE::xch_a_r6,  &MCS48_BASE::xch_a_r7,
438                 &MCS48_BASE::xchd_a_xr0, &MCS48_BASE::xchd_a_xr1, &MCS48_BASE::jb_1,       &MCS48_BASE::illegal,   &MCS48_BASE::call_1,    &MCS48_BASE::dis_tcnti, &MCS48_BASE::jt_0,     &MCS48_BASE::cpl_a,         /* 30 */
439                 &MCS48_BASE::illegal,    &MCS48_BASE::outl_p1_a,   &MCS48_BASE::outl_p2_a,  &MCS48_BASE::illegal,   &MCS48_BASE::movd_p4_a, &MCS48_BASE::movd_p5_a, &MCS48_BASE::movd_p6_a, &MCS48_BASE::movd_p7_a,
440                 &MCS48_BASE::orl_a_xr0,  &MCS48_BASE::orl_a_xr1,   &MCS48_BASE::mov_a_t,    &MCS48_BASE::orl_a_n,   &MCS48_BASE::jmp_2,     &MCS48_BASE::strt_cnt,  &MCS48_BASE::jnt_1,     &MCS48_BASE::swap_a,        /* 40 */
441                 &MCS48_BASE::orl_a_r0,   &MCS48_BASE::orl_a_r1,    &MCS48_BASE::orl_a_r2,   &MCS48_BASE::orl_a_r3,  &MCS48_BASE::orl_a_r4,  &MCS48_BASE::orl_a_r5,  &MCS48_BASE::orl_a_r6,  &MCS48_BASE::orl_a_r7,
442                 &MCS48_BASE::anl_a_xr0,  &MCS48_BASE::anl_a_xr1,   &MCS48_BASE::jb_2,       &MCS48_BASE::anl_a_n,   &MCS48_BASE::call_2,    &MCS48_BASE::strt_t,    &MCS48_BASE::jt_1,      &MCS48_BASE::da_a,          /* 50 */
443                 &MCS48_BASE::anl_a_r0,   &MCS48_BASE::anl_a_r1,    &MCS48_BASE::anl_a_r2,   &MCS48_BASE::anl_a_r3,  &MCS48_BASE::anl_a_r4,  &MCS48_BASE::anl_a_r5,  &MCS48_BASE::anl_a_r6,  &MCS48_BASE::anl_a_r7,
444                 &MCS48_BASE::add_a_xr0,  &MCS48_BASE::add_a_xr1,   &MCS48_BASE::mov_t_a,    &MCS48_BASE::illegal,   &MCS48_BASE::jmp_3,     &MCS48_BASE::stop_tcnt, &MCS48_BASE::illegal,   &MCS48_BASE::rrc_a,         /* 60 */
445                 &MCS48_BASE::add_a_r0,   &MCS48_BASE::add_a_r1,    &MCS48_BASE::add_a_r2,   &MCS48_BASE::add_a_r3,  &MCS48_BASE::add_a_r4,  &MCS48_BASE::add_a_r5,  &MCS48_BASE::add_a_r6,  &MCS48_BASE::add_a_r7,
446                 &MCS48_BASE::adc_a_xr0,  &MCS48_BASE::adc_a_xr1,   &MCS48_BASE::jb_3,       &MCS48_BASE::illegal,   &MCS48_BASE::call_3,    &MCS48_BASE::ent0_clk,  &MCS48_BASE::jf1,       &MCS48_BASE::rr_a,          /* 70 */
447                 &MCS48_BASE::adc_a_r0,   &MCS48_BASE::adc_a_r1,    &MCS48_BASE::adc_a_r2,   &MCS48_BASE::adc_a_r3,  &MCS48_BASE::adc_a_r4,  &MCS48_BASE::adc_a_r5,  &MCS48_BASE::adc_a_r6,  &MCS48_BASE::adc_a_r7,
448                 &MCS48_BASE::movx_a_xr0, &MCS48_BASE::movx_a_xr1,  &MCS48_BASE::illegal,    &MCS48_BASE::ret,       &MCS48_BASE::jmp_4,     &MCS48_BASE::clr_f0,    &MCS48_BASE::jni,       &MCS48_BASE::illegal,       /* 80 */
449                 &MCS48_BASE::orl_bus_n,  &MCS48_BASE::orl_p1_n,    &MCS48_BASE::orl_p2_n,   &MCS48_BASE::illegal,   &MCS48_BASE::orld_p4_a, &MCS48_BASE::orld_p5_a, &MCS48_BASE::orld_p6_a, &MCS48_BASE::orld_p7_a,
450                 &MCS48_BASE::movx_xr0_a, &MCS48_BASE::movx_xr1_a,  &MCS48_BASE::jb_4,       &MCS48_BASE::retr,      &MCS48_BASE::call_4,    &MCS48_BASE::cpl_f0,    &MCS48_BASE::jnz,       &MCS48_BASE::clr_c,         /* 90 */
451                 &MCS48_BASE::anl_bus_n,  &MCS48_BASE::anl_p1_n,    &MCS48_BASE::anl_p2_n,   &MCS48_BASE::illegal,   &MCS48_BASE::anld_p4_a, &MCS48_BASE::anld_p5_a, &MCS48_BASE::anld_p6_a, &MCS48_BASE::anld_p7_a,
452                 &MCS48_BASE::mov_xr0_a,  &MCS48_BASE::mov_xr1_a,   &MCS48_BASE::illegal,    &MCS48_BASE::movp_a_xa, &MCS48_BASE::jmp_5,     &MCS48_BASE::clr_f1,    &MCS48_BASE::illegal,   &MCS48_BASE::cpl_c,         /* A0 */
453                 &MCS48_BASE::mov_r0_a,   &MCS48_BASE::mov_r1_a,    &MCS48_BASE::mov_r2_a,   &MCS48_BASE::mov_r3_a,  &MCS48_BASE::mov_r4_a,  &MCS48_BASE::mov_r5_a,  &MCS48_BASE::mov_r6_a,  &MCS48_BASE::mov_r7_a,
454                 &MCS48_BASE::mov_xr0_n,  &MCS48_BASE::mov_xr1_n,   &MCS48_BASE::jb_5,       &MCS48_BASE::jmpp_xa,   &MCS48_BASE::call_5,    &MCS48_BASE::cpl_f1,    &MCS48_BASE::jf0,       &MCS48_BASE::illegal,       /* B0 */
455                 &MCS48_BASE::mov_r0_n,   &MCS48_BASE::mov_r1_n,    &MCS48_BASE::mov_r2_n,   &MCS48_BASE::mov_r3_n,  &MCS48_BASE::mov_r4_n,  &MCS48_BASE::mov_r5_n,  &MCS48_BASE::mov_r6_n,  &MCS48_BASE::mov_r7_n,
456                 &MCS48_BASE::illegal,    &MCS48_BASE::illegal,     &MCS48_BASE::illegal,    &MCS48_BASE::illegal,   &MCS48_BASE::jmp_6,     &MCS48_BASE::sel_rb0,   &MCS48_BASE::jz,        &MCS48_BASE::mov_a_psw,     /* C0 */
457                 &MCS48_BASE::dec_r0,     &MCS48_BASE::dec_r1,      &MCS48_BASE::dec_r2,     &MCS48_BASE::dec_r3,    &MCS48_BASE::dec_r4,    &MCS48_BASE::dec_r5,    &MCS48_BASE::dec_r6,    &MCS48_BASE::dec_r7,
458                 &MCS48_BASE::xrl_a_xr0,  &MCS48_BASE::xrl_a_xr1,   &MCS48_BASE::jb_6,       &MCS48_BASE::xrl_a_n,   &MCS48_BASE::call_6,    &MCS48_BASE::sel_rb1,   &MCS48_BASE::illegal,   &MCS48_BASE::mov_psw_a,     /* D0 */
459                 &MCS48_BASE::xrl_a_r0,   &MCS48_BASE::xrl_a_r1,    &MCS48_BASE::xrl_a_r2,   &MCS48_BASE::xrl_a_r3,  &MCS48_BASE::xrl_a_r4,  &MCS48_BASE::xrl_a_r5,  &MCS48_BASE::xrl_a_r6,  &MCS48_BASE::xrl_a_r7,
460                 &MCS48_BASE::illegal,    &MCS48_BASE::illegal,     &MCS48_BASE::illegal,    &MCS48_BASE::movp3_a_xa,&MCS48_BASE::jmp_7,     &MCS48_BASE::sel_mb0,   &MCS48_BASE::jnc,       &MCS48_BASE::rl_a,          /* E0 */
461                 &MCS48_BASE::djnz_r0,    &MCS48_BASE::djnz_r1,     &MCS48_BASE::djnz_r2,    &MCS48_BASE::djnz_r3,   &MCS48_BASE::djnz_r4,   &MCS48_BASE::djnz_r5,   &MCS48_BASE::djnz_r6,   &MCS48_BASE::djnz_r7,
462                 &MCS48_BASE::mov_a_xr0,  &MCS48_BASE::mov_a_xr1,   &MCS48_BASE::jb_7,       &MCS48_BASE::illegal,   &MCS48_BASE::call_7,    &MCS48_BASE::sel_mb1,   &MCS48_BASE::jc,        &MCS48_BASE::rlc_a,         /* F0 */
463                 &MCS48_BASE::mov_a_r0,   &MCS48_BASE::mov_a_r1,    &MCS48_BASE::mov_a_r2,   &MCS48_BASE::mov_a_r3,  &MCS48_BASE::mov_a_r4,  &MCS48_BASE::mov_a_r5,  &MCS48_BASE::mov_a_r6,  &MCS48_BASE::mov_a_r7
464         };
465         
466         inline void update_regptr(mcs48_state *cpustate);
467         inline void push_pc_psw(mcs48_state *cpustate);
468         inline void pull_pc_psw(mcs48_state *cpustate);
469         inline int check_irqs(mcs48_state *cpustate);
470         inline UINT8 opcode_fetch(mcs48_state *cpustate);
471         int op_call(mcs48_state *);
472 public:
473         MCS48_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
474         {
475                 d_mem = d_io = d_intr = NULL;
476                 d_debugger = NULL;
477                 d_mem_stored = d_io_stored = NULL;
478                 total_icount = prev_total_icount = 0;
479                 set_device_name(_T("MCS48 MCU"));
480         }
481         ~MCS48_BASE() {}
482         
483         // common functions
484         virtual void initialize();
485         virtual void release();
486         void reset();
487         virtual int run(int icount);
488         void write_signal(int id, uint32_t data, uint32_t mask);
489         uint32_t get_pc();
490         uint32_t get_next_pc();
491 //#ifdef USE_DEBUGGER
492         void write_debug_data8(uint32_t addr, uint32_t data);
493         uint32_t read_debug_data8(uint32_t addr);
494         void write_debug_io8(uint32_t addr, uint32_t data);
495         uint32_t read_debug_io8(uint32_t addr);
496         bool write_debug_reg(const _TCHAR *reg, uint32_t data);
497         void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
498         int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
499 //#endif
500         
501         // unique functions
502         void set_context_mem(DEVICE* device)
503         {
504                 d_mem = device;
505         }
506         void set_context_io(DEVICE* device)
507         {
508                 d_io = device;
509         }
510         void set_context_intr(DEVICE* device)
511         {
512                 d_intr = device;
513         }
514         void load_rom_image(const _TCHAR *file_path);
515         uint8_t *get_rom_ptr();
516 };
517
518
519 /*-------------------------------------------------
520     update_regptr - update the regptr member to
521     point to the appropriate register bank
522 -------------------------------------------------*/
523
524 inline void MCS48_BASE::update_regptr(mcs48_state *cpustate)
525 {
526         cpustate->regptr = ((cpustate->psw & B_FLAG) ? 24 : 0);
527 }
528
529 /*-------------------------------------------------
530     push_pc_psw - push the cpustate->pc and cpustate->psw values onto
531     the stack
532 -------------------------------------------------*/
533
534 inline void MCS48_BASE::push_pc_psw(mcs48_state *cpustate)
535 {
536         UINT8 sp = cpustate->psw & 0x07;
537         __mcs48_ram_w(8 + 2*sp, cpustate->pc);
538         __mcs48_ram_w(9 + 2*sp, ((cpustate->pc >> 8) & 0x0f) | (cpustate->psw & 0xf0));
539         cpustate->psw = (cpustate->psw & 0xf8) | ((sp + 1) & 0x07);
540 }
541
542 /*-------------------------------------------------
543     pull_pc_psw - pull the PC and PSW values from
544     the stack
545 -------------------------------------------------*/
546
547 inline void MCS48_BASE::pull_pc_psw(mcs48_state *cpustate)
548 {
549         UINT8 sp = (cpustate->psw - 1) & 0x07;
550         cpustate->pc = __mcs48_ram_r(8 + 2*sp);
551         cpustate->pc |= __mcs48_ram_r(9 + 2*sp) << 8;
552         cpustate->psw = ((cpustate->pc >> 8) & 0xf0) | 0x08 | sp;
553         cpustate->pc &= 0xfff;
554         update_regptr(cpustate);
555 }
556
557 /*-------------------------------------------------
558     check_irqs - check for and process IRQs
559 -------------------------------------------------*/
560
561 inline int MCS48_BASE::check_irqs(mcs48_state *cpustate)
562 {
563         /* if something is in progress, we do nothing */
564         if (cpustate->irq_in_progress)
565                 return 0;
566
567         /* external interrupts take priority */
568         if (cpustate->irq_state && cpustate->xirq_enabled)
569         {
570                 cpustate->irq_state = FALSE;
571                 cpustate->irq_in_progress = TRUE;
572
573                 /* transfer to location 0x03 */
574                 push_pc_psw(cpustate);
575                 cpustate->pc = 0x03;
576
577                 /* indicate we took the external IRQ */
578                 if (cpustate->intr != NULL)
579                         cpustate->intr->get_intr_ack();
580                 return 2;
581         }
582
583         /* timer overflow interrupts follow */
584         if (cpustate->timer_overflow && cpustate->tirq_enabled)
585         {
586                 cpustate->irq_in_progress = TRUE;
587
588                 /* transfer to location 0x07 */
589                 push_pc_psw(cpustate);
590                 cpustate->pc = 0x07;
591
592                 /* timer overflow flip-flop is reset once taken */
593                 cpustate->timer_overflow = FALSE;
594                 return 2;
595         }
596         return 0;
597 }
598
599 /***************************************************************************
600     INLINE FUNCTIONS
601 ***************************************************************************/
602
603 /*-------------------------------------------------
604     opcode_fetch - fetch an opcode byte
605 -------------------------------------------------*/
606
607 inline UINT8 MCS48_BASE::opcode_fetch(mcs48_state *cpustate)
608 {
609         return cpustate->rom[cpustate->pc++ & 0xfff];
610 }
611
612 /*-------------------------------------------------
613     argument_fetch - fetch an opcode argument
614     byte
615 -------------------------------------------------*/
616
617 inline UINT8 MCS48_BASE::argument_fetch(mcs48_state *cpustate)
618 {
619         return cpustate->rom[cpustate->pc++ & 0xfff];
620 }
621
622 /*-------------------------------------------------
623     pull_pc - pull the PC value from the stack,
624     leaving the upper part of PSW intact
625 -------------------------------------------------*/
626
627 inline void MCS48_BASE::pull_pc(mcs48_state *cpustate)
628 {
629         UINT8 sp = (cpustate->psw - 1) & 0x07;
630         cpustate->pc = __mcs48_ram_r(8 + 2*sp);
631         cpustate->pc |= __mcs48_ram_r(9 + 2*sp) << 8;
632         cpustate->pc &= 0xfff;
633         cpustate->psw = (cpustate->psw & 0xf0) | 0x08 | sp;
634 }
635
636 /*-------------------------------------------------
637     execute_add - perform the logic of an ADD
638     instruction
639 -------------------------------------------------*/
640
641 inline void MCS48_BASE::execute_add(mcs48_state *cpustate, UINT8 dat)
642 {
643         UINT16 temp = cpustate->a + dat;
644         UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f);
645
646         cpustate->psw &= ~(C_FLAG | A_FLAG);
647         cpustate->psw |= (temp4 << 2) & A_FLAG;
648         cpustate->psw |= (temp >> 1) & C_FLAG;
649         cpustate->a = temp;
650 }
651
652 /*-------------------------------------------------
653     execute_addc - perform the logic of an ADDC
654     instruction
655 -------------------------------------------------*/
656
657 inline void MCS48_BASE::execute_addc(mcs48_state *cpustate, UINT8 dat)
658 {
659         UINT8 carryin = (cpustate->psw & C_FLAG) >> 7;
660         UINT16 temp = cpustate->a + dat + carryin;
661         UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f) + carryin;
662
663         cpustate->psw &= ~(C_FLAG | A_FLAG);
664         cpustate->psw |= (temp4 << 2) & A_FLAG;
665         cpustate->psw |= (temp >> 1) & C_FLAG;
666         cpustate->a = temp;
667 }
668
669 /*-------------------------------------------------
670     execute_jmp - perform the logic of a JMP
671     instruction
672 -------------------------------------------------*/
673
674 inline void MCS48_BASE::execute_jmp(mcs48_state *cpustate, UINT16 address)
675 {
676         UINT16 a11 = (cpustate->irq_in_progress) ? 0 : cpustate->a11;
677         cpustate->pc = address | a11;
678 }
679
680 /*-------------------------------------------------
681     execute_call - perform the logic of a CALL
682     instruction
683 -------------------------------------------------*/
684
685 inline void MCS48_BASE::execute_call(mcs48_state *cpustate, UINT16 address)
686 {
687         push_pc_psw(cpustate);
688         execute_jmp(cpustate, address);
689 }
690
691 /*-------------------------------------------------
692     execute_jcc - perform the logic of a
693     conditional jump instruction
694 -------------------------------------------------*/
695
696 inline void MCS48_BASE::execute_jcc(mcs48_state *cpustate, UINT8 result)
697 {
698         UINT8 offset = argument_fetch(cpustate);
699         if (result != 0)
700                 cpustate->pc = ((cpustate->pc - 1) & 0xf00) | offset;
701 }
702
703 /*-------------------------------------------------
704     expander_operation - perform an operation via
705     the 8243 expander chip
706 -------------------------------------------------*/
707
708 inline void MCS48_BASE::expander_operation(mcs48_state *cpustate, UINT8 operation, UINT8 port)
709 {
710         /* put opcode/data on low 4 bits of P2 */
711         __mcs48_port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (operation << 2) | (port & 3));
712
713         /* generate high-to-low transition on PROG line */
714         __mcs48_prog_w(0);
715
716         /* put data on low 4 bits of P2 */
717         if (operation != 0)
718                 __mcs48_port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (cpustate->a & 0x0f));
719         else
720                 cpustate->a = __mcs48_port_r(2) | 0x0f;
721
722         /* generate low-to-high transition on PROG line */
723         __mcs48_prog_w(1);
724 }
725
726
727 class MCS48 : public MCS48_BASE
728 {
729 private:
730         void burn_cycles(mcs48_state *cpustate, int count);
731         /* ---------------------------------------------------------------------------
732         registers
733         --------------------------------------------------------------------------- */
734         
735         
736 public:
737         MCS48(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MCS48_BASE(parent_vm, parent_emu)
738         {
739         }
740         ~MCS48() {}
741         void initialize();
742         void release();
743         int run(int icount);
744         bool process_state(FILEIO* state_fio, bool loading);
745 #ifdef USE_DEBUGGER
746         void *get_debugger()
747         {
748                 return d_debugger;
749         }
750         uint32_t get_debug_prog_addr_mask()
751         {
752                 return 0xfff;
753         }
754         uint32_t get_debug_data_addr_mask()
755         {
756                 return 0xff;
757         }
758         void set_context_debugger(DEBUGGER* device)
759         {
760                 d_debugger = device;
761         }
762 #endif
763 };      
764
765 #endif
766