Previous 199869 Revisions Next

r24028 Monday 1st July, 2013 at 02:05:59 UTC by R. Belmont
(MESS) SNES SA-1 work: [Fabio Priuli, R. Belmont]
- Initial support for plain SA-1 DMA
- Fixed incorrect BWRAM banking
- Fixed SA-1 vectors to not blot out all banks
- Added S-CPU vector override
- Fire interrupt for CC type 1; this allows levelling up in SMRPG (gfx not correct yet)
[src/mess/machine]sns_sa1.c sns_sa1.h

trunk/src/mess/machine/sns_sa1.c
r24027r24028
3838    haruaug3a, pebble, haruaug3: uses SA-1 DMA
3939    itoibass: boots, some missing gfx
4040    jikkparo: plays OK
41    jl96drem: sprites corrupt in gameplay, SA-1 DMA/character conversion?
42    jumpind: boots and runs, uses SA-1 DMA and character conversion
41    jl96drem: plays OK
42    jumpind: boots and runs, uses SA-1 normal DMA only but has corrupt gfx
4343    kakinoki: S-CPU crashes after pressing start
4444    kirby3j, kirby3: uses SA-1 DMA
4545    kirbysdb, kirbyss, kirbyfun, kirbysd, kirbysda: plays OK
46    marvelou: plays OK, some gfx corruption
46    marvelou: plays OK, uses SA-1 normal DMA only but has corrupt gfx
4747    miniyonk: plays OK
4848    panicbw: plays OK
4949    pgaeuro, pgaeurou, pga96, pga96u, pga, pgaj: plays OK
r24027r24028
5656    shinshog: plays OK
5757    shogisai: plays OK
5858    shogisa2: plays OK
59    smrpgj, smrpg: boots, can't start game (SRAM mapping?)
59    smrpgj, smrpg: needs SA-1 character conversion for level up Bonus Chance (possible to get past now)
6060    srobotg: some corrupt in-game GFX, may be SNES rendering errors
6161    sshogi3: plays OK
6262    taikyoid: plays OK
r24027r24028
6666
6767 ***********************************************************************************************************/
6868
69
7069#include "emu.h"
7170#include "machine/sns_sa1.h"
7271
r24027r24028
142141   m_vcr = 0;
143142   m_scpu_sie = m_sa1_sie = 0;
144143   m_scpu_flags = m_sa1_flags = 0;
144   m_dma_ctrl = 0;
145   m_dma_ccparam = 0;
146   m_dma_cnt = 0;
145147
146148   // sa-1 CPU starts out not running?
147149   m_sa1->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
r24027r24028
190192
191193// handle this separately to avoid accessing recursively the regs?
192194
193inline UINT8 sns_sa1_device::var_length_read(address_space &space, UINT32 offset)
195UINT8 sns_sa1_device::var_length_read(address_space &space, UINT32 offset)
194196{
195197   // handle 0xffea/0xffeb/0xffee/0xffef
196198   if ((offset & 0xffffe0) == 0x00ffe0)
r24027r24028
211213      return read_h(space, (offset & 0x7fffff));
212214
213215   if ((offset & 0x40e000) == 0x006000)  //$00-3f|80-bf:6000-7fff
214      return read_bwram((m_bwram_sa1 * 0x2000) + (offset & 0x1fff));
216      return read_bwram((m_bwram_snes * 0x2000) + (offset & 0x1fff));
215217
216218   if ((offset & 0xf00000) == 0x400000)  //$40-4f:0000-ffff
217219      return read_bwram(offset & 0xfffff);
r24027r24028
225227   return 0;
226228}
227229
230void sns_sa1_device::dma_transfer(address_space &space)
231{
232//   printf("DMA src %08x (%d), dst %08x (%d) cnt %d\n", m_src_addr, m_dma_ctrl & 3, m_dst_addr, m_dma_ctrl & 4, m_dma_cnt);
233
234   while (m_dma_cnt--)
235   {
236      UINT8 data = 0; // open bus?
237      UINT32 dma_src = m_src_addr++;
238      UINT32 dma_dst = m_dst_addr++;
239     
240      // source and destination cannot be the same
241      // source = { 0=ROM, 1=BWRAM, 2=IRAM }
242      // destination = { 0=IRAM, 1=BWRAM }
243      if ((m_dma_ctrl & 0x03) == 1 && (m_dma_ctrl & 0x04) == 0x04) continue;
244      if ((m_dma_ctrl & 0x03) == 2 && (m_dma_ctrl & 0x04) == 0x00) continue;
245
246      switch (m_dma_ctrl & 0x03)
247      {
248         case 0: // ROM
249            if ((dma_src & 0x408000) == 0x008000 && (dma_src & 0x800000) == 0x000000)
250            {
251               data = read_l(space, (dma_src & 0x7fffff));
252            }
253            if ((dma_src & 0x408000) == 0x008000 && (dma_src & 0x800000) == 0x800000)
254            {
255               data = read_h(space, (dma_src & 0x7fffff));
256            }
257            if ((dma_src & 0xc00000) == 0xc00000)
258            {
259               data = read_h(space, (dma_src & 0x7fffff));
260            }
261            break;
262
263         case 1: // BWRAM
264            if ((dma_src & 0x40e000) == 0x006000)
265            {
266               data = read_bwram((m_bwram_sa1 * 0x2000) + (dma_src & 0x1fff));           
267            }
268            if ((dma_src & 0xf00000) == 0x400000)
269            {
270               data = read_bwram(dma_src & 0xfffff);
271            }
272            break;
273
274         case 2: // IRAM
275            data = read_iram(dma_src);
276            break;
277      }
278     
279      switch (m_dma_ctrl & 0x04)
280      {
281         case 0x00:   // IRAM
282            write_iram(dma_dst, data);
283            break;
284
285         case 0x04:   // BWRAM
286            if ((dma_dst & 0x40e000) == 0x006000)
287            {
288               write_bwram((m_bwram_sa1 * 0x2000) + (dma_dst & 0x1fff), data);           
289            }
290            if ((dma_dst & 0xf00000) == 0x400000)
291            {
292               write_bwram(dma_dst & 0xfffff, data);
293            }
294            break;
295      }
296   }
297   
298   m_sa1_flags |= SA1_IRQ_DMA;
299   recalc_irqs();
300}
301
302void sns_sa1_device::dma_cctype1_transfer(address_space &space)
303{
304   m_scpu_flags |= SCPU_IRQ_CHARCONV;
305   recalc_irqs();
306}
307
308void sns_sa1_device::dma_cctype2_transfer(address_space &space)
309{
310}
311
228312UINT8 sns_sa1_device::read_regs(address_space &space, UINT32 offset)
229313{
230314   UINT8 value = 0xff;
r24027r24028
321405   return value;
322406}
323407
324void sns_sa1_device::write_regs(UINT32 offset, UINT8 data)
408void sns_sa1_device::write_regs(address_space &space, UINT32 offset, UINT8 data)
325409{
326410   offset &= 0x1ff;    // $2200 + offset gives the reg value to compare with docs
327411
r24027r24028
544628      case 0x030:
545629         // SA-1  DCNT  00h   DMA Control (W)
546630//         printf("%02x to SA-1 DMA control\n", data);
631         m_dma_ctrl = data;
547632         break;
548633      case 0x031:
549634         // Both  CDMA  00h   Character Conversion DMA Parameters (W)
635         m_dma_ccparam = data;
550636         break;
551637      case 0x032:
552638         // DMA Source Device Start Address Low
r24027r24028
567653      case 0x036:
568654         // DMA Dest Device Start Address Mid
569655         m_dst_addr = (m_dst_addr & 0xff00ff) | (data << 8);
570         break;
656         if (m_dma_ctrl & 0x80)
657         {
658            if (!(m_dma_ctrl & 0x20) && !(m_dma_ctrl & 0x04)) // Normal DMA to IRAM
659            {
660               dma_transfer(space);
661//               printf("SA-1: normal DMA to IRAM\n");
662            }
663
664            if (m_dma_ctrl & 0x20 && m_dma_ctrl & 0x10)   // CC DMA Type 1
665            {
666//               printf("SA-1: CC DMA type 1\n");
667               dma_cctype1_transfer(space);
668            }
669         }
670         break;
571671      case 0x037:
572672         // DMA Dest Device Start Address High
573673         m_dst_addr = (m_dst_addr & 0xffff00) | (data << 16);
674         if (m_dma_ctrl & 0x80)
675         {
676            if (!(m_dma_ctrl & 0x20) && m_dma_ctrl & 0x04)   // Normal DMA to BWRAM
677            {
678//               printf("SA-1: normal DMA to BWRAM\n");
679               dma_transfer(space);
680            }
681         }
574682         break;
575683      case 0x038:
576684         // SA-1  DTC   -     DMA Terminal Counter Lsb (W)
685         m_dma_cnt &= 0xff00;
686         m_dma_cnt |= data;
577687         break;
578688      case 0x039:
579689         // SA-1  DTC   -     DMA Terminal Counter Msb (W)
690         m_dma_cnt &= 0x00ff;
691         m_dma_cnt |= (data<<8);
580692         break;
581693      case 0x03f:
582694         // Format for BWRAM when mapped to bitmap
r24027r24028
600712      case 0x04f:
601713         // Bit Map Register File (2240h..224Fh)
602714         m_brf_reg[offset & 0x0f] = data;
715         if ((offset & 0x07) == 7 && m_dma_ctrl & 0x80)
716         {
717            if (m_dma_ctrl & 0x20 && !(m_dma_ctrl & 0x10))   // CC DMA Type 2
718            {
719//               printf("SA-1: CC DMA type 2\n");
720               dma_cctype2_transfer(space);
721            }
722         }         
603723         break;
604724      case 0x050:
605725         // Math control
r24027r24028
773893{
774894   int bank = 0;
775895
896   if (offset == 0xffea && BIT(m_scpu_ctrl, 4)) return (m_nmi_vector >> 0) & 0xff;
897   if (offset == 0xffeb && BIT(m_scpu_ctrl, 4)) return (m_nmi_vector >> 8) & 0xff;
898   if (offset == 0xffee && BIT(m_scpu_ctrl, 6)) return (m_irq_vector >> 0) & 0xff;
899   if (offset == 0xffef && BIT(m_scpu_ctrl, 6)) return (m_irq_vector >> 8) & 0xff;
900
776901   // ROM is mapped to [00-3f][8000-ffff] only here
777902   if (offset < 0x200000)
778903   {
r24027r24028
868993   UINT16 address = offset & 0xffff;
869994
870995   if (offset < 0x400000 && address >= 0x2200 && address < 0x2400)
871      write_regs(address & 0x1ff, data);  // SA-1 Regs
996      write_regs(space, address & 0x1ff, data);  // SA-1 Regs
872997
873998   if (offset < 0x400000 && address >= 0x3000 && address < 0x3800)
874999      write_iram(address & 0x7ff, data);  // Internal SA-1 RAM (2K)
r24027r24028
9321057      }
9331058      else if (address < 0x8000)
9341059         return read_bwram((m_bwram_sa1 * 0x2000) + (offset & 0x1fff) + (m_bwram_sa1_source * 0x100000));        // SA-1 BWRAM
935      else if (address == 0xffee)
1060      else if (offset == 0xffee)
9361061      {
9371062         return m_sa1_irq & 0xff;
9381063      }
939      else if (address == 0xffef)
1064      else if (offset == 0xffef)
9401065      {
9411066         return m_sa1_irq>>8;
9421067      }
943      else if (address == 0xffea)
1068      else if (offset == 0xffea)
9441069      {
9451070         return m_sa1_nmi & 0xff;
9461071      }
947      else if (address == 0xffeb)
1072      else if (offset == 0xffeb)
9481073      {
9491074         return m_sa1_nmi>>8;
9501075      }
951      else if (address == 0xfffc)
1076      else if (offset == 0xfffc)
9521077      {
9531078         return m_sa1_reset & 0xff;
9541079      }
955      else if (address == 0xfffd)
1080      else if (offset == 0xfffd)
9561081      {
9571082         return m_sa1_reset>>8;
9581083      }
r24027r24028
9791104         if (address < 0x0800)
9801105            write_iram(offset, data);   // Internal SA-1 RAM (2K)
9811106         else if (address >= 0x2200 && address < 0x2400)
982            write_regs(offset & 0x1ff, data);   // SA-1 Regs
1107            write_regs(space, offset & 0x1ff, data);   // SA-1 Regs
9831108         else if (address >= 0x3000 && address < 0x3800)
9841109            write_iram(offset, data);   // Internal SA-1 RAM (2K)
9851110      }
trunk/src/mess/machine/sns_sa1.h
r24027r24028
3636
3737private:
3838
39   inline UINT8 var_length_read(address_space &space, UINT32 offset);
39   UINT8 var_length_read(address_space &space, UINT32 offset);
40   void dma_transfer(address_space &space);
41   void dma_cctype1_transfer(address_space &space);
42   void dma_cctype2_transfer(address_space &space);
4043
4144   UINT8 read_regs(address_space &space, UINT32 offset);
4245   UINT8 read_iram(UINT32 offset);
4346   UINT8 read_bwram(UINT32 offset);
44   void write_regs(UINT32 offset, UINT8 data);
47   void write_regs(address_space &space, UINT32 offset, UINT8 data);
4548   void write_iram(UINT32 offset, UINT8 data);
4649   void write_bwram(UINT32 offset, UINT8 data);
4750   void recalc_irqs();
r24027r24028
7982   UINT32 m_bwpa_sa1;
8083   // $2229-$222a
8184   UINT8 m_iram_write_snes, m_iram_write_sa1;
85   // $2230-$2231
86   UINT8 m_dma_ctrl, m_dma_ccparam;
8287   // $2232-$2237
8388   UINT32 m_src_addr, m_dst_addr;
89   // $2238-$2239
90   UINT16 m_dma_cnt;
8491   // $2240-$224f
8592   UINT8 m_brf_reg[0x10];
8693   // $2250-$2254

Previous 199869 Revisions Next


© 1997-2024 The MAME Team