2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
16 #if defined(HAS_UPD7810)
17 #define CPU_MODEL upd7810
18 #elif defined(HAS_UPD7807)
19 #define CPU_MODEL upd7807
20 #elif defined(HAS_UPD7801)
21 #define CPU_MODEL upd7801
22 #elif defined(HAS_UPD78C05)
23 #define CPU_MODEL upd78c05
24 #elif defined(HAS_UPD78C06)
25 #define CPU_MODEL upd78c06
26 #elif defined(HAS_UPD7907)
27 #define CPU_MODEL upd7907
30 /* ----------------------------------------------------------------------------
32 ---------------------------------------------------------------------------- */
37 /*****************************************************************************/
38 /* src/emu/devcpu.h */
40 // CPU interface functions
41 #define CPU_INIT_NAME(name) cpu_init_##name
42 #define CPU_INIT(name) void* CPU_INIT_NAME(name)()
43 #define CPU_INIT_CALL(name) CPU_INIT_NAME(name)()
45 #define CPU_RESET_NAME(name) cpu_reset_##name
46 #define CPU_RESET(name) void CPU_RESET_NAME(name)(upd7810_state *cpustate)
47 #define CPU_RESET_CALL(name) CPU_RESET_NAME(name)(cpustate)
49 #define CPU_EXECUTE_NAME(name) cpu_execute_##name
50 #define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(upd7810_state *cpustate)
51 #define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate)
53 #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name
54 #define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol)
55 #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, oprom, d_debugger->first_symbol)
57 /*****************************************************************************/
58 /* src/emu/didisasm.h */
60 // Disassembler constants
61 const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported?
62 const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence
63 const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards
64 const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over
65 const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value
66 const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length
68 /*****************************************************************************/
69 /* src/emu/diexec.h */
74 CLEAR_LINE = 0, // clear (a fired or held) line
75 ASSERT_LINE // assert an interrupt immediately
88 #define fatalerror(...)
93 #include "mame/emu/cpu/upd7810/upd7810.c"
96 #include "mame/emu/cpu/upd7810/7810dasm.c"
101 void UPD7810::initialize()
103 DEVICE::initialize();
104 opaque = CPU_INIT_CALL(upd7810);
106 upd7810_state *cpustate = (upd7810_state *)opaque;
107 #if defined(HAS_UPD7810)
108 cpustate->config.type = TYPE_7810;
109 #elif defined(HAS_UPD7807)
110 cpustate->config.type = TYPE_7807;
111 #elif defined(HAS_UPD7801)
112 cpustate->config.type = TYPE_7801;
113 #elif defined(HAS_UPD78C05)
114 cpustate->config.type = TYPE_78C05;
115 #elif defined(HAS_UPD78C06)
116 cpustate->config.type = TYPE_78C06;
117 #elif defined(HAS_UPD7907)
118 cpustate->config.type = TYPE_78C06;
120 cpustate->program = d_mem;
122 cpustate->outputs_to = (void*)&outputs_to;
123 cpustate->outputs_txd = (void*)&outputs_txd;
126 cpustate->debugger = d_debugger;
127 cpustate->program_stored = d_mem;
128 cpustate->io_stored = d_io;
130 d_debugger->set_context_mem(d_mem);
131 d_debugger->set_context_io(d_io);
135 void UPD7810::release()
140 void UPD7810::reset()
142 upd7810_state *cpustate = (upd7810_state *)opaque;
144 CPU_RESET_CALL(CPU_MODEL);
146 cpustate->program = d_mem;
148 cpustate->outputs_to = (void*)&outputs_to;
149 cpustate->outputs_txd = (void*)&outputs_txd;
152 cpustate->debugger = d_debugger;
153 cpustate->program_stored = d_mem;
154 cpustate->io_stored = d_io;
160 int UPD7810::run(int clock)
162 upd7810_state *cpustate = (upd7810_state *)opaque;
172 // run only one opcode
173 return run_one_opecode();
177 int first_icount = icount;
179 // run cpu while given clocks
180 while(icount > 0 && !busreq) {
181 icount -= run_one_opecode();
183 // if busreq is raised, spin cpu while remained clock
184 if(icount > 0 && busreq) {
186 total_icount += icount;
190 return first_icount - icount;
194 int UPD7810::run_one_opecode()
197 upd7810_state *cpustate = (upd7810_state *)opaque;
198 d_debugger->add_cpu_trace(cpustate->pc.w.l);
200 int passed_icount = CPU_EXECUTE_CALL(upd7810);
202 total_icount += passed_icount;
204 return passed_icount;
207 void UPD7810::write_signal(int id, uint32_t data, uint32_t mask)
209 upd7810_state *cpustate = (upd7810_state *)opaque;
212 case SIG_UPD7810_INTF1:
213 set_irq_line(cpustate, UPD7810_INTF1, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
215 case SIG_UPD7810_INTF2:
216 set_irq_line(cpustate, UPD7810_INTF2, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
218 case SIG_UPD7810_INTF0:
219 set_irq_line(cpustate, UPD7810_INTF0, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
221 case SIG_UPD7810_INTFE1:
222 set_irq_line(cpustate, UPD7810_INTFE1, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
224 case SIG_UPD7810_NMI:
225 set_irq_line(cpustate, INPUT_LINE_NMI, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
228 busreq = ((data & mask) != 0);
233 uint32_t UPD7810::get_pc()
235 upd7810_state *cpustate = (upd7810_state *)opaque;
236 return cpustate->ppc.w.l;
239 uint32_t UPD7810::get_next_pc()
241 upd7810_state *cpustate = (upd7810_state *)opaque;
242 return cpustate->pc.w.l;
246 void UPD7810::write_debug_data8(uint32_t addr, uint32_t data)
249 d_mem->write_data8w(addr, data, &wait);
252 uint32_t UPD7810::read_debug_data8(uint32_t addr)
255 return d_mem->read_data8w(addr, &wait);
258 void UPD7810::write_debug_io8(uint32_t addr, uint32_t data)
261 d_io->write_io8w(addr, data, &wait);
264 uint32_t UPD7810::read_debug_io8(uint32_t addr) {
266 return d_io->read_io8w(addr, &wait);
269 bool UPD7810::write_debug_reg(const _TCHAR *reg, uint32_t data)
271 upd7810_state *cpustate = (upd7810_state *)opaque;
273 if(_tcsicmp(reg, _T("PC")) == 0) {
275 } else if(_tcsicmp(reg, _T("SP")) == 0) {
277 } else if(_tcsicmp(reg, _T("VA")) == 0) {
279 } else if(_tcsicmp(reg, _T("BC")) == 0) {
281 } else if(_tcsicmp(reg, _T("DE")) == 0) {
283 } else if(_tcsicmp(reg, _T("HL")) == 0) {
285 } else if(_tcsicmp(reg, _T("V")) == 0) {
287 } else if(_tcsicmp(reg, _T("A")) == 0) {
289 } else if(_tcsicmp(reg, _T("B")) == 0) {
291 } else if(_tcsicmp(reg, _T("C")) == 0) {
293 } else if(_tcsicmp(reg, _T("D")) == 0) {
295 } else if(_tcsicmp(reg, _T("E")) == 0) {
297 } else if(_tcsicmp(reg, _T("H")) == 0) {
299 } else if(_tcsicmp(reg, _T("L")) == 0) {
301 } else if(_tcsicmp(reg, _T("VA'")) == 0) {
303 } else if(_tcsicmp(reg, _T("BC'")) == 0) {
305 } else if(_tcsicmp(reg, _T("DE'")) == 0) {
307 } else if(_tcsicmp(reg, _T("HL'")) == 0) {
309 } else if(_tcsicmp(reg, _T("V'")) == 0) {
311 } else if(_tcsicmp(reg, _T("A'")) == 0) {
313 } else if(_tcsicmp(reg, _T("B'")) == 0) {
315 } else if(_tcsicmp(reg, _T("C'")) == 0) {
317 } else if(_tcsicmp(reg, _T("D'")) == 0) {
319 } else if(_tcsicmp(reg, _T("E'")) == 0) {
321 } else if(_tcsicmp(reg, _T("H'")) == 0) {
323 } else if(_tcsicmp(reg, _T("L'")) == 0) {
331 void UPD7810::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
334 VA = 0000 BC = 0000 DE = 0000 HL = 0000 PSW= 00 [Z SK HC L1 L0 CY]
335 VA'= 0000 BC'= 0000 DE'= 0000 HL'= 0000 SP = 0000 PC = 0000
336 (BC)= 0000 (DE)=0000 (HL)= 0000 (SP)= 0000 <DI>
337 Clocks = 0 (0) Since Scanline = 0/0 (0/0)
339 upd7810_state *cpustate = (upd7810_state *)opaque;
341 my_stprintf_s(buffer, buffer_len,
342 _T("VA = %04X BC = %04X DE = %04X HL = %04X PSW= %02x [%s %s %s %s %s %s]\nVA'= %04X BC'= %04X DE'= %04X HL'= %04X SP = %04X PC = %04X\n (BC)= %04X (DE)=%04X (HL)= %04X (SP)= %04X <%s>\nClocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
344 (PSW & Z) ? _T("Z") : _T("-"), (PSW & SK) ? _T("SK") : _T("--"), (PSW & HC) ? _T("HC") : _T("--"), (PSW & L1) ? _T("L1") : _T("--"), (PSW & L0) ? _T("L0") : _T("--"), (PSW & CY) ? _T("CY") : _T("--"),
345 VA2, BC2, DE2, HL2, SP, PC,
346 d_mem->read_data16w(BC, &wait), d_mem->read_data16w(DE, &wait), d_mem->read_data16w(HL, &wait), d_mem->read_data16w(SP, &wait),
347 IFF ? _T("EI") : _T("DI"),
348 total_icount, total_icount - prev_total_icount,
349 get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame());
350 prev_total_icount = total_icount;
355 int UPD7810::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
358 uint8_t *opram = oprom;
360 for(int i = 0; i < 8; i++) {
362 oprom[i] = d_mem->read_data8w(pc + i, &wait);
364 return CPU_DISASSEMBLE_CALL(CPU_MODEL) & DASMFLAG_LENGTHMASK;
368 #define STATE_VERSION 4
370 void UPD7810::process_state_cpustate(FILEIO* state_fio, bool loading)
372 upd7810_state *cpustate = (upd7810_state *)opaque;
374 state_fio->StateUint32(cpustate->ppc.d); /* previous program counter */
375 state_fio->StateUint32(cpustate->pc.d); /* program counter */
376 state_fio->StateUint32(cpustate->sp.d); /* stack pointer */
377 state_fio->StateUint8(cpustate->op); /* opcode */
378 state_fio->StateUint8(cpustate->op2); /* opcode part 2 */
379 state_fio->StateUint8(cpustate->iff); /* interrupt enable flip flop */
380 state_fio->StateUint8(cpustate->softi);
381 state_fio->StateUint8(cpustate->psw); /* processor status word */
382 state_fio->StateUint32(cpustate->ea.d); /* extended accumulator */
383 state_fio->StateUint32(cpustate->va.d); /* accumulator + vector register */
384 state_fio->StateUint32(cpustate->bc.d); /* 8bit B and C registers / 16bit BC register */
385 state_fio->StateUint32(cpustate->de.d); /* 8bit D and E registers / 16bit DE register */
386 state_fio->StateUint32(cpustate->hl.d); /* 8bit H and L registers / 16bit HL register */
387 state_fio->StateUint32(cpustate->ea2.d); /* alternate register set */
388 state_fio->StateUint32(cpustate->va2.d);
389 state_fio->StateUint32(cpustate->bc2.d);
390 state_fio->StateUint32(cpustate->de2.d);
391 state_fio->StateUint32(cpustate->hl2.d);
392 state_fio->StateUint32(cpustate->cnt.d); /* 8 bit timer counter */
393 state_fio->StateUint32(cpustate->tm.d); /* 8 bit timer 0/1 comparator inputs */
394 state_fio->StateUint32(cpustate->ecnt.d); /* timer counter register / capture register */
395 state_fio->StateUint32(cpustate->etm.d); /* timer 0/1 comparator inputs */
396 state_fio->StateUint8(cpustate->ma); /* port A input or output mask */
397 state_fio->StateUint8(cpustate->mb); /* port B input or output mask */
398 state_fio->StateUint8(cpustate->mcc); /* port C control/port select */
399 state_fio->StateUint8(cpustate->mc); /* port C input or output mask */
400 state_fio->StateUint8(cpustate->mm); /* memory mapping */
401 state_fio->StateUint8(cpustate->mf); /* port F input or output mask */
402 state_fio->StateUint8(cpustate->tmm); /* timer 0 and timer 1 operating parameters */
403 state_fio->StateUint8(cpustate->etmm); /* 16-bit multifunction timer/event counter */
404 state_fio->StateUint8(cpustate->eom); /* 16-bit timer/event counter output control */
405 state_fio->StateUint8(cpustate->sml); /* serial interface parameters low */
406 state_fio->StateUint8(cpustate->smh); /* -"- high */
407 state_fio->StateUint8(cpustate->anm); /* analog to digital converter operating parameters */
408 state_fio->StateUint8(cpustate->mkl); /* interrupt mask low */
409 state_fio->StateUint8(cpustate->mkh); /* -"- high */
410 state_fio->StateUint8(cpustate->zcm); /* bias circuitry for ac zero-cross detection */
411 state_fio->StateUint8(cpustate->pa_in); /* port A,B,C,D,F inputs */
412 state_fio->StateUint8(cpustate->pb_in);
413 state_fio->StateUint8(cpustate->pc_in);
414 state_fio->StateUint8(cpustate->pd_in);
415 state_fio->StateUint8(cpustate->pf_in);
416 state_fio->StateUint8(cpustate->pa_out); /* port A,B,C,D,F outputs */
417 state_fio->StateUint8(cpustate->pb_out);
418 state_fio->StateUint8(cpustate->pc_out);
419 state_fio->StateUint8(cpustate->pd_out);
420 state_fio->StateUint8(cpustate->pf_out);
421 state_fio->StateUint8(cpustate->cr0); /* analog digital conversion register 0 */
422 state_fio->StateUint8(cpustate->cr1); /* analog digital conversion register 1 */
423 state_fio->StateUint8(cpustate->cr2); /* analog digital conversion register 2 */
424 state_fio->StateUint8(cpustate->cr3); /* analog digital conversion register 3 */
425 state_fio->StateUint8(cpustate->txb); /* transmitter buffer */
426 state_fio->StateUint8(cpustate->rxb); /* receiver buffer */
427 state_fio->StateUint8(cpustate->txd); /* port C control line states */
428 state_fio->StateUint8(cpustate->rxd);
429 state_fio->StateUint8(cpustate->sck);
430 state_fio->StateUint8(cpustate->ti);
431 state_fio->StateUint8(cpustate->to);
432 state_fio->StateUint8(cpustate->ci);
433 state_fio->StateUint8(cpustate->co0);
434 state_fio->StateUint8(cpustate->co1);
435 state_fio->StateUint16(cpustate->irr); /* interrupt request register */
436 state_fio->StateUint16(cpustate->itf); /* interrupt test flag register */
437 state_fio->StateInt32(cpustate->int1); /* keep track of current int1 state. Needed for 7801 irq checking. */
438 state_fio->StateInt32(cpustate->int2); /* keep track to current int2 state. Needed for 7801 irq checking. */
440 /* internal helper variables */
441 state_fio->StateUint16(cpustate->txs); /* transmitter shift register */
442 state_fio->StateUint16(cpustate->rxs); /* receiver shift register */
443 state_fio->StateUint8(cpustate->txcnt); /* transmitter shift register bit count */
444 state_fio->StateUint8(cpustate->rxcnt); /* receiver shift register bit count */
445 state_fio->StateUint8(cpustate->txbuf); /* transmitter buffer was written */
446 state_fio->StateInt32(cpustate->ovc0); /* overflow counter for timer 0 ((for clock div 12/384) */
447 state_fio->StateInt32(cpustate->ovc1); /* overflow counter for timer 0 (for clock div 12/384) */
448 state_fio->StateInt32(cpustate->ovce); /* overflow counter for ecnt */
449 state_fio->StateInt32(cpustate->ovcf); /* overflow counter for fixed clock div 3 mode */
450 state_fio->StateInt32(cpustate->ovcs); /* overflow counter for serial I/O */
451 state_fio->StateInt32(cpustate->ovcsio);
452 state_fio->StateUint8(cpustate->edges); /* rising/falling edge flag for serial I/O */
453 state_fio->StateInt32(cpustate->icount);
457 bool UPD7810::process_state(FILEIO* state_fio, bool loading)
459 upd7810_state *cpustate = (upd7810_state *)opaque;
460 const struct opcode_s *opXX = cpustate->opXX;
461 const struct opcode_s *op48 = cpustate->op48;
462 const struct opcode_s *op4C = cpustate->op4C;
463 const struct opcode_s *op4D = cpustate->op4D;
464 const struct opcode_s *op60 = cpustate->op60;
465 const struct opcode_s *op64 = cpustate->op64;
466 const struct opcode_s *op70 = cpustate->op70;
467 const struct opcode_s *op74 = cpustate->op74;
468 void(*handle_timers)(upd7810_state *cpustate, int cycles) = cpustate->handle_timers;
469 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
472 if(!state_fio->StateCheckInt32(this_device_id)) {
475 //state_fio->StateBuffer(opaque, sizeof(upd7810_state), 1);
476 process_state_cpustate(state_fio, loading);
478 state_fio->StateUint64(total_icount);
480 state_fio->StateInt32(icount);
481 state_fio->StateBool(busreq);
485 cpustate->opXX = opXX;
486 cpustate->op48 = op48;
487 cpustate->op4C = op4C;
488 cpustate->op4D = op4D;
489 cpustate->op60 = op60;
490 cpustate->op64 = op64;
491 cpustate->op70 = op70;
492 cpustate->op74 = op74;
493 cpustate->handle_timers = handle_timers;
495 cpustate->program = d_mem;
497 cpustate->outputs_to = (void*)&outputs_to;
498 cpustate->outputs_txd = (void*)&outputs_txd;
501 cpustate->debugger = d_debugger;
502 cpustate->program_stored = d_mem;
503 cpustate->io_stored = d_io;
504 prev_total_icount = total_icount;