summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2021-11-20 09:35:18 +0900
committer GitHub <noreply@github.com>2021-11-19 19:35:18 -0500
commit6229ca9544962fa7e69dc8691346bc586482197b (patch)
treecd612ab88a31c2adeaa3067bc0932abcd1b00d43 /src
parentf0d98df48769ffaa92155137aa5733eeabe90f93 (diff)
tms32031.cpp: Add TMS320VC33 emulation support, Add notes (#8766)
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/tms32031/32031ops.hxx46
-rw-r--r--src/devices/cpu/tms32031/tms32031.cpp75
-rw-r--r--src/devices/cpu/tms32031/tms32031.h44
-rw-r--r--src/mame/audio/cage.cpp2
4 files changed, 125 insertions, 42 deletions
diff --git a/src/devices/cpu/tms32031/32031ops.hxx b/src/devices/cpu/tms32031/32031ops.hxx
index 06533f09abb..db994cb26c2 100644
--- a/src/devices/cpu/tms32031/32031ops.hxx
+++ b/src/devices/cpu/tms32031/32031ops.hxx
@@ -88,7 +88,7 @@ void tms3203x_device::unimplemented(uint32_t op)
inline void tms3203x_device::execute_one()
{
uint32_t op = ROPCODE(m_pc);
- m_icount -= 2; // 2 clocks per cycle
+ burn_cycle(1);
m_pc++;
#if (TMS_3203X_LOG_OPCODE_USAGE)
m_hits[op >> 21]++;
@@ -118,6 +118,11 @@ void tms3203x_device::update_special(int dreg)
}
+void tms3203x_device::burn_cycle(int cycle)
+{
+ m_icount -= cycle * (m_is_lopower ? 16 : 1);
+}
+
//**************************************************************************
// CONDITION CODES
@@ -2560,7 +2565,12 @@ void tms3203x_device::or_imm(uint32_t op)
/*-----------------------------------------------------*/
-void tms3203x_device::maxspeed(uint32_t op) { unimplemented(op); }
+void tms3203x_device::maxspeed(uint32_t op)
+{
+ // 0x10800000 MAXSPEED
+ // 0x10800001 LOPOWER
+ m_is_lopower = BIT(op, 0);
+}
/*-----------------------------------------------------*/
@@ -2695,7 +2705,7 @@ void tms3203x_device::rpts_reg(uint32_t op)
IREG(TMR_RS) = m_pc;
IREG(TMR_RE) = m_pc;
IREG(TMR_ST) |= RMFLAG;
- m_icount -= 3*2;
+ burn_cycle(3);
m_delayed = true;
}
@@ -2705,7 +2715,7 @@ void tms3203x_device::rpts_dir(uint32_t op)
IREG(TMR_RS) = m_pc;
IREG(TMR_RE) = m_pc;
IREG(TMR_ST) |= RMFLAG;
- m_icount -= 3*2;
+ burn_cycle(3);
m_delayed = true;
}
@@ -2715,7 +2725,7 @@ void tms3203x_device::rpts_ind(uint32_t op)
IREG(TMR_RS) = m_pc;
IREG(TMR_RE) = m_pc;
IREG(TMR_ST) |= RMFLAG;
- m_icount -= 3*2;
+ burn_cycle(3);
m_delayed = true;
}
@@ -2725,7 +2735,7 @@ void tms3203x_device::rpts_imm(uint32_t op)
IREG(TMR_RS) = m_pc;
IREG(TMR_RE) = m_pc;
IREG(TMR_ST) |= RMFLAG;
- m_icount -= 3*2;
+ burn_cycle(3);
m_delayed = true;
}
@@ -5514,7 +5524,7 @@ inline void tms3203x_device::execute_delayed(uint32_t newpc)
void tms3203x_device::br_imm(uint32_t op)
{
m_pc = op & 0xffffff;
- m_icount -= 3*2;
+ burn_cycle(3);
}
void tms3203x_device::brd_imm(uint32_t op)
@@ -5528,7 +5538,7 @@ void tms3203x_device::call_imm(uint32_t op)
{
WMEM(++IREG(TMR_SP), m_pc);
m_pc = op & 0xffffff;
- m_icount -= 3*2;
+ burn_cycle(3);
}
/*-----------------------------------------------------*/
@@ -5538,7 +5548,7 @@ void tms3203x_device::rptb_imm(uint32_t op)
IREG(TMR_RS) = m_pc;
IREG(TMR_RE) = op & 0xffffff;
IREG(TMR_ST) |= RMFLAG;
- m_icount -= 3*2;
+ burn_cycle(3);
}
/*-----------------------------------------------------*/
@@ -5552,7 +5562,7 @@ void tms3203x_device::brc_reg(uint32_t op)
if (condition(op >> 16))
{
m_pc = IREG(op & 31);
- m_icount -= 3*2;
+ burn_cycle(3);
}
}
@@ -5569,7 +5579,7 @@ void tms3203x_device::brc_imm(uint32_t op)
if (condition(op >> 16))
{
m_pc += (int16_t)op;
- m_icount -= 3*2;
+ burn_cycle(3);
}
}
@@ -5591,7 +5601,7 @@ void tms3203x_device::dbc_reg(uint32_t op)
if (condition(op >> 16) && !(res & 0x800000))
{
m_pc = IREG(op & 31);
- m_icount -= 3*2;
+ burn_cycle(3);
}
}
@@ -5614,7 +5624,7 @@ void tms3203x_device::dbc_imm(uint32_t op)
if (condition(op >> 16) && !(res & 0x800000))
{
m_pc += (int16_t)op;
- m_icount -= 3*2;
+ burn_cycle(3);
}
}
@@ -5637,7 +5647,7 @@ void tms3203x_device::callc_reg(uint32_t op)
{
WMEM(++IREG(TMR_SP), m_pc);
m_pc = IREG(op & 31);
- m_icount -= 3*2;
+ burn_cycle(3);
}
}
@@ -5647,7 +5657,7 @@ void tms3203x_device::callc_imm(uint32_t op)
{
WMEM(++IREG(TMR_SP), m_pc);
m_pc += (int16_t)op;
- m_icount -= 3*2;
+ burn_cycle(3);
}
}
@@ -5661,7 +5671,7 @@ void tms3203x_device::trap(int trapnum)
m_pc = RMEM(((IREG(TMR_IF) >> 16) << 8) + trapnum);
else
m_pc = RMEM(trapnum);
- m_icount -= 4*2;
+ burn_cycle(4);
}
void tms3203x_device::trapc(uint32_t op)
@@ -5678,7 +5688,7 @@ void tms3203x_device::retic_reg(uint32_t op)
{
m_pc = RMEM(IREG(TMR_SP)--);
IREG(TMR_ST) |= GIEFLAG;
- m_icount -= 3*2;
+ burn_cycle(3);
check_irqs();
}
}
@@ -5688,7 +5698,7 @@ void tms3203x_device::retsc_reg(uint32_t op)
if (condition(op >> 16))
{
m_pc = RMEM(IREG(TMR_SP)--);
- m_icount -= 3*2;
+ burn_cycle(3);
}
}
diff --git a/src/devices/cpu/tms32031/tms32031.cpp b/src/devices/cpu/tms32031/tms32031.cpp
index 2e0409b2886..b46a2078498 100644
--- a/src/devices/cpu/tms32031/tms32031.cpp
+++ b/src/devices/cpu/tms32031/tms32031.cpp
@@ -6,10 +6,10 @@
TMS320C3x family 32-bit floating point DSP emulator
- TMS320C30/1/2 difference table:
+ TMS320C3x family difference table:
|-------------------|-------------------|-------------------|-------------------|
- | Feature | 'C30 | 'C31 | 'C32 |
+ | Feature | 'C30 | 'C31/'VC33 | 'C32 |
|-------------------|-------------------|-------------------|-------------------|
| External Bus | Two buses: | One bus: | One bus: |
| | Primary bus: | 32-bit data | 32-bit data |
@@ -35,9 +35,12 @@
|-------------------|-------------------|-------------------|-------------------|
| Boot Loader | No | Yes | Yes |
|-------------------|-------------------|-------------------|-------------------|
- | On-Chip RAM | 2k | 2k | 512 |
+ | On-Chip RAM | 2k | 2k('31)/34k('33) | 512 |
| (Words) | Address: | Address: | Address: |
| | 809800-809fff | 809800-809fff | 87fe00-87ffff |
+ | | | ('C31,'VC33) | |
+ | | | 800000-807fff | |
+ | | | ('VC33 only) | |
|-------------------|-------------------|-------------------|-------------------|
| DMA | 1 Channel | 1 Channel | 2 Channels |
| | CPU greater | CPU greater | Configurable |
@@ -62,6 +65,8 @@
TODO:
- merge and implement internal peripheral emulations
- implement chip family difference
+ - interlocked operation
+ - instruction pipelining
***************************************************************************/
@@ -148,6 +153,7 @@ const int GIEFLAG = 0x2000;
DEFINE_DEVICE_TYPE(TMS32030, tms32030_device, "tms32030", "Texas Instruments TMS320C30")
DEFINE_DEVICE_TYPE(TMS32031, tms32031_device, "tms32031", "Texas Instruments TMS320C31")
DEFINE_DEVICE_TYPE(TMS32032, tms32032_device, "tms32032", "Texas Instruments TMS320C32")
+DEFINE_DEVICE_TYPE(TMS32033, tms32033_device, "tms32033", "Texas Instruments TMS320VC33")
// memory map common to all 'C30 devices
// TODO: expand to cover all the standard internal peripherals
@@ -193,6 +199,8 @@ void tms32030_device::internal_32030(address_map &map)
//map(0x808060, 0x808060) Expansion-Bus Control
//map(0x808064, 0x808064) Primary-Bus Control
map(0x809800, 0x809fff).ram();
+ //map(0x809800, 0x809bff).ram(); // RAM block 0
+ //map(0x809c00, 0x809fff).ram(); // RAM block 1
//map(0x80a000, 0xffffff) STRB
}
@@ -203,6 +211,8 @@ void tms32031_device::internal_32031(address_map &map)
//map(0x000000, 0x7fffff) STRB
//map(0x808064, 0x808064) Primary-Bus Control
map(0x809800, 0x809fff).ram();
+ //map(0x809800, 0x809bff).ram(); // RAM block 0
+ //map(0x809c00, 0x809fff).ram(); // RAM block 1
//map(0x80a000, 0xffffff) STRB
}
@@ -220,10 +230,27 @@ void tms32032_device::internal_32032(address_map &map)
//map(0x808068, 0x808068) STRB1 Bus Control
//map(0x810000, 0x82ffff) IOSTRB
map(0x87fe00, 0x87ffff).ram();
+ //map(0x87fe00, 0x87feff).ram(); // RAM block 0
+ //map(0x87ff00, 0x87ffff).ram(); // RAM block 1
//map(0x880000, 0x8fffff) STRB0
//map(0x900000, 0xffffff) STRB1
}
+void tms32033_device::internal_32033(address_map &map)
+{
+ common_3203x(map);
+
+ //map(0x000000, 0x7fffff) STRB
+ map(0x800000, 0x807fff).ram();
+ //map(0x800000, 0x803fff).ram(); // RAM block 2
+ //map(0x804000, 0x807fff).ram(); // RAM block 3
+ //map(0x808064, 0x808064) Primary-Bus Control
+ map(0x809800, 0x809fff).ram();
+ //map(0x809800, 0x809bff).ram(); // RAM block 0
+ //map(0x809c00, 0x809fff).ram(); // RAM block 1
+ //map(0x80a000, 0xffffff) STRB
+}
+
// ROM definitions for the internal boot loader programs
// (Using assembled versions until the code ROMs are extracted from both DSPs)
@@ -380,7 +407,7 @@ void tms3203x_device::tmsreg::from_double(double val)
// tms3203x_device - constructor
//-------------------------------------------------
-tms3203x_device::tms3203x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t chiptype, address_map_constructor internal_map)
+tms3203x_device::tms3203x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t chiptype, int clock_per_inst, address_map_constructor internal_map)
: cpu_device(mconfig, type, tag, owner, clock),
m_program_config("program", ENDIANNESS_LITTLE, 32, 24, -2, internal_map),
m_chip_type(chiptype),
@@ -392,8 +419,10 @@ tms3203x_device::tms3203x_device(const machine_config &mconfig, device_type type
m_irq_pending(false),
m_is_idling(false),
m_icount(0),
+ m_clock_per_inst(clock_per_inst), // 1('VC33)/2 clocks per cycle
m_internal_rom(*this, "internal_rom"),
m_mcbl_mode(false),
+ m_is_lopower(false),
m_xf0_cb(*this),
m_xf1_cb(*this),
m_iack_cb(*this),
@@ -411,17 +440,22 @@ tms3203x_device::tms3203x_device(const machine_config &mconfig, device_type type
}
tms32030_device::tms32030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : tms3203x_device(mconfig, TMS32030, tag, owner, clock, CHIP_TYPE_TMS32030, address_map_constructor(FUNC(tms32030_device::internal_32030), this))
+ : tms3203x_device(mconfig, TMS32030, tag, owner, clock, CHIP_TYPE_TMS32030, 2, address_map_constructor(FUNC(tms32030_device::internal_32030), this))
{
}
tms32031_device::tms32031_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : tms3203x_device(mconfig, TMS32031, tag, owner, clock, CHIP_TYPE_TMS32031, address_map_constructor(FUNC(tms32031_device::internal_32031), this))
+ : tms3203x_device(mconfig, TMS32031, tag, owner, clock, CHIP_TYPE_TMS32031, 2, address_map_constructor(FUNC(tms32031_device::internal_32031), this))
{
}
tms32032_device::tms32032_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : tms3203x_device(mconfig, TMS32032, tag, owner, clock, CHIP_TYPE_TMS32032, address_map_constructor(FUNC(tms32032_device::internal_32032), this))
+ : tms3203x_device(mconfig, TMS32032, tag, owner, clock, CHIP_TYPE_TMS32032, 2, address_map_constructor(FUNC(tms32032_device::internal_32032), this))
+{
+}
+
+tms32033_device::tms32033_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : tms3203x_device(mconfig, TMS32033, tag, owner, clock, CHIP_TYPE_TMS32031, 1, address_map_constructor(FUNC(tms32033_device::internal_32033), this))
{
}
@@ -522,6 +556,7 @@ void tms3203x_device::device_start()
save_item(NAME(m_is_idling));
save_item(NAME(m_mcbl_mode));
save_item(NAME(m_hold_state));
+ save_item(NAME(m_is_lopower));
// register our state for the debugger
state_add(TMS3203X_PC, "PC", m_pc);
@@ -588,7 +623,7 @@ void tms3203x_device::device_reset()
m_primary_bus_control = 0x000010f8;
// reset internal stuff
- m_delayed = m_irq_pending = m_is_idling = false;
+ m_delayed = m_irq_pending = m_is_idling = m_is_lopower = false;
}
@@ -822,7 +857,7 @@ uint32_t tms3203x_device::execute_min_cycles() const noexcept
uint32_t tms3203x_device::execute_max_cycles() const noexcept
{
- return 4;
+ return 5 * 16; // max opcode cycle * low power operation mode
}
@@ -838,6 +873,28 @@ uint32_t tms3203x_device::execute_input_lines() const noexcept
//-------------------------------------------------
+// execute_clocks_to_cycles - convert the raw
+// clock into cycles per second
+//-------------------------------------------------
+
+uint64_t tms3203x_device::execute_clocks_to_cycles(uint64_t clocks) const noexcept
+{
+ return (clocks + m_clock_per_inst - 1) / m_clock_per_inst;
+}
+
+
+//-------------------------------------------------
+// execute_cycles_to_clocks - convert a cycle
+// count back to raw clocks
+//-------------------------------------------------
+
+uint64_t tms3203x_device::execute_cycles_to_clocks(uint64_t cycles) const noexcept
+{
+ return cycles * m_clock_per_inst;
+}
+
+
+//-------------------------------------------------
// execute_set_input - set input and IRQ lines
//-------------------------------------------------
diff --git a/src/devices/cpu/tms32031/tms32031.h b/src/devices/cpu/tms32031/tms32031.h
index f27f0757244..975a8d1cb32 100644
--- a/src/devices/cpu/tms32031/tms32031.h
+++ b/src/devices/cpu/tms32031/tms32031.h
@@ -31,15 +31,14 @@ const int TMS3203X_IRQ0 = 0; // IRQ0
const int TMS3203X_IRQ1 = 1; // IRQ1
const int TMS3203X_IRQ2 = 2; // IRQ2
const int TMS3203X_IRQ3 = 3; // IRQ3
-const int TMS3203X_XINT0 = 4; // serial 0 transmit interrupt
-const int TMS3203X_RINT0 = 5; // serial 0 receive interrupt
-const int TMS3203X_XINT1 = 6; // serial 1 transmit interrupt
-const int TMS3203X_RINT1 = 7; // serial 1 receive interrupt
+const int TMS3203X_XINT0 = 4; // serial (0) transmit interrupt
+const int TMS3203X_RINT0 = 5; // serial (0) receive interrupt
+const int TMS3203X_XINT1 = 6; // serial 1 transmit interrupt (TMS320C30 only)
+const int TMS3203X_RINT1 = 7; // serial 1 receive interrupt (TMS320C30 only)
const int TMS3203X_TINT0 = 8; // timer 0 interrupt
const int TMS3203X_TINT1 = 9; // timer 1 interrupt
-const int TMS3203X_DINT = 10; // DMA interrupt
-const int TMS3203X_DINT0 = 10; // DMA 0 interrupt (32032 only)
-const int TMS3203X_DINT1 = 11; // DMA 1 interrupt (32032 only)
+const int TMS3203X_DINT0 = 10; // DMA (0) interrupt
+const int TMS3203X_DINT1 = 11; // DMA 1 interrupt (TMS320C32 only)
const int TMS3203X_MCBL = 12; // Microcomputer/boot loader mode
const int TMS3203X_HOLD = 13; // Primary bus interface hold signal
@@ -138,13 +137,13 @@ public:
protected:
enum
{
- CHIP_TYPE_TMS32030,
- CHIP_TYPE_TMS32031,
- CHIP_TYPE_TMS32032
+ CHIP_TYPE_TMS32030, // 'C30
+ CHIP_TYPE_TMS32031, // 'C31/'VC33
+ CHIP_TYPE_TMS32032 // 'C32
};
// construction/destruction
- tms3203x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t chiptype, address_map_constructor internal_map);
+ tms3203x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t chiptype, int clock_per_inst, address_map_constructor internal_map);
void common_3203x(address_map &map);
// device-level overrides
@@ -157,6 +156,8 @@ protected:
virtual uint32_t execute_min_cycles() const noexcept override;
virtual uint32_t execute_max_cycles() const noexcept override;
virtual uint32_t execute_input_lines() const noexcept override;
+ virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override;
+ virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override;
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
@@ -184,6 +185,7 @@ protected:
void check_irqs();
void execute_one();
void update_special(int dreg);
+ void burn_cycle(int cycle);
bool condition(int which);
// floating point helpers
@@ -732,7 +734,7 @@ protected:
// configuration
const address_space_config m_program_config;
- uint32_t m_chip_type;
+ uint32_t m_chip_type;
union int_double
{
@@ -742,9 +744,9 @@ protected:
};
// core registers
- uint32_t m_pc;
+ uint32_t m_pc;
tmsreg m_r[36];
- uint32_t m_bkmask;
+ uint32_t m_bkmask;
// internal peripheral registers
enum primary_bus_control_mask : uint32_t
@@ -766,6 +768,7 @@ protected:
bool m_irq_pending;
bool m_is_idling;
int m_icount;
+ int m_clock_per_inst; // clock per instruction cycle
uint32_t m_iotemp;
memory_access<24, 2, -2, ENDIANNESS_LITTLE>::cache m_cache;
@@ -775,6 +778,7 @@ protected:
bool m_mcbl_mode;
bool m_hold_state;
+ bool m_is_lopower;
devcb_write8 m_xf0_cb;
devcb_write8 m_xf1_cb;
@@ -826,9 +830,21 @@ public:
};
+// ======================> tms32033_device
+
+class tms32033_device : public tms3203x_device
+{
+public:
+ // construction/destruction
+ tms32033_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ void internal_32033(address_map &map);
+};
+
+
// device type definition
DECLARE_DEVICE_TYPE(TMS32030, tms32030_device)
DECLARE_DEVICE_TYPE(TMS32031, tms32031_device)
DECLARE_DEVICE_TYPE(TMS32032, tms32032_device)
+DECLARE_DEVICE_TYPE(TMS32033, tms32033_device)
#endif // MAME_CPU_TMS32031_TMS32031_H
diff --git a/src/mame/audio/cage.cpp b/src/mame/audio/cage.cpp
index e0c9e9fae37..d295b690b0f 100644
--- a/src/mame/audio/cage.cpp
+++ b/src/mame/audio/cage.cpp
@@ -200,7 +200,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( atari_cage_device::dma_timer_callback )
m_tms32031_io_regs[DMA_SOURCE_ADDR] = param;
/* set the interrupt */
- m_cpu->set_input_line(TMS3203X_DINT, ASSERT_LINE);
+ m_cpu->set_input_line(TMS3203X_DINT0, ASSERT_LINE);
m_dma_enabled = 0;
}