diff --git a/src/emu/cpu/tms32031/32031ops.c b/src/emu/cpu/tms32031/32031ops.c index 258b0cf0018..4075572f789 100644 --- a/src/emu/cpu/tms32031/32031ops.c +++ b/src/emu/cpu/tms32031/32031ops.c @@ -5693,8 +5693,6 @@ void tms3203x_device::trap(int trapnum) IREG(TMR_ST) &= ~GIEFLAG; if (m_chip_type == CHIP_TYPE_TMS32032) m_pc = RMEM(((IREG(TMR_IF) >> 16) << 8) + trapnum); - else if (m_mcu_mode) - m_pc = 0x809fc0 + trapnum; else m_pc = RMEM(trapnum); m_icount -= 4*2; diff --git a/src/emu/cpu/tms32031/tms32031.c b/src/emu/cpu/tms32031/tms32031.c index f81fc2c3bdf..279a2d6a269 100644 --- a/src/emu/cpu/tms32031/tms32031.c +++ b/src/emu/cpu/tms32031/tms32031.c @@ -119,16 +119,30 @@ const int GIEFLAG = 0x2000; const device_type TMS32031 = &device_creator; const device_type TMS32032 = &device_creator; + // internal memory maps -static ADDRESS_MAP_START( internal_32031, AS_PROGRAM, 32, legacy_cpu_device ) +static ADDRESS_MAP_START( internal_32031, AS_PROGRAM, 32, tms32031_device ) AM_RANGE(0x809800, 0x809fff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( internal_32032, AS_PROGRAM, 32, legacy_cpu_device ) +static ADDRESS_MAP_START( internal_32032, AS_PROGRAM, 32, tms32032_device ) AM_RANGE(0x87fe00, 0x87ffff) AM_RAM ADDRESS_MAP_END +// ROM definitions for the internal boot loader programs +// (Using assembled versions until the code ROMs are extracted from both DSPs) +ROM_START( tms32031 ) + ROM_REGION(0x4000, "tms32031", 0) + ROM_LOAD( "c31boot.bin", 0x0000, 0x4000, BAD_DUMP CRC(bddc2763) SHA1(96b2170ecee5bec5abaa1741bb2d3b6096ecc262) ) // Assembled from c31boot.asm (02-07-92) +ROM_END + +ROM_START( tms32032 ) + ROM_REGION(0x4000, "tms32032", 0) + ROM_LOAD( "c32boot.bin", 0x0000, 0x4000, BAD_DUMP CRC(ecf84729) SHA1(4d32ead450f921f563514b061ea561a222283616) ) // Assembled from c32boot.asm (03-04-96) +ROM_END + + //************************************************************************** // TMSREG REGISTER @@ -275,14 +289,13 @@ tms3203x_device::tms3203x_device(const machine_config &mconfig, device_type type m_irq_state(0), m_delayed(false), m_irq_pending(false), - m_mcu_mode(false), m_is_idling(false), m_icount(0), m_irq_callback(0), m_program(0), m_direct(0) { - m_bootoffset = 0; + m_mcbl_mode = false; m_xf0_w = NULL; m_xf1_w = NULL; m_iack_w = NULL; @@ -299,10 +312,29 @@ tms3203x_device::tms3203x_device(const machine_config &mconfig, device_type type } tms32031_device::tms32031_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : tms3203x_device(mconfig, TMS32031, "TMS32031", tag, owner, clock, CHIP_TYPE_TMS32031, ADDRESS_MAP_NAME(internal_32031)) { } + : tms3203x_device(mconfig, TMS32031, "TMS32031", tag, owner, clock, CHIP_TYPE_TMS32031, ADDRESS_MAP_NAME(internal_32031)) +{ + m_shortname = "tms32031"; +} tms32032_device::tms32032_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : tms3203x_device(mconfig, TMS32032, "TMS32032", tag, owner, clock, CHIP_TYPE_TMS32032, ADDRESS_MAP_NAME(internal_32032)) { } + : tms3203x_device(mconfig, TMS32032, "TMS32032", tag, owner, clock, CHIP_TYPE_TMS32032, ADDRESS_MAP_NAME(internal_32032)) +{ + m_shortname = "tms32032"; +} + + +DIRECT_UPDATE_MEMBER( tms3203x_device::direct_handler ) +{ + // internal boot loader ROM + if (m_mcbl_mode && address < (0x1000 << 2)) + { + direct.explicit_configure(0x000000, 0x003fff, 0x003fff, m_bootrom); + return (offs_t)-1; + } + + return address; +} //------------------------------------------------- @@ -331,6 +363,21 @@ void tms3203x_device::static_set_config(device_t &device, const tms3203x_config } +//------------------------------------------------- +// rom_region - return a pointer to the device's +// internal ROM region +//------------------------------------------------- + +const rom_entry *tms3203x_device::device_rom_region() const +{ + switch (m_chip_type) + { + default: + case CHIP_TYPE_TMS32031: return ROM_NAME( tms32031 ); + case CHIP_TYPE_TMS32032: return ROM_NAME( tms32032 ); + } +} + //------------------------------------------------- // ROPCODE - fetch an opcode //------------------------------------------------- @@ -347,6 +394,9 @@ inline UINT32 tms3203x_device::ROPCODE(offs_t pc) inline UINT32 tms3203x_device::RMEM(offs_t addr) { + if (m_mcbl_mode && addr < 0x1000) + return m_bootrom[addr]; + return m_program->read_dword(addr << 2); } @@ -371,6 +421,10 @@ void tms3203x_device::device_start() m_program = &space(AS_PROGRAM); m_direct = &m_program->direct(); + // set up the internal boot loader ROM + m_bootrom = reinterpret_cast(memregion(m_shortname)->base()); + m_direct->set_direct_update(direct_update_delegate(FUNC(tms3203x_device::direct_handler), this)); + // save state save_item(NAME(m_pc)); for (int regnum = 0; regnum < 36; regnum++) @@ -379,7 +433,6 @@ void tms3203x_device::device_start() save_item(NAME(m_irq_state)); save_item(NAME(m_delayed)); save_item(NAME(m_irq_pending)); - save_item(NAME(m_mcu_mode)); save_item(NAME(m_is_idling)); // register our state for the debugger @@ -431,17 +484,7 @@ void tms3203x_device::device_start() void tms3203x_device::device_reset() { - // if we have a config struct, get the boot ROM address - if (m_bootoffset != 0) - { - m_mcu_mode = true; - m_pc = boot_loader(m_bootoffset); - } - else - { - m_mcu_mode = false; - m_pc = RMEM(0); - } + m_pc = RMEM(0); // reset some registers IREG(TMR_IE) = 0; @@ -449,6 +492,9 @@ void tms3203x_device::device_reset() IREG(TMR_ST) = 0; IREG(TMR_IOF) = 0; + // update IF with the external interrupt state (required for boot loader operation) + IREG(TMR_IF) |= m_irq_state & 0x0f; + // reset internal stuff m_delayed = m_irq_pending = m_is_idling = false; } @@ -718,7 +764,7 @@ UINT32 tms3203x_device::execute_max_cycles() const UINT32 tms3203x_device::execute_input_lines() const { - return 11; + return (m_chip_type == CHIP_TYPE_TMS32032) ? 13 : 12; } @@ -729,9 +775,17 @@ UINT32 tms3203x_device::execute_input_lines() const void tms3203x_device::execute_set_input(int inputnum, int state) { // ignore anything out of range - if (inputnum >= 12) + if (inputnum >= 13) return; + if (inputnum == TMS3203X_MCBL) + { + // switch between microcomputer/boot loader and microprocessor modes + m_mcbl_mode = (state == ASSERT_LINE); + m_direct->force_update(); + return; + } + // update the external state UINT16 intmask = 1 << inputnum; if (state == ASSERT_LINE) @@ -830,67 +884,6 @@ void tms3203x_device::execute_run() } -//------------------------------------------------- -// boot_loader - reset the state of the system -// by simulating the internal boot loader -//------------------------------------------------- - -UINT32 tms3203x_device::boot_loader(UINT32 boot_rom_addr) -{ - // read the size of the data - UINT32 bits = RMEM(boot_rom_addr); - if (bits != 8 && bits != 16 && bits != 32) - return 0; - UINT32 datamask = 0xffffffffUL >> (32 - bits); - UINT32 advance = 32 / bits; - boot_rom_addr += advance; - - // read the control register - UINT32 control = RMEM(boot_rom_addr++) & datamask; - for (int i = 1; i < advance; i++) - control |= (RMEM(boot_rom_addr++) & datamask) << (bits * i); - - // now parse the data - UINT32 start_offset = 0; - bool first = true; - while (1) - { - // read the length of this section - UINT32 len = RMEM(boot_rom_addr++) & datamask; - for (int i = 1; i < advance; i++) - len |= (RMEM(boot_rom_addr++) & datamask) << (bits * i); - - // stop at 0 - if (len == 0) - return start_offset; - - // read the destination offset of this section - UINT32 offs = RMEM(boot_rom_addr++) & datamask; - for (int i = 1; i < advance; i++) - offs |= (RMEM(boot_rom_addr++) & datamask) << (bits * i); - - // if this is the first block, that's where we boot to - if (first) - { - start_offset = offs; - first = false; - } - - // now copy the data - while (len--) - { - // extract the 32-bit word - UINT32 data = RMEM(boot_rom_addr++) & datamask; - for (int i = 1; i < advance; i++) - data |= (RMEM(boot_rom_addr++) & datamask) << (bits * i); - - // write it out - WMEM(offs++, data); - } - } -} - - //************************************************************************** // CORE OPCODES //************************************************************************** diff --git a/src/emu/cpu/tms32031/tms32031.h b/src/emu/cpu/tms32031/tms32031.h index 58074f8825c..6d80b183df5 100644 --- a/src/emu/cpu/tms32031/tms32031.h +++ b/src/emu/cpu/tms32031/tms32031.h @@ -69,6 +69,7 @@ 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_MCBL = 12; // Microcomputer/boot loader mode // register enumeration enum @@ -138,7 +139,7 @@ typedef void (*tms3203x_iack_func)(tms3203x_device &device, UINT8 val, offs_t ad struct tms3203x_config { - UINT32 m_bootoffset; + bool m_mcbl_mode; tms3203x_xf_func m_xf0_w; tms3203x_xf_func m_xf1_w; tms3203x_iack_func m_iack_w; @@ -201,6 +202,8 @@ protected: virtual void device_start(); virtual void device_reset(); + virtual const rom_entry *device_rom_region() const; + // device_execute_interface overrides virtual UINT32 execute_min_cycles() const; virtual UINT32 execute_max_cycles() const; @@ -222,13 +225,13 @@ protected: virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); // memory helpers + DECLARE_DIRECT_UPDATE_MEMBER(direct_handler); UINT32 ROPCODE(offs_t pc); UINT32 RMEM(offs_t addr); void WMEM(offs_t addr, UINT32 data); // misc helpers void check_irqs(); - UINT32 boot_loader(UINT32 boot_rom_addr); void execute_one(); void update_special(int dreg); bool condition(int which); @@ -798,7 +801,6 @@ protected: UINT16 m_irq_state; bool m_delayed; bool m_irq_pending; - bool m_mcu_mode; bool m_is_idling; int m_icount; @@ -806,6 +808,7 @@ protected: device_irq_acknowledge_callback m_irq_callback; address_space * m_program; direct_read_data * m_direct; + UINT32 * m_bootrom; // tables static void (tms3203x_device::*const s_tms32031ops[])(UINT32 op); diff --git a/src/mame/audio/cage.c b/src/mame/audio/cage.c index 384f566cbe5..2aac2c3059d 100644 --- a/src/mame/audio/cage.c +++ b/src/mame/audio/cage.c @@ -603,6 +603,7 @@ void cage_control_w(running_machine &machine, UINT16 data) if (!(state->control & 3)) { state->cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + state->cpu->set_input_line(TMS3203X_IRQ1, ASSERT_LINE); state->dma_enabled = 0; state->dma_timer_enabled = 0; @@ -619,7 +620,10 @@ void cage_control_w(running_machine &machine, UINT16 data) state->cage_to_cpu_ready = 0; } else + { state->cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + state->cpu->set_input_line(TMS3203X_IRQ1, CLEAR_LINE); + } /* update the control state */ update_control_lines(machine); @@ -651,7 +655,7 @@ static WRITE32_HANDLER( speedup_w ) static const tms3203x_config cage_config = { - 0x400000 + true }; diff --git a/src/mame/drivers/gaelco3d.c b/src/mame/drivers/gaelco3d.c index a31b7a0e239..d32c761d9ad 100644 --- a/src/mame/drivers/gaelco3d.c +++ b/src/mame/drivers/gaelco3d.c @@ -980,7 +980,7 @@ static const adsp21xx_config adsp_config = static const tms3203x_config tms_config = { - 0x1000, + true, 0, 0, iack_w diff --git a/src/mame/drivers/midvunit.c b/src/mame/drivers/midvunit.c index 2e07a1091c4..8b9b4e42eba 100644 --- a/src/mame/drivers/midvunit.c +++ b/src/mame/drivers/midvunit.c @@ -496,7 +496,7 @@ static ADDRESS_MAP_START( midvunit_map, AS_PROGRAM, 32, midvunit_state ) ADDRESS_MAP_END -static const tms3203x_config midvplus_config = { 0, NULL, midvplus_xf1_w }; +static const tms3203x_config midvplus_config = { false, NULL, midvplus_xf1_w }; static ADDRESS_MAP_START( midvplus_map, AS_PROGRAM, 32, midvunit_state ) AM_RANGE(0x000000, 0x01ffff) AM_RAM AM_SHARE("ram_base")