Previous 15994 Revisions Next

r7652 Saturday 27th March, 2010 at 14:38:02 UTC by Fabio Priuli
[SNES]: enabled PPU->CPU hdma transfer and moved hdma variables to snes_state
[src/mame/includes]snes.h
[src/mame/machine]snes.c

src/mame/machine/snes.c
r7651r7652
232232      if (video_screen_get_vpos(machine->primary_screen) > 0)
233233      {
234234         /* Do HDMA */
235         if (snes_ram[HDMAEN])
235         if (state->hdmaen)
236236            snes_hdma(cpu0space);
237237
238238         video_screen_update_partial(machine->primary_screen, (snes_ppu.interlace == 2) ? (snes_ppu.beam.current_vert*snes_ppu.interlace) : snes_ppu.beam.current_vert-1);
r7651r7652
305305   visarea.max_x = (SNES_SCR_WIDTH * 2) - 1;
306306
307307   // fixme: should compensate for SNES_DBG_video
308   if (snes_ppu.mode == 5 || snes_ppu.mode == 6 )
308   if (snes_ppu.mode == 5 || snes_ppu.mode == 6 || snes_ppu.pseudo_hires)
309309      state->htmult = 2;
310310   else
311311      state->htmult = 1;
r7651r7652
337337   return result;
338338}
339339
340/*************************************************
341
342 SNES VRAM accesses:
343
344 VRAM accesses during active display are invalid.
345 Unlike OAM and CGRAM, they will not be written
346 anywhere at all. Thanks to byuu's researches,
347 the ranges where writes are invalid have been
348 validated on hardware, as has the edge case where
349 the S-CPU open bus can be written if the write
350 occurs during the very last clock cycle of
351 vblank.
352 Our implementation could be not 100% accurate
353 when interlace is active.
354*************************************************/
355
340356INLINE UINT32 snes_get_vram_address( running_machine *machine )
341357{
342358   snes_state *state = (snes_state *)machine->driver_data;
r7651r7652
352368   return addr;
353369}
354370
355/* VRAM accesses during active display are invalid. */
356static UINT16 snes_vram_read( const address_space *space, UINT32 addr )
371static READ8_HANDLER( snes_vram_read )
357372{
358   UINT16 res = 0;
373   UINT8 res = 0;
374   offset &= 0x1ffff;
359375
360376   if (snes_ppu.screen_disabled)
361      res = snes_vram[addr & 0x1ffff] | snes_vram[(addr + 1) & 0x1ffff] << 8;
377      res = snes_vram[offset];
362378   else
363379   {
364380      UINT16 v = video_screen_get_vpos(space->machine->primary_screen);
r7651r7652
375391      else if (v == snes_ppu.beam.last_visible_line - 1)
376392      {
377393         if (h == 1362)
378            res = snes_vram[addr & 0x1ffff] | snes_vram[(addr + 1) & 0x1ffff] << 8;
394            res = snes_vram[offset];
379395         else
380396            res = 0;
381397      }
382398      else
383         res = snes_vram[addr & 0x1ffff] | snes_vram[(addr + 1) & 0x1ffff] << 8;
399         res = snes_vram[offset];
384400   }
385401   return res;
386402}
387403
388static void snes_vram_write( const address_space *space, UINT32 addr, UINT8 data )
404static WRITE8_HANDLER( snes_vram_write )
389405{
406   offset &= 0x1ffff;
407
390408   if (snes_ppu.screen_disabled)
391      snes_vram[addr & 0x1ffff] = data;
409      snes_vram[offset] = data;
392410   else
393411   {
394412      UINT16 v = video_screen_get_vpos(space->machine->primary_screen);
r7651r7652
396414      if (v == 0)
397415      {
398416         if (h <= 4)
399            snes_vram[addr & 0x1ffff] = data;
417            snes_vram[offset] = data;
400418         else if (h == 6)
401            snes_vram[addr & 0x1ffff] = snes_open_bus_r(space, 0);
419            snes_vram[offset] = snes_open_bus_r(space, 0);
402420         else
403421         {
404422            //no write
r7651r7652
415433            //no write
416434         }
417435         else
418            snes_vram[addr & 0x1ffff] = data;
436            snes_vram[offset] = data;
419437      }
420438      else
421         snes_vram[addr & 0x1ffff] = data;
439         snes_vram[offset] = data;
422440   }
423
424441}
425442
426443/*
r7651r7652
536553
537554            snes_ppu.ppu1_open_bus = (snes_oam[oam_addr] >> (snes_ram[OAMDATA] << 3)) & 0xff;
538555            snes_ram[OAMDATA] = (snes_ram[OAMDATA] + 1) % 2;
539            if (snes_ram[OAMDATA] == 0)
556            if (!snes_ram[OAMDATA])
540557            {
541558               snes_ppu.oam.address++;
542559               snes_ppu.oam.address &= 0x1ff;
r7651r7652
552569            if (!state->vram_fgr_high)
553570            {
554571               state->vram_read_buffer = snes_vram_read(space, addr);
572               state->vram_read_buffer |= (snes_vram_read(space, addr + 1) << 8);
555573
556574               addr = ((snes_ram[VMADDH] << 8) | snes_ram[VMADDL]) + state->vram_fgr_increment;
557575               snes_ram[VMADDL] = addr & 0xff;
r7651r7652
568586            if (state->vram_fgr_high)
569587            {
570588               state->vram_read_buffer = snes_vram_read(space, addr);
589               state->vram_read_buffer |= (snes_vram_read(space, addr + 1) << 8);
571590
572591               addr = ((snes_ram[VMADDH] << 8) | snes_ram[VMADDL]) + state->vram_fgr_increment;
573592               snes_ram[VMADDL] = addr & 0xff;
r7651r7652
715734         return state->joy4h;
716735      case DMAP0:   case DMAP1: case DMAP2: case DMAP3: /*0x43n0*/
717736      case DMAP4: case DMAP5: case DMAP6: case DMAP7:
737         return state->dma_channel[(offset & 0x70) >> 4].dmap;
718738      case BBAD0: case BBAD1: case BBAD2: case BBAD3: /*0x43n1*/
719739      case BBAD4: case BBAD5: case BBAD6: case BBAD7:
740         return state->dma_channel[(offset & 0x70) >> 4].dest_addr;
720741      case A1T0L: case A1T1L: case A1T2L: case A1T3L: /*0x43n2*/
721742      case A1T4L: case A1T5L: case A1T6L: case A1T7L:
743         return state->dma_channel[(offset & 0x70) >> 4].src_addr & 0xff;
722744      case A1T0H: case A1T1H: case A1T2H: case A1T3H: /*0x43n3*/
723745      case A1T4H: case A1T5H: case A1T6H: case A1T7H:
746         return (state->dma_channel[(offset & 0x70) >> 4].src_addr >> 8) & 0xff;
724747      case A1B0: case A1B1: case A1B2: case A1B3:     /*0x43n4*/
725748      case A1B4: case A1B5: case A1B6: case A1B7:
749         return state->dma_channel[(offset & 0x70) >> 4].bank;
726750      case DAS0L: case DAS1L: case DAS2L: case DAS3L: /*0x43n5*/
727751      case DAS4L: case DAS5L: case DAS6L: case DAS7L:
752         return state->dma_channel[(offset & 0x70) >> 4].trans_size & 0xff;
728753      case DAS0H: case DAS1H: case DAS2H: case DAS3H: /*0x43n6*/
729754      case DAS4H: case DAS5H: case DAS6H: case DAS7H:
755         return (state->dma_channel[(offset & 0x70) >> 4].trans_size >> 8) & 0xff;
730756      case DSAB0: case DSAB1: case DSAB2: case DSAB3: /*0x43n7*/
731757      case DSAB4: case DSAB5: case DSAB6: case DSAB7:
758         return state->dma_channel[(offset & 0x70) >> 4].ibank;
732759      case A2A0L: case A2A1L: case A2A2L: case A2A3L: /*0x43n8*/
733760      case A2A4L: case A2A5L: case A2A6L: case A2A7L:
761         return state->dma_channel[(offset & 0x70) >> 4].hdma_addr & 0xff;
734762      case A2A0H: case A2A1H: case A2A2H: case A2A3H: /*0x43n9*/
735763      case A2A4H: case A2A5H: case A2A6H: case A2A7H:
764         return (state->dma_channel[(offset & 0x70) >> 4].hdma_addr >> 8) & 0xff;
736765      case NTRL0: case NTRL1: case NTRL2: case NTRL3: /*0x43na*/
737766      case NTRL4: case NTRL5: case NTRL6: case NTRL7:
767         return state->dma_channel[(offset & 0x70) >> 4].hdma_line_counter;
738768      case 0x430b: case 0x431b: case 0x432b: case 0x433b: /* according to bsnes, this does not return open_bus (even if its precise effect is unknown) */
739769      case 0x434b: case 0x435b: case 0x436b: case 0x437b:
740         return snes_ram[offset];
770         return state->dma_channel[(offset & 0x70) >> 4].unk;
741771
742772#ifndef MESS
743773      case 0x4100:      /* NSS Dip-Switches */
r7651r7652
9941024            snes_ram[offset] = data;
9951025            addr = snes_get_vram_address(space->machine) << 1;
9961026            state->vram_read_buffer = snes_vram_read(space, addr);
1027            state->vram_read_buffer |= (snes_vram_read(space, addr + 1) << 8);
9971028         }
9981029         break;
9991030      case VMDATAL:   /* 2118: Data for VRAM write (low) */
r7651r7652
11781209         snes_ppu.layer[SNES_OAM].sub_window_enabled = BIT(data, 4);
11791210         break;
11801211      case CGWSEL:   /* Initial settings for Fixed colour addition or screen addition */
1181         /* FIXME: We don't support direct select for modes 3 & 4 or subscreen window stuff */
11821212         snes_ppu.clip_to_black = (data >> 6) & 0x03;
11831213         snes_ppu.prevent_color_math = (data >> 4) & 0x03;
11841214         snes_ppu.sub_add_mode = BIT(data, 1);
r7651r7652
13051335         data = 0;   /* Once DMA is done we need to reset all bits to 0 */
13061336         break;
13071337      case HDMAEN:   /* HDMA channel designation */
1308         if (data) //if a HDMA is enabled, data is inited at the next scanline
1338         state->hdmaen = data;
1339         if (state->hdmaen) //if a HDMA is enabled, data is inited at the next scanline
13091340            timer_set(space->machine, video_screen_get_time_until_pos(space->machine->primary_screen, snes_ppu.beam.current_vert + 1, 0), NULL, 0, snes_reset_hdma);
13101341         break;
13111342      case MEMSEL:   /* Access cycle designation in memory (2) area */
r7651r7652
13451376      /* Below is all DMA related */
13461377      case DMAP0:   case DMAP1: case DMAP2: case DMAP3: /*0x43n0*/
13471378      case DMAP4: case DMAP5: case DMAP6: case DMAP7:
1379         state->dma_channel[(offset & 0x70) >> 4].dmap = data;
1380         break;
13481381      case BBAD0: case BBAD1: case BBAD2: case BBAD3: /*0x43n1*/
13491382      case BBAD4: case BBAD5: case BBAD6: case BBAD7:
1383         state->dma_channel[(offset & 0x70) >> 4].dest_addr = data;
1384         break;
13501385      case A1T0L: case A1T1L: case A1T2L: case A1T3L: /*0x43n2*/
13511386      case A1T4L: case A1T5L: case A1T6L: case A1T7L:
1387         state->dma_channel[(offset & 0x70) >> 4].src_addr = (state->dma_channel[(offset & 0x70) >> 4].src_addr & 0xff00) | (data << 0);
1388         break;
13521389      case A1T0H: case A1T1H: case A1T2H: case A1T3H: /*0x43n3*/
13531390      case A1T4H: case A1T5H: case A1T6H: case A1T7H:
1391         state->dma_channel[(offset & 0x70) >> 4].src_addr = (state->dma_channel[(offset & 0x70) >> 4].src_addr & 0x00ff) | (data << 8);
1392         break;
13541393      case A1B0: case A1B1: case A1B2: case A1B3:     /*0x43n4*/
13551394      case A1B4: case A1B5: case A1B6: case A1B7:
1395         state->dma_channel[(offset & 0x70) >> 4].bank = data;
1396         break;
13561397      case DAS0L: case DAS1L: case DAS2L: case DAS3L: /*0x43n5*/
13571398      case DAS4L: case DAS5L: case DAS6L: case DAS7L:
1399         state->dma_channel[(offset & 0x70) >> 4].trans_size = (state->dma_channel[(offset & 0x70) >> 4].trans_size & 0xff00) | (data << 0);
1400         break;
13581401      case DAS0H: case DAS1H: case DAS2H: case DAS3H: /*0x43n6*/
13591402      case DAS4H: case DAS5H: case DAS6H: case DAS7H:
1403         state->dma_channel[(offset & 0x70) >> 4].trans_size = (state->dma_channel[(offset & 0x70) >> 4].trans_size & 0x00ff) | (data << 8);
1404         break;
13601405      case DSAB0: case DSAB1: case DSAB2: case DSAB3: /*0x43n7*/
13611406      case DSAB4: case DSAB5: case DSAB6: case DSAB7:
1407         state->dma_channel[(offset & 0x70) >> 4].ibank = data;
1408         break;
13621409      case A2A0L: case A2A1L: case A2A2L: case A2A3L: /*0x43n8*/
13631410      case A2A4L: case A2A5L: case A2A6L: case A2A7L:
1411         state->dma_channel[(offset & 0x70) >> 4].hdma_addr = (state->dma_channel[(offset & 0x70) >> 4].hdma_addr & 0xff00) | (data << 0);
1412         break;
13641413      case A2A0H: case A2A1H: case A2A2H: case A2A3H: /*0x43n9*/
13651414      case A2A4H: case A2A5H: case A2A6H: case A2A7H:
1415         state->dma_channel[(offset & 0x70) >> 4].hdma_addr = (state->dma_channel[(offset & 0x70) >> 4].hdma_addr & 0x00ff) | (data << 8);
1416         break;
13661417      case NTRL0: case NTRL1: case NTRL2: case NTRL3: /*0x43na*/
13671418      case NTRL4: case NTRL5: case NTRL6: case NTRL7:
1419         state->dma_channel[(offset & 0x70) >> 4].hdma_line_counter = data;
1420         break;
13681421      case 0x430b: case 0x431b: case 0x432b: case 0x433b:
13691422      case 0x434b: case 0x435b: case 0x436b: case 0x437b:
1423         state->dma_channel[(offset & 0x70) >> 4].unk = data;
13701424         break;
13711425   }
13721426
r7651r7652
23982452
23992453INLINE void snes_dma_transfer( const address_space *space, UINT8 dma, UINT32 abus, UINT16 bbus )
24002454{
2455   snes_state *state = (snes_state *)space->machine->driver_data;
24012456   UINT32 src, dst;
24022457
2403   if (snes_ram[SNES_DMA_BASE + dma] & 0x80)   /* PPU->CPU */
2458   if (state->dma_channel[dma].dmap & 0x80)   /* PPU->CPU */
24042459   {
24052460      if (bbus == 0x2180 && ((abus & 0xfe0000) == 0x7e0000 || (abus & 0x40e000) == 0x0000))
24062461      {
r7651r7652
24362491}
24372492
24382493#if 0
2439INLINE void snes_dma_transfer( const address_space *space, UINT8 dma, UINT32 abus, UINT16 bbus )
2494// FIXME: we need to use snes_state->hdma_iaddr[i] where appropriate (we now still
2495// use snes_state->trans_size[i] to avoid regressions in this first wip)
2496// and try to make the addr recovering/updating a bit more abstract
2497INLINE UINT32 snes_get_hdma_addr( running_machine *machine, int dma )
24402498{
2441   /* TODO: implement open bus access when DMA tries to transfer from not accessible regs */
2442   if (snes_ram[SNES_DMA_BASE + dma] & 0x80)   /* PPU->CPU */
2443      memory_write_byte(space, abus, memory_read_byte(space, bbus));
2444   else                           /* CPU->PPU */
2445      memory_write_byte(space, bbus, memory_read_byte(space, abus));
2499   snes_state *state = (snes_state *)machine->driver_data;
2500   return (state->dma_channel[dma].bank << 16) | (state->dma_channel[dma].hdma_addr++);
24462501}
2502
2503INLINE UINT32 snes_get_hdma_iaddr( running_machine *machine, int dma )
2504{
2505   snes_state *state = (snes_state *)machine->driver_data;
2506   return (state->dma_channel[dma].ibank << 16) | (state->dma_channel[dma].hdma_iaddr++);
2507}
24472508#endif
24482509
24492510static void snes_hdma_init( running_machine *machine )
24502511{
24512512   snes_state *state = (snes_state *)machine->driver_data;
2452   UINT8 mask = 1, dma = 0, i;
2513   int i;
24532514
2454   state->hdma_chnl = snes_ram[HDMAEN];
24552515   for (i = 0; i < 8; i++)
24562516   {
2457      if (snes_ram[HDMAEN] & mask)
2517      if (BIT(state->hdmaen, i))
24582518      {
2459         snes_ram[SNES_DMA_BASE + dma + 8] = snes_ram[SNES_DMA_BASE + dma + 2];
2460         snes_ram[SNES_DMA_BASE + dma + 9] = snes_ram[SNES_DMA_BASE + dma + 3];
2461         snes_ram[SNES_DMA_BASE + dma + 0xa] = 0;
2519         state->dma_channel[i].hdma_addr = state->dma_channel[i].src_addr;
2520         state->dma_channel[i].hdma_line_counter = 0;
24622521      }
2463      dma += 0x10;
2464      mask <<= 1;
24652522   }
24662523}
24672524
24682525static void snes_hdma( const address_space *space )
24692526{
24702527   snes_state *state = (snes_state *)space->machine->driver_data;
2471   UINT8 mask = 1, dma = 0, i, contmode;
2528   UINT8 i, contmode;
24722529   UINT16 bbus;
24732530   UINT32 abus;
24742531
24752532   /* Assume priority of the 8 DMA channels is 0-7 */
24762533   for (i = 0; i < 8; i++)
24772534   {
2478      if (state->hdma_chnl & mask)
2535      if (BIT(state->hdmaen, i))
24792536      {
24802537         /* Check if we need to read a new line from the table */
2481         if (!(snes_ram[SNES_DMA_BASE + dma + 0xa] & 0x7f))
2538         if (!(state->dma_channel[i].hdma_line_counter & 0x7f))
24822539         {
2483            abus = (snes_ram[SNES_DMA_BASE + dma + 4] << 16) + (snes_ram[SNES_DMA_BASE + dma + 9] << 8) + snes_ram[SNES_DMA_BASE + dma + 8];
2540            abus = (state->dma_channel[i].bank << 16) + state->dma_channel[i].hdma_addr;
24842541
24852542            /* Get the number of lines */
2486            snes_ram[SNES_DMA_BASE + dma + 0xa] = memory_read_byte(space, abus);
2487            if (!snes_ram[SNES_DMA_BASE + dma + 0xa])
2543            state->dma_channel[i].hdma_line_counter = memory_read_byte(space, abus);
2544            if (!state->dma_channel[i].hdma_line_counter)
24882545            {
24892546               /* No more lines so clear HDMA */
2490               state->hdma_chnl &= ~mask;
2547               state->hdmaen &= ~(1 << i);
24912548               continue;
24922549            }
24932550            abus++;
2494            snes_ram[SNES_DMA_BASE + dma + 8] = abus & 0xff;
2495            snes_ram[SNES_DMA_BASE + dma + 9] = (abus >> 8) & 0xff;
2496            if (snes_ram[SNES_DMA_BASE + dma] & 0x40)
2551            state->dma_channel[i].hdma_addr = abus;
2552            if (state->dma_channel[i].dmap & 0x40)
24972553            {
2498               snes_ram[SNES_DMA_BASE + dma + 5] = memory_read_byte(space, abus++);
2499               snes_ram[SNES_DMA_BASE + dma + 6] = memory_read_byte(space, abus++);
2500               snes_ram[SNES_DMA_BASE + dma + 8] = abus & 0xff;
2501               snes_ram[SNES_DMA_BASE + dma + 9] = (abus >> 8) & 0xff;
2554               state->dma_channel[i].trans_size = memory_read_byte(space, abus++);
2555               state->dma_channel[i].trans_size |= (memory_read_byte(space, abus++) << 8);
2556               state->dma_channel[i].hdma_addr = abus;
25022557            }
25032558         }
25042559
2505         contmode = (--snes_ram[SNES_DMA_BASE + dma + 0xa]) & 0x80;
2560         contmode = (--state->dma_channel[i].hdma_line_counter) & 0x80;
25062561
25072562         /* Transfer addresses */
2508         if (snes_ram[SNES_DMA_BASE + dma] & 0x40)   /* Indirect */
2509            abus = (snes_ram[SNES_DMA_BASE + dma + 7] << 16) + (snes_ram[SNES_DMA_BASE + dma + 6] << 8) + snes_ram[SNES_DMA_BASE + dma + 5];
2563         if (state->dma_channel[i].dmap & 0x40)   /* Indirect */
2564            abus = (state->dma_channel[i].ibank << 16) + state->dma_channel[i].trans_size;
25102565         else                           /* Absolute */
2511            abus = (snes_ram[SNES_DMA_BASE + dma + 4] << 16) + (snes_ram[SNES_DMA_BASE + dma + 9] << 8) + snes_ram[SNES_DMA_BASE + dma + 8];
2512         bbus = 0x2100 + snes_ram[SNES_DMA_BASE + dma + 1];
2566            abus = (state->dma_channel[i].bank << 16) + state->dma_channel[i].hdma_addr;
25132567
2568         bbus = state->dma_channel[i].dest_addr + 0x2100;
2569
25142570#ifdef SNES_DBG_HDMA
2515         mame_printf_debug( "HDMA-Ch: %d(%s) abus: %X bbus: %X type: %d(%X %X)\n", i, snes_ram[SNES_DMA_BASE + dma] & 0x40 ? "Indirect" : "Absolute", abus, bbus, snes_ram[SNES_DMA_BASE + dma] & 0x07, snes_ram[SNES_DMA_BASE + dma + 8],snes_ram[SNES_DMA_BASE + dma + 9] );
2571         mame_printf_debug( "HDMA-Ch: %d(%s) abus: %X bbus: %X type: %d(%X)\n", i, state->dma_channel[i].dmap & 0x40 ? "Indirect" : "Absolute", abus, bbus, state->dma_channel[i].dmap & 0x07, state->dma_channel[i].hdma_addr);
25162572#endif
25172573
2518         switch (snes_ram[SNES_DMA_BASE + dma] & 0x07)
2574         switch (state->dma_channel[i].dmap & 0x07)
25192575         {
25202576         case 0:      /* 1 register write once             (1 byte:  p               ) */
2521            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2577            snes_dma_transfer(space, i, abus++, bbus);
25222578            break;
25232579         case 5:      /* 2 registers write twice alternate (4 bytes: p, p+1, p,   p+1) */
2524            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2525            memory_write_byte(space, bbus + 1, memory_read_byte(space, abus++));
2526            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2527            memory_write_byte(space, bbus + 1, memory_read_byte(space, abus++));
2580            snes_dma_transfer(space, i, abus++, bbus);
2581            snes_dma_transfer(space, i, abus++, bbus + 1);
2582            snes_dma_transfer(space, i, abus++, bbus);
2583            snes_dma_transfer(space, i, abus++, bbus + 1);
25282584            break;
25292585         case 1:      /* 2 registers write once            (2 bytes: p, p+1          ) */
2530            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2531            memory_write_byte(space, bbus + 1, memory_read_byte(space, abus++));
2586            snes_dma_transfer(space, i, abus++, bbus);
2587            snes_dma_transfer(space, i, abus++, bbus + 1);
25322588            break;
25332589         case 2:      /* 1 register write twice            (2 bytes: p, p            ) */
25342590         case 6:
2535            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2536            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2591            snes_dma_transfer(space, i, abus++, bbus);
2592            snes_dma_transfer(space, i, abus++, bbus);
25372593            break;
25382594         case 3:      /* 2 registers write twice each      (4 bytes: p, p,   p+1, p+1) */
25392595         case 7:
2540            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2541            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2542            memory_write_byte(space, bbus + 1, memory_read_byte(space, abus++));
2543            memory_write_byte(space, bbus + 1, memory_read_byte(space, abus++));
2596            snes_dma_transfer(space, i, abus++, bbus);
2597            snes_dma_transfer(space, i, abus++, bbus);
2598            snes_dma_transfer(space, i, abus++, bbus + 1);
2599            snes_dma_transfer(space, i, abus++, bbus + 1);
25442600            break;
25452601         case 4:      /* 4 registers write once            (4 bytes: p, p+1, p+2, p+3) */
2546            memory_write_byte(space, bbus,     memory_read_byte(space, abus++));
2547            memory_write_byte(space, bbus + 1, memory_read_byte(space, abus++));
2548            memory_write_byte(space, bbus + 2, memory_read_byte(space, abus++));
2549            memory_write_byte(space, bbus + 3, memory_read_byte(space, abus++));
2602            snes_dma_transfer(space, i, abus++, bbus);
2603            snes_dma_transfer(space, i, abus++, bbus + 1);
2604            snes_dma_transfer(space, i, abus++, bbus + 2);
2605            snes_dma_transfer(space, i, abus++, bbus + 3);
25502606            break;
25512607         default:
25522608#ifdef MAME_DEBUG
2553            mame_printf_debug( "  HDMA of unsupported type: %d\n", snes_ram[SNES_DMA_BASE + dma] & 0x07);
2609            mame_printf_debug( "  HDMA of unsupported type: %d\n", state->dma_channel[i].dmap & 0x07);
25542610#endif
25552611            break;
25562612         }
r7651r7652
25582614         /* Update address */
25592615         if (contmode)
25602616         {
2561            if (snes_ram[SNES_DMA_BASE + dma] & 0x40)   /* Indirect */
2562            {
2563               snes_ram[SNES_DMA_BASE + dma + 5] = abus & 0xff;
2564               snes_ram[SNES_DMA_BASE + dma + 6] = (abus >> 8) & 0xff;
2565            }
2617            if (state->dma_channel[i].dmap & 0x40)   /* Indirect */
2618               state->dma_channel[i].trans_size = abus;
25662619            else                           /* Absolute */
2567            {
2568               snes_ram[SNES_DMA_BASE + dma + 8] = abus & 0xff;
2569               snes_ram[SNES_DMA_BASE + dma + 9] = (abus >> 8) & 0xff;
2570            }
2620               state->dma_channel[i].hdma_addr = abus;
25712621         }
25722622
2573         if (!(snes_ram[SNES_DMA_BASE + dma + 0xa] & 0x7f))
2623         if (!(state->dma_channel[i].hdma_line_counter & 0x7f))
25742624         {
2575            if (!(snes_ram[SNES_DMA_BASE + dma] & 0x40))   /* Absolute */
2625            if (!(state->dma_channel[i].dmap & 0x40))   /* Absolute */
25762626            {
25772627               if (!contmode)
2578               {
2579                  snes_ram[SNES_DMA_BASE + dma + 8] = abus & 0xff;
2580                  snes_ram[SNES_DMA_BASE + dma + 9] = (abus >> 8) & 0xff;
2581               }
2628                  state->dma_channel[i].hdma_addr = abus;
25822629            }
25832630         }
25842631      }
2585      dma += 0x10;
2586      mask <<= 1;
25872632   }
25882633}
25892634
25902635static void snes_dma( const address_space *space, UINT8 channels )
25912636{
25922637   snes_state *state = (snes_state *)space->machine->driver_data;
2593   UINT8 mask = 1, dma = 0, i;
2638   int i;
25942639   INT8 increment;
25952640   UINT16 bbus;
25962641   UINT32 abus, abus_bank, length;
r7651r7652
25982643   /* Assume priority of the 8 DMA channels is 0-7 */
25992644   for (i = 0; i < 8; i++)
26002645   {
2601      if (channels & mask)
2646      if (BIT(channels, i))
26022647      {
26032648         /* FIXME: the following should be used to stop DMA if the same channel is used by HDMA (being set to 1 in snes_hdma)
26042649            However, this cannot be implemented as is atm, because currently DMA transfers always happen as soon as they are enabled... */
2605         state->dma_disabled[i] = 0;
2650         state->dma_channel[i].dma_disabled = 0;
26062651
26072652         //printf( "Making a transfer on channel %d\n", i );
26082653         /* Find transfer addresses */
2609         abus = (snes_ram[SNES_DMA_BASE + dma + 3] << 8) + snes_ram[SNES_DMA_BASE + dma + 2];
2610         abus_bank = (snes_ram[SNES_DMA_BASE + dma + 4] << 16);
2611         bbus = 0x2100 + snes_ram[SNES_DMA_BASE + dma + 1];
2654         abus = state->dma_channel[i].src_addr;
2655         abus_bank = state->dma_channel[i].bank << 16;
2656         bbus = state->dma_channel[i].dest_addr + 0x2100;
26122657
2613         //printf( "Address: %06x\n", abus | abus_bank );
2658         //printf("Address: %06x\n", abus | abus_bank);
26142659         /* Auto increment */
2615         if (snes_ram[SNES_DMA_BASE + dma] & 0x8)
2616         {
2660         if (state->dma_channel[i].dmap & 0x8)
26172661            increment = 0;
2618         }
26192662         else
26202663         {
2621            if (snes_ram[SNES_DMA_BASE + dma] & 0x10)
2664            if (state->dma_channel[i].dmap & 0x10)
26222665               increment = -1;
26232666            else
26242667               increment = 1;
26252668         }
26262669
26272670         /* Number of bytes to transfer */
2628         length = (snes_ram[SNES_DMA_BASE + dma + 6] << 8) + snes_ram[SNES_DMA_BASE + dma + 5];
2671         length = state->dma_channel[i].trans_size;
26292672         if (!length)
26302673            length = 0x10000;   /* 0x0000 really means 0x10000 */
26312674
2632//          printf( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus, bbus, increment, snes_ram[SNES_DMA_BASE + dma] & 0x80 ? "PPU->CPU" : "CPU->PPU", snes_ram[SNES_DMA_BASE + dma] & 0x07);
2675//          printf( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus, bbus, increment, state->dma_channel[i].dmap & 0x80 ? "PPU->CPU" : "CPU->PPU", state->dma_channel[i].dmap & 0x07);
26332676
26342677#ifdef SNES_DBG_DMA
2635         mame_printf_debug( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus, bbus, increment, snes_ram[SNES_DMA_BASE + dma] & 0x80 ? "PPU->CPU" : "CPU->PPU", snes_ram[SNES_DMA_BASE + dma] & 0x07);
2678         mame_printf_debug( "DMA-Ch %d: len: %X, abus: %X, bbus: %X, incr: %d, dir: %s, type: %d\n", i, length, abus, bbus, increment, state->dma_channel[i].dmap & 0x80 ? "PPU->CPU" : "CPU->PPU", state->dma_channel[i].dmap & 0x07);
26362679#endif
26372680
2638         switch (snes_ram[SNES_DMA_BASE + dma] & 0x07)
2681         switch (state->dma_channel[i].dmap & 0x07)
26392682         {
26402683         case 0:      /* 1 register write once */
26412684         case 2:      /* 1 register write twice */
26422685         case 6:      /* 1 register write twice */
2643
2644            while (length-- && !state->dma_disabled[i])
2686            while (length-- && !state->dma_channel[i].dma_disabled)
26452687            {
2646               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus);
2688               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
26472689               abus += increment;
26482690            }
26492691            break;
26502692         case 1:      /* 2 registers write once */
26512693         case 5:      /* 2 registers write twice alternate */
2652            while (length-- && !state->dma_disabled[i])
2694            while (length-- && !state->dma_channel[i].dma_disabled)
26532695            {
2654               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus);
2696               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
26552697               abus += increment;
2656               if (!(length--) || state->dma_disabled[i])
2698               if (!(length--) || state->dma_channel[i].dma_disabled)
26572699                  break;
2658               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus + 1);
2700               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
26592701               abus += increment;
26602702            }
26612703            break;
26622704         case 3:      /* 2 registers write twice each */
26632705         case 7:      /* 2 registers write twice each */
2664            while (length-- && !state->dma_disabled[i])
2706            while (length-- && !state->dma_channel[i].dma_disabled)
26652707            {
2666               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus);
2708               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
26672709               abus += increment;
2668               if (!(length--) || state->dma_disabled[i])
2710               if (!(length--) || state->dma_channel[i].dma_disabled)
26692711                  break;
2670               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus);
2712               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
26712713               abus += increment;
2672               if (!(length--) || state->dma_disabled[i])
2714               if (!(length--) || state->dma_channel[i].dma_disabled)
26732715                  break;
2674               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus + 1);
2716               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
26752717               abus += increment;
2676               if (!(length--) || state->dma_disabled[i])
2718               if (!(length--) || state->dma_channel[i].dma_disabled)
26772719                  break;
2678               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus + 1);
2720               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
26792721               abus += increment;
26802722            }
26812723            break;
26822724         case 4:      /* 4 registers write once */
2683            while (length-- && !state->dma_disabled[i])
2725            while (length-- && !state->dma_channel[i].dma_disabled)
26842726            {
2685               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus);
2727               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus);
26862728               abus += increment;
2687               if (!(length--) || state->dma_disabled[i])
2729               if (!(length--) || state->dma_channel[i].dma_disabled)
26882730                  break;
2689               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus + 1);
2731               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 1);
26902732               abus += increment;
2691               if (!(length--) || state->dma_disabled[i])
2733               if (!(length--) || state->dma_channel[i].dma_disabled)
26922734                  break;
2693               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus + 2);
2735               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 2);
26942736               abus += increment;
2695               if (!(length--) || state->dma_disabled[i])
2737               if (!(length--) || state->dma_channel[i].dma_disabled)
26962738                  break;
2697               snes_dma_transfer(space, dma, (abus & 0xffff) | abus_bank, bbus + 3);
2739               snes_dma_transfer(space, i, (abus & 0xffff) | abus_bank, bbus + 3);
26982740               abus += increment;
26992741            }
27002742            break;
27012743         default:
27022744#ifdef MAME_DEBUG
2703            mame_printf_debug( "  DMA of unsupported type: %d\n", snes_ram[SNES_DMA_BASE + dma] & 0x07);
2745            mame_printf_debug("  DMA of unsupported type: %d\n", state->dma_channel[i].dmap & 0x07);
27042746#endif
27052747            break;
27062748         }
27072749
2708         /* We're done so write the new abus back to the registers */
2709         snes_w_io(space, SNES_DMA_BASE + dma + 2, abus & 0xff);
2710         snes_w_io(space, SNES_DMA_BASE + dma + 3, (abus >> 8) & 0xff);
2711         snes_w_io(space, SNES_DMA_BASE + dma + 5, 0);
2712         snes_w_io(space, SNES_DMA_BASE + dma + 6, 0);
2750         /* We're done, so write the new abus back to the registers */
2751         state->dma_channel[i].src_addr = abus;
2752         state->dma_channel[i].trans_size = 0;
27132753      }
2714      dma += 0x10;
2715      mask <<= 1;
27162754   }
27172755}
27182756
src/mame/includes/snes.h
r7651r7652
402402   emu_timer             *mult_timer;
403403
404404   /* DMA/HDMA-related */
405   int                   dma_disabled[8];   // used to stop DMA if HDMA is enabled (currently not implemented, see machine/snes.c)
406   UINT8                 hdma_chnl;   /* channels enabled for HDMA */
405   struct
406   {
407      UINT8  dmap;
408      UINT8  dest_addr;
409      UINT16 src_addr;
410      UINT16 trans_size;
411      UINT8  bank;
412      UINT8  ibank;
413      UINT16 hdma_addr;
414      UINT16 hdma_iaddr;
415      UINT8  hdma_line_counter;
416      UINT8  unk;
407417
418      int    dma_disabled;   // used to stop DMA if HDMA is enabled (currently not implemented, see machine/snes.c)
419   }dma_channel[8];
420   UINT8                 hdmaen;   /* channels enabled for HDMA */
421
408422   /* input-related */
409423   UINT8                 joy1l, joy1h, joy2l, joy2h, joy3l, joy3h, joy4l, joy4h;
410424   UINT16                data1[2], data2[2];

Previous 15994 Revisions Next


© 1998-2018 The MESS Team