summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/i86/i86.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/i86/i86.c')
-rw-r--r--trunk/src/emu/cpu/i86/i86.c698
1 files changed, 698 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/i86/i86.c b/trunk/src/emu/cpu/i86/i86.c
new file mode 100644
index 00000000000..341454b28d9
--- /dev/null
+++ b/trunk/src/emu/cpu/i86/i86.c
@@ -0,0 +1,698 @@
+/****************************************************************************
+* real mode i286 emulator v1.4 by Fabrice Frances *
+* (initial work based on David Hedley's pcemu) *
+****************************************************************************/
+/* 26.March 2000 PeT changed set_irq_line */
+
+#include "emu.h"
+#include "debugger.h"
+
+#include "host.h"
+#include "i86priv.h"
+#include "i86.h"
+
+extern int i386_dasm_one(char *buffer, UINT32 eip, const UINT8 *oprom, int mode);
+
+#define VERBOSE 0
+#define LOG(x) do { if (VERBOSE) mame_printf_debug x; } while (0)
+
+
+/* All pre-i286 CPUs have a 1MB address space */
+#define AMASK 0xfffff
+
+
+/* I86 registers */
+typedef union
+{ /* eight general registers */
+ UINT16 w[8]; /* viewed as 16 bits registers */
+ UINT8 b[16]; /* or as 8 bit registers */
+}
+i8086basicregs;
+
+typedef struct _i8086_state i8086_state;
+struct _i8086_state
+{
+ i8086basicregs regs;
+ offs_t fetch_xor;
+ UINT32 pc;
+ UINT32 prevpc;
+ UINT32 base[4];
+ UINT16 sregs[4];
+ UINT16 flags;
+ device_irq_callback irq_callback;
+ INT32 AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */
+ UINT8 ParityVal;
+ UINT8 TF, IF; /* 0 or 1 valued flags */
+ UINT8 MF; /* V30 mode flag */
+ UINT8 int_vector;
+ INT8 nmi_state;
+ INT8 irq_state;
+ INT8 test_state;
+ UINT8 rep_in_progress;
+ INT32 extra_cycles; /* extra cycles for interrupts */
+
+ int halted; /* Is the CPU halted ? */
+
+ UINT16 ip;
+ UINT32 sp;
+
+ legacy_cpu_device *device;
+ address_space *program;
+ direct_read_data *direct;
+ address_space *io;
+ int icount;
+
+ char seg_prefix; /* prefix segment indicator */
+ UINT8 prefix_seg; /* The prefixed segment */
+ unsigned ea;
+ UINT16 eo; /* HJB 12/13/98 effective offset of the address (before segment is added) */
+ UINT8 ea_seg; /* effective segment of the address */
+
+ devcb_resolved_write_line out_tmrout0_func;
+ devcb_resolved_write_line out_tmrout1_func;
+};
+
+INLINE i8086_state *get_safe_token(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == I8086 ||
+ device->type() == I8088 ||
+ device->type() == I80186 ||
+ device->type() == I80188);
+ return (i8086_state *)downcast<legacy_cpu_device *>(device)->token();
+}
+
+
+#include "i86time.c"
+
+/***************************************************************************/
+/* cpu state */
+/***************************************************************************/
+
+
+static struct i80x86_timing timing;
+
+static UINT8 parity_table[256];
+
+/* The interrupt number of a pending external interrupt pending NMI is 2. */
+/* For INTR interrupts, the level is caught on the bus during an INTA cycle */
+
+#define PREFIX(name) i8086##name
+#define PREFIX86(name) i8086##name
+
+#define I8086
+#include "instr86.h"
+#include "ea.h"
+#include "modrm.h"
+#include "table86.h"
+
+#include "instr86.c"
+#undef I8086
+
+
+/***************************************************************************/
+static void i8086_state_register(device_t *device)
+{
+ i8086_state *cpustate = get_safe_token(device);
+ device->save_item(NAME(cpustate->regs.w));
+ device->save_item(NAME(cpustate->pc));
+ device->save_item(NAME(cpustate->prevpc));
+ device->save_item(NAME(cpustate->base));
+ device->save_item(NAME(cpustate->sregs));
+ device->save_item(NAME(cpustate->flags));
+ device->save_item(NAME(cpustate->AuxVal));
+ device->save_item(NAME(cpustate->OverVal));
+ device->save_item(NAME(cpustate->SignVal));
+ device->save_item(NAME(cpustate->ZeroVal));
+ device->save_item(NAME(cpustate->CarryVal));
+ device->save_item(NAME(cpustate->DirVal));
+ device->save_item(NAME(cpustate->ParityVal));
+ device->save_item(NAME(cpustate->TF));
+ device->save_item(NAME(cpustate->IF));
+ device->save_item(NAME(cpustate->MF));
+ device->save_item(NAME(cpustate->int_vector));
+ device->save_item(NAME(cpustate->nmi_state));
+ device->save_item(NAME(cpustate->irq_state));
+ device->save_item(NAME(cpustate->extra_cycles));
+ device->save_item(NAME(cpustate->halted));
+ device->save_item(NAME(cpustate->test_state)); /* PJB 03/05 */
+ device->save_item(NAME(cpustate->rep_in_progress)); /* PJB 03/05 */
+}
+
+static CPU_INIT( i8086 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+ unsigned int i, j, c;
+ static const BREGS reg_name[8] = {AL, CL, DL, BL, AH, CH, DH, BH};
+ for (i = 0; i < 256; i++)
+ {
+ for (j = i, c = 0; j > 0; j >>= 1)
+ if (j & 1)
+ c++;
+
+ parity_table[i] = !(c & 1);
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
+ Mod_RM.reg.w[i] = (WREGS) ((i & 0x38) >> 3);
+ }
+
+ for (i = 0xc0; i < 0x100; i++)
+ {
+ Mod_RM.RM.w[i] = (WREGS) (i & 7);
+ Mod_RM.RM.b[i] = (BREGS) reg_name[i & 7];
+ }
+
+ cpustate->irq_callback = irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->io = device->space(AS_IO);
+
+ /* set up the state table */
+ {
+ device_state_interface *state;
+ device->interface(state);
+ state->state_add(STATE_GENPC, "GENPC", cpustate->pc).mask(0xfffff).formatstr("%9s").callimport();
+ state->state_add(I8086_IP, "IP", cpustate->ip).callimport().callexport();
+ state->state_add(I8086_FLAGS, "FLAGS", cpustate->flags).callimport().callexport().noshow();
+ state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->flags).callimport().callexport().noshow().formatstr("%16s");
+ state->state_add(I8086_AX, "AX", cpustate->regs.w[AX]);
+ state->state_add(I8086_BX, "BX", cpustate->regs.w[BX]);
+ state->state_add(I8086_CX, "CX", cpustate->regs.w[CX]);
+ state->state_add(I8086_DX, "DX", cpustate->regs.w[DX]);
+ state->state_add(I8086_SI, "SI", cpustate->regs.w[SI]);
+ state->state_add(I8086_DI, "DI", cpustate->regs.w[DI]);
+ state->state_add(I8086_BP, "BP", cpustate->regs.w[BP]);
+ state->state_add(I8086_SP, "SP", cpustate->regs.w[SP]);
+ state->state_add(STATE_GENSP, "GENSP", cpustate->sp).mask(0xfffff).formatstr("%9s").callimport().callexport();
+ state->state_add(I8086_AL, "AL", cpustate->regs.b[AL]).noshow();
+ state->state_add(I8086_BL, "BL", cpustate->regs.b[BL]).noshow();
+ state->state_add(I8086_CL, "CL", cpustate->regs.b[CL]).noshow();
+ state->state_add(I8086_DL, "DL", cpustate->regs.b[DL]).noshow();
+ state->state_add(I8086_AH, "AH", cpustate->regs.b[AH]).noshow();
+ state->state_add(I8086_BH, "BH", cpustate->regs.b[BH]).noshow();
+ state->state_add(I8086_CH, "CH", cpustate->regs.b[CH]).noshow();
+ state->state_add(I8086_DH, "DH", cpustate->regs.b[DH]).noshow();
+ state->state_add(I8086_CS, "CS", cpustate->sregs[CS]).callimport();
+ state->state_add(I8086_DS, "DS", cpustate->sregs[DS]).callimport();
+ state->state_add(I8086_ES, "ES", cpustate->sregs[ES]).callimport();
+ state->state_add(I8086_SS, "SS", cpustate->sregs[SS]).callimport();
+ }
+
+ i8086_state_register(device);
+ cpustate->fetch_xor = BYTE_XOR_LE(0);
+}
+
+static CPU_INIT( i8088 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+ CPU_INIT_CALL(i8086);
+ cpustate->fetch_xor = 0;
+}
+
+static CPU_INIT( i80186 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+ CPU_INIT_CALL(i8086);
+
+ /* resolve callbacks */
+ i80186_interface *intf = (i80186_interface *) device->static_config();
+
+ if (intf != NULL)
+ {
+ cpustate->out_tmrout0_func.resolve(intf->out_tmrout0_func, *device);
+ cpustate->out_tmrout1_func.resolve(intf->out_tmrout1_func, *device);
+ }
+}
+
+static CPU_RESET( i8086 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+ device_irq_callback save_irqcallback;
+
+ save_irqcallback = cpustate->irq_callback;
+ memset(cpustate, 0, sizeof(*cpustate));
+ cpustate->irq_callback = save_irqcallback;
+ cpustate->device = device;
+ cpustate->program = device->space(AS_PROGRAM);
+ cpustate->direct = &cpustate->program->direct();
+ cpustate->io = device->space(AS_IO);
+
+ cpustate->sregs[CS] = 0xffff;
+ cpustate->base[CS] = SegBase(CS);
+ cpustate->pc = 0xffff0 & AMASK;
+ ExpandFlags(cpustate->flags);
+
+ cpustate->halted = 0;
+}
+
+static CPU_EXIT( i8086 )
+{
+ /* nothing to do ? */
+}
+
+/* ASG 971222 -- added these interface functions */
+
+static void set_irq_line(i8086_state *cpustate, int irqline, int state)
+{
+ if (state != CLEAR_LINE && cpustate->halted)
+ {
+ cpustate->halted = 0;
+ }
+
+ if (irqline == INPUT_LINE_NMI)
+ {
+ if (cpustate->nmi_state == state)
+ return;
+ cpustate->nmi_state = state;
+
+ /* on a rising edge, signal the NMI */
+ if (state != CLEAR_LINE)
+ {
+ PREFIX(_interrupt)(cpustate, I8086_NMI_INT_VECTOR);
+ }
+ }
+ else
+ {
+ cpustate->irq_state = state;
+
+ /* if the IF is set, signal an interrupt */
+ if (state != CLEAR_LINE && cpustate->IF)
+ PREFIX(_interrupt)(cpustate, (UINT32)-1);
+ }
+}
+
+static void set_drq_line(i8086_state *cpustate, int irqline, int state)
+{
+ // TODO implement me
+}
+
+static void set_tmrin_line(i8086_state *cpustate, int irqline, int state)
+{
+ // TODO implement me
+}
+
+/* PJB 03/05 */
+static void set_test_line(i8086_state *cpustate, int state)
+{
+ cpustate->test_state = !state;
+}
+
+static CPU_EXECUTE( i8086 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+
+ if (cpustate->halted)
+ {
+ cpustate->icount = 0;
+ return;
+ }
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 8086)
+ timing = i8086_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0)
+ {
+ LOG(("[%04x:%04x]=%02x\tF:%04x\tAX=%04x\tBX=%04x\tCX=%04x\tDX=%04x %d%d%d%d%d%d%d%d%d\n",
+ cpustate->sregs[CS], cpustate->pc - cpustate->base[CS], ReadByte(cpustate->pc), cpustate->flags, cpustate->regs.w[AX], cpustate->regs.w[BX], cpustate->regs.w[CX], cpustate->regs.w[DX], cpustate->AuxVal ? 1 : 0, cpustate->OverVal ? 1 : 0,
+ cpustate->SignVal ? 1 : 0, cpustate->ZeroVal ? 1 : 0, cpustate->CarryVal ? 1 : 0, cpustate->ParityVal ? 1 : 0, cpustate->TF, cpustate->IF, cpustate->DirVal < 0 ? 1 : 0));
+ debugger_instruction_hook(device, cpustate->pc);
+
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE86;
+ }
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+}
+
+
+static CPU_DISASSEMBLE( i8086 )
+{
+ return i386_dasm_one(buffer, pc, oprom, 1);
+}
+
+
+
+#include "i86.h"
+
+#undef PREFIX
+#define PREFIX(name) i80186##name
+#define PREFIX186(name) i80186##name
+
+#define I80186
+#include "instr186.h"
+#include "table186.h"
+
+#include "instr86.c"
+#include "instr186.c"
+#undef I80186
+
+static CPU_EXECUTE( i80186 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+ /* copy over the cycle counts if they're not correct */
+ if (timing.id != 80186)
+ timing = i80186_cycles;
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+
+ /* run until we're out */
+ while (cpustate->icount > 0)
+ {
+ LOG(("[%04x:%04x]=%02x\tAX=%04x\tBX=%04x\tCX=%04x\tDX=%04x\n", cpustate->sregs[CS], cpustate->pc, ReadByte(cpustate->pc), cpustate->regs.w[AX],
+ cpustate->regs.w[BX], cpustate->regs.w[CX], cpustate->regs.w[DX]));
+ debugger_instruction_hook(device, cpustate->pc);
+
+ cpustate->seg_prefix = FALSE;
+ cpustate->prevpc = cpustate->pc;
+ TABLE186;
+ }
+
+ /* adjust for any interrupts that came in */
+ cpustate->icount -= cpustate->extra_cycles;
+ cpustate->extra_cycles = 0;
+}
+
+
+
+
+/**************************************************************************
+ * STATE IMPORT/EXPORT
+ **************************************************************************/
+
+static CPU_IMPORT_STATE( i8086 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+ switch (entry.index())
+ {
+ case I8086_GENPC:
+ if (cpustate->pc - cpustate->base[CS] >= 0x10000)
+ {
+ cpustate->base[CS] = cpustate->pc & 0xffff0;
+ cpustate->sregs[CS] = cpustate->base[CS] >> 4;
+ }
+ break;
+
+ case I8086_IP:
+ cpustate->pc = cpustate->base[CS] + cpustate->ip;
+ break;
+
+ case I8086_GENSP:
+ if (cpustate->sp - cpustate->base[SS] >= 0x10000)
+ {
+ cpustate->base[SS] = cpustate->sp & 0xffff0;
+ cpustate->sregs[SS] = cpustate->base[SS] >> 4;
+ }
+ cpustate->regs.w[SP] = cpustate->sp - cpustate->base[SS];
+ break;
+
+ case I8086_FLAGS:
+ case STATE_GENFLAGS:
+ ExpandFlags(cpustate->flags);
+ break;
+
+ case I8086_ES:
+ cpustate->base[ES] = SegBase(ES);
+ break;
+
+ case I8086_CS:
+ cpustate->base[CS] = SegBase(CS);
+ break;
+
+ case I8086_SS:
+ cpustate->base[SS] = SegBase(SS);
+ break;
+
+ case I8086_DS:
+ cpustate->base[DS] = SegBase(DS);
+ break;
+
+ default:
+ fatalerror("CPU_IMPORT_STATE(i8086) called for unexpected value\n");
+ break;
+ }
+}
+
+
+static CPU_EXPORT_STATE( i8086 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+ switch (entry.index())
+ {
+ case I8086_IP:
+ cpustate->ip = cpustate->pc - cpustate->base[CS];
+ break;
+
+ case I8086_FLAGS:
+ case STATE_GENFLAGS:
+ cpustate->flags = CompressFlags();
+ break;
+
+ case I8086_GENSP:
+ cpustate->sp = cpustate->base[SS] + cpustate->regs.w[SP];
+ break;
+
+ default:
+ fatalerror("CPU_EXPORT_STATE(i8086) called for unexpected value\n");
+ break;
+ }
+}
+
+
+static CPU_EXPORT_STRING( i8086 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+ switch (entry.index())
+ {
+ case I8086_GENPC:
+ string.printf("%04X:%04X", cpustate->sregs[CS] & 0xffff, (cpustate->pc - cpustate->base[CS]) & 0xffff);
+ break;
+
+ case I8086_GENSP:
+ string.printf("%04X:%04X", cpustate->sregs[SS] & 0xffff, cpustate->regs.w[SP] & 0xffff);
+ break;
+
+ case STATE_GENFLAGS:
+ cpustate->flags = CompressFlags();
+ string.printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+ cpustate->flags & 0x8000 ? '1' : '.',
+ cpustate->flags & 0x4000 ? '1' : '.',
+ cpustate->flags & 0x2000 ? '1' : '.',
+ cpustate->flags & 0x1000 ? '1' : '.',
+ cpustate->flags & 0x0800 ? 'O' : '.',
+ cpustate->flags & 0x0400 ? 'D' : '.',
+ cpustate->flags & 0x0200 ? 'I' : '.',
+ cpustate->flags & 0x0100 ? 'T' : '.',
+ cpustate->flags & 0x0080 ? 'S' : '.',
+ cpustate->flags & 0x0040 ? 'Z' : '.',
+ cpustate->flags & 0x0020 ? '0' : '.',
+ cpustate->flags & 0x0010 ? 'A' : '.',
+ cpustate->flags & 0x0008 ? '0' : '.',
+ cpustate->flags & 0x0004 ? 'P' : '.',
+ cpustate->flags & 0x0002 ? '1' : '.',
+ cpustate->flags & 0x0001 ? 'C' : '.');
+ break;
+
+ default:
+ fatalerror("CPU_EXPORT_STRING(i8086) called for unexpected value\n");
+ break;
+ }
+}
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static CPU_SET_INFO( i8086 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(cpustate, 0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TEST: set_test_line(cpustate, info->i); break; /* PJB 03/05 */
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+CPU_GET_INFO( i8086 )
+{
+ i8086_state *cpustate = (device != NULL && device->token() != NULL) ? get_safe_token(device) : NULL;
+
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(i8086_state); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 1; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0xff; break;
+ case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 8; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 50; break;
+
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 20; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 16; break;
+ case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + 0: info->i = cpustate->irq_state; break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = cpustate->nmi_state; break;
+
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TEST: info->i = cpustate->test_state; break; /* PJB 03/05 */
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = cpustate->prevpc; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(i8086); break;
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(i8086); break;
+ case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(i8086); break;
+ case CPUINFO_FCT_EXIT: info->exit = CPU_EXIT_NAME(i8086); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(i8086); break;
+ case CPUINFO_FCT_BURN: info->burn = NULL; break;
+ case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(i8086); break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break;
+ case CPUINFO_FCT_IMPORT_STATE: info->import_state = CPU_IMPORT_STATE_NAME(i8086); break;
+ case CPUINFO_FCT_EXPORT_STATE: info->export_state = CPU_EXPORT_STATE_NAME(i8086); break;
+ case CPUINFO_FCT_EXPORT_STRING: info->export_string = CPU_EXPORT_STRING_NAME(i8086);break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "8086"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "Intel 80x86"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.4"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Real mode i286 emulator v1.4 by Fabrice Frances\n(initial work cpustate->based on David Hedley's pcemu)"); break;
+ }
+}
+
+
+/**************************************************************************
+ * CPU-specific get_info/set_info
+ **************************************************************************/
+
+CPU_GET_INFO( i8088 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(i8088); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "8088"); break;
+
+ default: CPU_GET_INFO_CALL(i8086); break;
+ }
+}
+
+
+/**************************************************************************
+ * CPU-specific get_info/set_info
+ **************************************************************************/
+
+static CPU_SET_INFO( i80186 )
+{
+ i8086_state *cpustate = get_safe_token(device);
+
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT0: set_irq_line(cpustate, 0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT1: set_irq_line(cpustate, 1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT2: set_irq_line(cpustate, 2, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_INT3: set_irq_line(cpustate, 3, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_DRQ0: set_drq_line(cpustate, 0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_DRQ1: set_drq_line(cpustate, 1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TMRIN0: set_tmrin_line(cpustate, 0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TMRIN1: set_tmrin_line(cpustate, 1, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(cpustate, INPUT_LINE_NMI, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_TEST: set_test_line(cpustate, info->i); break; /* PJB 03/05 */
+ }
+}
+
+CPU_GET_INFO( i80186 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 2; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(i80186); break;
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(i80186); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(i80186); break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "80186"); break;
+
+ default: CPU_GET_INFO_CALL(i8086); break;
+ }
+}
+
+
+/**************************************************************************
+ * CPU-specific get_info/set_info
+ **************************************************************************/
+
+CPU_GET_INFO( i80188 )
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break;
+ case DEVINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 8; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(i8088); break;
+ case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(i80186);break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case DEVINFO_STR_NAME: strcpy(info->s, "80188"); break;
+
+ default: CPU_GET_INFO_CALL(i8086); break;
+ }
+}
+
+DEFINE_LEGACY_CPU_DEVICE(I8086, i8086);
+DEFINE_LEGACY_CPU_DEVICE(I8088, i8088);
+DEFINE_LEGACY_CPU_DEVICE(I80186, i80186);
+DEFINE_LEGACY_CPU_DEVICE(I80188, i80188);