diff options
-rw-r--r-- | src/emu/cpu/tms0980/tms0980.c | 786 | ||||
-rw-r--r-- | src/emu/cpu/tms0980/tms0980.h | 26 | ||||
-rw-r--r-- | src/emu/cpu/tms0980/tms0980d.c | 223 |
3 files changed, 809 insertions, 226 deletions
diff --git a/src/emu/cpu/tms0980/tms0980.c b/src/emu/cpu/tms0980/tms0980.c index 399653ee569..163156517c9 100644 --- a/src/emu/cpu/tms0980/tms0980.c +++ b/src/emu/cpu/tms0980/tms0980.c @@ -1,10 +1,47 @@ /* -This CPU core has not been thoroughly tested. Several features may still be -incomplete, missing, or broken. [Wilbert Pol] - -TMS0980 CPU core +TMS0980/TMS1000-family CPU cores + +The tms0980 and tms1000-family cpu cores are very similar. The tms0980 has a +slightly bigger addressable area and uses 9bit instructions where the tms1000 +family uses 8bit instruction. The instruction set themselves are very similar +though. The table below shows the differences between the different models. + +Mode | ROM | RAM | R pins | O pins | K pins | ids +---------+-----------+----------+--------+--------+--------|---------- +tms0970* | 1024 * 8 | 64 * 4 | | | | tms0972 +tms0920* | 511?* 9 | 40 * 5 | | | | tmc0921 +tms0980 | 2048 * 9 | 64 * 9 | | | | tmc0981 +tms1000 | 1024 * 8 | 64 * 4 | 11 | 8 | 4 | tms1001 +tms1040* | 1024 * 8 | 64 * 4 | | | | tms1043 +tms1070 | 1024 * 8 | 64 * 4 | 11 | 8 | 4 | tms1071 +tms1100 | 2048 * 8 | 128 * 4 | 11 | 8 | 4 | tms1111/tms1115 +tms1170* | 2048 * 8 | 128 * 4 | | | | tmc1172 +tms1200 | 1024 * 8 | 64 * 4 | 13 | 8 | 4 | tms1215 +tms1270 | 1024 * 8 | 64 * 4 | 13 | 10 | 4 | tms1278 +tms1300 | 2048 * 8 | 128 * 4 | 16 | 8 | 4 | tms1309 +tms1370* | 2048 * 8 | 128 * 4 | | | | za0543 +tms1400* | 4096 * 8 | 128 * 4 | | | | +tms1470* | 4096 * 8 | 128 * 4 | | | | tms1470 +tms1500* | 2048 * 13 | 64 * 20 | | | | tmc1501 +tms1600* | 4096 * 8 | 128 * 4 | | | | +tms1670* | 4096 * 8 | 128 * 4 | | | | +tms1700* | 512 * 8 | 32 * 4 | | | | +tms1980* | 2048 * 9 | 64 * 9 | | | | tmc1982 +tms1990* | 1024 * 8 | 64 * 4 | | | | tmc1991 +tp0310* | 511?* 9 | 40 * 5 | | | | tp0311 +tp0320* | 2048 * 9 | 64 * 13 | | | | tp0321 +tp0455* | | | | | | cd4501 +tp0456* | | | | | | cd4555 +tp0458* | | | | | | cd4812 +tp0485* | | | | | | cd2901 +tp0530* | | | | | | cd5402 + +* = not supported yet + +The TMS1000 core has been tested with some example code, the other models +have not been tested lacking rom dumps. 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 @@ -45,74 +82,14 @@ cycle #5 - 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: + +The CPU cores contains a set of fixed instructions and a set of +instructions created using microinstructions. A subset of the +instruction set could be defined from the microinstructions by +TI customers. Currently we only support the standard instruction +set as defined by TI. + +The microinstructions are: 15TN - 15 to -ALU ATN - ACC to -ALU AUTA - ALU to ACC @@ -138,7 +115,7 @@ 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 +unknown cycle: CME, SSE, SSS */ @@ -146,30 +123,34 @@ unknown: CME, SSE, SSS #include "tms0980.h" #include "deprecat.h" -#define LOG 1 +#define LOG 0 #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 +#define F_COMC 0x00000008 +#define F_COMX 0x00000010 +#define F_COMX8 0x00000020 +#define F_LDP 0x00000040 +#define F_LDX 0x00000080 +#define F_OFF 0x00000100 +#define F_RBIT 0x00000200 +#define F_REAC 0x00000400 +#define F_RETN 0x00000800 +#define F_RSTR 0x00001000 +#define F_SAL 0x00002000 +#define F_SBIT 0x00004000 +#define F_SBL 0x00008000 +#define F_SEAC 0x00010000 +#define F_SETR 0x00020000 +#define F_TDO 0x00040000 + /* Microinstructions */ #define M_15TN 0x00000001 @@ -191,9 +172,15 @@ unknown: CME, SSE, SSS #define M_SSE 0x00010000 #define M_SSS 0x00020000 #define M_STO 0x00040000 -#define M_YTP 0x00080000 +#define M_STSL 0x00080000 +#define M_YTP 0x00100000 + /* instructions built from microinstructions */ +#define I_AC1AC ( MICRO_MASK | M_CKP | M_ATN | M_CIN | M_C8 | M_AUTA ) +#define I_A6AAC I_ACACC +#define I_A8AAC I_ACACC +#define I_A10AAC I_ACACC #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 ) @@ -203,10 +190,12 @@ unknown: CME, SSE, 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_DAN ( MICRO_MASK | M_CKP | M_ATN | M_CIN | M_C8 | M_AUTA ) #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_IA ( MICRO_MASK | M_ATN | M_CIN | M_AUTA ) #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 ) @@ -218,6 +207,7 @@ unknown: CME, SSE, SSS #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_TAMIY ( MICRO_MASK | M_STO | M_YTP | M_CIN | M_AUTY ) #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 ) @@ -241,7 +231,7 @@ 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 pc; /* program counter is a 7 bit register on tms0980, 6 bit register on tms1000/1070/1200/1270/1100/1300 */ 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 */ @@ -249,6 +239,9 @@ struct _tms0980_state 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 */ + UINT8 ca; /* Chapter address bit */ + UINT8 cb; /* Chapter buffer bit */ + UINT8 cs; /* Chapter subroutine bit */ UINT16 r; UINT8 o; UINT8 cki_bus; /* CKI bus */ @@ -262,9 +255,6 @@ struct _tms0980_state 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; @@ -272,13 +262,22 @@ struct _tms0980_state UINT16 opcode; UINT32 decode; int icount; + UINT16 o_mask; /* mask to determine the number of O outputs */ + UINT16 r_mask; /* mask to determine the number of R outputs */ + UINT8 pc_size; /* how bits in the PC register */ + UINT8 byte_size; /* 8 or 9 bit bytes */ + const UINT32 *decode_table; const tms0980_config *config; const address_space *program; const address_space *data; }; -static const UINT8 tms0980_c_value[16] = +static const UINT8 tms0980_c2_value[4] = +{ + 0x00, 0x02, 0x01, 0x03 +}; +static const UINT8 tms0980_c4_value[16] = { 0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F }; @@ -363,12 +362,102 @@ static const UINT32 tms0980_decode[512] = }; +static const UINT32 tms1000_default_decode[256] = { + /* 0x00 */ + F_COMX, I_A8AAC, I_YNEA, I_TAM, I_TAMZA, I_A10AAC, I_A6AAC, I_DAN, + I_TKA, I_KNEZ, F_TDO, F_CLO, F_RSTR, F_SETR, I_IA, F_RETN, + 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, + /* 0x20 */ + I_TAMIY, I_TMA, I_TMY, I_TYA, I_TAY, I_AMAAC, I_MNEZ, I_SAMAN, + I_IMAC, I_ALEM, I_DMAN, I_IYC, I_DYN, I_CPAIZ, I_XMA, I_CLA, + F_SBIT, F_SBIT, F_SBIT, F_SBIT, F_RBIT, F_RBIT, F_RBIT, F_RBIT, + I_TBIT, I_TBIT, I_TBIT, I_TBIT, F_LDX, F_LDX, F_LDX, F_LDX, + /* 0x40 */ + 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, + /* 0x60 */ + 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_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, + /* 0x80 */ + 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, + /* 0xC0 */ + 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, +}; + + +static const UINT32 tms1100_default_decode[256] = { + /* 0x00 */ + I_MNEA, I_ALEM, I_YNEA, I_XMA, I_DYN, I_IYC, I_AMAAC, I_DMAN, + I_TKA, F_COMX, F_TDO, F_COMC, F_RSTR, F_SETR, I_KNEZ, F_RETN, + 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, + /* 0x20 */ + I_TAY, I_TMA, I_TMY, I_TYA, I_TAMDYN, I_TAMIYC, I_TAMZA, I_TAM, + 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, + I_TBIT, I_TBIT, I_TBIT, I_TBIT, I_SAMAN, I_CPAIZ, I_IMAC, I_MNEZ, + /* 0x40 */ + 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, + /* 0x60 */ + 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_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, + I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_AC1AC, I_CLA, + /* 0x80 */ + 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, + /* 0xC0 */ + 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); + assert(cpu_get_type(device) == CPU_TMS0980 || + cpu_get_type(device) == CPU_TMS1000 || + cpu_get_type(device) == CPU_TMS1070 || + cpu_get_type(device) == CPU_TMS1100 || + cpu_get_type(device) == CPU_TMS1200 || + cpu_get_type(device) == CPU_TMS1270 || + cpu_get_type(device) == CPU_TMS1300 ); return (tms0980_state *)device->token; } @@ -383,12 +472,40 @@ static ADDRESS_MAP_START(tms0980_internal_ram, ADDRESS_SPACE_DATA, 8) ADDRESS_MAP_END -static CPU_INIT( tms0980 ) +static ADDRESS_MAP_START(program_10bit_8, ADDRESS_SPACE_PROGRAM, 8) + AM_RANGE( 0x000, 0x3ff ) AM_ROM +ADDRESS_MAP_END + + +static ADDRESS_MAP_START(program_11bit_8, ADDRESS_SPACE_PROGRAM, 8) + AM_RANGE( 0x000, 0x7ff ) AM_ROM +ADDRESS_MAP_END + + +static ADDRESS_MAP_START(data_6bit, ADDRESS_SPACE_DATA, 8) + AM_RANGE( 0x00, 0x3f ) AM_RAM +ADDRESS_MAP_END + + +static ADDRESS_MAP_START(data_7bit, ADDRESS_SPACE_DATA, 8) + AM_RANGE( 0x00, 0x7f ) AM_RAM +ADDRESS_MAP_END + + +static void cpu_init_tms_common( const device_config *device, const UINT32* decode_table, UINT16 o_mask, UINT16 r_mask, UINT8 pc_size, UINT8 byte_size ) { tms0980_state *cpustate = get_safe_token( device ); cpustate->config = (const tms0980_config *) device->static_config; + assert( cpustate->config != NULL ); + + cpustate->decode_table = decode_table; + cpustate->o_mask = o_mask; + cpustate->r_mask = r_mask; + cpustate->pc_size = pc_size; + cpustate->byte_size = byte_size; + cpustate->program = memory_find_address_space( device, ADDRESS_SPACE_PROGRAM ); cpustate->data = memory_find_address_space( device, ADDRESS_SPACE_DATA ); @@ -402,6 +519,9 @@ static CPU_INIT( tms0980 ) 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->ca ); + state_save_register_device_item( device, 0, cpustate->cb ); + state_save_register_device_item( device, 0, cpustate->cs ); 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 ); @@ -424,6 +544,48 @@ static CPU_INIT( tms0980 ) } +static CPU_INIT( tms0980 ) +{ + cpu_init_tms_common( device, tms0980_decode, 0x00ff, 0x07ff, 7, 9 ); +} + + +static CPU_INIT( tms1000 ) +{ + cpu_init_tms_common( device, tms1000_default_decode, 0x00ff, 0x07ff, 6, 8 ); +} + + +static CPU_INIT( tms1070 ) +{ + cpu_init_tms_common( device, tms1000_default_decode, 0x00ff, 0x07ff, 6, 8 ); +} + + +static CPU_INIT( tms1200 ) +{ + cpu_init_tms_common( device, tms1000_default_decode, 0x00ff, 0x1fff, 6, 8 ); +} + + +static CPU_INIT( tms1270 ) +{ + cpu_init_tms_common( device, tms1000_default_decode, 0x03ff, 0x1fff, 6, 8 ); +} + + +static CPU_INIT( tms1100 ) +{ + cpu_init_tms_common( device, tms1100_default_decode, 0x00ff, 0x07ff, 6, 8 ); +} + + +static CPU_INIT( tms1300 ) +{ + cpu_init_tms_common( device, tms1100_default_decode, 0x00ff, 0xffff, 6, 8 ); +} + + static CPU_RESET( tms0980 ) { tms0980_state *cpustate = get_safe_token( device ); @@ -432,28 +594,125 @@ static CPU_RESET( tms0980 ) cpustate->pb = 0x0F; cpustate->pc = 0; cpustate->dam = 0; + cpustate->ca = 0; + cpustate->cb = 0; + cpustate->cs = 0; cpustate->subcycle = 0; cpustate->status = 1; + cpustate->status_latch = 0; 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->decode = F_ILL; 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; - } } +/* +The program counter is implemented using PRNG logic and gets incremented as follows: + +00, 01, 03, 07, 0F, 1F, 3F, 3E, +3D, 3B, 37, 2F, 1E, 3C, 39, 33 +27, 0E, 1D, 3A, 35, 2B, 16, 2C, +18, 30, 21, 02, 05, 0B, 17, 2E, +1C, 38, 31, 23, 06, 0D, 1B, 36, +2D, 1A, 34, 29, 12, 24, 08, 11, +22, 04, 09, 13, 26, 0C, 19, 32, +25, 0A, 15, 2A, 14, 28, 10, 20 + +There is also a strange address (AD) to location (LOC) mapping performed by the +tms1000 family. + +From tms1000 family pdf: +AD LOC +000 000000 003 000011 +001 000001 004 000100 +003 000011 00C 001100 +007 000111 01C 011100 +00F 001111 03C 111100 +01F 011111 03F 111111 +03F 111111 03E 111110 +03E 111110 039 111001 +03D 111101 036 110110 +03B 111011 02E 101110 +037 110111 01E 011110 +02F 101111 03D 111101 +01E 011110 038 111000 +03C 111100 031 110001 +039 111001 026 100110 +033 110011 00E 001110 +027 100111 01D 011101 +00E 001110 03B 111011 +01D 011101 037 110111 +03A 111010 029 101001 +035 110101 016 010110 +02B 101011 02D 101101 +016 010110 018 011000 +02C 101100 032 110010 +018 011000 020 100000 +030 110000 001 000001 +021 100001 005 000101 +002 000010 00B 001011 +005 000101 014 010100 +00B 001011 02C 101100 +017 010111 01F 011111 +02E 101110 03A 111010 +01C 011100 030 110000 +038 111000 021 100001 +031 110001 006 000110 +023 100011 00D 001101 +006 000110 01B 011011 +00D 001101 034 110100 +01B 011011 02F 101111 +036 110110 019 011001 +02D 101101 035 110101 +01A 011010 028 101000 +034 110100 011 010001 +029 101001 025 100101 +012 010010 008 001000 +024 100100 012 010010 +008 001000 023 100011 +011 010001 007 000111 +022 100010 00A 001010 +004 000100 013 010011 +009 001001 024 100100 +013 010011 00F 001111 +026 100110 01A 011010 +00C 001100 033 110011 +019 011001 027 100111 +032 110010 009 001001 +025 100101 015 010101 +00A 001010 02B 101011 +015 010101 017 010111 +02A 101010 02A 101010 +014 010100 010 010000 +028 101000 022 100010 +010 010000 000 000000 +020 100000 002 000010 + +The following formula seems to be used to decode a program counter +into a rom address: +location{5:2} = pc{3:0} +location{1:0} = ( pc{5:4} == 00 && pc{0} == 0 ) => 11 + ( pc{5:4} == 00 && pc{0} == 1 ) => 00 + ( pc{5:4} == 01 && pc{0} == 0 ) => 00 + ( pc{5:4} == 01 && pc{0} == 1 ) => 11 + ( pc{5:4} == 10 && pc{0} == 0 ) => 10 + ( pc{5:4} == 10 && pc{0} == 1 ) => 01 + ( pc{5:4} == 11 && pc{0} == 0 ) => 01 + ( pc{5:4} == 11 && pc{0} == 1 ) => 10 + +*/ +static const UINT8 tms1000_next_pc[64] = { + 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3F, + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, + 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3B, 0x3D, 0x3E, +}; + /* emulator for the program counter increment on the tms0980/tmc0980 mcu; see patent 4064554 figure 19 (on page 13) for an explanation of feedback: @@ -472,66 +731,74 @@ static CPU_RESET( tms0980 ) tms0980_nect_pc below implements an indentical function to this in a somewhat more elegant way. */ -INLINE UINT8 tms0980_next_pc( UINT8 pc ) +INLINE void tms0980_next_pc( tms0980_state *cpustate ) { - UINT8 xorval = ( pc & 0x3F ) == 0x3F ? 1 : 0; - UINT8 new_bit = ( ( pc ^ ( pc << 1 ) ) & 0x40 ) ? xorval : 1 - xorval; + if ( cpustate->byte_size > 8 ) + { + UINT8 xorval = ( cpustate->pc & 0x3F ) == 0x3F ? 1 : 0; + UINT8 new_bit = ( ( cpustate->pc ^ ( cpustate->pc << 1 ) ) & 0x40 ) ? xorval : 1 - xorval; - return ( pc << 1 ) | new_bit; + cpustate->pc = ( cpustate->pc << 1 ) | new_bit; + } + else + { + cpustate->pc = tms1000_next_pc[ cpustate->pc & 0x3f ]; + } } +static const UINT8 tms1000_pc_decode[64] = +{ + 0x03, 0x04, 0x0B, 0x0C, 0x13, 0x14, 0x1B, 0x1C, + 0x23, 0x24, 0x2B, 0x2C, 0x33, 0x34, 0x3B, 0x3C, + 0x00, 0x07, 0x08, 0x0F, 0x10, 0x17, 0x18, 0x1F, + 0x20, 0x27, 0x28, 0x2F, 0x30, 0x37, 0x38, 0x3F, + 0x02, 0x05, 0x0A, 0x0D, 0x12, 0x15, 0x1A, 0x1D, + 0x22, 0x25, 0x2A, 0x2D, 0x32, 0x35, 0x3A, 0x3D, + 0x01, 0x06, 0x09, 0x0E, 0x11, 0x16, 0x19, 0x1E, + 0x21, 0x26, 0x29, 0x2E, 0x31, 0x36, 0x39, 0x3E +}; + + static void tms0980_set_cki_bus( const device_config *device ) { tms0980_state *cpustate = get_safe_token( device ); - switch( cpustate->opcode & 0xF8 ) + switch( cpustate->opcode & 0x1F8 ) { - case 0x08: - if ( cpustate->read_k ) + case 0x008: + if ( cpustate->config->read_k ) { - cpustate->cki_bus = cpustate->read_k( device, 0 ); + cpustate->cki_bus = cpustate->config->read_k( device, 0 ); } else { cpustate->cki_bus = 0x0F; } break; - case 0x20: case 0x28: + case 0x020: case 0x028: cpustate->cki_bus = 0; break; - case 0x30: - case 0x38: + case 0x030: case 0x038: 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 ]; + case 0x000: + case 0x040: case 0x048: + case 0x050: case 0x058: + case 0x060: case 0x068: + case 0x070: case 0x078: + case 0x080: case 0x088: + case 0x090: case 0x098: + case 0x0c0: case 0x0c8: + case 0x0d0: case 0x0d8: + case 0x0e0: case 0x0e8: + case 0x0f0: case 0x0f8: + cpustate->cki_bus = tms0980_c4_value[ cpustate->opcode & 0x0F ]; break; default: cpustate->cki_bus = 0x0F; break; } - /* Case 000001XXX */ - if ( ( cpustate->opcode & 0x1F8 ) == 0x008 ) - { - } - /* Case 00001XXXX */ - if ( ( cpustate->opcode & 0x1F0 ) == 0x010 ) - { - } - /* Case 00100XXXX - TCY */ - if ( ( cpustate->opcode & 0x1F0 ) == 0x040 ) - { - cpustate->cki_bus = cpustate->opcode & 0x0F; - } - /* Case 01XXXXXXX */ - if ( ( cpustate->opcode & 0x180 ) == 0x080 ) - { - } } @@ -543,7 +810,7 @@ static CPU_EXECUTE( tms0980 ) do { -// debugger_instruction_hook( device, ( ( cpustate->pa << 7 ) | cpustate->pc ) << 1 ); +// debugger_instruction_hook( device, ( ( cpustate->pa << cpustate->pc_size ) | cpustate->pc ) << 1 ); cpustate->icount--; switch( cpustate->subcycle ) { @@ -559,33 +826,36 @@ static CPU_EXECUTE( tms0980 ) break; case 1: /* fetch: rom address 1 */ - cpustate->rom_address = ( cpustate->pa << 7 ) | cpustate->pc; + if ( cpustate->pc_size == 6 ) + cpustate->rom_address = ( cpustate->pa << 6 ) | tms1000_pc_decode[ cpustate->pc ]; + else + 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; + cpustate->n = 0; if ( cpustate->decode & M_15TN ) { - cpustate->n &= 0x0F; + cpustate->n |= 0x0F; } if ( cpustate->decode & M_ATN ) { - cpustate->n &= cpustate->a; + cpustate->n |= cpustate->a; } if ( cpustate->decode & M_CKN ) { - cpustate->n &= cpustate->cki_bus; + cpustate->n |= cpustate->cki_bus; } if ( cpustate->decode & M_MTN ) { - cpustate->n &= cpustate->ram_data; + cpustate->n |= cpustate->ram_data; } if ( cpustate->decode & M_NATN ) { - cpustate->n &= ( ( ~cpustate->a ) & 0x0F ); + cpustate->n |= ( ( ~cpustate->a ) & 0x0F ); } } @@ -593,26 +863,26 @@ static CPU_EXECUTE( tms0980 ) /* Check P inputs */ if ( cpustate->decode & ( M_CKP | M_DMTP | M_MTP | M_NDMTP | M_YTP ) ) { - cpustate->p = 0x0F; + cpustate->p = 0; if ( cpustate->decode & M_CKP ) { - cpustate->p &= cpustate->cki_bus; + cpustate->p |= cpustate->cki_bus; } if ( cpustate->decode & M_DMTP ) { - cpustate->p &= cpustate->dam; + cpustate->p |= cpustate->dam; } if ( cpustate->decode & M_MTP ) { - cpustate->p &= cpustate->ram_data; + cpustate->p |= cpustate->ram_data; } if ( cpustate->decode & M_NDMTP ) { - cpustate->p &= ( ( ~cpustate->dam ) & 0x0F ); + cpustate->p |= ( ( ~cpustate->dam ) & 0x0F ); } if ( cpustate->decode & M_YTP ) { - cpustate->p &= cpustate->y; + cpustate->p |= cpustate->y; } } @@ -663,38 +933,61 @@ static CPU_EXECUTE( tms0980 ) if ( cpustate->decode & F_SETR ) { cpustate->r = cpustate->r | ( 1 << cpustate->y ); - if ( cpustate->write_r ) + if ( cpustate->config->write_r ) + { + cpustate->config->write_r( device, 0, cpustate->r & cpustate->r_mask, 0xffff ); + } + } + if ( cpustate->decode & F_RSTR ) + { + cpustate->r = cpustate->r & ( ~( 1 << cpustate->y ) ); + if ( cpustate->config->write_r ) { - cpustate->write_r( device, 0, cpustate->r, 0xFFFF ); + cpustate->config->write_r( device, 0, cpustate->r & cpustate->r_mask, 0xffff ); } } if ( cpustate->decode & F_TDO ) { - cpustate->o = ( cpustate->status_latch << 4 ) | cpustate->a; - if ( cpustate->write_o ) + int i = 0; + + /* Calculate O-outputs based on status latch, A, and the output PLA configuration */ + cpustate->o = 0; + for ( i = 0; i < 20; i++ ) { - cpustate->write_o( device, 0, cpustate->o ); + if ( ( ( cpustate->status_latch << 4 ) | cpustate->a ) == cpustate->config->o_pla[i].value ) + { + cpustate->o = cpustate->config->o_pla[i].output; + } + } + + if ( cpustate->config->write_o ) + { + cpustate->config->write_o( device, 0, cpustate->o & cpustate->o_mask, 0xffff ); } } if ( cpustate->decode & F_CLO ) { cpustate->o = 0; - if ( cpustate->write_o ) + if ( cpustate->config->write_o ) { - cpustate->write_o( device, 0, cpustate->o ); + cpustate->config->write_o( device, 0, cpustate->o & cpustate->o_mask, 0xffff ); } } if ( cpustate->decode & F_LDX ) { - cpustate->x = tms0980_c_value[ cpustate->opcode & 0x0F ]; + cpustate->x = tms0980_c2_value[ cpustate->opcode & 0x03 ]; } if ( cpustate->decode & F_COMX ) { cpustate->x = cpustate->x ^ 0x03; } + if ( cpustate->decode & F_COMC ) + { + cpustate->cb = cpustate->cb ^ 0x01; + } if ( cpustate->decode & F_LDP ) { - cpustate->pb = tms0980_c_value[ cpustate->opcode & 0x0F ]; + cpustate->pb = tms0980_c4_value[ cpustate->opcode & 0x0F ]; } if ( cpustate->decode & F_REAC ) { @@ -716,7 +1009,6 @@ static CPU_EXECUTE( tms0980 ) break; case 3: /* fetch: fetch, update pc, ram address */ - cpustate->ram_address = ( cpustate->x << 4 ) | cpustate->y; /* execute: register store */ break; case 4: @@ -731,22 +1023,32 @@ static CPU_EXECUTE( tms0980 ) { cpustate->y = cpustate->adder_result & 0x0F; } -// if ( cpustate->decode & M_STSL ) -// { -// cpustate->status_latch = cpustate->status; -// } + if ( cpustate->decode & 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 ( cpustate->byte_size > 8 ) + { + debugger_instruction_hook( device, cpustate->rom_address << 1 ); + cpustate->opcode = memory_read_word_16be( cpustate->program, cpustate->rom_address << 1 ) & 0x1FF; + } + else + { + debugger_instruction_hook( device, cpustate->rom_address ); + cpustate->opcode = memory_read_word_8le( cpustate->program, cpustate->rom_address ) & 0xFF; + } + tms0980_next_pc( cpustate ); if (LOG) - logerror( "tms0980: read opcode %04x. Set pc to %04x\n", cpustate->opcode, cpustate->pc ); + logerror( "tms0980: read opcode %04x from %04x. Set pc to %04x\n", cpustate->opcode, cpustate->rom_address, cpustate->pc ); + + /* ram address */ + cpustate->ram_address = ( cpustate->x << 4 ) | cpustate->y; break; case 5: /* fetch: instruction decode */ - cpustate->decode = tms0980_decode[ cpustate->opcode ]; + cpustate->decode = cpustate->decode_table[ cpustate->opcode ]; /* execute: execute br/call */ if ( cpustate->status ) { @@ -756,7 +1058,7 @@ static CPU_EXECUTE( tms0980 ) { cpustate->pa = cpustate->pb; } - cpustate->pc = cpustate->opcode & 0x7F; + cpustate->pc = cpustate->opcode & ( ( 1 << cpustate->pc_size ) - 1 ); } if ( cpustate->decode == F_CALL ) { @@ -768,7 +1070,7 @@ static CPU_EXECUTE( tms0980 ) cpustate->pa = cpustate->pb; } cpustate->pb = t; - cpustate->pc = cpustate->opcode & 0x7F; + cpustate->pc = cpustate->opcode & ( ( 1 << cpustate->pc_size ) - 1 ); } } if ( cpustate->decode == F_RETN ) @@ -811,7 +1113,7 @@ static CPU_SET_INFO( tms0980 ) } -CPU_GET_INFO( tms0980 ) +static CPU_GET_INFO( tms_generic ) { tms0980_state *cpustate = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL; @@ -822,16 +1124,11 @@ CPU_GET_INFO( tms0980 ) case DEVINFO_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 DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16 /* 9 */; break; - case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 12; break; case DEVINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break; case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 8 /* 4 */; break; - case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; case DEVINFO_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; @@ -846,21 +1143,16 @@ CPU_GET_INFO( tms0980 ) 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_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME( tms0980_internal_rom ); break; - case CPUINFO_PTR_INTERNAL_MEMORY_MAP_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 DEVINFO_STR_NAME: strcpy( info->s, "TMS0980" ); break; - case DEVINFO_STR_FAMILY: strcpy( info->s, "Texas Instruments TMS0980" ); break; - case DEVINFO_STR_VERSION: strcpy( info->s, "0.1" ); break; - case DEVINFO_STR_SOURCE_FILE: strcpy( info->s, __FILE__ ); break; - case DEVINFO_STR_CREDITS: strcpy( info->s, "Copyright the MESS and MAME teams" ); break; + case DEVINFO_STR_FAMILY: strcpy( info->s, "Texas Instruments TMS0980/TMS1000" ); break; + case DEVINFO_STR_VERSION: strcpy( info->s, "0.2" ); break; + case DEVINFO_STR_SOURCE_FILE: strcpy( info->s, __FILE__ ); break; + case DEVINFO_STR_CREDITS: strcpy( info->s, "Copyright the MESS and MAME teams" ); break; case CPUINFO_STR_FLAGS: strcpy( info->s, "N/A" ); break; @@ -876,3 +1168,115 @@ CPU_GET_INFO( tms0980 ) } } + +CPU_GET_INFO( tms0980 ) +{ + tms0980_state *cpustate = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL; + + switch(state) + { + case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break; + case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 2; break; + case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16 /* 9 */; break; + case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 12; break; + case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; 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_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map16 = ADDRESS_MAP_NAME( tms0980_internal_rom ); break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: info->internal_map8 = ADDRESS_MAP_NAME( tms0980_internal_ram ); break; + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms0980 ); break; + case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME( tms0980 ); break; + case DEVINFO_STR_NAME: strcpy( info->s, "TMS0980" ); break; + default: CPU_GET_INFO_CALL( tms_generic ); + } +} + + +CPU_GET_INFO( tms1000 ) +{ + tms0980_state *cpustate = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL; + + switch(state) + { + case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break; + case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 1; break; + case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; + case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 10; break; + case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 6; break; + case CPUINFO_INT_PREVIOUSPC: info->i = ( cpustate->prev_pa << 6 ) | tms1000_pc_decode[ cpustate->prev_pc ]; break; + case CPUINFO_INT_PC: info->i = ( cpustate->pa << 6 ) | tms1000_pc_decode[ cpustate->pc ]; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME( program_10bit_8 ); break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: info->internal_map8 = ADDRESS_MAP_NAME( data_6bit ); break; + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1000 ); break; + case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME( tms1000 ); break; + case DEVINFO_STR_NAME: strcpy( info->s, "TMS1000" ); break; + default: CPU_GET_INFO_CALL( tms_generic ); + } +} + + +CPU_GET_INFO( tms1070 ) +{ + switch(state) + { + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1070 ); break; + case DEVINFO_STR_NAME: strcpy( info->s, "TMS1070" ); break; + default: CPU_GET_INFO_CALL( tms1000 ); + } +} + + +CPU_GET_INFO( tms1200 ) +{ + switch(state) + { + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1200 ); break; + case DEVINFO_STR_NAME: strcpy( info->s, "TMS1200" ); break; + default: CPU_GET_INFO_CALL( tms1000 ); + } +} + + +CPU_GET_INFO( tms1270 ) +{ + switch(state) + { + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1270 ); break; + case DEVINFO_STR_NAME: strcpy( info->s, "TMS1270" ); break; + default: CPU_GET_INFO_CALL( tms1000 ); + } +} + + + +CPU_GET_INFO( tms1100 ) +{ + tms0980_state *cpustate = (device != NULL && device->token != NULL) ? get_safe_token(device) : NULL; + + switch(state) + { + case DEVINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break; + case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 11; break; + case DEVINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 7; break; + case CPUINFO_INT_PREVIOUSPC: info->i = ( cpustate->prev_pa << 6 ) | tms1000_pc_decode[ cpustate->prev_pc ]; break; + case CPUINFO_INT_PC: info->i = ( cpustate->pa << 6 ) | tms1000_pc_decode[ cpustate->pc ]; break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP_PROGRAM: info->internal_map8 = ADDRESS_MAP_NAME( program_11bit_8 ); break; + case CPUINFO_PTR_INTERNAL_MEMORY_MAP_DATA: info->internal_map8 = ADDRESS_MAP_NAME( data_7bit ); break; + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1100 ); break; + case CPUINFO_FCT_DISASSEMBLE: info->disassemble = CPU_DISASSEMBLE_NAME( tms1100 ); break; + case DEVINFO_STR_NAME: strcpy( info->s, "TMS1100" ); break; + default: CPU_GET_INFO_CALL( tms_generic ); + } +} + + +CPU_GET_INFO( tms1300 ) +{ + switch(state) + { + case CPUINFO_FCT_INIT: info->init = CPU_INIT_NAME( tms1300 ); break; + case DEVINFO_STR_NAME: strcpy( info->s, "TMS1300" ); break; + default: CPU_GET_INFO_CALL( tms1100 ); + } +} + diff --git a/src/emu/cpu/tms0980/tms0980.h b/src/emu/cpu/tms0980/tms0980.h index cd590d33f8c..78d2234ae48 100644 --- a/src/emu/cpu/tms0980/tms0980.h +++ b/src/emu/cpu/tms0980/tms0980.h @@ -12,16 +12,40 @@ enum { typedef struct _tms0980_config tms0980_config; struct _tms0980_config { + /* O-output PLA configuration */ + struct { + UINT8 value; + UINT16 output; + } o_pla[20]; read8_device_func read_k; - write8_device_func write_o; + write16_device_func write_o; /* tms1270 has 10 O-outputs */ write16_device_func write_r; }; +/* 9-bit family */ #define CPU_TMS0980 CPU_GET_INFO_NAME( tms0980 ) extern CPU_GET_INFO( tms0980 ); extern CPU_DISASSEMBLE( tms0980 ); +/* 8-bit family */ +#define CPU_TMS1000 CPU_GET_INFO_NAME( tms1000 ) +#define CPU_TMS1070 CPU_GET_INFO_NAME( tms1070 ) +#define CPU_TMS1100 CPU_GET_INFO_NAME( tms1100 ) +#define CPU_TMS1200 CPU_GET_INFO_NAME( tms1200 ) +#define CPU_TMS1270 CPU_GET_INFO_NAME( tms1270 ) +#define CPU_TMS1300 CPU_GET_INFO_NAME( tms1300 ) + +extern CPU_GET_INFO( tms1000 ); +extern CPU_GET_INFO( tms1070 ); +extern CPU_GET_INFO( tms1100 ); +extern CPU_GET_INFO( tms1200 ); +extern CPU_GET_INFO( tms1270 ); +extern CPU_GET_INFO( tms1300 ); + +extern CPU_DISASSEMBLE( tms1000 ); +extern CPU_DISASSEMBLE( tms1100 ); + #endif /* _TMS0980_H_ */ diff --git a/src/emu/cpu/tms0980/tms0980d.c b/src/emu/cpu/tms0980/tms0980d.c index f35f82266d7..da86411996e 100644 --- a/src/emu/cpu/tms0980/tms0980d.c +++ b/src/emu/cpu/tms0980/tms0980d.c @@ -14,11 +14,11 @@ TMS0980 disassembly 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, + zA10AAC=0, zA6AAC, zA8AAC, zAC1AC, zACACC, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA, + zCLA, zCLO, zCOMC, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDAN, zDMAN, zDMEA, zDNAA, + zDYN, zIA, zIMAC, zIYC, zKNE, zKNEZ, zLDP, zLDX, zLDX4, zMNEA, zMNEZ, + zNDMEA, zOFF, zRBIT, zREAC, zRETN, zRSTR, zSAL, zSAMAN, zSBIT, + zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIY, zTAMIYC, zTAMZA, zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA, zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC, zILL @@ -26,16 +26,16 @@ enum e_mnemonics { enum e_addressing { - zB0=0, zB2, zB4, zB7 + zB0=0, zB2, zI2, zI4, 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", + "a10aac", "a6aac", "a8aac", "ac1ac", "acacc", "acnaa", "alec", "alem", "amaac", "branch", "call", "ccla", + "cla", "clo", "comc", "comx", "comx8", "cpaiz", "ctmdyn", "dan", "dman", "dmea", "dnaa", + "dyn", "ia", "imac", "iyc", "kne", "knez", "ldp", "ldx", "ldx", "mnea", "mnez", + "ndmea", "off", "rbit", "reac", "retn", "rstr", "sal", "saman", "sbit", + "sbl", "seac", "setr", "tam", "tamacs", "tamdyn", "tamiy", "tamiyc", "tamza", "tay", "tbit", "tcmiy", "tcy", "tdo", "tka", "tkm", "tma", "tmy", "tya", "xda", "xma", "ymcy", "ynea", "ynec", "illegal" @@ -43,11 +43,11 @@ static const char *s_mnemonic[] = { 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, _OVER, 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, _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, 0, 0 @@ -55,13 +55,13 @@ static const UINT32 s_flags[] = { 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, zB0, zB0, zI4, zI4, zI4, zI4, zB0, zB0, zB7, zB7, zB0, + zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, + zB0, zB0, zB0, zB0, zB0, zB0, zI4, zI2, zI4, zB0, zB0, + zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, + zB0, zB0, zB0, zB0, zI4, zB0, zB0, zB0, zB2, + zB0, zB2, zI4, zI4, zB0, zB0, zB0, zB0, + zB0, zB0, zB0, zB0, zI4, zB0, zI4, zB0 }; @@ -95,8 +95,8 @@ static const UINT8 tms0980_mnemonic[512] = { 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, + zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, + zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, /* 0x0A0 */ zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, zILL, zILL, zILL, zILL, zILL, zILL, zILL, zILL, @@ -152,13 +152,99 @@ static const UINT8 tms0980_mnemonic[512] = { }; -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 }; +static const UINT8 tms1000_mnemonic[256] = { + /* 0x00 */ + zCOMX, zA8AAC, zYNEA, zTAM, zTAMZA, zA10AAC, zA6AAC, zDAN, + zTKA, zKNEZ, zTDO, zCLO, zRSTR, zSETR, zIA, zRETN, + zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, + zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, + zTAMIY, zTMA, zTMY, zTYA, zTAY, zAMAAC, zMNEZ, zSAMAN, + zIMAC, zALEM, zDMAN, zIYC, zDYN, zCPAIZ, zXMA, zCLA, + zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, + zTBIT, zTBIT, zTBIT, zTBIT, zLDX, zLDX, zLDX, zLDX, + /* 0x40 */ + zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, + zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, + zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, + zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, + zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, + zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, + zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, + zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, + /* 0x80 */ + 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, + /* 0xc0 */ + 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 +}; + + +static const UINT8 tms1100_mnemonic[256] = { + /* 0x00 */ + zMNEA, zALEM, zYNEA, zXMA, zDYN, zIYC, zAMAAC, zDMAN, + zTKA, zCOMX, zTDO, zCOMC, zRSTR, zSETR, zKNEZ, zRETN, + zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, + zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, + /* 0x20 */ + zTAY, zTMA, zTMY, zTYA, zTAMDYN, zTAMIYC, zTAMZA, zTAM, + zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, zLDX, + zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, + zTBIT, zTBIT, zTBIT, zTBIT, zSAMAN, zCPAIZ, zIMAC, zMNEZ, + /* 0x40 */ + zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, + zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, + zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, + zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, + /* 0x60 */ + zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, + zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, + zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, + zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zCLA, + /* 0x80 */ + 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, + /* 0xC0 */ + 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, +}; +static const UINT8 tms0980_i2_value[4] = +{ + 0x00, 0x02, 0x01, 0x03 +}; +static const UINT8 tms0980_i4_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 }; + + +CPU_DISASSEMBLE( tms0980 ) { char *dst = buffer; UINT16 op, instr; int pos = 0; @@ -176,11 +262,80 @@ CPU_DISASSEMBLE( tms0980 ) { case zB2: dst += sprintf( dst, "#$%d", tms0980_bit_value[ op & 3 ] ); break; - case zB4: - dst += sprintf( dst, "#$%01X", tms0980_c_value[ op & 0x0F ] ); + case zI2: + dst += sprintf( dst, "#$%01X", tms0980_i2_value[ op & 0x03 ] ); + break; + case zI4: + dst += sprintf( dst, "#$%01X", tms0980_i4_value[ op & 0x0F ] ); + break; + case zB7: + dst += sprintf( dst, "#$%02X", ( op & 0x7F ) << 1 ); + break; + } + + return pos | s_flags[instr] | DASMFLAG_SUPPORTED; +} + + +CPU_DISASSEMBLE( tms1000 ) { + char *dst = buffer; + UINT8 op, instr; + int pos = 0; + + op = oprom[pos]; + pos += 1; + + instr = tms1000_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 zI2: + dst += sprintf( dst, "#$%01X", tms0980_i2_value[ op & 0x03 ] ); + break; + case zI4: + dst += sprintf( dst, "#$%01X", tms0980_i4_value[ op & 0x0F ] ); + break; + case zB7: + dst += sprintf( dst, "#$%02X", ( op & 0x3F ) ); + break; + } + + return pos | s_flags[instr] | DASMFLAG_SUPPORTED; +} + + +CPU_DISASSEMBLE( tms1100 ) { + char *dst = buffer; + UINT8 op, instr; + int pos = 0; + + op = oprom[pos]; + pos += 1; + + instr = tms1100_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 zI2: + dst += sprintf( dst, "#$%01X", tms0980_i2_value[ op & 0x03 ] ); + break; + case zI4: + dst += sprintf( dst, "#$%01X", tms0980_i4_value[ op & 0x0F ] ); break; case zB7: - dst += sprintf( dst, "#$%02X", op & 0x7F ); + dst += sprintf( dst, "#$%02X", ( op & 0x3F ) ); break; } |