src/mess/drivers/supracan.c
| r8778 | r8779 | |
| 132 | 132 | emu_timer *line_on_timer; |
| 133 | 133 | emu_timer *line_off_timer; |
| 134 | 134 | UINT16 *vram; |
| 135 | | UINT8 bg_color; |
| 135 | UINT16 *pram; |
| 136 | 136 | |
| 137 | 137 | bitmap_t *sprite_final_bitmap; |
| 138 | 138 | UINT8 sprite_pri[1024*1024]; |
| r8778 | r8779 | |
| 370 | 370 | scrollx |= (scrollx & 0x800) ? 0xfffff000 : 0; |
| 371 | 371 | scrolly |= (scrolly & 0x800) ? 0xfffff000 : 0; |
| 372 | 372 | |
| 373 | | int gfx_mode = (state->tilemap_mode[layer] & 0x7000) >> 12; |
| 374 | | |
| 375 | | int region = 1; |
| 376 | | UINT16 tile_bank = 0; |
| 377 | | UINT16 palette_bank = 0; |
| 378 | | switch(gfx_mode) |
| 379 | | { |
| 380 | | case 7: |
| 381 | | region = 2; |
| 382 | | tile_bank = 0x1c00; |
| 383 | | palette_bank = 0x00; |
| 384 | | break; |
| 385 | | |
| 386 | | case 4: |
| 387 | | region = 1; |
| 388 | | tile_bank = 0x800; |
| 389 | | palette_bank = 0x00; |
| 390 | | break; |
| 391 | | |
| 392 | | case 2: |
| 393 | | region = 1; |
| 394 | | tile_bank = 0x400; |
| 395 | | palette_bank = 0x00; |
| 396 | | break; |
| 397 | | |
| 398 | | case 0: |
| 399 | | region = 1; |
| 400 | | tile_bank = 0; |
| 401 | | palette_bank = 0x00; |
| 402 | | break; |
| 403 | | |
| 404 | | default: |
| 405 | | verboselog("maincpu", machine, 0, "Unsupported tilemap mode: %d\n", (state->tilemap_flags[layer] & 0x7000) >> 12); |
| 406 | | break; |
| 407 | | } |
| 408 | | |
| 409 | 373 | int wrapped_x = scrollx; |
| 410 | 374 | int wrapped_y = ypos + scrolly; |
| 411 | 375 | |
| r8778 | r8779 | |
| 427 | 391 | } |
| 428 | 392 | } |
| 429 | 393 | |
| 430 | | UINT16 *src = BITMAP_ADDR16(state->tilemap_bitmap[layer], wrapped_y, 0); |
| 431 | | UINT8 *srcpri = &state->tilemap_pri[layer][1024*wrapped_y]; |
| 394 | int mosaic = (state->tilemap_flags[layer] & 0x001c) >> 2; |
| 395 | UINT32 mask = 0xffffffff; |
| 432 | 396 | |
| 397 | if(mosaic) |
| 398 | { |
| 399 | mosaic--; |
| 400 | mask = ~(1 << mosaic); |
| 401 | } |
| 402 | |
| 403 | UINT16 *src = BITMAP_ADDR16(state->tilemap_bitmap[layer], wrapped_y & mask, 0); |
| 404 | UINT8 *srcpri = &state->tilemap_pri[layer][1024*(wrapped_y & mask)]; |
| 405 | |
| 433 | 406 | if(state->tilemap_flags[layer] & 0x20) |
| 434 | 407 | { |
| 435 | 408 | while(wrapped_x >= width*8) wrapped_x -= width*8; |
| r8778 | r8779 | |
| 437 | 410 | |
| 438 | 411 | for(int x = 0; x < 320; x++) |
| 439 | 412 | { |
| 440 | | scanline[x] = src[wrapped_x] ? src[wrapped_x] : scanline[x]; |
| 441 | | priline[x] = src[wrapped_x] ? srcpri[wrapped_x] : 8; |
| 413 | scanline[x] = src[wrapped_x & mask] ? src[wrapped_x & mask] : scanline[x]; |
| 414 | priline[x] = src[wrapped_x & mask] ? srcpri[wrapped_x & mask] : 8; |
| 442 | 415 | wrapped_x++; |
| 443 | 416 | while(wrapped_x >= width*8) wrapped_x -= width*8; |
| 444 | 417 | } |
| r8778 | r8779 | |
| 449 | 422 | { |
| 450 | 423 | if(wrapped_x >= 0 && wrapped_x < width*8) |
| 451 | 424 | { |
| 452 | | scanline[x] = src[wrapped_x] ? src[wrapped_x] : scanline[x]; |
| 453 | | priline[x] = src[wrapped_x] ? srcpri[wrapped_x] : 8; |
| 425 | scanline[x] = src[wrapped_x & mask] ? src[wrapped_x & mask] : scanline[x]; |
| 426 | priline[x] = src[wrapped_x & mask] ? srcpri[wrapped_x & mask] : 8; |
| 454 | 427 | } |
| 455 | 428 | else |
| 456 | 429 | { |
| r8778 | r8779 | |
| 533 | 506 | break; |
| 534 | 507 | |
| 535 | 508 | default: |
| 536 | | verboselog("maincpu", machine, 0, "Unsupported tilemap mode: %d\n", (state->tilemap_flags[layer] & 0x7000) >> 12); |
| 509 | verboselog("maincpu", machine, 0, "Unsupported tilemap mode: %d\n", (state->tilemap_mode[layer] & 0x7000) >> 12); |
| 537 | 510 | break; |
| 538 | 511 | } |
| 539 | 512 | |
| 513 | if(layer == 2) |
| 514 | { |
| 515 | region = 1; |
| 516 | tile_bank = 0x400; |
| 517 | palette_bank = 0x00; |
| 518 | } |
| 519 | |
| 540 | 520 | if(state->tilemap_flags[layer] & 0x20) |
| 541 | 521 | { |
| 542 | 522 | bitmap_fill(state->tilemap_bitmap[layer], NULL, 0); |
| r8778 | r8779 | |
| 824 | 804 | bool hflip = (supracan_vram[i+1] & 0x0800) ? true : false; |
| 825 | 805 | bool vflip = (supracan_vram[i+1] & 0x0400) ? true : false; |
| 826 | 806 | #if !(DRAW_DEBUG_UNK_SPRITE) |
| 827 | | UINT8 priority = ((supracan_vram[i+0] >> 12) & 7) + 1; |
| 807 | UINT8 priority = ((supracan_vram[i+2] >> 12) & 7) + 1; |
| 828 | 808 | #endif |
| 829 | | while(x > cliprect->max_x) |
| 809 | while(x > 0x200) |
| 830 | 810 | { |
| 831 | | x -= 0x200; |
| 811 | x -= 0x200; |
| 832 | 812 | } |
| 833 | 813 | |
| 834 | | while(y > cliprect->max_y) |
| 814 | while(y > 0x200) |
| 835 | 815 | { |
| 836 | | y -= 0x200; |
| 816 | y -= 0x200; |
| 837 | 817 | } |
| 838 | 818 | |
| 839 | 819 | if(supracan_vram[i+3] != 0) |
| 840 | 820 | { |
| 841 | 821 | int xsize = 1 << (supracan_vram[i+1] & 7); |
| 842 | | int ysize = ((supracan_vram[i+0] & 0x1e00) >> 9)+1; |
| 822 | int ysize = ((supracan_vram[i+0] & 0x1e00) >> 9) + 1; |
| 843 | 823 | //int ysize = (((supracan_vram[i+0] & 0x0600) >> 9) + 1) * (1 << ((supracan_vram[i+0] & 0x1800) >> 11)); |
| 844 | 824 | //if(supracan_vram[i+2] & 0x2000) ysize = xsize; |
| 845 | 825 | //int ysize = ((supracan_vram[i+2] & 0x1e00) >> 9)+1; |
| r8778 | r8779 | |
| 1022 | 1002 | // crash debug: printf("K"); fflush(stdout); |
| 1023 | 1003 | supracan_state *state = (supracan_state *)screen->machine->driver_data<supracan_state>(); |
| 1024 | 1004 | |
| 1025 | | bitmap_fill(bitmap, cliprect, state->bg_color); |
| 1005 | bitmap_fill(bitmap, cliprect, 0); |
| 1026 | 1006 | |
| 1027 | 1007 | bitmap_fill(state->sprite_final_bitmap, cliprect, 0); |
| 1028 | 1008 | memset(state->sprite_pri, 8, 1024*1024 * sizeof(UINT8)); |
| r8778 | r8779 | |
| 1200 | 1180 | } |
| 1201 | 1181 | } |
| 1202 | 1182 | |
| 1183 | /* |
| 1184 | static WRITE16_HANDLER( supracan_pram_w ) |
| 1185 | { |
| 1186 | supracan_state *state = (supracan_state *)space->machine->driver_data<supracan_state>(); |
| 1187 | state->pram[offset] &= ~mem_mask; |
| 1188 | state->pram[offset] |= data & mem_mask; |
| 1189 | } |
| 1190 | */ |
| 1191 | |
| 1203 | 1192 | static ADDRESS_MAP_START( supracan_mem, ADDRESS_SPACE_PROGRAM, 16 ) |
| 1204 | 1193 | AM_RANGE( 0x000000, 0x3fffff ) AM_ROM AM_REGION( "cart", 0 ) |
| 1205 | 1194 | AM_RANGE( 0xe80200, 0xe80201 ) AM_READ_PORT("P1") |
| r8778 | r8779 | |
| 1432 | 1421 | PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 Button A") |
| 1433 | 1422 | INPUT_PORTS_END |
| 1434 | 1423 | |
| 1435 | | |
| 1436 | 1424 | static PALETTE_INIT( supracan ) |
| 1437 | 1425 | { |
| 1438 | 1426 | // Used for debugging purposes for now |
| r8778 | r8779 | |
| 1449 | 1437 | //#endif |
| 1450 | 1438 | } |
| 1451 | 1439 | |
| 1452 | | |
| 1453 | 1440 | static WRITE16_HANDLER( supracan_68k_soundram_w ) |
| 1454 | 1441 | { |
| 1455 | 1442 | // crash debug: printf("P"); fflush(stdout); |
| r8778 | r8779 | |
| 1564 | 1551 | case 0x00/2: // Video IRQ flags |
| 1565 | 1552 | if(!space->debugger_access) |
| 1566 | 1553 | { |
| 1554 | //verboselog("maincpu", space->machine, 0, "read video IRQ flags (%04x)\n", data); |
| 1567 | 1555 | cpu_set_input_line(space->machine->device("maincpu"), 7, CLEAR_LINE); |
| 1568 | 1556 | } |
| 1569 | 1557 | break; |
| 1570 | 1558 | case 0x02/2: // Current scanline |
| 1571 | 1559 | break; |
| 1560 | case 0x08/2: // Unknown (not video flags!) |
| 1561 | data = 0; |
| 1562 | break; |
| 1563 | case 0x100/2: |
| 1564 | if(!space->debugger_access) verboselog("maincpu", space->machine, 0, "read tilemap_flags[0] (%04x)\n", data); |
| 1565 | break; |
| 1566 | case 0x106/2: |
| 1567 | if(!space->debugger_access) verboselog("maincpu", space->machine, 0, "read tilemap_scrolly[0] (%04x)\n", data); |
| 1568 | break; |
| 1569 | case 0x120/2: |
| 1570 | if(!space->debugger_access) verboselog("maincpu", space->machine, 0, "read tilemap_flags[1] (%04x)\n", data); |
| 1571 | break; |
| 1572 | 1572 | default: |
| 1573 | 1573 | if(!space->debugger_access) verboselog("maincpu", space->machine, 0, "supracan_video_r: Unknown register: %08x (%04x & %04x)\n", 0xf00000 + (offset << 1), data, mem_mask); |
| 1574 | 1574 | break; |
| r8778 | r8779 | |
| 1620 | 1620 | state->video_regs[0] |= 0x8000; |
| 1621 | 1621 | if(state->irq_mask & 1) |
| 1622 | 1622 | { |
| 1623 | | verboselog("maincpu", machine, 0, "Triggering VBL IRQ\n"); |
| 1623 | verboselog("maincpu", machine, 0, "Triggering VBL IRQ\n\n"); |
| 1624 | 1624 | cpu_set_input_line(machine->device("maincpu"), 7, HOLD_LINE); |
| 1625 | 1625 | } |
| 1626 | 1626 | break; |
| r8778 | r8779 | |
| 1630 | 1630 | |
| 1631 | 1631 | if (vpos == 0) |
| 1632 | 1632 | { |
| 1633 | | bitmap_fill(state->roz_final_bitmap, &machine->primary_screen->visible_area(), 0); |
| 1634 | | bitmap_fill(state->roz_bitmap, &machine->primary_screen->visible_area(), 0); |
| 1633 | bitmap_fill(state->roz_final_bitmap, NULL, 0); |
| 1634 | bitmap_fill(state->roz_bitmap, NULL, 0); |
| 1635 | 1635 | bitmap_fill(state->tilemap_bitmap[0], NULL, 0); |
| 1636 | 1636 | bitmap_fill(state->tilemap_bitmap[1], NULL, 0); |
| 1637 | 1637 | bitmap_fill(state->tilemap_bitmap[2], NULL, 0); |
| r8778 | r8779 | |
| 1662 | 1662 | |
| 1663 | 1663 | if(state->video_flags & 0x20) |
| 1664 | 1664 | { |
| 1665 | // Causes issues in Speedy Dragon; investigate later |
| 1665 | 1666 | draw_tilemap(machine, state->tilemap_bitmap[2], &machine->primary_screen->visible_area(), 2); |
| 1666 | 1667 | } |
| 1667 | 1668 | } |
| r8778 | r8779 | |
| 1670 | 1671 | { |
| 1671 | 1672 | UINT16 *scandata = BITMAP_ADDR16(state->roz_final_bitmap, vpos, 0); |
| 1672 | 1673 | UINT8 *pridata = &state->roz_final_pri[vpos*320]; |
| 1673 | | draw_roz_bitmap_scanline(machine, state->roz_bitmap, scandata, pridata, vpos, state->roz_scrollx, state->roz_scrolly, state->roz_coeffa, state->roz_coeffb, state->roz_coeffc, state->roz_coeffd, &state->roz_cx, &state->roz_cy, state->roz_changed); |
| 1674 | if(state->video_flags & 4) |
| 1675 | { |
| 1676 | draw_roz_bitmap_scanline(machine, state->roz_bitmap, scandata, pridata, vpos, state->roz_scrollx, state->roz_scrolly, state->roz_coeffa, state->roz_coeffb, state->roz_coeffc, state->roz_coeffd, &state->roz_cx, &state->roz_cy, state->roz_changed); |
| 1677 | } |
| 1674 | 1678 | |
| 1675 | 1679 | for(int index = 0; index < 3; index++) |
| 1676 | 1680 | { |
| 1681 | if(index == 2) |
| 1682 | { |
| 1683 | // Tilemap 2 causes issues in Speedy Dragon; investigate later |
| 1684 | //break; |
| 1685 | } |
| 1677 | 1686 | if(state->video_flags & (0x80 >> index) ) |
| 1678 | 1687 | { |
| 1679 | 1688 | scandata = BITMAP_ADDR16(state->tilemap_final_bitmap[index], vpos, 0); |
| r8778 | r8779 | |
| 1829 | 1838 | case 0x140/2: state->tilemap_flags[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_flags[2] = %04x\n", data); break; |
| 1830 | 1839 | case 0x144/2: state->tilemap_scrollx[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_scrollx[2] = %04x\n", data); break; |
| 1831 | 1840 | case 0x146/2: state->tilemap_scrolly[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_scrolly[2] = %04x\n", data); break; |
| 1832 | | case 0x148/2: state->tilemap_base_addr[2] = (data) << 1; verboselog("maincpu", space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 2); verboselog("maincpu", space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 1); break; |
| 1841 | case 0x148/2: state->tilemap_base_addr[2] = (data) << 1; verboselog("maincpu", space->machine, 0, "tilemap_base_addr[2] = %05x\n", data << 2); break; |
| 1833 | 1842 | case 0x14a/2: state->tilemap_mode[2] = data; verboselog("maincpu", space->machine, 0, "tilemap_mode[2] = %04x\n", data); break; |
| 1834 | 1843 | |
| 1835 | 1844 | /* ROZ */ |
| r8778 | r8779 | |
| 1848 | 1857 | case 0x19a/2: state->roz_unk_base1 = data << 1; verboselog("maincpu", space->machine, 3, "roz_unk_base1 = %05x\n", data << 2); break; |
| 1849 | 1858 | case 0x19e/2: state->roz_unk_base2 = data << 1; verboselog("maincpu", space->machine, 3, "roz_unk_base2 = %05x\n", data << 2); break; |
| 1850 | 1859 | |
| 1851 | | case 0x1d0/2: state->bg_color = data & 0x00ff; verboselog("maincpu", space->machine, 3, "bg_color = %02x\n", data & 0x00ff); break; |
| 1860 | //case 0x1d0/2: state->bg_color = data & 0x00ff; verboselog("maincpu", space->machine, 3, "bg_color = %04x\n", data); break; |
| 1852 | 1861 | |
| 1853 | 1862 | case 0x1f0/2: //FIXME: this register is mostly not understood |
| 1854 | 1863 | state->irq_mask = data;//(data & 8) ? 0 : 1; |
| r8778 | r8779 | |
| 2007 | 2016 | |
| 2008 | 2017 | MDRV_SCREEN_ADD( "screen", RASTER ) |
| 2009 | 2018 | MDRV_SCREEN_FORMAT( BITMAP_FORMAT_INDEXED16 ) |
| 2019 | //MDRV_SCREEN_FORMAT( BITMAP_FORMAT_RGB32 ) |
| 2010 | 2020 | MDRV_SCREEN_RAW_PARAMS(XTAL_10_738635MHz/2, 348, 0, 256, 256, 0, 240 ) /* No idea if this is correct */ |
| 2011 | 2021 | |
| 2012 | 2022 | MDRV_PALETTE_LENGTH( 32768 ) |