diff options
| author | 2021-11-20 09:35:18 +0900 | |
|---|---|---|
| committer | 2021-11-19 19:35:18 -0500 | |
| commit | 6229ca9544962fa7e69dc8691346bc586482197b (patch) | |
| tree | cd612ab88a31c2adeaa3067bc0932abcd1b00d43 /src | |
| parent | f0d98df48769ffaa92155137aa5733eeabe90f93 (diff) | |
tms32031.cpp: Add TMS320VC33 emulation support, Add notes (#8766)
Diffstat (limited to 'src')
| -rw-r--r-- | src/devices/cpu/tms32031/32031ops.hxx | 46 | ||||
| -rw-r--r-- | src/devices/cpu/tms32031/tms32031.cpp | 75 | ||||
| -rw-r--r-- | src/devices/cpu/tms32031/tms32031.h | 44 | ||||
| -rw-r--r-- | src/mame/audio/cage.cpp | 2 |
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; } |
