diff --git a/.gitattributes b/.gitattributes index eb5315f9c96..490aaaf0159 100644 --- a/.gitattributes +++ b/.gitattributes @@ -919,6 +919,9 @@ src/emu/clifront.c svneol=native#text/plain src/emu/clifront.h svneol=native#text/plain src/emu/config.c svneol=native#text/plain src/emu/config.h svneol=native#text/plain +src/emu/cpu/8x300/8x300.c svneol=native#text/plain +src/emu/cpu/8x300/8x300.h svneol=native#text/plain +src/emu/cpu/8x300/8x300dasm.c svneol=native#text/plain src/emu/cpu/adsp2100/2100dasm.c svneol=native#text/plain src/emu/cpu/adsp2100/2100ops.c svneol=native#text/plain src/emu/cpu/adsp2100/adsp2100.c svneol=native#text/plain diff --git a/src/emu/cpu/8x300/8x300.c b/src/emu/cpu/8x300/8x300.c new file mode 100644 index 00000000000..1d031be2d4a --- /dev/null +++ b/src/emu/cpu/8x300/8x300.c @@ -0,0 +1,553 @@ +/* + * 8x300.c + * + * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 CPU + * Created on: 18/12/2013 + * + * Written by Barry Rodewald + */ + +#include "debugger.h" +#include "8x300.h" + +#define FETCHOP(a) (m_direct->read_decrypted_word(a)) +#define CYCLES(x) do { m_icount -= (x); } while (0) +#define READPORT(a) (m_io->read_byte(a)) +#define WRITEPORT(a,v) (m_io->write_byte((a), (v))) + +#define SRC ((opcode & 0x1f00) >> 8) +#define DST (opcode & 0x001f) +#define ROTLEN ((opcode & 0x00e0) >> 5) +#define IMM8 (opcode & 0x00ff) +#define IMM5 (opcode & 0x001f) +#define ADDR (opcode & 0x1fff) +#define OP ((opcode & 0xe000) >> 13) +#define SRC_IS_RIGHT_BANK (opcode & 0x0800) +#define DST_IS_RIGHT_BANK (opcode & 0x0008) +#define SRC_LSB ((opcode & 0x0700) >> 8) +#define DST_LSB (opcode & 0x0007) +#define SET_PC(x) do { m_PC = (x); m_AR = m_PC; m_genPC = m_PC << 1; } while (0) +// for XEC intruction, which sets the AR, but not PC, so that after the instruction at the relative address is done, execution +// returns back to next instruction after XEC, unless a JMP or successful NZT is there. +#define SET_AR(x) do { m_AR = (x); m_genPC = m_AR << 1; m_PC--;} while (0) +#define SRC_LATCH do { if(SRC_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0) +#define DST_LATCH do { if(DST_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0) +#define SET_OVF do { if(result & 0xff00) m_OVF = 1; else m_OVF = 0; } while (0) + +const device_type N8X300 = &device_creator; + + +n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : cpu_device(mconfig, N8X300, "Signetics 8X300", tag, owner, clock, "8x300", __FILE__) + , m_program_config("program", ENDIANNESS_BIG, 16, 14, 0) + , m_io_config("io", ENDIANNESS_BIG, 8, 9, 0) +{ +} + +void n8x300_cpu_device::set_reg(UINT8 reg, UINT8 val) +{ + switch(reg) + { + case 0x00: m_AUX = val; break; + case 0x01: m_R1 = val; break; + case 0x02: m_R2 = val; break; + case 0x03: m_R3 = val; break; + case 0x04: m_R4 = val; break; + case 0x05: m_R5 = val; break; + case 0x06: m_R6 = val; break; + case 0x07: m_IVL = val; break; +// OVF is read-only + case 0x09: m_R11 = val; break; + case 0x0f: m_IVR = val; break; + default: logerror("8X300: Invalid register %02x written to.\n",reg); break; + } +} + +UINT8 n8x300_cpu_device::get_reg(UINT8 reg) +{ + switch(reg) + { + case 0x00: return m_AUX; + case 0x01: return m_R1; + case 0x02: return m_R2; + case 0x03: return m_R3; + case 0x04: return m_R4; + case 0x05: return m_R5; + case 0x06: return m_R6; +// IVL is write-only + case 0x08: return m_OVF; + case 0x09: return m_R11; +// IVR is write-only + default: logerror("8X300: Invalid register %02x read.\n",reg); return 0; + } + return 0; +} + +void n8x300_cpu_device::device_start() +{ + m_program = &space(AS_PROGRAM); + m_direct = &m_program->direct(); + m_io = &space(AS_IO); + + save_item(NAME(m_PC)); + save_item(NAME(m_AR)); + save_item(NAME(m_IR)); + save_item(NAME(m_R1)); + save_item(NAME(m_R2)); + save_item(NAME(m_R3)); + save_item(NAME(m_R4)); + save_item(NAME(m_R5)); + save_item(NAME(m_R6)); + save_item(NAME(m_R11)); + save_item(NAME(m_AUX)); + save_item(NAME(m_IVL)); + save_item(NAME(m_IVR)); + save_item(NAME(m_OVF)); + save_item(NAME(m_left_IV)); + save_item(NAME(m_right_IV)); + + // Register state for debugger + state_add( _8X300_PC, "PC", m_PC).mask(0x1fff).formatstr("%04X"); + state_add( _8X300_AR, "AR", m_AR).mask(0x1fff).formatstr("%04X"); + state_add( _8X300_IR, "IR", m_IR).mask(0xffff).formatstr("%04X"); + state_add( _8X300_AUX, "AUX", m_AUX).mask(0xff).formatstr("%02X"); + state_add( _8X300_R1, "R1", m_R1).mask(0xff).formatstr("%02X"); + state_add( _8X300_R2, "R2", m_R2).mask(0xff).formatstr("%02X"); + state_add( _8X300_R3, "R3", m_R3).mask(0xff).formatstr("%02X"); + state_add( _8X300_R4, "R4", m_R4).mask(0xff).formatstr("%02X"); + state_add( _8X300_R5, "R5", m_R5).mask(0xff).formatstr("%02X"); + state_add( _8X300_R6, "R6", m_R6).mask(0xff).formatstr("%02X"); + state_add( _8X300_R11, "R11", m_R11).mask(0xff).formatstr("%02X"); + state_add( _8X300_OVF, "OVF", m_OVF).mask(0x01).formatstr("%01X"); + state_add( _8X300_IVL, "IVL", m_IVL).mask(0xff).formatstr("%02X"); + state_add( _8X300_IVR, "IVR", m_IVR).mask(0xff).formatstr("%02X"); + state_add(STATE_GENPC, "curpc", m_genPC).noshow(); + + m_icountptr = &m_icount; + + // reset registers here, since they are unchanged when /RESET goes low. + m_R1 = 0; + m_R2 = 0; + m_R3 = 0; + m_R4 = 0; + m_R5 = 0; + m_R6 = 0; + m_R11 = 0; + m_IVL = 0; + m_IVR = 0; + m_AUX = 0; +} + +void n8x300_cpu_device::state_string_export(const device_state_entry &entry, astring &string) +{ + switch (entry.index()) + { +// case STATE_GENFLAGS: +// string.printf("%c%c%c%c%c%c", +// break; + } +} + +void n8x300_cpu_device::device_reset() +{ + /* zero registers */ + m_PC = 0; + m_AR = 0; + m_IR = 0; +} + +void n8x300_cpu_device::execute_run() +{ + do + { + UINT16 opcode; + UINT8 src = 0; + UINT8 dst; + UINT8 rotlen; // rotate amount or I/O field length + UINT8 mask; + UINT16 result; + + /* fetch the opcode */ + debugger_instruction_hook(this, m_genPC); + opcode = FETCHOP(m_genPC); + m_PC++; + m_PC &= 0x1fff; + m_AR = m_PC; + m_IR = opcode; + m_genPC = m_PC << 1; + + switch (OP) + { + case 0x00: // MOVE + rotlen = ROTLEN; + if(is_rot(opcode)) // MOVE reg,reg + { + src = get_reg(SRC); + dst = rotate(src,rotlen); + set_reg(DST,dst); + } + else + { + if(rotlen == 0) + rotlen = 8; // 0 = 8-bit I/O field length + if(is_src_reg(opcode) && !(is_dst_reg(opcode))) + { // MOVE reg,IV + DST_LATCH; + mask = ((1 << rotlen)-1); + src = (get_reg(SRC)) << (7-DST_LSB); + mask <<= (7-DST_LSB); + if(DST_IS_RIGHT_BANK) + { + dst = (m_right_IV & ~mask) | (src & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (src & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) + { // MOVE IV,reg + SRC_LATCH; + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB); + else + src = rotate(m_left_IV,7-SRC_LSB); + mask = ((1 << rotlen)-1); + dst = src & mask; + set_reg(DST,dst); + } + else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) + { // MOVE IV,IV + SRC_LATCH; + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB); + else + src = rotate(m_left_IV,7-SRC_LSB); + mask = ((1 << rotlen)-1); + dst = src & mask; + dst <<= (7-DST_LSB); + mask <<= (7-DST_LSB); + if(SRC_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV + { + dst = (m_right_IV & ~mask) | (dst & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (dst & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + } + break; + case 0x01: // ADD + rotlen = ROTLEN; + if(is_rot(opcode)) + { // ADD reg,reg + src = rotate(get_reg(SRC),rotlen); + result = src + m_AUX; + set_reg(DST,result & 0xff); + SET_OVF; + } + else + { + if(rotlen == 0) + rotlen = 8; // 0 = 8-bit I/O field length + if(is_src_reg(opcode) && !(is_dst_reg(opcode))) + { // ADD reg,IV + DST_LATCH; + result = get_reg(SRC) + m_AUX; + mask = ((1 << rotlen)-1); + dst = (result & 0xff) << DST_LSB; + mask <<= DST_LSB; + SET_OVF; + if(DST_IS_RIGHT_BANK) + { + dst = (m_right_IV & ~mask) | (dst & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (dst & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) + { // ADD IV,reg + SRC_LATCH; + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB) & mask; + else + src = rotate(m_left_IV,7-SRC_LSB) & mask; + result = src + m_AUX; + SET_OVF; + set_reg(DST,result & 0xff); + } + else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) + { // ADD IV,IV + SRC_LATCH; + DST_LATCH; + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB) & mask; + else + src = rotate(m_left_IV,7-SRC_LSB) & mask; + result = src + m_AUX; + SET_OVF; + dst = (result << (7-DST_LSB)) & 0xff; + mask <<= (7-DST_LSB); + if(SRC_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data + { + dst = (m_right_IV & ~mask) | (dst & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (dst & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + } + break; + case 0x02: // AND + rotlen = ROTLEN; + if(is_rot(opcode)) + { // AND reg,reg + src = rotate(get_reg(SRC),rotlen); + dst = src & m_AUX; + set_reg(DST,dst); + } + else + { + if(rotlen == 0) + rotlen = 8; // 0 = 8-bit I/O field length + if(is_src_reg(opcode) && !(is_dst_reg(opcode))) + { // AND reg,IV + DST_LATCH; + src = get_reg(SRC) & m_AUX; + mask = ((1 << rotlen)-1); + src <<= (7-DST_LSB); + mask <<= (7-DST_LSB); + if(DST_IS_RIGHT_BANK) + { + dst = (m_right_IV & ~mask) | (src & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (src & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) + { // AND IV,reg + SRC_LATCH; + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB) & mask; + else + src = rotate(m_left_IV,7-SRC_LSB) & mask; + src &= mask; + dst = src & m_AUX; + set_reg(DST,dst); + } + else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) + { // AND IV,IV + SRC_LATCH; + DST_LATCH; + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB) & mask; + else + src = rotate(m_left_IV,7-SRC_LSB) & mask; + src &= mask; + dst = src & m_AUX; + dst <<= (7-DST_LSB); + mask <<= (7-DST_LSB); + if(SRC_IS_RIGHT_BANK) + { + dst = (m_right_IV & ~mask) | (src & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (src & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + } + break; + case 0x03: // XOR + rotlen = ROTLEN; + if(is_rot(opcode)) + { // AND reg,reg + src = rotate(get_reg(SRC),rotlen); + dst = src ^ m_AUX; + set_reg(DST,dst); + } + else + { + if(rotlen == 0) + rotlen = 8; // 0 = 8-bit I/O field length + if(is_src_reg(opcode) && !(is_dst_reg(opcode))) + { // AND reg,IV + DST_LATCH; + src = get_reg(SRC) ^ m_AUX; + mask = ((1 << rotlen)-1); + src <<= (7-DST_LSB); + mask <<= (7-DST_LSB); + if(DST_IS_RIGHT_BANK) + { + dst = (m_right_IV & ~mask) | (src & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (src & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + else if(!(is_src_reg(opcode)) && is_dst_reg(opcode)) + { // AND IV,reg + SRC_LATCH; + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB) & mask; + else + src = rotate(m_left_IV,7-SRC_LSB) & mask; + src &= mask; + dst = src ^ m_AUX; + set_reg(DST,dst); + } + else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode))) + { // AND IV,IV + SRC_LATCH; + DST_LATCH; + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB) & mask; + else + src = rotate(m_left_IV,7-SRC_LSB) & mask; + src &= mask; + dst = src ^ m_AUX; + dst <<= (7-DST_LSB); + mask <<= (7-DST_LSB); + if(SRC_IS_RIGHT_BANK) + { + dst = (m_right_IV & ~mask) | (src & mask); + m_right_IV = dst; + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + dst = (m_left_IV & ~mask) | (src & mask); + m_left_IV = dst; + WRITEPORT(m_IVL,m_left_IV); + } + } + } + break; + case 0x04: // XEC (Execute) + if(is_src_reg(opcode)) + { + src = get_reg(SRC); + src += IMM8; + SET_AR((m_AR & 0x1f00) | src); + } + else + { + SRC_LATCH; + rotlen = ROTLEN; + if(rotlen == 0) + rotlen = 8; // 0 = 8-bit I/O field length + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB); + else + src = rotate(m_left_IV,7-SRC_LSB); + src &= mask; + src += IMM5; + SET_AR((m_AR & 0x1fe0) | (src & 0x1f)); + } + break; + case 0x05: // NZT (Non-zero transfer) + if(is_src_reg(opcode)) + { + src = get_reg(SRC); + if(src != 0) + SET_PC((m_PC & 0x1f00) | IMM8); + } + else + { + SRC_LATCH; + rotlen = ROTLEN; + if(rotlen == 0) + rotlen = 8; // 0 = 8-bit I/O field length + mask = ((1 << rotlen)-1); + if(SRC_IS_RIGHT_BANK) + src = rotate(m_right_IV,7-SRC_LSB); + else + src = rotate(m_left_IV,7-SRC_LSB); + rotate(src,SRC_LSB); + src &= mask; + if(src != 0) + SET_PC((m_PC & 0x1fe0) | IMM5); + } + break; + case 0x06: // XMIT (Transmit) + // the source is actually the destination for this instruction + if(is_src_reg(opcode)) + set_reg(SRC,IMM8); + else + { + SRC_LATCH; + rotlen = ROTLEN; + if(rotlen == 0) + rotlen = 8; // 0 = 8-bit I/O field length + mask = ((1 << rotlen)-1); + dst = IMM5; + mask <<= (7-SRC_LSB); + dst <<= (7-SRC_LSB); + if(SRC_IS_RIGHT_BANK) + { + m_right_IV = (m_right_IV & ~mask) | (dst & mask); + WRITEPORT(m_IVR+0x100,m_right_IV); + } + else + { + m_left_IV = (m_left_IV & ~mask) | (dst & mask); + WRITEPORT(m_IVL,m_left_IV); + } + } + break; + case 0x07: // JMP + SET_PC(ADDR); + break; + } + CYCLES(1); // all instructions take 1 cycle (250ns) + } while (m_icount > 0); +} + +offs_t n8x300_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) +{ + extern CPU_DISASSEMBLE( n8x300 ); + return CPU_DISASSEMBLE_NAME(n8x300)(this, buffer, pc, oprom, opram, options); +} + diff --git a/src/emu/cpu/8x300/8x300.h b/src/emu/cpu/8x300/8x300.h new file mode 100644 index 00000000000..f05ec299551 --- /dev/null +++ b/src/emu/cpu/8x300/8x300.h @@ -0,0 +1,134 @@ +/* + * 8x300.h + * + * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 Microcontroller + * Created on: 18/12/2013 + */ + +#ifndef _8X300_H_ +#define _8X300_H_ + +// Register enumeration +enum +{ + _8X300_PC = 1, + _8X300_AR, + _8X300_IR, + _8X300_AUX, + _8X300_R1, + _8X300_R2, + _8X300_R3, + _8X300_R4, + _8X300_R5, + _8X300_R6, + _8X300_IVL, + _8X300_OVF, + _8X300_R11, + _8X300_UNUSED12, + _8X300_UNUSED13, + _8X300_UNUSED14, + _8X300_UNUSED15, + _8X300_UNUSED16, + _8X300_IVR, + _8X300_LIV, + _8X300_RIV, + _8X300_GENPC +}; + +class n8x300_cpu_device : public cpu_device +{ +public: + // construction/destruction + n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + + // device_execute_interface overrides + virtual UINT32 execute_min_cycles() const { return 1; } + virtual UINT32 execute_max_cycles() const { return 1; } + 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 + { + switch (spacenum) + { + case AS_PROGRAM: return &m_program_config; + case AS_IO: return &m_io_config; + default: return 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 2; } + 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); + + address_space_config m_program_config; + address_space_config m_io_config; + + int m_icount; + + address_space *m_program; + direct_read_data *m_direct; + address_space *m_io; + + UINT16 m_PC; // Program Counter + UINT16 m_AR; // Address Register + UINT16 m_IR; // Instruction Register + UINT8 m_AUX; // Auxiliary Register (second operand for AND, ADD, XOR) + UINT8 m_R1; + UINT8 m_R2; + UINT8 m_R3; + UINT8 m_R4; + UINT8 m_R5; + UINT8 m_R6; + UINT8 m_R11; + UINT8 m_IVL; // Interface vector (I/O) left bank (write-only) + UINT8 m_IVR; // Interface vector (I/O) right bank (write-only) + UINT8 m_OVF; // Overflow register (read-only) + UINT16 m_genPC; + + UINT8 m_left_IV; // IV bank contents, these are latched when IVL or IVR are set + UINT8 m_right_IV; + +private: + inline bool is_rot(UINT16 opcode) + { + if((opcode & 0x1000) || (opcode & 0x0010)) + return false; + else + return true; + } + inline bool is_src_reg(UINT16 opcode) + { + if((opcode & 0x1000)) + return false; + else + return true; + } + inline bool is_dst_reg(UINT16 opcode) + { + if((opcode & 0x0010)) + return false; + else + return true; + } + inline UINT8 rotate(UINT8 s, UINT8 n) // right rotate + { + return ((s & ((UINT8)0xff << n)) >> n) | ((s & ((UINT8)0xff >> (8-n))) << (8-n)); + } + void set_reg(UINT8 reg,UINT8 val); + UINT8 get_reg(UINT8 reg); +}; + +extern const device_type N8X300; + +#endif /* 8X300_H_ */ diff --git a/src/emu/cpu/8x300/8x300dasm.c b/src/emu/cpu/8x300/8x300dasm.c new file mode 100644 index 00000000000..707b3ccdb6e --- /dev/null +++ b/src/emu/cpu/8x300/8x300dasm.c @@ -0,0 +1,149 @@ +/* + * 8x300dasm.c + * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 Microcontroller + * + * Created on: 18/12/2013 + */ + +#include "emu.h" +#include "8x300.h" + +#define SRC ((opcode & 0x1f00) >> 8) +#define DST (opcode & 0x001f) +#define ROTLEN ((opcode & 0x00e0) >> 5) +#define IMM8 (opcode & 0x00ff) +#define IMM5 (opcode & 0x001f) + +static const char *reg_names[32] = +{ + "AUX", "R1", "R2", "R3", "R4", "R5", "R6", "IVL", "OVF", "R11", + "Unused12", "Unused13", "Unused14", "Unused15", "Unused16", "IVR", + "LIV0", "LIV1", "LIV2", "LIV3", "LIV4", "LIV5", "LIV6", "LIV7", + "RIV0", "RIV1", "RIV2", "RIV3", "RIV4", "RIV5", "RIV6", "RIV7" +}; + +// determines if right rotate or I/O field length is to be used +INLINE bool is_rot(UINT16 opcode) +{ + if((opcode & 0x1000) || (opcode & 0x0010)) + return false; + else + return true; +} + +INLINE bool is_src_rot(UINT16 opcode) +{ + if((opcode & 0x1000)) + return false; + else + return true; +} + +CPU_DISASSEMBLE( n8x300 ) +{ + char tmp[16]; + unsigned startpc = pc; + UINT16 opcode = (oprom[pc - startpc] << 8) | oprom[pc+1 - startpc]; + UINT8 inst = opcode >> 13; + pc+=2; + + // determine instruction + switch (inst) + { + case 0x00: + sprintf(buffer,"MOVE "); + strcat(buffer,reg_names[SRC]); + if(is_rot(opcode)) + sprintf(tmp,"(%i),",ROTLEN); + else + sprintf(tmp,",%i,",ROTLEN); + strcat(buffer,tmp); + strcat(buffer,reg_names[DST]); + break; + case 0x01: + sprintf(buffer,"ADD "); + strcat(buffer,reg_names[SRC]); + if(is_rot(opcode)) + sprintf(tmp,"(%i),",ROTLEN); + else + sprintf(tmp,",%i,",ROTLEN); + strcat(buffer,tmp); + strcat(buffer,reg_names[DST]); + break; + case 0x02: + sprintf(buffer,"AND "); + strcat(buffer,reg_names[SRC]); + if(is_rot(opcode)) + sprintf(tmp,"(%i),",ROTLEN); + else + sprintf(tmp,",%i,",ROTLEN); + strcat(buffer,tmp); + strcat(buffer,reg_names[DST]); + break; + case 0x03: + sprintf(buffer,"XOR "); + strcat(buffer,reg_names[SRC]); + if(is_rot(opcode)) + sprintf(tmp,"(%i),",ROTLEN); + else + sprintf(tmp,",%i,",ROTLEN); + strcat(buffer,tmp); + strcat(buffer,reg_names[DST]); + break; + case 0x04: + sprintf(buffer,"XEC "); + strcat(buffer,reg_names[SRC]); + if(is_src_rot(opcode)) + { + sprintf(tmp,",%02XH",IMM8); + strcat(buffer,tmp); + } + else + { + sprintf(tmp,",%i",ROTLEN); + strcat(buffer,tmp); + sprintf(tmp,",%02XH",IMM5); + strcat(buffer,tmp); + } + break; + case 0x05: + sprintf(buffer,"NZT "); + strcat(buffer,reg_names[SRC]); + if(is_src_rot(opcode)) + { + sprintf(tmp,",%02XH",IMM8); + strcat(buffer,tmp); + } + else + { + sprintf(tmp,",%i",ROTLEN); + strcat(buffer,tmp); + sprintf(tmp,",%02XH",IMM5); + strcat(buffer,tmp); + } + break; + case 0x06: + sprintf(buffer,"XMIT "); + if(is_src_rot(opcode)) + { + sprintf(tmp,"%02XH,",IMM8); + strcat(buffer,tmp); + strcat(buffer,reg_names[SRC]); + } + else + { + sprintf(tmp,"%02XH,",IMM5); + strcat(buffer,tmp); + strcat(buffer,reg_names[SRC]); + sprintf(tmp,",%i",ROTLEN); + strcat(buffer,tmp); + } + break; + case 0x07: + sprintf(buffer,"JMP %04XH",opcode & 0x1fff); + break; + } + + + return (pc - startpc); +} diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index de12ce64349..d0d955c98c1 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -66,6 +66,20 @@ $(DRCOBJ): $(DRCDEPS) +#------------------------------------------------- +# Signetics 8X300 / Scientific Micro Systems SMS300 +#@src/emu/cpu/8x300/8x300.h,CPUS += 8X300 +#------------------------------------------------- + +ifneq ($(filter 8X300,$(CPUS)),) +OBJDIRS += $(CPUOBJ)/8x300 +CPUOBJS += $(CPUOBJ)/8x300/8x300.o +DASMOBJS += $(CPUOBJ)/8x300/8x300dasm.o +endif + +$(CPUOBJ)/8x300/8x300.o: $(CPUSRC)/8x300/8x300.c \ + $(CPUSRC)/8x300/8x300.h + #------------------------------------------------- # Acorn ARM series # diff --git a/src/mess/drivers/wicat.c b/src/mess/drivers/wicat.c index 08694eef7fa..68f29a155ae 100644 --- a/src/mess/drivers/wicat.c +++ b/src/mess/drivers/wicat.c @@ -11,6 +11,7 @@ Wicat - various systems. #include "emu.h" #include "cpu/m68000/m68000.h" #include "cpu/z8000/z8000.h" +#include "cpu/8x300/8x300.h" #include "machine/serial.h" #include "machine/6522via.h" #include "machine/mm58274c.h" @@ -19,6 +20,7 @@ Wicat - various systems. #include "video/i8275x.h" #include "machine/am9517a.h" #include "machine/x2212.h" +#include "machine/wd17xx.h" #include "wicat.lh" class wicat_state : public driver_device @@ -159,6 +161,16 @@ static ADDRESS_MAP_START(wicat_video_io, AS_IO, 8, wicat_state) AM_RANGE(0x9000,0x9fff) AM_ROM AM_REGION("g2char",0x0000) ADDRESS_MAP_END +static ADDRESS_MAP_START(wicat_flop_mem, AS_PROGRAM, 16, wicat_state) + AM_RANGE(0x0000, 0x17ff) AM_ROM AM_REGION("wd3", 0x0000) + AM_RANGE(0x1800, 0x1fff) AM_NOP +ADDRESS_MAP_END + +static ADDRESS_MAP_START(wicat_flop_io, AS_IO, 8, wicat_state) + AM_RANGE(0x0000, 0x00ff) AM_RAM // left bank + AM_RANGE(0x0100, 0x01ff) AM_RAM // right bank -- one of these probably is RAM... +ADDRESS_MAP_END + /* Input ports */ static INPUT_PORTS_START( wicat ) @@ -673,8 +685,8 @@ static MACHINE_CONFIG_START( wicat, wicat_state ) MCFG_X2212_ADD("videosram") // XD2210 MCFG_SCREEN_ADD("screen",RASTER) - MCFG_SCREEN_SIZE(400,300) - MCFG_SCREEN_VISIBLE_AREA(0,400-1,0,300-1) + MCFG_SCREEN_SIZE(720,300) + MCFG_SCREEN_VISIBLE_AREA(0,720-1,0,300-1) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_UPDATE_DEVICE("video",i8275x_device,screen_update) @@ -684,6 +696,12 @@ static MACHINE_CONFIG_START( wicat, wicat_state ) MCFG_DEFAULT_LAYOUT(layout_wicat) + /* Winchester Floppy Controller */ + MCFG_CPU_ADD("floppycpu",N8X300,XTAL_8MHz) + MCFG_CPU_PROGRAM_MAP(wicat_flop_mem) + MCFG_CPU_IO_MAP(wicat_flop_io) +// MCFG_FD1795_ADD("fdc") + MACHINE_CONFIG_END /* ROM definition */ @@ -750,14 +768,14 @@ ROM_START( wicat ) ROM_LOAD ("apl.chr", 0x00800, 0x0800, CRC(8c6d698e) SHA1(147dd9296fe2efc6140fa148a6edf673c33f9371) ) // Winchester Floppy Controller (Signetics N8X300I + FD1795) - ROM_REGION(0x1800, "wd3", 0) - ROM_LOAD ("wd3.u95", 0x00000, 0x0800, CRC(80bb0617) SHA1(ac0f3194fcbef77532571baa3fec78b3010528bf) ) - ROM_LOAD ("wd3.u96", 0x00800, 0x0800, CRC(52736e61) SHA1(71c7c9170c733c483393969cb1cb3798b3eb980c) ) - ROM_LOAD ("wd3.u97", 0x01000, 0x0800, CRC(a66619ec) SHA1(5d091ac7c88f2f45b4a05e78bfc7a16c206b31ff) ) + ROM_REGION16_BE(0x1800, "wd3", 0) + ROM_LOAD16_BYTE("wd3.u96", 0x00000, 0x0800, CRC(52736e61) SHA1(71c7c9170c733c483393969cb1cb3798b3eb980c) ) + ROM_LOAD16_BYTE("wd3.u97", 0x00001, 0x0800, CRC(a66619ec) SHA1(5d091ac7c88f2f45b4a05e78bfc7a16c206b31ff) ) + ROM_LOAD ("wd3.u95", 0x01000, 0x0800, CRC(80bb0617) SHA1(ac0f3194fcbef77532571baa3fec78b3010528bf) ) ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 198?, wicat, 0, 0, wicat, wicat, driver_device, 0, "Millennium Systems", "Wicat", GAME_NOT_WORKING | GAME_NO_SOUND_HW ) +COMP( 1982, wicat, 0, 0, wicat, wicat, driver_device, 0, "Millennium Systems", "Wicat System 150", GAME_NOT_WORKING | GAME_NO_SOUND_HW ) diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 5605bb9f103..c3494958f97 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -129,6 +129,7 @@ CPUS += SCORE CPUS += ES5510 CPUS += SCUDSP CPUS += IE15 +CPUS += 8X300 #------------------------------------------------- # specify available sound cores; some of these are