2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
14 #include "../fileio.h"
16 /* ----------------------------------------------------------------------------
18 ---------------------------------------------------------------------------- */
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 )
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_I286)
34 #define CPU_MODEL i80286
37 #ifndef __BIG_ENDIAN__
47 /*****************************************************************************/
48 /* src/emu/devcpu.h */
50 // CPU interface functions
51 #define CPU_INIT_NAME(name) cpu_init_##name
52 #define CPU_INIT(name) void* CPU_INIT_NAME(name)()
53 #define CPU_INIT_CALL(name) CPU_INIT_NAME(name)()
55 #define CPU_RESET_NAME(name) cpu_reset_##name
56 #define CPU_RESET(name) void CPU_RESET_NAME(name)(cpu_state *cpustate)
57 #define CPU_RESET_CALL(name) CPU_RESET_NAME(name)(cpustate)
59 #define CPU_EXECUTE_NAME(name) cpu_execute_##name
60 #define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(cpu_state *cpustate, int icount)
61 #define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate, icount)
63 #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name
64 #define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(char *buffer, offs_t eip, const UINT8 *oprom)
65 #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, eip, oprom)
67 /*****************************************************************************/
68 /* src/emu/didisasm.h */
70 // Disassembler constants
71 const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported?
72 const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence
73 const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards
74 const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over
75 const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value
76 const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length
78 /*****************************************************************************/
79 /* src/emu/diexec.h */
84 CLEAR_LINE = 0, // clear (a fired or held) line
85 ASSERT_LINE, // assert an interrupt immediately
86 HOLD_LINE, // hold interrupt line until acknowledged
87 PULSE_LINE // pulse interrupt line instantaneously (only for NMI, RESET)
96 /*****************************************************************************/
97 /* src/emu/emucore.h */
99 // constants for expression endianness
106 // declare native endianness to be one or the other
108 const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE;
110 const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG;
112 // endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian
113 #define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval))
114 // endian-based value: first value is if native endianness is little-endian, second is if native is big-endian
115 #define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval)
116 // endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native
117 #define ENDIAN_VALUE_NE_NNE(endian,leval,beval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval))
119 /*****************************************************************************/
120 /* src/emu/memory.h */
122 // offsets and addresses are 32-bit (for now...)
123 typedef UINT32 offs_t;
125 /*****************************************************************************/
126 /* src/osd/osdcomm.h */
128 /* Highly useful macro for compile-time knowledge of an array size */
129 #define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))
131 #if defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186)
132 #define cpu_state i8086_state
133 #include "mame/emu/cpu/i86/i86.c"
134 #elif defined(HAS_I286)
135 #define cpu_state i80286_state
136 #include "mame/emu/cpu/i86/i286.c"
139 #include "mame/emu/cpu/i386/i386dasm.c"
142 void I286::initialize()
144 opaque = CPU_INIT_CALL(CPU_MODEL);
146 cpu_state *cpustate = (cpu_state *)opaque;
147 cpustate->pic = d_pic;
148 cpustate->program = d_mem;
151 cpustate->bios = d_bios;
153 #ifdef SINGLE_MODE_DMA
154 cpustate->dma = d_dma;
158 cpustate->debugger = d_debugger;
159 cpustate->program_stored = d_mem;
160 cpustate->io_stored = d_io;
162 d_debugger->set_context_mem(d_mem);
163 d_debugger->set_context_io(d_io);
174 cpu_state *cpustate = (cpu_state *)opaque;
175 int busreq = cpustate->busreq;
177 CPU_RESET_CALL(CPU_MODEL);
179 cpustate->pic = d_pic;
180 cpustate->program = d_mem;
183 cpustate->bios = d_bios;
185 #ifdef SINGLE_MODE_DMA
186 cpustate->dma = d_dma;
190 cpustate->debugger = d_debugger;
191 cpustate->program_stored = d_mem;
192 cpustate->io_stored = d_io;
194 cpustate->busreq = busreq;
197 int I286::run(int icount)
199 cpu_state *cpustate = (cpu_state *)opaque;
200 return CPU_EXECUTE_CALL(CPU_MODEL);
203 void I286::write_signal(int id, uint32 data, uint32 mask)
205 cpu_state *cpustate = (cpu_state *)opaque;
207 if(id == SIG_CPU_NMI) {
208 set_irq_line(cpustate, INPUT_LINE_NMI, (data & mask) ? HOLD_LINE : CLEAR_LINE);
209 } else if(id == SIG_CPU_IRQ) {
210 set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE);
211 } else if(id == SIG_CPU_BUSREQ) {
212 cpustate->busreq = (data & mask) ? 1 : 0;
213 } else if(id == SIG_I86_TEST) {
214 cpustate->test_state = (data & mask) ? 1 : 0;
216 } else if(id == SIG_I86_A20) {
217 i80286_set_a20_line(cpustate, data & mask);
222 void I286::set_intr_line(bool line, bool pending, uint32 bit)
224 cpu_state *cpustate = (cpu_state *)opaque;
225 set_irq_line(cpustate, INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE);
228 void I286::set_extra_clock(int icount)
230 cpu_state *cpustate = (cpu_state *)opaque;
231 cpustate->extra_cycles += icount;
234 int I286::get_extra_clock()
236 cpu_state *cpustate = (cpu_state *)opaque;
237 return cpustate->extra_cycles;
240 uint32 I286::get_pc()
242 cpu_state *cpustate = (cpu_state *)opaque;
243 return cpustate->prevpc;
246 uint32 I286::get_next_pc()
248 cpu_state *cpustate = (cpu_state *)opaque;
253 void I286::debug_write_data8(uint32 addr, uint32 data)
256 d_mem->write_data8w(addr, data, &wait);
259 uint32 I286::debug_read_data8(uint32 addr)
262 return d_mem->read_data8w(addr, &wait);
265 void I286::debug_write_data16(uint32 addr, uint32 data)
268 d_mem->write_data16w(addr, data, &wait);
271 uint32 I286::debug_read_data16(uint32 addr)
274 return d_mem->read_data16w(addr, &wait);
277 void I286::debug_write_io8(uint32 addr, uint32 data)
280 d_io->write_io8w(addr, data, &wait);
283 uint32 I286::debug_read_io8(uint32 addr) {
285 return d_io->read_io8w(addr, &wait);
288 void I286::debug_write_io16(uint32 addr, uint32 data)
291 d_io->write_io16w(addr, data, &wait);
294 uint32 I286::debug_read_io16(uint32 addr) {
296 return d_io->read_io16w(addr, &wait);
299 bool I286::debug_write_reg(_TCHAR *reg, uint32 data)
301 cpu_state *cpustate = (cpu_state *)opaque;
302 if(_tcsicmp(reg, _T("IP")) == 0) {
303 cpustate->pc = ((data & 0xffff) + cpustate->base[CS]) & AMASK;
304 CHANGE_PC(cpustate->pc);
305 } else if(_tcsicmp(reg, _T("AX")) == 0) {
306 cpustate->regs.w[AX] = data;
307 } else if(_tcsicmp(reg, _T("BX")) == 0) {
308 cpustate->regs.w[BX] = data;
309 } else if(_tcsicmp(reg, _T("CX")) == 0) {
310 cpustate->regs.w[CX] = data;
311 } else if(_tcsicmp(reg, _T("DX")) == 0) {
312 cpustate->regs.w[DX] = data;
313 } else if(_tcsicmp(reg, _T("SP")) == 0) {
314 cpustate->regs.w[SP] = data;
315 } else if(_tcsicmp(reg, _T("BP")) == 0) {
316 cpustate->regs.w[BP] = data;
317 } else if(_tcsicmp(reg, _T("SI")) == 0) {
318 cpustate->regs.w[SI] = data;
319 } else if(_tcsicmp(reg, _T("DI")) == 0) {
320 cpustate->regs.w[DI] = data;
321 } else if(_tcsicmp(reg, _T("AL")) == 0) {
322 cpustate->regs.b[AL] = data;
323 } else if(_tcsicmp(reg, _T("AH")) == 0) {
324 cpustate->regs.b[AH] = data;
325 } else if(_tcsicmp(reg, _T("BL")) == 0) {
326 cpustate->regs.b[BL] = data;
327 } else if(_tcsicmp(reg, _T("BH")) == 0) {
328 cpustate->regs.b[BH] = data;
329 } else if(_tcsicmp(reg, _T("CL")) == 0) {
330 cpustate->regs.b[CL] = data;
331 } else if(_tcsicmp(reg, _T("CH")) == 0) {
332 cpustate->regs.b[CH] = data;
333 } else if(_tcsicmp(reg, _T("DL")) == 0) {
334 cpustate->regs.b[DL] = data;
335 } else if(_tcsicmp(reg, _T("DH")) == 0) {
336 cpustate->regs.b[DH] = data;
343 void I286::debug_regs_info(_TCHAR *buffer, size_t buffer_len)
345 cpu_state *cpustate = (cpu_state *)opaque;
346 _stprintf_s(buffer, buffer_len,
347 _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]"),
348 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],
349 cpustate->sregs[DS], cpustate->sregs[ES], cpustate->sregs[SS], cpustate->sregs[CS], cpustate->pc - cpustate->base[CS],
350 OF ? _T('O') : _T('-'), DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'),
351 SF ? _T('S') : _T('-'), ZF ? _T('Z') : _T('-'), AF ? _T('A') : _T('-'), PF ? _T('P') : _T('-'), CF ? _T('C') : _T('-'));
354 int I286::debug_dasm(uint32 pc, _TCHAR *buffer, size_t buffer_len)
356 cpu_state *cpustate = (cpu_state *)opaque;
357 UINT64 eip = pc - cpustate->base[CS];
359 for(int i = 0; i < 16; i++) {
361 ops[i] = d_mem->read_data8w(pc + i, &wait);
365 return CPU_DISASSEMBLE_CALL(x86_16) & DASMFLAG_LENGTHMASK;
370 void I286::set_address_mask(uint32 mask)
372 cpu_state *cpustate = (cpu_state *)opaque;
373 cpustate->amask = mask;
376 uint32 I286::get_address_mask()
378 cpu_state *cpustate = (cpu_state *)opaque;
379 return cpustate->amask;
382 void I286::set_shutdown_flag(int shutdown)
384 cpu_state *cpustate = (cpu_state *)opaque;
385 cpustate->shutdown = shutdown;
388 int I286::get_shutdown_flag()
390 cpu_state *cpustate = (cpu_state *)opaque;
391 return cpustate->shutdown;
395 #define STATE_VERSION 1
397 void I286::save_state(FILEIO* state_fio)
399 state_fio->FputUint32(STATE_VERSION);
400 state_fio->FputInt32(this_device_id);
402 state_fio->Fwrite(opaque, sizeof(cpu_state), 1);
405 bool I286::load_state(FILEIO* state_fio)
407 if(state_fio->FgetUint32() != STATE_VERSION) {
410 if(state_fio->FgetInt32() != this_device_id) {
413 state_fio->Fread(opaque, sizeof(cpu_state), 1);
416 cpu_state *cpustate = (cpu_state *)opaque;
417 cpustate->pic = d_pic;
418 cpustate->program = d_mem;
421 cpustate->bios = d_bios;
423 #ifdef SINGLE_MODE_DMA
424 cpustate->dma = d_dma;
428 cpustate->debugger = d_debugger;
429 cpustate->program_stored = d_mem;
430 cpustate->io_stored = d_io;