diff options
Diffstat (limited to 'src/mess/drivers/supracan.c')
-rw-r--r-- | src/mess/drivers/supracan.c | 1927 |
1 files changed, 0 insertions, 1927 deletions
diff --git a/src/mess/drivers/supracan.c b/src/mess/drivers/supracan.c deleted file mode 100644 index baf2a4668f1..00000000000 --- a/src/mess/drivers/supracan.c +++ /dev/null @@ -1,1927 +0,0 @@ -// license:LGPL-2.1+ -// copyright-holders:Angelo Salese,Ryan Holtz -/*************************************************************************** - - - Funtech Super A'Can - ------------------- - - Preliminary driver by Angelo Salese - Improvements by Harmony - - -******************************************************************************* - -INFO: - - The system unit contains a reset button. - - Controllers: - - 4 directional buttons - - A, B, X, Y, buttons - - Start, select buttons - - L, R shoulder buttons - -STATUS: - - The driver is begging for a re-write or at least a split into video/supracan.c. It will happen eventually. - - Sound CPU comms and sound chip are completely unknown. - - There are 6 interrupt sources on the 6502 side, all of which use the IRQ line. - The register at 0x411 is bitmapped to indicate what source(s) are active. - In priority order from most to least important, they are: - - 411 value How acked Notes - 0x40 read reg 0x16 of sound chip likely timer. snd regs 0x16/0x17 are time constant, write 0 to reg 0x9f to start - 0x04 read at 0x405 latch 1? 0xcd is magic value - 0x08 read at 0x404 latch 2? 0xcd is magic value - 0x10 read at 0x409 unknown, dispatched but not used in startup 6502 code - 0x20 read at 0x40a possible periodic like vblank? - 0x80 read reg 0x14 of sound chip depends on reg 0x14 of sound chip & 0x40: if not set writes 0x8f to reg 0x14, - otherwise writes 0x4f to reg 0x14 and performs additional processing - - Known unemulated graphical effects and issues: - - All: Sprite sizing is still imperfect. - - All: Sprites need to be converted to use scanline rendering for proper clipping. - - All: Improperly-emulated 1bpp ROZ mode, used by the Super A'Can BIOS logo. - - All: Unimplemented ROZ scaling tables, used by the Super A'Can BIOS logo and Speedy Dragon intro, among others. - - All: Priorities are largely unknown. - - C.U.G.: Gameplay backgrounds are broken. - - Sango Fighter: Possible missing masking on the upper edges of the screen during gameplay. - - Sango Fighter: Raster effects off by 1 line - - Sango Fighter: Specifies tiles out of range of video ram?? - - Speedy Dragon: Backgrounds are broken (wrong tile bank/region). - - Super Taiwanese Baseball League: Does not boot, uses an unemulated DMA type - - Super Taiwanese Baseball League: Missing window effect applied on tilemaps? - - The Son of Evil: Many graphical issues. - - Visible area, looks like it should be 224 pixels high at most, most games need 8 off the top and 8 off the bottom (or a global scroll) - Sango looks like it needs 16 off the bottom instead - Visible area is almost certainly 224 as Son of Evil has an explicit check in the vblank handler - - - All: are ALL the layers ROZ capable?? - -DEBUG TRICKS: - - baseball game debug trick: - wpset e90020,1f,w - do pc=5ac40 - ... - do pc=5acd4 - wpclear - bp 0269E4 - [ff7be4] <- 0x269ec - bpclear - -***************************************************************************/ - -#include "emu.h" -#include "cpu/m68000/m68000.h" -#include "cpu/m6502/m6502.h" -#include "bus/generic/slot.h" -#include "bus/generic/carts.h" - -#define SOUNDCPU_BOOT_HACK (1) - -#define DRAW_DEBUG_ROZ (0) - -#define DRAW_DEBUG_UNK_SPRITE (0) - -#define DEBUG_PRIORITY (0) -#define DEBUG_PRIORITY_INDEX (0) // 0-3 - -#define VERBOSE_LEVEL (3) - -#define ENABLE_VERBOSE_LOG (1) - -struct acan_dma_regs_t -{ - UINT32 source[2]; - UINT32 dest[2]; - UINT16 count[2]; - UINT16 control[2]; -}; - -struct acan_sprdma_regs_t -{ - UINT32 src; - UINT16 src_inc; - UINT32 dst; - UINT16 dst_inc; - UINT16 count; - UINT16 control; -}; - -class supracan_state : public driver_device -{ -public: - supracan_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_soundcpu(*this, "soundcpu"), - m_cart(*this, "cartslot"), - m_vram(*this, "vram"), - m_soundram(*this, "soundram"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette") - { - m_m6502_reset = 0; - } - - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_soundcpu; - required_device<generic_slot_device> m_cart; - - required_shared_ptr<UINT16> m_vram; - required_shared_ptr<UINT8> m_soundram; - - DECLARE_READ16_MEMBER(_68k_soundram_r); - DECLARE_WRITE16_MEMBER(_68k_soundram_w); - DECLARE_READ8_MEMBER(_6502_soundmem_r); - DECLARE_WRITE8_MEMBER(_6502_soundmem_w); - - void dma_w(address_space &space, int offset, UINT16 data, UINT16 mem_mask, int ch); - DECLARE_WRITE16_MEMBER(dma_channel0_w); - DECLARE_WRITE16_MEMBER(dma_channel1_w); - - DECLARE_READ16_MEMBER(sound_r); - DECLARE_WRITE16_MEMBER(sound_w); - DECLARE_READ16_MEMBER(video_r); - DECLARE_WRITE16_MEMBER(video_w); - DECLARE_WRITE16_MEMBER(vram_w); - acan_dma_regs_t m_acan_dma_regs; - acan_sprdma_regs_t m_acan_sprdma_regs; - - UINT16 m_m6502_reset; - UINT8 m_soundlatch; - UINT8 m_soundcpu_irq_src; - UINT8 m_sound_irq_enable_reg; - UINT8 m_sound_irq_source_reg; - UINT8 m_sound_cpu_68k_irq_reg; - - emu_timer *m_video_timer; - emu_timer *m_hbl_timer; - emu_timer *m_line_on_timer; - emu_timer *m_line_off_timer; - - dynamic_buffer m_vram_addr_swapped; - - UINT16 *m_pram; - - UINT16 m_sprite_count; - UINT32 m_sprite_base_addr; - UINT8 m_sprite_flags; - - UINT32 m_tilemap_base_addr[3]; - int m_tilemap_scrollx[3]; - int m_tilemap_scrolly[3]; - UINT16 m_video_flags; - UINT16 m_tilemap_flags[3]; - UINT16 m_tilemap_mode[3]; - UINT16 m_irq_mask; - UINT16 m_hbl_mask; - - UINT32 m_roz_base_addr; - UINT16 m_roz_mode; - UINT32 m_roz_scrollx; - UINT32 m_roz_scrolly; - UINT16 m_roz_tile_bank; - UINT32 m_roz_unk_base0; - UINT32 m_roz_unk_base1; - UINT32 m_roz_unk_base2; - UINT16 m_roz_coeffa; - UINT16 m_roz_coeffb; - UINT16 m_roz_coeffc; - UINT16 m_roz_coeffd; - INT32 m_roz_changed; - INT32 m_roz_cx; - INT32 m_roz_cy; - UINT16 m_unk_1d0; - - UINT16 m_video_regs[256]; - - bool m_hack_68k_to_6502_access; - - tilemap_t *m_tilemap_sizes[4][4]; - bitmap_ind16 m_sprite_final_bitmap; - void write_swapped_byte(int offset, UINT8 byte); - TILE_GET_INFO_MEMBER(get_supracan_tilemap0_tile_info); - TILE_GET_INFO_MEMBER(get_supracan_tilemap1_tile_info); - TILE_GET_INFO_MEMBER(get_supracan_tilemap2_tile_info); - TILE_GET_INFO_MEMBER(get_supracan_roz_tile_info); - virtual void machine_start(); - virtual void machine_reset(); - virtual void video_start(); - DECLARE_PALETTE_INIT(supracan); - UINT32 screen_update_supracan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(supracan_irq); - INTERRUPT_GEN_MEMBER(supracan_sound_irq); - TIMER_CALLBACK_MEMBER(supracan_hbl_callback); - TIMER_CALLBACK_MEMBER(supracan_line_on_callback); - TIMER_CALLBACK_MEMBER(supracan_line_off_callback); - TIMER_CALLBACK_MEMBER(supracan_video_callback); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(supracan_cart); - inline void verboselog(const char *tag, int n_level, const char *s_fmt, ...) ATTR_PRINTF(4,5); - int supracan_tilemap_get_region(int layer); - void supracan_tilemap_get_info_common(int layer, tile_data &tileinfo, int count); - void supracan_tilemap_get_info_roz(int layer, tile_data &tileinfo, int count); - int get_tilemap_dimensions(int &xsize, int &ysize, int layer); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); - void mark_active_tilemap_all_dirty(int layer); - void supracan_suprnova_draw_roz(bitmap_ind16 &bitmap, const rectangle &cliprect, tilemap_t *tmap, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound/*, int columnscroll, UINT32* scrollram*/, int transmask); - required_device<gfxdecode_device> m_gfxdecode; - required_device<palette_device> m_palette; -}; - - - -inline void supracan_state::verboselog(const char *tag, int n_level, const char *s_fmt, ...) -{ -#if ENABLE_VERBOSE_LOG - if( VERBOSE_LEVEL >= n_level ) - { - va_list v; - char buf[ 32768 ]; - va_start( v, s_fmt ); - vsprintf( buf, s_fmt, v ); - va_end( v ); - logerror( "%06x: %s: %s", machine().device(tag)->safe_pc(), tag, buf ); - } -#endif -} - -int supracan_state::supracan_tilemap_get_region(int layer) -{ - // HACK!!! - if (layer==2) - { - return 2; - } - - - if (layer==3) - { - // roz layer - - int gfx_mode = (m_roz_mode & 3); - - switch(gfx_mode) - { - case 0: return 4; - case 1: return 2; - case 2: return 1; - case 3: return 0; - } - return 1; - } - else - { - // normal layers - int gfx_mode = (m_tilemap_mode[layer] & 0x7000) >> 12; - - switch(gfx_mode) - { - case 7: return 2; - case 4: return 1; - case 2: return 1; - case 0: return 1; - } - - return 1; - } - -} - -void supracan_state::supracan_tilemap_get_info_common(int layer, tile_data &tileinfo, int count) -{ - UINT16* supracan_vram = m_vram; - - UINT32 base = (m_tilemap_base_addr[layer]); - int gfx_mode = (m_tilemap_mode[layer] & 0x7000) >> 12; - int region = supracan_tilemap_get_region(layer); - - count += base; - - UINT16 tile_bank = 0; - UINT16 palette_bank = 0; - switch(gfx_mode) - { - case 7: - tile_bank = 0x1c00; - palette_bank = 0x00; - break; - - case 6: // gambling lord - tile_bank = 0x0c00; - palette_bank = 0x00; - break; - - case 4: - tile_bank = 0x800; - palette_bank = 0x00; - break; - - case 2: - tile_bank = 0x400; - palette_bank = 0x00; - break; - - case 0: - tile_bank = 0; - palette_bank = 0x00; - break; - - default: - verboselog("maincpu", 0, "Unsupported tilemap mode: %d\n", (m_tilemap_mode[layer] & 0x7000) >> 12); - break; - } - - - if(layer == 2) - { - tile_bank = 0x1000; - } - - int tile = (supracan_vram[count] & 0x03ff) + tile_bank; - int flipxy = (supracan_vram[count] & 0x0c00)>>10; - int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank; - - SET_TILE_INFO_MEMBER(region, tile, palette, TILE_FLIPXY(flipxy)); -} - -// I wonder how different this really is.. my guess, not at all. -void supracan_state::supracan_tilemap_get_info_roz(int layer, tile_data &tileinfo, int count) -{ - UINT16* supracan_vram = m_vram; - - UINT32 base = m_roz_base_addr; - - - int region = 1; - UINT16 tile_bank = 0; - UINT16 palette_bank = 0; - - region = supracan_tilemap_get_region(layer); - - switch(m_roz_mode & 3) //FIXME: fix gfx bpp order - { - case 0: - // hack: case for startup logo - // this isn't understood properly, it's rendering a single 64x64 tile, which for convenience we've rearranged and decoded as 8x8 for the tilemaps - { - int tile = 0x880 + ((count & 7)*2); - // tile += (count & 0x070) >> 2; - - if (count & 0x20) tile ^= 1; - tile |= (count & 0xc0)>>2; - - SET_TILE_INFO_MEMBER(region, tile, 0, 0); - return; - } - - - case 1: - tile_bank = (m_roz_tile_bank & 0xf000) >> 3; - break; - - case 2: - tile_bank = (m_roz_tile_bank & 0xf000) >> 3; - break; - - case 3: - tile_bank = (m_roz_tile_bank & 0xf000) >> 3; - break; - } - - count += base; - - int tile = (supracan_vram[count] & 0x03ff) + tile_bank; - int flipxy = (supracan_vram[count] & 0x0c00)>>10; - int palette = ((supracan_vram[count] & 0xf000) >> 12) + palette_bank; - - SET_TILE_INFO_MEMBER(region, tile, palette, TILE_FLIPXY(flipxy)); -} - - - -TILE_GET_INFO_MEMBER(supracan_state::get_supracan_tilemap0_tile_info) -{ - supracan_tilemap_get_info_common(0, tileinfo, tile_index); -} - -TILE_GET_INFO_MEMBER(supracan_state::get_supracan_tilemap1_tile_info) -{ - supracan_tilemap_get_info_common(1, tileinfo, tile_index); -} - -TILE_GET_INFO_MEMBER(supracan_state::get_supracan_tilemap2_tile_info) -{ - supracan_tilemap_get_info_common(2, tileinfo, tile_index); -} - -TILE_GET_INFO_MEMBER(supracan_state::get_supracan_roz_tile_info) -{ - supracan_tilemap_get_info_roz(3, tileinfo, tile_index); -} - - -void supracan_state::video_start() -{ - m_sprite_final_bitmap.allocate(1024, 1024, BITMAP_FORMAT_IND16); - - m_vram_addr_swapped.resize(0x20000); // hack for 1bpp layer at startup - m_gfxdecode->gfx(4)->set_source(&m_vram_addr_swapped[0]); - m_gfxdecode->gfx(4)->set_xormask(0); - - m_tilemap_sizes[0][0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap0_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_tilemap_sizes[0][1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap0_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32); - m_tilemap_sizes[0][2] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap0_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 32); - m_tilemap_sizes[0][3] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap0_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); - - m_tilemap_sizes[1][0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap1_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_tilemap_sizes[1][1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap1_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32); - m_tilemap_sizes[1][2] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap1_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 32); - m_tilemap_sizes[1][3] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap1_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); - - m_tilemap_sizes[2][0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap2_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_tilemap_sizes[2][1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap2_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32); - m_tilemap_sizes[2][2] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap2_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 32); - m_tilemap_sizes[2][3] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_tilemap2_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); - - m_tilemap_sizes[3][0] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_roz_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); - m_tilemap_sizes[3][1] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_roz_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32); - m_tilemap_sizes[3][2] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_roz_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 32); - m_tilemap_sizes[3][3] = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(supracan_state::get_supracan_roz_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); -} - -int supracan_state::get_tilemap_dimensions(int &xsize, int &ysize, int layer) -{ - int select; - - xsize = 32; - ysize = 32; - - if (layer==3) select = (m_roz_mode & 0x0f00); - else select = m_tilemap_flags[layer] & 0x0f00; - - switch(select) - { - case 0x600: - xsize = 64; - ysize = 32; - return 1; - - case 0xa00: - xsize = 128; - ysize = 32; - return 2; - - case 0xc00: - xsize = 64; - ysize = 64; - return 3; - - default: - verboselog("maincpu", 0, "Unsupported tilemap size for layer %d: %04x\n", layer, select); - return 0; - } -} - - - - -void supracan_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - UINT16 *supracan_vram = m_vram; - -// [0] -// -e-- ---- ---- ---- sprite enable? -// ---h hhh- ---- ---- Y size (not always right) -// ---- ---y yyyy yyyy Y position -// [1] -// bbbb ---- ---- ---- Tile bank -// ---- h--- ---- ---- Horizontal flip -// ---- -v-- ---- ---- Vertical flip -// ---- --mm ---- ---- Masking mode -// ---- ---- ---- -www X size -// [2] -// zzzz ---- ---- ---- X scale -// ---- ---x xxxx xxxx X position -// [3] -// d--- ---- ---- ---- Direct Sprite (use details from here, not looked up in vram) -// -ooo oooo oooo oooo Sprite address - - UINT32 skip_count = 0; - UINT32 start_word = (m_sprite_base_addr >> 1) + skip_count * 4; - UINT32 end_word = start_word + (m_sprite_count - skip_count) * 4; - int region = (m_sprite_flags & 1) ? 0 : 1; //8bpp : 4bpp - -// printf("frame\n"); - #define VRAM_MASK (0xffff) - - for(int i = start_word; i < end_word; i += 4) - { - int x = supracan_vram[i+2] & 0x01ff; - int y = supracan_vram[i+0] & 0x01ff; - - int sprite_offset = (supracan_vram[i+3])<< 1; - - int bank = (supracan_vram[i+1] & 0xf000) >> 12; - //int mask = (supracan_vram[i+1] & 0x0300) >> 8; - int sprite_xflip = (supracan_vram[i+1] & 0x0800) >> 11; - int sprite_yflip = (supracan_vram[i+1] & 0x0400) >> 10; - //int xscale = (supracan_vram[i+2] & 0xf000) >> 12; - gfx_element *gfx = m_gfxdecode->gfx(region); - - - - - // wraparound - if (y>=0x180) y-=0x200; - if (x>=0x180) x-=0x200; - - if((supracan_vram[i+0] & 0x4000)) - { - #if 0 - printf("%d (unk %02x) (enable %02x) (unk Y2 %02x, %02x) (y pos %02x) (bank %01x) (flip %01x) (unknown %02x) (x size %02x) (xscale %01x) (unk %01x) (xpos %02x) (code %04x)\n", i, - (supracan_vram[i+0] & 0x8000) >> 15, - (supracan_vram[i+0] & 0x4000) >> 14, - (supracan_vram[i+0] & 0x2000) >> 13, - (supracan_vram[i+0] & 0x1e00) >> 8, - (supracan_vram[i+0] & 0x01ff), - (supracan_vram[i+1] & 0xf000) >> 12, - (supracan_vram[i+1] & 0x0c00) >> 10, - (supracan_vram[i+1] & 0x03f0) >> 4, - (supracan_vram[i+1] & 0x000f), - (supracan_vram[i+2] & 0xf000) >> 12, - (supracan_vram[i+2] & 0x0e00) >> 8, - (supracan_vram[i+2] & 0x01ff) >> 0, - (supracan_vram[i+3] & 0xffff)); - #endif - - - if (supracan_vram[i+3] &0x8000) - { - UINT16 data = supracan_vram[i+3]; - int tile = (bank * 0x200) + (data & 0x03ff); - - int palette = (data & 0xf000) >> 12; // this might not be correct, due to the &0x8000 condition above this would force all single tile sprites to be using palette >=0x8 only - - //printf("sprite data %04x %04x %04x %04x\n", supracan_vram[i+0] , supracan_vram[i+1] , supracan_vram[i+2] ,supracan_vram[i+3] ); - - gfx->transpen(bitmap,cliprect,tile,palette,sprite_xflip,sprite_yflip, - x, - y, - 0); - - } - else - { - int xsize = 1 << (supracan_vram[i+1] & 7); - int ysize = ((supracan_vram[i+0] & 0x1e00) >> 9) + 1; - - // I think the xsize must influence the ysize somehow, there are too many conflicting cases otherwise - // there don't appear to be any special markers in the actual looked up tile data to indicate skip / end of list - - for(int ytile = 0; ytile < ysize; ytile++) - { - for(int xtile = 0; xtile< xsize; xtile++) - { - UINT16 data = supracan_vram[(sprite_offset+ytile*xsize+xtile)&VRAM_MASK]; - int tile = (bank * 0x200) + (data & 0x03ff); - int palette = (data & 0xf000) >> 12; - - int xpos, ypos; - - if (!sprite_yflip) - { - ypos = y + ytile*8; - } - else - { - ypos = y - (ytile+1)*8; - ypos += ysize*8; - } - - if (!sprite_xflip) - { - xpos = x + xtile*8; - } - else - { - xpos = x - (xtile+1)*8; - xpos += xsize*8; - } - - int tile_xflip = sprite_xflip ^ ((data & 0x0800)>>11); - int tile_yflip = sprite_yflip ^ ((data & 0x0400)>>10); - - gfx->transpen(bitmap,cliprect,tile,palette,tile_xflip,tile_yflip,xpos,ypos,0); - } - } - } - -#if 0 - if(xscale == 0) continue; - UINT32 delta = (1 << 17) / xscale; - for(int sy = 0; sy < ysize*8; sy++) - { - UINT16 *src = &sprite_bitmap->pix16(sy); - UINT16 *dst = &bitmap.pix16(y + sy); - UINT32 dx = x << 16; - for(int sx = 0; sx < xsize*8; sx++) - { - dst[dx >> 16] = src[sx]; - dx += delta; - } - } -#endif - - } - } -} - - - -void supracan_state::mark_active_tilemap_all_dirty(int layer) -{ - int xsize = 0; - int ysize = 0; - - int which_tilemap_size; - - which_tilemap_size = get_tilemap_dimensions(xsize, ysize, layer); -// for (int i=0;i<4;i++) -// tilemap_mark_all_tiles_dirty(m_tilemap_sizes[layer][i]); - m_tilemap_sizes[layer][which_tilemap_size]->mark_all_dirty(); -} - - - -/* draws ROZ with linescroll OR columnscroll to 16-bit indexed bitmap */ -void supracan_state::supracan_suprnova_draw_roz(bitmap_ind16 &bitmap, const rectangle &cliprect, tilemap_t *tmap, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound/*, int columnscroll, UINT32* scrollram*/, int transmask) -{ - //bitmap_ind16 *destbitmap = bitmap; - bitmap_ind16 &srcbitmap = tmap->pixmap(); - //bitmap_ind16 &srcbitmapflags = tmap->flagsmap(); - const int xmask = srcbitmap.width()-1; - const int ymask = srcbitmap.height()-1; - const int widthshifted = srcbitmap.width() << 16; - const int heightshifted = srcbitmap.height() << 16; - UINT32 cx; - UINT32 cy; - int x; - int sx; - int sy; - int ex; - int ey; - UINT16 *dest; -// UINT8* destflags; -// UINT8 *pri; - //const UINT16 *src; - //const UINT8 *maskptr; - //int destadvance = destbitmap->bpp / 8; - - /* pre-advance based on the cliprect */ - startx += cliprect.min_x * incxx + cliprect.min_y * incyx; - starty += cliprect.min_x * incxy + cliprect.min_y * incyy; - - /* extract start/end points */ - sx = cliprect.min_x; - sy = cliprect.min_y; - ex = cliprect.max_x; - ey = cliprect.max_y; - - { - /* loop over rows */ - while (sy <= ey) - { - /* initialize X counters */ - x = sx; - cx = startx; - cy = starty; - - /* get dest and priority pointers */ - dest = &bitmap.pix16(sy, sx); - //destflags = &bitmapflags->pix8(sy, sx); - - /* loop over columns */ - while (x <= ex) - { - if ((wraparound) || (cx < widthshifted && cy < heightshifted)) // not sure how this will cope with no wraparound, but row/col scroll.. - { - #if 0 - if (columnscroll) - { - int scroll = 0;//scrollram[(cx>>16)&0x3ff]); - - - UINT16 data = &srcbitmap.pix16( - ((cy >> 16) - scroll) & ymask, - (cx >> 16) & xmask)[0]; - - if ((data & transmask)!=0) - dest[0] = data; - - //destflags[0] = &srcbitmapflags.pix8(((cy >> 16) - scrollram[(cx>>16)&0x3ff]) & ymask, (cx >> 16) & xmask)[0]; - } - else - #endif - { - int scroll = 0;//scrollram[(cy>>16)&0x3ff]); - UINT16 data = srcbitmap.pix16( - (cy >> 16) & ymask, - ((cx >> 16) - scroll) & xmask); - - - if ((data & transmask)!=0) - dest[0] = data; - - //destflags[0] = &srcbitmapflags.pix8((cy >> 16) & ymask, ((cx >> 16) - scrollram[(cy>>16)&0x3ff]) & xmask)[0]; - } - } - - /* advance in X */ - cx += incxx; - cy += incxy; - x++; - dest++; -// destflags++; -// pri++; - } - - /* advance in Y */ - startx += incyx; - starty += incyy; - sy++; - } - } -} - - -// VIDEO FLAGS ROZ MODE TILEMAP FLAGS -// -// Bit Bit Bit -// 15-9: Unknown 15-13: Priority? 15-13: Priority? -// 8: X ht. (256/320) 12: Unknown 12: Unknown -// 7: Tilemap 0 enable 11-8: Dims 11-8: Dims -// 6: Tilemap 1 enable 7-6: Unknown 7-6: Unknown -// 5: Tilemap 2 enable? 5: Wrap 5: Wrap -// 3: Sprite enable 4-2: Unknown 4-2: Mosaic -// 2: ROZ enable 1-0: Bit Depth 1-0: Bit Depth -// 1-0: Unknown - -// Video Flags ROZ Mode Tilemap 0 Tilemap 1 Tilemap 2 VF Unk0 -// A'Can logo: 120e: 0001 0010 0000 1110 4020: 0100 0000 0010 0000 4620 ---- ---- 0x09 -// Boomzoo Intro: 9a82: 1001 1010 1000 0010 0402: 0000 0100 0000 0010 6400 6400 4400 0x4d -// Boomzoo Title: 9acc: 1001 1010 1100 1100 0402: 0000 0100 0000 0010 6400 6400 4400 0x4d -// C.U.G. Intro: 11c8: 0001 0001 1100 1000 0402: 0000 0100 0000 0010 2400 4400 6400 0x08 -// C.U.G. Title: 11cc: 0001 0001 1100 1100 0602: 0000 0110 0000 0010 2600 4600 ---- 0x08 -// Speedy Dragon Logo: 0388: 0000 0011 1000 1000 4020: 0100 0000 0010 0000 6c20 6c20 2600 0x01 -// Speedy Dragon Title: 038c: 0000 0011 1000 1100 2603: 0010 0110 0000 0011 6c20 2c20 2600 0x01 -// Sango Fighter Intro: 03c8: 0000 0011 1100 1000 ----: ---- ---- ---- ---- 6c20 4620 ---- 0x01 -// Sango Fighter Game: 03ce: 0000 0011 1100 1110 0622: 0000 0110 0010 0010 2620 4620 ---- 0x01 - -UINT32 supracan_state::screen_update_supracan(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - // treat the sprites as frame-buffered and only update the buffer when drawing scanline 0 - this might not be true! - - if (0) - { - if (cliprect.min_y == 0x00) - { - const rectangle &visarea = screen.visible_area(); - - m_sprite_final_bitmap.fill(0x00, visarea); - bitmap.fill(0x80, visarea); - - draw_sprites( m_sprite_final_bitmap, visarea); - } - } - else - { - m_sprite_final_bitmap.fill(0x00, cliprect); - bitmap.fill(0x80, cliprect); - - draw_sprites(m_sprite_final_bitmap, cliprect); - } - - - - // mix screen - int xsize = 0, ysize = 0; -// int tilemap_num; - int which_tilemap_size; - int priority = 0; - - - for (int pri=7;pri>=0;pri--) - { - for (int layer = 3; layer >=0; layer--) - { - // popmessage("%04x\n",m_video_flags); - int enabled = 0; - - if(m_video_flags & 0x04) - if (layer==3) enabled = 1; - - if(m_video_flags & 0x80) - if (layer==0) enabled = 1; - - if(m_video_flags & 0x40) - if (layer==1) enabled = 1; - - if(m_video_flags & 0x20) - if (layer==2) enabled = 1; - - - if (layer==3) priority = ((m_roz_mode >> 13) & 7); // roz case - else priority = ((m_tilemap_flags[layer] >> 13) & 7); // normal cases - - - if (priority==pri) - { -// tilemap_num = layer; - which_tilemap_size = get_tilemap_dimensions(xsize, ysize, layer); - bitmap_ind16 &src_bitmap = m_tilemap_sizes[layer][which_tilemap_size]->pixmap(); - int gfx_region = supracan_tilemap_get_region(layer); - int transmask = 0xff; - - switch (gfx_region) - { - case 0:transmask = 0xff; break; - case 1:transmask = 0x0f; break; - case 2:transmask = 0x03; break; - case 3:transmask = 0x01; break; - case 4:transmask = 0x01; break; - } - - if (enabled) - { - if (layer != 3) // standard layers, NOT roz - { - int wrap = (m_tilemap_flags[layer] & 0x20); - - int scrollx = m_tilemap_scrollx[layer]; - int scrolly = m_tilemap_scrolly[layer]; - - if (scrollx&0x8000) scrollx-= 0x10000; - if (scrolly&0x8000) scrolly-= 0x10000; - - int mosaic_count = (m_tilemap_flags[layer] & 0x001c) >> 2; - int mosaic_mask = 0xffffffff << mosaic_count; - - int y,x; - // yes, it will draw a single line if you specify a cliprect as such (partial updates...) - - for (y=cliprect.min_y;y<=cliprect.max_y;y++) - { - // these will have to change to ADDR32 etc. once alpha blending is supported - UINT16* screen = &bitmap.pix16(y); - - int actualy = y&mosaic_mask; - - int realy = actualy+scrolly; - - if (!wrap) - if (scrolly+y < 0 || scrolly+y > ((ysize*8)-1)) - continue; - - - UINT16* src = &src_bitmap.pix16((realy)&((ysize*8)-1)); - - for (x=cliprect.min_x;x<=cliprect.max_x;x++) - { - int actualx = x & mosaic_mask; - int realx = actualx+scrollx; - - if (!wrap) - if (scrollx+x < 0 || scrollx+x > ((xsize*8)-1)) - continue; - - UINT16 srcpix = src[(realx)&((xsize*8)-1)]; - - if ((srcpix & transmask) != 0) - screen[x] = srcpix; - } - } - } - else - { - int wrap = m_roz_mode & 0x20; - - int incxx = (m_roz_coeffa); - int incyy = (m_roz_coeffd); - - int incxy = (m_roz_coeffc); - int incyx = (m_roz_coeffb); - - int scrollx = (m_roz_scrollx); - int scrolly = (m_roz_scrolly); - - - - - - - if (incyx & 0x8000) incyx -= 0x10000; - if (incxy & 0x8000) incxy -= 0x10000; - - if (incyy & 0x8000) incyy -= 0x10000; - if (incxx & 0x8000) incxx -= 0x10000; - - //popmessage("%04x %04x\n",m_video_flags, m_roz_mode); - - // roz mode.. - //4020 = enabled speedyd - //6c22 = enabled speedyd - //2c22 = enabled speedyd - //4622 = disabled jttlaugh - //2602 = disabled monopoly - //0402 = disabled (sango title) - // or is it always enabled, and only corrupt because we don't clear ram properly? - // (probably not this register?) - - if (!(m_roz_mode & 0x0200) && (m_roz_mode&0xf000) ) // HACK - Not Trusted, Acan Logo, Speedy Dragon Intro ,Speed Dragon Bonus stage need it. Monopoly and JTT *don't* causes graphical issues - { - // NOT accurate, causes issues when the attract mode loops and the logo is shown the 2nd time in some games - investigate - for (int y=cliprect.min_y;y<=cliprect.max_y;y++) - { - rectangle clip(cliprect.min_x, cliprect.max_x, y, y); - - scrollx = (m_roz_scrollx); - scrolly = (m_roz_scrolly); - incxx = (m_roz_coeffa); - - incxx += m_vram[m_roz_unk_base0/2 + y]; - - scrollx += m_vram[m_roz_unk_base1/2 + y*2] << 16; - scrollx += m_vram[m_roz_unk_base1/2 + y*2 + 1]; - - scrolly += m_vram[m_roz_unk_base2/2 + y*2] << 16; - scrolly += m_vram[m_roz_unk_base2/2 + y*2 + 1]; - - if (incxx & 0x8000) incxx -= 0x10000; - - - if (m_vram[m_roz_unk_base0/2 + y]) // incxx = 0, no draw? - supracan_suprnova_draw_roz(bitmap, clip, m_tilemap_sizes[layer][which_tilemap_size], scrollx<<8, scrolly<<8, incxx<<8, incxy<<8, incyx<<8, incyy<<8, wrap, transmask); - } - } - else - { - supracan_suprnova_draw_roz(bitmap, cliprect, m_tilemap_sizes[layer][which_tilemap_size], scrollx<<8, scrolly<<8, incxx<<8, incxy<<8, incyx<<8, incyy<<8, wrap, transmask); - } - } - } - } - } - } - - - // just draw the sprites on top for now - if(m_video_flags & 0x08) - { - for (int y=cliprect.min_y;y<=cliprect.max_y;y++) - { - UINT16* src = &m_sprite_final_bitmap.pix16(y); - UINT16* dst = &bitmap.pix16(y); - - for (int x=cliprect.min_x;x<=cliprect.max_x;x++) - { - UINT16 dat = src[x]; - if (dat) dst[x] = dat; - } - } - } - - return 0; -} - - -void supracan_state::dma_w(address_space &space, int offset, UINT16 data, UINT16 mem_mask, int ch) -{ - acan_dma_regs_t *acan_dma_regs = &m_acan_dma_regs; - address_space &mem = m_maincpu->space(AS_PROGRAM); - - switch(offset) - { - case 0x00/2: // Source address MSW - verboselog("maincpu", 0, "dma_w: source msw %d: %04x\n", ch, data); - acan_dma_regs->source[ch] &= 0x0000ffff; - acan_dma_regs->source[ch] |= data << 16; - break; - case 0x02/2: // Source address LSW - verboselog("maincpu", 0, "dma_w: source lsw %d: %04x\n", ch, data); - acan_dma_regs->source[ch] &= 0xffff0000; - acan_dma_regs->source[ch] |= data; - break; - case 0x04/2: // Destination address MSW - verboselog("maincpu", 0, "dma_w: dest msw %d: %04x\n", ch, data); - acan_dma_regs->dest[ch] &= 0x0000ffff; - acan_dma_regs->dest[ch] |= data << 16; - break; - case 0x06/2: // Destination address LSW - verboselog("maincpu", 0, "dma_w: dest lsw %d: %04x\n", ch, data); - acan_dma_regs->dest[ch] &= 0xffff0000; - acan_dma_regs->dest[ch] |= data; - break; - case 0x08/2: // Byte count - verboselog("maincpu", 0, "dma_w: count %d: %04x\n", ch, data); - acan_dma_regs->count[ch] = data; - break; - case 0x0a/2: // Control - verboselog("maincpu", 0, "dma_w: control %d: %04x\n", ch, data); - if(data & 0x8800) - { -// if(data & 0x2000) -// acan_dma_regs->source-=2; - logerror("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); - - for(int i = 0; i <= acan_dma_regs->count[ch]; i++) - { - if(data & 0x1000) - { - mem.write_word(acan_dma_regs->dest[ch], mem.read_word(acan_dma_regs->source[ch])); - acan_dma_regs->dest[ch]+=2; - acan_dma_regs->source[ch]+=2; - if(data & 0x0100) - if((acan_dma_regs->dest[ch] & 0xf) == 0) - acan_dma_regs->dest[ch]-=0x10; - } - else - { - mem.write_byte(acan_dma_regs->dest[ch], mem.read_byte(acan_dma_regs->source[ch])); - acan_dma_regs->dest[ch]++; - acan_dma_regs->source[ch]++; - } - } - } - else if(data != 0x0000) // fake DMA, used by C.U.G. - { - verboselog("maincpu", 0, "dma_w: Unknown DMA kickoff value of %04x (other regs %08x, %08x, %d)\n", data, acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1); - fatalerror("dma_w: Unknown DMA kickoff value of %04x (other regs %08x, %08x, %d)\n",data, acan_dma_regs->source[ch], acan_dma_regs->dest[ch], acan_dma_regs->count[ch] + 1); - } - break; - default: - verboselog("maincpu", 0, "dma_w: Unknown register: %08x = %04x & %04x\n", 0xe90020 + (offset << 1), data, mem_mask); - break; - } -} - -WRITE16_MEMBER( supracan_state::dma_channel0_w ) -{ - dma_w(space, offset, data, mem_mask, 0); -} - -WRITE16_MEMBER( supracan_state::dma_channel1_w ) -{ - dma_w(space, offset, data, mem_mask, 1); -} - - -#if 0 -WRITE16_MEMBER( supracan_state::supracan_pram_w ) -{ - m_pram[offset] &= ~mem_mask; - m_pram[offset] |= data & mem_mask; -} -#endif - -// swap address around so that 64x64 tile can be decoded as 8x8 tiles.. -void supracan_state::write_swapped_byte( int offset, UINT8 byte ) -{ - int swapped_offset = BITSWAP32(offset, 31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,2,1,0,6,5,4,3); - - m_vram_addr_swapped[swapped_offset] = byte; -} - -WRITE16_MEMBER( supracan_state::vram_w ) -{ - COMBINE_DATA(&m_vram[offset]); - - // hack for 1bpp layer at startup - write_swapped_byte(offset*2, (data & 0xff00)>>8); - write_swapped_byte(offset*2+1, (data & 0x00ff)); - - // mark tiles of each depth as dirty - m_gfxdecode->gfx(0)->mark_dirty((offset*2)/(64)); - m_gfxdecode->gfx(1)->mark_dirty((offset*2)/(32)); - m_gfxdecode->gfx(2)->mark_dirty((offset*2)/(16)); - m_gfxdecode->gfx(3)->mark_dirty((offset*2)/(512)); - m_gfxdecode->gfx(4)->mark_dirty((offset*2)/(8)); - -} - -static ADDRESS_MAP_START( supracan_mem, AS_PROGRAM, 16, supracan_state ) - //AM_RANGE( 0x000000, 0x3fffff ) // mapped by the cartslot - AM_RANGE( 0xe80200, 0xe80201 ) AM_READ_PORT("P1") - AM_RANGE( 0xe80202, 0xe80203 ) AM_READ_PORT("P2") - AM_RANGE( 0xe80208, 0xe80209 ) AM_READ_PORT("P3") - AM_RANGE( 0xe8020c, 0xe8020d ) AM_READ_PORT("P4") - AM_RANGE( 0xe80000, 0xe8ffff ) AM_READWRITE(_68k_soundram_r, _68k_soundram_w) - AM_RANGE( 0xe90000, 0xe9001f ) AM_READWRITE(sound_r, sound_w) - AM_RANGE( 0xe90020, 0xe9002f ) AM_WRITE(dma_channel0_w) - AM_RANGE( 0xe90030, 0xe9003f ) AM_WRITE(dma_channel1_w) - - AM_RANGE( 0xf00000, 0xf001ff ) AM_READWRITE(video_r, video_w) - AM_RANGE( 0xf00200, 0xf003ff ) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") - AM_RANGE( 0xf40000, 0xf5ffff ) AM_RAM_WRITE(vram_w) AM_SHARE("vram") - AM_RANGE( 0xfc0000, 0xfdffff ) AM_MIRROR(0x30000) AM_RAM /* System work ram */ -ADDRESS_MAP_END - -READ8_MEMBER( supracan_state::_6502_soundmem_r ) -{ - address_space &mem = m_maincpu->space(AS_PROGRAM); - UINT8 data = m_soundram[offset]; - - switch(offset) - { -#if SOUNDCPU_BOOT_HACK - case 0x300: // HACK to make games think the sound CPU is always reporting 'OK'. - return 0xff; -#endif - - case 0x410: // Sound IRQ enable - data = m_sound_irq_enable_reg; - if(!mem.debugger_access()) verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 0, "supracan_soundreg_r: IRQ enable: %04x\n", data); - if(!mem.debugger_access()) - { - if(m_sound_irq_enable_reg & m_sound_irq_source_reg) - { - m_soundcpu->set_input_line(0, ASSERT_LINE); - } - else - { - m_soundcpu->set_input_line(0, CLEAR_LINE); - } - } - break; - case 0x411: // Sound IRQ source - data = m_sound_irq_source_reg; - m_sound_irq_source_reg = 0; - if(!mem.debugger_access()) verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 3, "supracan_soundreg_r: IRQ source: %04x\n", data); - if(!mem.debugger_access()) - { - m_soundcpu->set_input_line(0, CLEAR_LINE); - } - break; - case 0x420: - if(!mem.debugger_access()) verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 3, "supracan_soundreg_r: Sound hardware status? (not yet implemented): %02x\n", 0); - break; - case 0x422: - if(!mem.debugger_access()) verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 3, "supracan_soundreg_r: Sound hardware data? (not yet implemented): %02x\n", 0); - break; - case 0x404: - case 0x405: - case 0x409: - case 0x414: - case 0x416: - // Intentional fall-through - default: - if(offset >= 0x300 && offset < 0x500) - { - if(!mem.debugger_access()) verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 0, "supracan_soundreg_r: Unknown register %04x\n", offset); - } - break; - } - - return data; -} - -WRITE8_MEMBER( supracan_state::_6502_soundmem_w ) -{ - switch(offset) - { - case 0x407: - if(m_sound_cpu_68k_irq_reg &~ data) - { - verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 0, "supracan_soundreg_w: sound_cpu_68k_irq_reg: %04x: Triggering M68k IRQ\n", data); - m_maincpu->set_input_line(7, HOLD_LINE); - } - else - { - verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 0, "supracan_soundreg_w: sound_cpu_68k_irq_reg: %04x\n", data); - } - m_sound_cpu_68k_irq_reg = data; - break; - case 0x410: - m_sound_irq_enable_reg = data; - verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 0, "supracan_soundreg_w: IRQ enable: %02x\n", data); - break; - case 0x420: - verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 3, "supracan_soundreg_w: Sound hardware reg data? (not yet implemented): %02x\n", data); - break; - case 0x422: - verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 3, "supracan_soundreg_w: Sound hardware reg addr? (not yet implemented): %02x\n", data); - break; - default: - if(offset >= 0x300 && offset < 0x500) - { - verboselog(m_hack_68k_to_6502_access ? "maincpu" : "soundcpu", 0, "supracan_soundreg_w: Unknown register %04x = %02x\n", offset, data); - } - m_soundram[offset] = data; - break; - } -} - -static ADDRESS_MAP_START( supracan_sound_mem, AS_PROGRAM, 8, supracan_state ) - AM_RANGE(0x0000, 0xffff) AM_READWRITE(_6502_soundmem_r, _6502_soundmem_w) AM_SHARE("soundram") -ADDRESS_MAP_END - -static INPUT_PORTS_START( supracan ) - PORT_START("P1") - PORT_DIPNAME( 0x01, 0x00, "SYSTEM" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(1) PORT_NAME("P1 Button R") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_NAME("P1 Button L") - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 Button Y") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Button X") - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_NAME("P1 Joypad Right") - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_NAME("P1 Joypad Left") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_NAME("P1 Joypad Down") - PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_NAME("P1 Joypad Up") - PORT_DIPNAME( 0x1000, 0x0000, "SYSTEM" ) - PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( On ) ) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_START1 ) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Button B") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Button A") - - PORT_START("P2") - PORT_DIPNAME( 0x01, 0x00, "SYSTEM" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(2) PORT_NAME("P2 Button R") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(2) PORT_NAME("P2 Button L") - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 Button Y") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Button X") - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_NAME("P2 Joypad Right") - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_NAME("P2 Joypad Left") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_NAME("P2 Joypad Down") - PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_NAME("P2 Joypad Up") - PORT_DIPNAME( 0x1000, 0x0000, "SYSTEM" ) - PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( On ) ) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_START2 ) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Button B") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Button A") - - PORT_START("P3") - PORT_DIPNAME( 0x01, 0x00, "SYSTEM" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(3) PORT_NAME("P3 Button R") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(3) PORT_NAME("P3 Button L") - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(3) PORT_NAME("P3 Button Y") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 Button X") - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) PORT_NAME("P3 Joypad Right") - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) PORT_NAME("P3 Joypad Left") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3) PORT_NAME("P3 Joypad Down") - PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(3) PORT_NAME("P3 Joypad Up") - PORT_DIPNAME( 0x1000, 0x0000, "SYSTEM" ) - PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( On ) ) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_START3 ) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 Button B") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 Button A") - - PORT_START("P4") - PORT_DIPNAME( 0x01, 0x00, "SYSTEM" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_PLAYER(4) PORT_NAME("P4 Button R") - PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(4) PORT_NAME("P4 Button L") - PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(4) PORT_NAME("P4 Button Y") - PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(4) PORT_NAME("P4 Button X") - PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4) PORT_NAME("P4 Joypad Right") - PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4) PORT_NAME("P4 Joypad Left") - PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4) PORT_NAME("P4 Joypad Down") - PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_PLAYER(4) PORT_NAME("P4 Joypad Up") - PORT_DIPNAME( 0x1000, 0x0000, "SYSTEM" ) - PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( On ) ) - PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_START4 ) - PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(4) PORT_NAME("P4 Button B") - PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 Button A") -INPUT_PORTS_END - -PALETTE_INIT_MEMBER(supracan_state, supracan) -{ - // Used for debugging purposes for now - //#if 0 - int i, r, g, b; - - for( i = 0; i < 32768; i++ ) - { - r = (i & 0x1f) << 3; - g = ((i >> 5) & 0x1f) << 3; - b = ((i >> 10) & 0x1f) << 3; - palette.set_pen_color( i, r, g, b ); - } - //#endif -} - -WRITE16_MEMBER( supracan_state::_68k_soundram_w ) -{ - address_space &mem = m_maincpu->space(AS_PROGRAM); - m_soundram[offset*2 + 1] = data & 0xff; - m_soundram[offset*2 + 0] = data >> 8; - - if(offset*2 < 0x500 && offset*2 >= 0x300) - { - if(mem_mask & 0xff00) - { - m_hack_68k_to_6502_access = true; - _6502_soundmem_w(mem, offset*2, data >> 8); - m_hack_68k_to_6502_access = false; - } - if(mem_mask & 0x00ff) - { - m_hack_68k_to_6502_access = true; - _6502_soundmem_w(mem, offset*2 + 1, data & 0xff); - m_hack_68k_to_6502_access = false; - } - } -} - -READ16_MEMBER( supracan_state::_68k_soundram_r ) -{ - address_space &mem = m_maincpu->space(AS_PROGRAM); - UINT16 val = m_soundram[offset*2 + 0] << 8; - val |= m_soundram[offset*2 + 1]; - - if(offset*2 >= 0x300 && offset*2 < 0x500) - { - val = 0; - if(mem_mask & 0xff00) - { - m_hack_68k_to_6502_access = true; - val |= _6502_soundmem_r(mem, offset*2) << 8; - m_hack_68k_to_6502_access = false; - } - if(mem_mask & 0x00ff) - { - m_hack_68k_to_6502_access = true; - val |= _6502_soundmem_r(mem, offset*2 + 1); - m_hack_68k_to_6502_access = false; - } - } - - return val; -} - -READ16_MEMBER( supracan_state::sound_r ) -{ - UINT16 data = 0; - - switch( offset ) - { - default: - verboselog("maincpu", 0, "sound_r: Unknown register: (%08x) & %04x\n", 0xe90000 + (offset << 1), mem_mask); - break; - } - - return data; -} - -WRITE16_MEMBER( supracan_state::sound_w ) -{ - switch ( offset ) - { - case 0x000a/2: /* Sound cpu IRQ request. */ - m_soundcpu->set_input_line(0, ASSERT_LINE); - break; - case 0x001c/2: /* Sound cpu control. Bit 0 tied to sound cpu RESET line */ - if(data & 0x01) - { - if(!m_m6502_reset) - { - /* Reset and enable the sound cpu */ -#if !(SOUNDCPU_BOOT_HACK) - m_soundcpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); - m_soundcpu->reset(); -#endif - } - m_m6502_reset = data & 0x01; - } - else - { - /* Halt the sound cpu */ - m_soundcpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); - } - verboselog("maincpu", 0, "sound cpu ctrl: %04x\n", data); - break; - default: - verboselog("maincpu", 0, "sound_w: Unknown register: %08x = %04x & %04x\n", 0xe90000 + (offset << 1), data, mem_mask); - break; - } -} - - -READ16_MEMBER( supracan_state::video_r ) -{ - address_space &mem = m_maincpu->space(AS_PROGRAM); - UINT16 data = m_video_regs[offset]; - - switch(offset) - { - case 0x00/2: // Video IRQ flags - if(!mem.debugger_access()) - { - //verboselog("maincpu", 0, "read video IRQ flags (%04x)\n", data); - m_maincpu->set_input_line(7, CLEAR_LINE); - } - break; - case 0x02/2: // Current scanline - break; - case 0x08/2: // Unknown (not video flags!) - gambling lord disagrees, it MUST read back what it wrote because it reads it before turning on/off layers and writes it back - //data = 0; - break; - case 0x100/2: - if(!mem.debugger_access()) verboselog("maincpu", 0, "read tilemap_flags[0] (%04x)\n", data); - break; - case 0x106/2: - if(!mem.debugger_access()) verboselog("maincpu", 0, "read tilemap_scrolly[0] (%04x)\n", data); - break; - case 0x120/2: - if(!mem.debugger_access()) verboselog("maincpu", 0, "read tilemap_flags[1] (%04x)\n", data); - break; - default: - if(!mem.debugger_access()) verboselog("maincpu", 0, "video_r: Unknown register: %08x (%04x & %04x)\n", 0xf00000 + (offset << 1), data, mem_mask); - break; - } - - return data; -} - -TIMER_CALLBACK_MEMBER(supracan_state::supracan_hbl_callback) -{ - m_maincpu->set_input_line(3, HOLD_LINE); - - m_hbl_timer->adjust(attotime::never); -} - -TIMER_CALLBACK_MEMBER(supracan_state::supracan_line_on_callback) -{ - m_maincpu->set_input_line(5, HOLD_LINE); - - m_line_on_timer->adjust(attotime::never); -} - -TIMER_CALLBACK_MEMBER(supracan_state::supracan_line_off_callback) -{ - m_maincpu->set_input_line(5, CLEAR_LINE); - - m_line_on_timer->adjust(attotime::never); -} - -TIMER_CALLBACK_MEMBER(supracan_state::supracan_video_callback) -{ - int vpos = machine().first_screen()->vpos(); - - m_video_regs[0] &= ~0x0002; - - switch( vpos ) - { - case 0: - m_video_regs[0] &= 0x7fff; - - // we really need better management of this - mark_active_tilemap_all_dirty(0); - mark_active_tilemap_all_dirty(1); - mark_active_tilemap_all_dirty(2); - mark_active_tilemap_all_dirty(3); - - - break; - - case 224://FIXME: Son of Evil is pretty picky about this one, a timing of 240 makes it to crash - m_video_regs[0] |= 0x8000; - break; - - case 240: - if(m_irq_mask & 1) - { - verboselog("maincpu", 0, "Triggering VBL IRQ\n\n"); - m_maincpu->set_input_line(7, HOLD_LINE); - } - break; - } - - m_video_regs[1] = machine().first_screen()->vpos()-16; // for son of evil, wants vblank active around 224 instead... - - m_hbl_timer->adjust( machine().first_screen()->time_until_pos( vpos, 320 ) ); - m_video_timer->adjust( machine().first_screen()->time_until_pos( ( vpos + 1 ) % 256, 0 ) ); -} - -WRITE16_MEMBER( supracan_state::video_w ) -{ - address_space &mem = m_maincpu->space(AS_PROGRAM); - acan_sprdma_regs_t *acan_sprdma_regs = &m_acan_sprdma_regs; - int i; - - // if any of this changes we need a partial update (see sango fighters intro) - machine().first_screen()->update_partial(machine().first_screen()->vpos()); - - COMBINE_DATA(&m_video_regs[offset]); - data = m_video_regs[offset]; - - switch(offset) - { - case 0x10/2: // Byte count - verboselog("maincpu", 0, "sprite dma word count: %04x\n", data); - acan_sprdma_regs->count = data; - break; - case 0x12/2: // Destination address MSW - acan_sprdma_regs->dst &= 0x0000ffff; - acan_sprdma_regs->dst |= data << 16; - verboselog("maincpu", 0, "sprite dma dest msw: %04x\n", data); - break; - case 0x14/2: // Destination address LSW - acan_sprdma_regs->dst &= 0xffff0000; - acan_sprdma_regs->dst |= data; - verboselog("maincpu", 0, "sprite dma dest lsw: %04x\n", data); - break; - case 0x16/2: // Source word increment - verboselog("maincpu", 0, "sprite dma dest word inc: %04x\n", data); - acan_sprdma_regs->dst_inc = data; - break; - case 0x18/2: // Source address MSW - acan_sprdma_regs->src &= 0x0000ffff; - acan_sprdma_regs->src |= data << 16; - verboselog("maincpu", 0, "sprite dma src msw: %04x\n", data); - break; - case 0x1a/2: // Source address LSW - verboselog("maincpu", 0, "sprite dma src lsw: %04x\n", data); - acan_sprdma_regs->src &= 0xffff0000; - acan_sprdma_regs->src |= data; - break; - case 0x1c/2: // Source word increment - verboselog("maincpu", 0, "sprite dma src word inc: %04x\n", data); - acan_sprdma_regs->src_inc = data; - break; - case 0x1e/2: - logerror( "video_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, data); - - /* TODO: what's 0x2000 and 0x4000 for? */ - if(data & 0x8000) - { - if(data & 0x2000 || data & 0x4000) - { - acan_sprdma_regs->dst |= 0xf40000; - } - - if(data & 0x2000) - { - //acan_sprdma_regs->count <<= 1; - } - - for(i = 0; i <= acan_sprdma_regs->count; i++) - { - if(data & 0x0100) //dma 0x00 fill (or fixed value?) - { - mem.write_word(acan_sprdma_regs->dst, 0); - acan_sprdma_regs->dst+=2 * acan_sprdma_regs->dst_inc; - //memset(supracan_vram,0x00,0x020000); - } - else - { - mem.write_word(acan_sprdma_regs->dst, mem.read_word(acan_sprdma_regs->src)); - acan_sprdma_regs->dst+=2 * acan_sprdma_regs->dst_inc; - acan_sprdma_regs->src+=2 * acan_sprdma_regs->src_inc; - } - } - } - else - { - verboselog("maincpu", 0, "dma_w: Attempting to kick off a DMA without bit 15 set! (%04x)\n", data); - } - break; - case 0x08/2: - { - verboselog("maincpu", 3, "video_flags = %04x\n", data); - m_video_flags = data; - - rectangle visarea = machine().first_screen()->visible_area(); - - visarea.set(0, ((m_video_flags & 0x100) ? 320 : 256) - 1, 8, 232 - 1); - machine().first_screen()->configure(348, 256, visarea, machine().first_screen()->frame_period().attoseconds()); - } - break; - case 0x0a/2: - { - // raster interrupt - verboselog("maincpu", 0, "IRQ Trigger? = %04x\n", data); - if(data & 0x8000) - { - m_line_on_timer->adjust(machine().first_screen()->time_until_pos((data & 0x00ff), 0)); - } - else - { - m_line_on_timer->adjust(attotime::never); - } - } - break; - - case 0x0c/2: - { - verboselog("maincpu", 0, "IRQ De-Trigger? = %04x\n", data); - if(data & 0x8000) - { - m_line_off_timer->adjust(machine().first_screen()->time_until_pos(data & 0x00ff, 0)); - } - else - { - m_line_off_timer->adjust(attotime::never); - } - } - break; - - /* Sprites */ - case 0x20/2: m_sprite_base_addr = data << 2; verboselog("maincpu", 0, "sprite_base_addr = %04x\n", data); break; - case 0x22/2: m_sprite_count = data+1; verboselog("maincpu", 0, "sprite_count = %d\n", data+1); break; - case 0x26/2: m_sprite_flags = data; verboselog("maincpu", 0, "sprite_flags = %04x\n", data); break; - - /* Tilemap 0 */ - case 0x100/2: m_tilemap_flags[0] = data; verboselog("maincpu", 3, "tilemap_flags[0] = %04x\n", data); break; - case 0x104/2: m_tilemap_scrollx[0] = data; verboselog("maincpu", 3, "tilemap_scrollx[0] = %04x\n", data); break; - case 0x106/2: m_tilemap_scrolly[0] = data; verboselog("maincpu", 3, "tilemap_scrolly[0] = %04x\n", data); break; - case 0x108/2: m_tilemap_base_addr[0] = (data) << 1; verboselog("maincpu", 3, "tilemap_base_addr[0] = %05x\n", data << 2); break; - case 0x10a/2: m_tilemap_mode[0] = data; verboselog("maincpu", 3, "tilemap_mode[0] = %04x\n", data); break; - - /* Tilemap 1 */ - case 0x120/2: m_tilemap_flags[1] = data; verboselog("maincpu", 3, "tilemap_flags[1] = %04x\n", data); break; - case 0x124/2: m_tilemap_scrollx[1] = data; verboselog("maincpu", 3, "tilemap_scrollx[1] = %04x\n", data); break; - case 0x126/2: m_tilemap_scrolly[1] = data; verboselog("maincpu", 3, "tilemap_scrolly[1] = %04x\n", data); break; - case 0x128/2: m_tilemap_base_addr[1] = (data) << 1; verboselog("maincpu", 3, "tilemap_base_addr[1] = %05x\n", data << 2); break; - case 0x12a/2: m_tilemap_mode[1] = data; verboselog("maincpu", 3, "tilemap_mode[1] = %04x\n", data); break; - - /* Tilemap 2? */ - case 0x140/2: m_tilemap_flags[2] = data; verboselog("maincpu", 0, "tilemap_flags[2] = %04x\n", data); break; - case 0x144/2: m_tilemap_scrollx[2] = data; verboselog("maincpu", 0, "tilemap_scrollx[2] = %04x\n", data); break; - case 0x146/2: m_tilemap_scrolly[2] = data; verboselog("maincpu", 0, "tilemap_scrolly[2] = %04x\n", data); break; - case 0x148/2: m_tilemap_base_addr[2] = (data) << 1; verboselog("maincpu", 0, "tilemap_base_addr[2] = %05x\n", data << 2); break; - case 0x14a/2: m_tilemap_mode[2] = data; verboselog("maincpu", 0, "tilemap_mode[2] = %04x\n", data); break; - - /* ROZ */ - case 0x180/2: m_roz_mode = data; verboselog("maincpu", 3, "roz_mode = %04x\n", data); break; - case 0x184/2: m_roz_scrollx = (data << 16) | (m_roz_scrollx & 0xffff); m_roz_changed |= 1; verboselog("maincpu", 3, "roz_scrollx = %08x\n", m_roz_scrollx); break; - case 0x186/2: m_roz_scrollx = (data) | (m_roz_scrollx & 0xffff0000); m_roz_changed |= 1; verboselog("maincpu", 3, "roz_scrollx = %08x\n", m_roz_scrollx); break; - case 0x188/2: m_roz_scrolly = (data << 16) | (m_roz_scrolly & 0xffff); m_roz_changed |= 2; verboselog("maincpu", 3, "roz_scrolly = %08x\n", m_roz_scrolly); break; - case 0x18a/2: m_roz_scrolly = (data) | (m_roz_scrolly & 0xffff0000); m_roz_changed |= 2; verboselog("maincpu", 3, "roz_scrolly = %08x\n", m_roz_scrolly); break; - case 0x18c/2: m_roz_coeffa = data; verboselog("maincpu", 3, "roz_coeffa = %04x\n", data); break; - case 0x18e/2: m_roz_coeffb = data; verboselog("maincpu", 3, "roz_coeffb = %04x\n", data); break; - case 0x190/2: m_roz_coeffc = data; verboselog("maincpu", 3, "roz_coeffc = %04x\n", data); break; - case 0x192/2: m_roz_coeffd = data; verboselog("maincpu", 3, "roz_coeffd = %04x\n", data); break; - case 0x194/2: m_roz_base_addr = (data) << 1; verboselog("maincpu", 3, "roz_base_addr = %05x\n", data << 2); break; - case 0x196/2: m_roz_tile_bank = data; verboselog("maincpu", 3, "roz_tile_bank = %04x\n", data); break; //tile bank - case 0x198/2: m_roz_unk_base0 = data << 2; verboselog("maincpu", 3, "roz_unk_base0 = %05x\n", data << 2); break; - case 0x19a/2: m_roz_unk_base1 = data << 2; verboselog("maincpu", 3, "roz_unk_base1 = %05x\n", data << 2); break; - case 0x19e/2: m_roz_unk_base2 = data << 2; verboselog("maincpu", 3, "roz_unk_base2 = %05x\n", data << 2); break; - - case 0x1d0/2: m_unk_1d0 = data; verboselog("maincpu", 3, "unk_1d0 = %04x\n", data); break; - - - - - case 0x1f0/2: //FIXME: this register is mostly not understood - m_irq_mask = data;//(data & 8) ? 0 : 1; -#if 0 - if(!m_irq_mask && !m_hbl_mask) - { - m_maincpu->set_input_line(7, CLEAR_LINE); - } -#endif - verboselog("maincpu", 3, "irq_mask = %04x\n", data); - break; - default: - verboselog("maincpu", 0, "video_w: Unknown register: %08x = %04x & %04x\n", 0xf00000 + (offset << 1), data, mem_mask); - break; - } -// m_video_regs[offset] = data; -} - - -DEVICE_IMAGE_LOAD_MEMBER( supracan_state, supracan_cart ) -{ - UINT32 size = m_cart->common_get_size("rom"); - - if (size > 0x400000) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); - return IMAGE_INIT_FAIL; - } - - m_cart->rom_alloc(size, GENERIC_ROM16_WIDTH, ENDIANNESS_BIG); - m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom"); - - return IMAGE_INIT_PASS; -} - - -void supracan_state::machine_start() -{ - m_video_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(supracan_state::supracan_video_callback),this)); - m_hbl_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(supracan_state::supracan_hbl_callback),this)); - m_line_on_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(supracan_state::supracan_line_on_callback),this)); - m_line_off_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(supracan_state::supracan_line_off_callback),this)); - - if (m_cart->exists()) - m_maincpu->space(AS_PROGRAM).install_read_handler(0x000000, 0x3fffff, read16_delegate(FUNC(generic_slot_device::read16_rom),(generic_slot_device*)m_cart)); -} - - -void supracan_state::machine_reset() -{ - m_soundcpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); - - m_video_timer->adjust( machine().first_screen()->time_until_pos( 0, 0 ) ); - m_irq_mask = 0; -} - -/* gfxdecode is retained for reference purposes but not otherwise used by the driver */ -static const gfx_layout supracan_gfx8bpp = -{ - 8,8, - RGN_FRAC(1,1), - 8, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - { STEP8(0,8*8) }, - 8*8*8 -}; - - - -static const gfx_layout supracan_gfx4bpp = -{ - 8,8, - RGN_FRAC(1,1), - 4, - { 0,1,2,3 }, - { 0*4, 1*4, 2*4, 3*4, 4*4, 5*4, 6*4, 7*4 }, - { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 }, - 8*32 -}; - -static const gfx_layout supracan_gfx2bpp = -{ - 8,8, - RGN_FRAC(1,1), - 2, - { 0,1 }, - { 0*2, 1*2, 2*2, 3*2, 4*2, 5*2, 6*2, 7*2 }, - { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, - 8*16 -}; - - -static const UINT32 xtexlayout_xoffset[64] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23, - 24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44, - 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 }; - -static const UINT32 xtexlayout_yoffset[64] = { 0*64,1*64,2*64,3*64,4*64,5*64,6*64,7*64,8*64, - 9*64,10*64,11*64,12*64,13*64,14*64,15*64, - 16*64,17*64,18*64,19*64,20*64,21*64,22*64,23*64, - 24*64,25*64,26*64,27*64,28*64,29*64,30*64,31*64, - 32*64,33*64,34*64,35*64,36*64,37*64,38*64,39*64, - 40*64,41*64,42*64,43*64,44*64,45*64,46*64,47*64, - 48*64,49*64,50*64,51*64,52*64,53*64,54*64,55*64, - 56*64,57*64,58*64,59*64,60*64,61*64,62*64,63*64 }; -static const gfx_layout supracan_gfx1bpp = -{ - 64,64, - RGN_FRAC(1,1), - 1, - { 0 }, - EXTENDED_XOFFS, - EXTENDED_YOFFS, - 64*64, - xtexlayout_xoffset, - xtexlayout_yoffset -}; - -static const gfx_layout supracan_gfx1bpp_alt = -{ - 8,8, - RGN_FRAC(1,1), - 1, - { 0 }, - { 0,1,2,3,4,5,6,7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 -}; - - -static GFXDECODE_START( supracan ) - GFXDECODE_RAM( "vram", 0, supracan_gfx8bpp, 0, 1 ) - GFXDECODE_RAM( "vram", 0, supracan_gfx4bpp, 0, 0x10 ) - GFXDECODE_RAM( "vram", 0, supracan_gfx2bpp, 0, 0x40 ) - GFXDECODE_RAM( "vram", 0, supracan_gfx1bpp, 0, 0x80 ) - GFXDECODE_RAM( "vram", 0, supracan_gfx1bpp_alt, 0, 0x80 ) -GFXDECODE_END - -INTERRUPT_GEN_MEMBER(supracan_state::supracan_irq) -{ -#if 0 - - if(m_irq_mask) - { - device.execute().set_input_line(7, HOLD_LINE); - } -#endif -} - -INTERRUPT_GEN_MEMBER(supracan_state::supracan_sound_irq) -{ - m_sound_irq_source_reg |= 0x80; - - if(m_sound_irq_enable_reg & m_sound_irq_source_reg) - { - m_soundcpu->set_input_line(0, ASSERT_LINE); - } - else - { - m_soundcpu->set_input_line(0, CLEAR_LINE); - } -} - -static MACHINE_CONFIG_START( supracan, supracan_state ) - - MCFG_CPU_ADD( "maincpu", M68000, XTAL_10_738635MHz ) /* Correct frequency unknown */ - MCFG_CPU_PROGRAM_MAP( supracan_mem ) - MCFG_CPU_VBLANK_INT_DRIVER("screen", supracan_state, supracan_irq) - - MCFG_CPU_ADD( "soundcpu", M6502, XTAL_3_579545MHz ) /* TODO: Verify actual clock */ - MCFG_CPU_PROGRAM_MAP( supracan_sound_mem ) - MCFG_CPU_VBLANK_INT_DRIVER("screen", supracan_state, supracan_sound_irq) - -#if !(SOUNDCPU_BOOT_HACK) - MCFG_QUANTUM_PERFECT_CPU("maincpu") - MCFG_QUANTUM_PERFECT_CPU("soundcpu") -#endif - - MCFG_SCREEN_ADD( "screen", RASTER ) - MCFG_SCREEN_RAW_PARAMS(XTAL_10_738635MHz/2, 348, 0, 256, 256, 0, 240 ) /* No idea if this is correct */ - MCFG_SCREEN_UPDATE_DRIVER(supracan_state, screen_update_supracan) - MCFG_SCREEN_PALETTE("palette") - - MCFG_PALETTE_ADD( "palette", 32768 ) - MCFG_PALETTE_FORMAT(xBBBBBGGGGGRRRRR) - MCFG_PALETTE_INIT_OWNER(supracan_state, supracan) - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", supracan) - - MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "supracan_cart") - MCFG_GENERIC_WIDTH(GENERIC_ROM16_WIDTH) - MCFG_GENERIC_ENDIAN(ENDIANNESS_BIG) - MCFG_GENERIC_LOAD(supracan_state, supracan_cart) - - MCFG_SOFTWARE_LIST_ADD("cart_list","supracan") -MACHINE_CONFIG_END - - -ROM_START( supracan ) -ROM_END - - -/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ -CONS( 1995, supracan, 0, 0, supracan, supracan, driver_device, 0, "Funtech Entertainment", "Super A'Can", MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) |