From 75ce6af1337c4f795d9d32b63b8e97da36b5851c Mon Sep 17 00:00:00 2001 From: Wilbert Pol Date: Fri, 26 Jun 2009 17:49:45 +0000 Subject: [PATCH] Added TMS0980 cpu core. --- .gitattributes | 3 + src/emu/cpu/cpu.mak | 18 + src/emu/cpu/tms0980/tms0980.c | 872 +++++++++++++++++++++++++++++++++ src/emu/cpu/tms0980/tms0980.h | 27 + src/emu/cpu/tms0980/tms0980d.c | 189 +++++++ src/mame/mame.mak | 1 + 6 files changed, 1110 insertions(+) create mode 100644 src/emu/cpu/tms0980/tms0980.c create mode 100644 src/emu/cpu/tms0980/tms0980.h create mode 100644 src/emu/cpu/tms0980/tms0980d.c diff --git a/.gitattributes b/.gitattributes index df714ec9ff7..f2bfb11adc0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -390,6 +390,9 @@ src/emu/cpu/tlcs900/900tbl.c svneol=native#text/plain src/emu/cpu/tlcs900/dasm900.c svneol=native#text/plain src/emu/cpu/tlcs900/tlcs900.c svneol=native#text/plain src/emu/cpu/tlcs900/tlcs900.h svneol=native#text/plain +src/emu/cpu/tms0980/tms0980.c svneol=native#text/plain +src/emu/cpu/tms0980/tms0980.h svneol=native#text/plain +src/emu/cpu/tms0980/tms0980d.c svneol=native#text/plain src/emu/cpu/tms32010/32010dsm.c svneol=native#text/plain src/emu/cpu/tms32010/dis32010.c svneol=native#text/plain src/emu/cpu/tms32010/tms32010.c svneol=native#text/plain diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index df48b5bb915..f1968df5e80 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -1271,6 +1271,24 @@ $(CPUOBJ)/ssp1610/ssp1601.o: $(CPUSRC)/ssp1601/ssp1601.c \ +#------------------------------------------------- +# Texas Instruments TMS0980 +#------------------------------------------------- + +ifneq ($(filter TMS0980,$(CPUS)),) +OBJDIRS += $(CPUOBJ)/tms0980 +CPUOBJS += $(CPUOBJ)/tms0980/tms0980.o +DBGOBJS += $(CPUOBJ)/tms0980/tms0980d.o +endif + +$(CPUOBJ)/tms0980/tms0980.o: $(CPUSRC)/tms0980/tms0980.h \ + $(CPUSRC)/tms0980/tms0980.c + +$(CPUOBJ)/tms0980/tms0980d.o: $(CPUSRC)/tms0980/tms0980.h \ + $(CPUSRC)/tms0980/tms0980d.c + + + #------------------------------------------------- # Texas Instruments TMS7000 series #------------------------------------------------- diff --git a/src/emu/cpu/tms0980/tms0980.c b/src/emu/cpu/tms0980/tms0980.c new file mode 100644 index 00000000000..fa431dc5b78 --- /dev/null +++ b/src/emu/cpu/tms0980/tms0980.c @@ -0,0 +1,872 @@ +/* + +This CPU core has not been thoroughly tested. Several features may still be +incomplete, missing, or broken. [Wilbert Pol] + + +TMS0980 CPU core + +Each instruction takes 12 cycles to execute in 2 phases: a fetch phase and an +execution phase. The execution phase takes place at the same time as the fetch +phase of the next instruction. So, during execution there are both fetch and +execution operations taking place. The operation can be split up as follows: +cycle #0 + - Fetch: + 1. ROM address 0 + - Execute: + 1. Read RAM + 2. Clear ALU inputs + 3. Execute BRANCH/CALL/RETN part #2 + 4. K input valid +cycle #1 + - Fetch: + 1. ROM address 1 + - Execute: + 1. Update ALU inputs +cycle #2 + - Fetch: + 1. nothing/wait(?) + - Execute: + 1. Perform ALU operation + 2. Write RAM +cycle #3 + - Fetch: + 1. Fetch/Update PC/RAM address #1 + - Execute: + 1. Register store part #1 +cycle #4 + - Fetch: + 1. Fetch/Update PC/RAM address #2 + - Execute: + 1. Register store part #2 +cycle #5 + - Fetch: + 1. Instruction decode + - Execute: + 1. Execute BRANCH/CALL/RETN part #1 + +Instructions built from microinstructions: + +ACACC 000111011* CKP, ATN, C8, AUTA + 00111cccc +ACNAA 000111100* CKP, NATN, AUTA + 01100cccc +ALEC 000111110* CIN, CKP, NATN, C8 + 01110cccc +ALEM 000000001 MTP, NATN, CIN, C8 +AMAAC 000010101 ATN, MTP, C8, AUTA +BRANCH 10wwwwwww no microinstructions +CALL 11wwwwwww no microinstructions +CCLA 000010010 AUTA, SSS +CLA 000000110 AUTA +COMX 000000000 no microinstructions +COMX8 010110010 no microinstructions +CPAIZ 000110001 NATN, CIN, C8, AUTA +CTMDYN 000011000 YTP, 15TN, C8, CME, AUTY +DMAN 000000111 MTP, 15TN, C8, AUTA +DMEA 000010000 MTP, DMTP, SSS, AUTA +DNAA 000010001 DMTP, NATN, SSS, AUTA +DYN 000000100 YTP, 15TN, C8, AUTY +IMAC 000110010 MTP, CIN, C8, AUTA +IYC 000000101 YTP, CIN, C8, AUTY +KNEZ 000001110 CKP, NE +LDP 01000cccc no microinstructions +LDX 01001cccc no microinstructions +MNEA 000001001 MTP, ATN, NE +MNEZ 000110011 MTP, NE +NDMEA 000010011 MTN, NDMTP, SSS, AUTA +OFF 010110110 +RBIT 0101001bb no microinstructions +REAC 010110100 no microinstructions +RETN 010111111 no microinstructions +SAL 010110001 no microinstructions +SAMAN 000110000 MTP, NATN, CIN, C8, AUTA +SBIT 0101000bb no microinstructions +SBL 010110011 no microinstructions +SEAC 010110101 no microinstructions +SETR 000001101 YTP, 15TN, AUTY, C8 +TAM 000101111 STO +TAMACS 000111101* STO, ATN, CKP, AUTA, SSE + 01101cccc +TAMDYN 000101100 STO, YTP, 15TN, AUTY, C8 +TAMIYC 000101101 STO, YTP, CIN, C8, AUTY +TAMZA 000101110 STO, AUTA +TAY 000101000 ATN, AUTY +TBIT 0001000bb CKP, CKN, MTP, NE +TCMIY 000111010* CKM, YTP, CIN, AUTY + 00110cccc +TCY 000111000* CKP, AUTY + 00100cccc +TDO 010110000 no microinstructions +TKA 000001000 CKP, AUTA +TKM 000001010 CKM +TMA 000101001 MTP, AUTA +TMY 000101010 MTP, AUTY +TYA 000101011 YTP, AUTA +XDA 000011001 DMTP, AUTA, STO +XMA 000000011 MTP, STO, AUTA +YMCY 000111111* CIN, YTP, CKN, AUTY + 01111cccc +YNEA 000000010 YTP, ATN, NE +YNEC 000111001* YTP, CKN, NE + 00101cccc +* = faked/special decode variant of instruction + +Microinstructions: +15TN - 15 to -ALU +ATN - ACC to -ALU +AUTA - ALU to ACC +AUTY - ALU to Y +C8 - CARRY8 to STATUS +CIN - Carry In to ALU +CKM - CKB to MEM +CKN - CKB to -ALU +CKP - CKB to +ALU +CME - Conditional Memory Enable +DMTP - DAM to +ALU +MTN - MEM to -ALU +MTP - MEM to +ALU +NATN - ~ACC to -ALU +NDMTP - ~DAM to +ALU +NE - COMP to STATUS +SSE - Special Status Enable +SSS - Special Status Sample +STO - ACC to MEM +YTP - Y to +ALU + +cycle #0: 15TN, ATN, CIN, CKN, CKP, DMTP, MTN, MTP, NATN, NDMTP, YTP +cycle #2: C8(?), CKM, NE(?), STO +cycle #3,#4: AUTA, AUTY + +unknown: CME, SSE, SSS + +*/ + +#include "debugger.h" +#include "tms0980.h" +#include "deprecat.h" + +#define LOG 1 + +#define MICRO_MASK 0x80000000 +#define FIXED_INSTRUCTION 0x00000000 + +/* Standard/fixed intructions */ +#define F_ILL 0x00000000 +#define F_BR 0x00000001 +#define F_CALL 0x00000002 +#define F_CLO 0x00000004 +#define F_COMX 0x00000008 +#define F_COMX8 0x00000010 +#define F_LDP 0x00000020 +#define F_LDX 0x00000040 +#define F_OFF 0x00000080 +#define F_RBIT 0x00000100 +#define F_REAC 0x00000200 +#define F_RETN 0x00000400 +#define F_SAL 0x00000800 +#define F_SBIT 0x00001000 +#define F_SBL 0x00002000 +#define F_SEAC 0x00004000 +#define F_SETR 0x00008000 +#define F_TDO 0x00010000 + +/* Microinstructions */ +#define M_15TN 0x00000001 +#define M_ATN 0x00000002 +#define M_AUTA 0x00000004 +#define M_AUTY 0x00000008 +#define M_C8 0x00000010 +#define M_CIN 0x00000020 +#define M_CKM 0x00000040 +#define M_CKN 0x00000080 +#define M_CKP 0x00000100 +#define M_CME 0x00000200 +#define M_DMTP 0x00000400 +#define M_MTN 0x00000800 +#define M_MTP 0x00001000 +#define M_NATN 0x00002000 +#define M_NDMTP 0x00004000 +#define M_NE 0x00008000 +#define M_SSE 0x00010000 +#define M_SSS 0x00020000 +#define M_STO 0x00040000 +#define M_YTP 0x00080000 + +/* instructions built from microinstructions */ +#define I_ACACC ( MICRO_MASK | M_CKP | M_ATN | M_C8 | M_AUTA ) +#define I_ACNAA ( MICRO_MASK | M_CKP | M_NATN | M_AUTA ) +#define I_ALEC ( MICRO_MASK | M_CKP | M_NATN | M_CIN | M_C8 ) +#define I_ALEM ( MICRO_MASK | M_MTP | M_NATN | M_CIN | M_C8 ) +#define I_AMAAC ( MICRO_MASK | M_MTP | M_ATN | M_C8 | M_AUTA ) +#define I_CCLA ( MICRO_MASK | M_AUTA | M_SSS ) +#define I_CLA ( MICRO_MASK | M_AUTA ) +#define I_CPAIZ ( MICRO_MASK | M_NATN | M_CIN | M_C8 | M_AUTA ) +#define I_CTMDYN ( MICRO_MASK | M_YTP | M_15TN | M_C8 | M_AUTY | M_CME ) +#define I_DMAN ( MICRO_MASK | M_MTP | M_15TN | M_C8 | M_AUTA ) +#define I_DMEA ( MICRO_MASK | M_MTP | M_DMTP | M_SSS | M_AUTA ) +#define I_DNAA ( MICRO_MASK | M_DMTP | M_NATN | M_SSS | M_AUTA ) +#define I_DYN ( MICRO_MASK | M_YTP | M_15TN | M_C8 | M_AUTY ) +#define I_IMAC ( MICRO_MASK | M_MTP | M_CIN | M_C8 | M_AUTA ) +#define I_IYC ( MICRO_MASK | M_YTP | M_CIN | M_C8 | M_AUTY ) +#define I_KNEZ ( MICRO_MASK | M_CKP | M_NE ) +#define I_MNEA ( MICRO_MASK | M_MTP | M_ATN | M_NE ) +#define I_MNEZ ( MICRO_MASK | M_MTP | M_NE ) +#define I_M_NDMEA ( MICRO_MASK | M_MTN | M_NDTMP | M_SSS | M_AUTA ) +#define I_SAMAN ( MICRO_MASK | M_MTP | M_NATN | M_CIN | M_C8 | M_AUTA ) +#define I_SETR ( MICRO_MASK | M_YTP | M_15TN | M_AUTY | M_C8 ) +#define I_TAM ( MICRO_MASK | M_STO ) +#define I_TAMACS ( MICRO_MASK | M_STO | M_ATN | M_CKP | M_AUTA | M_SSE ) +#define I_TAMDYN ( MICRO_MASK | M_STO | M_YTP | M_15TN | M_AUTY | M_C8 ) +#define I_TAMIYC ( MICRO_MASK | M_STO | M_YTP | M_CIN | M_C8 | M_AUTY ) +#define I_TAMZA ( MICRO_MASK | M_STO | M_AUTA ) +#define I_TAY ( MICRO_MASK | M_ATN | M_AUTY ) +#define I_TBIT ( MICRO_MASK | M_CKP | M_CKN | M_MTP | M_NE ) +#define I_TCY ( MICRO_MASK | M_CKP | M_AUTY ) +#define I_TCMIY ( MICRO_MASK | M_CKM | M_YTP | M_CIN | M_AUTY ) +#define I_TKA ( MICRO_MASK | M_CKP | M_AUTA ) +#define I_TKM ( MICRO_MASK | M_CKM ) +#define I_TMA ( MICRO_MASK | M_MTP | M_AUTA ) +#define I_TMY ( MICRO_MASK | M_MTP | M_AUTY ) +#define I_TYA ( MICRO_MASK | M_YTP | M_AUTA ) +#define I_XDA ( MICRO_MASK | M_DMTP | M_AUTA | M_STO ) +#define I_XMA ( MICRO_MASK | M_MTP | M_STO | M_AUTA ) +#define I_YMCY ( MICRO_MASK | M_CIN | M_YTP | M_CKN | M_AUTY ) +#define I_YNEA ( MICRO_MASK | M_YTP | M_ATN | M_NE ) +#define I_YNEC ( MICRO_MASK | M_YTP | M_CKN | M_NE ) + + +typedef struct _tms0980_state tms0980_state; +struct _tms0980_state +{ + UINT8 prev_pc; /* previous program counter */ + UINT8 prev_pa; /* previous page address register */ + UINT8 pc; /* program counter is a 7 bit register */ + UINT8 pa; /* page address register is a 4 bit register */ + UINT8 sr; /* subroutine return register is a 7 bit register */ + UINT8 pb; /* page buffer register is a 4 bit register */ + UINT8 a; /* Accumulator is a 4 bit register (?) */ + UINT8 x; /* X-register is a 2 bit register */ + UINT8 y; /* Y-register is a 4 bit register */ + UINT8 dam; /* DAM register is a 4 bit register */ + UINT16 r; + UINT8 o; + UINT8 cki_bus; /* CKI bus */ + UINT8 p; /* adder p-input */ + UINT8 n; /* adder n-input */ + UINT8 adder_result; /* adder result */ + UINT8 carry_in; /* carry in */ + UINT8 status; + UINT8 status_latch; + UINT8 special_status; + UINT8 call_latch; + UINT8 add_latch; + UINT8 branch_latch; + read8_device_func read_k; + write8_device_func write_o; + write16_device_func write_r; + int subcycle; + UINT8 ram_address; + UINT16 ram_data; + UINT16 rom_address; + UINT16 opcode; + UINT32 decode; + int icount; + const tms0980_config *config; + const address_space *program; + const address_space *data; +}; + + +static const UINT8 tms0980_c_value[16] = +{ + 0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F +}; +static const UINT8 tms0980_bit_value[4] = { 1, 4, 2, 8 }; +static const UINT8 tms0980_nbit_value[4] = { 0x0E, 0x0B, 0x0D, 0x07 }; + + +static const UINT32 tms0980_decode[512] = +{ + /* 0x000 */ + F_COMX, I_ALEM, I_YNEA, I_XMA, I_DYN, I_IYC, I_CLA, I_DMAN, + I_TKA, I_MNEA, I_TKM, F_ILL, F_ILL, F_SETR, I_KNEZ, F_ILL, + I_DMEA, I_DNAA, I_CCLA, I_DMEA, F_ILL, I_AMAAC, F_ILL, F_ILL, + I_CTMDYN, I_XDA, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, + I_TBIT, I_TBIT, I_TBIT, I_TBIT, F_ILL, F_ILL, F_ILL, F_ILL, + I_TAY, I_TMA, I_TMY, I_TYA, I_TAMDYN, I_TAMIYC, I_TAMZA, I_TAM, + I_SAMAN, I_CPAIZ, I_IMAC, I_MNEZ, F_ILL, F_ILL, F_ILL, F_ILL, + I_TCY, I_YNEC, I_TCMIY, I_ACACC, I_ACNAA, I_TAMACS, I_ALEC, I_YMCY, + /* 0x040 */ + I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, + I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, I_TCY, + I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, + I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, I_YNEC, + I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, + I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, I_TCMIY, + I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, + I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, I_ACACC, + /* 0x080 */ + F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, + F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, F_LDP, + F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, + F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, F_LDX, + F_SBIT, F_SBIT, F_SBIT, F_SBIT, F_RBIT, F_RBIT, F_RBIT, F_RBIT, + F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, + F_TDO, F_SAL, F_COMX8, F_SBL, F_REAC, F_SEAC, F_OFF, F_ILL, + F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_ILL, F_RETN, + /* 0x0c0 */ + I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, + I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, I_ACNAA, + I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, + I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, I_TAMACS, + I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, + I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, I_ALEC, + I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, + I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, I_YMCY, + /* 0x100 */ + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + /* 0x140 */ + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, F_BR, + /* 0x180 */ + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + /* 0x1c0 */ + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, + F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL, F_CALL +}; + + +INLINE tms0980_state *get_safe_token(const device_config *device) +{ + assert(device != NULL); + assert(device->token != NULL); + assert(device->type == CPU); + assert(cpu_get_type(device) == CPU_TMS0980); + return (tms0980_state *)device->token; +} + + +static ADDRESS_MAP_START(tms0980_internal_rom, ADDRESS_SPACE_PROGRAM, 16) + AM_RANGE( 0x0000, 0x07FF ) AM_ROM +ADDRESS_MAP_END + + +static ADDRESS_MAP_START(tms0980_internal_ram, ADDRESS_SPACE_DATA, 8) + AM_RANGE( 0x0000, 0x0FFF ) AM_RAM +ADDRESS_MAP_END + + +static CPU_INIT( tms0980 ) +{ + tms0980_state *cpustate = get_safe_token( device ); + + cpustate->config = (const tms0980_config *) device->static_config; + + cpustate->program = memory_find_address_space( device, ADDRESS_SPACE_PROGRAM ); + cpustate->data = memory_find_address_space( device, ADDRESS_SPACE_DATA ); + + state_save_register_device_item( device, 0, cpustate->prev_pc ); + state_save_register_device_item( device, 0, cpustate->prev_pa ); + state_save_register_device_item( device, 0, cpustate->pc ); + state_save_register_device_item( device, 0, cpustate->pa ); + state_save_register_device_item( device, 0, cpustate->sr ); + state_save_register_device_item( device, 0, cpustate->pb ); + state_save_register_device_item( device, 0, cpustate->a ); + state_save_register_device_item( device, 0, cpustate->x ); + state_save_register_device_item( device, 0, cpustate->y ); + state_save_register_device_item( device, 0, cpustate->dam ); + state_save_register_device_item( device, 0, cpustate->r ); + state_save_register_device_item( device, 0, cpustate->o ); + state_save_register_device_item( device, 0, cpustate->cki_bus ); + state_save_register_device_item( device, 0, cpustate->p ); + state_save_register_device_item( device, 0, cpustate->n ); + state_save_register_device_item( device, 0, cpustate->adder_result ); + state_save_register_device_item( device, 0, cpustate->carry_in ); + state_save_register_device_item( device, 0, cpustate->status ); + state_save_register_device_item( device, 0, cpustate->status_latch ); + state_save_register_device_item( device, 0, cpustate->special_status ); + state_save_register_device_item( device, 0, cpustate->call_latch ); + state_save_register_device_item( device, 0, cpustate->add_latch ); + state_save_register_device_item( device, 0, cpustate->branch_latch ); + state_save_register_device_item( device, 0, cpustate->subcycle ); + state_save_register_device_item( device, 0, cpustate->ram_address ); + state_save_register_device_item( device, 0, cpustate->ram_data ); + state_save_register_device_item( device, 0, cpustate->rom_address ); + state_save_register_device_item( device, 0, cpustate->opcode ); + state_save_register_device_item( device, 0, cpustate->decode ); +} + + +static CPU_RESET( tms0980 ) +{ + tms0980_state *cpustate = get_safe_token( device ); + + cpustate->pa = 0x0F; + cpustate->pb = 0x0F; + cpustate->pc = 0; + cpustate->dam = 0; + cpustate->subcycle = 0; + cpustate->status = 1; + cpustate->call_latch = 0; + cpustate->add_latch = 0; + cpustate->branch_latch = 0; + cpustate->r = 0; + cpustate->o = 0; + cpustate->ram_address = 0; + cpustate->decode = 0; + cpustate->opcode = 0; + cpustate->read_k = NULL; + cpustate->write_o = NULL; + cpustate->write_r = NULL; + if ( cpustate->config ) + { + cpustate->read_k = cpustate->config->read_k; + cpustate->write_o = cpustate->config->write_o; + cpustate->write_r = cpustate->config->write_r; + } +} + + +/* emulator for the program counter increment on the tms0980/tmc0980 mcu; + see patent 4064554 figure 19 (on page 13) for an explanation of feedback: + + nand324 = NAND of PC0 thru pc4, i.e. output is true if ((pc&0x1f) != 0x1f) + nand323 = NAND of pc5, pc6 and nand324 + i.e. output is true, if ((pc&0x1f)==0x1f) || pc5 is 0 || pc 6 is 0 + or321 = OR of pc5 and pc6, i.e. output is true if ((pc&0x60) != 0) + nand322 = NAND of pc0 thru pc5 plus /pc6, + i.e. output is true if (pc != 0x3f) + nand325 = nand pf nand323, or321 and nand322 + This one is complex: + / or321 means if pc&0x60 is zero, output MUST be true + \ nand323 means if (pc&0x60=0x60) && (pc&0x1f != 0x1f), output MUST be true + nand322 means if pc = 0x3f, output MUST be true + hence, nand325 is if pc = 0x7f, false. if pc = 0x3f, true. if pc&0x60 is zero OR pc&0x60 is 0x60, true. otherwise, false. + + tms0980_nect_pc below implements an indentical function to this in a somewhat more elegant way. +*/ +INLINE UINT8 tms0980_next_pc( UINT8 pc ) +{ + UINT8 xor = ( pc & 0x3F ) == 0x3F ? 1 : 0; + UINT8 new_bit = ( ( pc ^ ( pc << 1 ) ) & 0x40 ) ? xor : 1 - xor; + + return ( pc << 1 ) | new_bit; +} + + +static void tms0980_set_cki_bus( const device_config *device ) +{ + tms0980_state *cpustate = get_safe_token( device ); + + switch( cpustate->opcode & 0xF8 ) + { + case 0x08: + if ( cpustate->read_k ) + { + cpustate->cki_bus = cpustate->read_k( device, 0 ); + } + else + { + cpustate->cki_bus = 0x0F; + } + break; + case 0x20: case 0x28: + cpustate->cki_bus = 0; + break; + case 0x30: + case 0x38: + cpustate->cki_bus = tms0980_nbit_value[ cpustate->opcode & 0x03 ]; + break; + case 0x00: + case 0x40: case 0x48: + case 0x50: case 0x58: + case 0x60: case 0x68: + case 0x70: case 0x78: + cpustate->cki_bus = tms0980_c_value[ cpustate->opcode & 0x0F ]; + break; + } + cpustate->cki_bus = 0x0F; + /* Case 000001XXX */ + if ( ( cpustate->opcode & 0x1F8 ) == 0x008 ) + { + } + /* Case 00001XXXX */ + if ( ( cpustate->opcode & 0x1F0 ) == 0x010 ) + { + } + /* Case 00100XXXX - TCY */ + if ( ( cpustate->opcode & 0x1F0 ) == 0x040 ) + { + } + /* Case 01XXXXXXX */ + if ( ( cpustate->opcode & 0x180 ) == 0x080 ) + { + } +} + + +static CPU_EXECUTE( tms0980 ) +{ + tms0980_state *cpustate = get_safe_token( device ); + + cpustate->icount = cycles; + + do + { +// debugger_instruction_hook( device, ( ( cpustate->pa << 7 ) | cpustate->pc ) << 1 ); + cpustate->icount--; + switch( cpustate->subcycle ) + { + case 0: + /* fetch: rom address 0 */ + /* execute: read ram, alu input, execute br/call, k input valid */ + tms0980_set_cki_bus( device ); + cpustate->ram_data = memory_read_byte_8le( cpustate->data, cpustate->ram_address ); + cpustate->status = 1; + cpustate->p = 0; + cpustate->n = 0; + cpustate->carry_in = 0; + break; + case 1: + /* fetch: rom address 1 */ + cpustate->rom_address = ( cpustate->pa << 7 ) | cpustate->pc; + /* execute: k input valid */ + if ( cpustate->decode & MICRO_MASK ) + { + /* Check N inputs */ + if ( cpustate->decode & ( M_15TN | M_ATN | M_CKN | M_MTN | M_NATN ) ) + { + cpustate->n = 0x0F; + if ( cpustate->decode & M_15TN ) + { + cpustate->n &= 0x0F; + } + if ( cpustate->decode & M_ATN ) + { + cpustate->n &= cpustate->a; + } + if ( cpustate->decode & M_CKN ) + { + cpustate->n &= cpustate->cki_bus; + } + if ( cpustate->decode & M_MTN ) + { + cpustate->n &= cpustate->ram_data; + } + if ( cpustate->decode & M_NATN ) + { + cpustate->n &= ( ( ~cpustate->a ) & 0x0F ); + } + } + + + /* Check P inputs */ + if ( cpustate->decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) ) + { + cpustate->p = 0x0F; + if ( cpustate->decode & M_CKP ) + { + cpustate->p &= cpustate->cki_bus; + } + if ( cpustate->decode & M_DMTP ) + { + cpustate->p &= cpustate->dam; + } + if ( cpustate->decode & M_MTP ) + { + cpustate->p &= cpustate->ram_data; + } + if ( cpustate->decode & M_NDMTP ) + { + cpustate->p &= ( ( ~cpustate->dam ) & 0x0F ); + } + if ( cpustate->decode & M_YTP ) + { + cpustate->p &= cpustate->y; + } + } + + /* Carry In input */ + if ( cpustate->decode & M_CIN ) + { + cpustate->carry_in = 1; + } + } + break; + case 2: + /* fetch: nothing */ + /* execute: write ram */ + /* perform adder logic */ + cpustate->adder_result = cpustate->p + cpustate->n + cpustate->carry_in; + if ( cpustate->decode & MICRO_MASK ) + { + if ( cpustate->decode & M_NE ) + { + if ( cpustate->n == cpustate->p ) + { + cpustate->status = 0; + } + } + if ( cpustate->decode & M_C8 ) + { + cpustate->status = cpustate->adder_result >> 4; + } + if ( cpustate->decode & M_STO ) + { + memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->a ); + } + if ( cpustate->decode & M_CKM ) + { + memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->cki_bus ); + } + } + else + { + if ( cpustate->decode & F_SBIT ) + { + memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->ram_data | tms0980_bit_value[ cpustate->opcode & 0x03 ] ); + } + if ( cpustate->decode & F_RBIT ) + { + memory_write_byte_8le( cpustate->data, cpustate->ram_address, cpustate->ram_data & tms0980_nbit_value[ cpustate->opcode & 0x03 ] ); + } + if ( cpustate->decode & F_SETR ) + { + cpustate->r = cpustate->r | ( 1 << cpustate->y ); + if ( cpustate->write_r ) + { + cpustate->write_r( device, 0, cpustate->r, 0xFFFF ); + } + } + if ( cpustate->decode & F_TDO ) + { + cpustate->o = ( cpustate->status_latch << 4 ) | cpustate->a; + if ( cpustate->write_o ) + { + cpustate->write_o( device, 0, cpustate->o ); + } + } + if ( cpustate->decode & F_CLO ) + { + cpustate->o = 0; + if ( cpustate->write_o ) + { + cpustate->write_o( device, 0, cpustate->o ); + } + } + if ( cpustate->decode & F_LDX ) + { + cpustate->x = tms0980_c_value[ cpustate->opcode & 0x0F ]; + } + if ( cpustate->decode & F_COMX ) + { + cpustate->x = cpustate->x ^ 0x03; + } + if ( cpustate->decode & F_LDP ) + { + cpustate->pb = tms0980_c_value[ cpustate->opcode & 0x0F ]; + } + if ( cpustate->decode & F_REAC ) + { + cpustate->special_status = 0; + } + if ( cpustate->decode & F_SEAC ) + { + cpustate->special_status = 1; + } + if ( cpustate->decode == F_SAL ) + { + cpustate->add_latch = 1; + } + if ( cpustate->decode == F_SBL ) + { + cpustate->branch_latch = 1; + } + } + break; + case 3: + /* fetch: fetch, update pc, ram address */ + cpustate->ram_address = ( cpustate->x << 4 ) | cpustate->y; + /* execute: register store */ + break; + case 4: + /* execute: register store */ + if ( cpustate->decode & ( MICRO_MASK | M_AUTA ) ) + { + cpustate->a = cpustate->adder_result & 0x0F; + } + if ( cpustate->decode & ( MICRO_MASK | M_AUTY ) ) + { + cpustate->y = cpustate->adder_result & 0x0F; + } +// if ( cpustate->decode & ( MICRO_MASK | M_STSL ) ) +// { +// cpustate->status_latch = cpustate->status; +// } + debugger_instruction_hook( device, cpustate->rom_address << 1 ); + /* fetch: fetch, update pc, ram address */ + cpustate->opcode = memory_read_word_16be( cpustate->program, cpustate->rom_address << 1 ); + cpustate->opcode &= 0x1FF; + cpustate->pc = tms0980_next_pc( cpustate->pc ); + if (LOG) + logerror("tms0980: read opcode %04x. Set pc to %04x\n", cpustate->opcode, cpustate->pc ); + break; + case 5: + /* fetch: instruction decode */ + cpustate->decode = tms0980_decode[ cpustate->opcode ]; + /* execute: execute br/call */ + if ( cpustate->status ) + { + if ( cpustate->decode == F_BR ) + { + if ( cpustate->call_latch == 0 ) + { + cpustate->pa = cpustate->pb; + } + cpustate->pc = cpustate->opcode & 0x7F; + } + if ( cpustate->decode == F_CALL ) + { + UINT8 t = cpustate->pa; + if ( cpustate->call_latch == 0 ) + { + cpustate->sr = cpustate->pc; + cpustate->call_latch = 1; + cpustate->pa = cpustate->pb; + } + cpustate->pb = t; + cpustate->pc = cpustate->opcode & 0x7F; + } + } + if ( cpustate->decode == F_RETN ) + { + if ( cpustate->call_latch == 1 ) + { + cpustate->pc = cpustate->sr; + cpustate->call_latch = 0; + } + cpustate->add_latch = 0; + cpustate->pa = cpustate->pb; + } else { + cpustate->branch_latch = 0; + } + break; + } + cpustate->subcycle = ( cpustate->subcycle + 1 ) % 6; + } while( cpustate->icount > 0 ); + + return cycles - cpustate->icount; +} + + +static CPU_SET_INFO( tms0980 ) +{ + tms0980_state *cpustate = get_safe_token( device ); + + switch( state ) + { + case CPUINFO_INT_PC: cpustate->pc = ( info->i >> 1 ) & 0x7f; cpustate->pa = info->i >> 8; break; + case CPUINFO_INT_REGISTER + TMS0980_PC: cpustate->pc = info->i; break; + case CPUINFO_INT_REGISTER + TMS0980_SR: cpustate->sr = info->i; break; + case CPUINFO_INT_REGISTER + TMS0980_PA: cpustate->pa = info->i; break; + case CPUINFO_INT_REGISTER + TMS0980_PB: cpustate->pb = info->i; break; + case CPUINFO_INT_REGISTER + TMS0980_A: cpustate->a = info->i; break; + case CPUINFO_INT_REGISTER + TMS0980_X: cpustate->x = info->i; break; + case CPUINFO_INT_REGISTER + TMS0980_Y: cpustate->y = info->i; break; + case CPUINFO_INT_REGISTER + TMS0980_STATUS: cpustate->status = info->i; break; + } +} + + +CPU_GET_INFO( tms0980 ) +{ + tms0980_state *cpustate = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL; + + switch(state) + { + case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(tms0980_state); break; + case CPUINFO_INT_INPUT_LINES: info->i = 1; break; + case CPUINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; 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 = 2; break; + case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 2; break; + case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; + case CPUINFO_INT_MAX_CYCLES: info->i = 6; break; + + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16 /* 9 */; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 11; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; + case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8 /* 4 */; break; + case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; + case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break; + + case CPUINFO_INT_PREVIOUSPC: info->i = ( ( cpustate->prev_pa << 7 ) | cpustate->prev_pc ) << 1; break; + case CPUINFO_INT_PC: info->i = ( ( cpustate->pa << 7 ) | cpustate->pc ) << 1; break; + case CPUINFO_INT_SP: info->i = 0xFFFF; break; + case CPUINFO_INT_REGISTER + TMS0980_PC: info->i = cpustate->pc; break; + case CPUINFO_INT_REGISTER + TMS0980_SR: info->i = cpustate->sr; break; + case CPUINFO_INT_REGISTER + TMS0980_PA: info->i = cpustate->pa; break; + case CPUINFO_INT_REGISTER + TMS0980_PB: info->i = cpustate->pb; break; + case CPUINFO_INT_REGISTER + TMS0980_A: info->i = cpustate->a; break; + case CPUINFO_INT_REGISTER + TMS0980_X: info->i = cpustate->x; break; + case CPUINFO_INT_REGISTER + TMS0980_Y: info->i = cpustate->y; break; + case CPUINFO_INT_REGISTER + TMS0980_STATUS: info->i = cpustate->status; break; + + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME( tms0980_internal_rom ); break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACE_DATA: info->internal_map8 = ADDRESS_MAP_NAME( tms0980_internal_ram ); break; + + case CPUINFO_FCT_SET_INFO: info->setinfo = CPU_SET_INFO_NAME( tms0980 ); break; + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms0980 ); break; + case CPUINFO_FCT_RESET: info->reset = CPU_RESET_NAME( tms0980 ); break; + case CPUINFO_FCT_EXECUTE: info->execute = CPU_EXECUTE_NAME( tms0980 ); break; + case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME( tms0980 ); break; + case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cpustate->icount; break; + + case CPUINFO_STR_NAME: strcpy( info->s, "TMS0980" ); break; + case CPUINFO_STR_CORE_FAMILY: strcpy( info->s, "Texas Instruments TMS0980" ); break; + case CPUINFO_STR_CORE_VERSION: strcpy( info->s, "0.1" ); break; + case CPUINFO_STR_CORE_FILE: strcpy( info->s, __FILE__ ); break; + case CPUINFO_STR_CORE_CREDITS: strcpy( info->s, "Copyright the MESS and MAME teams" ); break; + + case CPUINFO_STR_FLAGS: strcpy( info->s, "N/A" ); break; + + case CPUINFO_STR_REGISTER + TMS0980_PC: sprintf( info->s, "PC:%02X", cpustate->pc ); break; + case CPUINFO_STR_REGISTER + TMS0980_SR: sprintf( info->s, "SR:%01X", cpustate->sr ); break; + case CPUINFO_STR_REGISTER + TMS0980_PA: sprintf( info->s, "PA:%01X", cpustate->pa ); break; + case CPUINFO_STR_REGISTER + TMS0980_PB: sprintf( info->s, "PB:%01X", cpustate->pb ); break; + case CPUINFO_STR_REGISTER + TMS0980_A: sprintf( info->s, "A:%01X", cpustate->a ); break; + case CPUINFO_STR_REGISTER + TMS0980_X: sprintf( info->s, "X:%01X", cpustate->x ); break; + case CPUINFO_STR_REGISTER + TMS0980_Y: sprintf( info->s, "Y:%01X", cpustate->y ); break; + case CPUINFO_STR_REGISTER + TMS0980_STATUS: sprintf( info->s, "STATUS:%01X", cpustate->status ); break; + + } +} + diff --git a/src/emu/cpu/tms0980/tms0980.h b/src/emu/cpu/tms0980/tms0980.h new file mode 100644 index 00000000000..cd590d33f8c --- /dev/null +++ b/src/emu/cpu/tms0980/tms0980.h @@ -0,0 +1,27 @@ +#ifndef _TMS0980_H_ +#define _TMS0980_H_ + +#include "cpuintrf.h" + +/* Registers */ +enum { + TMS0980_PC=1, TMS0980_SR, TMS0980_PA, TMS0980_PB, + TMS0980_A, TMS0980_X, TMS0980_Y, TMS0980_STATUS +}; + + +typedef struct _tms0980_config tms0980_config; +struct _tms0980_config { + read8_device_func read_k; + write8_device_func write_o; + write16_device_func write_r; +}; + + +#define CPU_TMS0980 CPU_GET_INFO_NAME( tms0980 ) + +extern CPU_GET_INFO( tms0980 ); +extern CPU_DISASSEMBLE( tms0980 ); + +#endif /* _TMS0980_H_ */ + diff --git a/src/emu/cpu/tms0980/tms0980d.c b/src/emu/cpu/tms0980/tms0980d.c new file mode 100644 index 00000000000..f35f82266d7 --- /dev/null +++ b/src/emu/cpu/tms0980/tms0980d.c @@ -0,0 +1,189 @@ +/******************************************************************* + +tms0980d.c +TMS0980 disassembly + +*******************************************************************/ + +#include "debugger.h" +#include "tms0980.h" + + +#define _OVER DASMFLAG_STEP_OVER +#define _OUT DASMFLAG_STEP_OUT + + +enum e_mnemonics { + zACACC=0, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA, + zCLA, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDMAN, zDMEA, zDNAA, + zDYN, zIMAC, zIYC, zKNE, zLDP, zLDX, zMNEA, zMNEZ, + zNDMEA, zOFF, zRBIT, zREAC, zRETN, zSAL, zSAMAN, zSBIT, + zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIYC, zTAMZA, + zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA, + zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC, + zILL +}; + + +enum e_addressing { + zB0=0, zB2, zB4, zB7 +}; + + +static const char *s_mnemonic[] = { + "acacc", "acnaa", "alec", "alem", "amaac", "branch", "call", "ccla", + "cla", "comx", "comx8", "cpaiz", "ctmdyn", "dman", "dmea", "dnaa", + "dyn", "imac", "iyc", "kne", "ldp", "ldx", "mnea", "mnez", + "ndmea", "off", "rbit", "reac", "retn", "sal", "saman", "sbit", + "sbl", "seac", "setr", "tam", "tamacs", "tamdyn", "tamiyc", "tamza", + "tay", "tbit", "tcmiy", "tcy", "tdo", "tka", "tkm", "tma", + "tmy", "tya", "xda", "xma", "ymcy", "ynea", "ynec", + "illegal" +}; + + +static const UINT32 s_flags[] = { + 0, 0, 0, 0, 0, 0, _OVER, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, _OUT, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0 +}; + + +static const UINT8 s_addressing[] = { + zB4, zB4, zB4, zB0, zB0, zB7, zB7, zB0, + zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, + zB0, zB0, zB0, zB0, zB4, zB4, zB0, zB0, + zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, + zB0, zB0, zB2, zB0, zB4, zB0, zB0, zB2, + zB0, zB2, zB4, zB4, zB0, zB0, zB0, zB0, + zB0, zB0, zB0, zB0, zB4, zB0, zB4, + zB0 +}; + + +static const UINT8 tms0980_mnemonic[512] = { + /* 0x000 */ + zCOMX, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN, + zTKA, zMNEA, zTKM, zILL, zILL, zSETR, zKNE, zILL, + /* 0x010 */ + zDMEA, zDNAA, zCCLA, zNDMEA, zILL, zAMAAC, zILL, zILL, + zCTMDYN, zXDA, zILL, zILL, zILL, zILL, zILL, zILL, + /* 0x020 */ + zTBIT, zTBIT, zTBIT, zTBIT, zILL, zILL, zILL, zILL, + zTAY, zTMA, zTMY, zTYA, zTAMDYN, zTAMIYC, zTAMZA, zTAM, + /* 0x030 */ + zSAMAN, zCPAIZ, zIMAC, zMNEZ, zILL, zILL, zILL, zILL, + zTCY, zYNEC, zTCMIY, zACACC, zACNAA, zTAMACS, zALEC, zYMCY, + /* 0x040 */ + zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, + zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, + /* 0x050 */ + zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, + zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, + /* 0x060 */ + zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, + zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, + /* 0x070 */ + zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, + zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, + /* 0x080 */ + zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, + zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, + /* 0x090 */ + zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, + zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, + /* 0x0A0 */ + zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, + zILL, zILL, zILL, zILL, zILL, zILL, zILL, zILL, + /* 0x0B0 */ + zTDO, zSAL, zCOMX8, zSBL, zREAC, zSEAC, zOFF, zILL, + zILL, zILL, zILL, zILL, zILL, zILL, zILL, zRETN, + /* 0x0C0 */ + zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, + zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, + /* 0x0D0 */ + zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, + zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, + /* 0x0E0 */ + zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, + zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, + /* 0x0F0 */ + zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, + zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, + /* 0x100 */ + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, + /* 0x180 */ + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, + zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL +}; + + +CPU_DISASSEMBLE( tms0980 ) { + static const UINT8 tms0980_c_value[16] = + { + 0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F + }; + static const UINT8 tms0980_bit_value[4] = { 1, 4, 2, 8 }; + + char *dst = buffer; + UINT16 op, instr; + int pos = 0; + + op = ( ( oprom[pos] << 8 ) | oprom[pos + 1] ) & 0x01FF; + pos += 2; + + instr = tms0980_mnemonic[op]; + + dst += sprintf( dst, "%-8s ", s_mnemonic[instr] ); + + switch( s_addressing[instr] ) { + case zB0: + break; + case zB2: + dst += sprintf( dst, "#$%d", tms0980_bit_value[ op & 3 ] ); + break; + case zB4: + dst += sprintf( dst, "#$%01X", tms0980_c_value[ op & 0x0F ] ); + break; + case zB7: + dst += sprintf( dst, "#$%02X", op & 0x7F ); + break; + } + + return pos | s_flags[instr] | DASMFLAG_SUPPORTED; +} + diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 693cb00d7f9..f8380a91442 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -112,6 +112,7 @@ CPUS += SM8500 CPUS += MINX CPUS += SSEM CPUS += AVR8 +CPUS += TMS0980 #-------------------------------------------------