Previous 15994 Revisions Next

r8301 Monday 21st June, 2010 at 07:28:17 UTC by MooglyGuy
Refactored tilemap priorities and ROZ wraparound. [Harmony]
[src/mess/drivers]supracan.c

src/mess/drivers/supracan.c
r8300r8301
5050#include "devices/cartslot.h"
5151#include "debugger.h"
5252
53#define DRAW_DEBUG_ROZ  (0)
54
5355typedef struct _acan_dma_regs_t acan_dma_regs_t;
5456struct _acan_dma_regs_t
5557{
r8300r8301
6365struct _acan_sprdma_regs_t
6466{
6567   UINT32 src;
68    UINT16 src_inc;
6669   UINT32 dst;
70    UINT16 dst_inc;
6771   UINT16 count;
6872   UINT16 control;
6973};
r8300r8301
8488   emu_timer *video_timer;
8589   UINT16 *vram;
8690   UINT16 spr_limit;
91    UINT16 spr_yline;
8792   UINT32 spr_base_addr;
8893   UINT8 spr_flags;
8994   UINT32 tilemap_base_addr[4];
r8300r8301
170175      default: xsize = 32; ysize = 32; break;
171176   }
172177
173   scrollx = (state->tilemap_scrollx[layer] & 0x800) ? ((state->tilemap_scrollx[layer] & (xsize*8-1)) - xsize*8) : (state->tilemap_scrollx[layer] & (xsize*8-1));
174   scrolly = (state->tilemap_scrolly[layer] & 0x800) ? ((state->tilemap_scrolly[layer] & (ysize*8-1)) - ysize*8) : (state->tilemap_scrolly[layer] & (ysize*8-1));
178    scrollx = state->tilemap_scrollx[layer];
179    scrolly = state->tilemap_scrolly[layer];
180    scrollx |= (scrollx & 0x800) ? 0xfffff000 : 0;
181    scrolly |= (scrolly & 0x800) ? 0xfffff000 : 0;
175182
176183   gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12;
177184
r8300r8301
223230    INT32 sx = 0;
224231    INT32 sy = 0;
225232
226    sx = (state->roz_mode & 0x800) ? 512 : 256;
227    sy = (state->roz_mode & 0x800) ? 512 : 256;
233    switch(state->roz_mode & 0x0f00)
234    {
235        case 0x600: sx = 64*8; sy = 32*8; break;
236        case 0xa00: sx = 128*8; sy = 32*8; break;
237        case 0xc00: sx = 64*8; sy = 64*8; break;
238        default: sx = 32*8; sy = 32*8; break;
239    }
228240
229241    if (X & 0x08000000) X |= 0xf0000000;
230242    if (Y & 0x08000000) Y |= 0xf0000000;
r8300r8301
272284
273285    for(int x = 0; x < 320; x++)
274286    {
275        if(!(pixx < 0 || pixy < 0 || pixx >= sx || pixy >= sy))
287        if(state->roz_mode & 0x20)
276288        {
289            while(pixx < 0) pixx += sx;
290            while(pixy < 0) pixy += sy;
291            while(pixx >= sx) pixx -= sx;
292            while(pixy >= sy) pixy -= sy;
293
277294            scanline[x] = *BITMAP_ADDR16(roz_bitmap, pixy, pixx);
278295        }
296        else
297        {
298            if(pixx >= 0 && pixy >= 0 && pixx < sx && pixy < sy)
299            {
300                scanline[x] = *BITMAP_ADDR16(roz_bitmap, pixy, pixx);
301            }
302        }
279303
280304        rx += dx;
281305        ry += dy;
r8300r8301
284308        pixy = ry >> 8;
285309    }
286310
287    /*
288    for (y=0;y<ysize;y++)
289    {
290        for (x=0;x<xsize;x++)
291        {
292            int tile, flipx, flipy, pal;
293            tile = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x03ff) | tile_bank;
294            flipx = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0800) ? 1 : 0;
295            flipy = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0400) ? 1 : 0;
296            pal = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0xf000) >> 12;
297
298            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx,(y*8)-scrolly,0);
299            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx+xsize*8,(y*8)-scrolly,0);
300            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx,(y*8)-scrolly+ysize*8,0);
301            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)-scrollx+xsize*8,(y*8)-scrolly+ysize*8,0);
302
303            count++;
304        }
305    }
306    */
307
308311    state->roz_changed = 0;
309312}
310313
r8300r8301
314317    UINT16 *supracan_vram = state->vram;
315318    UINT32 roz_base_addr = state->roz_base_addr;
316319    int region = 0;
320    UINT16 tile_bank = 0;
317321//  int gfx_mode;
318322
319323    switch(state->roz_mode & 3) //FIXME: fix gfx bpp order
320324    {
321        case 0: return; //1bpp! Used on BIOS logo
325        case 0: return;//region = 2; tile_bank = (state->roz_tile_bank & 0xf000) >> 3; break;
322326        case 1: region = 2; break;
323        case 2: region = 1; break;
327        case 2: region = 1; tile_bank = (state->roz_tile_bank & 0xf000) >> 3; break;
324328        case 3: region = 0; break;
325329    }
326330
327    int xsize = (state->roz_mode & 0x800) ? 64 : 32;
328    int ysize = (state->roz_mode & 0x800) ? 64 : 32;
331    int xsize = 32;
332    int ysize = 32;
333    switch(state->roz_mode & 0x0f00)
334    {
335        case 0x600: xsize = 64; ysize = 32; break;
336        case 0xa00: xsize = 128; ysize = 32; break;
337        case 0xc00: xsize = 64; ysize = 64; break;
338        default: xsize = 32; ysize = 32; break;
339    }
329340
330341    UINT32 count = (0);
331342
332    UINT16 tile_bank = (state->roz_tile_bank & 0xf000) >> 3; //FIXME: check this
333
334343    bitmap_t *roz_bitmap = state->roz_bitmap;
335344    for (int y = 0; y < ysize; y++)
336345    {
r8300r8301
347356            count++;
348357        }
349358    }
350
351    /*
352   supracan_state *state = (supracan_state *)machine->driver_data;
353   UINT16 *supracan_vram = state->vram;
354   UINT32 roz_base_addr = state->roz_base_addr;
355   UINT32 count = 0;
356   int xsize,ysize;
357
358   //roz_mode & 0x20 enables roz capabilities
359
360    int region = 0;
361    switch(state->roz_mode & 3)
362    {
363        case 0: region = 3; break;
364        case 1: region = 2; break;
365        case 2: region = 1; break;
366        case 3: region = 0; break;
367    }
368
369    if((state->roz_mode & 0xe00) == 0xc00)
370    {
371        xsize = ysize = 64;
372    }
373    else
374    {
375        xsize = ysize = (state->roz_mode & 0x200) ? 64 : 32;
376    }
377
378    int tile_bank = (state->roz_tile_bank & 0xf000) >> 3;
379
380    //bitmap_t *roz_bitmap = state->roz_bitmap;
381    for(int y = 0; y < ysize; y++)
382    {
383        for(int x = 0; x < xsize; x++)
384        {
385            int tile = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x03ff) | tile_bank;
386            int flipx = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0800) ? 1 : 0;
387            int flipy = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0x0400) ? 1 : 0;
388            int pal = (supracan_vram[roz_base_addr | (count & 0xfff)] & 0xf000) >> 12;
389
390            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8),(y*8),0);
391            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)+xsize*8,(y*8),0);
392            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8),(y*8)+ysize*8,0);
393            drawgfx_transpen(bitmap,cliprect,machine->gfx[region],tile,pal,flipx,flipy,(x*8)+xsize*8,(y*8)+ysize*8,0);
394
395            count++;
396        }
397    }
398    */
399359}
400360
401361static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect)
r8300r8301
515475   }
516476}
517477
518/*
478#if DRAW_DEBUG_ROZ
519479static void draw_debug_roz(running_machine *machine, bitmap_t *bitmap)
520480{
521481    supracan_state *state = (supracan_state *)machine->driver_data;
r8300r8301
524484    for(int y = 0; y < 240; y++)
525485    {
526486        float x = ((float)supracan_vram[state->roz_unk_base0 + y] / 1024.0f) * 256.0f;
527        *BITMAP_ADDR16(bitmap, y, (int)x) = 0xffff;
487        *BITMAP_ADDR16(bitmap, y, (int)x) = 1;
488
489        INT32 temp = supracan_vram[state->roz_unk_base1 + y*2] << 16;
490        temp |= supracan_vram[state->roz_unk_base1 + y*2 + 1];
491        x = ((float)temp / 65536.0f) * 128.0f;
492        if(x > -160 && x < 160)
493        {
494            *BITMAP_ADDR16(bitmap, y, (int)x + 160) = 2;
495        }
496
497        temp = supracan_vram[state->roz_unk_base2 + y*2] << 16;
498        temp |= supracan_vram[state->roz_unk_base2 + y*2 + 1];
499        x = ((float)temp / 65536.0f) * 128.0f;
500        if(x > -160 && x < 160)
501        {
502            *BITMAP_ADDR16(bitmap, y, (int)x + 160) = 4;
503        }
528504    }
529505}
530*/
506#endif
531507
532508static VIDEO_UPDATE( supracan )
533509{
r8300r8301
569545   }
570546#endif
571547
572#if 0
573   count = 0x4200/2;
548   if(state->video_flags & 0x20) //guess, not tested
549      draw_tilemap(screen->machine,bitmap,cliprect,2);
574550
575   for (y=0;y<16;y++)
576   {
577      for (x=0;x<16;x++)
578      {
579         int tile;
551    int pri_order[3] = { 0, 0, 0 };
552    int pri_index[3] = { 0, 1, 2 };
580553
581         tile = (supracan_vram[count] & 0x01ff);
582         drawgfx_transpen(bitmap,cliprect,screen->machine->gfx[0],tile,0,0,0,x*8,y*8,0);
583         count++;
584      }
585   }
586#endif
554    pri_order[0] = state->tilemap_flags[0] >> 13;
555    pri_order[1] = state->tilemap_flags[1] >> 13;
556    pri_order[2] = state->roz_mode >> 13;
587557
588   if(state->video_flags & 0x20) //guess, not tested
589      draw_tilemap(screen->machine,bitmap,cliprect,2);
558    // Evil bubble sort, but who cares, it's 3 entries long...
559    for(int i1 = 0; i1 < 3; i1++)
560    {
561        for(int i2 = i1; i2 < 3; i2++)
562        {
563            if(pri_order[i2] > pri_order[i1])
564            {
565                int temp = pri_order[i1];
566                pri_order[i1] = pri_order[i2];
567                pri_order[i2] = temp;
590568
591   if((state->tilemap_flags[1] & 0x7000) < (state->tilemap_flags[0] & 0x7000)) //pri number?
592   {
593      if(state->video_flags & 0x80)
594         draw_tilemap(screen->machine,bitmap,cliprect,0);
595      if(state->video_flags & 0x40)
596         draw_tilemap(screen->machine,bitmap,cliprect,1);
597   }
598   else
599   {
600      if(state->video_flags & 0x40)
601         draw_tilemap(screen->machine,bitmap,cliprect,1);
602      if(state->video_flags & 0x80)
603         draw_tilemap(screen->machine,bitmap,cliprect,0);
604   }
569                temp = pri_index[i1];
570                pri_index[i1] = pri_index[i2];
571                pri_index[i2] = temp;
572            }
573        }
574    }
575
576    for(int index = 0; index < 3; index++)
577    {
578        switch(pri_index[index])
579        {
580            case 0:
581                if(state->video_flags & 0x80)
582                {
583                    draw_tilemap(screen->machine,bitmap,cliprect, 0);
584                }
585                break;
586            case 1:
587                if(state->video_flags & 0x40)
588                {
589                    draw_tilemap(screen->machine,bitmap,cliprect, 1);
590                }
591                break;
592            case 2:
593                copybitmap_trans(bitmap,state->roz_final_bitmap,0,0,0,0,cliprect,0);
594                break;
595        }
596    }
597
605598   if(state->video_flags & 8)
606599      draw_sprites(screen->machine,bitmap,cliprect);
607600
608    copybitmap_trans(bitmap,state->roz_final_bitmap,0,0,0,0,cliprect,0);
601#if DRAW_DEBUG_ROZ
602    draw_debug_roz(screen->machine,bitmap);
603#endif
609604
610    //draw_debug_roz(screen->machine,bitmap);
611
612605   return 0;
613606}
614607
r8300r8301
651644      case 0x0a/2: // Control
652645      case 0x1a/2:
653646         //if(acan_dma_regs.dest != 0xf00200)
654         printf("%08x %08x %02x %04x\n",acan_dma_regs->source[ch],acan_dma_regs->dest[ch],acan_dma_regs->count[ch] + 1,data);
647         //printf("%08x %08x %02x %04x\n",acan_dma_regs->source[ch],acan_dma_regs->dest[ch],acan_dma_regs->count[ch] + 1,data);
655648         if(data & 0x8800)
656649         {
657650            //if(data != 0x9800 && data != 0x8800)
r8300r8301
660653            //}
661654//              if(data & 0x2000)
662655//                  acan_dma_regs->source-=2;
663            verboselog(space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1, data);
656            //verboselog(space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1, data);
664657
665658            for(i = 0; i <= acan_dma_regs->count[ch]; i++)
666659            {
r8300r8301
991984
992985   switch(offset)
993986   {
994      case 0x18/2: // Source address MSW
995         acan_sprdma_regs->src &= 0x0000ffff;
996         acan_sprdma_regs->src |= data << 16;
997         break;
998      case 0x1a/2: // Source address LSW
999         acan_sprdma_regs->src &= 0xffff0000;
1000         acan_sprdma_regs->src |= data;
1001         break;
987        case 0x10/2: // Byte count
988            acan_sprdma_regs->count = data;
989            break;
1002990      case 0x12/2: // Destination address MSW
1003991         acan_sprdma_regs->dst &= 0x0000ffff;
1004992         acan_sprdma_regs->dst |= data << 16;
r8300r8301
1007995         acan_sprdma_regs->dst &= 0xffff0000;
1008996         acan_sprdma_regs->dst |= data;
1009997         break;
1010      case 0x10/2: // Byte count
1011         acan_sprdma_regs->count = data;
1012         break;
998        case 0x16/2: // Source word increment
999            acan_sprdma_regs->dst_inc = data;
1000            break;
1001        case 0x18/2: // Source address MSW
1002            acan_sprdma_regs->src &= 0x0000ffff;
1003            acan_sprdma_regs->src |= data << 16;
1004            break;
1005        case 0x1a/2: // Source address LSW
1006            acan_sprdma_regs->src &= 0xffff0000;
1007            acan_sprdma_regs->src |= data;
1008            break;
1009        case 0x1c/2: // Source word increment
1010            acan_sprdma_regs->src_inc = data;
1011            break;
10131012      case 0x1e/2:
1014         printf("* %08x %08x %04x %04x\n",acan_sprdma_regs->src,acan_sprdma_regs->dst,acan_sprdma_regs->count,data);
1015         verboselog(space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_sprdma_regs->src, acan_sprdma_regs->dst, acan_sprdma_regs->count + 1, data);
1013         //printf("* %08x %08x %04x %04x\n",acan_sprdma_regs->src,acan_sprdma_regs->dst,acan_sprdma_regs->count,data);
1014         //verboselog(space->machine, 0, "supracan_dma_w: Kicking off a DMA from %08x to %08x, %d bytes (%04x)\n", acan_sprdma_regs->src, acan_sprdma_regs->dst, acan_sprdma_regs->count + 1, data);
10161015
10171016         /* TODO: what's 0x2000 and 0x4000 for? */
10181017         if(data & 0x8000)
r8300r8301
10251024               if(data & 0x0100) //dma 0x00 fill (or fixed value?)
10261025               {
10271026                  memory_write_word(space, acan_sprdma_regs->dst, 0);
1028                  acan_sprdma_regs->dst+=2;
1027                        acan_sprdma_regs->dst+=2 * acan_sprdma_regs->dst_inc;
10291028                  //memset(supracan_vram,0x00,0x020000);
10301029               }
10311030               else
10321031               {
10331032                  memory_write_word(space, acan_sprdma_regs->dst, memory_read_word(space, acan_sprdma_regs->src));
1034                  acan_sprdma_regs->dst+=2;
1035                  acan_sprdma_regs->src+=2;
1033                        acan_sprdma_regs->dst+=2 * acan_sprdma_regs->dst_inc;
1034                        acan_sprdma_regs->src+=2 * acan_sprdma_regs->src_inc;
10361035               }
10371036            }
10381037         }
r8300r8301
10561055         break;
10571056      case 0x20/2: state->spr_base_addr = data << 2; break;
10581057      case 0x22/2: state->spr_limit = data+1; break;
1059      case 0x26/2: state->spr_flags = data; break;
1060      case 0x100/2: state->tilemap_flags[0] = data; break;
1061        case 0x104/2: state->tilemap_scrollx[0] = data; break;
1062      case 0x106/2: state->tilemap_scrolly[0] = data; break;
1063      case 0x108/2: state->tilemap_base_addr[0] = (data) << 1; break;
1064      case 0x10a/2: state->tilemap_mode[0] = data; break;
1065      case 0x120/2: state->tilemap_flags[1] = data; break;
1066      case 0x124/2: state->tilemap_scrollx[1] = data; break;
1067      case 0x126/2: state->tilemap_scrolly[1] = data; break;
1068      case 0x128/2: state->tilemap_base_addr[1] = (data) << 1; break;
1069      case 0x12a/2: state->tilemap_mode[1] = data; break;
1070        case 0x140/2: state->tilemap_flags[2] = data; verboselog(space->machine, 5, "tilemap_flags[2] = %04x\n", data); break;
1071        case 0x144/2: state->tilemap_scrollx[2] = data; verboselog(space->machine, 5, "tilemap_scrollx[2] = %04x\n", data); break;
1072        case 0x146/2: state->tilemap_scrolly[2] = data; verboselog(space->machine, 5, "tilemap_scrolly[2] = %04x\n", data); break;
1073        case 0x148/2: state->tilemap_base_addr[2] = (data) << 1; verboselog(space->machine, 5, "tilemap_base_addr[2] = %05x\n", data << 1); break;
1074        case 0x14a/2: state->tilemap_mode[2] = data; verboselog(space->machine, 5, "tilemap_mode[2] = %04x\n", data); break;
1058        case 0x24/2: state->spr_yline = data; verboselog(space->machine, 0, "spr_yline = %04x\n", data); break;
1059        case 0x26/2: state->spr_flags = data; verboselog(space->machine, 0, "spr_flags = %04x\n", data); break;
1060        case 0x100/2: state->tilemap_flags[0] = data; verboselog(space->machine, 0, "tilemap_flags[0] = %04x\n", data); break;
1061        case 0x104/2: state->tilemap_scrollx[0] = data; verboselog(space->machine, 0, "tilemap_scrollx[0] = %04x\n", data); break;
1062        case 0x106/2: state->tilemap_scrolly[0] = data; verboselog(space->machine, 0, "tilemap_scrolly[0] = %04x\n", data); break;
1063        case 0x108/2: state->tilemap_base_addr[0] = (data) << 1; verboselog(space->machine, 0, "tilemap_base_addr[0] = %05x\n", data << 2); break;
1064        case 0x10a/2: state->tilemap_mode[0] = data; verboselog(space->machine, 0, "tilemap_mode[0] = %04x\n", data); break;
1065        case 0x120/2: state->tilemap_flags[1] = data; verboselog(space->machine, 0, "tilemap_flags[1] = %04x\n", data); break;
1066        case 0x124/2: state->tilemap_scrollx[1] = data; verboselog(space->machine, 0, "tilemap_scrollx[1] = %04x\n", data); break;
1067        case 0x126/2: state->tilemap_scrolly[1] = data; verboselog(space->machine, 0, "tilemap_scrolly[1] = %04x\n", data); break;
1068        case 0x128/2: state->tilemap_base_addr[1] = (data) << 1; verboselog(space->machine, 0, "tilemap_base_addr[1] = %05x\n", data << 2); break;
1069        case 0x12a/2: state->tilemap_mode[1] = data; verboselog(space->machine, 0, "tilemap_mode[1] = %04x\n", data); break;
1070        case 0x140/2: state->tilemap_flags[2] = data; verboselog(space->machine, 0, "tilemap_flags[2] = %04x\n", data); break;
1071        case 0x144/2: state->tilemap_scrollx[2] = data; verboselog(space->machine, 0, "tilemap_scrollx[2] = %04x\n", data); break;
1072        case 0x146/2: state->tilemap_scrolly[2] = data; verboselog(space->machine, 0, "tilemap_scrolly[2] = %04x\n", data); break;
1073        case 0x148/2: state->tilemap_base_addr[2] = (data) << 1; verboselog(space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 2); verboselog(space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 1); break;
1074        case 0x14a/2: state->tilemap_mode[2] = data; verboselog(space->machine, 0, "tilemap_mode[2] = %04x\n", data); break;
10751075
10761076      /* 0x180-0x19f are roz tilemap related regs */
10771077        case 0x180/2: state->roz_mode = data; verboselog(space->machine, 5, "roz_mode = %04x\n", data); break;
r8300r8301
11811181   8*16
11821182};
11831183
1184
11851184static GFXDECODE_START( supracan )
11861185   GFXDECODE_ENTRY( "ram_gfx",  0, supracan_gfx8bpp,   0, 1 )
11871186   GFXDECODE_ENTRY( "ram_gfx",  0, supracan_gfx4bpp,   0, 0x10 )

Previous 15994 Revisions Next


© 1998-2018 The MESS Team