OSDN Git Service

[VM][STATE][WIP] Apply process_state() to some devices.
[csp-qt/common_source_project-fm7.git] / source / src / vm / upd7810.cpp
1 /*
2         Skelton for retropc emulator
3
4         Origin : MESS 0.152
5         Author : Takeda.Toshiya
6         Date   : 2016.03.17-
7
8         [ uPD7810 ]
9 */
10
11 #include "upd7810.h"
12 #ifdef USE_DEBUGGER
13 #include "debugger.h"
14 #endif
15
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
28 #endif
29
30 /* ----------------------------------------------------------------------------
31         MAME uPD7810
32 ---------------------------------------------------------------------------- */
33
34 #define PAIR pair_t
35 #define offs_t UINT16
36
37 /*****************************************************************************/
38 /* src/emu/devcpu.h */
39
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)()
44
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)
48
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)
52
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)
56
57 /*****************************************************************************/
58 /* src/emu/didisasm.h */
59
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
67
68 /*****************************************************************************/
69 /* src/emu/diexec.h */
70
71 // I/O line states
72 enum line_state
73 {
74         CLEAR_LINE = 0,                         // clear (a fired or held) line
75         ASSERT_LINE                             // assert an interrupt immediately
76 };
77
78 enum
79 {
80         UPD7810_INTF1  = 0,
81         UPD7810_INTF2  = 1,
82         UPD7810_INTF0  = 2,
83         UPD7810_INTFE1 = 4,
84         INPUT_LINE_NMI
85 };
86
87 #define logerror(...)
88 #define fatalerror(...)
89
90 #undef IN
91 #undef OUT
92
93 #include "mame/emu/cpu/upd7810/upd7810.c"
94 #ifdef USE_DEBUGGER
95 #undef _DOFF
96 #include "mame/emu/cpu/upd7810/7810dasm.c"
97 #endif
98
99 // main
100
101 void UPD7810::initialize()
102 {
103         DEVICE::initialize();
104         opaque = CPU_INIT_CALL(upd7810);
105         
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;
119 #endif
120         cpustate->program = d_mem;
121         cpustate->io = d_io;
122         cpustate->outputs_to = (void*)&outputs_to;
123         cpustate->outputs_txd = (void*)&outputs_txd;
124 #ifdef USE_DEBUGGER
125         cpustate->emu = emu;
126         cpustate->debugger = d_debugger;
127         cpustate->program_stored = d_mem;
128         cpustate->io_stored = d_io;
129         
130         d_debugger->set_context_mem(d_mem);
131         d_debugger->set_context_io(d_io);
132 #endif
133 }
134
135 void UPD7810::release()
136 {
137         free(opaque);
138 }
139
140 void UPD7810::reset()
141 {
142         upd7810_state *cpustate = (upd7810_state *)opaque;
143         
144         CPU_RESET_CALL(CPU_MODEL);
145         
146         cpustate->program = d_mem;
147         cpustate->io = d_io;
148         cpustate->outputs_to = (void*)&outputs_to;
149         cpustate->outputs_txd = (void*)&outputs_txd;
150 #ifdef USE_DEBUGGER
151         cpustate->emu = emu;
152         cpustate->debugger = d_debugger;
153         cpustate->program_stored = d_mem;
154         cpustate->io_stored = d_io;
155 #endif
156         icount = 0;
157         busreq = false;
158 }
159
160 int UPD7810::run(int clock)
161 {
162         upd7810_state *cpustate = (upd7810_state *)opaque;
163         
164         if(clock == -1) {
165                 if(busreq) {
166                         // don't run cpu!
167 #ifdef USE_DEBUGGER
168                         total_icount += 1;
169 #endif
170                         return 1;
171                 } else {
172                         // run only one opcode
173                         return run_one_opecode();
174                 }
175         } else {
176                 icount += clock;
177                 int first_icount = icount;
178                 
179                 // run cpu while given clocks
180                 while(icount > 0 && !busreq) {
181                         icount -= run_one_opecode();
182                 }
183                 // if busreq is raised, spin cpu while remained clock
184                 if(icount > 0 && busreq) {
185 #ifdef USE_DEBUGGER
186                         total_icount += icount;
187 #endif
188                         icount = 0;
189                 }
190                 return first_icount - icount;
191         }
192 }
193
194 int UPD7810::run_one_opecode()
195 {
196 #ifdef USE_DEBUGGER
197         upd7810_state *cpustate = (upd7810_state *)opaque;
198         d_debugger->add_cpu_trace(cpustate->pc.w.l);
199 #endif
200         int passed_icount = CPU_EXECUTE_CALL(upd7810);
201 #ifdef USE_DEBUGGER
202         total_icount += passed_icount;
203 #endif
204         return passed_icount;
205 }
206
207 void UPD7810::write_signal(int id, uint32_t data, uint32_t mask)
208 {
209         upd7810_state *cpustate = (upd7810_state *)opaque;
210         
211         switch(id) {
212         case SIG_UPD7810_INTF1:
213                 set_irq_line(cpustate, UPD7810_INTF1, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
214                 break;
215         case SIG_UPD7810_INTF2:
216                 set_irq_line(cpustate, UPD7810_INTF2, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
217                 break;
218         case SIG_UPD7810_INTF0:
219                 set_irq_line(cpustate, UPD7810_INTF0, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
220                 break;
221         case SIG_UPD7810_INTFE1:
222                 set_irq_line(cpustate, UPD7810_INTFE1, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
223                 break;
224         case SIG_UPD7810_NMI:
225                 set_irq_line(cpustate, INPUT_LINE_NMI, (data & mask) ? ASSERT_LINE : CLEAR_LINE);
226                 break;
227         case SIG_CPU_BUSREQ:
228                 busreq = ((data & mask) != 0);
229                 break;
230         }
231 }
232
233 uint32_t UPD7810::get_pc()
234 {
235         upd7810_state *cpustate = (upd7810_state *)opaque;
236         return cpustate->ppc.w.l;
237 }
238
239 uint32_t UPD7810::get_next_pc()
240 {
241         upd7810_state *cpustate = (upd7810_state *)opaque;
242         return cpustate->pc.w.l;
243 }
244
245 #ifdef USE_DEBUGGER
246 void UPD7810::write_debug_data8(uint32_t addr, uint32_t data)
247 {
248         int wait;
249         d_mem->write_data8w(addr, data, &wait);
250 }
251
252 uint32_t UPD7810::read_debug_data8(uint32_t addr)
253 {
254         int wait;
255         return d_mem->read_data8w(addr, &wait);
256 }
257
258 void UPD7810::write_debug_io8(uint32_t addr, uint32_t data)
259 {
260         int wait;
261         d_io->write_io8w(addr, data, &wait);
262 }
263
264 uint32_t UPD7810::read_debug_io8(uint32_t addr) {
265         int wait;
266         return d_io->read_io8w(addr, &wait);
267 }
268
269 bool UPD7810::write_debug_reg(const _TCHAR *reg, uint32_t data)
270 {
271         upd7810_state *cpustate = (upd7810_state *)opaque;
272         
273         if(_tcsicmp(reg, _T("PC")) == 0) {
274                 PC = data;
275         } else if(_tcsicmp(reg, _T("SP")) == 0) {
276                 SP = data;
277         } else if(_tcsicmp(reg, _T("VA")) == 0) {
278                 VA = data;
279         } else if(_tcsicmp(reg, _T("BC")) == 0) {
280                 BC = data;
281         } else if(_tcsicmp(reg, _T("DE")) == 0) {
282                 DE = data;
283         } else if(_tcsicmp(reg, _T("HL")) == 0) {
284                 HL = data;
285         } else if(_tcsicmp(reg, _T("V")) == 0) {
286                 V = data;
287         } else if(_tcsicmp(reg, _T("A")) == 0) {
288                 A = data;
289         } else if(_tcsicmp(reg, _T("B")) == 0) {
290                 B = data;
291         } else if(_tcsicmp(reg, _T("C")) == 0) {
292                 C = data;
293         } else if(_tcsicmp(reg, _T("D")) == 0) {
294                 D = data;
295         } else if(_tcsicmp(reg, _T("E")) == 0) {
296                 E = data;
297         } else if(_tcsicmp(reg, _T("H")) == 0) {
298                 H = data;
299         } else if(_tcsicmp(reg, _T("L")) == 0) {
300                 L = data;
301         } else if(_tcsicmp(reg, _T("VA'")) == 0) {
302                 VA2 = data;
303         } else if(_tcsicmp(reg, _T("BC'")) == 0) {
304                 BC2 = data;
305         } else if(_tcsicmp(reg, _T("DE'")) == 0) {
306                 DE2 = data;
307         } else if(_tcsicmp(reg, _T("HL'")) == 0) {
308                 HL2 = data;
309         } else if(_tcsicmp(reg, _T("V'")) == 0) {
310                 V2 = data;
311         } else if(_tcsicmp(reg, _T("A'")) == 0) {
312                 A2 = data;
313         } else if(_tcsicmp(reg, _T("B'")) == 0) {
314                 B2 = data;
315         } else if(_tcsicmp(reg, _T("C'")) == 0) {
316                 C2 = data;
317         } else if(_tcsicmp(reg, _T("D'")) == 0) {
318                 D2 = data;
319         } else if(_tcsicmp(reg, _T("E'")) == 0) {
320                 E2 = data;
321         } else if(_tcsicmp(reg, _T("H'")) == 0) {
322                 H2 = data;
323         } else if(_tcsicmp(reg, _T("L'")) == 0) {
324                 L2 = data;
325         } else {
326                 return false;
327         }
328         return true;
329 }
330
331 void UPD7810::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
332 {
333 /*
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)
338 */
339         upd7810_state *cpustate = (upd7810_state *)opaque;
340         int wait;
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)"),
343         VA, BC, DE, HL, PSW,
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;
351 }
352
353 // disassembler
354
355 int UPD7810::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
356 {
357         uint8_t oprom[8];
358         uint8_t *opram = oprom;
359         
360         for(int i = 0; i < 8; i++) {
361                 int wait;
362                 oprom[i] = d_mem->read_data8w(pc + i, &wait);
363         }
364         return CPU_DISASSEMBLE_CALL(CPU_MODEL) & DASMFLAG_LENGTHMASK;
365 }
366 #endif
367
368 #define STATE_VERSION   4
369
370 #include "../statesub.h"
371
372 void UPD7810::decl_state_cpustate()
373 {
374         upd7810_state *cpustate = (upd7810_state *)opaque;
375
376         DECL_STATE_ENTRY_PAIR((cpustate->ppc));    /* previous program counter */
377         DECL_STATE_ENTRY_PAIR((cpustate->pc));     /* program counter */
378         DECL_STATE_ENTRY_PAIR((cpustate->sp));     /* stack pointer */
379         DECL_STATE_ENTRY_UINT8((cpustate->op));     /* opcode */
380         DECL_STATE_ENTRY_UINT8((cpustate->op2));    /* opcode part 2 */
381         DECL_STATE_ENTRY_UINT8((cpustate->iff));    /* interrupt enable flip flop */
382         DECL_STATE_ENTRY_UINT8((cpustate->softi));
383         DECL_STATE_ENTRY_UINT8((cpustate->psw));    /* processor status word */
384         DECL_STATE_ENTRY_PAIR((cpustate->ea));     /* extended accumulator */
385         DECL_STATE_ENTRY_PAIR((cpustate->va));     /* accumulator + vector register */
386         DECL_STATE_ENTRY_PAIR((cpustate->bc));     /* 8bit B and C registers / 16bit BC register */
387         DECL_STATE_ENTRY_PAIR((cpustate->de));     /* 8bit D and E registers / 16bit DE register */
388         DECL_STATE_ENTRY_PAIR((cpustate->hl));     /* 8bit H and L registers / 16bit HL register */
389         DECL_STATE_ENTRY_PAIR((cpustate->ea2));    /* alternate register set */
390         DECL_STATE_ENTRY_PAIR((cpustate->va2));
391         DECL_STATE_ENTRY_PAIR((cpustate->bc2));
392         DECL_STATE_ENTRY_PAIR((cpustate->de2));
393         DECL_STATE_ENTRY_PAIR((cpustate->hl2));
394         DECL_STATE_ENTRY_PAIR((cpustate->cnt));    /* 8 bit timer counter */
395         DECL_STATE_ENTRY_PAIR((cpustate->tm));     /* 8 bit timer 0/1 comparator inputs */
396         DECL_STATE_ENTRY_PAIR((cpustate->ecnt));   /* timer counter register / capture register */
397         DECL_STATE_ENTRY_PAIR((cpustate->etm));    /* timer 0/1 comparator inputs */
398         DECL_STATE_ENTRY_UINT8((cpustate->ma));     /* port A input or output mask */
399         DECL_STATE_ENTRY_UINT8((cpustate->mb));     /* port B input or output mask */
400         DECL_STATE_ENTRY_UINT8((cpustate->mcc));    /* port C control/port select */
401         DECL_STATE_ENTRY_UINT8((cpustate->mc));     /* port C input or output mask */
402         DECL_STATE_ENTRY_UINT8((cpustate->mm));     /* memory mapping */
403         DECL_STATE_ENTRY_UINT8((cpustate->mf));     /* port F input or output mask */
404         DECL_STATE_ENTRY_UINT8((cpustate->tmm));    /* timer 0 and timer 1 operating parameters */
405         DECL_STATE_ENTRY_UINT8((cpustate->etmm));   /* 16-bit multifunction timer/event counter */
406         DECL_STATE_ENTRY_UINT8((cpustate->eom));    /* 16-bit timer/event counter output control */
407         DECL_STATE_ENTRY_UINT8((cpustate->sml));    /* serial interface parameters low */
408         DECL_STATE_ENTRY_UINT8((cpustate->smh));    /* -"- high */
409         DECL_STATE_ENTRY_UINT8((cpustate->anm));    /* analog to digital converter operating parameters */
410         DECL_STATE_ENTRY_UINT8((cpustate->mkl));    /* interrupt mask low */
411         DECL_STATE_ENTRY_UINT8((cpustate->mkh));    /* -"- high */
412         DECL_STATE_ENTRY_UINT8((cpustate->zcm));    /* bias circuitry for ac zero-cross detection */
413         DECL_STATE_ENTRY_UINT8((cpustate->pa_in));  /* port A,B,C,D,F inputs */
414         DECL_STATE_ENTRY_UINT8((cpustate->pb_in));
415         DECL_STATE_ENTRY_UINT8((cpustate->pc_in));
416         DECL_STATE_ENTRY_UINT8((cpustate->pd_in));
417         DECL_STATE_ENTRY_UINT8((cpustate->pf_in));
418         DECL_STATE_ENTRY_UINT8((cpustate->pa_out)); /* port A,B,C,D,F outputs */
419         DECL_STATE_ENTRY_UINT8((cpustate->pb_out));
420         DECL_STATE_ENTRY_UINT8((cpustate->pc_out));
421         DECL_STATE_ENTRY_UINT8((cpustate->pd_out));
422         DECL_STATE_ENTRY_UINT8((cpustate->pf_out));
423         DECL_STATE_ENTRY_UINT8((cpustate->cr0));    /* analog digital conversion register 0 */
424         DECL_STATE_ENTRY_UINT8((cpustate->cr1));    /* analog digital conversion register 1 */
425         DECL_STATE_ENTRY_UINT8((cpustate->cr2));    /* analog digital conversion register 2 */
426         DECL_STATE_ENTRY_UINT8((cpustate->cr3));    /* analog digital conversion register 3 */
427         DECL_STATE_ENTRY_UINT8((cpustate->txb));    /* transmitter buffer */
428         DECL_STATE_ENTRY_UINT8((cpustate->rxb));    /* receiver buffer */
429         DECL_STATE_ENTRY_UINT8((cpustate->txd));    /* port C control line states */
430         DECL_STATE_ENTRY_UINT8((cpustate->rxd));
431         DECL_STATE_ENTRY_UINT8((cpustate->sck));
432         DECL_STATE_ENTRY_UINT8((cpustate->ti));
433         DECL_STATE_ENTRY_UINT8((cpustate->to));
434         DECL_STATE_ENTRY_UINT8((cpustate->ci));
435         DECL_STATE_ENTRY_UINT8((cpustate->co0));
436         DECL_STATE_ENTRY_UINT8((cpustate->co1));
437         DECL_STATE_ENTRY_UINT16((cpustate->irr));    /* interrupt request register */
438         DECL_STATE_ENTRY_UINT16((cpustate->itf));    /* interrupt test flag register */
439         DECL_STATE_ENTRY_INT32((cpustate->int1));   /* keep track of current int1 state. Needed for 7801 irq checking. */
440         DECL_STATE_ENTRY_INT32((cpustate->int2));   /* keep track to current int2 state. Needed for 7801 irq checking. */
441
442 /* internal helper variables */
443         DECL_STATE_ENTRY_UINT16((cpustate->txs));    /* transmitter shift register */
444         DECL_STATE_ENTRY_UINT16((cpustate->rxs));    /* receiver shift register */
445         DECL_STATE_ENTRY_UINT8((cpustate->txcnt));  /* transmitter shift register bit count */
446         DECL_STATE_ENTRY_UINT8((cpustate->rxcnt));  /* receiver shift register bit count */
447         DECL_STATE_ENTRY_UINT8((cpustate->txbuf));  /* transmitter buffer was written */
448         DECL_STATE_ENTRY_INT32((cpustate->ovc0));   /* overflow counter for timer 0 ((for clock div 12/384) */
449         DECL_STATE_ENTRY_INT32((cpustate->ovc1));   /* overflow counter for timer 0 (for clock div 12/384) */
450         DECL_STATE_ENTRY_INT32((cpustate->ovce));   /* overflow counter for ecnt */
451         DECL_STATE_ENTRY_INT32((cpustate->ovcf));   /* overflow counter for fixed clock div 3 mode */
452         DECL_STATE_ENTRY_INT32((cpustate->ovcs));   /* overflow counter for serial I/O */
453         DECL_STATE_ENTRY_INT32((cpustate->ovcsio));
454         DECL_STATE_ENTRY_UINT8((cpustate->edges));  /* rising/falling edge flag for serial I/O */
455 //      const struct opcode_s *opXX;    /* opcode table */
456 //      const struct opcode_s *op48;
457 //      const struct opcode_s *op4C;
458 //      const struct opcode_s *op4D;
459 //      const struct opcode_s *op60;
460 //      const struct opcode_s *op64;
461 //      const struct opcode_s *op70;
462 //      const struct opcode_s *op74;
463 //      void (*handle_timers)(upd7810_state *cpustate, int cycles);
464 //      UPD7810_CONFIG config;
465 //      device_irq_acknowledge_callback irq_callback;
466 //      legacy_cpu_device *device;
467 //      DEVICE *program;
468 //      DEVICE *io;
469 //      void *outputs_to;
470 //      void *outputs_txd;
471 //#ifdef USE_DEBUGGER
472 //      EMU *emu;
473 //      DEBUGGER *debugger;
474 //      DEVICE *program_stored;
475 //      DEVICE *io_stored;
476 //#endif
477         DECL_STATE_ENTRY_INT32((cpustate->icount));
478
479 }
480
481 void UPD7810::decl_state()
482 {
483         enter_decl_state(STATE_VERSION);
484
485         decl_state_cpustate();
486 #ifdef USE_DEBUGGER
487         DECL_STATE_ENTRY_UINT64(total_icount);
488 #endif
489         DECL_STATE_ENTRY_INT32(icount);
490         DECL_STATE_ENTRY_BOOL(busreq);
491
492         leave_decl_state();
493 }
494
495 void UPD7810::save_state(FILEIO* state_fio)
496 {
497         if(state_entry != NULL) {
498                 state_entry->save_state(state_fio);
499         }
500
501 //      state_fio->FputUint32(STATE_VERSION);
502 //      state_fio->FputInt32(this_device_id);
503         
504 //      state_fio->Fwrite(opaque, sizeof(upd7810_state), 1);
505 //#ifdef USE_DEBUGGER
506 //      state_fio->FputUint64(total_icount);
507 //#endif
508 //      state_fio->FputInt32(icount);
509 //      state_fio->FputBool(busreq);
510 }
511
512 bool UPD7810::load_state(FILEIO* state_fio)
513 {
514         bool mb = false;
515         if(state_entry != NULL) {
516                 mb = state_entry->load_state(state_fio);
517         }
518         if(!mb) return false;
519
520 //      if(state_fio->FgetUint32() != STATE_VERSION) {
521 //              return false;
522 //      }
523 //      if(state_fio->FgetInt32() != this_device_id) {
524 //              return false;
525 //      }
526 //      state_fio->Fread(opaque, sizeof(upd7810_state), 1);
527 #ifdef USE_DEBUGGER
528         //total_icount = prev_total_icount = state_fio->FgetUint64();
529         prev_total_icount = total_icount;
530 #endif
531         //icount = state_fio->FgetInt32();
532         //busreq = state_fio->FgetBool();
533         
534         // post process
535         upd7810_state *cpustate = (upd7810_state *)opaque;
536         cpustate->program = d_mem;
537         cpustate->io = d_io;
538         cpustate->outputs_to = (void*)&outputs_to;
539         cpustate->outputs_txd = (void*)&outputs_txd;
540 #ifdef USE_DEBUGGER
541         cpustate->emu = emu;
542         cpustate->debugger = d_debugger;
543         cpustate->program_stored = d_mem;
544         cpustate->io_stored = d_io;
545 #endif
546         return true;
547 }