From 1eac5f4e9e8ac55966170bc73b25089a079fead4 Mon Sep 17 00:00:00 2001 From: Wilbert Pol Date: Sat, 28 Dec 2013 20:53:14 +0000 Subject: [PATCH] scmp.c: Modernized cpu core. [Wilbert Pol] --- src/emu/cpu/scmp/scmp.c | 632 +++++++++++++++++----------------------- src/emu/cpu/scmp/scmp.h | 111 +++++-- 2 files changed, 358 insertions(+), 385 deletions(-) diff --git a/src/emu/cpu/scmp/scmp.c b/src/emu/cpu/scmp/scmp.c index 402369d4515..9a3b58ea5e6 100644 --- a/src/emu/cpu/scmp/scmp.c +++ b/src/emu/cpu/scmp/scmp.c @@ -16,128 +16,128 @@ #define LOG(x) do { if (VERBOSE) logerror x; } while (0) -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ -struct scmp_state +const device_type SCMP = &device_creator; +const device_type INS8060 = &device_creator; + + +scmp_device::scmp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : cpu_device(mconfig, SCMP, "INS 8050 SC/MP", tag, owner, clock, "ins8050", __FILE__) + , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0) + , m_flag_out_func(*this) + , m_sout_func(*this) + , m_sin_func(*this) + , m_sensea_func(*this) + , m_senseb_func(*this) + , m_halt_func(*this) { - scmp_config config; - PAIR PC; - PAIR P1; - PAIR P2; - PAIR P3; - UINT8 AC; - UINT8 ER; - UINT8 SR; - - legacy_cpu_device *device; - address_space *program; - direct_read_data *direct; - address_space *io; - int icount; - - devcb_resolved_write8 flag_out_func; - devcb_resolved_write_line sout_func; - devcb_resolved_read_line sin_func; - devcb_resolved_read_line sensea_func; - devcb_resolved_read_line senseb_func; - devcb_resolved_write_line halt_func; -}; - -/*************************************************************************** - MACROS -***************************************************************************/ - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -INLINE scmp_state *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == SCMP || device->type() == INS8060); - return (scmp_state *)downcast(device)->token(); } -INLINE UINT16 ADD12(UINT16 addr, INT8 val) + +scmp_device::scmp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) + , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0) + , m_flag_out_func(*this) + , m_sout_func(*this) + , m_sin_func(*this) + , m_sensea_func(*this) + , m_senseb_func(*this) + , m_halt_func(*this) +{ +} + + +ins8060_device::ins8060_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : scmp_device(mconfig, INS8060, "INS 8060 SC/MP II", tag, owner, clock, "ins8060", __FILE__) +{ +} + + +offs_t scmp_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) +{ + extern CPU_DISASSEMBLE( scmp ); + return CPU_DISASSEMBLE_NAME(scmp)(this, buffer, pc, oprom, opram, options); +} + + +UINT16 scmp_device::ADD12(UINT16 addr, INT8 val) { return ((addr + val) & 0x0fff) | (addr & 0xf000); } -INLINE UINT8 ROP(scmp_state *cpustate) +UINT8 scmp_device::ROP() { - UINT16 pc = cpustate->PC.w.l; - cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1); - return cpustate->direct->read_decrypted_byte( pc); + UINT16 pc = m_PC.w.l; + m_PC.w.l = ADD12(m_PC.w.l,1); + return m_direct->read_decrypted_byte( pc); } -INLINE UINT8 ARG(scmp_state *cpustate) +UINT8 scmp_device::ARG() { - UINT16 pc = cpustate->PC.w.l; - cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1); - return cpustate->direct->read_raw_byte(pc); + UINT16 pc = m_PC.w.l; + m_PC.w.l = ADD12(m_PC.w.l,1); + return m_direct->read_raw_byte(pc); } -INLINE UINT8 RM(scmp_state *cpustate,UINT32 a) +UINT8 scmp_device::RM(UINT32 a) { - return cpustate->program->read_byte(a); + return m_program->read_byte(a); } -INLINE void WM(scmp_state *cpustate,UINT32 a, UINT8 v) +void scmp_device::WM(UINT32 a, UINT8 v) { - cpustate->program->write_byte(a, v); + m_program->write_byte(a, v); } -INLINE void illegal(scmp_state *cpustate,UINT8 opcode) +void scmp_device::illegal(UINT8 opcode) { #if VERBOSE - UINT16 pc = cpustate->PC.w.l; + UINT16 pc = m_PC.w.l; LOG(("SC/MP illegal instruction %04X $%02X\n", pc-1, opcode)); #endif } -INLINE PAIR *GET_PTR_REG(scmp_state *cpustate, int num) +PAIR *scmp_device::GET_PTR_REG(int num) { switch(num) { - case 1: return &cpustate->P1; - case 2: return &cpustate->P2; - case 3: return &cpustate->P3; + case 1: return &m_P1; + case 2: return &m_P2; + case 3: return &m_P3; default : - return &cpustate->PC; + return &m_PC; } } -INLINE void BIN_ADD(scmp_state *cpustate, UINT8 val) +void scmp_device::BIN_ADD(UINT8 val) { - UINT16 tmp = cpustate->AC + val + ((cpustate->SR >> 7) & 1); - UINT8 ov = (((cpustate->AC & 0x80)==(val & 0x80)) && ((cpustate->AC & 0x80)!=(tmp & 0x80))) ? 0x40 : 0x00; + UINT16 tmp = m_AC + val + ((m_SR >> 7) & 1); + UINT8 ov = (((m_AC & 0x80)==(val & 0x80)) && ((m_AC & 0x80)!=(tmp & 0x80))) ? 0x40 : 0x00; - cpustate->AC = tmp & 0xff; - cpustate->SR &= 0x3f; // clear CY/L and OV flag - cpustate->SR |= (tmp & 0x100) ? 0x80 : 0x00; // set CY/L - cpustate->SR |= ov; + m_AC = tmp & 0xff; + m_SR &= 0x3f; // clear CY/L and OV flag + m_SR |= (tmp & 0x100) ? 0x80 : 0x00; // set CY/L + m_SR |= ov; } -INLINE void DEC_ADD(scmp_state *cpustate, UINT8 val) +void scmp_device::DEC_ADD(UINT8 val) { - UINT16 tmp = cpustate->AC + val + ((cpustate->SR >> 7) & 1); + UINT16 tmp = m_AC + val + ((m_SR >> 7) & 1); if ((tmp & 0x0f) > 9) tmp +=6; - cpustate->AC = tmp % 0xa0; - cpustate->SR &= 0x7f; // clear CY/L flag - cpustate->SR |= (tmp > 0x99) ? 0x80 : 0x00; + m_AC = tmp % 0xa0; + m_SR &= 0x7f; // clear CY/L flag + m_SR |= (tmp > 0x99) ? 0x80 : 0x00; } -INLINE UINT16 GET_ADDR(scmp_state *cpustate, UINT8 code) +UINT16 scmp_device::GET_ADDR(UINT8 code) { UINT16 addr = 0; INT8 offset = 0; UINT16 retVal = 0; - UINT16 ptr = GET_PTR_REG(cpustate,code & 0x03)->w.l; + UINT16 ptr = GET_PTR_REG(code & 0x03)->w.l; - UINT8 arg = ARG(cpustate); + UINT8 arg = ARG(); if (arg == 0x80) { - offset = cpustate->ER; + offset = m_ER; } else { if (arg & 0x80) { offset = (INT8)arg; @@ -153,12 +153,12 @@ INLINE UINT16 GET_ADDR(scmp_state *cpustate, UINT8 code) // Auto-indexed if (offset < 0) { // pre decrement - GET_PTR_REG(cpustate,code & 0x03)->w.l = addr; + GET_PTR_REG(code & 0x03)->w.l = addr; retVal = addr; } else { // post increment retVal = ptr; - GET_PTR_REG(cpustate,code & 0x03)->w.l = addr; + GET_PTR_REG(code & 0x03)->w.l = addr; } } else { // Immediate @@ -170,7 +170,7 @@ INLINE UINT16 GET_ADDR(scmp_state *cpustate, UINT8 code) return retVal; } -static void execute_one(scmp_state *cpustate, int opcode) +void scmp_device::execute_one(int opcode) { UINT8 tmp; UINT8 ptr = opcode & 3; @@ -182,140 +182,140 @@ static void execute_one(scmp_state *cpustate, int opcode) case 0xc0 : case 0xc1 : case 0xc2 : case 0xc3 : case 0xc5 : case 0xc6 : case 0xc7 : //LD - cpustate->icount -= 18; - cpustate->AC = RM(cpustate,GET_ADDR(cpustate,opcode)); + m_icount -= 18; + m_AC = RM(GET_ADDR(opcode)); break; case 0xc8 : case 0xc9 : case 0xca : case 0xcb : case 0xcd : case 0xce : case 0xcf : // ST - cpustate->icount -= 18; - WM(cpustate,GET_ADDR(cpustate,opcode),cpustate->AC); + m_icount -= 18; + WM(GET_ADDR(opcode),m_AC); break; case 0xd0 : case 0xd1 : case 0xd2 : case 0xd3 : case 0xd5 : case 0xd6 : case 0xd7 : // AND - cpustate->icount -= 18; - cpustate->AC &= RM(cpustate,GET_ADDR(cpustate,opcode)); + m_icount -= 18; + m_AC &= RM(GET_ADDR(opcode)); break; case 0xd8 : case 0xd9 : case 0xda : case 0xdb : case 0xdd : case 0xde : case 0xdf : //OR - cpustate->icount -= 18; - cpustate->AC |= RM(cpustate,GET_ADDR(cpustate,opcode)); + m_icount -= 18; + m_AC |= RM(GET_ADDR(opcode)); break; case 0xe0 : case 0xe1 : case 0xe2 : case 0xe3 : case 0xe5 : case 0xe6 : case 0xe7 : // XOR - cpustate->icount -= 18; - cpustate->AC ^= RM(cpustate,GET_ADDR(cpustate,opcode)); + m_icount -= 18; + m_AC ^= RM(GET_ADDR(opcode)); break; case 0xe8 : case 0xe9 : case 0xea : case 0xeb : case 0xed : case 0xee : case 0xef : // DAD - cpustate->icount -= 23; - DEC_ADD(cpustate,RM(cpustate,GET_ADDR(cpustate,opcode))); + m_icount -= 23; + DEC_ADD(RM(GET_ADDR(opcode))); break; case 0xf0 : case 0xf1 : case 0xf2 : case 0xf3 : case 0xf5 : case 0xf6 : case 0xf7 : // ADD - cpustate->icount -= 19; - BIN_ADD(cpustate,RM(cpustate,GET_ADDR(cpustate,opcode))); + m_icount -= 19; + BIN_ADD(RM(GET_ADDR(opcode))); break; case 0xf8 : case 0xf9 : case 0xfa : case 0xfb : case 0xfd : case 0xfe : case 0xff : // CAD - cpustate->icount -= 20; - BIN_ADD(cpustate,~RM(cpustate,GET_ADDR(cpustate,opcode))); + m_icount -= 20; + BIN_ADD(~RM(GET_ADDR(opcode))); break; // Memory Increment/Decrement Instructions case 0xa8 : case 0xa9 : case 0xaa : case 0xab : // IDL { - UINT16 addr = GET_ADDR(cpustate,opcode); - cpustate->icount -= 22; - cpustate->AC = RM(cpustate,addr) + 1; - WM(cpustate,addr,cpustate->AC); + UINT16 addr = GET_ADDR(opcode); + m_icount -= 22; + m_AC = RM(addr) + 1; + WM(addr,m_AC); } break; case 0xb8 : case 0xb9 : case 0xba : case 0xbb : // DLD { - UINT16 addr = GET_ADDR(cpustate,opcode); - cpustate->icount -= 22; - cpustate->AC = RM(cpustate,addr) - 1; - WM(cpustate,addr,cpustate->AC); + UINT16 addr = GET_ADDR(opcode); + m_icount -= 22; + m_AC = RM(addr) - 1; + WM(addr,m_AC); } break; // Immediate Instructions case 0xc4 : // LDI - cpustate->icount -= 10; - cpustate->AC = ARG(cpustate); + m_icount -= 10; + m_AC = ARG(); break; case 0xd4 : // ANI - cpustate->icount -= 10; - cpustate->AC &= ARG(cpustate); + m_icount -= 10; + m_AC &= ARG(); break; case 0xdc : // ORI - cpustate->icount -= 10; - cpustate->AC |= ARG(cpustate); + m_icount -= 10; + m_AC |= ARG(); break; case 0xe4 : // XRI - cpustate->icount -= 10; - cpustate->AC ^= ARG(cpustate); + m_icount -= 10; + m_AC ^= ARG(); break; case 0xec : // DAI - cpustate->icount -= 15; - DEC_ADD(cpustate,ARG(cpustate)); + m_icount -= 15; + DEC_ADD(ARG()); break; case 0xf4 : // ADI - cpustate->icount -= 11; - BIN_ADD(cpustate,ARG(cpustate)); + m_icount -= 11; + BIN_ADD(ARG()); break; case 0xfc : // CAI - cpustate->icount -= 12; - BIN_ADD(cpustate,~ARG(cpustate)); + m_icount -= 12; + BIN_ADD(~ARG()); break; // Transfer Instructions case 0x90 : case 0x91 : case 0x92 : case 0x93 :// JMP - cpustate->icount -= 11; - cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)ARG(cpustate)); + m_icount -= 11; + m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)ARG()); break; case 0x94 : case 0x95 : case 0x96 : case 0x97 : // JP - cpustate->icount -= 9; - tmp = ARG(cpustate); - if (!(cpustate->AC & 0x80)) { - cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)tmp); - cpustate->icount -= 2; + m_icount -= 9; + tmp = ARG(); + if (!(m_AC & 0x80)) { + m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)tmp); + m_icount -= 2; } break; case 0x98 : case 0x99 : case 0x9a : case 0x9b : // JZ - cpustate->icount -= 9; - tmp = ARG(cpustate); - if (!cpustate->AC) { - cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)tmp); - cpustate->icount -= 2; + m_icount -= 9; + tmp = ARG(); + if (!m_AC) { + m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)tmp); + m_icount -= 2; } break; case 0x9c : case 0x9d : case 0x9e : case 0x9f : // JNZ - cpustate->icount -= 9; - tmp = ARG(cpustate); - if (cpustate->AC) { - cpustate->PC.w.l = ADD12(GET_PTR_REG(cpustate,ptr)->w.l,(INT8)tmp); - cpustate->icount -= 2; + m_icount -= 9; + tmp = ARG(); + if (m_AC) { + m_PC.w.l = ADD12(GET_PTR_REG(ptr)->w.l,(INT8)tmp); + m_icount -= 2; } break; // Double-Byte Miscellaneous Instructions case 0x8f: // DLY - tmp = ARG(cpustate); - cpustate->icount -= 13 + (cpustate->AC * 2) + (((UINT32)tmp) << 1) + (((UINT32)tmp) << 9); - cpustate->AC = 0xff; + tmp = ARG(); + m_icount -= 13 + (m_AC * 2) + (((UINT32)tmp) << 1) + (((UINT32)tmp) << 9); + m_AC = 0xff; break; // Others are illegal - default : cpustate->icount -= 1; - illegal (cpustate,opcode); + default : m_icount -= 1; + illegal (opcode); break; } } else { @@ -324,130 +324,130 @@ static void execute_one(scmp_state *cpustate, int opcode) { // Extension Register Instructions case 0x40: // LDE - cpustate->icount -= 6; - cpustate->AC = cpustate->ER; + m_icount -= 6; + m_AC = m_ER; break; case 0x01: // XAE - cpustate->icount -= 7; - tmp = cpustate->AC; - cpustate->AC = cpustate->ER; - cpustate->ER = tmp; + m_icount -= 7; + tmp = m_AC; + m_AC = m_ER; + m_ER = tmp; break; case 0x50: // ANE - cpustate->icount -= 6; - cpustate->AC &= cpustate->ER; + m_icount -= 6; + m_AC &= m_ER; break; case 0x58: // ORE - cpustate->icount -= 6; - cpustate->AC |= cpustate->ER; + m_icount -= 6; + m_AC |= m_ER; break; case 0x60: // XRE - cpustate->icount -= 6; - cpustate->AC ^= cpustate->ER; + m_icount -= 6; + m_AC ^= m_ER; break; case 0x68: // DAE - cpustate->icount -= 11; - DEC_ADD(cpustate,cpustate->ER); + m_icount -= 11; + DEC_ADD(m_ER); break; case 0x70: // ADE - cpustate->icount -= 7; - BIN_ADD(cpustate,cpustate->ER); + m_icount -= 7; + BIN_ADD(m_ER); break; case 0x78: // CAE - cpustate->icount -= 8; - BIN_ADD(cpustate,~cpustate->ER); + m_icount -= 8; + BIN_ADD(~m_ER); break; // Pointer Register Move Instructions case 0x30: case 0x31: case 0x32: case 0x33: // XPAL - cpustate->icount -= 8; - tmp = cpustate->AC; - cpustate->AC = GET_PTR_REG(cpustate,ptr)->b.l; - GET_PTR_REG(cpustate,ptr)->b.l = tmp; + m_icount -= 8; + tmp = m_AC; + m_AC = GET_PTR_REG(ptr)->b.l; + GET_PTR_REG(ptr)->b.l = tmp; break; case 0x34: case 0x35 :case 0x36: case 0x37: // XPAH - cpustate->icount -= 8; - tmp = cpustate->AC; - cpustate->AC = GET_PTR_REG(cpustate,ptr)->b.h; - GET_PTR_REG(cpustate,ptr)->b.h = tmp; + m_icount -= 8; + tmp = m_AC; + m_AC = GET_PTR_REG(ptr)->b.h; + GET_PTR_REG(ptr)->b.h = tmp; break; case 0x3c: case 0x3d :case 0x3e: case 0x3f: // XPPC { - UINT16 tmp16 = ADD12(cpustate->PC.w.l,-1); // Since PC is incremented we need to fix it - cpustate->icount -= 7; - cpustate->PC.w.l = GET_PTR_REG(cpustate,ptr)->w.l; - GET_PTR_REG(cpustate,ptr)->w.l = tmp16; + UINT16 tmp16 = ADD12(m_PC.w.l,-1); // Since PC is incremented we need to fix it + m_icount -= 7; + m_PC.w.l = GET_PTR_REG(ptr)->w.l; + GET_PTR_REG(ptr)->w.l = tmp16; // After exchange CPU increment PC - cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1); + m_PC.w.l = ADD12(m_PC.w.l,1); } break; // Shift, Rotate, Serial I/O Instructions case 0x19: // SIO - cpustate->icount -= 5; - cpustate->sout_func(cpustate->ER & 0x01); - cpustate->ER >>= 1; - cpustate->ER |= cpustate->sin_func() ? 0x80 : 0x00; + m_icount -= 5; + m_sout_func(m_ER & 0x01); + m_ER >>= 1; + m_ER |= m_sin_func() ? 0x80 : 0x00; break; case 0x1c: // SR - cpustate->icount -= 5; - cpustate->AC >>= 1; + m_icount -= 5; + m_AC >>= 1; break; case 0x1d: // SRL - cpustate->icount -= 5; - cpustate->AC >>= 1; - cpustate->AC |= cpustate->SR & 0x80; // add C/L flag + m_icount -= 5; + m_AC >>= 1; + m_AC |= m_SR & 0x80; // add C/L flag break; case 0x1e: // RR - cpustate->icount -= 5; - cpustate->AC = (cpustate->AC >> 1) | ((cpustate->AC & 0x01) << 7); + m_icount -= 5; + m_AC = (m_AC >> 1) | ((m_AC & 0x01) << 7); break; case 0x1f: // RRL - cpustate->icount -= 5; - tmp = (cpustate->AC & 0x01) << 7; - cpustate->AC = (cpustate->AC >> 1) | (cpustate->SR & 0x80); - cpustate->SR = (cpustate->SR & 0x7f) | tmp; + m_icount -= 5; + tmp = (m_AC & 0x01) << 7; + m_AC = (m_AC >> 1) | (m_SR & 0x80); + m_SR = (m_SR & 0x7f) | tmp; break; // Single Byte Miscellaneous Instructions case 0x00: // HALT - cpustate->icount -= 8; - cpustate->halt_func(1); - cpustate->halt_func(0); + m_icount -= 8; + m_halt_func(1); + m_halt_func(0); break; case 0x02: // CCL - cpustate->icount -= 5; - cpustate->SR &= 0x7f; + m_icount -= 5; + m_SR &= 0x7f; break; case 0x03: // SCL - cpustate->icount -= 5; - cpustate->SR |= 0x80; + m_icount -= 5; + m_SR |= 0x80; break; case 0x04: // DINT - cpustate->icount -= 6; - cpustate->SR &= 0xf7; + m_icount -= 6; + m_SR &= 0xf7; break; case 0x05: // IEN - cpustate->icount -= 6; - cpustate->SR |= 0x08; + m_icount -= 6; + m_SR |= 0x08; break; case 0x06: // CSA - cpustate->icount -= 5; - cpustate->SR &= 0xcf; // clear SA and SB flags - cpustate->SR |= cpustate->sensea_func() ? 0x10 : 0x00; - cpustate->SR |= cpustate->senseb_func() ? 0x20 : 0x00; - cpustate->AC = cpustate->SR; + m_icount -= 5; + m_SR &= 0xcf; // clear SA and SB flags + m_SR |= m_sensea_func() ? 0x10 : 0x00; + m_SR |= m_senseb_func() ? 0x20 : 0x00; + m_AC = m_SR; break; case 0x07: // CAS - cpustate->icount -= 6; - cpustate->SR = cpustate->AC; - cpustate->flag_out_func(0, cpustate->SR & 0x07); + m_icount -= 6; + m_SR = m_AC; + m_flag_out_func(m_SR & 0x07); break; case 0x08: // NOP - cpustate->icount -= 5; + m_icount -= 5; break; // Others are illegal - default : cpustate->icount -= 1; - illegal (cpustate,opcode); + default : m_icount -= 1; + illegal (opcode); break; } } @@ -457,80 +457,71 @@ static void execute_one(scmp_state *cpustate, int opcode) /*************************************************************************** COMMON EXECUTION ***************************************************************************/ -static void take_interrupt(scmp_state *cpustate) +void scmp_device::take_interrupt() { - UINT16 tmp = ADD12(cpustate->PC.w.l,-1); // We fix PC so at return it goes to current location - cpustate->SR &= 0xf7; // clear IE flag + UINT16 tmp = ADD12(m_PC.w.l,-1); // We fix PC so at return it goes to current location + m_SR &= 0xf7; // clear IE flag - cpustate->icount -= 8; // assumption + m_icount -= 8; // assumption // do XPPC 3 - cpustate->PC.w.l = GET_PTR_REG(cpustate,3)->w.l; - GET_PTR_REG(cpustate,3)->w.l = tmp; + m_PC.w.l = GET_PTR_REG(3)->w.l; + GET_PTR_REG(3)->w.l = tmp; // After exchange CPU increment PC - cpustate->PC.w.l = ADD12(cpustate->PC.w.l,1); + m_PC.w.l = ADD12(m_PC.w.l,1); } -static CPU_EXECUTE( scmp ) +void scmp_device::execute_run() { - scmp_state *cpustate = get_safe_token(device); - do { - if ((cpustate->SR & 0x08) && (cpustate->sensea_func())) { - take_interrupt(cpustate); + if ((m_SR & 0x08) && (m_sensea_func())) { + take_interrupt(); } - debugger_instruction_hook(device, cpustate->PC.d); - execute_one(cpustate, ROP(cpustate)); + debugger_instruction_hook(this, m_PC.d); + execute_one(ROP()); - } while (cpustate->icount > 0); + } while (m_icount > 0); } /*************************************************************************** CORE INITIALIZATION ***************************************************************************/ -static CPU_INIT( scmp ) +void scmp_device::device_start() { - scmp_state *cpustate = get_safe_token(device); - - if (device->static_config() != NULL) - cpustate->config = *(scmp_config *)device->static_config(); - /* set up the state table */ { - device_state_interface *state; - device->interface(state); - state->state_add(SCMP_PC, "PC", cpustate->PC.w.l); - state->state_add(STATE_GENPC, "GENPC", cpustate->PC.w.l).noshow(); - state->state_add(STATE_GENFLAGS, "GENFLAGS", cpustate->SR).noshow().formatstr("%8s"); - state->state_add(SCMP_P1, "P1", cpustate->P1.w.l); - state->state_add(SCMP_P2, "P2", cpustate->P2.w.l); - state->state_add(SCMP_P3, "P3", cpustate->P3.w.l); - state->state_add(SCMP_AC, "AC", cpustate->AC); - state->state_add(SCMP_ER, "ER", cpustate->ER); - state->state_add(SCMP_SR, "SR", cpustate->SR); + state_add(SCMP_PC, "PC", m_PC.w.l); + state_add(STATE_GENPC, "GENPC", m_PC.w.l).noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_SR).noshow().formatstr("%8s"); + state_add(SCMP_P1, "P1", m_P1.w.l); + state_add(SCMP_P2, "P2", m_P2.w.l); + state_add(SCMP_P3, "P3", m_P3.w.l); + state_add(SCMP_AC, "AC", m_AC); + state_add(SCMP_ER, "ER", m_ER); + state_add(SCMP_SR, "SR", m_SR); } - cpustate->device = device; - - cpustate->program = &device->space(AS_PROGRAM); - cpustate->direct = &cpustate->program->direct(); + m_program = &space(AS_PROGRAM); + m_direct = &m_program->direct(); /* resolve callbacks */ - cpustate->flag_out_func.resolve(cpustate->config.flag_out_func, *device); - cpustate->sout_func.resolve(cpustate->config.sout_func, *device); - cpustate->sin_func.resolve(cpustate->config.sin_func, *device); - cpustate->sensea_func.resolve(cpustate->config.sensea_func, *device); - cpustate->senseb_func.resolve(cpustate->config.senseb_func, *device); - cpustate->halt_func.resolve(cpustate->config.halt_func, *device); + m_flag_out_func.resolve_safe(); + m_sout_func.resolve_safe(); + m_sin_func.resolve_safe(0); + m_sensea_func.resolve_safe(0); + m_senseb_func.resolve_safe(0); + m_halt_func.resolve_safe(); - device->save_item(NAME(cpustate->PC)); - device->save_item(NAME(cpustate->P1)); - device->save_item(NAME(cpustate->P2)); - device->save_item(NAME(cpustate->P3)); - device->save_item(NAME(cpustate->AC)); - device->save_item(NAME(cpustate->ER)); - device->save_item(NAME(cpustate->SR)); + save_item(NAME(m_PC)); + save_item(NAME(m_P1)); + save_item(NAME(m_P2)); + save_item(NAME(m_P3)); + save_item(NAME(m_AC)); + save_item(NAME(m_ER)); + save_item(NAME(m_SR)); + + m_icountptr = &m_icount; } @@ -539,17 +530,15 @@ static CPU_INIT( scmp ) COMMON RESET ***************************************************************************/ -static CPU_RESET( scmp ) +void scmp_device::device_reset() { - scmp_state *cpustate = get_safe_token(device); - - cpustate->PC.d = 0; - cpustate->P1.d = 0; - cpustate->P2.d = 0; - cpustate->P3.d = 0; - cpustate->AC = 0; - cpustate->ER = 0; - cpustate->SR = 0; + m_PC.d = 0; + m_P1.d = 0; + m_P2.d = 0; + m_P3.d = 0; + m_AC = 0; + m_ER = 0; + m_SR = 0; } @@ -558,114 +547,21 @@ static CPU_RESET( scmp ) COMMON STATE IMPORT/EXPORT ***************************************************************************/ -static CPU_IMPORT_STATE( scmp ) +void scmp_device::state_string_export(const device_state_entry &entry, astring &string) { -} - -static CPU_EXPORT_STATE( scmp ) -{ -} - -static CPU_EXPORT_STRING( scmp ) -{ - scmp_state *cpustate = get_safe_token(device); - switch (entry.index()) { case STATE_GENFLAGS: string.printf("%c%c%c%c%c%c%c%c", - (cpustate->SR & 0x80) ? 'C' : '.', - (cpustate->SR & 0x40) ? 'V' : '.', - (cpustate->SR & 0x20) ? 'B' : '.', - (cpustate->SR & 0x10) ? 'A' : '.', - (cpustate->SR & 0x08) ? 'I' : '.', - (cpustate->SR & 0x04) ? '2' : '.', - (cpustate->SR & 0x02) ? '1' : '.', - (cpustate->SR & 0x01) ? '0' : '.'); + (m_SR & 0x80) ? 'C' : '.', + (m_SR & 0x40) ? 'V' : '.', + (m_SR & 0x20) ? 'B' : '.', + (m_SR & 0x10) ? 'A' : '.', + (m_SR & 0x08) ? 'I' : '.', + (m_SR & 0x04) ? '2' : '.', + (m_SR & 0x02) ? '1' : '.', + (m_SR & 0x01) ? '0' : '.'); break; } } -/*************************************************************************** - COMMON SET INFO -***************************************************************************/ -static CPU_SET_INFO( scmp ) -{ -} - -/*************************************************************************** - SCMP GET INFO -***************************************************************************/ - -CPU_GET_INFO( scmp ) -{ - scmp_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(scmp_state); break; - case CPUINFO_INT_INPUT_LINES: info->i = 0; break; - case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break; - case CPUINFO_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 = 2; break; - case CPUINFO_INT_MIN_CYCLES: info->i = 5; break; - case CPUINFO_INT_MAX_CYCLES: info->i = 131593; break; // DLY instruction max time - - case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM: info->i = 8; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = 0; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_DATA: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA: info->i = 0; break; - - case CPUINFO_INT_DATABUS_WIDTH + AS_IO: info->i = 0; break; - case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO: info->i = 0; break; - case CPUINFO_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(scmp); break; - case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME(scmp); break; - case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME(scmp); break; - case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME(scmp); break; - case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME(scmp); break; - case CPUINFO_FCT_IMPORT_STATE: info->import_state = CPU_IMPORT_STATE_NAME(scmp); break; - case CPUINFO_FCT_EXPORT_STATE: info->export_state = CPU_EXPORT_STATE_NAME(scmp); break; - case CPUINFO_FCT_EXPORT_STRING: info->export_string = CPU_EXPORT_STRING_NAME(scmp); 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 CPUINFO_STR_NAME: strcpy(info->s, "INS 8050 SC/MP"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ins8050"); break; - case CPUINFO_STR_FAMILY: strcpy(info->s, "National Semiconductor SC/MP"); break; - case CPUINFO_STR_VERSION: strcpy(info->s, "1.0"); break; - case CPUINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case CPUINFO_STR_CREDITS: strcpy(info->s, "Copyright Miodrag Milanovic"); break; - } -} - -/************************************************************************** - * CPU-specific set_info - **************************************************************************/ -CPU_GET_INFO( ins8060 ) -{ - switch (state) - { - /* --- the following bits of info are returned as pointers to data or functions --- */ - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 2; break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case CPUINFO_STR_NAME: strcpy(info->s, "INS 8060 SC/MP II"); break; - case CPUINFO_STR_SHORTNAME: strcpy(info->s, "ins8060"); break; - - default: CPU_GET_INFO_CALL(scmp); break; - } -} - -DEFINE_LEGACY_CPU_DEVICE(SCMP, scmp); -DEFINE_LEGACY_CPU_DEVICE(INS8060, ins8060); diff --git a/src/emu/cpu/scmp/scmp.h b/src/emu/cpu/scmp/scmp.h index d5ac880587f..974ebd079be 100644 --- a/src/emu/cpu/scmp/scmp.h +++ b/src/emu/cpu/scmp/scmp.h @@ -16,28 +16,105 @@ enum SCMP_GENPCBASE = STATE_GENPCBASE }; -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ -struct scmp_config + +#define MCFG_SCMP_CONFIG(_flag_out_devcb, _sout_devcb, _sin_devcb, _sensea_devcb, _senseb_devcb, _halt_devcb) \ + scmp_device::set_flag_out_cb(*device, DEVCB2_##_flag_out_devcb); \ + scmp_device::set_sout_cb(*device, DEVCB2_##_sout_devcb); \ + scmp_device::set_sin_cb(*device, DEVCB2_##_sin_devcb); \ + scmp_device::set_sensea_cb(*device, DEVCB2_##_sensea_devcb); \ + scmp_device::set_senseb_cb(*device, DEVCB2_##_senseb_devcb); \ + scmp_device::set_halt_cb(*device, DEVCB2_##_halt_devcb); + + +class scmp_device : public cpu_device { - devcb_write8 flag_out_func; - devcb_write_line sout_func; - devcb_read_line sin_func; - devcb_read_line sensea_func; - devcb_read_line senseb_func; - devcb_write_line halt_func; +public: + // construction/destruction + scmp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + scmp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + + // static configuration helpers + template static devcb2_base &set_flag_out_cb(device_t &device, _Object object) { return downcast(device).m_flag_out_func.set_callback(object); } + template static devcb2_base &set_sout_cb(device_t &device, _Object object) { return downcast(device).m_sout_func.set_callback(object); } + template static devcb2_base &set_sin_cb(device_t &device, _Object object) { return downcast(device).m_sin_func.set_callback(object); } + template static devcb2_base &set_sensea_cb(device_t &device, _Object object) { return downcast(device).m_sensea_func.set_callback(object); } + template static devcb2_base &set_senseb_cb(device_t &device, _Object object) { return downcast(device).m_senseb_func.set_callback(object); } + template static devcb2_base &set_halt_cb(device_t &device, _Object object) { return downcast(device).m_halt_func.set_callback(object); } + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // device_execute_interface overrides + virtual UINT32 execute_min_cycles() const { return 5; } + virtual UINT32 execute_max_cycles() const { return 131593; } + virtual UINT32 execute_input_lines() const { return 0; } + virtual void execute_run(); + + // device_memory_interface overrides + virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; } + + // device_state_interface overrides + void state_string_export(const device_state_entry &entry, astring &string); + + // device_disasm_interface overrides + virtual UINT32 disasm_min_opcode_bytes() const { return 1; } + virtual UINT32 disasm_max_opcode_bytes() const { return 2; } + virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); + +private: + address_space_config m_program_config; + + PAIR m_PC; + PAIR m_P1; + PAIR m_P2; + PAIR m_P3; + UINT8 m_AC; + UINT8 m_ER; + UINT8 m_SR; + + address_space *m_program; + direct_read_data *m_direct; + int m_icount; + + devcb2_write8 m_flag_out_func; + devcb2_write_line m_sout_func; + devcb2_read_line m_sin_func; + devcb2_read_line m_sensea_func; + devcb2_read_line m_senseb_func; + devcb2_write_line m_halt_func; + + inline UINT16 ADD12(UINT16 addr, INT8 val); + inline UINT8 ROP(); + inline UINT8 ARG(); + inline UINT8 RM(UINT32 a); + inline void WM(UINT32 a, UINT8 v); + inline void illegal(UINT8 opcode); + inline PAIR *GET_PTR_REG(int num); + inline void BIN_ADD(UINT8 val); + inline void DEC_ADD(UINT8 val); + inline UINT16 GET_ADDR(UINT8 code); + void execute_one(int opcode); + void take_interrupt(); + }; -#define SCMP_CONFIG(name) const scmp_config (name) = -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ -DECLARE_LEGACY_CPU_DEVICE(SCMP, scmp); +class ins8060_device : public scmp_device +{ +public: + // construction/destruction + ins8060_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); -CPU_DISASSEMBLE( scmp ); +protected: + virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const { return (clocks + 2 - 1) / 2; } + virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const { return (cycles * 2); } +}; + + +extern const device_type SCMP; +extern const device_type INS8060; -DECLARE_LEGACY_CPU_DEVICE(INS8060, ins8060); #endif