diff options
Diffstat (limited to 'trunk/src/emu/cpu/i8008/i8008.c')
-rw-r--r-- | trunk/src/emu/cpu/i8008/i8008.c | 725 |
1 files changed, 725 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/i8008/i8008.c b/trunk/src/emu/cpu/i8008/i8008.c new file mode 100644 index 00000000000..bcc6b1672b6 --- /dev/null +++ b/trunk/src/emu/cpu/i8008/i8008.c @@ -0,0 +1,725 @@ +/***************************************************************************** + * + * i8008.c + * + * Intel 8008 CPU + * + * Initial version by Miodrag Milanovic + * + *****************************************************************************/ +#include "emu.h" +#include "debugger.h" +#include "i8008.h" + +#define VERBOSE 0 + +#define LOG(x) do { if (VERBOSE) logerror x; } while (0) + +static UINT8 PARITY[256]; + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +typedef struct _i8008_state i8008_state; +struct _i8008_state +{ + UINT8 A,B,C,D,E,H,L; + PAIR PC; // It is in fact one of ADDR regs + PAIR ADDR[8]; // Address registers + UINT8 CF; // Carry flag + UINT8 ZF; // Zero flag + UINT8 SF; // Sign flag + UINT8 PF; // Parity flag + UINT8 HALT; + UINT8 flags; // temporary I/O only + legacy_cpu_device *device; + address_space *program; + direct_read_data *direct; + address_space *io; + int icount; + int pc_pos; // PC possition in ADDR + + device_irq_callback irq_callback; + UINT8 irq_state; +}; + +/*************************************************************************** + MACROS +***************************************************************************/ +#define REG_1 ((opcode >> 3) & 7) +#define REG_2 (opcode & 7) +#define GET_PC (cpustate->ADDR[cpustate->pc_pos]) + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +INLINE i8008_state *get_safe_token(device_t *device) +{ + assert(device != NULL); + assert(device->type() == I8008); + return (i8008_state *)downcast<legacy_cpu_device *>(device)->token(); +} + +INLINE void PUSH_STACK(i8008_state *cpustate) +{ + cpustate->pc_pos = (cpustate->pc_pos + 1) & 7; +} + +INLINE void POP_STACK(i8008_state *cpustate) +{ + cpustate->ADDR[cpustate->pc_pos].d = 0; + cpustate->pc_pos = (cpustate->pc_pos - 1) & 7; +} + +INLINE UINT8 ROP(i8008_state *cpustate) +{ + UINT8 retVal = cpustate->direct->read_decrypted_byte(GET_PC.w.l); + GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff; + cpustate->PC = GET_PC; + return retVal; +} + +INLINE UINT8 GET_REG(i8008_state *cpustate,UINT8 reg) +{ + UINT8 retVal; + switch(reg) { + case 0 : retVal = cpustate->A; break; + case 1 : retVal = cpustate->B; break; + case 2 : retVal = cpustate->C; break; + case 3 : retVal = cpustate->D; break; + case 4 : retVal = cpustate->E; break; + case 5 : retVal = cpustate->H; break; + case 6 : retVal = cpustate->L; break; + default: retVal = cpustate->program->read_byte((cpustate->H << 8) + cpustate->L); break; + } + return retVal; +} + +INLINE void SET_REG(i8008_state *cpustate,UINT8 reg, UINT8 val) +{ + switch(reg) { + case 0 : cpustate->A = val; break; + case 1 : cpustate->B = val; break; + case 2 : cpustate->C = val; break; + case 3 : cpustate->D = val; break; + case 4 : cpustate->E = val; break; + case 5 : cpustate->H = val; break; + case 6 : cpustate->L = val; break; + default: cpustate->program->write_byte((cpustate->H << 8) + cpustate->L, val); break; + } +} + +INLINE UINT8 ARG(i8008_state *cpustate) +{ + UINT8 retVal = cpustate->direct->read_raw_byte(GET_PC.w.l); + GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff; + cpustate->PC = GET_PC; + return retVal; +} + +INLINE void UPDATE_FLAGS(i8008_state *cpustate,UINT8 val) +{ + cpustate->ZF = (val == 0) ? 1 : 0; + cpustate->SF = (val & 0x80) ? 1 : 0; + cpustate->PF = PARITY[val]; +} + +INLINE UINT8 DO_CONDITION(i8008_state *cpustate, UINT8 val) +{ + UINT8 v = (val >> 5) & 1; + UINT8 cond = 0; + switch((val>> 3) & 0x03) { + case 0 : + if (cpustate->CF==v) cond = 1; + break; + case 1 : + if (cpustate->ZF==v) cond = 1; + break; + case 2 : + if (cpustate->SF==v) cond = 1; + break; + case 3 : + if (cpustate->PF==v) cond = 1; + break; + } + return cond; +} + +INLINE UINT16 GET_ADDR(i8008_state *cpustate) +{ + UINT8 lo = ARG(cpustate); + UINT8 hi = ARG(cpustate); + return ((hi & 0x3f) << 8) + lo; +} + +INLINE void illegal(i8008_state *cpustate,UINT8 opcode) +{ +#if VERBOSE + UINT16 pc = cpustate->PC.w.l; + LOG(("I8008 illegal instruction %04X $%02X\n", pc, opcode)); +#endif +} + +static void execute_one(i8008_state *cpustate, int opcode) +{ + UINT16 tmp; + + switch (opcode >> 6) + { + case 0x03: // starting with 11 + if (opcode==0xff) { + // HLT + cpustate->icount -= 4; + GET_PC.w.l = GET_PC.w.l - 1; + cpustate->PC = GET_PC; + cpustate->HALT = 1; + } else { + // Lrr + cpustate->icount -= 5; + if (REG_1==7) cpustate->icount -= 2; + if (REG_2==7) cpustate->icount -= 3; + SET_REG(cpustate,REG_1, GET_REG(cpustate,REG_2)); + } + break; + case 0x00: // starting with 00 + switch(opcode & 7) { + case 0 : if(((opcode >> 3) & 7)==0) { + // HLT + cpustate->icount -= 4; + GET_PC.w.l = GET_PC.w.l - 1; + cpustate->PC = GET_PC; + cpustate->HALT = 1; + } else { + if(((opcode >> 3) & 7)==7) { + // ILLEGAL + cpustate->icount -= 5; + illegal(cpustate,opcode); + } else { + // INr + cpustate->icount -= 5; + tmp = GET_REG(cpustate,REG_1) + 1; + SET_REG(cpustate,REG_1, tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + } + } + break; + case 1 : if(((opcode >> 3) & 7)==0) { + // HLT + cpustate->icount -= 4; + GET_PC.w.l = GET_PC.w.l - 1; + cpustate->PC = GET_PC; + cpustate->HALT = 1; + } else { + if(((opcode >> 3) & 7)==7) { + // ILLEGAL + cpustate->icount -= 5; + illegal(cpustate,opcode); + } else { + // DCr + cpustate->icount -= 5; + tmp = GET_REG(cpustate,REG_1) - 1; + SET_REG(cpustate,REG_1, tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + } + } + break; + case 2 : { + // All instuction from this group have same timing + cpustate->icount -= 5; + switch((opcode >> 3) & 7) { + case 0 : + // RLC + tmp = cpustate->A; + cpustate->A = (cpustate->A << 1) | BIT(tmp,7); + cpustate->CF = BIT(tmp,7); + break; + case 1 : + // RRC + tmp = cpustate->A; + cpustate->A = (cpustate->A >> 1) | (BIT(tmp,0) ? 0x80 : 0x00); + cpustate->CF = BIT(tmp,0); + break; + case 2 : + // RAL + tmp = cpustate->A; + cpustate->A = (cpustate->A << 1) | cpustate->CF; + cpustate->CF = BIT(tmp,7); + break; + case 3 : + // RAR + tmp = cpustate->A; + cpustate->A = (cpustate->A >> 1) | (cpustate->CF ? 0x80 : 0x00); + cpustate->CF = BIT(tmp,0); + break; + default : + // ILLEGAL + illegal(cpustate,opcode); + break; + } + } + break; + case 3 : + // Rcc + { + cpustate->icount -= 3; + if (DO_CONDITION(cpustate,opcode)==1) { + cpustate->icount -= 2; + POP_STACK(cpustate); + cpustate->PC = GET_PC; + } + } + break; + case 4 : { + cpustate->icount -= 8; + switch((opcode >> 3) & 7) { + case 0 : + // ADI + tmp = GET_REG(cpustate,0) + ARG(cpustate); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 1 : + // ACI + tmp = GET_REG(cpustate,0) + ARG(cpustate) + cpustate->CF; + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 2 : + // SUI + tmp = GET_REG(cpustate,0) - ARG(cpustate); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 3 : + // SBI + tmp = GET_REG(cpustate,0) - ARG(cpustate) - cpustate->CF; + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 4 : + // NDI + tmp = GET_REG(cpustate,0) & ARG(cpustate); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = 0; + break; + case 5 : + // XRI + tmp = GET_REG(cpustate,0) ^ ARG(cpustate); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = 0; + break; + case 6 : + // ORI + tmp = GET_REG(cpustate,0) | ARG(cpustate); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = 0; + break; + case 7 : + // CPI + tmp = GET_REG(cpustate,0) - ARG(cpustate); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + } + } + break; + case 5 : // RST + cpustate->icount -= 5; + PUSH_STACK(cpustate); + GET_PC.w.l = opcode & 0x38; + cpustate->PC = GET_PC; + break; + case 6 : // LrI + cpustate->icount -= 8; + if (REG_1==7) cpustate->icount -= 1; // LMI + SET_REG(cpustate,REG_1, ARG(cpustate)); + break; + case 7 : // RET + cpustate->icount -= 5; + POP_STACK(cpustate); + cpustate->PC = GET_PC; + break; + } + break; + + case 0x01: // starting with 01 + switch(opcode & 7) { + case 0 : + // Jcc + cpustate->icount -= 9; + tmp = GET_ADDR(cpustate); + if (DO_CONDITION(cpustate,opcode)==1) { + cpustate->icount -= 2; + GET_PC.w.l = tmp; + cpustate->PC = GET_PC; + } + break; + case 2 : + // Ccc + cpustate->icount -= 9; + tmp = GET_ADDR(cpustate); + if (DO_CONDITION(cpustate,opcode)==1) { + cpustate->icount -= 2; + PUSH_STACK(cpustate); + GET_PC.w.l = tmp; + cpustate->PC = GET_PC; + } + break; + case 4 : + // JMP + cpustate->icount -= 11; + GET_PC.w.l = GET_ADDR(cpustate); + cpustate->PC = GET_PC; + break; + case 6 : + // CAL + cpustate->icount -= 11; + tmp = GET_ADDR(cpustate); + PUSH_STACK(cpustate); + GET_PC.w.l = tmp; + cpustate->PC = GET_PC; + break; + default : + if (((opcode>>4)&3)==0) { + // INP + cpustate->icount -= 8; + cpustate->A = cpustate->io->read_byte((opcode >> 1) & 0x1f); + } else { + // OUT + cpustate->icount -= 6; + cpustate->io->write_byte((opcode >> 1) & 0x1f, cpustate->A); + } + break; + } + break; + case 0x02: // starting with 10 + cpustate->icount -= 5; + if ((opcode & 7)==7) cpustate->icount -= 3; // operations with memory + switch((opcode >> 3) & 7) { + case 0 : + // ADx + tmp = GET_REG(cpustate,0) + GET_REG(cpustate,opcode & 7); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 1 : + // ACx + tmp = GET_REG(cpustate,0) + GET_REG(cpustate,opcode & 7) + cpustate->CF; + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 2 : + // SUx + tmp = GET_REG(cpustate,0) - GET_REG(cpustate,opcode & 7); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 3 : + // SBx + tmp = GET_REG(cpustate,0) - GET_REG(cpustate,opcode & 7) - cpustate->CF; + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + case 4 : + // NDx + tmp = GET_REG(cpustate,0) & GET_REG(cpustate,opcode & 7); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = 0; + break; + case 5 : + // XRx + tmp = GET_REG(cpustate,0) ^ GET_REG(cpustate,opcode & 7); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = 0; + break; + case 6 : + // ORx + tmp = GET_REG(cpustate,0) | GET_REG(cpustate,opcode & 7); + SET_REG(cpustate,0,tmp & 0xff); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = 0; + break; + case 7 : + // CPx + tmp = GET_REG(cpustate,0) - GET_REG(cpustate,opcode & 7); + UPDATE_FLAGS(cpustate,tmp & 0xff); + cpustate->CF = (tmp >> 8) & 1; + break; + } + break; + } +} + + +/*************************************************************************** + COMMON EXECUTION +***************************************************************************/ +static void take_interrupt(i8008_state *cpustate) +{ + if (cpustate->HALT) { + GET_PC.w.l = (GET_PC.w.l + 1) & 0x3fff; + cpustate->PC = GET_PC; + cpustate->HALT = 0; + } + // For now only support one byte operation to be executed + execute_one(cpustate,(*cpustate->irq_callback)(cpustate->device, 0)); +} + +static CPU_EXECUTE( i8008 ) +{ + i8008_state *cpustate = get_safe_token(device); + + do + { + if (cpustate->irq_state != CLEAR_LINE) { + take_interrupt(cpustate); + } + debugger_instruction_hook(device, cpustate->PC.d); + execute_one(cpustate, ROP(cpustate)); + + } while (cpustate->icount > 0); +} + +/*************************************************************************** + CORE INITIALIZATION +***************************************************************************/ +static void init_tables (void) +{ + int i; + UINT8 p; + for (i = 0; i < 256; i++) + { + p = 0; + if (BIT(i,0)) p++; + if (BIT(i,1)) p++; + if (BIT(i,2)) p++; + if (BIT(i,3)) p++; + if (BIT(i,4)) p++; + if (BIT(i,5)) p++; + if (BIT(i,6)) p++; + if (BIT(i,7)) p++; + PARITY[i] = ((p&1) ? 0 : 1); + } +} + +static CPU_INIT( i8008 ) +{ + i8008_state *cpustate = get_safe_token(device); + + /* set up the state table */ + { + device_state_interface *state; + device->interface(state); + state->state_add(I8008_PC, "PC", cpustate->PC.w.l).mask(0x3fff); + state->state_add(STATE_GENPC, "GENPC", cpustate->PC.w.l).mask(0x3fff).noshow(); + state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->flags).mask(0x0f).callimport().callexport().noshow().formatstr("%4s"); + state->state_add(I8008_A, "A", cpustate->A); + state->state_add(I8008_B, "B", cpustate->B); + state->state_add(I8008_C, "C", cpustate->C); + state->state_add(I8008_D, "D", cpustate->D); + state->state_add(I8008_E, "E", cpustate->E); + state->state_add(I8008_H, "H", cpustate->H); + state->state_add(I8008_L, "L", cpustate->L); + + astring tempstr; + for (int addrnum = 0; addrnum < 8; addrnum++) + state->state_add(I8008_ADDR1 + addrnum, tempstr.format("ADDR%d", addrnum + 1), cpustate->ADDR[addrnum].w.l).mask(0xfff); + } + + cpustate->device = device; + + cpustate->program = device->space(AS_PROGRAM); + cpustate->direct = &cpustate->program->direct(); + cpustate->io = device->space(AS_IO); + + cpustate->irq_callback = irqcallback; + + init_tables(); + + device->save_item(NAME(cpustate->PC)); + device->save_item(NAME(cpustate->A)); + device->save_item(NAME(cpustate->B)); + device->save_item(NAME(cpustate->C)); + device->save_item(NAME(cpustate->D)); + device->save_item(NAME(cpustate->E)); + device->save_item(NAME(cpustate->H)); + device->save_item(NAME(cpustate->L)); + device->save_item(NAME(cpustate->CF)); + device->save_item(NAME(cpustate->SF)); + device->save_item(NAME(cpustate->ZF)); + device->save_item(NAME(cpustate->PF)); + device->save_item(NAME(cpustate->pc_pos)); + device->save_item(NAME(cpustate->ADDR[0])); + device->save_item(NAME(cpustate->ADDR[1])); + device->save_item(NAME(cpustate->ADDR[2])); + device->save_item(NAME(cpustate->ADDR[3])); + device->save_item(NAME(cpustate->ADDR[4])); + device->save_item(NAME(cpustate->ADDR[5])); + device->save_item(NAME(cpustate->ADDR[6])); + device->save_item(NAME(cpustate->ADDR[7])); + device->save_item(NAME(cpustate->HALT)); + device->save_item(NAME(cpustate->irq_state)); +} + + + +/*************************************************************************** + COMMON RESET +***************************************************************************/ + +static CPU_RESET( i8008 ) +{ + i8008_state *cpustate = get_safe_token(device); + + cpustate->CF = cpustate->SF = cpustate->ZF = cpustate->PF = 0; + cpustate->A = cpustate->B = cpustate->C = cpustate->D = cpustate->E = cpustate->H = cpustate->L = 0; + cpustate->PC.d = 0; + cpustate->pc_pos = 0; + cpustate->HALT = 0; + cpustate->irq_state = CLEAR_LINE; + memset(cpustate->ADDR,0,sizeof(cpustate->ADDR)); + +} + +/**************************************************************************** + * Set IRQ line state + ****************************************************************************/ +static void set_irq_line(i8008_state *cpustate, int irqline, int state) +{ + cpustate->irq_state = state; +} + +/*************************************************************************** + COMMON STATE IMPORT/EXPORT +***************************************************************************/ + +static CPU_IMPORT_STATE( i8008 ) +{ + i8008_state *cpustate = get_safe_token(device); + + switch (entry.index()) + { + case STATE_GENFLAGS: + cpustate->CF = (cpustate->flags >> 3) & 1; + cpustate->ZF = (cpustate->flags >> 2) & 1; + cpustate->SF = (cpustate->flags >> 1) & 1; + cpustate->PF = (cpustate->flags >> 0) & 1; + break; + } +} + +static CPU_EXPORT_STATE( i8008 ) +{ + i8008_state *cpustate = get_safe_token(device); + + switch (entry.index()) + { + case STATE_GENFLAGS: + cpustate->flags = (cpustate->CF ? 0x08 : 0x00) | + (cpustate->ZF ? 0x04 : 0x00) | + (cpustate->SF ? 0x02 : 0x00) | + (cpustate->PF ? 0x01 : 0x00); + break; + } +} + +static CPU_EXPORT_STRING( i8008 ) +{ + i8008_state *cpustate = get_safe_token(device); + + switch (entry.index()) + { + case STATE_GENFLAGS: + string.printf("%c%c%c%c", + cpustate->CF ? 'C':'.', + cpustate->ZF ? 'Z':'.', + cpustate->SF ? 'S':'.', + cpustate->PF ? 'P':'.'); + break; + } +} + +/*************************************************************************** + COMMON SET INFO +***************************************************************************/ +static CPU_SET_INFO( i8008 ) +{ + i8008_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; + } +} + +/*************************************************************************** + 8008 GET INFO +***************************************************************************/ + +CPU_GET_INFO( i8008 ) +{ + i8008_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(i8008_state); break; + case CPUINFO_INT_INPUT_LINES: info->i = 0; break; + case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; 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 = 3; break; + case CPUINFO_INT_MIN_CYCLES: info->i = 8; break; + case CPUINFO_INT_MAX_CYCLES: info->i = 16; break; + + case DEVINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; + case DEVINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 14; 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 = 8; break; + case DEVINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 8; break; + case DEVINFO_INT_ADDRBUS_SHIFT + AS_IO: info->i = 0; break; + + /* --- the following bits of info are returned as pointers to functions --- */ + case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(i8008); break; + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(i8008); break; + case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(i8008); break; + case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(i8008); break; + case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(i8008); break; + case CPUINFO_FCT_IMPORT_STATE: info->import_state = CPU_IMPORT_STATE_NAME(i8008); break; + case CPUINFO_FCT_EXPORT_STATE: info->export_state = CPU_EXPORT_STATE_NAME(i8008); break; + case CPUINFO_FCT_EXPORT_STRING: info->export_string = CPU_EXPORT_STRING_NAME(i8008); break; + + /* --- the following bits of info are returned as pointers --- */ + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; + + /* --- the following bits of info are returned as NULL-terminated strings --- */ + case DEVINFO_STR_NAME: strcpy(info->s, "8008"); break; + case DEVINFO_STR_FAMILY: strcpy(info->s, "Intel 8008"); break; + case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; + case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; + case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Miodrag Milanovic"); break; + } +} + +DEFINE_LEGACY_CPU_DEVICE(I8008, i8008); |