Skip to content

Commit

Permalink
funtech/supracan.cpp: add 128x128 tilemap paging mode, identify a pos…
Browse files Browse the repository at this point in the history
…sible RNG register at $e90018
  • Loading branch information
angelosa committed Sep 12, 2024
1 parent 666278a commit 813c5fe
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 21 deletions.
8 changes: 5 additions & 3 deletions hash/supracan.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ license:CC0-1.0
<publisher>AV Artisan Corp.</publisher>
<notes><![CDATA[
[video] intro uses circular clipping effect
[video] wrong tilemap paging for layer 1 on game over
[sound] noisy channels 13-15 starting from character screen, supposed to release after a while (12 00 0f 79)
game over screen uses a RNG register for rain scroll (verify)
]]></notes>
<info name="serial" value="F001" />
<info name="alt_title" value="福爾摩沙大對決" />
Expand All @@ -29,7 +29,9 @@ license:CC0-1.0
<notes><![CDATA[
[video] sprites may need buffering (noticeable on gameplay jumps, verify)
[video] intro raster effect is slightly off (btanb)
[video] enables clipping effect during ending and credits
[video] rain stage should overlay clip effect over sprites (TODO: fill which character)
[video] 3rd from right stage floor glitches with scroll, [irq 5] related
[video] 9th character ball special attack cuts off 1 tile, [4]12P (numpad notation)
]]></notes>
<info name="serial" value="F002" />
<info name="alt_title" value="三國志 武將爭霸" />
Expand All @@ -47,7 +49,7 @@ license:CC0-1.0
<notes><![CDATA[
Uses [video] blending during attract and title screen
Wrong [video] ROZ paging for title screen
Broken [video] during intro, uses bitmap mode
Broken [video] during intro, uses bitmap mode with ROZ layer
[video] uses per-tile priority during gameplay
[sound] BGM during intro releases few keys too early (TODO: pinpoint which)
]]></notes>
Expand Down
66 changes: 48 additions & 18 deletions src/mame/funtech/supracan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Super A'Can (c) 1995 Funtech
#define LOG_ALL (LOG_UNKNOWNS | LOG_HFUNKNOWNS | LOG_DMA | LOG_VIDEO | LOG_HFVIDEO | LOG_IRQS | LOG_SOUND | LOG_68K_SOUND | LOG_CONTROLS)
#define LOG_DEFAULT (LOG_ALL & ~(LOG_HFVIDEO | LOG_HFUNKNOWNS))

#define VERBOSE (LOG_UNKNOWNS | LOG_DMA)
#define VERBOSE (LOG_GENERAL | LOG_UNKNOWNS | LOG_DMA | LOG_HFUNKNOWNS)
#include "logmacro.h"


Expand Down Expand Up @@ -194,9 +194,6 @@ class supracan_state : public driver_device

required_ioport_array<2> m_pad;

dma_regs_t m_dma_regs;
sprdma_regs_t m_sprdma_regs;

uint16_t m_sound_cpu_ctrl = 0;
uint8_t m_soundcpu_irq_enable = 0;
uint8_t m_soundcpu_irq_source = 0;
Expand All @@ -212,18 +209,18 @@ class supracan_state : public driver_device

std::vector<uint8_t> m_vram_addr_swapped{};

#if 0
uint16_t *m_pram = nullptr;
#endif

uint16_t m_sprite_count = 0;
uint32_t m_sprite_base_addr = 0;
uint8_t m_sprite_mono_color = 0;
uint8_t m_sprite_flags = 0;

dma_regs_t m_dma_regs;
sprdma_regs_t m_sprdma_regs;

uint16_t m_video_flags = 0;
uint32_t m_tilemap_base_addr[3]{};
int m_tilemap_scrollx[3]{};
int m_tilemap_scrolly[3]{};
uint16_t m_video_flags = 0;
uint16_t m_tilemap_flags[3]{};
uint16_t m_tilemap_mode[3]{};
uint16_t m_tilemap_tile_mode[3]{};
Expand Down Expand Up @@ -253,7 +250,7 @@ class supracan_state : public driver_device

uint16_t m_video_regs[256]{};

tilemap_t *m_tilemap_sizes[4][4]{};
tilemap_t *m_tilemap_sizes[4][5]{};
bitmap_ind16 m_sprite_final_bitmap;
bitmap_ind8 m_sprite_mask_bitmap;
bitmap_ind8 m_prio_bitmap;
Expand Down Expand Up @@ -481,21 +478,25 @@ void supracan_state::video_start()
m_tilemap_sizes[0][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_tilemap_sizes[0][2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 32);
m_tilemap_sizes[0][3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_tilemap_sizes[0][4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 16, 16);

m_tilemap_sizes[1][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_tilemap_sizes[1][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_tilemap_sizes[1][2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 32);
m_tilemap_sizes[1][3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_tilemap_sizes[1][4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 16, 16);

m_tilemap_sizes[2][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_tilemap_sizes[2][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_tilemap_sizes[2][2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 32);
m_tilemap_sizes[2][3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_tilemap_sizes[2][4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_tilemap2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 16, 16);

m_tilemap_sizes[3][0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_roz_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_tilemap_sizes[3][1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_roz_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_tilemap_sizes[3][2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_roz_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 32);
m_tilemap_sizes[3][3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_roz_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_tilemap_sizes[3][4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(supracan_state::get_roz_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 16, 16);
}

int supracan_state::get_tilemap_dimensions(int &xsize, int &ysize, int layer)
Expand All @@ -511,6 +512,18 @@ int supracan_state::get_tilemap_dimensions(int &xsize, int &ysize, int layer)

switch (select)
{
// formduel rain layer on game over
// sonevil title screen
case 0x200:
xsize = 16;
ysize = 16;
return 4;

case 0x400:
xsize = 32;
ysize = 32;
return 0;

case 0x600:
xsize = 64;
ysize = 32;
Expand All @@ -527,6 +540,8 @@ int supracan_state::get_tilemap_dimensions(int &xsize, int &ysize, int layer)
return 3;

default:
// TODO: setting 0 is already tested by A'Can logo (in bitmap mode)
// select & 0x100 is 16x16 tiles
LOGMASKED(LOG_HFUNKNOWNS, "Unsupported tilemap size for layer %d: %04x\n", layer, select);
return 0;
}
Expand Down Expand Up @@ -936,6 +951,7 @@ void supracan_state::draw_roz_layer(bitmap_ind16 &bitmap, const rectangle &clipr

/* get dest and priority pointers */
uint16_t *dest = &bitmap.pix(sy, sx);
// TODO: somebody ate the priority pointer here ...

/* loop over columns */
while (x <= ex)
Expand Down Expand Up @@ -1342,6 +1358,9 @@ template <unsigned ch> void supracan_state::dma_w(offs_t offset, uint16_t data,
if (data & 0x0100)
{
// staiwbbl, indirect transfers towards port $f00010-$1f
// TODO: also used by sangofgt
// will glitch on some super moves because it tries to transfer
// multiple times to the VRAM port (normally size is set to 8x2 bytes)
if ((m_dma_regs.dest[ch] & 0xf) == 0)
m_dma_regs.dest[ch] -= 0x10;
}
Expand Down Expand Up @@ -1369,14 +1388,6 @@ template <unsigned ch> void supracan_state::dma_w(offs_t offset, uint16_t data,
}
}

#if 0
void supracan_state::supracan_pram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
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_t byte)
{
Expand Down Expand Up @@ -1466,6 +1477,10 @@ uint8_t supracan_state::_6502_soundmem_r(offs_t offset)
}
break;
}
case 0x406:
// staiwbbl: pad +5V presence?
// Will flip and pass bits 1-0 to 0x407 writes
return 0x00;
case 0x410:
data = m_soundcpu_irq_enable;
if (!machine().side_effects_disabled())
Expand All @@ -1483,6 +1498,9 @@ uint8_t supracan_state::_6502_soundmem_r(offs_t offset)
m_soundcpu->set_input_line(0, CLEAR_LINE);
}
break;
case 0x412:
// NMI acknowledge
break;
case 0x420:
if (!machine().side_effects_disabled())
{
Expand Down Expand Up @@ -1549,6 +1567,10 @@ void supracan_state::_6502_soundmem_w(offs_t offset, uint8_t data)
}
break;
}
// written with 0x06 at game startups, prior to enabling sound irqs
// (NMI + master irq enable?)
//case 0x409:
//break;
case 0x40a:
// speedyd/magipool uses this to request main to kickoff a sound DMA.
// gamblord/formduel just sets this just to poll a sound command
Expand Down Expand Up @@ -1742,6 +1764,14 @@ void supracan_state::host_um6619_map(address_map &map)
update_frc_state();
})
);
map(0x18, 0x19).lr16(
NAME([this] (offs_t offset) {
// formduel uses this to scroll the game over rain layer, in both X & Y directions.
// TODO: details, obviously.
logerror("$e90018: RNG read?\n");
return m_soundcpu->total_cycles() % (0xffff);
})
);
/**
* x--- to hiview lockout
* -x-- internal ROM lockout?
Expand Down

0 comments on commit 813c5fe

Please sign in to comment.