Previous 199869 Revisions Next

r19126 Saturday 24th November, 2012 at 10:48:17 UTC by Phil Bennett
Added internal boot loader programs to the TMS3203x core and support a switch between microcomputer (bootloader) and microprocessor modes via the TMS3203X_MCBL input [Phil Bennett]

***

This is required for Rise of the Robots, whose boot code jumps into the middle of the bootloader ROM. Changes tested with primrage, sfrush and speedup.
[src/emu/cpu/tms32031]32031ops.c tms32031.c tms32031.h
[src/mame/audio]cage.c
[src/mame/drivers]gaelco3d.c midvunit.c

trunk/src/emu/cpu/tms32031/tms32031.h
r19125r19126
6969const int TMS3203X_DINT      = 10;      // DMA interrupt
7070const int TMS3203X_DINT0   = 10;      // DMA 0 interrupt (32032 only)
7171const int TMS3203X_DINT1   = 11;      // DMA 1 interrupt (32032 only)
72const int TMS3203X_MCBL      = 12;      // Microcomputer/boot loader mode
7273
7374// register enumeration
7475enum
r19125r19126
138139
139140struct tms3203x_config
140141{
141   UINT32            m_bootoffset;
142   bool            m_mcbl_mode;
142143   tms3203x_xf_func   m_xf0_w;
143144   tms3203x_xf_func   m_xf1_w;
144145   tms3203x_iack_func   m_iack_w;
r19125r19126
201202   virtual void device_start();
202203   virtual void device_reset();
203204
205   virtual const rom_entry *device_rom_region() const;
206
204207   // device_execute_interface overrides
205208   virtual UINT32 execute_min_cycles() const;
206209   virtual UINT32 execute_max_cycles() const;
r19125r19126
222225   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
223226
224227   // memory helpers
228   DECLARE_DIRECT_UPDATE_MEMBER(direct_handler);
225229   UINT32 ROPCODE(offs_t pc);
226230   UINT32 RMEM(offs_t addr);
227231   void WMEM(offs_t addr, UINT32 data);
228232
229233   // misc helpers
230234   void check_irqs();
231   UINT32 boot_loader(UINT32 boot_rom_addr);
232235   void execute_one();
233236   void update_special(int dreg);
234237   bool condition(int which);
r19125r19126
798801   UINT16            m_irq_state;
799802   bool            m_delayed;
800803   bool            m_irq_pending;
801   bool            m_mcu_mode;
802804   bool            m_is_idling;
803805   int               m_icount;
804806
r19125r19126
806808   device_irq_acknowledge_callback   m_irq_callback;
807809   address_space *      m_program;
808810   direct_read_data *   m_direct;
811   UINT32 *         m_bootrom;
809812
810813   // tables
811814   static void (tms3203x_device::*const s_tms32031ops[])(UINT32 op);
trunk/src/emu/cpu/tms32031/32031ops.c
r19125r19126
56935693   IREG(TMR_ST) &= ~GIEFLAG;
56945694   if (m_chip_type == CHIP_TYPE_TMS32032)
56955695      m_pc = RMEM(((IREG(TMR_IF) >> 16) << 8) + trapnum);
5696   else if (m_mcu_mode)
5697      m_pc = 0x809fc0 + trapnum;
56985696   else
56995697      m_pc = RMEM(trapnum);
57005698   m_icount -= 4*2;
trunk/src/emu/cpu/tms32031/tms32031.c
r19125r19126
119119const device_type TMS32031 = &device_creator<tms32031_device>;
120120const device_type TMS32032 = &device_creator<tms32032_device>;
121121
122
122123// internal memory maps
123static ADDRESS_MAP_START( internal_32031, AS_PROGRAM, 32, legacy_cpu_device )
124static ADDRESS_MAP_START( internal_32031, AS_PROGRAM, 32, tms32031_device )
124125   AM_RANGE(0x809800, 0x809fff) AM_RAM
125126ADDRESS_MAP_END
126127
127static ADDRESS_MAP_START( internal_32032, AS_PROGRAM, 32, legacy_cpu_device )
128static ADDRESS_MAP_START( internal_32032, AS_PROGRAM, 32, tms32032_device )
128129   AM_RANGE(0x87fe00, 0x87ffff) AM_RAM
129130ADDRESS_MAP_END
130131
131132
133// ROM definitions for the internal boot loader programs
134// (Using assembled versions until the code ROMs are extracted from both DSPs)
135ROM_START( tms32031 )
136   ROM_REGION(0x4000, "tms32031", 0)
137   ROM_LOAD( "c31boot.bin", 0x0000, 0x4000, BAD_DUMP CRC(bddc2763) SHA1(96b2170ecee5bec5abaa1741bb2d3b6096ecc262) ) // Assembled from c31boot.asm (02-07-92)
138ROM_END
132139
140ROM_START( tms32032 )
141   ROM_REGION(0x4000, "tms32032", 0)
142   ROM_LOAD( "c32boot.bin", 0x0000, 0x4000, BAD_DUMP CRC(ecf84729) SHA1(4d32ead450f921f563514b061ea561a222283616) ) // Assembled from c32boot.asm (03-04-96)
143ROM_END
144
145
146
133147//**************************************************************************
134148//  TMSREG REGISTER
135149//**************************************************************************
r19125r19126
275289     m_irq_state(0),
276290     m_delayed(false),
277291     m_irq_pending(false),
278     m_mcu_mode(false),
279292     m_is_idling(false),
280293     m_icount(0),
281294     m_irq_callback(0),
282295     m_program(0),
283296     m_direct(0)
284297{
285   m_bootoffset = 0;
298   m_mcbl_mode = false;
286299   m_xf0_w = NULL;
287300   m_xf1_w = NULL;
288301   m_iack_w = NULL;
r19125r19126
299312}
300313
301314tms32031_device::tms32031_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
302   : tms3203x_device(mconfig, TMS32031, "TMS32031", tag, owner, clock, CHIP_TYPE_TMS32031, ADDRESS_MAP_NAME(internal_32031)) { }
315   : tms3203x_device(mconfig, TMS32031, "TMS32031", tag, owner, clock, CHIP_TYPE_TMS32031, ADDRESS_MAP_NAME(internal_32031))
316{
317   m_shortname = "tms32031";
318}
303319
304320tms32032_device::tms32032_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
305   : tms3203x_device(mconfig, TMS32032, "TMS32032", tag, owner, clock, CHIP_TYPE_TMS32032, ADDRESS_MAP_NAME(internal_32032)) { }
321   : tms3203x_device(mconfig, TMS32032, "TMS32032", tag, owner, clock, CHIP_TYPE_TMS32032, ADDRESS_MAP_NAME(internal_32032))
322{
323   m_shortname = "tms32032";
324}
306325
307326
327DIRECT_UPDATE_MEMBER( tms3203x_device::direct_handler )
328{
329   // internal boot loader ROM
330   if (m_mcbl_mode && address < (0x1000 << 2))
331   {
332      direct.explicit_configure(0x000000, 0x003fff, 0x003fff, m_bootrom);
333      return (offs_t)-1;
334   }
335
336   return address;
337}
338
339
308340//-------------------------------------------------
309341//  ~tms3203x_device - destructor
310342//-------------------------------------------------
r19125r19126
332364
333365
334366//-------------------------------------------------
367//  rom_region - return a pointer to the device's
368//  internal ROM region
369//-------------------------------------------------
370
371const rom_entry *tms3203x_device::device_rom_region() const
372{
373   switch (m_chip_type)
374   {
375      default:
376      case CHIP_TYPE_TMS32031:   return ROM_NAME( tms32031 );
377      case CHIP_TYPE_TMS32032:   return ROM_NAME( tms32032 );
378   }
379}
380
381//-------------------------------------------------
335382//  ROPCODE - fetch an opcode
336383//-------------------------------------------------
337384
r19125r19126
347394
348395inline UINT32 tms3203x_device::RMEM(offs_t addr)
349396{
397   if (m_mcbl_mode && addr < 0x1000)
398      return m_bootrom[addr];
399     
350400   return m_program->read_dword(addr << 2);
351401}
352402
r19125r19126
371421   m_program = &space(AS_PROGRAM);
372422   m_direct = &m_program->direct();
373423
424   // set up the internal boot loader ROM
425   m_bootrom = reinterpret_cast<UINT32*>(memregion(m_shortname)->base());
426   m_direct->set_direct_update(direct_update_delegate(FUNC(tms3203x_device::direct_handler), this));
427
374428   // save state
375429   save_item(NAME(m_pc));
376430   for (int regnum = 0; regnum < 36; regnum++)
r19125r19126
379433   save_item(NAME(m_irq_state));
380434   save_item(NAME(m_delayed));
381435   save_item(NAME(m_irq_pending));
382   save_item(NAME(m_mcu_mode));
383436   save_item(NAME(m_is_idling));
384437
385438   // register our state for the debugger
r19125r19126
431484
432485void tms3203x_device::device_reset()
433486{
434   // if we have a config struct, get the boot ROM address
435   if (m_bootoffset != 0)
436   {
437      m_mcu_mode = true;
438      m_pc = boot_loader(m_bootoffset);
439   }
440   else
441   {
442      m_mcu_mode = false;
443      m_pc = RMEM(0);
444   }
487   m_pc = RMEM(0);
445488
446489   // reset some registers
447490   IREG(TMR_IE) = 0;
r19125r19126
449492   IREG(TMR_ST) = 0;
450493   IREG(TMR_IOF) = 0;
451494
495   // update IF with the external interrupt state (required for boot loader operation)
496   IREG(TMR_IF) |= m_irq_state & 0x0f;
497
452498   // reset internal stuff
453499   m_delayed = m_irq_pending = m_is_idling = false;
454500}
r19125r19126
718764
719765UINT32 tms3203x_device::execute_input_lines() const
720766{
721   return 11;
767   return (m_chip_type == CHIP_TYPE_TMS32032) ? 13 : 12;
722768}
723769
724770
r19125r19126
729775void tms3203x_device::execute_set_input(int inputnum, int state)
730776{
731777   // ignore anything out of range
732   if (inputnum >= 12)
778   if (inputnum >= 13)
733779      return;
734780
781   if (inputnum == TMS3203X_MCBL)
782   {
783      // switch between microcomputer/boot loader and microprocessor modes
784      m_mcbl_mode = (state == ASSERT_LINE);
785      m_direct->force_update();
786      return;
787   }
788
735789   // update the external state
736790   UINT16 intmask = 1 << inputnum;
737791    if (state == ASSERT_LINE)
r19125r19126
830884}
831885
832886
833//-------------------------------------------------
834//  boot_loader - reset the state of the system
835//  by simulating the internal boot loader
836//-------------------------------------------------
837
838UINT32 tms3203x_device::boot_loader(UINT32 boot_rom_addr)
839{
840   // read the size of the data
841   UINT32 bits = RMEM(boot_rom_addr);
842   if (bits != 8 && bits != 16 && bits != 32)
843      return 0;
844   UINT32 datamask = 0xffffffffUL >> (32 - bits);
845   UINT32 advance = 32 / bits;
846   boot_rom_addr += advance;
847
848   // read the control register
849   UINT32 control = RMEM(boot_rom_addr++) & datamask;
850   for (int i = 1; i < advance; i++)
851      control |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
852
853   // now parse the data
854   UINT32 start_offset = 0;
855   bool first = true;
856   while (1)
857   {
858      // read the length of this section
859      UINT32 len = RMEM(boot_rom_addr++) & datamask;
860      for (int i = 1; i < advance; i++)
861         len |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
862
863      // stop at 0
864      if (len == 0)
865         return start_offset;
866
867      // read the destination offset of this section
868      UINT32 offs = RMEM(boot_rom_addr++) & datamask;
869      for (int i = 1; i < advance; i++)
870         offs |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
871
872      // if this is the first block, that's where we boot to
873      if (first)
874      {
875         start_offset = offs;
876         first = false;
877      }
878
879      // now copy the data
880      while (len--)
881      {
882         // extract the 32-bit word
883         UINT32 data = RMEM(boot_rom_addr++) & datamask;
884         for (int i = 1; i < advance; i++)
885            data |= (RMEM(boot_rom_addr++) & datamask) << (bits * i);
886
887         // write it out
888         WMEM(offs++, data);
889      }
890   }
891}
892
893
894887//**************************************************************************
895888//  CORE OPCODES
896889//**************************************************************************
trunk/src/mame/audio/cage.c
r19125r19126
603603   if (!(state->control & 3))
604604   {
605605      state->cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
606      state->cpu->set_input_line(TMS3203X_IRQ1, ASSERT_LINE);
606607
607608      state->dma_enabled = 0;
608609      state->dma_timer_enabled = 0;
r19125r19126
619620      state->cage_to_cpu_ready = 0;
620621   }
621622   else
623   {
622624      state->cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
625      state->cpu->set_input_line(TMS3203X_IRQ1, CLEAR_LINE);
626   }
623627
624628   /* update the control state */
625629   update_control_lines(machine);
r19125r19126
651655
652656static const tms3203x_config cage_config =
653657{
654   0x400000
658   true
655659};
656660
657661
trunk/src/mame/drivers/midvunit.c
r19125r19126
496496ADDRESS_MAP_END
497497
498498
499static const tms3203x_config midvplus_config = { 0, NULL, midvplus_xf1_w };
499static const tms3203x_config midvplus_config = { false, NULL, midvplus_xf1_w };
500500
501501static ADDRESS_MAP_START( midvplus_map, AS_PROGRAM, 32, midvunit_state )
502502   AM_RANGE(0x000000, 0x01ffff) AM_RAM AM_SHARE("ram_base")
trunk/src/mame/drivers/gaelco3d.c
r19125r19126
980980
981981static const tms3203x_config tms_config =
982982{
983   0x1000,
983   true,
984984   0,
985985   0,
986986   iack_w

Previous 199869 Revisions Next


© 1997-2024 The MAME Team