2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
18 #include "mcs48_flags.h"
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 */
35 /***************************************************************************
37 ***************************************************************************/
39 /* timer/counter enable bits */
40 #define __MCS48_TIMER_ENABLED 0x01
41 #define __MCS48_COUNTER_ENABLED 0x02
43 /***************************************************************************
45 ***************************************************************************/
47 /* live processor state */
50 UINT16 prevpc; /* 16-bit previous program counter */
51 UINT16 pc; /* 16-bit program counter */
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 */
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 */
73 UINT16 a11; /* A11 value, either 0x000 or 0x800 */
84 /***************************************************************************
86 ***************************************************************************/
88 #define __mcs48_program_r(a) cpustate->rom[(a) & 0xfff]
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)
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)
107 #define __MCS48_OPHANDLER(_name) int MCS48_BASE::_name(mcs48_state *cpustate)
108 #define __MCS48_OPHANDLER_D(_name) int _name(mcs48_state *cpustate)
110 class MCS48MEM : public DEVICE
115 MCS48MEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
117 memset(ram, 0, sizeof(ram));
118 set_device_name(_T("MCS48 MEMORY BUS"));
122 uint32_t read_data8(uint32_t addr)
124 return ram[addr & 0xff];
126 void write_data8(uint32_t addr, uint32_t data)
128 ram[addr & 0xff] = data;
130 bool process_state(FILEIO* state_fio, bool loading);
133 class MCS48_BASE : public DEVICE
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);
145 uint64_t total_icount;
146 uint64_t prev_total_icount;
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 );
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 );
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 );
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 );
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 );
203 __MCS48_OPHANDLER_D( clr_a );
204 __MCS48_OPHANDLER_D( clr_c );
205 __MCS48_OPHANDLER_D( clr_f0 );
206 __MCS48_OPHANDLER_D( clr_f1 );
208 __MCS48_OPHANDLER_D( cpl_a );
209 __MCS48_OPHANDLER_D( cpl_c );
210 __MCS48_OPHANDLER_D( cpl_f0 );
211 __MCS48_OPHANDLER_D( cpl_f1 );
213 __MCS48_OPHANDLER_D( da_a );
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 );
225 __MCS48_OPHANDLER_D( dis_i );
226 __MCS48_OPHANDLER_D( dis_tcnti );
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 );
237 __MCS48_OPHANDLER_D( en_i );
238 __MCS48_OPHANDLER_D( en_tcnti );
239 __MCS48_OPHANDLER_D( ent0_clk );
241 __MCS48_OPHANDLER_D( in_a_p1 );
242 __MCS48_OPHANDLER_D( in_a_p2 );
243 __MCS48_OPHANDLER_D( ins_a_bus );
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 );
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 );
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 );
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 );
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 );
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 );
334 __MCS48_OPHANDLER_D( movp_a_xa );
335 __MCS48_OPHANDLER_D( movp3_a_xa );
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 );
342 __MCS48_OPHANDLER_D( nop );
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 );
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 );
364 __MCS48_OPHANDLER_D( outl_bus_a );
365 __MCS48_OPHANDLER_D( outl_p1_a );
366 __MCS48_OPHANDLER_D( outl_p2_a );
368 __MCS48_OPHANDLER_D( ret );
369 __MCS48_OPHANDLER_D( retr );
371 __MCS48_OPHANDLER_D( rl_a );
372 __MCS48_OPHANDLER_D( rlc_a );
374 __MCS48_OPHANDLER_D( rr_a );
375 __MCS48_OPHANDLER_D( rrc_a );
377 __MCS48_OPHANDLER_D( sel_mb0 );
378 __MCS48_OPHANDLER_D( sel_mb1 );
380 __MCS48_OPHANDLER_D( sel_rb0 );
381 __MCS48_OPHANDLER_D( sel_rb1 );
383 __MCS48_OPHANDLER_D( stop_tcnt );
385 __MCS48_OPHANDLER_D( strt_cnt );
386 __MCS48_OPHANDLER_D( strt_t );
388 __MCS48_OPHANDLER_D( swap_a );
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 );
401 __MCS48_OPHANDLER_D( xchd_a_xr0 );
402 __MCS48_OPHANDLER_D( xchd_a_xr1 );
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 );
417 /* ---------------------------------------------------------------------------
419 --------------------------------------------------------------------------- */
421 DEVICE *d_mem, *d_io, *d_intr;
422 //#ifdef USE_DEBUGGER
423 DEBUGGER *d_debugger;
424 DEVICE *d_mem_stored, *d_io_stored;
427 /* opcode table entry */
428 typedef int (MCS48_BASE::*mcs48_ophandler)(mcs48_state *state);
430 const mcs48_ophandler opcode_table[256] =
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
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 *);
473 MCS48_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
475 d_mem = d_io = d_intr = NULL;
477 d_mem_stored = d_io_stored = NULL;
478 total_icount = prev_total_icount = 0;
479 set_device_name(_T("MCS48 MCU"));
484 virtual void initialize();
485 virtual void release();
487 virtual int run(int icount);
488 void write_signal(int id, uint32_t data, uint32_t mask);
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);
502 void set_context_mem(DEVICE* device)
506 void set_context_io(DEVICE* device)
510 void set_context_intr(DEVICE* device)
514 void load_rom_image(const _TCHAR *file_path);
515 uint8_t *get_rom_ptr();
519 /*-------------------------------------------------
520 update_regptr - update the regptr member to
521 point to the appropriate register bank
522 -------------------------------------------------*/
524 inline void MCS48_BASE::update_regptr(mcs48_state *cpustate)
526 cpustate->regptr = ((cpustate->psw & B_FLAG) ? 24 : 0);
529 /*-------------------------------------------------
530 push_pc_psw - push the cpustate->pc and cpustate->psw values onto
532 -------------------------------------------------*/
534 inline void MCS48_BASE::push_pc_psw(mcs48_state *cpustate)
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);
542 /*-------------------------------------------------
543 pull_pc_psw - pull the PC and PSW values from
545 -------------------------------------------------*/
547 inline void MCS48_BASE::pull_pc_psw(mcs48_state *cpustate)
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);
557 /*-------------------------------------------------
558 check_irqs - check for and process IRQs
559 -------------------------------------------------*/
561 inline int MCS48_BASE::check_irqs(mcs48_state *cpustate)
563 /* if something is in progress, we do nothing */
564 if (cpustate->irq_in_progress)
567 /* external interrupts take priority */
568 if (cpustate->irq_state && cpustate->xirq_enabled)
570 cpustate->irq_state = FALSE;
571 cpustate->irq_in_progress = TRUE;
573 /* transfer to location 0x03 */
574 push_pc_psw(cpustate);
577 /* indicate we took the external IRQ */
578 if (cpustate->intr != NULL)
579 cpustate->intr->get_intr_ack();
583 /* timer overflow interrupts follow */
584 if (cpustate->timer_overflow && cpustate->tirq_enabled)
586 cpustate->irq_in_progress = TRUE;
588 /* transfer to location 0x07 */
589 push_pc_psw(cpustate);
592 /* timer overflow flip-flop is reset once taken */
593 cpustate->timer_overflow = FALSE;
599 /***************************************************************************
601 ***************************************************************************/
603 /*-------------------------------------------------
604 opcode_fetch - fetch an opcode byte
605 -------------------------------------------------*/
607 inline UINT8 MCS48_BASE::opcode_fetch(mcs48_state *cpustate)
609 return cpustate->rom[cpustate->pc++ & 0xfff];
612 /*-------------------------------------------------
613 argument_fetch - fetch an opcode argument
615 -------------------------------------------------*/
617 inline UINT8 MCS48_BASE::argument_fetch(mcs48_state *cpustate)
619 return cpustate->rom[cpustate->pc++ & 0xfff];
622 /*-------------------------------------------------
623 pull_pc - pull the PC value from the stack,
624 leaving the upper part of PSW intact
625 -------------------------------------------------*/
627 inline void MCS48_BASE::pull_pc(mcs48_state *cpustate)
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;
636 /*-------------------------------------------------
637 execute_add - perform the logic of an ADD
639 -------------------------------------------------*/
641 inline void MCS48_BASE::execute_add(mcs48_state *cpustate, UINT8 dat)
643 UINT16 temp = cpustate->a + dat;
644 UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f);
646 cpustate->psw &= ~(C_FLAG | A_FLAG);
647 cpustate->psw |= (temp4 << 2) & A_FLAG;
648 cpustate->psw |= (temp >> 1) & C_FLAG;
652 /*-------------------------------------------------
653 execute_addc - perform the logic of an ADDC
655 -------------------------------------------------*/
657 inline void MCS48_BASE::execute_addc(mcs48_state *cpustate, UINT8 dat)
659 UINT8 carryin = (cpustate->psw & C_FLAG) >> 7;
660 UINT16 temp = cpustate->a + dat + carryin;
661 UINT16 temp4 = (cpustate->a & 0x0f) + (dat & 0x0f) + carryin;
663 cpustate->psw &= ~(C_FLAG | A_FLAG);
664 cpustate->psw |= (temp4 << 2) & A_FLAG;
665 cpustate->psw |= (temp >> 1) & C_FLAG;
669 /*-------------------------------------------------
670 execute_jmp - perform the logic of a JMP
672 -------------------------------------------------*/
674 inline void MCS48_BASE::execute_jmp(mcs48_state *cpustate, UINT16 address)
676 UINT16 a11 = (cpustate->irq_in_progress) ? 0 : cpustate->a11;
677 cpustate->pc = address | a11;
680 /*-------------------------------------------------
681 execute_call - perform the logic of a CALL
683 -------------------------------------------------*/
685 inline void MCS48_BASE::execute_call(mcs48_state *cpustate, UINT16 address)
687 push_pc_psw(cpustate);
688 execute_jmp(cpustate, address);
691 /*-------------------------------------------------
692 execute_jcc - perform the logic of a
693 conditional jump instruction
694 -------------------------------------------------*/
696 inline void MCS48_BASE::execute_jcc(mcs48_state *cpustate, UINT8 result)
698 UINT8 offset = argument_fetch(cpustate);
700 cpustate->pc = ((cpustate->pc - 1) & 0xf00) | offset;
703 /*-------------------------------------------------
704 expander_operation - perform an operation via
705 the 8243 expander chip
706 -------------------------------------------------*/
708 inline void MCS48_BASE::expander_operation(mcs48_state *cpustate, UINT8 operation, UINT8 port)
710 /* put opcode/data on low 4 bits of P2 */
711 __mcs48_port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (operation << 2) | (port & 3));
713 /* generate high-to-low transition on PROG line */
716 /* put data on low 4 bits of P2 */
718 __mcs48_port_w(2, cpustate->p2 = (cpustate->p2 & 0xf0) | (cpustate->a & 0x0f));
720 cpustate->a = __mcs48_port_r(2) | 0x0f;
722 /* generate low-to-high transition on PROG line */
727 class MCS48 : public MCS48_BASE
730 void burn_cycles(mcs48_state *cpustate, int count);
731 /* ---------------------------------------------------------------------------
733 --------------------------------------------------------------------------- */
737 MCS48(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MCS48_BASE(parent_vm, parent_emu)
744 bool process_state(FILEIO* state_fio, bool loading);
750 uint32_t get_debug_prog_addr_mask()
754 uint32_t get_debug_data_addr_mask()
758 void set_context_debugger(DEBUGGER* device)