diff options
author | hap <happppp@users.noreply.github.com> | 2014-12-09 03:16:47 +0100 |
---|---|---|
committer | hap <happppp@users.noreply.github.com> | 2014-12-09 03:16:47 +0100 |
commit | cd02eac42e826f78d362f0b5b5e2c5250587d997 (patch) | |
tree | 778411edaaaa6909d1f4d847c760a45675416b0a | |
parent | d3daab0a210dca630e1a864153217ee4c1c95e9a (diff) |
added tmc0270_cpu_device, preliminary
-rw-r--r-- | src/emu/cpu/tms0980/tms0980.c | 175 | ||||
-rw-r--r-- | src/emu/cpu/tms0980/tms0980.h | 32 |
2 files changed, 160 insertions, 47 deletions
diff --git a/src/emu/cpu/tms0980/tms0980.c b/src/emu/cpu/tms0980/tms0980.c index 35898829fee..48413ce93f2 100644 --- a/src/emu/cpu/tms0980/tms0980.c +++ b/src/emu/cpu/tms0980/tms0980.c @@ -91,6 +91,8 @@ unknown cycle: CME, SSE, SSS #define M_STSL 0x00080000 /* STATUS to Status Latch */ #define M_YTP 0x00100000 /* Y to +ALU */ +#define M_RSTR 0x00200000 /* -> F_RSTR */ + /* Standard/fixed instructions - these are documented more in their specific handlers below */ #define F_BR 0x00000001 #define F_CALL 0x00000002 @@ -115,7 +117,7 @@ unknown cycle: CME, SSE, SSS // supported types: -// note: dice information assumes the orientation is pictured with RAM at the bottom-left +// note: dice information assumes the orientation is pictured with RAM at the bottom-left, except where noted // TMS1000 // - 64x4bit RAM array at the bottom-left @@ -127,8 +129,8 @@ unknown cycle: CME, SSE, SSS // - 20-term output PLA(opla) at the top-left // - the ALU is between the opla and mpla const device_type TMS1000 = &device_creator<tms1000_cpu_device>; // 28-pin DIP, 11 R pins -const device_type TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // same as tms1000, just supports higher voltage +const device_type TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins // TMS1270 has 10 O pins, how does that work? // TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM @@ -140,17 +142,23 @@ const device_type TMS1300 = &device_creator<tms1300_cpu_device>; // 40-pin DIP, // - 2048x9bit ROM array at the bottom-left // - main instructions PLA at the top half, to the right of the midline // - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions -// - 16-term output PLA and segment PLA above the RAM -const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins +// - 16-term output PLA and segment PLA above the RAM (rotate opla 90 degrees) +const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins, 5 K pins // TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000 -// - 64x4bit RAM array at the bottom-left -// - 1024x8bit ROM array at the bottom-right +// - RAM and ROM is exactly the same as TMS1000 // - main instructions PLA at the top half, to the right of the midline // - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions -// - 16-term output PLA and segment PLA above the RAM +// - 16-term output PLA and segment PLA above the RAM (rotate opla 90 degrees) const device_type TMS0970 = &device_creator<tms0970_cpu_device>; // 28-pin DIP, 11 R pins +// TMC0270 on the other hand, is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky +// - RAM, ROM, and main instructions PLA is exactly the same as TMS0980 +// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions plus optional separate lines for custom opcode handling +// - 48-term output PLA above the RAM (rotate opla 90 degrees) +const device_type TMC0270 = &device_creator<tmc0270_cpu_device>; // 40-pin DIP, 16 O pins, 8 R pins (the other R pins are internally hooked up to support more I/O) +// TMC0260 is same? except opla is 32 instead of 48 terms + static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1xxx_cpu_device) AM_RANGE(0x000, 0xfff) AM_ROM @@ -232,6 +240,17 @@ tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char { } +tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 k_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source) + : tms0970_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, k_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source) +{ +} + + +tmc0270_cpu_device::tmc0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : tms0980_cpu_device(mconfig, TMC0270, "TMC0270", tag, owner, clock, 16, 8, 4, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tmc0270", __FILE__) +{ +} + static MACHINE_CONFIG_FRAGMENT(tms1000) @@ -287,6 +306,23 @@ machine_config_constructor tms0980_cpu_device::device_mconfig_additions() const } +static MACHINE_CONFIG_FRAGMENT(tmc0270) + + // main opcodes PLA, microinstructions PLA, output PLA + MCFG_PLA_ADD("ipla", 9, 22, 24) + MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY) + MCFG_PLA_ADD("mpla", 6, 21, 64) + MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY) + MCFG_PLA_ADD("opla", 6, 16, 48) + MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY) +MACHINE_CONFIG_END + +machine_config_constructor tmc0270_cpu_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME(tmc0270); +} + + offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) { @@ -357,6 +393,7 @@ void tms1xxx_cpu_device::device_start() m_cs = 0; m_r = 0; m_o = 0; + m_o_latch = 0; m_cki_bus = 0; m_c4 = 0; m_p = 0; @@ -370,7 +407,7 @@ void tms1xxx_cpu_device::device_start() m_clatch = 0; m_add = 0; m_bl = 0; - + m_ram_in = 0; m_dam_in = 0; m_ram_out = 0; @@ -381,6 +418,10 @@ void tms1xxx_cpu_device::device_start() m_micro = 0; m_subcycle = 0; + m_a_prev = m_a; + m_r_prev = m_r; + m_o_prev = m_o; + // register for savestates save_item(NAME(m_pc)); save_item(NAME(m_sr)); @@ -394,6 +435,7 @@ void tms1xxx_cpu_device::device_start() save_item(NAME(m_cs)); save_item(NAME(m_r)); save_item(NAME(m_o)); + save_item(NAME(m_o_latch)); save_item(NAME(m_cki_bus)); save_item(NAME(m_c4)); save_item(NAME(m_p)); @@ -418,6 +460,10 @@ void tms1xxx_cpu_device::device_start() save_item(NAME(m_micro)); save_item(NAME(m_subcycle)); + save_item(NAME(m_a_prev)); + save_item(NAME(m_r_prev)); + save_item(NAME(m_o_prev)); + // register state for debugger state_add(TMS0980_PC, "PC", m_pc ).formatstr("%02X"); state_add(TMS0980_SR, "SR", m_sr ).formatstr("%01X"); @@ -570,11 +616,12 @@ UINT32 tms0980_cpu_device::decode_micro(UINT8 sel) sel = BITSWAP8(sel,7,6,0,1,2,3,4,5); // lines are reversed UINT32 mask = m_mpla->read(sel); mask ^= 0x43fc3; // invert active-negative - + + // note: M_RSTR is specific to TMC02x0, it redirects to F_RSTR // _______ ______ _____ _____ _____ _____ ______ _____ ______ _____ _____ - const UINT32 md[20] = { M_NDMTP, M_DMTP, M_AUTY, M_AUTA, M_CKM, M_SSE, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_SSS, M_CME, M_CIN, M_STO }; + const UINT32 md[21] = { M_NDMTP, M_DMTP, M_AUTY, M_AUTA, M_CKM, M_SSE, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_SSS, M_CME, M_CIN, M_STO, M_RSTR }; - for (int bit = 0; bit < 20; bit++) + for (int bit = 0; bit < 21 && bit < m_mpla->outputs(); bit++) if (mask & (1 << bit)) decode |= md[bit]; @@ -619,7 +666,9 @@ void tms0980_cpu_device::device_reset() - +//------------------------------------------------- +// program counter/opcode decode +//------------------------------------------------- void tms1xxx_cpu_device::next_pc() { @@ -666,6 +715,20 @@ void tms0980_cpu_device::read_opcode() next_pc(); } +void tmc0270_cpu_device::read_opcode() +{ + tms0980_cpu_device::read_opcode(); + + // RSTR is on the mpla + if (m_micro & M_RSTR) + m_fixed |= F_RSTR; +} + + + +//------------------------------------------------- +// i/o handling +//------------------------------------------------- void tms1xxx_cpu_device::write_o_output(UINT8 data) { @@ -684,6 +747,17 @@ void tms0970_cpu_device::write_o_output(UINT8 data) m_write_o(0, m_o & m_o_mask, 0xffff); } + +void tmc0270_cpu_device::dynamic_output() +{ + // TODO.. + + m_a_prev = m_a; + m_r_prev = m_r; + m_o_prev = m_o; +} + + UINT8 tms1xxx_cpu_device::read_k_input() { // K1,2,4,8,3 (KC test pin is not emulated) @@ -692,6 +766,13 @@ UINT8 tms1xxx_cpu_device::read_k_input() return (k & 0xf) | k3; } +UINT8 tmc0270_cpu_device::read_k_input() +{ + // TODO.. + + return tms1xxx_cpu_device::read_k_input(); +} + void tms1xxx_cpu_device::set_cki_bus() { @@ -746,7 +827,10 @@ void tms0980_cpu_device::set_cki_bus() } -// fixed opcode set + +//------------------------------------------------- +// fixed opcode set +//------------------------------------------------- // TMS1000/common: @@ -841,7 +925,7 @@ void tms1xxx_cpu_device::op_comc() } -// TMS09x0-specific +// TMS0970-specific (and possibly child classes) void tms0970_cpu_device::op_setr() { // SETR: set output register @@ -858,7 +942,7 @@ void tms0970_cpu_device::op_tdo() } -// TMS0980-specific +// TMS0980-specific (and possibly child classes) void tms0980_cpu_device::op_comx() { // COMX: complement X register, but not the MSB @@ -904,38 +988,24 @@ void tms1xxx_cpu_device::op_sbl() } -void tms1xxx_cpu_device::execute_fixed_opcode() +// TMC0270-specific +void tmc0270_cpu_device::op_tdo() { - switch (m_fixed) - { - case F_SBIT: op_sbit(); break; - case F_RBIT: op_rbit(); break; - case F_SETR: op_setr(); break; - case F_RSTR: op_rstr(); break; - case F_TDO: op_tdo(); break; - case F_CLO: op_clo(); break; - case F_LDX: op_ldx(); break; - case F_COMX: op_comx(); break; - case F_COMX8:op_comx8();break; - case F_LDP: op_ldp(); break; - case F_COMC: op_comc(); break; - case F_OFF: op_off(); break; - case F_SEAC: op_seac(); break; - case F_REAC: op_reac(); break; - case F_SAL: op_sal(); break; - case F_SBL: op_sbl(); break; - case F_XDA: op_xda(); break; - - default: - // BR, CALL, RETN are handled in execute_run - if (m_fixed & ~(F_BR | F_CALL | F_RETN)) - fatalerror("%s unsupported fixed opcode %03X %04X!\n", tag(), m_opcode, m_fixed); - break; - } + // TDO: transfer data out + if (m_status) + m_o_latch = m_a; + else + m_o = m_o_latch | (m_a << 4 & 0x30); + + // handled further in dynamic_output } +//------------------------------------------------- +// execute_run +//------------------------------------------------- + void tms1xxx_cpu_device::execute_run() { do @@ -995,6 +1065,7 @@ void tms1xxx_cpu_device::execute_run() // execute: k input valid, read ram, clear alu inputs set_cki_bus(); + dynamic_output(); m_ram_in = m_data->read_byte(m_ram_address) & 0xf; m_dam_in = m_data->read_byte(m_ram_address | (0x10 << (m_x_bits-1))) & 0xf; m_ram_out = -1; @@ -1056,8 +1127,24 @@ void tms1xxx_cpu_device::execute_run() if (m_micro & M_STO || (m_micro & M_CME && m_eac == m_add)) m_ram_out = m_a; - // handle the fixed opcodes here - execute_fixed_opcode(); + // handle the other fixed opcodes here + if (m_fixed & F_SBIT) op_sbit(); + if (m_fixed & F_RBIT) op_rbit(); + if (m_fixed & F_SETR) op_setr(); + if (m_fixed & F_RSTR) op_rstr(); + if (m_fixed & F_TDO) op_tdo(); + if (m_fixed & F_CLO) op_clo(); + if (m_fixed & F_LDX) op_ldx(); + if (m_fixed & F_COMX) op_comx(); + if (m_fixed & F_COMX8) op_comx8(); + if (m_fixed & F_LDP) op_ldp(); + if (m_fixed & F_COMC) op_comc(); + if (m_fixed & F_OFF) op_off(); + if (m_fixed & F_SEAC) op_seac(); + if (m_fixed & F_REAC) op_reac(); + if (m_fixed & F_SAL) op_sal(); + if (m_fixed & F_SBL) op_sbl(); + if (m_fixed & F_XDA) op_xda(); // execute: write ram if (m_ram_out != -1) diff --git a/src/emu/cpu/tms0980/tms0980.h b/src/emu/cpu/tms0980/tms0980.h index 25556f0121f..dfbaf22c8c9 100644 --- a/src/emu/cpu/tms0980/tms0980.h +++ b/src/emu/cpu/tms0980/tms0980.h @@ -83,11 +83,11 @@ protected: void state_string_export(const device_state_entry &entry, astring &string); void next_pc(); - void execute_fixed_opcode(); - + virtual void write_o_output(UINT8 data); virtual UINT8 read_k_input(); virtual void set_cki_bus(); + virtual void dynamic_output() { ; } // not used by default virtual void read_opcode(); virtual void op_sbit(); @@ -122,13 +122,17 @@ protected: UINT8 m_pa; // 4-bit page address register UINT8 m_pb; // 4-bit page buffer register UINT8 m_a; // 4-bit accumulator + UINT8 m_a_prev; UINT8 m_x; // 2,3,or 4-bit RAM X register UINT8 m_y; // 4-bit RAM Y register UINT8 m_ca; // chapter address bit UINT8 m_cb; // chapter buffer bit UINT8 m_cs; // chapter subroutine bit UINT16 m_r; + UINT16 m_r_prev; UINT16 m_o; + UINT16 m_o_prev; + UINT16 m_o_latch; // TMC0270 hold latch UINT8 m_cki_bus; UINT8 m_c4; UINT8 m_p; // 4-bit adder p(lus)-input @@ -258,6 +262,7 @@ class tms0980_cpu_device : public tms0970_cpu_device { public: tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 k_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source); protected: // overrides @@ -273,11 +278,31 @@ protected: virtual void read_opcode(); virtual void op_comx(); -private: + UINT32 decode_micro(UINT8 sel); }; +class tmc0270_cpu_device : public tms0980_cpu_device +{ +public: + tmc0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + // overrides + virtual machine_config_constructor device_mconfig_additions() const; + + virtual void write_o_output(UINT8 data) { tms1xxx_cpu_device::write_o_output(data); } + virtual UINT8 read_k_input(); + virtual void dynamic_output(); + virtual void read_opcode(); + + virtual void op_setr() { tms1xxx_cpu_device::op_setr(); } + virtual void op_rstr() { tms1xxx_cpu_device::op_rstr(); } + virtual void op_tdo(); +}; + + extern const device_type TMS1000; extern const device_type TMS1070; @@ -286,6 +311,7 @@ extern const device_type TMS1100; extern const device_type TMS1300; extern const device_type TMS0970; extern const device_type TMS0980; +extern const device_type TMC0270; #endif /* _TMS0980_H_ */ |