OSDN Git Service

d975e0071966e2d46756e4595febef0aea014f04
[csp-qt/common_source_project-fm7.git] / source / src / vm / i286.cpp
1 /*
2         Skelton for retropc emulator
3
4         Origin : MAME i286 core
5         Author : Takeda.Toshiya
6         Date  : 2012.10.18-
7
8         [ i286 ]
9 */
10
11 #include "i286.h"
12 #ifdef USE_DEBUGGER
13 #include "debugger.h"
14 #endif
15
16 /* ----------------------------------------------------------------------------
17         MAME i286
18 ---------------------------------------------------------------------------- */
19
20 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
21 #pragma warning( disable : 4018 )
22 #pragma warning( disable : 4146 )
23 #pragma warning( disable : 4244 )
24 #pragma warning( disable : 4996 )
25 #endif
26
27 #if defined(HAS_I86)
28         #define CPU_MODEL i8086
29 #elif defined(HAS_I88)
30         #define CPU_MODEL i8088
31 #elif defined(HAS_I186)
32         #define CPU_MODEL i80186
33 #elif defined(HAS_V30)
34         #define CPU_MODEL v30
35 #elif defined(HAS_I286)
36         #define CPU_MODEL i80286
37 #endif
38
39 #ifndef __BIG_ENDIAN__
40 #define LSB_FIRST
41 #endif
42
43 #ifndef INLINE
44 #define INLINE inline
45 #endif
46
47 #define logerror(...)
48
49 /*****************************************************************************/
50 /* src/emu/devcpu.h */
51
52 // CPU interface functions
53 #define CPU_INIT_NAME(name)                     cpu_init_##name
54 #define CPU_INIT(name)                          void* CPU_INIT_NAME(name)()
55 #define CPU_INIT_CALL(name)                     CPU_INIT_NAME(name)()
56
57 #define CPU_RESET_NAME(name)                    cpu_reset_##name
58 #define CPU_RESET(name)                         void CPU_RESET_NAME(name)(cpu_state *cpustate)
59 #define CPU_RESET_CALL(name)                    CPU_RESET_NAME(name)(cpustate)
60
61 #define CPU_EXECUTE_NAME(name)                  cpu_execute_##name
62 #define CPU_EXECUTE(name)                       int CPU_EXECUTE_NAME(name)(cpu_state *cpustate, int icount)
63 #define CPU_EXECUTE_CALL(name)                  CPU_EXECUTE_NAME(name)(cpustate, icount)
64
65 #define CPU_DISASSEMBLE_NAME(name)              cpu_disassemble_##name
66 #define CPU_DISASSEMBLE(name)                   int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom)
67 #define CPU_DISASSEMBLE_CALL(name)              CPU_DISASSEMBLE_NAME(name)(buffer, eip, oprom)
68
69 /*****************************************************************************/
70 /* src/emu/didisasm.h */
71
72 // Disassembler constants
73 const UINT32 DASMFLAG_SUPPORTED     = 0x80000000;   // are disassembly flags supported?
74 const UINT32 DASMFLAG_STEP_OUT      = 0x40000000;   // this instruction should be the end of a step out sequence
75 const UINT32 DASMFLAG_STEP_OVER     = 0x20000000;   // this instruction should be stepped over by setting a breakpoint afterwards
76 const UINT32 DASMFLAG_OVERINSTMASK  = 0x18000000;   // number of extra instructions to skip when stepping over
77 const UINT32 DASMFLAG_OVERINSTSHIFT = 27;           // bits to shift after masking to get the value
78 const UINT32 DASMFLAG_LENGTHMASK    = 0x0000ffff;   // the low 16-bits contain the actual length
79
80 /*****************************************************************************/
81 /* src/emu/diexec.h */
82
83 // I/O line states
84 enum line_state
85 {
86         CLEAR_LINE = 0,                         // clear (a fired or held) line
87         ASSERT_LINE,                            // assert an interrupt immediately
88         HOLD_LINE,                              // hold interrupt line until acknowledged
89         PULSE_LINE                              // pulse interrupt line instantaneously (only for NMI, RESET)
90 };
91
92 enum
93 {
94         INPUT_LINE_IRQ = 0,
95         INPUT_LINE_NMI
96 };
97
98 /*****************************************************************************/
99 /* src/emu/emucore.h */
100
101 // constants for expression endianness
102 enum endianness_t
103 {
104         ENDIANNESS_LITTLE,
105         ENDIANNESS_BIG
106 };
107
108 // declare native endianness to be one or the other
109 #ifdef LSB_FIRST
110 const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE;
111 #else
112 const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG;
113 #endif
114 // endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian
115 #define ENDIAN_VALUE_LE_BE(endian,leval,beval)  (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval))
116 // endian-based value: first value is if native endianness is little-endian, second is if native is big-endian
117 #define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval)  ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval)
118 // endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native
119 #define ENDIAN_VALUE_NE_NNE(endian,leval,beval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval))
120
121 /*****************************************************************************/
122 /* src/emu/memory.h */
123
124 // offsets and addresses are 32-bit (for now...)
125 typedef UINT32  offs_t;
126
127 /*****************************************************************************/
128 /* src/osd/osdcomm.h */
129
130 /* Highly useful macro for compile-time knowledge of an array size */
131 #define ARRAY_LENGTH(x)     (sizeof(x) / sizeof(x[0]))
132
133 #if defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186) || defined(HAS_V30)
134 #define cpu_state i8086_state
135 #include "mame/emu/cpu/i86/i86.c"
136 #elif defined(HAS_I286)
137 #define cpu_state i80286_state
138 #include "mame/emu/cpu/i86/i286.c"
139 #endif
140 #ifdef USE_DEBUGGER
141 #ifdef HAS_V30
142 #include "mame/emu/cpu/nec/necdasm.c"
143 #else
144 #include "mame/emu/cpu/i386/i386dasm.c"
145 #endif
146 #endif
147
148 void I286::initialize()
149 {
150         DEVICE::initialize();
151         opaque = CPU_INIT_CALL(CPU_MODEL);
152         
153         cpu_state *cpustate = (cpu_state *)opaque;
154         cpustate->pic = d_pic;
155         cpustate->program = d_mem;
156         cpustate->io = d_io;
157 #ifdef I86_PSEUDO_BIOS
158         cpustate->bios = d_bios;
159 #endif
160 #ifdef SINGLE_MODE_DMA
161         cpustate->dma = d_dma;
162 #endif
163 #ifdef USE_DEBUGGER
164         cpustate->emu = emu;
165         cpustate->debugger = d_debugger;
166         cpustate->program_stored = d_mem;
167         cpustate->io_stored = d_io;
168         
169         d_debugger->set_context_mem(d_mem);
170         d_debugger->set_context_io(d_io);
171 #endif
172 }
173
174 void I286::release()
175 {
176         free(opaque);
177 }
178
179 void I286::reset()
180 {
181         cpu_state *cpustate = (cpu_state *)opaque;
182         int busreq = cpustate->busreq;
183         
184         CPU_RESET_CALL(CPU_MODEL);
185         
186         cpustate->pic = d_pic;
187         cpustate->program = d_mem;
188         cpustate->io = d_io;
189 #ifdef I86_PSEUDO_BIOS
190         cpustate->bios = d_bios;
191 #endif
192 #ifdef SINGLE_MODE_DMA
193         cpustate->dma = d_dma;
194 #endif
195 #ifdef USE_DEBUGGER
196         cpustate->emu = emu;
197         cpustate->debugger = d_debugger;
198         cpustate->program_stored = d_mem;
199         cpustate->io_stored = d_io;
200 #endif
201         cpustate->busreq = busreq;
202 }
203
204 int I286::run(int icount)
205 {
206         cpu_state *cpustate = (cpu_state *)opaque;
207         return CPU_EXECUTE_CALL(CPU_MODEL);
208 }
209
210 void I286::write_signal(int id, uint32_t data, uint32_t mask)
211 {
212         cpu_state *cpustate = (cpu_state *)opaque;
213         
214         if(id == SIG_CPU_NMI) {
215                 set_irq_line(cpustate, INPUT_LINE_NMI, (data & mask) ? HOLD_LINE : CLEAR_LINE);
216         } else if(id == SIG_CPU_IRQ) {
217                 set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE);
218         } else if(id == SIG_CPU_BUSREQ) {
219                 cpustate->busreq = (data & mask) ? 1 : 0;
220         } else if(id == SIG_I86_TEST) {
221                 cpustate->test_state = (data & mask) ? 1 : 0;
222 #ifdef HAS_I286
223         } else if(id == SIG_I286_A20) {
224                 i80286_set_a20_line(cpustate, data & mask);
225 #endif
226         }
227 }
228
229 void I286::set_intr_line(bool line, bool pending, uint32_t bit)
230 {
231         cpu_state *cpustate = (cpu_state *)opaque;
232         set_irq_line(cpustate, INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE);
233 }
234
235 void I286::set_extra_clock(int icount)
236 {
237         cpu_state *cpustate = (cpu_state *)opaque;
238         cpustate->extra_cycles += icount;
239 }
240
241 int I286::get_extra_clock()
242 {
243         cpu_state *cpustate = (cpu_state *)opaque;
244         return cpustate->extra_cycles;
245 }
246
247 uint32_t I286::get_pc()
248 {
249         cpu_state *cpustate = (cpu_state *)opaque;
250         return cpustate->prevpc;
251 }
252
253 uint32_t I286::get_next_pc()
254 {
255         cpu_state *cpustate = (cpu_state *)opaque;
256         return cpustate->pc;
257 }
258
259 #ifdef USE_DEBUGGER
260 void I286::write_debug_data8(uint32_t addr, uint32_t data)
261 {
262         int wait;
263         d_mem->write_data8w(addr, data, &wait);
264 }
265
266 uint32_t I286::read_debug_data8(uint32_t addr)
267 {
268         int wait;
269         return d_mem->read_data8w(addr, &wait);
270 }
271
272 void I286::write_debug_data16(uint32_t addr, uint32_t data)
273 {
274         int wait;
275         d_mem->write_data16w(addr, data, &wait);
276 }
277
278 uint32_t I286::read_debug_data16(uint32_t addr)
279 {
280         int wait;
281         return d_mem->read_data16w(addr, &wait);
282 }
283
284 void I286::write_debug_io8(uint32_t addr, uint32_t data)
285 {
286         int wait;
287         d_io->write_io8w(addr, data, &wait);
288 }
289
290 uint32_t I286::read_debug_io8(uint32_t addr) {
291         int wait;
292         return d_io->read_io8w(addr, &wait);
293 }
294
295 void I286::write_debug_io16(uint32_t addr, uint32_t data)
296 {
297         int wait;
298         d_io->write_io16w(addr, data, &wait);
299 }
300
301 uint32_t I286::read_debug_io16(uint32_t addr) {
302         int wait;
303         return d_io->read_io16w(addr, &wait);
304 }
305
306 bool I286::write_debug_reg(const _TCHAR *reg, uint32_t data)
307 {
308         cpu_state *cpustate = (cpu_state *)opaque;
309         if(_tcsicmp(reg, _T("IP")) == 0) {
310                 cpustate->pc = ((data & 0xffff) + cpustate->base[CS]) & AMASK;
311                 CHANGE_PC(cpustate->pc);
312         } else if(_tcsicmp(reg, _T("AX")) == 0) {
313                 cpustate->regs.w[AX] = data;
314         } else if(_tcsicmp(reg, _T("BX")) == 0) {
315                 cpustate->regs.w[BX] = data;
316         } else if(_tcsicmp(reg, _T("CX")) == 0) {
317                 cpustate->regs.w[CX] = data;
318         } else if(_tcsicmp(reg, _T("DX")) == 0) {
319                 cpustate->regs.w[DX] = data;
320         } else if(_tcsicmp(reg, _T("SP")) == 0) {
321                 cpustate->regs.w[SP] = data;
322         } else if(_tcsicmp(reg, _T("BP")) == 0) {
323                 cpustate->regs.w[BP] = data;
324         } else if(_tcsicmp(reg, _T("SI")) == 0) {
325                 cpustate->regs.w[SI] = data;
326         } else if(_tcsicmp(reg, _T("DI")) == 0) {
327                 cpustate->regs.w[DI] = data;
328         } else if(_tcsicmp(reg, _T("AL")) == 0) {
329                 cpustate->regs.b[AL] = data;
330         } else if(_tcsicmp(reg, _T("AH")) == 0) {
331                 cpustate->regs.b[AH] = data;
332         } else if(_tcsicmp(reg, _T("BL")) == 0) {
333                 cpustate->regs.b[BL] = data;
334         } else if(_tcsicmp(reg, _T("BH")) == 0) {
335                 cpustate->regs.b[BH] = data;
336         } else if(_tcsicmp(reg, _T("CL")) == 0) {
337                 cpustate->regs.b[CL] = data;
338         } else if(_tcsicmp(reg, _T("CH")) == 0) {
339                 cpustate->regs.b[CH] = data;
340         } else if(_tcsicmp(reg, _T("DL")) == 0) {
341                 cpustate->regs.b[DL] = data;
342         } else if(_tcsicmp(reg, _T("DH")) == 0) {
343                 cpustate->regs.b[DH] = data;
344         } else {
345                 return false;
346         }
347         return true;
348 }
349
350 uint32_t I286::read_debug_reg(const _TCHAR *reg)
351 {
352         cpu_state *cpustate = (cpu_state *)opaque;
353         if(_tcsicmp(reg, _T("IP")) == 0) {
354                 return cpustate->pc - cpustate->base[CS];
355         } else if(_tcsicmp(reg, _T("AX")) == 0) {
356                 return cpustate->regs.w[AX];
357         } else if(_tcsicmp(reg, _T("BX")) == 0) {
358                 return cpustate->regs.w[BX];
359         } else if(_tcsicmp(reg, _T("CX")) == 0) {
360                 return cpustate->regs.w[CX];
361         } else if(_tcsicmp(reg, _T("DX")) == 0) {
362                 return cpustate->regs.w[DX];
363         } else if(_tcsicmp(reg, _T("SP")) == 0) {
364                 return cpustate->regs.w[SP];
365         } else if(_tcsicmp(reg, _T("BP")) == 0) {
366                 return cpustate->regs.w[BP];
367         } else if(_tcsicmp(reg, _T("SI")) == 0) {
368                 return cpustate->regs.w[SI];
369         } else if(_tcsicmp(reg, _T("DI")) == 0) {
370                 return cpustate->regs.w[DI];
371         } else if(_tcsicmp(reg, _T("AL")) == 0) {
372                 return cpustate->regs.b[AL];
373         } else if(_tcsicmp(reg, _T("AH")) == 0) {
374                 return cpustate->regs.b[AH];
375         } else if(_tcsicmp(reg, _T("BL")) == 0) {
376                 return cpustate->regs.b[BL];
377         } else if(_tcsicmp(reg, _T("BH")) == 0) {
378                 return cpustate->regs.b[BH];
379         } else if(_tcsicmp(reg, _T("CL")) == 0) {
380                 return cpustate->regs.b[CL];
381         } else if(_tcsicmp(reg, _T("CH")) == 0) {
382                 return cpustate->regs.b[CH];
383         } else if(_tcsicmp(reg, _T("DL")) == 0) {
384                 return cpustate->regs.b[DL];
385         } else if(_tcsicmp(reg, _T("DH")) == 0) {
386                 return cpustate->regs.b[DH];
387         }
388         return 0;
389 }
390
391 void I286::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
392 {
393         cpu_state *cpustate = (cpu_state *)opaque;
394         my_stprintf_s(buffer, buffer_len,
395         _T("AX=%04X  BX=%04X CX=%04X DX=%04X SP=%04X  BP=%04X  SI=%04X  DI=%04X\nDS=%04X  ES=%04X SS=%04X CS=%04X IP=%04X  FLAG=[%c%c%c%c%c%c%c%c%c]\nClocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"),
396         cpustate->regs.w[AX], cpustate->regs.w[BX], cpustate->regs.w[CX], cpustate->regs.w[DX], cpustate->regs.w[SP], cpustate->regs.w[BP], cpustate->regs.w[SI], cpustate->regs.w[DI],
397         cpustate->sregs[DS], cpustate->sregs[ES], cpustate->sregs[SS], cpustate->sregs[CS], cpustate->pc - cpustate->base[CS],
398         OF ? _T('O') : _T('-'), DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'),
399         SF ? _T('S') : _T('-'), ZF ? _T('Z') : _T('-'), AF ? _T('A') : _T('-'), PF ? _T('P') : _T('-'), CF ? _T('C') : _T('-'),
400         cpustate->total_icount, cpustate->total_icount - cpustate->prev_total_icount,
401         get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame());
402         cpustate->prev_total_icount = cpustate->total_icount;
403 }
404
405 int I286::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
406 {
407         cpu_state *cpustate = (cpu_state *)opaque;
408         UINT64 eip = pc - cpustate->base[CS];
409         UINT8 ops[16];
410         for(int i = 0; i < 16; i++) {
411                 int wait;
412                 ops[i] = d_mem->read_data8w(pc + i, &wait);
413         }
414         UINT8 *oprom = ops;
415         
416 #ifdef HAS_V30
417         return CPU_DISASSEMBLE_CALL(nec_generic) & DASMFLAG_LENGTHMASK;
418 #else
419         return CPU_DISASSEMBLE_CALL(x86_16) & DASMFLAG_LENGTHMASK;
420 #endif
421 }
422 #endif
423
424 #ifdef HAS_I286
425 void I286::set_address_mask(uint32_t mask)
426 {
427         cpu_state *cpustate = (cpu_state *)opaque;
428         cpustate->amask = mask;
429 }
430
431 uint32_t I286::get_address_mask()
432 {
433         cpu_state *cpustate = (cpu_state *)opaque;
434         return cpustate->amask;
435 }
436
437 void I286::set_shutdown_flag(int shutdown)
438 {
439         cpu_state *cpustate = (cpu_state *)opaque;
440         cpustate->shutdown = shutdown;
441 }
442
443 int I286::get_shutdown_flag()
444 {
445         cpu_state *cpustate = (cpu_state *)opaque;
446         return cpustate->shutdown;
447 }
448 #endif
449
450 typedef struct i286_dtr_1_t{
451         UINT32 base;
452         UINT16 limit;
453 };
454 typedef struct i286_dtr_2_t{
455         UINT16 sel;
456         UINT32 base;
457         UINT16 limit;
458         UINT8 rights;
459 };
460
461 #if 0
462 #include "../statesub.h"
463
464
465 void I286::decl_state_cpustate()
466 {
467 #if defined(HAS_I286)
468         struct i80286_state *state = (i80286_state *)opaque;
469         //state_fio->Fwrite(&(state->regs), sizeof(i80286basicregs), 1);
470         for(int i = 0; i < 8; i++) {
471                 DECL_STATE_ENTRY_UINT16_MEMBER((state->regs.w[i]), i);
472         }
473         DECL_STATE_ENTRY_UINT32((state->amask));
474         DECL_STATE_ENTRY_UINT32((state->pc));
475         DECL_STATE_ENTRY_UINT32((state->prevpc));
476         DECL_STATE_ENTRY_UINT16((state->flags));
477         DECL_STATE_ENTRY_UINT16((state->msw));
478         DECL_STATE_ENTRY_1D_ARRAY((state->base), 4);
479         DECL_STATE_ENTRY_1D_ARRAY((state->sregs), 4);
480         DECL_STATE_ENTRY_1D_ARRAY((state->limit), 4);
481         DECL_STATE_ENTRY_1D_ARRAY((state->rights), 4);
482         DECL_STATE_ENTRY_1D_ARRAY((state->valid), 4);
483         
484         DECL_STATE_ENTRY_UINT32((state->gdtr.base));
485         DECL_STATE_ENTRY_UINT16((state->gdtr.limit));
486
487         DECL_STATE_ENTRY_UINT32((state->idtr.base));
488         DECL_STATE_ENTRY_UINT16((state->idtr.limit));
489         
490         DECL_STATE_ENTRY_UINT16((state->ldtr.sel));
491         DECL_STATE_ENTRY_UINT32((state->ldtr.base));
492         DECL_STATE_ENTRY_UINT32((state->ldtr.limit));
493         DECL_STATE_ENTRY_UINT32((state->ldtr.rights));
494
495         DECL_STATE_ENTRY_UINT16((state->tr.sel));
496         DECL_STATE_ENTRY_UINT32((state->tr.base));
497         DECL_STATE_ENTRY_UINT32((state->tr.limit));
498         DECL_STATE_ENTRY_UINT32((state->tr.rights));
499
500         DECL_STATE_ENTRY_INT32((state->AuxVal));
501         DECL_STATE_ENTRY_INT32((state->OverVal));
502         DECL_STATE_ENTRY_INT32((state->SignVal));
503         DECL_STATE_ENTRY_INT32((state->ZeroVal));
504         DECL_STATE_ENTRY_INT32((state->CarryVal));
505         DECL_STATE_ENTRY_INT32((state->DirVal));
506         
507         DECL_STATE_ENTRY_UINT8((state->ParityVal));
508         DECL_STATE_ENTRY_UINT8((state->TF));
509         DECL_STATE_ENTRY_UINT8((state->IF));
510         DECL_STATE_ENTRY_UINT8((state->MF));
511         DECL_STATE_ENTRY_INT8((state->nmi_state));
512         DECL_STATE_ENTRY_INT8((state->irq_state));
513         DECL_STATE_ENTRY_INT8((state->test_state));
514         
515         DECL_STATE_ENTRY_UINT8((state->rep_in_progress));       
516         DECL_STATE_ENTRY_INT32((state->extra_cycles));
517         
518         DECL_STATE_ENTRY_INT32((state->halted));
519         DECL_STATE_ENTRY_INT32((state->busreq));
520         DECL_STATE_ENTRY_INT32((state->trap_level));
521         DECL_STATE_ENTRY_INT32((state->shutdown));
522         DECL_STATE_ENTRY_INT32((state->icount));
523
524         DECL_STATE_ENTRY_UINT8((state->seg_prefix));
525         DECL_STATE_ENTRY_UINT8((state->prefix_seg));
526         
527         DECL_STATE_ENTRY_UINT32((state->ea));
528         DECL_STATE_ENTRY_UINT16((state->eo));
529         DECL_STATE_ENTRY_UINT8((state->ea_seg));
530
531 #  ifdef USE_DEBUGGER
532         DECL_STATE_ENTRY_UINT64((state->total_icount));
533 #  endif
534 #else // not I286
535
536         struct i8086_state *state = (i8086_state *)opaque;
537         for(int i = 0; i < 8; i++) {
538                 DECL_STATE_ENTRY_UINT16_MEMBER((state->regs.w[i]), i);
539         }
540
541         DECL_STATE_ENTRY_UINT32((state->pc));
542         DECL_STATE_ENTRY_UINT32((state->prevpc));
543         DECL_STATE_ENTRY_1D_ARRAY((state->base), 4);
544         DECL_STATE_ENTRY_1D_ARRAY((state->sregs), 4);
545         
546         DECL_STATE_ENTRY_UINT16((state->flags));
547
548         DECL_STATE_ENTRY_INT32((state->AuxVal));
549         DECL_STATE_ENTRY_INT32((state->OverVal));
550         DECL_STATE_ENTRY_INT32((state->SignVal));
551         DECL_STATE_ENTRY_INT32((state->ZeroVal));
552         DECL_STATE_ENTRY_INT32((state->CarryVal));
553         DECL_STATE_ENTRY_INT32((state->DirVal));
554         
555         DECL_STATE_ENTRY_UINT8((state->ParityVal));
556         DECL_STATE_ENTRY_UINT8((state->TF));
557         DECL_STATE_ENTRY_UINT8((state->IF));
558         DECL_STATE_ENTRY_UINT8((state->MF));
559         
560         DECL_STATE_ENTRY_UINT8((state->int_vector));
561
562         DECL_STATE_ENTRY_INT8((state->nmi_state));
563         DECL_STATE_ENTRY_INT8((state->irq_state));
564         DECL_STATE_ENTRY_INT8((state->test_state));
565         
566         DECL_STATE_ENTRY_UINT8((state->rep_in_progress));       
567         DECL_STATE_ENTRY_INT32((state->extra_cycles));
568         
569         DECL_STATE_ENTRY_INT32((state->halted));
570         DECL_STATE_ENTRY_INT32((state->busreq));
571
572         DECL_STATE_ENTRY_UINT16((state->ip));
573         DECL_STATE_ENTRY_UINT32((state->sp));
574         
575         DECL_STATE_ENTRY_INT32((state->icount));
576
577         DECL_STATE_ENTRY_UINT8((state->seg_prefix));
578         DECL_STATE_ENTRY_UINT8((state->prefix_seg));
579         
580         DECL_STATE_ENTRY_UINT32((state->ea));
581         DECL_STATE_ENTRY_UINT16((state->eo));
582         DECL_STATE_ENTRY_UINT8((state->ea_seg));
583         
584 #  ifdef USE_DEBUGGER
585         DECL_STATE_ENTRY_UINT64((state->total_icount));
586 #  endif
587 #endif
588 }
589 #endif
590
591 void I286::save_state_cpustate(FILEIO* state_fio)
592 {
593 #if defined(HAS_I286)
594         struct i80286_state *state = (i80286_state *)opaque;
595         state_fio->Fwrite(&(state->regs), sizeof(i80286basicregs), 1);
596         state_fio->Fwrite(&(state->amask), sizeof(UINT32), 1);
597         state_fio->Fwrite(&(state->pc), sizeof(UINT32), 1);
598         state_fio->Fwrite(&(state->prevpc), sizeof(UINT32), 1);
599         state_fio->Fwrite(&(state->flags), sizeof(UINT16), 1);
600         state_fio->Fwrite(&(state->msw), sizeof(UINT16), 1);
601         
602         state_fio->Fwrite(&(state->base[0]), sizeof(UINT32) * 4, 1);
603         state_fio->Fwrite(&(state->sregs[0]), sizeof(UINT16) * 4, 1);
604         
605         state_fio->Fwrite(&(state->limit[0]), sizeof(UINT16) * 4, 1);
606         state_fio->Fwrite(&(state->rights[0]), sizeof(UINT8) * 4, 1);
607         
608         state_fio->Fwrite(&(state->valid), sizeof(bool) * 4, 1);
609         
610         state_fio->Fwrite(&(state->gdtr), sizeof(i286_dtr_1_t), 1);
611         state_fio->Fwrite(&(state->idtr), sizeof(i286_dtr_1_t), 1);
612         state_fio->Fwrite(&(state->ldtr), sizeof(i286_dtr_2_t), 1);
613         state_fio->Fwrite(&(state->tr), sizeof(i286_dtr_2_t), 1);
614         
615         state_fio->Fwrite(&(state->pic), sizeof(DEVICE *), 1);
616         state_fio->Fwrite(&(state->program), sizeof(DEVICE *), 1);
617         state_fio->Fwrite(&(state->io), sizeof(DEVICE *), 1);
618 #ifdef I86_PSEUDO_BIOS
619         state_fio->Fwrite(&(state->bios), sizeof(DEVICE *), 1);
620 #endif
621 #ifdef SINGLE_MODE_DMA
622         state_fio->Fwrite(&(state->dma), sizeof(DEVICE *), 1);
623 #endif
624 #ifdef USE_DEBUGGER
625         state_fio->Fwrite(&(state->emu), sizeof(EMU *), 1);
626         state_fio->Fwrite(&(state->debugger), sizeof(DEBUGGER *), 1);
627         state_fio->Fwrite(&(state->program_stored), sizeof(DEVICE *), 1);
628         state_fio->Fwrite(&(state->io_stored), sizeof(DEVICE *), 1);
629 #endif
630         //INT32   AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */
631         state_fio->Fwrite(&(state->AuxVal), sizeof(INT32) * 6, 1);
632         //UINT8   ParityVal;
633         //UINT8   TF, IF;     /* 0 or 1 valued flags */
634         //UINT8   MF;         /* V30 mode flag */
635         state_fio->Fwrite(&(state->ParityVal), sizeof(UINT8) * 4, 1);
636         //INT8    nmi_state;
637         //INT8    irq_state;
638         //INT8    test_state;
639         state_fio->Fwrite(&(state->nmi_state), sizeof(INT8) * 3, 1);
640         //UINT8 rep_in_progress;
641         state_fio->Fwrite(&(state->rep_in_progress), sizeof(UINT8) * 1, 1);
642         //INT32   extra_cycles;       /* extra cycles for interrupts */
643         state_fio->Fwrite(&(state->extra_cycles), sizeof(INT32) * 1, 1);
644         //int halted;         /* Is the CPU halted ? */
645         //int busreq;
646         //int trap_level;
647         //int shutdown;
648         //int icount;
649         state_fio->Fwrite(&(state->halted), sizeof(int) * 5, 1);
650         state_fio->Fwrite(&(state->seg_prefix), sizeof(char) * 1, 1);
651         state_fio->Fwrite(&(state->prefix_seg), sizeof(UINT8) * 1, 1);
652         state_fio->Fwrite(&(state->ea), sizeof(unsigned), 1);
653         state_fio->Fwrite(&(state->eo), sizeof(UINT16), 1);
654         state_fio->Fwrite(&(state->ea_seg), sizeof(UINT8), 1);
655
656 #else // not I286
657
658         struct i8086_state *state = (i8086_state *)opaque;
659         state_fio->Fwrite(&(state->regs), sizeof(i8086basicregs), 1);
660         state_fio->Fwrite(&(state->pc), sizeof(UINT32), 1);
661         state_fio->Fwrite(&(state->prevpc), sizeof(UINT32), 1);
662         state_fio->Fwrite(&(state->base[0]), sizeof(UINT32) * 4, 1);
663         state_fio->Fwrite(&(state->sregs[0]), sizeof(UINT16) * 4, 1);
664         
665         state_fio->Fwrite(&(state->flags), sizeof(UINT16), 1);
666
667         //INT32   AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */
668         state_fio->Fwrite(&(state->AuxVal), sizeof(INT32) * 6, 1);
669         //UINT8   ParityVal;
670         //UINT8   TF, IF;     /* 0 or 1 valued flags */
671         //UINT8   MF;         /* V30 mode flag */
672         state_fio->Fwrite(&(state->ParityVal), sizeof(UINT8) * 4, 1);
673         state_fio->Fwrite(&(state->int_vector), sizeof(UINT8), 1);
674         //INT8    nmi_state;
675         //INT8    irq_state;
676         //INT8    test_state;
677         state_fio->Fwrite(&(state->nmi_state), sizeof(INT8) * 3, 1);
678         //UINT8 rep_in_progress;
679         state_fio->Fwrite(&(state->rep_in_progress), sizeof(UINT8) * 1, 1);
680         //INT32   extra_cycles;       /* extra cycles for interrupts */
681         state_fio->Fwrite(&(state->extra_cycles), sizeof(INT32) * 1, 1);
682         //int halted;         /* Is the CPU halted ? */
683         //int busreq;
684         state_fio->Fwrite(&(state->halted), sizeof(int) * 2, 1);
685
686         state_fio->Fwrite(&(state->ip), sizeof(UINT16) * 1, 1);
687         state_fio->Fwrite(&(state->sp), sizeof(UINT32) * 1, 1);
688         
689         state_fio->Fwrite(&(state->pic), sizeof(DEVICE *), 1);
690         state_fio->Fwrite(&(state->program), sizeof(DEVICE *), 1);
691         state_fio->Fwrite(&(state->io), sizeof(DEVICE *), 1);
692 #ifdef I86_PSEUDO_BIOS
693         state_fio->Fwrite(&(state->bios), sizeof(DEVICE *), 1);
694 #endif
695 #ifdef SINGLE_MODE_DMA
696         state_fio->Fwrite(&(state->dma), sizeof(DEVICE *), 1);
697 #endif
698 #ifdef USE_DEBUGGER
699         state_fio->Fwrite(&(state->emu), sizeof(EMU *), 1);
700         state_fio->Fwrite(&(state->debugger), sizeof(DEBUGGER *), 1);
701         state_fio->Fwrite(&(state->program_stored), sizeof(DEVICE *), 1);
702         state_fio->Fwrite(&(state->io_stored), sizeof(DEVICE *), 1);
703 #endif
704         state_fio->Fwrite(&(state->icount), sizeof(int) * 1, 1);
705         state_fio->Fwrite(&(state->seg_prefix), sizeof(char) * 1, 1);
706         state_fio->Fwrite(&(state->prefix_seg), sizeof(UINT8) * 1, 1);
707         state_fio->Fwrite(&(state->ea), sizeof(unsigned), 1);
708         state_fio->Fwrite(&(state->eo), sizeof(UINT16), 1);
709         state_fio->Fwrite(&(state->ea_seg), sizeof(UINT8), 1);
710 #endif
711 }
712
713 void I286::load_state_cpustate(FILEIO* state_fio)
714 {
715 #if defined(HAS_I286)
716         struct i80286_state *state = (i80286_state *)opaque;
717         state_fio->Fread(&(state->regs), sizeof(i80286basicregs), 1);
718         state_fio->Fread(&(state->amask), sizeof(UINT32), 1);
719         state_fio->Fread(&(state->pc), sizeof(UINT32), 1);
720         state_fio->Fread(&(state->prevpc), sizeof(UINT32), 1);
721         state_fio->Fread(&(state->flags), sizeof(UINT16), 1);
722         state_fio->Fread(&(state->msw), sizeof(UINT16), 1);
723         
724         state_fio->Fread(&(state->base[0]), sizeof(UINT32) * 4, 1);
725         state_fio->Fread(&(state->sregs[0]), sizeof(UINT16) * 4, 1);
726         
727         state_fio->Fread(&(state->limit[0]), sizeof(UINT16) * 4, 1);
728         state_fio->Fread(&(state->rights[0]), sizeof(UINT8) * 4, 1);
729         
730         state_fio->Fread(&(state->valid), sizeof(bool) * 4, 1);
731         
732         state_fio->Fread(&(state->gdtr), sizeof(i286_dtr_1_t), 1);
733         state_fio->Fread(&(state->idtr), sizeof(i286_dtr_1_t), 1);
734         state_fio->Fread(&(state->ldtr), sizeof(i286_dtr_2_t), 1);
735         state_fio->Fread(&(state->tr), sizeof(i286_dtr_2_t), 1);
736         
737         state_fio->Fread(&(state->pic), sizeof(DEVICE *), 1);
738         state_fio->Fread(&(state->program), sizeof(DEVICE *), 1);
739         state_fio->Fread(&(state->io), sizeof(DEVICE *), 1);
740 #ifdef I86_PSEUDO_BIOS
741         state_fio->Fread(&(state->bios), sizeof(DEVICE *), 1);
742 #endif
743 #ifdef SINGLE_MODE_DMA
744         state_fio->Fread(&(state->dma), sizeof(DEVICE *), 1);
745 #endif
746 #ifdef USE_DEBUGGER
747         state_fio->Fread(&(state->emu), sizeof(EMU *), 1);
748         state_fio->Fread(&(state->debugger), sizeof(DEBUGGER *), 1);
749         state_fio->Fread(&(state->program_stored), sizeof(DEVICE *), 1);
750         state_fio->Fread(&(state->io_stored), sizeof(DEVICE *), 1);
751 #endif
752         //INT32   AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */
753         state_fio->Fread(&(state->AuxVal), sizeof(INT32) * 6, 1);
754         //UINT8   ParityVal;
755         //UINT8   TF, IF;     /* 0 or 1 valued flags */
756         //UINT8   MF;         /* V30 mode flag */
757         state_fio->Fread(&(state->ParityVal), sizeof(UINT8) * 4, 1);
758         //INT8    nmi_state;
759         //INT8    irq_state;
760         //INT8    test_state;
761         state_fio->Fread(&(state->nmi_state), sizeof(INT8) * 3, 1);
762         //UINT8 rep_in_progress;
763         state_fio->Fread(&(state->rep_in_progress), sizeof(UINT8) * 1, 1);
764         //INT32   extra_cycles;       /* extra cycles for interrupts */
765         state_fio->Fread(&(state->extra_cycles), sizeof(INT32) * 1, 1);
766         //int halted;         /* Is the CPU halted ? */
767         //int busreq;
768         //int trap_level;
769         //int shutdown;
770         //int icount;
771         state_fio->Fread(&(state->halted), sizeof(int) * 5, 1);
772         state_fio->Fread(&(state->seg_prefix), sizeof(char) * 1, 1);
773         state_fio->Fread(&(state->prefix_seg), sizeof(UINT8) * 1, 1);
774         state_fio->Fread(&(state->ea), sizeof(unsigned), 1);
775         state_fio->Fread(&(state->eo), sizeof(UINT16), 1);
776         state_fio->Fread(&(state->ea_seg), sizeof(UINT8), 1);
777
778 #else // not I286
779
780         struct i8086_state *state = (i8086_state *)opaque;
781         state_fio->Fread(&(state->regs), sizeof(i8086basicregs), 1);
782         state_fio->Fread(&(state->pc), sizeof(UINT32), 1);
783         state_fio->Fread(&(state->prevpc), sizeof(UINT32), 1);
784         state_fio->Fread(&(state->base[0]), sizeof(UINT32) * 4, 1);
785         state_fio->Fread(&(state->sregs[0]), sizeof(UINT16) * 4, 1);
786         
787         state_fio->Fread(&(state->flags), sizeof(UINT16), 1);
788
789         //INT32   AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */
790         state_fio->Fread(&(state->AuxVal), sizeof(INT32) * 6, 1);
791         //UINT8   ParityVal;
792         //UINT8   TF, IF;     /* 0 or 1 valued flags */
793         //UINT8   MF;         /* V30 mode flag */
794         state_fio->Fread(&(state->ParityVal), sizeof(UINT8) * 4, 1);
795         state_fio->Fread(&(state->int_vector), sizeof(UINT8), 1);
796         //INT8    nmi_state;
797         //INT8    irq_state;
798         //INT8    test_state;
799         state_fio->Fread(&(state->nmi_state), sizeof(INT8) * 3, 1);
800         //UINT8 rep_in_progress;
801         state_fio->Fread(&(state->rep_in_progress), sizeof(UINT8) * 1, 1);
802         //INT32   extra_cycles;       /* extra cycles for interrupts */
803         state_fio->Fread(&(state->extra_cycles), sizeof(INT32) * 1, 1);
804         //int halted;         /* Is the CPU halted ? */
805         //int busreq;
806         state_fio->Fread(&(state->halted), sizeof(int) * 2, 1);
807
808         state_fio->Fread(&(state->ip), sizeof(UINT16) * 1, 1);
809         state_fio->Fread(&(state->sp), sizeof(UINT32) * 1, 1);
810         
811         state_fio->Fread(&(state->pic), sizeof(DEVICE *), 1);
812         state_fio->Fread(&(state->program), sizeof(DEVICE *), 1);
813         state_fio->Fread(&(state->io), sizeof(DEVICE *), 1);
814 #ifdef I86_PSEUDO_BIOS
815         state_fio->Fread(&(state->bios), sizeof(DEVICE *), 1);
816 #endif
817 #ifdef SINGLE_MODE_DMA
818         state_fio->Fread(&(state->dma), sizeof(DEVICE *), 1);
819 #endif
820 #ifdef USE_DEBUGGER
821         state_fio->Fread(&(state->emu), sizeof(EMU *), 1);
822         state_fio->Fread(&(state->debugger), sizeof(DEBUGGER *), 1);
823         state_fio->Fread(&(state->program_stored), sizeof(DEVICE *), 1);
824         state_fio->Fread(&(state->io_stored), sizeof(DEVICE *), 1);
825 #endif
826         state_fio->Fread(&(state->icount), sizeof(int) * 1, 1);
827         state_fio->Fread(&(state->seg_prefix), sizeof(char) * 1, 1);
828         state_fio->Fread(&(state->prefix_seg), sizeof(UINT8) * 1, 1);
829         state_fio->Fread(&(state->ea), sizeof(unsigned), 1);
830         state_fio->Fread(&(state->eo), sizeof(UINT16), 1);
831         state_fio->Fread(&(state->ea_seg), sizeof(UINT8), 1);
832 #endif
833 }
834
835
836 #define STATE_VERSION   4
837
838 bool I286::process_state(FILEIO* state_fio, bool loading)
839 {
840         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
841                 return false;
842         }
843         if(!state_fio->StateCheckInt32(this_device_id)) {
844                 return false;
845         }
846         state_fio->StateBuffer(opaque, sizeof(cpu_state), 1);
847         
848         // post process
849         if(loading) {
850                 cpu_state *cpustate = (cpu_state *)opaque;
851                 cpustate->pic = d_pic;
852                 cpustate->program = d_mem;
853                 cpustate->io = d_io;
854 #ifdef I86_PSEUDO_BIOS
855                 cpustate->bios = d_bios;
856 #endif
857 #ifdef SINGLE_MODE_DMA
858                 cpustate->dma = d_dma;
859 #endif
860 #ifdef USE_DEBUGGER
861                 cpustate->emu = emu;
862                 cpustate->debugger = d_debugger;
863                 cpustate->program_stored = d_mem;
864                 cpustate->io_stored = d_io;
865                 cpustate->prev_total_icount = cpustate->total_icount;
866 #endif
867         }
868         return true;
869 }