preliminary support for TMS1400

This commit is contained in:
hap 2015-01-17 02:34:10 +01:00
parent 09683be0d8
commit 53d8bfbd6b
2 changed files with 244 additions and 90 deletions

View File

@ -69,54 +69,55 @@ unknown cycle: CME, SSE, SSS
*/
/* Microinstructions */
#define M_15TN 0x00000001 /* 15 to -ALU */
#define M_ATN 0x00000002 /* ACC to -ALU */
#define M_AUTA 0x00000004 /* ALU to ACC */
#define M_AUTY 0x00000008 /* ALU to Y */
#define M_C8 0x00000010 /* CARRY8 to STATUS */
#define M_CIN 0x00000020 /* Carry In to ALU */
#define M_CKM 0x00000040 /* CKB to MEM */
#define M_CKN 0x00000080 /* CKB to -ALU */
#define M_CKP 0x00000100 /* CKB to +ALU */
#define M_MTN 0x00000200 /* MEM to -ALU */
#define M_MTP 0x00000400 /* MEM to +ALU */
#define M_NATN 0x00000800 /* ~ACC to -ALU */
#define M_NE 0x00001000 /* COMP to STATUS */
#define M_STO 0x00002000 /* ACC to MEM */
#define M_STSL 0x00004000 /* STATUS to Status Latch */
#define M_YTP 0x00008000 /* Y to +ALU */
#define M_15TN (1<<0) /* 15 to -ALU */
#define M_ATN (1<<1) /* ACC to -ALU */
#define M_AUTA (1<<2) /* ALU to ACC */
#define M_AUTY (1<<3) /* ALU to Y */
#define M_C8 (1<<4) /* CARRY8 to STATUS */
#define M_CIN (1<<5) /* Carry In to ALU */
#define M_CKM (1<<6) /* CKB to MEM */
#define M_CKN (1<<7) /* CKB to -ALU */
#define M_CKP (1<<8) /* CKB to +ALU */
#define M_MTN (1<<9) /* MEM to -ALU */
#define M_MTP (1<<10) /* MEM to +ALU */
#define M_NATN (1<<11) /* ~ACC to -ALU */
#define M_NE (1<<12) /* COMP to STATUS */
#define M_STO (1<<13) /* ACC to MEM */
#define M_STSL (1<<14) /* STATUS to Status Latch */
#define M_YTP (1<<15) /* Y to +ALU */
#define M_CME 0x00010000 /* Conditional Memory Enable */
#define M_DMTP 0x00020000 /* DAM to +ALU */
#define M_NDMTP 0x00040000 /* ~DAM to +ALU */
#define M_SSE 0x00080000 /* Special Status Enable */
#define M_SSS 0x00100000 /* Special Status Sample */
#define M_CME (1<<16) /* Conditional Memory Enable */
#define M_DMTP (1<<17) /* DAM to +ALU */
#define M_NDMTP (1<<18) /* ~DAM to +ALU */
#define M_SSE (1<<19) /* Special Status Enable */
#define M_SSS (1<<20) /* Special Status Sample */
#define M_RSTR 0x00200000 /* -> line #36, F_RSTR (TMS02x0 custom) */
#define M_UNK1 0x00400000 /* -> line #37, F_???? (TMS0270 custom) */
#define M_RSTR (1<<21) /* -> line #36, F_RSTR (TMS02x0 custom) */
#define M_UNK1 (1<<22) /* -> line #37, F_???? (TMS0270 custom) */
/* Standard/fixed instructions - these are documented more in their specific handlers below */
#define F_BR 0x00000001
#define F_CALL 0x00000002
#define F_CLO 0x00000004
#define F_COMC 0x00000008
#define F_COMX 0x00000010
#define F_COMX8 0x00000020
#define F_LDP 0x00000040
#define F_LDX 0x00000080
#define F_RBIT 0x00000100
#define F_RETN 0x00000200
#define F_RSTR 0x00000400
#define F_SBIT 0x00000800
#define F_SETR 0x00001000
#define F_TDO 0x00002000
#define F_BR (1<<0)
#define F_CALL (1<<1)
#define F_CLO (1<<2)
#define F_COMC (1<<3)
#define F_COMX (1<<4)
#define F_COMX8 (1<<5)
#define F_LDP (1<<6)
#define F_LDX (1<<7)
#define F_RBIT (1<<8)
#define F_RETN (1<<9)
#define F_RSTR (1<<10)
#define F_SBIT (1<<11)
#define F_SETR (1<<12)
#define F_TDO (1<<13)
#define F_TPC (1<<14)
#define F_OFF 0x00004000
#define F_REAC 0x00008000
#define F_SAL 0x00010000
#define F_SBL 0x00020000
#define F_SEAC 0x00040000
#define F_XDA 0x00080000
#define F_OFF (1<<15)
#define F_REAC (1<<16)
#define F_SAL (1<<17)
#define F_SBL (1<<18)
#define F_SEAC (1<<19)
#define F_XDA (1<<20)
// supported types:
@ -132,13 +133,21 @@ 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 TMS1070 = &device_creator<tms1070_cpu_device>; // same as tms1000, just supports higher voltage
const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // almost 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
const device_type TMS1100 = &device_creator<tms1100_cpu_device>; // 28-pin DIP, 11 R pins
const device_type TMS1170 = &device_creator<tms1170_cpu_device>; // almost same as tms1100, just supports higher voltage
const device_type TMS1300 = &device_creator<tms1300_cpu_device>; // 40-pin DIP, 16 R pins
const device_type TMS1370 = &device_creator<tms1370_cpu_device>; // almost same as tms1300, just supports higher voltage
// TMS1400 follows the TMS1100, it doubles the ROM size again (4 chapters of 16 pages), and adds a 3-level callstack
// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
// - the opla size is increased from 20 to 32 terms
const device_type TMS1400 = &device_creator<tms1400_cpu_device>; // 28-pin DIP, 11 R pins
const device_type TMS1470 = &device_creator<tms1470_cpu_device>; // almost same as tms1400, just supports higher voltage
// TMS0980
// - 64x9bit RAM array at the bottom-left (set up as 144x4)
@ -177,6 +186,10 @@ static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
AM_RANGE(0x000, 0x7ff) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START(program_12bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
AM_RANGE(0x000, 0xfff) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1xxx_cpu_device)
AM_RANGE(0x00, 0x3f) AM_RAM
@ -217,8 +230,29 @@ tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, device_typ
: tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
{ }
tms1170_cpu_device::tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: tms1100_cpu_device(mconfig, TMS1170, "TMS1170", tag, owner, clock, 8, 11, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1170", __FILE__)
{ }
tms1300_cpu_device::tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: tms1100_cpu_device(mconfig, TMS1300, "TMS1200", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1300", __FILE__)
: tms1100_cpu_device(mconfig, TMS1300, "TMS1300", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1300", __FILE__)
{ }
tms1370_cpu_device::tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: tms1100_cpu_device(mconfig, TMS1370, "TMS1370", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1370", __FILE__)
{ }
tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: tms1100_cpu_device(mconfig, TMS1400, "TMS1400", tag, owner, clock, 8, 11, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1400", __FILE__)
{ }
tms1400_cpu_device::tms1400_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 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)
: tms1100_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
{ }
tms1470_cpu_device::tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: tms1400_cpu_device(mconfig, TMS1470, "TMS1470", tag, owner, clock, 8, 10, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1470", __FILE__)
{ }
@ -264,6 +298,21 @@ machine_config_constructor tms1000_cpu_device::device_mconfig_additions() const
}
static MACHINE_CONFIG_FRAGMENT(tms1400)
// microinstructions PLA, output PLA
MCFG_PLA_ADD("mpla", 8, 16, 30)
MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
MCFG_PLA_ADD("opla", 5, 8, 32)
MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
MACHINE_CONFIG_END
machine_config_constructor tms1400_cpu_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME(tms1400);
}
static MACHINE_CONFIG_FRAGMENT(tms0970)
// main opcodes PLA, microinstructions PLA, output PLA, segment PLA
@ -582,6 +631,15 @@ void tms1100_cpu_device::device_reset()
for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = 0;
}
void tms1400_cpu_device::device_reset()
{
tms1100_cpu_device::device_reset();
// small differences in 00-3f area
m_fixed_decode[0x09] = F_COMX; // !
m_fixed_decode[0x0b] = F_TPC;
}
void tms0970_cpu_device::device_reset()
{
@ -899,6 +957,87 @@ void tms0980_cpu_device::set_cki_bus()
// fixed opcode set
//-------------------------------------------------
// handle branches:
// note: add(latch) and bl(branch latch) are specific to 0980 series,
// c(chapter) bits are specific to 1100(and 1400) series
// TMS1000/common:
void tms1xxx_cpu_device::op_br()
{
// BR/BL: conditional branch
if (!m_status)
return;
if (!m_clatch)
m_pa = m_pb;
m_ca = m_cb;
m_pc = m_opcode & m_pc_mask;
}
void tms1xxx_cpu_device::op_call()
{
// CALL/CALLL: conditional call
if (!m_status)
return;
UINT8 prev_pa = m_pa;
if (!m_clatch)
{
m_sr = m_pc;
m_clatch = 1;
m_pa = m_pb;
m_cs = m_ca;
}
m_ca = m_cb;
m_pb = prev_pa;
m_pc = m_opcode & m_pc_mask;
}
void tms1xxx_cpu_device::op_retn()
{
// RETN: return from subroutine
if (m_clatch)
{
m_pc = m_sr;
m_clatch = 0;
m_ca = m_cs;
}
m_add = 0;
m_bl = 0;
m_pa = m_pb;
}
// TMS1400-specific
void tms1400_cpu_device::op_br()
{
// BR/BL: conditional branch
if (!m_status)
return;
//..
}
void tms1400_cpu_device::op_call()
{
// CALL/CALLL: conditional call
if (!m_status)
return;
//..
}
void tms1400_cpu_device::op_retn()
{
// RETN: return from subroutine
//..
}
// handle other:
// TMS1000/common:
void tms1xxx_cpu_device::op_sbit()
@ -992,6 +1131,15 @@ void tms1xxx_cpu_device::op_comc()
}
// TMS1400-specific
void tms1xxx_cpu_device::op_tpc()
{
// TPC: transfer page buffer to chapter buffer
m_cb = m_pb & 3;
}
// TMS0970-specific (and possibly child classes)
void tms0970_cpu_device::op_setr()
{
@ -1095,51 +1243,9 @@ void tms1xxx_cpu_device::execute_run()
// fetch: rom address 1/2
// execute: br/call 2/2
// note: add(latch) and bl(branch latch) are specific to 0980 series,
// c(chapter) bits are specific to 1100 series
if (m_status)
{
UINT8 new_pc = m_opcode & m_pc_mask;
// BR: conditional branch
if (m_fixed & F_BR)
{
if (m_clatch == 0)
m_pa = m_pb;
m_ca = m_cb;
m_pc = new_pc;
}
// CALL: conditional call
if (m_fixed & F_CALL)
{
UINT8 prev_pa = m_pa;
if (m_clatch == 0)
{
m_sr = m_pc;
m_clatch = 1;
m_pa = m_pb;
m_cs = m_ca;
}
m_ca = m_cb;
m_pb = prev_pa;
m_pc = new_pc;
}
}
// RETN: return from subroutine
if (m_fixed & F_RETN)
{
if (m_clatch == 1)
{
m_pc = m_sr;
m_clatch = 0;
m_ca = m_cs;
}
m_add = 0;
m_bl = 0;
m_pa = m_pb;
}
if (m_fixed & F_BR) op_br();
if (m_fixed & F_CALL) op_call();
if (m_fixed & F_RETN) op_retn();
// execute: k input valid, read ram, clear alu inputs
dynamic_output();
@ -1216,6 +1322,7 @@ void tms1xxx_cpu_device::execute_run()
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_TPC) op_tpc();
if (m_fixed & F_OFF) op_off();
if (m_fixed & F_SEAC) op_seac();
if (m_fixed & F_REAC) op_reac();

View File

@ -106,6 +106,10 @@ protected:
virtual void dynamic_output() { ; } // not used by default
virtual void read_opcode();
virtual void op_br();
virtual void op_call();
virtual void op_retn();
virtual void op_sbit();
virtual void op_rbit();
virtual void op_setr();
@ -118,6 +122,7 @@ protected:
virtual void op_ldp();
virtual void op_comc();
virtual void op_tpc();
virtual void op_xda();
virtual void op_off();
virtual void op_seac();
@ -244,12 +249,50 @@ protected:
virtual void op_rstr();
};
class tms1170_cpu_device : public tms1100_cpu_device
{
public:
tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class tms1300_cpu_device : public tms1100_cpu_device
{
public:
tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class tms1370_cpu_device : public tms1100_cpu_device
{
public:
tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class tms1400_cpu_device : public tms1100_cpu_device
{
public:
tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
tms1400_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 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
virtual void device_reset();
virtual machine_config_constructor device_mconfig_additions() const;
virtual void op_br();
virtual void op_call();
virtual void op_retn();
virtual void op_setr() { tms1xxx_cpu_device::op_setr(); } // no anomaly with MSB of X register
virtual void op_rstr() { tms1xxx_cpu_device::op_rstr(); } // "
};
class tms1470_cpu_device : public tms1400_cpu_device
{
public:
tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
class tms0970_cpu_device : public tms1000_cpu_device
{
@ -344,7 +387,11 @@ extern const device_type TMS1000;
extern const device_type TMS1070;
extern const device_type TMS1200;
extern const device_type TMS1100;
extern const device_type TMS1170;
extern const device_type TMS1300;
extern const device_type TMS1370;
extern const device_type TMS1400;
extern const device_type TMS1470;
extern const device_type TMS0970;
extern const device_type TMS0980;
extern const device_type TMS0270;