Miscellaneous late 90s Jaleco HW fixes and cleanups (#7445)

* ms32.cpp: fix/document memory map

* ms32.cpp: preliminary CRTC hookup

* ms32.cpp: implement sprite direction bit, nuke per-game kludges

* Move note where it belongs (nw)

* ms32.cpp, bnstars.cpp: correct sprite RAM ranges

* tetrisp2.cpp: kill some legacy screen params, need those anyway

* Improve notes (nw)

* ms32.cpp: move CRTC to a new sysctrl device

Also added a bare-bones Python script for generating new device file
defs to src/mame/etc

* gen_python_def.py: address issues, misc improvements

* Kill device_memory_interface in favour of direct address_map, QA always broken flip_screen in flags

* ms32.cpp: reinstated flip screen thru callback

* ms32.cpp: Make mixing to honor cliprects instead of erratic screen.width / height call

* Need a safeguard somehow, and a symbols build doesn't help here lalala

* Fix notes, cannot repro the bug, next

* Move irq assert/clear lines to device, add preliminary prg timer, make 30 Hz irq to behave like one.
(Note: very untested, feedback is appreciated)

* Send a prg timer ack if irq is disabled

* Misc cleanups

* Nuke emu_timers in favour of configure_scanline, preliminary bnstars1 hookup

* No magic number please

* Add sysctrl to tetrisp2.cpp, move rockms stuff into its own state machine, misc

* Kill off 30 Hz refresh rate hack in stepstag/vjdash sub screens

* Flag all those xtals as unknown

* Move has_zoom/has_yuv in ms32_sprite init constructor, fix dummy config bug with stepstag right screen update

* jalcrpt.h doesn't belong to tetrisp2.cpp, errata on sysctrl reset line

* Fix build

* Left-over

* Fix bool comparison to itself (blame JS habits), nuke bnstars1 mahjong
switch case altogether.

* Notes

* Fix bnstars1 crash

* update_color fn doesn't work without a memory_share_creator, documentation

* Translate clamp_to_12bits_neg to a constexpr method

* Fix crashing in main ms32 driver, except it now has very broken priority for seemingly no reason

* Fix nasty spriteram buffer RAM allocation bug

* Make objectram_size to be calculated at init time

* First (naive) pass in moving common interface to a ms32_base_state

Move m_irqreg save state from video_start to machine_start fn;
Fix embarassing palette overflow bug in ms32.cpp;
Add bitswap for bnstars1 mahjong panel;
.bytes() -> .length() for objectram_size;

* bnstars: template video handlers

* bnstars: fix config, split sprite chips/gfxdecode/palette into two, fix palette ranges

* ms32.cpp: implement proper irq acknowledge lines

* Add config setter in sysctrl for inverted vblank/field lines, make tp2ms32 and wpksocv2 happy

* Move f1superb to own state

* MS32 merge sound maps

* Remove TIMER_DEVICE_CALLBACK_MEMBER in favour of emu_timer
This commit is contained in:
Angelo Salese 2020-11-25 11:14:04 +01:00 committed by GitHub
parent 21ad5da328
commit b88fe8a45e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1894 additions and 1310 deletions

View File

@ -2314,6 +2314,8 @@ files {
MAME_DIR .. "src/mame/video/ms1_tmap.h",
MAME_DIR .. "src/mame/video/ms32_sprite.cpp",
MAME_DIR .. "src/mame/video/ms32_sprite.h",
MAME_DIR .. "src/mame/machine/jaleco_ms32_sysctrl.cpp",
MAME_DIR .. "src/mame/machine/jaleco_ms32_sysctrl.h",
}
createMAMEProjects(_target, _subtarget, "jpm")

View File

@ -10,7 +10,6 @@ Single board version with Dual Screen output
for the time being most of this driver is copied
from ms32.cpp, with some adjustments for dual screen.
Main PCB
--------
@ -93,7 +92,6 @@ ROMs : MR96004-10.1 [125661cd] (IC5 - Samples)
#include "cpu/z80/z80.h"
#include "cpu/v60/v60.h"
#include "sound/ymf271.h"
#include "machine/jalcrpt.h"
#include "rendlay.h"
@ -101,25 +99,27 @@ ROMs : MR96004-10.1 [125661cd] (IC5 - Samples)
#include "tilemap.h"
class bnstars_state : public ms32_state
class ms32_bnstars_state : public ms32_base_state
{
public:
bnstars_state(const machine_config &mconfig, device_type type, const char *tag)
: ms32_state(mconfig, type, tag)
, m_ms32_tx0_ram(*this, "tx0_ram", 0x4000, ENDIANNESS_LITTLE)
, m_ms32_tx1_ram(*this, "tx1_ram", 0x4000, ENDIANNESS_LITTLE)
, m_ms32_bg0_ram(*this, "bg0_ram", 0x4000, ENDIANNESS_LITTLE)
, m_ms32_bg1_ram(*this, "bg1_ram", 0x4000, ENDIANNESS_LITTLE)
, m_ms32_roz0_ram(*this, "roz0_ram", 0x10000, ENDIANNESS_LITTLE)
, m_ms32_roz1_ram(*this, "roz1_ram", 0x10000, ENDIANNESS_LITTLE)
, m_ms32_roz_ctrl(*this, "roz_ctrl.%u", 0)
, m_ms32_spram(*this, "spram", 0x20000, ENDIANNESS_LITTLE)
, m_ms32_tx0_scroll(*this, "tx0_scroll")
, m_ms32_bg0_scroll(*this, "bg0_scroll")
, m_ms32_tx1_scroll(*this, "tx1_scroll")
, m_ms32_bg1_scroll(*this, "bg1_scroll")
ms32_bnstars_state(const machine_config &mconfig, device_type type, const char *tag)
: ms32_base_state(mconfig, type, tag)
, m_sysctrl(*this, "sysctrl")
, m_screen(*this, "screen.%u", 0U)
, m_gfxdecode(*this, "gfxdecode.%u", 0U)
, m_palette(*this, "palette.%u", 0U)
, m_paletteram(*this, "paletteram.%u", 0U, 0x20000U, ENDIANNESS_LITTLE)
, m_ascii_vram(*this, "ascii_vram_%u", 0U, 0x4000U, ENDIANNESS_LITTLE)
, m_ascii_ctrl(*this, "ascii_ctrl.%u", 0U)
, m_scroll_vram(*this, "scroll_vram_%u", 0U, 0x4000U, ENDIANNESS_LITTLE)
, m_scroll_ctrl(*this, "scroll_ctrl.%u", 0U)
, m_rotate_vram(*this, "rotate_vram_%u", 0U, 0x10000U, ENDIANNESS_LITTLE)
, m_rotate_ctrl(*this, "rotate_ctrl.%u", 0U)
, m_sprite(*this, "sprite.%u", 0U)
, m_object_vram(*this, "objram_%u", 0U, 0x10000U, ENDIANNESS_LITTLE)
, m_p1_keys(*this, "P1KEY.%u", 0)
, m_p2_keys(*this, "P2KEY.%u", 0)
, m_ymf(*this, "ymf.%u", 1U)
{ }
void bnstars(machine_config &config);
@ -130,185 +130,170 @@ public:
private:
tilemap_t *m_ms32_tx_tilemap[2];
tilemap_t *m_ms32_bg_tilemap[2];
tilemap_t *m_ms32_roz_tilemap[2];
memory_share_creator<u16> m_ms32_tx0_ram;
memory_share_creator<u16> m_ms32_tx1_ram;
memory_share_creator<u16> m_ms32_bg0_ram;
memory_share_creator<u16> m_ms32_bg1_ram;
memory_share_creator<u16> m_ms32_roz0_ram;
memory_share_creator<u16> m_ms32_roz1_ram;
required_shared_ptr_array<u32, 2> m_ms32_roz_ctrl;
memory_share_creator<u16> m_ms32_spram;
required_shared_ptr<u32> m_ms32_tx0_scroll;
required_shared_ptr<u32> m_ms32_bg0_scroll;
required_shared_ptr<u32> m_ms32_tx1_scroll;
required_shared_ptr<u32> m_ms32_bg1_scroll;
// TODO: subclass this device for dual screen config
required_device<jaleco_ms32_sysctrl_device> m_sysctrl;
required_device_array<screen_device, 2> m_screen;
required_device_array<gfxdecode_device, 2> m_gfxdecode;
required_device_array<palette_device, 2> m_palette;
memory_share_array_creator<u16, 2> m_paletteram;
memory_share_array_creator<u16, 2> m_ascii_vram;
required_shared_ptr_array<u32, 2> m_ascii_ctrl;
memory_share_array_creator<u16, 2> m_scroll_vram;
required_shared_ptr_array<u32, 2> m_scroll_ctrl;
memory_share_array_creator<u16, 2> m_rotate_vram;
required_shared_ptr_array<u32, 2> m_rotate_ctrl;
required_device_array<ms32_sprite_device, 2> m_sprite;
memory_share_array_creator<u16, 2> m_object_vram;
required_ioport_array<4> m_p1_keys;
required_ioport_array<4> m_p2_keys;
u32 m_bnstars1_mahjong_select;
void ms32_tx0_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_tx1_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_bg0_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_bg1_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_roz0_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_roz1_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void bnstars1_mahjong_select_w(u32 data);
TILE_GET_INFO_MEMBER(get_ms32_tx0_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_tx1_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_bg0_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_bg1_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_roz0_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_roz1_tile_info);
template <int chip> void ascii_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
template <int chip> u16 ascii_vram_r(offs_t offset);
template <int chip> void scroll_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
template <int chip> u16 scroll_vram_r(offs_t offset);
template <int chip> void rotate_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
template <int chip> u16 rotate_vram_r(offs_t offset);
template <int chip> void object_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
template <int chip> u16 object_vram_r(offs_t offset);
template <int chip> void palette_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
template <int chip> u16 palette_ram_r(offs_t offset);
DECLARE_WRITE_LINE_MEMBER(flipscreen_dual_w);
template <int chip> TILE_GET_INFO_MEMBER(get_ascii_tile_info);
template <int chip> TILE_GET_INFO_MEMBER(get_scroll_tile_info);
template <int chip> TILE_GET_INFO_MEMBER(get_rotate_tile_info);
template <int chip> void draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority);
template <int chip> void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
tilemap_t *m_ascii_tilemap[2];
tilemap_t *m_scroll_tilemap[2];
tilemap_t *m_rotate_tilemap[2];
virtual void video_start() override;
u32 screen_update_bnstars_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_bnstars_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority, int chip);
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u16 *sprram_top, size_t sprram_size);
template <int which> u32 screen_update_dual(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void bnstars_map(address_map &map);
void bnstars_sound_map(address_map &map);
void bnstars1_mahjong_select_w(u32 data);
required_device_array<ymf271_device, 2> m_ymf;
};
WRITE_LINE_MEMBER(ms32_bnstars_state::flipscreen_dual_w)
{
for (int chip = 0; chip < 2; chip++)
{
m_scroll_tilemap[chip]->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
m_ascii_tilemap[chip]->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
m_rotate_tilemap[chip]->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
// TODO: sprite device
}
}
TILE_GET_INFO_MEMBER(bnstars_state::get_ms32_tx0_tile_info)
template <int chip> u16 ms32_bnstars_state::ascii_vram_r(offs_t offset)
{
return m_ascii_vram[chip][offset];
}
template <int chip> void ms32_bnstars_state::ascii_vram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_ascii_vram[chip][offset]);
m_ascii_tilemap[chip]->mark_tile_dirty(offset/2);
}
template <int chip> u16 ms32_bnstars_state::scroll_vram_r(offs_t offset)
{
return m_scroll_vram[chip][offset];
}
template <int chip> void ms32_bnstars_state::scroll_vram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_scroll_vram[chip][offset]);
m_scroll_tilemap[chip]->mark_tile_dirty(offset/2);
}
template <int chip> u16 ms32_bnstars_state::rotate_vram_r(offs_t offset)
{
return m_rotate_vram[chip][offset];
}
template <int chip> void ms32_bnstars_state::rotate_vram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_rotate_vram[chip][offset]);
m_rotate_tilemap[chip]->mark_tile_dirty(offset/2);
}
template <int chip> u16 ms32_bnstars_state::object_vram_r(offs_t offset)
{
return m_object_vram[chip][offset];
}
template <int chip> void ms32_bnstars_state::object_vram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_object_vram[chip][offset]);
}
template <int chip> TILE_GET_INFO_MEMBER(ms32_bnstars_state::get_ascii_tile_info)
{
int tileno, colour;
// const int gfx_region[2] = {2, 5};
tileno = m_ms32_tx0_ram[tile_index *2+0] & 0x0000ffff;
colour = m_ms32_tx0_ram[tile_index *2+1] & 0x0000000f;
tileno = m_ascii_vram[chip][tile_index *2+0] & 0x0000ffff;
colour = m_ascii_vram[chip][tile_index *2+1] & 0x0000000f;
tileinfo.set(2,tileno,colour,0);
tileinfo.set(2, tileno, colour, 0);
}
TILE_GET_INFO_MEMBER(bnstars_state::get_ms32_tx1_tile_info)
template <int chip> TILE_GET_INFO_MEMBER(ms32_bnstars_state::get_scroll_tile_info)
{
int tileno, colour;
// const int gfx_region[2] = {1, 4};
tileno = m_ms32_tx1_ram[tile_index *2+0] & 0x0000ffff;
colour = m_ms32_tx1_ram[tile_index *2+1] & 0x0000000f;
tileno = m_scroll_vram[chip][tile_index *2+0] & 0x0000ffff;
colour = m_scroll_vram[chip][tile_index *2+1] & 0x0000000f;
tileinfo.set(5,tileno,colour,0);
tileinfo.set(1, tileno, colour, 0);
}
void bnstars_state::ms32_tx0_ram_w(offs_t offset, u16 data, u16 mem_mask)
template <int chip> TILE_GET_INFO_MEMBER(ms32_bnstars_state::get_rotate_tile_info)
{
COMBINE_DATA(&m_ms32_tx0_ram[offset]);
m_ms32_tx_tilemap[0]->mark_tile_dirty(offset/2);
int tileno, colour;
// const int gfx_region[2] = {0, 3};
tileno = m_rotate_vram[chip][tile_index *2+0] & 0x0000ffff;
colour = m_rotate_vram[chip][tile_index *2+1] & 0x0000000f;
tileinfo.set(0, tileno, colour, 0);
}
void bnstars_state::ms32_tx1_ram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_ms32_tx1_ram[offset]);
m_ms32_tx_tilemap[1]->mark_tile_dirty(offset/2);
}
/* BG Layers */
TILE_GET_INFO_MEMBER(bnstars_state::get_ms32_bg0_tile_info)
{
int tileno,colour;
tileno = m_ms32_bg0_ram[tile_index *2+0] & 0x0000ffff;
colour = m_ms32_bg0_ram[tile_index *2+1] & 0x0000000f;
tileinfo.set(1,tileno,colour,0);
}
TILE_GET_INFO_MEMBER(bnstars_state::get_ms32_bg1_tile_info)
{
int tileno,colour;
tileno = m_ms32_bg1_ram[tile_index *2+0] & 0x0000ffff;
colour = m_ms32_bg1_ram[tile_index *2+1] & 0x0000000f;
tileinfo.set(4,tileno,colour,0);
}
void bnstars_state::ms32_bg0_ram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_ms32_bg0_ram[offset]);
m_ms32_bg_tilemap[0]->mark_tile_dirty(offset/2);
}
void bnstars_state::ms32_bg1_ram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_ms32_bg1_ram[offset]);
m_ms32_bg_tilemap[1]->mark_tile_dirty(offset/2);
}
/* ROZ Layers */
void bnstars_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority, int chip)
// TODO: merge with main ms32.cpp
template <int chip> void ms32_bnstars_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int priority)
{
/* TODO: registers 0x40/4 / 0x44/4 and 0x50/4 / 0x54/4 are used, meaning unknown */
// TODO: registers 0x40/4 / 0x44/4 and 0x50/4 / 0x54/4 are used, meaning unknown
if (m_ms32_roz_ctrl[chip][0x5c/4] & 1) /* "super" mode */
{
printf("no lineram!\n");
return;
/*
rectangle my_clip;
int y,maxy;
my_clip.min_x = cliprect.min_x;
my_clip.max_x = cliprect.max_x;
y = cliprect.min_y;
maxy = cliprect.max_y;
while (y <= maxy)
{
u32 *lineaddr = ms32_lineram + 8 * (y & 0xff);
int start2x = (lineaddr[0x00/4] & 0xffff) | ((lineaddr[0x04/4] & 3) << 16);
int start2y = (lineaddr[0x08/4] & 0xffff) | ((lineaddr[0x0c/4] & 3) << 16);
int incxx = (lineaddr[0x10/4] & 0xffff) | ((lineaddr[0x14/4] & 1) << 16);
int incxy = (lineaddr[0x18/4] & 0xffff) | ((lineaddr[0x1c/4] & 1) << 16);
int startx = (m_ms32_roz_ctrl[0x00/4] & 0xffff) | ((m_ms32_roz_ctrl[0x04/4] & 3) << 16);
int starty = (m_ms32_roz_ctrl[0x08/4] & 0xffff) | ((m_ms32_roz_ctrl[0x0c/4] & 3) << 16);
int offsx = m_ms32_roz_ctrl[0x30/4];
int offsy = m_ms32_roz_ctrl[0x34/4];
my_clip.min_y = my_clip.max_y = y;
offsx += (m_ms32_roz_ctrl[0x38/4] & 1) * 0x400; // ??? gratia, hayaosi1...
offsy += (m_ms32_roz_ctrl[0x3c/4] & 1) * 0x400; // ??? gratia, hayaosi1...
// extend sign
if (start2x & 0x20000) start2x |= ~0x3ffff;
if (start2y & 0x20000) start2y |= ~0x3ffff;
if (startx & 0x20000) startx |= ~0x3ffff;
if (starty & 0x20000) starty |= ~0x3ffff;
if (incxx & 0x10000) incxx |= ~0x1ffff;
if (incxy & 0x10000) incxy |= ~0x1ffff;
m_ms32_roz_tilemap->draw_roz(screen, bitmap, &my_clip,
(start2x+startx+offsx)<<16, (start2y+starty+offsy)<<16,
incxx<<8, incxy<<8, 0, 0,
1, // Wrap
0, priority);
y++;
}
*/
}
if (m_rotate_ctrl[chip][0x5c/4] & 1) /* "super" mode */
throw emu_fatalerror("Super mode in bnstars1?");
else /* "simple" mode */
{
int startx = (m_ms32_roz_ctrl[chip][0x00/4] & 0xffff) | ((m_ms32_roz_ctrl[chip][0x04/4] & 3) << 16);
int starty = (m_ms32_roz_ctrl[chip][0x08/4] & 0xffff) | ((m_ms32_roz_ctrl[chip][0x0c/4] & 3) << 16);
int incxx = (m_ms32_roz_ctrl[chip][0x10/4] & 0xffff) | ((m_ms32_roz_ctrl[chip][0x14/4] & 1) << 16);
int incxy = (m_ms32_roz_ctrl[chip][0x18/4] & 0xffff) | ((m_ms32_roz_ctrl[chip][0x1c/4] & 1) << 16);
int incyy = (m_ms32_roz_ctrl[chip][0x20/4] & 0xffff) | ((m_ms32_roz_ctrl[chip][0x24/4] & 1) << 16);
int incyx = (m_ms32_roz_ctrl[chip][0x28/4] & 0xffff) | ((m_ms32_roz_ctrl[chip][0x2c/4] & 1) << 16);
int offsx = m_ms32_roz_ctrl[chip][0x30/4];
int offsy = m_ms32_roz_ctrl[chip][0x34/4];
int startx = (m_rotate_ctrl[chip][0x00/4] & 0xffff) | ((m_rotate_ctrl[chip][0x04/4] & 3) << 16);
int starty = (m_rotate_ctrl[chip][0x08/4] & 0xffff) | ((m_rotate_ctrl[chip][0x0c/4] & 3) << 16);
int incxx = (m_rotate_ctrl[chip][0x10/4] & 0xffff) | ((m_rotate_ctrl[chip][0x14/4] & 1) << 16);
int incxy = (m_rotate_ctrl[chip][0x18/4] & 0xffff) | ((m_rotate_ctrl[chip][0x1c/4] & 1) << 16);
int incyy = (m_rotate_ctrl[chip][0x20/4] & 0xffff) | ((m_rotate_ctrl[chip][0x24/4] & 1) << 16);
int incyx = (m_rotate_ctrl[chip][0x28/4] & 0xffff) | ((m_rotate_ctrl[chip][0x2c/4] & 1) << 16);
int offsx = m_rotate_ctrl[chip][0x30/4];
int offsy = m_rotate_ctrl[chip][0x34/4];
offsx += (m_ms32_roz_ctrl[chip][0x38/4] & 1) * 0x400; // ??? gratia, hayaosi1...
offsy += (m_ms32_roz_ctrl[chip][0x3c/4] & 1) * 0x400; // ??? gratia, hayaosi1...
offsx += (m_rotate_ctrl[chip][0x38/4] & 1) * 0x400; // ??? gratia, hayaosi1...
offsy += (m_rotate_ctrl[chip][0x3c/4] & 1) * 0x400; // ??? gratia, hayaosi1...
/* extend sign */
if (startx & 0x20000) startx |= ~0x3ffff;
@ -318,7 +303,7 @@ void bnstars_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const
if (incyy & 0x10000) incyy |= ~0x1ffff;
if (incyx & 0x10000) incyx |= ~0x1ffff;
m_ms32_roz_tilemap[chip]->draw_roz(screen, bitmap, cliprect,
m_rotate_tilemap[chip]->draw_roz(screen, bitmap, cliprect,
(startx+offsx)<<16, (starty+offsy)<<16,
incxx<<8, incxy<<8, incyx<<8, incyy<<8,
1, // Wrap
@ -326,92 +311,22 @@ void bnstars_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const
}
}
TILE_GET_INFO_MEMBER(bnstars_state::get_ms32_roz0_tile_info)
// TODO: move to the sprite chip, fix priority
template <int chip> void ms32_bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int tileno,colour;
u16 *sprram_top = m_object_vram[chip];
const size_t sprite_tail = m_object_vram[chip].length() - 8;
u16 *source = sprram_top;
u16 *finish = sprram_top + sprite_tail;
const bool reverseorder = (m_sprite_ctrl[0x10/4] & 0x8000) == 0x0000;
tileno = m_ms32_roz0_ram[tile_index *2+0] & 0x0000ffff;
colour = m_ms32_roz0_ram[tile_index *2+1] & 0x0000000f;
tileinfo.set(0,tileno,colour,0);
}
TILE_GET_INFO_MEMBER(bnstars_state::get_ms32_roz1_tile_info)
{
int tileno,colour;
tileno = m_ms32_roz1_ram[tile_index *2+0] & 0x0000ffff;
colour = m_ms32_roz1_ram[tile_index *2+1] & 0x0000000f;
tileinfo.set(3,tileno,colour,0);
}
void bnstars_state::ms32_roz0_ram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_ms32_roz0_ram[offset]);
m_ms32_roz_tilemap[0]->mark_tile_dirty(offset/2);
}
void bnstars_state::ms32_roz1_ram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_ms32_roz1_ram[offset]);
m_ms32_roz_tilemap[1]->mark_tile_dirty(offset/2);
}
/* SPRITES based on tetrisp2 for now, readd priority bits later */
void bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, u16 *sprram_top, size_t sprram_size)
{
/***************************************************************************
Sprites Drawing
Offset: Bits: Meaning:
0.w fedc ba98 ---- ----
---- ---- 7654 ---- Priority
---- ---- ---- 3---
---- ---- ---- -2-- Draw this sprite
---- ---- ---- --1- Flip Y
---- ---- ---- ---0 Flip X
1.w fedc ba98 ---- ---- Tile's Y position in the tile page (*)
---- ---- 7654 3210 Tile's X position in the tile page (*)
2.w fedc ---- ---- ---- Color
---- ba98 7654 3210 Tile Page (32x32 tiles = 256x256 pixels each)
3.w fedc ba98 ---- ---- Y Size - 1 (*)
---- ---- 7654 3210 X Size - 1 (*)
4.w fedc ba-- ---- ----
---- --98 7654 3210 Y (Signed)
5.w fedc b--- ---- ----
---- -a98 7654 3210 X (Signed)
6.w fedc ba98 7654 3210 Zoom Y
7.w fedc ba98 7654 3210 Zoom X
(*) 1 pixel granularity
***************************************************************************/
u16 *source = sprram_top;
const u16 *finish = sprram_top + (sprram_size - 0x10) / 2;
if (m_reverse_sprite_order == 1)
if (reverseorder == true)
{
source = sprram_top + (sprram_size - 0x10) / 2;
finish = sprram_top;
source = sprram_top + sprite_tail;
finish = sprram_top;
}
for (;m_reverse_sprite_order ? (source>=finish) : (source<finish); m_reverse_sprite_order ? (source-=8) : (source+=8))
for (;reverseorder ? (source>=finish) : (source<finish); reverseorder ? (source-=8) : (source+=8))
{
bool disable;
u8 pri;
@ -423,14 +338,14 @@ void bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
u16 xzoom, yzoom;
u32 pri_mask = 0;
m_sprite->extract_parameters(true, false, source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom);
m_sprite[chip]->extract_parameters(source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom);
if (disable || !xzoom || !yzoom)
continue;
// there are surely also shadows (see gametngk) but how they're enabled we don't know
if (m_flipscreen)
/* if (m_flipscreen)
{
int yscale = 0x1000000/yzoom;
int xscale = 0x1000000/xzoom;
@ -439,10 +354,9 @@ void bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
sy = 224 - ((ysize*yscale)>>16) - sy;
flipx = !flipx;
flipy = !flipy;
}
}*/
pri >>= 4;
/* TODO: priority handling is completely wrong, but better than nothing */
if (pri == 0x0)
pri_mask = 0x00;
else if (pri <= 0xd)
@ -452,7 +366,7 @@ void bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
else
pri_mask = 0xfe;
m_sprite->prio_zoom_transpen(bitmap,cliprect,
m_sprite[chip]->prio_zoom_transpen(bitmap,cliprect,
code,
color,
flipx, flipy,
@ -463,74 +377,137 @@ void bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
}
void bnstars_state::video_start()
void ms32_bnstars_state::video_start()
{
m_ms32_tx_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bnstars_state::get_ms32_tx0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64,64);
m_ms32_tx_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bnstars_state::get_ms32_tx1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64,64);
m_ms32_tx_tilemap[0]->set_transparent_pen(0);
m_ms32_tx_tilemap[1]->set_transparent_pen(0);
m_ascii_tilemap[0] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(*this, FUNC(ms32_bnstars_state::get_ascii_tile_info<0>)), TILEMAP_SCAN_ROWS, 8, 8, 64,64);
m_ascii_tilemap[1] = &machine().tilemap().create(*m_gfxdecode[1], tilemap_get_info_delegate(*this, FUNC(ms32_bnstars_state::get_ascii_tile_info<1>)), TILEMAP_SCAN_ROWS, 8, 8, 64,64);
m_ascii_tilemap[0]->set_transparent_pen(0);
m_ascii_tilemap[1]->set_transparent_pen(0);
m_ms32_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bnstars_state::get_ms32_bg0_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 64,64);
m_ms32_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bnstars_state::get_ms32_bg1_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 64,64);
m_ms32_bg_tilemap[0]->set_transparent_pen(0);
m_ms32_bg_tilemap[1]->set_transparent_pen(0);
m_scroll_tilemap[0] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(*this, FUNC(ms32_bnstars_state::get_scroll_tile_info<0>)), TILEMAP_SCAN_ROWS, 16,16, 64,64);
m_scroll_tilemap[1] = &machine().tilemap().create(*m_gfxdecode[1], tilemap_get_info_delegate(*this, FUNC(ms32_bnstars_state::get_scroll_tile_info<1>)), TILEMAP_SCAN_ROWS, 16,16, 64,64);
m_scroll_tilemap[0]->set_transparent_pen(0);
m_scroll_tilemap[1]->set_transparent_pen(0);
m_ms32_roz_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bnstars_state::get_ms32_roz0_tile_info)),TILEMAP_SCAN_ROWS, 16,16,128,128);
m_ms32_roz_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(bnstars_state::get_ms32_roz1_tile_info)),TILEMAP_SCAN_ROWS, 16,16,128,128);
m_ms32_roz_tilemap[0]->set_transparent_pen(0);
m_ms32_roz_tilemap[1]->set_transparent_pen(0);
m_rotate_tilemap[0] = &machine().tilemap().create(*m_gfxdecode[0], tilemap_get_info_delegate(*this, FUNC(ms32_bnstars_state::get_rotate_tile_info<0>)),TILEMAP_SCAN_ROWS, 16,16,128,128);
m_rotate_tilemap[1] = &machine().tilemap().create(*m_gfxdecode[1], tilemap_get_info_delegate(*this, FUNC(ms32_bnstars_state::get_rotate_tile_info<1>)),TILEMAP_SCAN_ROWS, 16,16,128,128);
m_rotate_tilemap[0]->set_transparent_pen(0);
m_rotate_tilemap[1]->set_transparent_pen(0);
}
u32 bnstars_state::screen_update_bnstars_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
template <int which> u32 ms32_bnstars_state::screen_update_dual(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect); /* bg color */
m_scroll_tilemap[which]->set_scrollx(0, m_scroll_ctrl[which][0x00/4] + m_scroll_ctrl[which][0x08/4] + 0x10 );
m_scroll_tilemap[which]->set_scrolly(0, m_scroll_ctrl[which][0x0c/4] + m_scroll_ctrl[which][0x14/4] );
m_scroll_tilemap[which]->draw(screen, bitmap, cliprect, 0, 1);
m_ms32_bg_tilemap[0]->set_scrollx(0, m_ms32_bg0_scroll[0x00/4] + m_ms32_bg0_scroll[0x08/4] + 0x10 );
m_ms32_bg_tilemap[0]->set_scrolly(0, m_ms32_bg0_scroll[0x0c/4] + m_ms32_bg0_scroll[0x14/4] );
m_ms32_bg_tilemap[0]->draw(screen, bitmap, cliprect, 0,1);
draw_roz<which>(screen,bitmap,cliprect, 2);
draw_roz(screen,bitmap,cliprect,2,0);
m_ascii_tilemap[which]->set_scrollx(0, m_ascii_ctrl[which][0x00/4] + m_ascii_ctrl[which][0x08/4] + 0x18);
m_ascii_tilemap[which]->set_scrolly(0, m_ascii_ctrl[which][0x0c/4] + m_ascii_ctrl[which][0x14/4]);
m_ascii_tilemap[which]->draw(screen, bitmap, cliprect, 0, 4);
m_ms32_tx_tilemap[0]->set_scrollx(0, m_ms32_tx0_scroll[0x00/4] + m_ms32_tx0_scroll[0x08/4] + 0x18);
m_ms32_tx_tilemap[0]->set_scrolly(0, m_ms32_tx0_scroll[0x0c/4] + m_ms32_tx0_scroll[0x14/4]);
m_ms32_tx_tilemap[0]->draw(screen, bitmap, cliprect, 0,4);
draw_sprites(screen,bitmap,cliprect, m_ms32_spram, 0x20000/2);
draw_sprites<which>(screen, bitmap, cliprect);
return 0;
}
u32 bnstars_state::screen_update_bnstars_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
template <int chip> u16 ms32_bnstars_state::palette_ram_r(offs_t offset)
{
screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect); /* bg color */
m_ms32_bg_tilemap[1]->set_scrollx(0, m_ms32_bg1_scroll[0x00/4] + m_ms32_bg1_scroll[0x08/4] + 0x10 );
m_ms32_bg_tilemap[1]->set_scrolly(0, m_ms32_bg1_scroll[0x0c/4] + m_ms32_bg1_scroll[0x14/4] );
m_ms32_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0,1);
draw_roz(screen,bitmap,cliprect,2,1);
m_ms32_tx_tilemap[1]->set_scrollx(0, m_ms32_tx1_scroll[0x00/4] + m_ms32_tx1_scroll[0x08/4] + 0x18);
m_ms32_tx_tilemap[1]->set_scrolly(0, m_ms32_tx1_scroll[0x0c/4] + m_ms32_tx1_scroll[0x14/4]);
m_ms32_tx_tilemap[1]->draw(screen, bitmap, cliprect, 0,4);
draw_sprites(screen,bitmap,cliprect, m_ms32_spram+(0x20000/4), 0x20000/2);
return 0;
return m_paletteram[chip][offset];
}
template <int chip> void ms32_bnstars_state::palette_ram_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_paletteram[chip][offset]);
// TODO: support for RGB brightness
u32 pal_data = (m_paletteram[chip][offset | 1] << 16) | m_paletteram[chip][offset & ~1];
const int b = ((pal_data & 0xff0000) >> 16);
const int r = ((pal_data & 0x00ff00) >> 8);
const int g = ((pal_data & 0x0000ff) >> 0);
m_palette[chip]->set_pen_color(offset >> 1, rgb_t(r, g, b));
}
template <int P>
CUSTOM_INPUT_MEMBER(ms32_bnstars_state::mahjong_ctrl_r)
{
required_ioport_array<4> &keys = (P == 0) ? m_p1_keys : m_p2_keys;
// different routing than other ms32.cpp mahjong games, using 0x2080 as mask
u8 which = bitswap<2>(m_bnstars1_mahjong_select, 13, 7);
return keys[which]->read();
}
void ms32_bnstars_state::bnstars1_mahjong_select_w(u32 data)
{
m_bnstars1_mahjong_select = data;
// logerror("%08x\n",m_bnstars1_mahjong_select);
}
void ms32_bnstars_state::bnstars_map(address_map &map)
{
// TODO: derive from base ms32.cpp memory map
map(0x00000000, 0x001fffff).rom();
map(0xfc800000, 0xfc800003).w(FUNC(ms32_bnstars_state::sound_command_w));
map(0xfcc00004, 0xfcc00007).portr("P1");
map(0xfcc00008, 0xfcc0000b).portr("P2");
map(0xfcc00010, 0xfcc00013).portr("DSW");
map(0xfce00000, 0xfce0005f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap)).umask32(0x0000ffff);
map(0xfce00200, 0xfce0027f).ram().share("sprite_ctrl");
// map(0xfce00280, 0xfce0028f) // left screen brightness control
// map(0xfce00300, 0xfce0030f) // right screen brightness control
map(0xfce00400, 0xfce0045f).writeonly().share("rotate_ctrl.0");
map(0xfce00700, 0xfce0075f).writeonly().share("rotate_ctrl.1"); // guess
map(0xfce00a00, 0xfce00a17).writeonly().share("ascii_ctrl.0");
map(0xfce00a20, 0xfce00a37).writeonly().share("scroll_ctrl.0");
map(0xfce00c00, 0xfce00c17).writeonly().share("ascii_ctrl.1");
map(0xfce00c20, 0xfce00c37).writeonly().share("scroll_ctrl.1");
map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_bnstars_state::bnstars1_mahjong_select_w));
map(0xfd000000, 0xfd000003).r(FUNC(ms32_bnstars_state::sound_result_r));
/* wrote together */
map(0xfd040000, 0xfd047fff).ram(); // priority ram
map(0xfd080000, 0xfd087fff).ram();
// for some reason ***38*** isn't accessed by these two
map(0xfd200000, 0xfd23ffff).rw(FUNC(ms32_bnstars_state::palette_ram_r<1>), FUNC(ms32_bnstars_state::palette_ram_w<1>)).umask32(0x0000ffff);
map(0xfd400000, 0xfd43ffff).rw(FUNC(ms32_bnstars_state::palette_ram_r<0>), FUNC(ms32_bnstars_state::palette_ram_w<0>)).umask32(0x0000ffff);
map(0xfe000000, 0xfe01ffff).rw(FUNC(ms32_bnstars_state::rotate_vram_r<1>), FUNC(ms32_bnstars_state::rotate_vram_w<1>)).umask32(0x0000ffff);
map(0xfe400000, 0xfe41ffff).rw(FUNC(ms32_bnstars_state::rotate_vram_r<0>), FUNC(ms32_bnstars_state::rotate_vram_w<0>)).umask32(0x0000ffff);
// TODO: ms32_state should internalize sprite RAM interfaces, also NOP to $ffffxxxx
map(0xfe800000, 0xfe81ffff).rw(FUNC(ms32_bnstars_state::object_vram_r<0>), FUNC(ms32_bnstars_state::object_vram_w<0>)).umask32(0x0000ffff);
map(0xfe820000, 0xfe83ffff).rw(FUNC(ms32_bnstars_state::object_vram_r<1>), FUNC(ms32_bnstars_state::object_vram_w<1>)).umask32(0x0000ffff);
map(0xfea00000, 0xfea07fff).rw(FUNC(ms32_bnstars_state::ascii_vram_r<1>), FUNC(ms32_bnstars_state::ascii_vram_w<1>)).umask32(0x0000ffff);
map(0xfea08000, 0xfea0ffff).rw(FUNC(ms32_bnstars_state::scroll_vram_r<1>), FUNC(ms32_bnstars_state::scroll_vram_w<1>)).umask32(0x0000ffff);
map(0xfec00000, 0xfec07fff).rw(FUNC(ms32_bnstars_state::ascii_vram_r<0>), FUNC(ms32_bnstars_state::ascii_vram_w<0>)).umask32(0x0000ffff);
map(0xfec08000, 0xfec0ffff).rw(FUNC(ms32_bnstars_state::scroll_vram_r<0>), FUNC(ms32_bnstars_state::scroll_vram_w<0>)).umask32(0x0000ffff);
map(0xfee00000, 0xfee1ffff).ram();
map(0xffe00000, 0xffffffff).rom().region("maincpu", 0);
}
void ms32_bnstars_state::bnstars_sound_map(address_map &map)
{
base_sound_map(map);
map(0x3f00, 0x3f0f).rw(m_ymf[1], FUNC(ymf271_device::read), FUNC(ymf271_device::write));
map(0x3f20, 0x3f2f).rw(m_ymf[0], FUNC(ymf271_device::read), FUNC(ymf271_device::write));
}
static INPUT_PORTS_START( bnstars )
PORT_START("P1")
PORT_BIT( 0x000000ff, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(bnstars_state, mahjong_ctrl_r<0>)
PORT_BIT( 0x000000ff, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(ms32_bnstars_state, mahjong_ctrl_r<0>)
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -573,7 +550,7 @@ static INPUT_PORTS_START( bnstars )
PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("P2")
PORT_BIT( 0x000000ff, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(bnstars_state, mahjong_ctrl_r<1>)
PORT_BIT( 0x000000ff, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(ms32_bnstars_state, mahjong_ctrl_r<1>)
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -673,168 +650,60 @@ static INPUT_PORTS_START( bnstars )
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNUSED ) // Unused?
INPUT_PORTS_END
static GFXLAYOUT_RAW( bglayout, 16, 16, 16*8, 16*16*8 )
static GFXLAYOUT_RAW( txlayout, 8, 8, 8*8, 8*8*8 )
static GFXDECODE_START( gfx_bnstars )
static GFXDECODE_START( gfx_bnstars_left )
GFXDECODE_ENTRY( "gfx2", 0, bglayout, 0x5000, 0x10 ) /* Roz scr1 */
GFXDECODE_ENTRY( "gfx4", 0, bglayout, 0x1000, 0x10 ) /* Bg scr1 */
GFXDECODE_ENTRY( "gfx5", 0, txlayout, 0x6000, 0x10 ) /* Tx scr1 */
GFXDECODE_END
static GFXDECODE_START( gfx_bnstars_right )
GFXDECODE_ENTRY( "gfx3", 0, bglayout, 0x5000, 0x10 ) /* Roz scr2 */
GFXDECODE_ENTRY( "gfx6", 0, bglayout, 0x1000, 0x10 ) /* Bg scr2 */
GFXDECODE_ENTRY( "gfx7", 0, txlayout, 0x6000, 0x10 ) /* Tx scr2 */
GFXDECODE_END
template <int P>
CUSTOM_INPUT_MEMBER(bnstars_state::mahjong_ctrl_r)
void ms32_bnstars_state::bnstars(machine_config &config)
{
required_ioport_array<4> &keys = (P == 0) ? m_p1_keys : m_p2_keys;
switch (m_bnstars1_mahjong_select & 0x2080)
{
default:
printf("unk bnstars1_r %08x\n",m_bnstars1_mahjong_select);
return 0xff;
case 0x0000:
return keys[0]->read();
case 0x0080:
return keys[1]->read();
case 0x2000:
return keys[2]->read();
case 0x2080:
return keys[3]->read();
}
}
void bnstars_state::bnstars1_mahjong_select_w(u32 data)
{
m_bnstars1_mahjong_select = data;
// printf("%08x\n",m_bnstars1_mahjong_select);
}
void bnstars_state::bnstars_map(address_map &map)
{
map(0x00000000, 0x001fffff).rom();
map(0xfc800000, 0xfc800003).w(FUNC(bnstars_state::ms32_sound_w));
map(0xfcc00004, 0xfcc00007).portr("P1");
map(0xfcc00008, 0xfcc0000b).portr("P2");
map(0xfcc00010, 0xfcc00013).portr("DSW");
map(0xfce00034, 0xfce00037).nopw();
map(0xfce00038, 0xfce0003b).w(FUNC(bnstars_state::reset_sub_w));
map(0xfce00050, 0xfce00053).nopw();
map(0xfce00058, 0xfce0005b).nopw();
map(0xfce0005c, 0xfce0005f).nopw();
map(0xfce00300, 0xfce00303).nopw();
map(0xfce00400, 0xfce0045f).writeonly().share("roz_ctrl.0");
map(0xfce00700, 0xfce0075f).writeonly().share("roz_ctrl.1"); // guess
map(0xfce00a00, 0xfce00a17).writeonly().share("tx0_scroll");
map(0xfce00a20, 0xfce00a37).writeonly().share("bg0_scroll");
map(0xfce00c00, 0xfce00c17).writeonly().share("tx1_scroll");
map(0xfce00c20, 0xfce00c37).writeonly().share("bg1_scroll");
map(0xfce00e00, 0xfce00e03).w(FUNC(bnstars_state::bnstars1_mahjong_select_w)); // ?
map(0xfd000000, 0xfd000003).r(FUNC(bnstars_state::ms32_sound_r));
/* wrote together */
map(0xfd040000, 0xfd047fff).ram(); // priority ram
map(0xfd080000, 0xfd087fff).ram();
map(0xfd200000, 0xfd237fff).rw("palette2", FUNC(palette_device::read16), FUNC(palette_device::write16)).umask32(0x0000ffff).share("palette2");
map(0xfd400000, 0xfd437fff).rw(m_palette, FUNC(palette_device::read16), FUNC(palette_device::write16)).umask32(0x0000ffff).share("palette");
map(0xfe000000, 0xfe01ffff).lr16(
NAME([this] (offs_t offset) -> u16 { return m_ms32_roz1_ram[offset]; })).w(FUNC(bnstars_state::ms32_roz1_ram_w)).umask32(0x0000ffff);
map(0xfe400000, 0xfe41ffff).lr16(
NAME([this] (offs_t offset) -> u16 { return m_ms32_roz0_ram[offset]; })).w(FUNC(bnstars_state::ms32_roz0_ram_w)).umask32(0x0000ffff);
map(0xfe800000, 0xfe83ffff).lrw16(
NAME([this] (offs_t offset) -> u16 { return m_ms32_spram[offset]; }),
NAME([this] (offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(&m_ms32_spram[offset]); })).umask32(0x0000ffff);
map(0xfea00000, 0xfea07fff).lr16(
NAME([this] (offs_t offset) -> u16 { return m_ms32_tx1_ram[offset]; })).w(FUNC(bnstars_state::ms32_tx1_ram_w)).umask32(0x0000ffff);
map(0xfea08000, 0xfea0ffff).lr16(
NAME([this] (offs_t offset) -> u16 { return m_ms32_bg1_ram[offset]; })).w(FUNC(bnstars_state::ms32_bg1_ram_w)).umask32(0x0000ffff);
map(0xfec00000, 0xfec07fff).lr16(
NAME([this] (offs_t offset) -> u16 { return m_ms32_tx0_ram[offset]; })).w(FUNC(bnstars_state::ms32_tx0_ram_w)).umask32(0x0000ffff);
map(0xfec08000, 0xfec0ffff).lr16(
NAME([this] (offs_t offset) -> u16 { return m_ms32_bg0_ram[offset]; })).w(FUNC(bnstars_state::ms32_bg0_ram_w)).umask32(0x0000ffff);
map(0xfee00000, 0xfee1ffff).ram();
map(0xffe00000, 0xffffffff).rom().region("maincpu", 0);
}
void bnstars_state::bnstars_sound_map(address_map &map)
{
map(0x0000, 0x3eff).rom();
map(0x3f00, 0x3f0f).rw("ymf2", FUNC(ymf271_device::read), FUNC(ymf271_device::write));
map(0x3f10, 0x3f10).rw(FUNC(bnstars_state::latch_r), FUNC(bnstars_state::to_main_w));
map(0x3f20, 0x3f2f).rw("ymf1", FUNC(ymf271_device::read), FUNC(ymf271_device::write));
map(0x3f40, 0x3f40).nopw(); /* YMF271 pin 4 (bit 1) , YMF271 pin 39 (bit 4) */
map(0x3f70, 0x3f70).nopw(); // watchdog? banking? very noisy
map(0x3f80, 0x3f80).w(FUNC(bnstars_state::ms32_snd_bank_w));
map(0x4000, 0x7fff).ram();
map(0x8000, 0xbfff).bankr("z80bank1");
map(0xc000, 0xffff).bankr("z80bank2");
}
void bnstars_state::bnstars(machine_config &config)
{
/* basic machine hardware */
V70(config, m_maincpu, XTAL(40'000'000)/2); // 20MHz (40MHz / 2)
m_maincpu->set_addrmap(AS_PROGRAM, &bnstars_state::bnstars_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(ms32_state::irq_callback));
TIMER(config, "scantimer").configure_scanline(FUNC(bnstars_state::ms32_interrupt), "lscreen", 0, 1);
m_maincpu->set_addrmap(AS_PROGRAM, &ms32_bnstars_state::bnstars_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(ms32_bnstars_state::irq_callback));
Z80(config, m_audiocpu, XTAL(8'000'000)); // 8MHz present on sound PCB, Verified
m_audiocpu->set_addrmap(AS_PROGRAM, &bnstars_state::bnstars_sound_map);
m_audiocpu->set_addrmap(AS_PROGRAM, &ms32_bnstars_state::bnstars_sound_map);
config.set_maximum_quantum(attotime::from_hz(60000));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_bnstars);
auto &palette(PALETTE(config, "palette"));
palette.set_format(palette_device::xBRG_888, 0x8000);
palette.set_membits(16);
auto &palette2(PALETTE(config, "palette2"));
palette2.set_format(palette_device::xBRG_888, 0x8000);
palette2.set_membits(16);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video?
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
config.set_default_layout(layout_dualhsxs);
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
lscreen.set_refresh_hz(60);
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
lscreen.set_size(40*8, 32*8);
lscreen.set_visarea(0*8, 40*8-1, 0*8, 28*8-1);
lscreen.set_screen_update(FUNC(bnstars_state::screen_update_bnstars_left));
lscreen.set_palette("palette");
for (unsigned i=0; i < 2; i++)
{
PALETTE(config, m_palette[i]).set_entries(0x8000);
SCREEN(config, m_screen[i], SCREEN_TYPE_RASTER);
m_screen[i]->set_raw(XTAL(48'000'000)/8, 384, 0, 320, 263, 0, 224); // default CRTC setup
m_screen[i]->set_palette(m_palette[i]);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite[i], XTAL(48'000'000)); // 48MHz for video?
m_sprite[i]->set_palette(m_palette[i]);
m_sprite[i]->set_color_base(0);
m_sprite[i]->set_color_entries(16);
}
screen_device &rscreen(SCREEN(config, "rscreen", SCREEN_TYPE_RASTER));
rscreen.set_refresh_hz(60);
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(40*8, 32*8);
rscreen.set_visarea(0*8, 40*8-1, 0*8, 28*8-1);
rscreen.set_screen_update(FUNC(bnstars_state::screen_update_bnstars_right));
rscreen.set_palette("palette2");
GFXDECODE(config, m_gfxdecode[0], m_palette[0], gfx_bnstars_left);
GFXDECODE(config, m_gfxdecode[1], m_palette[1], gfx_bnstars_right);
m_screen[0]->set_screen_update(FUNC(ms32_bnstars_state::screen_update_dual<0>));
m_screen[1]->set_screen_update(FUNC(ms32_bnstars_state::screen_update_dual<1>));
JALECO_MS32_SYSCTRL(config, m_sysctrl, XTAL(48'000'000), m_screen[0]);
m_sysctrl->flip_screen_cb().set(FUNC(ms32_bnstars_state::flipscreen_dual_w));
m_sysctrl->vblank_cb().set(FUNC(ms32_bnstars_state::vblank_irq_w));
m_sysctrl->field_cb().set(FUNC(ms32_bnstars_state::field_irq_w));
m_sysctrl->prg_timer_cb().set(FUNC(ms32_bnstars_state::timer_irq_w));
m_sysctrl->sound_ack_cb().set(FUNC(ms32_bnstars_state::sound_ack_w));
m_sysctrl->sound_reset_cb().set(FUNC(ms32_bnstars_state::sound_reset_line_w));
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
@ -843,17 +712,19 @@ void bnstars_state::bnstars(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI);
ymf271_device &ymf1(YMF271(config, "ymf1", XTAL(16'934'400))); // 16.9344MHz
ymf1.add_route(0, "lspeaker", 1.0);
ymf1.add_route(1, "rspeaker", 1.0);
// ymf1.add_route(2, "lspeaker", 1.0); Output 2/3 not used?
// ymf1.add_route(3, "rspeaker", 1.0);
YMF271(config, m_ymf[0], XTAL(16'934'400)); // 16.9344MHz
m_ymf[0]->add_route(0, "lspeaker", 1.0);
m_ymf[0]->add_route(1, "rspeaker", 1.0);
// Output 2/3 not used?
// m_ymf[0]->add_route(2, "lspeaker", 1.0);
// m_ymf[0]->add_route(3, "rspeaker", 1.0);
ymf271_device &ymf2(YMF271(config, "ymf2", XTAL(16'934'400))); // 16.9344MHz
ymf2.add_route(0, "lspeaker", 1.0);
ymf2.add_route(1, "rspeaker", 1.0);
// ymf2.add_route(2, "lspeaker", 1.0); Output 2/3 not used?
// ymf2.add_route(3, "rspeaker", 1.0);
YMF271(config, m_ymf[1], XTAL(16'934'400)); // 16.9344MHz
m_ymf[1]->add_route(0, "lspeaker", 1.0);
m_ymf[1]->add_route(1, "rspeaker", 1.0);
// Output 2/3 not used?
// m_ymf[1]->add_route(2, "lspeaker", 1.0);
// m_ymf[1]->add_route(3, "rspeaker", 1.0);
}
@ -865,7 +736,7 @@ ROM_START( bnstars1 )
ROM_LOAD32_BYTE( "mb-93142.39", 0x000000, 0x80000, CRC(56b98539) SHA1(5eb0e77729b31e6a100c1b43813a39fea57bedee) )
/* Sprites - shared by both screens? */
ROM_REGION( 0x1000000, "sprite", 0 ) /* sprites */
ROM_REGION( 0x1000000, "sprite.0", 0 ) /* sprites */
ROM_LOAD32_WORD( "mr96004-01.20", 0x0000000, 0x200000, CRC(3366d104) SHA1(2de0cabe2ead777b5b02cade7f2003ef7f90b75b) )
ROM_LOAD32_WORD( "mr96004-02.28", 0x0000002, 0x200000, CRC(ad556664) SHA1(4b36f8d8d9efa37cf515af41d14433e7eafa27a2) )
ROM_LOAD32_WORD( "mr96004-03.21", 0x0400000, 0x200000, CRC(b399e2b1) SHA1(9b6a00a219db8d66dcf592160b7b5f7a86b8f0c9) )
@ -875,6 +746,9 @@ ROM_START( bnstars1 )
ROM_LOAD32_WORD( "mr96004-07.23", 0x0c00000, 0x200000, CRC(177e32fa) SHA1(3ca1f397dc28f1fa3a4136705b92c63e4e438f05) )
ROM_LOAD32_WORD( "mr96004-08.31", 0x0c00002, 0x200000, CRC(f6df27b2) SHA1(60590976020d86bdccd4eaf57b349ea31bec6830) )
ROM_REGION( 0x1000000, "sprite.1", 0 )
ROM_COPY( "sprite.0", 0, 0, 0x1000000)
/* Roz Tiles #1 (Screen 1) */
ROM_REGION( 0x400000, "gfx2", 0 ) /* roz tiles */
ROM_LOAD( "mr96004-09.1", 0x000000, 0x400000, CRC(7f8ea9f0) SHA1(f1fe682dcb884f1aa4a5536e17ab94157a99f519) )
@ -904,17 +778,17 @@ ROM_START( bnstars1 )
ROM_LOAD( "sb93145.5", 0x000000, 0x040000, CRC(0424e899) SHA1(fbcdebfa3d5f52b10cf30f7e416f5f53994e4d55) )
/* Samples #1 (Screen 1?) */
ROM_REGION( 0x400000, "ymf1", 0 ) /* samples - 8-bit signed PCM */
ROM_REGION( 0x400000, "ymf.1", 0 ) /* samples - 8-bit signed PCM */
ROM_LOAD( "mr96004-10.1", 0x000000, 0x400000, CRC(83f4303a) SHA1(90ee010591afe1d35744925ef0e8d9a7e2ef3378) )
/* Samples #2 (Screen 2?) */
ROM_REGION( 0x400000, "ymf2", 0 ) /* samples - 8-bit signed PCM */
ROM_REGION( 0x400000, "ymf.2", 0 ) /* samples - 8-bit signed PCM */
ROM_LOAD( "mr96004-10.1", 0x000000, 0x400000, CRC(83f4303a) SHA1(90ee010591afe1d35744925ef0e8d9a7e2ef3378) )
ROM_END
/* SS92046_01: bbbxing, f1superb, tetrisp, hayaosi1 */
void bnstars_state::init_bnstars()
void ms32_bnstars_state::init_bnstars()
{
decrypt_ms32_tx(machine(), 0x00020,0x7e, "gfx5");
decrypt_ms32_bg(machine(), 0x00001,0x9b, "gfx4");
@ -924,4 +798,4 @@ void bnstars_state::init_bnstars()
configure_banks();
}
GAME( 1997, bnstars1, 0, bnstars, bnstars, bnstars_state, init_bnstars, ROT0, "Jaleco", "Vs. Janshi Brandnew Stars", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, bnstars1, 0, bnstars, bnstars, ms32_bnstars_state, init_bnstars, ROT0, "Jaleco", "Vs. Janshi Brandnew Stars", MACHINE_IMPERFECT_GRAPHICS )

View File

@ -474,9 +474,10 @@ Notes from Charles MacDonald
#include "cpu/z80/z80.h"
#include "cpu/v60/v60.h"
#include "sound/ymf271.h"
#include "speaker.h"
#include "f1superb.lh"
/********** READ INPUTS **********/
@ -509,19 +510,7 @@ CUSTOM_INPUT_MEMBER(ms32_state::mahjong_ctrl_r)
return mj_input & 0xff;
}
u32 ms32_state::ms32_read_inputs3()
{
int a,b,c,d;
a = ioport("AN2")->read(); // unused?
b = ioport("AN2")->read(); // unused?
c = ioport("AN1")->read();
d = (ioport("AN0")->read() - 0xb0) & 0xff;
return a << 24 | b << 16 | c << 8 | d << 0;
}
void ms32_state::ms32_sound_w(u32 data)
void ms32_base_state::sound_command_w(u32 data)
{
m_soundlatch->write(data & 0xff);
@ -529,22 +518,13 @@ void ms32_state::ms32_sound_w(u32 data)
m_maincpu->spin_until_time(attotime::from_usec(40));
}
u32 ms32_state::ms32_sound_r()
u32 ms32_base_state::sound_result_r()
{
// tp2m32 never pings the sound ack, so irq ack is most likely done here
irq_raise(1, false);
return m_to_main^0xff;
}
void ms32_state::reset_sub_w(u32 data)
{
if(data) m_audiocpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero); // 0 too ?
}
/********** MEMORY MAP **********/
u8 ms32_state::ms32_nvram_r8(offs_t offset)
{
return m_nvram_8[offset];
@ -629,7 +609,7 @@ void ms32_state::ms32_bgram_w16(offs_t offset, u16 data, u16 mem_mask)
m_bg_tilemap_alt->mark_tile_dirty(offset/2);
}
void ms32_state::pip_w(u32 data)
void ms32_state::bgmode_w(u32 data)
{
m_tilemaplayoutcontrol = data;
@ -648,41 +628,72 @@ void ms32_state::coin_counter_w(u32 data)
void ms32_state::ms32_map(address_map &map)
{
/* RAM areas verified by testing on real hw - usually accessed at the 0xfc000000 + mirror */
map(0xc0000000, 0xc0007fff).rw(FUNC(ms32_state::ms32_nvram_r8), FUNC(ms32_state::ms32_nvram_w8)).umask32(0x000000ff).mirror(0x3c1f8000); // nvram is 8-bit wide, 0x2000 in size */
/* map(0xc0008000, 0xc01fffff) // mirrors of nvramram, handled above */
map(0xc1180000, 0xc1187fff).rw(FUNC(ms32_state::ms32_priram_r8), FUNC(ms32_state::ms32_priram_w8)).umask32(0x000000ff).mirror(0x3c038000).share("priram"); /* priram is 8-bit wide, 0x2000 in size */
/* map(0xc1188000, 0xc11bffff) // mirrors of priram, handled above */
map(0xc1400000, 0xc143ffff).rw(FUNC(ms32_state::ms32_palram_r16), FUNC(ms32_state::ms32_palram_w16)).umask32(0x0000ffff).mirror(0x3c1c0000).share("palram"); /* palram is 16-bit wide, 0x20000 in size */
/* map(0xc1440000, 0xc145ffff) // mirrors of palram, handled above */
map(0xc2000000, 0xc201ffff).rw(FUNC(ms32_state::ms32_rozram_r16), FUNC(ms32_state::ms32_rozram_w16)).umask32(0x0000ffff).mirror(0x3c1e0000).share("rozram"); /* rozram is 16-bit wide, 0x10000 in size */
/* map(0xc2020000, 0xc21fffff) // mirrors of rozram, handled above */
map(0xc2200000, 0xc2201fff).rw(FUNC(ms32_state::ms32_lineram_r16), FUNC(ms32_state::ms32_lineram_w16)).umask32(0x0000ffff).mirror(0x3c1fe000).share("lineram"); /* lineram is 16-bit wide, 0x1000 in size */
/* map(0xc2202000, 0xc23fffff) // mirrors of lineram, handled above */
map(0xc2800000, 0xc283ffff).rw(FUNC(ms32_state::ms32_sprram_r16), FUNC(ms32_state::ms32_sprram_w16)).umask32(0x0000ffff).mirror(0x3c1c0000).share("sprram"); /* spriteram is 16-bit wide, 0x20000 in size */
/* map(0xc2840000, 0xc29fffff) // mirrors of sprram, handled above */
map(0xc2c00000, 0xc2c07fff).rw(FUNC(ms32_state::ms32_txram_r16), FUNC(ms32_state::ms32_txram_w16)).umask32(0x0000ffff).mirror(0x3c1f0000).share("txram"); /* txram is 16-bit wide, 0x4000 in size */
map(0xc2c08000, 0xc2c0ffff).rw(FUNC(ms32_state::ms32_bgram_r16), FUNC(ms32_state::ms32_bgram_w16)).umask32(0x0000ffff).mirror(0x3c1f0000).share("bgram"); /* bgram is 16-bit wide, 0x4000 in size */
/* map(0xc2c10000, 0xc2dfffff) // mirrors of txram / bg, handled above */
map(0xc2e00000, 0xc2e1ffff).ram().share("mainram").mirror(0x3c0e0000); /* mainram is 32-bit wide, 0x20000 in size */
map(0xc3e00000, 0xc3ffffff).rom().region("maincpu", 0).mirror(0x3c000000); // ROM is 32-bit wide, 0x200000 in size */
// 0xfc000000 NVRAM (8-bits wide, 0x2000 in size)
map(0xc0000000, 0xc0007fff).rw(FUNC(ms32_state::ms32_nvram_r8), FUNC(ms32_state::ms32_nvram_w8)).umask32(0x000000ff).mirror(0x3c1f8000);
// map(0xc0008000, 0xc01fffff) // mirrors of nvramram, handled above
/* todo: clean up the mapping of these */
map(0xfc800000, 0xfc800003).nopr(); /* sound? */
map(0xfc800000, 0xfc800003).w(FUNC(ms32_state::ms32_sound_w)); /* sound? */
// 0xfd180000 Priority RAM (8-bits wide, 0x2000 in size)
map(0xc1180000, 0xc1187fff).rw(FUNC(ms32_state::ms32_priram_r8), FUNC(ms32_state::ms32_priram_w8)).umask32(0x000000ff).mirror(0x3c038000);
// map(0xc1188000, 0xc11bffff) // mirrors of priram, handled above
// 0xfd200000 palette related, unknown
// 0xfd400000 paletteram (16-bits wide, 0x20000 in size)
// 0xfd400000 object palette
// 0xfd408000 Background palette
// 0xfd410000 ROZ1 palette
// 0xfd420000 ROZ0 palette?
// 0xfd430000 ASCII palette
map(0xc1400000, 0xc143ffff).rw(FUNC(ms32_state::ms32_palram_r16), FUNC(ms32_state::ms32_palram_w16)).umask32(0x0000ffff).mirror(0x3c1c0000);
// map(0xc1440000, 0xc145ffff) // mirrors of palram, handled above
// 0xfe000000 ROZ1 VRAM (16-bits wide, 0x10000 in size)
map(0xc2000000, 0xc201ffff).rw(FUNC(ms32_state::ms32_rozram_r16), FUNC(ms32_state::ms32_rozram_w16)).umask32(0x0000ffff).mirror(0x3c1e0000);
// map(0xc2020000, 0xc21fffff) // mirrors of rozram, handled above
// 0xfe200000 ROZ1 line RAM (16-bits wide, 0x1000 in size)
map(0xc2200000, 0xc2201fff).rw(FUNC(ms32_state::ms32_lineram_r16), FUNC(ms32_state::ms32_lineram_w16)).umask32(0x0000ffff).mirror(0x3c1fe000);
// map(0xc2202000, 0xc23fffff) // mirrors of lineram, handled above
// 0xfe400000 ROZ0 VRAM?
// 0xfe600000 ROZ0 line RAM?
// 0xfe800000 object layer VRAM (16-bits wide, 0x10000 in size)
map(0xc2800000, 0xc281ffff).rw(FUNC(ms32_state::ms32_sprram_r16), FUNC(ms32_state::ms32_sprram_w16)).umask32(0x0000ffff).mirror(0x3c1e0000);
// map(0xc2820000, 0xc29fffff) // mirrors of sprram, handled above
// 0xfec00000 ASCII layer VRAM (16-bits wide, 0x4000 in size)
map(0xc2c00000, 0xc2c07fff).rw(FUNC(ms32_state::ms32_txram_r16), FUNC(ms32_state::ms32_txram_w16)).umask32(0x0000ffff).mirror(0x3c1f0000);
// 0xfec08000 Background layer VRAM (16-bits wide, 0x4000 in size)
map(0xc2c08000, 0xc2c0ffff).rw(FUNC(ms32_state::ms32_bgram_r16), FUNC(ms32_state::ms32_bgram_w16)).umask32(0x0000ffff).mirror(0x3c1f0000);
// map(0xc2c10000, 0xc2dfffff) // mirrors of txram / bg, handled above
// 0xfee00000 Scratch RAM (32-bit wide, 0x20000 in size)
map(0xc2e00000, 0xc2e1ffff).ram().mirror(0x3c0e0000);
// 0xffc00000 ROM (32-bit wide, 0x200000 in size)
map(0xc3e00000, 0xc3ffffff).rom().region("maincpu", 0).mirror(0x3c000000);
// I/O section
// TODO: mirrors like above?
map(0xfc800000, 0xfc800003).nopr().w(FUNC(ms32_state::sound_command_w)); // open bus on read?
// map(0xfcc00000, 0xfcc0001f) // input
map(0xfcc00004, 0xfcc00007).portr("INPUTS");
map(0xfcc00010, 0xfcc00013).portr("DSW");
map(0xfce00034, 0xfce00037).nopw(); // irq ack?
map(0xfce00038, 0xfce0003b).w(FUNC(ms32_state::reset_sub_w));
map(0xfce00050, 0xfce0005f).nopw(); // watchdog? I haven't investigated
// map(0xfce00000, 0xfce0007f).writeonly().share("ms32_fce00000"); /* registers not ram? */
map(0xfce00000, 0xfce00003).w(FUNC(ms32_state::ms32_gfxctrl_w)); /* flip screen + other unknown bits */
map(0xfce00280, 0xfce0028f).w(FUNC(ms32_state::ms32_brightness_w)); // global brightness control
/**/map(0xfce00600, 0xfce0065f).ram().share("roz_ctrl"); /* roz control registers */
/**/map(0xfce00a00, 0xfce00a17).ram().share("tx_scroll"); /* tx layer scroll */
/**/map(0xfce00a20, 0xfce00a37).ram().share("bg_scroll"); /* bg layer scroll */
map(0xfce00a7c, 0xfce00a7f).w(FUNC(ms32_state::pip_w)); // ??? layer related? seems to be always 0
map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_state::coin_counter_w)); // coin counters + something else
map(0xfd000000, 0xfd000003).r(FUNC(ms32_state::ms32_sound_r));
// System Registers
map(0xfce00000, 0xfce0005f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap)).umask32(0x0000ffff);
map(0xfce00200, 0xfce0027f).ram().share("sprite_ctrl");
map(0xfce00280, 0xfce0028f).w(FUNC(ms32_state::ms32_brightness_w)); // global brightness control
// map(0xfce00400, 0xfce0045f) // ROZ0 control registers
/**/map(0xfce00600, 0xfce0065f).ram().share("roz_ctrl"); // ROZ1 control registers
/**/map(0xfce00a00, 0xfce00a17).ram().share("tx_scroll"); // ASCII layer scroll
/**/map(0xfce00a20, 0xfce00a37).ram().share("bg_scroll"); // Background layer scroll
map(0xfce00a7c, 0xfce00a7f).w(FUNC(ms32_state::bgmode_w));
// map(0xfce00c00, 0xfce00c1f) // ???
map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_state::coin_counter_w)); // coin counters + something else
map(0xfd000000, 0xfd000003).r(FUNC(ms32_state::sound_result_r));
// Extended I/O
// map(0xfd040000, 0xfd040003)
// map(0xfd080000, 0xfd080003)
// map(0xfd0c0000, 0xfd0c0003)
map(0xfd1c0000, 0xfd1c0003).writeonly().share("mahjong_select");
}
@ -690,51 +701,75 @@ void ms32_state::ms32_map(address_map &map)
/* F1 Super Battle has an extra linemap for the road, and am unknown maths chip (mcu?) handling perspective calculations for the road / corners etc. */
/* it should use its own memory map */
void ms32_state::ms32_extra_w16(offs_t offset, u16 data, u16 mem_mask)
void ms32_f1superbattle_state::road_vram_w16(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_f1superb_extraram[offset]);
COMBINE_DATA(&m_road_vram[offset]);
m_extra_tilemap->mark_tile_dirty(offset/2);
}
u16 ms32_state::ms32_extra_r16(offs_t offset)
u16 ms32_f1superbattle_state::road_vram_r16(offs_t offset)
{
return m_f1superb_extraram[offset];
return m_road_vram[offset];
}
void ms32_state::ms32_irq2_guess_w(u32 data)
void ms32_f1superbattle_state::ms32_irq2_guess_w(u32 data)
{
irq_raise(2);
irq_raise(2, true);
}
void ms32_state::ms32_irq5_guess_w(u32 data)
void ms32_f1superbattle_state::ms32_irq5_guess_w(u32 data)
{
irq_raise(5);
irq_raise(5, true);
}
void ms32_state::f1superb_map(address_map &map)
u32 ms32_f1superbattle_state::analog_r()
{
int a,b,c,d;
a = ioport("AN2")->read(); // unused?
b = ioport("AN2")->read(); // unused?
c = ioport("AN1")->read();
d = (ioport("AN0")->read() - 0xb0) & 0xff;
return a << 24 | b << 16 | c << 8 | d << 0;
}
void ms32_f1superbattle_state::f1superb_map(address_map &map)
{
ms32_map(map);
// comms RAM, 8-bit resolution?
// unsurprisingly it seems to use similar mechanics to other Jaleco games
// Throws "FLAM ERROR" in test mode if irq 11 is enabled
// irq 11 is cleared to port $1e (irq_ack_w) in sysctrl.
map(0xfd0c0000, 0xfd0c0fff).ram();
map(0xfd0d0000, 0xfd0d0003).portr("DSW2"); // MB-93159
map(0xfd0e0000, 0xfd0e0003).r(FUNC(ms32_state::ms32_read_inputs3)).nopw(); // writes 7-led seg at very least
map(0xfd0e0000, 0xfd0e0003).r(FUNC(ms32_f1superbattle_state::analog_r)).nopw(); // writes 7-led seg at very least
map(0xfce00004, 0xfce00023).ram(); // regs?
map(0xfce00200, 0xfce0021f).ram(); // regs?
map(0xfce00800, 0xfce0085f).ram(); // regs?
map(0xfce00800, 0xfce0085f).ram(); // ROZ0 control register (mirrored from 0x400?)
/* these two are almost certainly wrong, they just let you see what
happens if you generate the FPU ints without breaking other games */
map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_state::ms32_irq5_guess_w));
map(0xfd0f0000, 0xfd0f0003).w(FUNC(ms32_state::ms32_irq2_guess_w));
// map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_f1superbattle_state::ms32_irq5_guess_w));
// bit 1: steering shock
// bit 0: seat motor
// map(0xfd0f0000, 0xfd0f0003).w(FUNC(ms32_f1superbattle_state::ms32_irq2_guess_w));
// Note: it is unknown how COPRO irqs actually acks,
// most likely candidate is a 0x06 ping at both $fd1024c8 / $fd1424c8
// irq_2: 0xffe00878 (really unused)
// irq_5: 0xffe008ac
// irq_7: 0xffe008ea (basically identical to irq_5)
// COPRO 1
map(0xfd100000, 0xfd103fff).ram(); // used when you start enabling fpu ints
map(0xfd104000, 0xfd105fff).ram(); // uploads data here
// COPRO 2
map(0xfd140000, 0xfd143fff).ram(); // used when you start enabling fpu ints
map(0xfd144000, 0xfd145fff).ram(); // same data here
// map(0xfd440000, 0xfd47ffff).ram(); // color?
map(0xfdc00000, 0xfdc1ffff).rw(FUNC(ms32_state::ms32_extra_r16), FUNC(ms32_state::ms32_extra_w16)).umask32(0x0000ffff).share("f1sb_extraram"); // definitely line ram
map(0xfdc00000, 0xfdc1ffff).rw(FUNC(ms32_f1superbattle_state::road_vram_r16), FUNC(ms32_f1superbattle_state::road_vram_w16)).umask32(0x0000ffff);
map(0xfde00000, 0xfde1ffff).ram(); // scroll info for lineram?
// map(0xfe202000, 0xfe2fffff).ram(); // vram?
}
/* F1 Super Battle speculation from nuapete
@ -837,14 +872,7 @@ what the operations might be, my maths isn't up to much though...
*/
// map(0xfce00800, 0xfce0085f) // f1superb, roz #2 control?
///**/map(0xfd104000, 0xfd105fff).ram(); /* f1superb */
///**/map(0xfd144000, 0xfd145fff).ram(); /* f1superb */
///**/map(0xfd440000, 0xfd47ffff).ram(); /* f1superb color */
///**/map(0xfdc00000, 0xfdc006ff).ram(); /* f1superb */
///**/map(0xfde00000, 0xfde01fff).ram(); /* f1superb lineram #2? */
///**/map(0xfe202000, 0xfe2fffff).ram(); /* f1superb vram */
// map(0xfd0e0000, 0xfd0e0003).r(FUNC(ms32_state::ms32_read_inputs3)); /* analog controls in f1superb? */
/*************************************
*
@ -1360,7 +1388,7 @@ static INPUT_PORTS_START( hayaosi3 )
PORT_DIPUNKNOWN_DIPLOC( 0x00000004, 0x00000004, "SW2:6" )
INPUT_PORTS_END
static INPUT_PORTS_START( kirarast ) // player 1 inputs done? others?
static INPUT_PORTS_START( kirarast )
PORT_INCLUDE( ms32_mahjong )
PORT_MODIFY("DSW")
@ -1383,7 +1411,7 @@ static INPUT_PORTS_START( kirarast ) // player 1 inputs done? others?
PORT_DIPNAME( 0x00000004, 0x00000004, "Campaign Mode" ) PORT_DIPLOCATION("SW2:6")
PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000004, DEF_STR( On ) )
PORT_DIPNAME( 0x00000008, 0x00000008, "Tumo Pinfu" ) PORT_DIPLOCATION("SW2:5")
PORT_DIPNAME( 0x00000008, 0x00000008, "Tsumo Pinfu" ) PORT_DIPLOCATION("SW2:5") // "Tumo Pinfu" (sic)
PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000008, DEF_STR( On ) )
PORT_DIPNAME( 0x00000010, 0x00000010, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:4")
@ -1400,17 +1428,17 @@ static INPUT_PORTS_START( kirarast ) // player 1 inputs done? others?
PORT_DIPSETTING( 0x00000020, DEF_STR( Hardest ) )
INPUT_PORTS_END
static INPUT_PORTS_START( suchie2 ) // player 1 inputs done? others?
static INPUT_PORTS_START( suchie2 )
PORT_INCLUDE( kirarast )
PORT_MODIFY("INPUTS")
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNUSED ) /* coin 2 is unused */
PORT_MODIFY("DSW")
PORT_DIPNAME( 0x00000400, 0x00000400, "Campaign Mode" ) PORT_DIPLOCATION("SW1:6")
PORT_DIPNAME( 0x00000400, 0x00000400, "Campaign Mode" ) PORT_DIPLOCATION("SW1:6") // "Campain Mode" (sic)
PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000400, DEF_STR( On ) )
PORT_DIPNAME( 0x00000800, 0x00000800, "Tumo Pinfu" ) PORT_DIPLOCATION("SW1:5")
PORT_DIPNAME( 0x00000800, 0x00000800, "Tsumo Pinfu" ) PORT_DIPLOCATION("SW1:5") // "Tumo Pinfu" (sic)
PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000800, DEF_STR( On ) )
PORT_DIPNAME( 0x00001000, 0x00001000, DEF_STR( Demo_Sounds) ) PORT_DIPLOCATION("SW1:4")
@ -1430,12 +1458,11 @@ static INPUT_PORTS_START( suchie2 ) // player 1 inputs done? others?
PORT_DIPSETTING( 0x00000080, DEF_STR( Hardest ) )
INPUT_PORTS_END
static INPUT_PORTS_START( wpksocv2 )
PORT_INCLUDE( ms32 )
PORT_MODIFY("INPUTS")
/* Still missing the correct input for begin the left right movement */
// TODO: Still missing the correct input for begin the left right movement
PORT_BIT( 0x0000000f, 0x00000000, IPT_PEDAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(7) PORT_PLAYER(1)
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_UNUSED )
@ -1476,17 +1503,16 @@ static INPUT_PORTS_START( wpksocv2 )
PORT_DIPSETTING( 0x00200000, DEF_STR( On ) )
PORT_DIPNAME( 0x00c00000, 0x00000000, DEF_STR( Region ) ) PORT_DIPLOCATION("SW3:2,1")
PORT_DIPSETTING( 0x00400000, DEF_STR( USA ) )
PORT_DIPSETTING( 0x00000000, DEF_STR( World ) )
PORT_DIPSETTING( 0x00000000, DEF_STR( Asia ) )
// PORT_DIPSETTING( 0x00800000, "?" )
PORT_DIPSETTING( 0x00c00000, DEF_STR( Japan ) )
INPUT_PORTS_END
static INPUT_PORTS_START( f1superb )
PORT_INCLUDE( ms32 )
PORT_MODIFY("INPUTS")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Shift")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Shift") PORT_TOGGLE
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Brake")
PORT_BIT( 0x0000fffc, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_UNUSED )
@ -1564,7 +1590,6 @@ static INPUT_PORTS_START( f1superb )
PORT_DIPSETTING( 0x0c, "7" )
PORT_DIPSETTING( 0x0e, "8" )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
/********** GFX DECODE **********/
@ -1585,7 +1610,7 @@ static GFXDECODE_START( gfx_f1superb )
GFXDECODE_ENTRY( "gfx2", 0, bglayout, 0x2000, 0x10 )
GFXDECODE_ENTRY( "gfx3", 0, bglayout, 0x1000, 0x10 )
GFXDECODE_ENTRY( "gfx4", 0, txlayout, 0x6000, 0x10 )
GFXDECODE_ENTRY( "gfx5", 0, f1layout, 0x0000, 0x100 ) // not tilemap data?
GFXDECODE_ENTRY( "gfx5", 0, f1layout, 0x0000, 0x80 ) // not tilemap data?
GFXDECODE_END
@ -1599,43 +1624,52 @@ GFXDECODE_END
*/
IRQ_CALLBACK_MEMBER(ms32_state::irq_callback)
IRQ_CALLBACK_MEMBER(ms32_base_state::irq_callback)
{
int i;
// TODO: confirm irq priority
for(i=15; i>=0 && !(m_irqreq & (1<<i)); i--);
m_irqreq &= ~(1<<i);
if(!m_irqreq)
device.execute().set_input_line(0, CLEAR_LINE);
return i;
}
void ms32_state::irq_init()
void ms32_base_state::irq_init()
{
m_irqreq = 0;
m_maincpu->set_input_line(0, CLEAR_LINE);
}
void ms32_state::irq_raise(int level)
{
m_irqreq |= (1<<level);
m_maincpu->set_input_line(0, ASSERT_LINE);
void ms32_base_state::irq_raise(int level, bool state)
{
if (state == true)
m_irqreq |= (1<<level);
else
m_irqreq &= ~(1<<level);
if (m_irqreq)
m_maincpu->set_input_line(0, ASSERT_LINE);
else
m_maincpu->set_input_line(0, CLEAR_LINE);
}
/* TODO: fix this arrangement (derived from old deprecat lib) */
TIMER_DEVICE_CALLBACK_MEMBER(ms32_state::ms32_interrupt)
WRITE_LINE_MEMBER(ms32_base_state::timer_irq_w)
{
int scanline = param;
if( scanline == 0) irq_raise(10);
if( scanline == 8) irq_raise(9);
/* hayaosi1 needs at least 12 IRQ 0 per frame to work (see code at FFE02289)
kirarast needs it too, at least 8 per frame, but waits for a variable amount
47pi2 needs ?? per frame (otherwise it hangs when you lose)
in different points. Could this be a raster interrupt?
Other games using it but not needing it to work:
desertwr
p47aces
*/
if( (scanline % 8) == 0 && scanline <= 224 ) irq_raise(0);
irq_raise(0, state);
}
WRITE_LINE_MEMBER(ms32_base_state::vblank_irq_w)
{
irq_raise(10, state);
}
WRITE_LINE_MEMBER(ms32_base_state::field_irq_w)
{
irq_raise(9, state);
}
WRITE_LINE_MEMBER(ms32_base_state::sound_reset_line_w)
{
if (state)
m_audiocpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
}
@ -1662,27 +1696,35 @@ TIMER_DEVICE_CALLBACK_MEMBER(ms32_state::ms32_interrupt)
code at $38 reads the 2nd command latch ??
*/
u8 ms32_state::latch_r()
u8 ms32_base_state::latch_r()
{
return m_soundlatch->read()^0xff;
}
void ms32_state::ms32_snd_bank_w(u8 data)
void ms32_base_state::ms32_snd_bank_w(u8 data)
{
m_z80bank[0]->set_entry((data >> 0) & 0x0F);
m_z80bank[1]->set_entry((data >> 4) & 0x0F);
m_z80bank[0]->set_entry((data >> 0) & 0x0f);
m_z80bank[1]->set_entry((data >> 4) & 0x0f);
}
void ms32_state::to_main_w(u8 data)
void ms32_base_state::to_main_w(u8 data)
{
m_to_main=data;
irq_raise(1);
m_to_main = data;
irq_raise(1, true);
}
void ms32_state::ms32_sound_map(address_map &map)
WRITE_LINE_MEMBER(ms32_base_state::sound_ack_w)
{
// used by f1superb, is it the reason for sound dying?
if (state)
m_to_main = 0xff;
}
void ms32_base_state::base_sound_map(address_map &map)
{
map(0x0000, 0x3eff).rom();
map(0x3f00, 0x3f0f).rw("ymf", FUNC(ymf271_device::read), FUNC(ymf271_device::write));
// map(0x3f00, 0x3f0f).rw("ymf", FUNC(ymf271_device::read), FUNC(ymf271_device::write));
map(0x3f10, 0x3f10).rw(FUNC(ms32_state::latch_r), FUNC(ms32_state::to_main_w));
map(0x3f20, 0x3f20).nopr(); /* 2nd latch ? */
map(0x3f20, 0x3f20).nopw(); /* to_main2_w ? */
@ -1694,10 +1736,22 @@ void ms32_state::ms32_sound_map(address_map &map)
map(0xc000, 0xffff).bankr("z80bank2");
}
void ms32_state::ms32_sound_map(address_map &map)
{
base_sound_map(map);
map(0x3f00, 0x3f0f).rw(m_ymf, FUNC(ymf271_device::read), FUNC(ymf271_device::write));
}
/********** MACHINE INIT **********/
void ms32_state::machine_reset()
void ms32_base_state::machine_start()
{
save_item(NAME(m_irqreq));
}
void ms32_base_state::machine_reset()
{
for (int bank = 0; bank < 2; bank++)
m_z80bank[bank]->set_entry(bank);
@ -1714,26 +1768,30 @@ void ms32_state::ms32(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &ms32_state::ms32_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(ms32_state::irq_callback));
TIMER(config, "scantimer").configure_scanline(FUNC(ms32_state::ms32_interrupt), "screen", 0, 1);
Z80(config, m_audiocpu, 8000000); // Z0840008PSC, Clock from notes (40MHz / 5 or 48MHz / 6?)
m_audiocpu->set_addrmap(AS_PROGRAM, &ms32_state::ms32_sound_map);
config.set_maximum_quantum(attotime::from_hz(60000));
JALECO_MS32_SYSCTRL(config, m_sysctrl, XTAL(48'000'000), m_screen);
m_sysctrl->flip_screen_cb().set(FUNC(ms32_state::flipscreen_w));
m_sysctrl->vblank_cb().set(FUNC(ms32_state::vblank_irq_w));
m_sysctrl->field_cb().set(FUNC(ms32_state::field_irq_w));
m_sysctrl->prg_timer_cb().set(FUNC(ms32_state::timer_irq_w));
m_sysctrl->sound_ack_cb().set(FUNC(ms32_state::sound_ack_w));
m_sysctrl->sound_reset_cb().set(FUNC(ms32_state::sound_reset_line_w));
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
m_screen->set_size(40*8, 28*8);
m_screen->set_visarea(0*8, 40*8-1, 0*8, 28*8-1);
m_screen->set_screen_update(FUNC(ms32_state::screen_update_ms32));
m_screen->screen_vblank().set(FUNC(ms32_state::screen_vblank_ms32));
// dot clock is 48/8 MHz, settable with /6 thru system register [0]
m_screen->set_raw(XTAL(48'000'000)/8, 384, 0, 320, 263, 0, 224); // default CRTC setup
m_screen->set_screen_update(FUNC(ms32_state::screen_update));
m_screen->screen_vblank().set(FUNC(ms32_state::screen_vblank));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_ms32);
PALETTE(config, m_palette).set_entries(0x10000);
PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video?
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)/8);
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
@ -1745,22 +1803,28 @@ void ms32_state::ms32(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI);
ymf271_device &ymf(YMF271(config, "ymf", XTAL(16'934'400))); // 16.9344MHz
ymf.add_route(0, "lspeaker", 1.0);
ymf.add_route(1, "rspeaker", 1.0);
// ymf.add_route(2, "lspeaker", 1.0); Output 2/3 not used?
// ymf.add_route(3, "rspeaker", 1.0);
YMF271(config, m_ymf, XTAL(16'934'400)); // 16.9344MHz
m_ymf->add_route(0, "lspeaker", 1.0);
m_ymf->add_route(1, "rspeaker", 1.0);
// Output 2/3 not used?
// m_ymf->add_route(2, "lspeaker", 1.0);
// m_ymf->add_route(3, "rspeaker", 1.0);
}
void ms32_state::f1superb(machine_config &config)
void ms32_state::ms32_invert_lines(machine_config &config)
{
ms32(config);
/* basic machine hardware */
m_maincpu->set_addrmap(AS_PROGRAM, &ms32_state::f1superb_map);
m_sysctrl->set_invert_vblank_lines(true);
}
void ms32_f1superbattle_state::f1superb(machine_config &config)
{
ms32(config);
m_maincpu->set_addrmap(AS_PROGRAM, &ms32_f1superbattle_state::f1superb_map);
m_gfxdecode->set_info(gfx_f1superb);
MCFG_VIDEO_START_OVERRIDE(ms32_state,f1superb)
// MCFG_VIDEO_START_OVERRIDE(ms32_state,f1superb)
}
@ -2591,7 +2655,7 @@ ROM_START( wpksocv2 )
ROM_END
void ms32_state::configure_banks()
void ms32_base_state::configure_banks()
{
save_item(NAME(m_to_main));
for (int bank = 0; bank < 2; bank++)
@ -2647,11 +2711,13 @@ void ms32_state::init_suchie2()
init_ss92048_01();
}
void ms32_state::init_f1superb()
void ms32_f1superbattle_state::init_f1superb()
{
#if 0 // we shouldn't need this hack, something else is wrong, and the x offsets are never copied either, v70 problems??
#if 0
// hack for ?, game needs FPUs emulated anyway, eventually remove me
u32 *pROM = (u32 *)memregion("maincpu")->base();
pROM[0x19d04/4]=0x167a021a; // bne->br : sprite Y offset table is always copied to RAM
// the x offsets are never copied either ...
#endif
init_ss92046_01();
}
@ -2664,25 +2730,25 @@ void ms32_state::init_bnstars()
/********** GAME DRIVERS **********/
// TODO: inputs in akiss, bnstars (former has no dip display in service mode)
GAME( 1994, hayaosi2, 0, ms32, hayaosi2, ms32_state, init_ss92046_01, ROT0, "Jaleco", "Hayaoshi Quiz Grand Champion Taikai", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1994, hayaosi3, 0, ms32, hayaosi3, ms32_state, init_ss92046_01, ROT0, "Jaleco", "Hayaoshi Quiz Nettou Namahousou (ver 1.5)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1994, hayaosi3a, hayaosi3, ms32, hayaosi3, ms32_state, init_ss92046_01, ROT0, "Jaleco", "Hayaoshi Quiz Nettou Namahousou (ver 1.2)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1994, bbbxing, 0, ms32, bbbxing, ms32_state, init_ss92046_01, ROT0, "Jaleco", "Best Bout Boxing (ver 1.3)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1994, bbbxing, 0, ms32, bbbxing, ms32_state, init_ss92046_01, ROT0, "Jaleco", "Best Bout Boxing (ver 1.3)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL )
GAME( 1994, suchie2, 0, ms32, suchie2, ms32_state, init_suchie2, ROT0, "Jaleco", "Idol Janshi Suchie-Pai II (ver 1.1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1994, suchie2o, suchie2, ms32, suchie2, ms32_state, init_suchie2, ROT0, "Jaleco", "Idol Janshi Suchie-Pai II (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, desertwr, 0, ms32, desertwr, ms32_state, init_ss91022_10, ROT270, "Jaleco", "Desert War / Wangan Sensou (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, gametngk, 0, ms32, gametngk, ms32_state, init_ss91022_10, ROT270, "Jaleco", "The Game Paradise - Master of Shooting! / Game Tengoku - The Game Paradise (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, tetrisp, 0, ms32, tetrisp, ms32_state, init_ss92046_01, ROT0, "Jaleco / BPS", "Tetris Plus (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, p47aces, 0, ms32, p47aces, ms32_state, init_ss92048_01, ROT0, "Jaleco", "P-47 Aces (ver 1.1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, p47acesa, p47aces, ms32, p47aces, ms32_state, init_ss92048_01, ROT0, "Jaleco", "P-47 Aces (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, akiss, 0, ms32, suchie2, ms32_state, init_kirarast, ROT0, "Jaleco", "Mahjong Angel Kiss (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1996, gratia, 0, ms32, gratia, ms32_state, init_ss92047_01, ROT0, "Jaleco", "Gratia - Second Earth (ver 1.0, 92047-01 version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1996, gratiaa, gratia, ms32, gratia, ms32_state, init_ss91022_10, ROT0, "Jaleco", "Gratia - Second Earth (ver 1.0, 91022-10 version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1996, kirarast, 0, ms32, kirarast, ms32_state, init_kirarast, ROT0, "Jaleco", "Ryuusei Janshi Kirara Star", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1997, tp2m32, tetrisp2, ms32, tp2m32, ms32_state, init_ss91022_10, ROT0, "Jaleco", "Tetris Plus 2 (ver 1.0, MegaSystem 32 Version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1997, bnstars, bnstars1, ms32, suchie2, ms32_state, init_bnstars, ROT0, "Jaleco", "Vs. Janshi Brandnew Stars (Ver 1.1, MegaSystem32 Version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1996, wpksocv2, 0, ms32, wpksocv2, ms32_state, init_ss92046_01, ROT0, "Jaleco", "World PK Soccer V2 (ver 1.1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, desertwr, 0, ms32, desertwr, ms32_state, init_ss91022_10, ROT270, "Jaleco", "Desert War / Wangan Sensou (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1995, gametngk, 0, ms32, gametngk, ms32_state, init_ss91022_10, ROT270, "Jaleco", "The Game Paradise - Master of Shooting! / Game Tengoku - The Game Paradise (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1995, tetrisp, 0, ms32, tetrisp, ms32_state, init_ss92046_01, ROT0, "Jaleco / BPS", "Tetris Plus (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1995, p47aces, 0, ms32, p47aces, ms32_state, init_ss92048_01, ROT0, "Jaleco", "P-47 Aces (ver 1.1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1995, p47acesa, p47aces, ms32, p47aces, ms32_state, init_ss92048_01, ROT0, "Jaleco", "P-47 Aces (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1995, akiss, 0, ms32, suchie2, ms32_state, init_kirarast, ROT0, "Jaleco", "Mahjong Angel Kiss (ver 1.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1996, gratia, 0, ms32, gratia, ms32_state, init_ss92047_01, ROT0, "Jaleco", "Gratia - Second Earth (ver 1.0, 92047-01 version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1996, gratiaa, gratia, ms32, gratia, ms32_state, init_ss91022_10, ROT0, "Jaleco", "Gratia - Second Earth (ver 1.0, 91022-10 version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1996, kirarast, 0, ms32, kirarast, ms32_state, init_kirarast, ROT0, "Jaleco", "Ryuusei Janshi Kirara Star", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1997, tp2m32, tetrisp2, ms32_invert_lines, tp2m32, ms32_state, init_ss91022_10, ROT0, "Jaleco", "Tetris Plus 2 (ver 1.0, MegaSystem 32 Version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1997, bnstars, bnstars1, ms32, suchie2, ms32_state, init_bnstars, ROT0, "Jaleco", "Vs. Janshi Brandnew Stars (Ver 1.1, MegaSystem32 Version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1996, wpksocv2, 0, ms32_invert_lines, wpksocv2, ms32_state, init_ss92046_01, ROT0, "Jaleco", "World PK Soccer V2 (ver 1.1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
/* these boot and show something */
GAME( 1994, f1superb, 0, f1superb, f1superb, ms32_state, init_f1superb, ROT0, "Jaleco", "F-1 Super Battle", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE )
GAMEL( 1994, f1superb, 0, f1superb, f1superb, ms32_f1superbattle_state, init_f1superb, ROT0, "Jaleco", "F-1 Super Battle", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_f1superb )

View File

@ -65,51 +65,6 @@ stepstag:
#include "stepstag.lh"
/***************************************************************************
System Registers
***************************************************************************/
void tetrisp2_state::tetrisp2_systemregs_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_systemregs[offset] = data;
}
}
#define ROCKN_TIMER_BASE attotime::from_nsec(500000)
void tetrisp2_state::rockn_systemregs_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_systemregs[offset] = data;
if (offset == 0x0c)
{
attotime timer = ROCKN_TIMER_BASE * (4096 - data);
m_rockn_timer_l4->adjust(timer, 0, timer);
}
}
}
void tetrisp2_state::rocknms_sub_systemregs_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
{
m_rocknms_sub_systemregs[offset] = data;
if (offset == 0x0c)
{
attotime timer = ROCKN_TIMER_BASE * (4096 - data);
m_rockn_timer_sub_l4->adjust(timer, 0, timer);
}
}
}
/***************************************************************************
@ -182,6 +137,7 @@ u16 tetrisp2_state::rockn_soundvolume_r()
void tetrisp2_state::rockn_soundvolume_w(u16 data)
{
m_rockn_soundvolume = data;
// TODO: unemulated
}
@ -263,23 +219,23 @@ u16 tetrisp2_state::rockn_nvram_r(offs_t offset)
***************************************************************************/
u16 tetrisp2_state::rocknms_main2sub_r()
u16 rocknms_state::rocknms_main2sub_r()
{
return m_rocknms_main2sub;
}
void tetrisp2_state::rocknms_main2sub_w(offs_t offset, u16 data, u16 mem_mask)
void rocknms_state::rocknms_main2sub_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
m_rocknms_main2sub = (data ^ 0xffff);
}
CUSTOM_INPUT_MEMBER(tetrisp2_state::rocknms_main2sub_status_r)
CUSTOM_INPUT_MEMBER(rocknms_state::rocknms_main2sub_status_r)
{
return m_rocknms_sub2main & 0x0003;
return m_rocknms_sub2main & 0x0003;
}
void tetrisp2_state::rocknms_sub2main_w(offs_t offset, u16 data, u16 mem_mask)
void rocknms_state::rocknms_sub2main_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
m_rocknms_sub2main = (data ^ 0xffff);
@ -324,7 +280,7 @@ void tetrisp2_state::tetrisp2_map(address_map &map)
map(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers
map(0xba0000, 0xba001f).w(FUNC(tetrisp2_state::tetrisp2_systemregs_w)); // system param
map(0xba0000, 0xba001f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap));
map(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs
map(0xbe0004, 0xbe0005).r(FUNC(tetrisp2_state::tetrisp2_ip_1_word_r)); // Inputs & protection
@ -389,7 +345,7 @@ void tetrisp2_state::nndmseal_map(address_map &map)
map(0xb80000, 0xb80001).w(FUNC(tetrisp2_state::nndmseal_sound_bank_w));
map(0xba0000, 0xba001f).w(FUNC(tetrisp2_state::rockn_systemregs_w)); // system param
map(0xba0000, 0xba001f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap));
map(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("BUTTONS"); // Inputs
@ -425,7 +381,7 @@ void tetrisp2_state::rockn1_map(address_map &map)
map(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers
map(0xba0000, 0xba001f).w(FUNC(tetrisp2_state::rockn_systemregs_w)); // system param
map(0xba0000, 0xba001f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap));
map(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs
map(0xbe0004, 0xbe0005).portr("SYSTEM"); // Inputs
@ -458,7 +414,7 @@ void tetrisp2_state::rockn2_map(address_map &map)
map(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers
map(0xba0000, 0xba001f).w(FUNC(tetrisp2_state::rockn_systemregs_w)); // system param
map(0xba0000, 0xba001f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap));
map(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs
map(0xbe0004, 0xbe0005).portr("SYSTEM"); // Inputs
@ -467,32 +423,32 @@ void tetrisp2_state::rockn2_map(address_map &map)
}
void tetrisp2_state::rocknms_main_map(address_map &map)
void rocknms_state::rocknms_main_map(address_map &map)
{
map(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x103fff).ram().share("spriteram"); // Object RAM
map(0x104000, 0x107fff).ram(); // Spare Object RAM
map(0x108000, 0x10ffff).ram(); // Work RAM
map(0x200000, 0x23ffff).rw(FUNC(tetrisp2_state::tetrisp2_priority_r), FUNC(tetrisp2_state::tetrisp2_priority_w));
map(0x300000, 0x31ffff).ram().w(FUNC(tetrisp2_state::tetrisp2_palette_w)).share("paletteram"); // Palette
map(0x200000, 0x23ffff).rw(FUNC(rocknms_state::tetrisp2_priority_r), FUNC(rocknms_state::tetrisp2_priority_w));
map(0x300000, 0x31ffff).ram().w(FUNC(rocknms_state::tetrisp2_palette_w)).share("paletteram"); // Palette
// map(0x500000, 0x50ffff).ram(); // Line
map(0x600000, 0x60ffff).ram().w(FUNC(tetrisp2_state::tetrisp2_vram_rot_w)).share("vram_rot"); // Rotation
map(0x800000, 0x803fff).ram().w(FUNC(tetrisp2_state::tetrisp2_vram_fg_w)).share("vram_fg"); // Foreground
map(0x804000, 0x807fff).ram().w(FUNC(tetrisp2_state::tetrisp2_vram_bg_w)).share("vram_bg"); // Background
map(0x600000, 0x60ffff).ram().w(FUNC(rocknms_state::tetrisp2_vram_rot_w)).share("vram_rot"); // Rotation
map(0x800000, 0x803fff).ram().w(FUNC(rocknms_state::tetrisp2_vram_fg_w)).share("vram_fg"); // Foreground
map(0x804000, 0x807fff).ram().w(FUNC(rocknms_state::tetrisp2_vram_bg_w)).share("vram_bg"); // Background
// map(0x808000, 0x809fff).ram(); // ???
map(0x900000, 0x903fff).r(FUNC(tetrisp2_state::rockn_nvram_r)).w(FUNC(tetrisp2_state::tetrisp2_nvram_w)).share("nvram"); // NVRAM
map(0xa30000, 0xa30001).rw(FUNC(tetrisp2_state::rockn_soundvolume_r), FUNC(tetrisp2_state::rockn_soundvolume_w)); // Sound Volume
map(0x900000, 0x903fff).r(FUNC(rocknms_state::rockn_nvram_r)).w(FUNC(rocknms_state::tetrisp2_nvram_w)).share("nvram"); // NVRAM
map(0xa30000, 0xa30001).rw(FUNC(rocknms_state::rockn_soundvolume_r), FUNC(rocknms_state::rockn_soundvolume_w)); // Sound Volume
map(0xa40000, 0xa40003).rw("ymz", FUNC(ymz280b_device::read), FUNC(ymz280b_device::write)).umask16(0x00ff); // Sound
map(0xa44000, 0xa44001).rw(FUNC(tetrisp2_state::rockn_adpcmbank_r), FUNC(tetrisp2_state::rockn_adpcmbank_w)); // Sound Bank
map(0xa44000, 0xa44001).rw(FUNC(rocknms_state::rockn_adpcmbank_r), FUNC(rocknms_state::rockn_adpcmbank_w)); // Sound Bank
map(0xa48000, 0xa48001).nopw(); // YMZ280 Reset
map(0xa00000, 0xa00001).w(FUNC(tetrisp2_state::rocknms_main2sub_w)); // MAIN -> SUB Communication
map(0xb00000, 0xb00001).w(FUNC(tetrisp2_state::tetrisp2_coincounter_w)); // Coin Counter
map(0xa00000, 0xa00001).w(FUNC(rocknms_state::rocknms_main2sub_w)); // MAIN -> SUB Communication
map(0xb00000, 0xb00001).w(FUNC(rocknms_state::tetrisp2_coincounter_w)); // Coin Counter
map(0xb20000, 0xb20001).nopw(); // ???
map(0xb40000, 0xb4000b).writeonly().share("scroll_fg"); // Foreground Scrolling
map(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers
map(0xba0000, 0xba001f).w(FUNC(tetrisp2_state::rockn_systemregs_w)); // system param
map(0xba0000, 0xba001f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap));
map(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS");
map(0xbe0004, 0xbe0005).portr("SYSTEM"); // Inputs
@ -501,33 +457,33 @@ void tetrisp2_state::rocknms_main_map(address_map &map)
}
void tetrisp2_state::rocknms_sub_map(address_map &map)
void rocknms_state::rocknms_sub_map(address_map &map)
{
map(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x103fff).ram().share("spriteram2"); // Object RAM
map(0x104000, 0x107fff).ram(); // Spare Object RAM
map(0x108000, 0x10ffff).ram(); // Work RAM
map(0x200000, 0x23ffff).ram().w(FUNC(tetrisp2_state::rocknms_sub_priority_w)).share("sub_priority"); // Priority
map(0x300000, 0x31ffff).ram().w(FUNC(tetrisp2_state::rocknms_sub_palette_w)).share("sub_paletteram"); // Palette
map(0x200000, 0x23ffff).ram().w(FUNC(rocknms_state::rocknms_sub_priority_w)).share("sub_priority"); // Priority
map(0x300000, 0x31ffff).ram().w(FUNC(rocknms_state::rocknms_sub_palette_w)).share("sub_paletteram"); // Palette
// map(0x500000, 0x50ffff).ram(); // Line
map(0x600000, 0x60ffff).ram().w(FUNC(tetrisp2_state::rocknms_sub_vram_rot_w)).share("sub_vram_rot"); // Rotation
map(0x800000, 0x803fff).ram().w(FUNC(tetrisp2_state::rocknms_sub_vram_fg_w)).share("sub_vram_fg"); // Foreground
map(0x804000, 0x807fff).ram().w(FUNC(tetrisp2_state::rocknms_sub_vram_bg_w)).share("sub_vram_bg"); // Background
map(0x600000, 0x60ffff).ram().w(FUNC(rocknms_state::rocknms_sub_vram_rot_w)).share("sub_vram_rot"); // Rotation
map(0x800000, 0x803fff).ram().w(FUNC(rocknms_state::rocknms_sub_vram_fg_w)).share("sub_vram_fg"); // Foreground
map(0x804000, 0x807fff).ram().w(FUNC(rocknms_state::rocknms_sub_vram_bg_w)).share("sub_vram_bg"); // Background
// map(0x808000, 0x809fff).ram(); // ???
map(0x900000, 0x907fff).ram(); // NVRAM
map(0xa30000, 0xa30001).w(FUNC(tetrisp2_state::rockn_soundvolume_w)); // Sound Volume
map(0xa30000, 0xa30001).w(FUNC(rocknms_state::rockn_soundvolume_w)); // Sound Volume
map(0xa40000, 0xa40003).w("ymz", FUNC(ymz280b_device::write)).umask16(0x00ff); // Sound
map(0xa44000, 0xa44001).w(FUNC(tetrisp2_state::rockn_adpcmbank_w)); // Sound Bank
map(0xa44000, 0xa44001).w(FUNC(rocknms_state::rockn_adpcmbank_w)); // Sound Bank
map(0xa48000, 0xa48001).nopw(); // YMZ280 Reset
map(0xb00000, 0xb00001).w(FUNC(tetrisp2_state::rocknms_sub2main_w)); // MAIN <- SUB Communication
map(0xb00000, 0xb00001).w(FUNC(rocknms_state::rocknms_sub2main_w)); // MAIN <- SUB Communication
map(0xb20000, 0xb20001).nopw(); // ???
map(0xb40000, 0xb4000b).writeonly().share("sub_scroll_fg"); // Foreground Scrolling
map(0xb40010, 0xb4001b).writeonly().share("sub_scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("sub_rotregs"); // Rotation Registers
map(0xba0000, 0xba001f).w(FUNC(tetrisp2_state::rocknms_sub_systemregs_w)); // system param
map(0xba0000, 0xba001f).m(m_sub_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap));
// map(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).rw(FUNC(tetrisp2_state::rocknms_main2sub_r), FUNC(tetrisp2_state::rocknms_sub2main_w)); // MAIN <-> SUB Communication
map(0xbe0002, 0xbe0003).rw(FUNC(rocknms_state::rocknms_main2sub_r), FUNC(rocknms_state::rocknms_sub2main_w)); // MAIN <-> SUB Communication
map(0xbe000a, 0xbe000b).r("watchdog", FUNC(watchdog_timer_device::reset16_r)); // Watchdog
}
@ -681,7 +637,7 @@ void stepstag_state::stepstag_map(address_map &map)
map(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).ram(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers
map(0xba0000, 0xba001f).w(FUNC(stepstag_state::rockn_systemregs_w)); // System param
map(0xba0000, 0xba001f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap));
map(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("BUTTONS"); // Inputs
map(0xbe0004, 0xbe0005).r(FUNC(stepstag_state::stepstag_coins_r)); // Inputs & protection
@ -1081,7 +1037,7 @@ INPUT_PORTS_END
static INPUT_PORTS_START( rocknms )
PORT_START("PLAYERS") // IN0 - $be0002.w
PORT_BIT( 0x0003, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(tetrisp2_state, rocknms_main2sub_status_r) // MAIN -> SUB Communication
PORT_BIT( 0x0003, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(rocknms_state, rocknms_main2sub_status_r) // MAIN -> SUB Communication
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1)
@ -1593,41 +1549,11 @@ GFXDECODE_END
***************************************************************************/
TIMER_CALLBACK_MEMBER(tetrisp2_state::rockn_timer_level4_callback)
{
m_maincpu->set_input_line(4, HOLD_LINE);
}
TIMER_CALLBACK_MEMBER(tetrisp2_state::rockn_timer_sub_level4_callback)
{
m_subcpu->set_input_line(4, HOLD_LINE);
}
TIMER_CALLBACK_MEMBER(tetrisp2_state::rockn_timer_level1_callback)
{
m_maincpu->set_input_line(1, HOLD_LINE);
}
TIMER_CALLBACK_MEMBER(tetrisp2_state::rockn_timer_sub_level1_callback)
{
m_subcpu->set_input_line(1, HOLD_LINE);
}
void tetrisp2_state::init_rockn_timer()
{
m_rockn_timer_l1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tetrisp2_state::rockn_timer_level1_callback),this));
m_rockn_timer_l4 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tetrisp2_state::rockn_timer_level4_callback),this));
m_rockn_timer_l1->adjust(attotime::from_msec(32), 0, attotime::from_msec(32));
save_item(NAME(m_systemregs));
save_item(NAME(m_rocknms_sub_systemregs));
save_item(NAME(m_rockn_protectdata));
save_item(NAME(m_rockn_adpcmbank));
save_item(NAME(m_rockn_soundvolume));
save_item(NAME(m_rocknms_main2sub));
save_item(NAME(m_rocknms_sub2main));
}
void tetrisp2_state::init_rockn()
@ -1648,17 +1574,12 @@ void tetrisp2_state::init_rockn2()
m_rockn_protectdata = 2;
}
void tetrisp2_state::init_rocknms()
void rocknms_state::init_rocknms()
{
init_rockn_timer();
m_rockn_timer_sub_l1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tetrisp2_state::rockn_timer_sub_level1_callback),this));
m_rockn_timer_sub_l4 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tetrisp2_state::rockn_timer_sub_level4_callback),this));
m_rockn_timer_sub_l1->adjust(attotime::from_msec(32), 0, attotime::from_msec(32));
m_rockn_protectdata = 3;
save_item(NAME(m_rocknms_main2sub));
save_item(NAME(m_rocknms_sub2main));
}
void tetrisp2_state::init_rockn3()
@ -1673,34 +1594,68 @@ void stepstag_state::init_stepstag()
m_rockn_protectdata = 1; // unused?
}
WRITE_LINE_MEMBER(tetrisp2_state::field_irq_w)
{
// irq1 is valid on all games but tetrisp2, but always masked by SR?
m_maincpu->set_input_line(1, (state) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER(tetrisp2_state::vblank_irq_w)
{
m_maincpu->set_input_line(2, (state) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER(tetrisp2_state::timer_irq_w)
{
m_maincpu->set_input_line(4, (state) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER(tetrisp2_state::sound_reset_line_w)
{
logerror("%s: sound_reset_line_w %d but no CPU to reset?\n", machine().describe_context(), state);
}
void tetrisp2_state::setup_main_sysctrl(machine_config &config, const XTAL clock)
{
JALECO_MS32_SYSCTRL(config, m_sysctrl, clock, m_screen);
m_sysctrl->flip_screen_cb().set(FUNC(tetrisp2_state::flipscreen_w));
m_sysctrl->vblank_cb().set(FUNC(tetrisp2_state::vblank_irq_w));
m_sysctrl->field_cb().set(FUNC(tetrisp2_state::field_irq_w));
m_sysctrl->prg_timer_cb().set(FUNC(tetrisp2_state::timer_irq_w));
m_sysctrl->sound_reset_cb().set(FUNC(tetrisp2_state::sound_reset_line_w));
}
void tetrisp2_state::setup_main_sprite(machine_config &config, const XTAL clock)
{
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, clock);
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
m_sprite->set_zoom(false);
}
void tetrisp2_state::tetrisp2(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, 12_MHz_XTAL); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::tetrisp2_map);
m_maincpu->set_vblank_int("screen", FUNC(tetrisp2_state::irq2_line_hold));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog").set_vblank_count("screen", 8); /* guess */
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(0x140, 0xe0);
screen.set_visarea(0, 0x140-1, 0, 0xe0-1);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2));
screen.set_palette(m_palette);
constexpr XTAL pixel_clock = XTAL(48'000'000)/8;
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224); // default CRTC setup
m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video?
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
setup_main_sprite(config, pixel_clock);
setup_main_sysctrl(config, XTAL(48'000'000));
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,tetrisp2)
@ -1708,7 +1663,7 @@ void tetrisp2_state::tetrisp2(machine_config &config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
ymz280b_device &ymz(YMZ280B(config, "ymz", 16.9344_MHz_XTAL)); // 16.9344MHz
ymz280b_device &ymz(YMZ280B(config, "ymz", XTAL(16'934'400))); // 16.9344MHz
ymz.add_route(0, "lspeaker", 1.0);
ymz.add_route(1, "rspeaker", 1.0);
}
@ -1719,28 +1674,25 @@ void tetrisp2_state::nndmseal(machine_config &config)
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::nndmseal_map);
m_maincpu->set_vblank_int("screen", FUNC(tetrisp2_state::irq2_line_hold));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(0x180, 0xf0);
screen.set_visarea(0, 0x180-1, 0, 0xf0-1);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2));
screen.set_palette(m_palette);
// An odd one: it uses the faster dot clock divider setting
// but they replaced the xtal to a OSC1(42.9545MHz), I guess they compensated to not go out of ~60 Hz
constexpr XTAL pixel_clock = XTAL(42'954'545)/6;
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(pixel_clock, 455, 0, 384, 262, 0, 240);
m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, 42954500); // OSC1(42.9545MHz) for video?
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
setup_main_sprite(config, pixel_clock);
setup_main_sysctrl(config, XTAL(42'954'545));
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,nndmseal) // bg layer offset
@ -1756,28 +1708,23 @@ void tetrisp2_state::rockn(machine_config &config)
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rockn1_map);
m_maincpu->set_vblank_int("screen", FUNC(tetrisp2_state::irq2_line_hold));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(0x140, 0xe0);
screen.set_visarea(0, 0x140-1, 0, 0xe0-1);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
screen.set_palette(m_palette);
constexpr XTAL pixel_clock = XTAL(48'000'000)/8;
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224);
m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video?
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
setup_main_sprite(config, pixel_clock);
setup_main_sysctrl(config, XTAL(48'000'000));
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,rockntread)
@ -1796,28 +1743,23 @@ void tetrisp2_state::rockn2(machine_config &config)
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rockn2_map);
m_maincpu->set_vblank_int("screen", FUNC(tetrisp2_state::irq2_line_hold));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog");
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(0x140, 0xe0);
screen.set_visarea(0, 0x140-1, 0, 0xe0-1);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
screen.set_palette(m_palette);
constexpr XTAL pixel_clock = XTAL(48'000'000)/8;
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224);
m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video?
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
setup_main_sprite(config, pixel_clock);
setup_main_sysctrl(config, XTAL(48'000'000));
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,rockntread)
@ -1830,17 +1772,34 @@ void tetrisp2_state::rockn2(machine_config &config)
ymz.add_route(1, "rspeaker", 1.0);
}
WRITE_LINE_MEMBER(rocknms_state::sub_field_irq_w)
{
m_subcpu->set_input_line(1, (state) ? ASSERT_LINE : CLEAR_LINE);
}
void tetrisp2_state::rocknms(machine_config &config)
WRITE_LINE_MEMBER(rocknms_state::sub_vblank_irq_w)
{
m_subcpu->set_input_line(2, (state) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER(rocknms_state::sub_timer_irq_w)
{
m_subcpu->set_input_line(4, (state) ? ASSERT_LINE : CLEAR_LINE);
}
WRITE_LINE_MEMBER(rocknms_state::sub_sound_reset_line_w)
{
logerror("%s: sound_reset_line_w %d on sub CPU but no CPU to reset?\n", machine().describe_context(), state);
}
void rocknms_state::rocknms(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rocknms_main_map);
m_maincpu->set_vblank_int("lscreen", FUNC(tetrisp2_state::irq2_line_hold));
m_maincpu->set_addrmap(AS_PROGRAM, &rocknms_state::rocknms_main_map);
M68000(config, m_subcpu, XTAL(12'000'000)); // 12MHz
m_subcpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rocknms_sub_map);
m_subcpu->set_vblank_int("lscreen", FUNC(tetrisp2_state::irq2_line_hold));
m_subcpu->set_addrmap(AS_PROGRAM, &rocknms_state::rocknms_sub_map);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
@ -1848,42 +1807,44 @@ void tetrisp2_state::rocknms(machine_config &config)
/* video hardware */
config.set_default_layout(layout_rocknms);
constexpr XTAL pixel_clock = XTAL(48'000'000)/8;
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_orientation(ROT0);
m_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224);
m_screen->set_screen_update(FUNC(rocknms_state::screen_update_rocknms_left));
SCREEN(config, m_sub_screen, SCREEN_TYPE_RASTER);
m_sub_screen->set_orientation(ROT270);
m_sub_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224);
m_sub_screen->set_screen_update(FUNC(rocknms_state::screen_update_rocknms_right));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000);
GFXDECODE(config, m_sub_gfxdecode, m_sub_palette, gfx_rocknms_sub);
PALETTE(config, m_sub_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video?
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
setup_main_sprite(config, pixel_clock);
JALECO_MEGASYSTEM32_SPRITE(config, m_rocknms_sub_sprite, XTAL(48'000'000)); // 48MHz for video?
JALECO_MEGASYSTEM32_SPRITE(config, m_rocknms_sub_sprite, pixel_clock); // 48MHz for video?
m_rocknms_sub_sprite->set_palette(m_sub_palette);
m_rocknms_sub_sprite->set_color_base(0);
m_rocknms_sub_sprite->set_color_entries(16);
m_rocknms_sub_sprite->set_zoom(false);
config.set_default_layout(layout_rocknms);
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
lscreen.set_orientation(ROT0);
lscreen.set_refresh_hz(60);
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
lscreen.set_size(0x140, 0xe0);
lscreen.set_visarea(0, 0x140-1, 0, 0xe0-1);
lscreen.set_screen_update(FUNC(tetrisp2_state::screen_update_rocknms_left));
screen_device &rscreen(SCREEN(config, "rscreen", SCREEN_TYPE_RASTER));
rscreen.set_orientation(ROT270);
rscreen.set_refresh_hz(60);
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(0x140, 0xe0);
rscreen.set_visarea(0, 0x140-1, 0, 0xe0-1);
rscreen.set_screen_update(FUNC(tetrisp2_state::screen_update_rocknms_right));
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,rocknms)
setup_main_sysctrl(config, XTAL(48'000'000));
JALECO_MS32_SYSCTRL(config, m_sub_sysctrl, XTAL(48'000'000), m_sub_screen);
m_sub_sysctrl->flip_screen_cb().set(FUNC(rocknms_state::sub_flipscreen_w));
m_sub_sysctrl->vblank_cb().set(FUNC(rocknms_state::sub_vblank_irq_w));
m_sub_sysctrl->field_cb().set(FUNC(rocknms_state::sub_field_irq_w));
m_sub_sysctrl->prg_timer_cb().set(FUNC(rocknms_state::sub_timer_irq_w));
m_sub_sysctrl->sound_reset_cb().set(FUNC(rocknms_state::sub_sound_reset_line_w));
MCFG_VIDEO_START_OVERRIDE(rocknms_state,rocknms)
/* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@ -1893,51 +1854,62 @@ void tetrisp2_state::rocknms(machine_config &config)
ymz.add_route(1, "rspeaker", 1.0);
}
TIMER_DEVICE_CALLBACK_MEMBER(stepstag_state::field_cb)
{
// TODO: pinpoint the exact source, translate to configure_scanline if necessary
// irq 4 is definitely a 30 Hz-ish here as well,
// except we have a multi-screen arrangement setup and no way to pinpoint source
m_subcpu->set_input_line(4, HOLD_LINE);
}
void stepstag_state::setup_non_sysctrl_screen(machine_config &config, screen_device *screen, const XTAL xtal)
{
// TODO: unknown clock and parameters
// assume there's a 42.954 MHz/6 like nndmseal to compensate the higher res
screen->set_raw(xtal/6, 455, 0, 352, 262, 0, 240);
}
void stepstag_state::stepstag(machine_config &config)
{
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz?
M68000(config, m_maincpu, XTAL(12'000'000)); // unknown
m_maincpu->set_addrmap(AS_PROGRAM, &stepstag_state::stepstag_map);
m_maincpu->set_vblank_int("mscreen", FUNC(tetrisp2_state::irq2_line_hold)); // lev 4 triggered by system timer
M68000(config, m_subcpu, 16000000); //??
constexpr XTAL subxtal = XTAL(42'954'545); // unknown
constexpr XTAL sub_pixel_clock = subxtal/6;
M68000(config, m_subcpu, subxtal/3);
m_subcpu->set_addrmap(AS_PROGRAM, &stepstag_state::stepstag_sub_map);
m_subcpu->set_vblank_int("lscreen", FUNC(tetrisp2_state::irq4_line_hold)); // lev 6 triggered by main CPU
TIMER(config, "field_timer").configure_periodic(FUNC(stepstag_state::field_cb), attotime::from_hz(30));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog");
// video hardware
// this screen arrangement is weird:
// it writes a regular 320x224 screen setup to the CRTC but none of these matches a 352 width,
// we are either missing a bit from the config regs or those writes are null and
// these screens are driven by something else.
// Also note: main 68k tilemap/sprite/palette aren't even displayed with this arrangement,
// even tho usage is minimal (POST/test mode), maybe just a left-over ...
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
lscreen.set_orientation(ROT270);
// lscreen.set_raw(12288000*2, 768, 0, 496, 264*2,0,480);
lscreen.set_refresh_hz(30);
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
lscreen.set_size(0x160, 0xf0);
lscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
setup_non_sysctrl_screen(config, &lscreen, subxtal);
lscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_left));
// lscreen.set_palette(m_vj_palette_l));
screen_device &mscreen(SCREEN(config, "mscreen", SCREEN_TYPE_RASTER));
mscreen.set_orientation(ROT0);
mscreen.set_refresh_hz(60);
mscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
mscreen.set_size(0x160, 0xf0);
mscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
mscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_mid));
// mscreen.set_palette(m_vj_palette_m));
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_orientation(ROT0);
// TODO: connected to the non sysctrl CRTC anyway?
m_screen->set_raw(XTAL(48'000'000)/8, 384, 0, 320, 263, 0, 224);
m_screen->set_screen_update(FUNC(stepstag_state::screen_update_stepstag_mid));
screen_device &rscreen(SCREEN(config, "rscreen", SCREEN_TYPE_RASTER));
rscreen.set_orientation(ROT270);
rscreen.set_refresh_hz(30);
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(0x160, 0xf0);
rscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
setup_non_sysctrl_screen(config, &rscreen, subxtal);
rscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_right));
rscreen.set_palette(m_vj_palette_r);
MCFG_VIDEO_START_OVERRIDE(stepstag_state, stepstag )
MCFG_VIDEO_START_OVERRIDE(stepstag_state, stepstag)
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000);
@ -1945,28 +1917,37 @@ void stepstag_state::stepstag(machine_config &config)
PALETTE(config, m_vj_palette_m).set_entries(0x8000);
PALETTE(config, m_vj_palette_r).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)/8); // unknown
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
m_sprite->set_zoom(false);
// (left screen, vertical in stepping stage)
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_l, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_l, sub_pixel_clock); // unknown
m_vj_sprite_l->set_palette(m_vj_palette_l);
m_vj_sprite_l->set_color_base(0);
m_vj_sprite_l->set_color_entries(0x80);
m_vj_sprite_l->set_zoom(false);
m_vj_sprite_l->set_yuv(true);
// (mid screen, horizontal)
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_m, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_m, sub_pixel_clock); // unknown
m_vj_sprite_m->set_palette(m_vj_palette_m);
m_vj_sprite_m->set_color_base(0);
m_vj_sprite_m->set_color_entries(0x80);
m_vj_sprite_m->set_zoom(false);
m_vj_sprite_m->set_yuv(true);
// (right screens, vertical in stepping stage)
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_r, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_r, sub_pixel_clock); // unknown
m_vj_sprite_r->set_palette(m_vj_palette_r);
m_vj_sprite_r->set_color_base(0);
m_vj_sprite_r->set_color_entries(0x80);
m_vj_sprite_r->set_zoom(false);
m_vj_sprite_r->set_yuv(true);
setup_main_sysctrl(config, XTAL(48'000'000));
config.set_default_layout(layout_stepstag);
@ -1976,7 +1957,7 @@ void stepstag_state::stepstag(machine_config &config)
GENERIC_LATCH_16(config, m_soundlatch);
ymz280b_device &ymz(YMZ280B(config, "ymz", XTAL(16'934'400))); // 16.9344MHz
ymz280b_device &ymz(YMZ280B(config, "ymz", subxtal/3)); // unknown
ymz.add_route(0, "lspeaker", 1.0);
ymz.add_route(1, "rspeaker", 1.0);
}
@ -1985,49 +1966,37 @@ void stepstag_state::vjdash(machine_config &config) // 4 Screens
{
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz?
m_maincpu->set_addrmap(AS_PROGRAM, &stepstag_state::vjdash_map);
m_maincpu->set_vblank_int("screen", FUNC(tetrisp2_state::irq2_line_hold)); // lev 4 triggered by system timer
M68000(config, m_subcpu, 16000000); //??
constexpr XTAL subxtal = XTAL(42'954'545); // unknown
constexpr XTAL main_pixel_clock = XTAL(48'000'000)/8;
constexpr XTAL sub_pixel_clock = subxtal/6;
M68000(config, m_subcpu, subxtal/3);
m_subcpu->set_addrmap(AS_PROGRAM, &stepstag_state::stepstag_sub_map);
m_subcpu->set_vblank_int("mscreen", FUNC(tetrisp2_state::irq4_line_hold)); // lev 6 triggered by main CPU
TIMER(config, "field_timer").configure_periodic(FUNC(stepstag_state::field_cb), attotime::from_hz(30));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog");
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(0x160, 0xf0);
screen.set_visarea(0, 0x140-1, 0, 0xe0-1);
screen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_main));
// screen.set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
screen.set_palette(m_palette);
// same as stepstag, we assume that this screen is effectively connected to the system CRTC
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(main_pixel_clock, 384, 0, 320, 263, 0, 224);
m_screen->set_screen_update(FUNC(stepstag_state::screen_update_stepstag_main));
m_screen->set_palette(m_palette);
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
lscreen.set_refresh_hz(30);
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
lscreen.set_size(0x160, 0xf0);
lscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
setup_non_sysctrl_screen(config, &lscreen, subxtal);
lscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_left));
// lscreen.set_palette(m_vj_palette_l);
screen_device &mscreen(SCREEN(config, "mscreen", SCREEN_TYPE_RASTER));
mscreen.set_refresh_hz(30);
mscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
mscreen.set_size(0x160, 0xf0);
mscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
setup_non_sysctrl_screen(config, &mscreen, subxtal);
mscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_mid));
// mscreen.set_palette(m_vj_palette_m);
screen_device &rscreen(SCREEN(config, "rscreen", SCREEN_TYPE_RASTER));
rscreen.set_refresh_hz(30);
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(0x160, 0xf0);
rscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
setup_non_sysctrl_screen(config, &rscreen, subxtal);
rscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_right));
rscreen.set_palette(m_vj_palette_r);
MCFG_VIDEO_START_OVERRIDE(stepstag_state, stepstag )
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
@ -2037,28 +2006,33 @@ void stepstag_state::vjdash(machine_config &config) // 4 Screens
PALETTE(config, m_vj_palette_m).set_entries(0x8000);
PALETTE(config, m_vj_palette_r).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, main_pixel_clock); // unknown
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
// (left screen, vertical in stepping stage)
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_l, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_l, sub_pixel_clock); // unknown
m_vj_sprite_l->set_palette(m_vj_palette_l);
m_vj_sprite_l->set_color_base(0);
m_vj_sprite_l->set_color_entries(0x80);
m_vj_sprite_l->set_zoom(false);
// (mid screen, horizontal)
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_m, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_m, sub_pixel_clock); // unknown
m_vj_sprite_m->set_palette(m_vj_palette_m);
m_vj_sprite_m->set_color_base(0);
m_vj_sprite_m->set_color_entries(0x80);
m_vj_sprite_m->set_zoom(false);
// (right screens, vertical in stepping stage)
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_r, 48000000); // unknown
JALECO_MEGASYSTEM32_SPRITE(config, m_vj_sprite_r, sub_pixel_clock); // unknown
m_vj_sprite_r->set_palette(m_vj_palette_r);
m_vj_sprite_r->set_color_base(0);
m_vj_sprite_r->set_color_entries(0x80);
m_vj_sprite_r->set_zoom(false);
setup_main_sysctrl(config, XTAL(48'000'000)); // unknown
config.set_default_layout(layout_vjdash);
@ -2068,7 +2042,7 @@ void stepstag_state::vjdash(machine_config &config) // 4 Screens
GENERIC_LATCH_16(config, m_soundlatch);
ymz280b_device &ymz(YMZ280B(config, "ymz", XTAL(16'934'400))); // 16.9344MHz
ymz280b_device &ymz(YMZ280B(config, "ymz", subxtal/3)); // unknown
ymz.add_route(0, "lspeaker", 1.0);
ymz.add_route(1, "rspeaker", 1.0);
}
@ -2910,14 +2884,14 @@ GAME( 1997, nndmseala, nndmseal, nndmseal, nndmseal, tetrisp2_state, init_rockn
GAME( 1999, rockn, 0, rockn, rockn, tetrisp2_state, init_rockn, ROT270, "Jaleco", "Rock'n Tread (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1999, rockna, rockn, rockn, rockn, tetrisp2_state, init_rockn1, ROT270, "Jaleco", "Rock'n Tread (Japan, alternate)", MACHINE_SUPPORTS_SAVE )
GAME( 1999, rockn2, 0, rockn2, rockn, tetrisp2_state, init_rockn2, ROT270, "Jaleco", "Rock'n Tread 2 (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1999, rocknms, 0, rocknms, rocknms, tetrisp2_state, init_rocknms, ROT0, "Jaleco", "Rock'n MegaSession (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1999, rocknms, 0, rocknms, rocknms, rocknms_state, init_rocknms, ROT0, "Jaleco", "Rock'n MegaSession (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1999, rockn3, 0, rockn2, rockn, tetrisp2_state, init_rockn3, ROT270, "Jaleco", "Rock'n 3 (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 2000, rockn4, 0, rockn2, rockn, tetrisp2_state, init_rockn3, ROT270, "Jaleco / PCCWJ", "Rock'n 4 (Japan, prototype)", MACHINE_SUPPORTS_SAVE )
// Undumped:
// - Stepping Stage <- the original Game
// - Stepping Stage 2 Supreme
// Dumped (partly):
// Dumped (partially):
GAME( 1999, vjdash, 0, vjdash, vjdash, stepstag_state, init_stepstag, ROT0, "Jaleco", "VJ Visual & Music Slap", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
GAME( 1999, stepstag, 0, stepstag, stepstag, stepstag_state, init_stepstag, ROT0, "Jaleco", "Stepping Stage Special", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)
GAME( 1999, step3, 0, stepstag, stepstag, stepstag_state, init_stepstag, ROT0, "Jaleco", "Stepping 3 Superior", MACHINE_NO_SOUND | MACHINE_NOT_WORKING)

View File

@ -0,0 +1,76 @@
# license: BSD-3-Clause
"""Simple Python script to generate a new definition from the template_* files
"""
import argparse
import os
def get_args():
parser = argparse.ArgumentParser(description="""
Create a new device .cpp/.h definition, using template_device.* as a base.
All arguments are sanitized to match the given patterns
"""
)
parser.add_argument(
"-device_file",
required=True,
type=str,
help="The device .cpp/.h base file name, also the header macro directive \"acorn_vidc20.cpp\" -> \"MAME_MACHINE_ACORN_VIDC20_H\""
)
# TODO: directory option, honor with os.getcwd() as default
parser.add_argument(
"-license_opt",
default="BSD-3-Clause",
type=str,
help="License option"
)
parser.add_argument(
"-device_longname",
required=True,
type=str,
help="Friendly name for a device \"Acorn VIDC20\""
)
parser.add_argument(
"-device_classname",
required=True,
type=str,
help="Class declaration \"acorn_vidc20\", this will also be the filename output"
)
parser.add_argument(
"-device_typename",
required=True,
type=str,
help='Type handle declaration \"ACORN_VIDC20\"'
)
parser.add_argument(
"-author_name",
required=True,
type=str,
help="Your author handle name in copyright header"
)
# TODO: add optional structures like device_memory_interface
user_input = vars(parser.parse_args())
return {
**user_input,
"device_header": user_input["device_file"].upper()
}
def sanitize(k, v):
rules_fn = {
"device_typename": lambda v: v.upper().strip(),
"device_classname": lambda v: v.lower().strip()
# TODO: validate license_opt with an enum
}
return rules_fn.get(k, lambda v: v.strip())(v)
if __name__ == '__main__':
args = get_args()
for file_type in [".cpp", ".h"]:
with open(".{0}template_device{1}".format(os.path.sep, file_type), "r", encoding="utf-8", newline="\n") as template_fh:
buf_string = template_fh.read()
for k, v in args.items():
if k == "device_file":
continue
buf_string = buf_string.replace("<" + k + ">", sanitize(k, v))
with open(".{0}{1}{2}".format(os.path.sep, args["device_file"], file_type), "w", encoding="utf-8", newline="\n") as result_fh:
result_fh.write(buf_string)

View File

@ -1,46 +1,47 @@
// license:BSD-3-Clause
// license:<license_opt>
// copyright-holders:<author_name>
/***************************************************************************
Template for skeleton device
<device_longname>
***************************************************************************/
#include "emu.h"
#include "xxx.h"
#include "<device_classname>.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(XXX, xxx_device, "xxx", "XXX")
DEFINE_DEVICE_TYPE(<device_typename>, <device_classname>_device, "<device_classname>", "<device_longname>")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// xxx_device - constructor
// <device_classname>_device - constructor
//-------------------------------------------------
xxx_device::xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, XXX, tag, owner, clock)
<device_classname>_device::<device_classname>_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, <device_typename>, tag, owner, clock)
{
}
//-------------------------------------------------
// device_add_mconfig - device-specific machine
// configuration addiitons
//-------------------------------------------------
void xxx_device::device_add_mconfig(machine_config &config)
void <device_classname>_device::device_add_mconfig(machine_config &config)
{
//DEVICE(config, ...);
}
@ -50,7 +51,8 @@ void xxx_device::device_add_mconfig(machine_config &config)
// device_start - device-specific startup
//-------------------------------------------------
void xxx_device::device_start()
void <device_classname>_device::device_start()
{
}
@ -59,7 +61,8 @@ void xxx_device::device_start()
// device_reset - device-specific reset
//-------------------------------------------------
void xxx_device::device_reset()
void <device_classname>_device::device_reset()
{
}
@ -68,11 +71,13 @@ void xxx_device::device_reset()
// READ/WRITE HANDLERS
//**************************************************************************
uint8_t xxx_device::read(address_space &space, offs_t offset, uint8_t mem_mask = ~0)
uint8_t <device_classname>_device::read(address_space &space, offs_t offset, uint8_t mem_mask = ~0)
{
return 0;
}
void xxx_device::write(address_space &space, offs_t offset, uint8_t data, uint8_t mem_mask = ~0)
void <device_classname>_device::write(address_space &space, offs_t offset, uint8_t data, uint8_t mem_mask = ~0)
{
}

View File

@ -1,35 +1,25 @@
// license:BSD-3-Clause
// license:<license_opt>
// copyright-holders:<author_name>
/***************************************************************************
Template for skeleton device
<device_longname>
***************************************************************************/
#ifndef MAME_MACHINE_XXX_H
#define MAME_MACHINE_XXX_H
#ifndef MAME_MACHINE_<device_header>_H
#define MAME_MACHINE_<device_header>_H
#pragma once
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> xxx_device
class xxx_device : public device_t
class <device_classname>_device : public device_t
{
public:
// construction/destruction
xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
<device_classname>_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// I/O operations
void write(address_space &space, offs_t offset, uint8_t data, uint8_t mem_mask = ~0);
@ -45,13 +35,6 @@ protected:
// device type definition
DECLARE_DEVICE_TYPE(XXX, xxx_device)
DECLARE_DEVICE_TYPE(<device_typename>, <device_classname>_device)
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#endif // MAME_MACHINE_XXX_H
#endif // MAME_MACHINE_<device_header>_H

View File

@ -7,41 +7,83 @@
#include "machine/gen_latch.h"
#include "machine/timer.h"
#include "machine/jaleco_ms32_sysctrl.h"
#include "video/ms32_sprite.h"
#include "sound/ymf271.h"
#include "emupal.h"
#include "screen.h"
#include "tilemap.h"
class ms32_state : public driver_device
class ms32_base_state : public driver_device
{
public:
ms32_base_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_audiocpu(*this, "audiocpu")
, m_soundlatch(*this, "soundlatch")
, m_z80bank(*this, "z80bank%u", 1)
, m_sprite_ctrl(*this, "sprite_ctrl")
{ }
protected:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<generic_latch_8_device> m_soundlatch;
required_memory_bank_array<2> m_z80bank;
required_shared_ptr<u32> m_sprite_ctrl;
DECLARE_WRITE_LINE_MEMBER(timer_irq_w);
DECLARE_WRITE_LINE_MEMBER(vblank_irq_w);
DECLARE_WRITE_LINE_MEMBER(field_irq_w);
DECLARE_WRITE_LINE_MEMBER(sound_ack_w);
DECLARE_WRITE_LINE_MEMBER(sound_reset_line_w);
void ms32_snd_bank_w(u8 data);
IRQ_CALLBACK_MEMBER(irq_callback);
void configure_banks();
u8 latch_r();
void to_main_w(u8 data);
u32 sound_result_r();
void sound_command_w(u32 data);
void irq_raise(int level, bool state);
void irq_init();
virtual void machine_start() override;
virtual void machine_reset() override;
void base_sound_map(address_map &map);
private:
u32 m_to_main;
u16 m_irqreq;
};
class ms32_state : public ms32_base_state
{
public:
ms32_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_palette(*this, "palette"),
m_gfxdecode(*this, "gfxdecode"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_sprite(*this, "sprite"),
m_soundlatch(*this, "soundlatch"),
m_screen(*this, "screen"),
m_mainram(*this, "mainram"),
m_roz_ctrl(*this, "roz_ctrl"),
m_tx_scroll(*this, "tx_scroll"),
m_bg_scroll(*this, "bg_scroll"),
m_mahjong_input_select(*this, "mahjong_select"),
m_priram(*this, "priram"),
m_palram(*this, "palram"),
m_rozram(*this, "rozram"),
m_lineram(*this, "lineram"),
m_sprram(*this, "sprram"),
m_txram(*this, "txram"),
m_bgram(*this, "bgram"),
m_f1superb_extraram(*this, "f1sb_extraram"),
m_z80bank(*this, "z80bank%u", 1)
ms32_base_state(mconfig, type, tag)
, m_sysctrl(*this, "sysctrl")
, m_screen(*this, "screen")
, m_sprite(*this, "sprite")
, m_palette(*this, "palette")
, m_gfxdecode(*this, "gfxdecode")
, m_ymf(*this, "ymf")
, m_roz_ctrl(*this, "roz_ctrl")
, m_tx_scroll(*this, "tx_scroll")
, m_bg_scroll(*this, "bg_scroll")
, m_mahjong_input_select(*this, "mahjong_select")
, m_priram(*this, "priram", 0x2000, ENDIANNESS_LITTLE)
, m_palram(*this, "palram", 0x20000, ENDIANNESS_LITTLE)
, m_rozram(*this, "rozram", 0x10000, ENDIANNESS_LITTLE)
, m_lineram(*this, "lineram", 0x1000, ENDIANNESS_LITTLE)
, m_sprram(*this, "sprram", 0x10000, ENDIANNESS_LITTLE)
, m_txram(*this, "txram", 0x4000, ENDIANNESS_LITTLE)
, m_bgram(*this, "bgram", 0x4000, ENDIANNESS_LITTLE)
{ }
void ms32(machine_config &config);
void f1superb(machine_config &config);
void ms32_invert_lines(machine_config &config);
void init_ss92047_01();
void init_ss91022_10();
@ -49,63 +91,47 @@ public:
void init_suchie2();
void init_ss92048_01();
void init_bnstars();
void init_f1superb();
void init_ss92046_01();
IRQ_CALLBACK_MEMBER(irq_callback);
DECLARE_CUSTOM_INPUT_MEMBER(mahjong_ctrl_r);
protected:
void configure_banks();
TIMER_DEVICE_CALLBACK_MEMBER(ms32_interrupt);
void ms32_snd_bank_w(u8 data);
u8 latch_r();
void to_main_w(u8 data);
u32 ms32_sound_r();
void ms32_sound_w(u32 data);
void reset_sub_w(u32 data);
required_device<jaleco_ms32_sysctrl_device> m_sysctrl;
required_device<screen_device> m_screen;
required_device<ms32_sprite_device> m_sprite;
required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode;
required_device<ymf271_device> m_ymf;
int m_reverse_sprite_order;
int m_flipscreen;
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
virtual void video_start() override;
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<ms32_sprite_device> m_sprite;
optional_device<generic_latch_8_device> m_soundlatch;
void ms32_map(address_map &map);
void ms32_sound_map(address_map &map);
private:
optional_device<screen_device> m_screen;
optional_shared_ptr<u32> m_mainram;
optional_shared_ptr<u32> m_roz_ctrl;
optional_shared_ptr<u32> m_tx_scroll;
optional_shared_ptr<u32> m_bg_scroll;
optional_shared_ptr<u32> m_mahjong_input_select;
optional_shared_ptr<u8> m_priram;
optional_shared_ptr<u16> m_palram;
optional_shared_ptr<u16> m_rozram;
optional_shared_ptr<u16> m_lineram;
optional_shared_ptr<u16> m_sprram;
optional_shared_ptr<u16> m_txram;
optional_shared_ptr<u16> m_bgram;
optional_shared_ptr<u16> m_f1superb_extraram;
required_shared_ptr<u32> m_roz_ctrl;
required_shared_ptr<u32> m_tx_scroll;
required_shared_ptr<u32> m_bg_scroll;
required_shared_ptr<u32> m_mahjong_input_select;
memory_share_creator<u8> m_priram;
memory_share_creator<u16> m_palram;
memory_share_creator<u16> m_rozram;
memory_share_creator<u16> m_lineram;
memory_share_creator<u16> m_sprram;
memory_share_creator<u16> m_txram;
memory_share_creator<u16> m_bgram;
optional_memory_bank_array<2> m_z80bank;
std::unique_ptr<u8[]> m_nvram_8;
std::unique_ptr<u16[]> m_sprram_buffer;
u32 m_to_main;
u16 m_irqreq;
size_t m_objectram_size;
tilemap_t *m_tx_tilemap;
tilemap_t *m_roz_tilemap;
tilemap_t *m_bg_tilemap;
tilemap_t *m_bg_tilemap_alt;
u32 m_tilemaplayoutcontrol;
tilemap_t* m_extra_tilemap;
bitmap_ind16 m_temp_bitmap_tilemaps;
bitmap_ind16 m_temp_bitmap_sprites;
bitmap_ind8 m_temp_bitmap_sprites_pri;
@ -113,7 +139,6 @@ private:
int m_brt_r;
int m_brt_g;
int m_brt_b;
u32 ms32_read_inputs3();
u8 ms32_nvram_r8(offs_t offset);
void ms32_nvram_w8(offs_t offset, u8 data);
u8 ms32_priram_r8(offs_t offset);
@ -130,33 +155,53 @@ private:
void ms32_txram_w16(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 ms32_bgram_r16(offs_t offset);
void ms32_bgram_w16(offs_t offset, u16 data, u16 mem_mask = ~0);
void pip_w(u32 data);
void ms32_extra_w16(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 ms32_extra_r16(offs_t offset);
void ms32_irq2_guess_w(u32 data);
void ms32_irq5_guess_w(u32 data);
void bgmode_w(u32 data);
void ms32_brightness_w(offs_t offset, u32 data, u32 mem_mask = ~0);
void ms32_gfxctrl_w(offs_t offset, u32 data, u32 mem_mask = ~0);
void coin_counter_w(u32 data);
void init_ms32_common();
TILE_GET_INFO_MEMBER(get_ms32_tx_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_roz_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_bg_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_extra_tile_info);
virtual void machine_reset() override;
virtual void video_start() override;
DECLARE_VIDEO_START(f1superb);
u32 screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank_ms32);
void irq_init();
void irq_raise(int level);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank);
void update_color(int color);
void draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u16 *sprram_top, size_t sprram_size, int reverseorder);
void draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u16 *sprram_top);
void draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect,int priority);
};
class ms32_f1superbattle_state : public ms32_state
{
public:
ms32_f1superbattle_state(const machine_config &mconfig, device_type type, const char *tag) :
ms32_state(mconfig, type, tag)
, m_road_vram(*this, "road_vram", 0x10000, ENDIANNESS_LITTLE)
// TODO: COPROs
{}
void f1superb(machine_config &config);
void init_f1superb();
protected:
virtual void video_start() override;
private:
TILE_GET_INFO_MEMBER(get_ms32_extra_tile_info);
void ms32_irq2_guess_w(u32 data);
void ms32_irq5_guess_w(u32 data);
memory_share_creator<u16> m_road_vram;
void f1superb_map(address_map &map);
void ms32_map(address_map &map);
void ms32_sound_map(address_map &map);
void road_vram_w16(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 road_vram_r16(offs_t offset);
u32 analog_r();
tilemap_t* m_extra_tilemap;
};
#endif // MAME_INCLUDES_MS32_H

View File

@ -2,6 +2,7 @@
// copyright-holders:Luca Elia
#include "machine/gen_latch.h"
#include "machine/jaleco_ms32_sysctrl.h"
#include "video/ms32_sprite.h"
#include "emupal.h"
#include "tilemap.h"
@ -10,57 +11,49 @@ class tetrisp2_state : public driver_device
{
public:
tetrisp2_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_subcpu(*this, "sub"),
m_sprite(*this, "sprite"),
m_rocknms_sub_sprite(*this, "sub_sprite"),
m_spriteram(*this, "spriteram"),
m_spriteram2(*this, "spriteram2"),
m_vram_fg(*this, "vram_fg"),
m_vram_bg(*this, "vram_bg"),
m_vram_rot(*this, "vram_rot"),
m_nvram(*this, "nvram"),
m_scroll_fg(*this, "scroll_fg"),
m_scroll_bg(*this, "scroll_bg"),
m_rotregs(*this, "rotregs"),
m_rocknms_sub_priority(*this, "sub_priority"),
m_rocknms_sub_vram_rot(*this, "sub_vram_rot"),
m_rocknms_sub_vram_fg(*this, "sub_vram_fg"),
m_rocknms_sub_vram_bg(*this, "sub_vram_bg"),
m_rocknms_sub_scroll_fg(*this, "sub_scroll_fg"),
m_rocknms_sub_scroll_bg(*this, "sub_scroll_bg"),
m_rocknms_sub_rotregs(*this, "sub_rotregs"),
m_gfxdecode(*this, "gfxdecode"),
m_sub_gfxdecode(*this, "sub_gfxdecode"),
m_palette(*this, "palette"),
m_sub_palette(*this, "sub_palette"),
m_paletteram(*this, "paletteram"),
m_sub_paletteram(*this, "sub_paletteram"),
m_leds(*this, "led%u", 0U)
driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_sysctrl(*this, "sysctrl")
, m_sprite(*this, "sprite")
, m_screen(*this, "screen")
, m_spriteram(*this, "spriteram")
, m_spriteram2(*this, "spriteram2")
, m_vram_fg(*this, "vram_fg")
, m_vram_bg(*this, "vram_bg")
, m_vram_rot(*this, "vram_rot")
, m_nvram(*this, "nvram")
, m_scroll_fg(*this, "scroll_fg")
, m_scroll_bg(*this, "scroll_bg")
, m_rotregs(*this, "rotregs")
, m_gfxdecode(*this, "gfxdecode")
, m_sub_gfxdecode(*this, "sub_gfxdecode")
, m_palette(*this, "palette")
, m_paletteram(*this, "paletteram")
, m_leds(*this, "led%u", 0U)
{ }
void rockn2(machine_config &config);
void tetrisp2(machine_config &config);
void nndmseal(machine_config &config);
void rocknms(machine_config &config);
void rockn(machine_config &config);
void init_rockn2();
void init_rockn1();
void init_rockn();
void init_rockn3();
void init_rocknms();
DECLARE_CUSTOM_INPUT_MEMBER(rocknms_main2sub_status_r);
TILE_GET_INFO_MEMBER(get_tile_info_bg);
TILE_GET_INFO_MEMBER(stepstag_get_tile_info_fg);
TILE_GET_INFO_MEMBER(get_tile_info_rot);
protected:
void rockn_systemregs_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_systemregs_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void setup_main_sysctrl(machine_config &config, const XTAL clock);
void setup_main_sprite(machine_config &config, const XTAL clock);
DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
DECLARE_WRITE_LINE_MEMBER(timer_irq_w);
DECLARE_WRITE_LINE_MEMBER(vblank_irq_w);
DECLARE_WRITE_LINE_MEMBER(field_irq_w);
DECLARE_WRITE_LINE_MEMBER(sound_reset_line_w);
u16 rockn_adpcmbank_r();
void rockn_adpcmbank_w(u16 data);
void rockn2_adpcmbank_w(u16 data);
@ -69,66 +62,42 @@ protected:
void nndmseal_sound_bank_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 tetrisp2_ip_1_word_r();
u16 rockn_nvram_r(offs_t offset);
u16 rocknms_main2sub_r();
void rocknms_main2sub_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub2main_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void tetrisp2_coincounter_w(u16 data);
void nndmseal_coincounter_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void nndmseal_b20000_w(u16 data);
void tetrisp2_systemregs_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 tetrisp2_nvram_r(offs_t offset);
void tetrisp2_nvram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void tetrisp2_palette_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_palette_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void tetrisp2_priority_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_priority_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 tetrisp2_priority_r(offs_t offset);
void tetrisp2_vram_bg_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void tetrisp2_vram_fg_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void tetrisp2_vram_rot_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_vram_bg_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_vram_fg_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_vram_rot_w(offs_t offset, u16 data, u16 mem_mask = ~0);
TILE_GET_INFO_MEMBER(get_tile_info_fg);
TILE_GET_INFO_MEMBER(get_tile_info_rocknms_sub_bg);
TILE_GET_INFO_MEMBER(get_tile_info_rocknms_sub_fg);
TILE_GET_INFO_MEMBER(get_tile_info_rocknms_sub_rot);
DECLARE_VIDEO_START(tetrisp2);
DECLARE_VIDEO_START(nndmseal);
DECLARE_VIDEO_START(rockntread);
DECLARE_VIDEO_START(rocknms);
u32 screen_update_tetrisp2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_rockntread(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_rocknms_left(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update_rocknms_right(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(rockn_timer_level4_callback);
TIMER_CALLBACK_MEMBER(rockn_timer_sub_level4_callback);
TIMER_CALLBACK_MEMBER(rockn_timer_level1_callback);
TIMER_CALLBACK_MEMBER(rockn_timer_sub_level1_callback);
void init_rockn_timer();
void nndmseal_map(address_map &map);
void rockn1_map(address_map &map);
void rockn2_map(address_map &map);
void rocknms_main_map(address_map &map);
void rocknms_sub_map(address_map &map);
void tetrisp2_map(address_map &map);
virtual void machine_start() override { m_leds.resolve(); }
required_device<cpu_device> m_maincpu;
optional_device<cpu_device> m_subcpu;
required_device<jaleco_ms32_sysctrl_device> m_sysctrl;
required_device<ms32_sprite_device> m_sprite;
optional_device<ms32_sprite_device> m_rocknms_sub_sprite;
required_device<screen_device> m_screen;
required_shared_ptr<u16> m_spriteram;
optional_shared_ptr<u16> m_spriteram2;
u16 m_systemregs[0x10];
required_shared_ptr<u16> m_vram_fg;
required_shared_ptr<u16> m_vram_bg;
required_shared_ptr<u16> m_vram_rot;
@ -137,59 +106,114 @@ protected:
required_shared_ptr<u16> m_scroll_bg;
required_shared_ptr<u16> m_rotregs;
std::unique_ptr<u8[]> m_priority;
optional_shared_ptr<u16> m_rocknms_sub_priority;
optional_shared_ptr<u16> m_rocknms_sub_vram_rot;
optional_shared_ptr<u16> m_rocknms_sub_vram_fg;
optional_shared_ptr<u16> m_rocknms_sub_vram_bg;
optional_shared_ptr<u16> m_rocknms_sub_scroll_fg;
optional_shared_ptr<u16> m_rocknms_sub_scroll_bg;
optional_shared_ptr<u16> m_rocknms_sub_rotregs;
required_device<gfxdecode_device> m_gfxdecode;
optional_device<gfxdecode_device> m_sub_gfxdecode;
required_device<palette_device> m_palette;
optional_device<palette_device> m_sub_palette;
required_shared_ptr<u16> m_paletteram;
optional_shared_ptr<u16> m_sub_paletteram;
output_finder<45> m_leds;
u16 m_rocknms_sub_systemregs[0x10];
u16 m_rockn_protectdata;
u16 m_rockn_adpcmbank;
u16 m_rockn_soundvolume;
emu_timer *m_rockn_timer_l4;
emu_timer *m_rockn_timer_sub_l4;
emu_timer *m_rockn_timer_l1;
emu_timer *m_rockn_timer_sub_l1;
int m_rot_ofsx, m_rot_ofsy;
int m_bank_lo;
int m_bank_hi;
u16 m_rocknms_main2sub;
u16 m_rocknms_sub2main;
int m_flipscreen_old;
tilemap_t *m_tilemap_bg;
tilemap_t *m_tilemap_fg;
tilemap_t *m_tilemap_rot;
};
class rocknms_state : public tetrisp2_state
{
public:
rocknms_state(const machine_config &mconfig, device_type type, const char *tag)
: tetrisp2_state(mconfig, type, tag)
, m_subcpu(*this, "sub")
, m_sub_sysctrl(*this, "sub_sysctrl")
, m_sub_screen(*this, "sub_screen")
, m_rocknms_sub_sprite(*this, "sub_sprite")
, m_rocknms_sub_priority(*this, "sub_priority")
, m_rocknms_sub_vram_rot(*this, "sub_vram_rot")
, m_rocknms_sub_vram_fg(*this, "sub_vram_fg")
, m_rocknms_sub_vram_bg(*this, "sub_vram_bg")
, m_rocknms_sub_scroll_fg(*this, "sub_scroll_fg")
, m_rocknms_sub_scroll_bg(*this, "sub_scroll_bg")
, m_rocknms_sub_rotregs(*this, "sub_rotregs")
, m_sub_palette(*this, "sub_palette")
, m_sub_paletteram(*this, "sub_paletteram")
{ }
void rocknms(machine_config &config);
void init_rocknms();
DECLARE_CUSTOM_INPUT_MEMBER(rocknms_main2sub_status_r);
private:
required_device<cpu_device> m_subcpu;
required_device<jaleco_ms32_sysctrl_device> m_sub_sysctrl;
required_device<screen_device> m_sub_screen;
required_device<ms32_sprite_device> m_rocknms_sub_sprite;
required_shared_ptr<u16> m_rocknms_sub_priority;
required_shared_ptr<u16> m_rocknms_sub_vram_rot;
required_shared_ptr<u16> m_rocknms_sub_vram_fg;
required_shared_ptr<u16> m_rocknms_sub_vram_bg;
required_shared_ptr<u16> m_rocknms_sub_scroll_fg;
required_shared_ptr<u16> m_rocknms_sub_scroll_bg;
required_shared_ptr<u16> m_rocknms_sub_rotregs;
required_device<palette_device> m_sub_palette;
required_shared_ptr<u16> m_sub_paletteram;
u32 screen_update_rocknms_left(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update_rocknms_right(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void rocknms_main_map(address_map &map);
void rocknms_sub_map(address_map &map);
u16 rocknms_main2sub_r();
void rocknms_main2sub_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub2main_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_palette_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_priority_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_vram_bg_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_vram_fg_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void rocknms_sub_vram_rot_w(offs_t offset, u16 data, u16 mem_mask = ~0);
DECLARE_VIDEO_START(rocknms);
TILE_GET_INFO_MEMBER(get_tile_info_rocknms_sub_bg);
TILE_GET_INFO_MEMBER(get_tile_info_rocknms_sub_fg);
TILE_GET_INFO_MEMBER(get_tile_info_rocknms_sub_rot);
u16 m_rocknms_main2sub;
u16 m_rocknms_sub2main;
tilemap_t *m_tilemap_sub_bg;
tilemap_t *m_tilemap_sub_fg;
tilemap_t *m_tilemap_sub_rot;
DECLARE_WRITE_LINE_MEMBER(sub_flipscreen_w);
DECLARE_WRITE_LINE_MEMBER(sub_timer_irq_w);
DECLARE_WRITE_LINE_MEMBER(sub_vblank_irq_w);
DECLARE_WRITE_LINE_MEMBER(sub_field_irq_w);
DECLARE_WRITE_LINE_MEMBER(sub_sound_reset_line_w);
};
class stepstag_state : public tetrisp2_state
{
public:
stepstag_state(const machine_config &mconfig, device_type type, const char *tag) :
tetrisp2_state(mconfig, type, tag),
m_vj_sprite_l(*this, "sprite_l"),
m_vj_sprite_m(*this, "sprite_m"),
m_vj_sprite_r(*this, "sprite_r"),
m_spriteram1(*this, "spriteram1"),
m_spriteram3(*this, "spriteram3"),
m_vj_palette_l(*this, "lpalette"),
m_vj_palette_m(*this, "mpalette"),
m_vj_palette_r(*this, "rpalette"),
m_vj_paletteram_l(*this, "paletteram1"),
m_vj_paletteram_m(*this, "paletteram2"),
m_vj_paletteram_r(*this, "paletteram3"),
m_soundlatch(*this, "soundlatch")
tetrisp2_state(mconfig, type, tag)
, m_subcpu(*this, "sub")
, m_vj_sprite_l(*this, "sprite_l")
, m_vj_sprite_m(*this, "sprite_m")
, m_vj_sprite_r(*this, "sprite_r")
, m_spriteram1(*this, "spriteram1")
, m_spriteram3(*this, "spriteram3")
, m_vj_palette_l(*this, "lpalette")
, m_vj_palette_m(*this, "mpalette")
, m_vj_palette_r(*this, "rpalette")
, m_vj_paletteram_l(*this, "paletteram1")
, m_vj_paletteram_m(*this, "paletteram2")
, m_vj_paletteram_r(*this, "paletteram3")
, m_soundlatch(*this, "soundlatch")
{ }
void stepstag(machine_config &config);
@ -217,9 +241,10 @@ private:
void stepstag_palette_mid_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void stepstag_palette_right_w(offs_t offset, u16 data, u16 mem_mask = ~0);
TILE_GET_INFO_MEMBER(stepstag_get_tile_info_fg);
u32 screen_update_stepstag_left(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update_stepstag_mid(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update_stepstag_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_stepstag_right(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u32 screen_update_stepstag_main(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
// inline int mypal(int x);
@ -227,6 +252,10 @@ private:
void stepstag_sub_map(address_map &map);
void vjdash_map(address_map &map);
TIMER_DEVICE_CALLBACK_MEMBER(field_cb);
void setup_non_sysctrl_screen(machine_config &config, screen_device *screen, const XTAL xtal);
required_device<cpu_device> m_subcpu;
optional_device<ms32_sprite_device> m_vj_sprite_l;
optional_device<ms32_sprite_device> m_vj_sprite_m;
optional_device<ms32_sprite_device> m_vj_sprite_r;

View File

@ -0,0 +1,88 @@
<?xml version="1.0"?>
<!--
license:CC0
-->
<mamelayout version="2">
<element name="shifter" defstate="0">
<rect>
<bounds left="0" right="32" top="0" bottom="64" />
<color red="0.85" green="0.4" blue="0.3" />
</rect>
<rect>
<bounds left="2" right="30" top="2" bottom="62" />
<color red="0.14" green="0.17" blue="0.2" />
</rect>
<rect>
<bounds left="14" right="18" top="15" bottom="49" />
<color red="0.44" green="0.47" blue="0.5" />
</rect>
<disk>
<bounds left="14" right="18" top="13" bottom="17" />
<color red="0.44" green="0.47" blue="0.5" />
</disk>
<disk>
<bounds left="14" right="18" top="47" bottom="51" />
<color red="0.44" green="0.47" blue="0.5" />
</disk>
<text string="LOW" state="0">
<bounds left="3" right="29" top="2" bottom="12" />
<color red="1.0" green="1.0" blue="0.4" />
</text>
<text string="LOW" state="1">
<bounds left="3" right="29" top="2" bottom="12" />
<color red="1.0" green="1.0" blue="1.0" />
</text>
<text string="HIGH" state="0">
<bounds left="3" right="29" top="52" bottom="62" />
<color red="1.0" green="1.0" blue="1.0" />
</text>
<text string="HIGH" state="1">
<bounds left="3" right="29" top="52" bottom="62" />
<color red="1.0" green="1.0" blue="0.4" />
</text>
<disk state="0">
<bounds left="9" right="23" top="14" bottom="28" />
<color red="0.85" green="0.4" blue="0.3" />
</disk>
<disk state="1">
<bounds left="9" right="23" top="36" bottom="50" />
<color red="0.85" green="0.4" blue="0.3" />
</disk>
</element>
<view name="Shifter-R">
<screen index="0">
<bounds x="0" y="0" width="640" height="480" />
</screen>
<element ref="shifter" inputtag="INPUTS" inputmask="0x01">
<bounds x="606" y="414" width="32" height="64" />
<color alpha="0.6" />
</element>
</view>
<view name="Shifter-L">
<screen index="0">
<bounds x="0" y="0" width="640" height="480" />
</screen>
<element ref="shifter" inputtag="INPUTS" inputmask="0x01">
<bounds x="2" y="414" width="32" height="64" />
<color alpha="0.6" />
</element>
</view>
<view name="Widescreen Shifter-R">
<screen index="0">
<bounds x="0" y="0" width="640" height="480" />
</screen>
<element ref="shifter" inputtag="INPUTS" inputmask="0x01">
<bounds x="648" y="414" width="32" height="64" />
</element>
</view>
<view name="Widescreen Shifter-L">
<screen index="0">
<bounds x="0" y="0" width="640" height="480" />
</screen>
<element ref="shifter" inputtag="INPUTS" inputmask="0x01">
<bounds x="-40" y="414" width="32" height="64" />
</element>
</view>
</mamelayout>

View File

@ -5,10 +5,10 @@ license:CC0
<mamelayout version="2">
<view name="Rockn Megasession Custom">
<screen tag="lscreen">
<screen tag="screen">
<bounds x="0" y="0" width="12" height="9" />
</screen>
<screen tag="rscreen">
<screen tag="sub_screen">
<bounds x="0" y="9" width="12" height="16" />
</screen>
</view>

View File

@ -8,7 +8,7 @@ license:CC0
<screen tag="lscreen">
<bounds x="0" y="0" width="9" height="13.2" />
</screen>
<screen tag="mscreen">
<screen tag="screen">
<bounds x="9.1" y="0" width="16" height="13.2" />
</screen>
<screen tag="rscreen">

View File

@ -125,7 +125,7 @@ void decrypt_ms32_tx(running_machine &machine, int addr_xor,int data_xor, const
uint8_t *source_data;
int source_size;
source_data = machine.root_device().memregion ( region )->base();
source_data = machine.root_device().memregion( region )->base();
source_size = machine.root_device().memregion( region )->bytes();
std::vector<uint8_t> result_data(source_size);
@ -176,7 +176,7 @@ void decrypt_ms32_bg(running_machine &machine, int addr_xor,int data_xor, const
uint8_t *source_data;
int source_size;
source_data = machine.root_device().memregion ( region )->base();
source_data = machine.root_device().memregion( region )->base();
source_size = machine.root_device().memregion( region )->bytes();
std::vector<uint8_t> result_data(source_size);

View File

@ -0,0 +1,368 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese, Alex Marshall
/******************************************************************************
Jaleco MS32 System Control Unit
A simple system controller for late 90s Jaleco HWs
Known features:
- CRTC & screen(s?) control;
- dot clock control;
- irq/reset controller;
- programmable timer;
- watchdog;
First use in MS32, then their later (?) 68k revision.
TODO:
- pinpoint exact timing generation for programmable irq
(free counter or based on host screen beams)
- interface with multiple screens is a mystery,
cfr. dual screen bnstars, stepping stage HW.
Most likely former effectively controls both screens in demux while
latter has no way to set the other screen(s)?
- watchdog timing;
- upper address line seems unconnected by 68k,
and is it a mystery how watchdog is supposed to route here and assuming
it is and not actually disabled by pin.
- network/COPROs irq connections, specifically for f1superb;
- actual chip name;
BTANBs:
- in p47aces v1.0 (p47acesa) code messes up the prg irq timer setup,
causing SFX overloads by using Spitfire ship with 30 Hz autofire
and shooting at point blank range over walls/enemies.
This has been fixed in v1.1
*******************************************************************************/
#include "emu.h"
#include "jaleco_ms32_sysctrl.h"
//*****************************************************************************
// GLOBAL VARIABLES
//*****************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(JALECO_MS32_SYSCTRL, jaleco_ms32_sysctrl_device, "jaleco_ms32_sysctrl", "Jaleco MS32 System Control Unit")
//*****************************************************************************
// LIVE DEVICE
//*****************************************************************************
//-------------------------------------------------
// jaleco_ms32_sysctrl_device - constructor
//-------------------------------------------------
jaleco_ms32_sysctrl_device::jaleco_ms32_sysctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, JALECO_MS32_SYSCTRL, tag, owner, clock)
, m_screen(*this, finder_base::DUMMY_TAG)
, m_flip_screen_cb(*this)
, m_vblank_cb(*this)
, m_field_cb(*this)
, m_prg_timer_cb(*this)
, m_sound_ack_cb(*this)
, m_sound_reset_cb(*this)
, m_invert_vblank_lines(false)
{
}
void jaleco_ms32_sysctrl_device::amap(address_map& map)
{
// 0xba0000 in 68k, 0xfce00000 in MS32 mapped at lower 16-bits mask
map(0x00, 0x01).w(FUNC(jaleco_ms32_sysctrl_device::control_w));
map(0x02, 0x03).w(FUNC(jaleco_ms32_sysctrl_device::hblank_w));
map(0x04, 0x05).w(FUNC(jaleco_ms32_sysctrl_device::hdisplay_w));
map(0x06, 0x07).w(FUNC(jaleco_ms32_sysctrl_device::hbp_w));
map(0x08, 0x09).w(FUNC(jaleco_ms32_sysctrl_device::hfp_w));
map(0x0a, 0x0b).w(FUNC(jaleco_ms32_sysctrl_device::vblank_w));
map(0x0c, 0x0d).w(FUNC(jaleco_ms32_sysctrl_device::vdisplay_w));
map(0x0e, 0x0f).w(FUNC(jaleco_ms32_sysctrl_device::vbp_w));
map(0x10, 0x11).w(FUNC(jaleco_ms32_sysctrl_device::vfp_w));
map(0x18, 0x19).w(FUNC(jaleco_ms32_sysctrl_device::timer_interval_w));
map(0x1a, 0x1b).w(FUNC(jaleco_ms32_sysctrl_device::timer_ack_w));
map(0x1c, 0x1d).w(FUNC(jaleco_ms32_sysctrl_device::sound_reset_w));
map(0x1e, 0x1f).w(FUNC(jaleco_ms32_sysctrl_device::irq_ack_w));
// map(0x24, 0x27).w // sound comms bidirectional acks?
map(0x26, 0x27).w(FUNC(jaleco_ms32_sysctrl_device::sound_ack_w));
map(0x28, 0x29).nopw(); // watchdog on MS32
map(0x2c, 0x2d).w(FUNC(jaleco_ms32_sysctrl_device::field_ack_w));
map(0x2e, 0x2f).w(FUNC(jaleco_ms32_sysctrl_device::vblank_ack_w));
}
//-------------------------------------------------
// device_add_mconfig - device-specific machine
// configuration addiitons
//-------------------------------------------------
void jaleco_ms32_sysctrl_device::device_add_mconfig(machine_config &config)
{
// TIMER(config, "scantimer").configure_scanline(FUNC(jaleco_ms32_sysctrl_device::scanline_cb), m_screen, 0, 1);
// TODO: watchdog
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void jaleco_ms32_sysctrl_device::device_resolve_objects()
{
m_flip_screen_cb.resolve();
m_vblank_cb.resolve();
m_field_cb.resolve();
m_prg_timer_cb.resolve();
m_sound_reset_cb.resolve();
m_sound_ack_cb.resolve();
}
void jaleco_ms32_sysctrl_device::device_start()
{
save_item(NAME(m_dotclock_setting));
save_item(NAME(m_crtc.horz_blank));
save_item(NAME(m_crtc.horz_display));
save_item(NAME(m_crtc.vert_blank));
save_item(NAME(m_crtc.vert_display));
save_item(NAME(m_flip_screen_state));
save_item(NAME(m_timer.irq_enable));
m_timer.prg_irq = timer_alloc(PRG_TIMER);
m_timer_scanline = timer_alloc(SCANLINE_TIMER);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void jaleco_ms32_sysctrl_device::device_reset()
{
m_dotclock_setting = 0;
m_crtc.horz_blank = 64;
m_crtc.horz_display = 320;
m_crtc.vert_blank = 39;
m_crtc.vert_display = 224;
m_timer.irq_enable = false;
m_timer.interval = 1;
flush_prg_timer();
// flush_scanline_timer(m_crtc.vert_display);
m_timer_scanline->adjust(attotime::never);
// put flipping in a default state
m_flip_screen_state = false;
m_flip_screen_cb(0);
}
void jaleco_ms32_sysctrl_device::flush_prg_timer()
{
attotime step;
if (m_timer.irq_enable)
{
//const u16 htotal = m_crtc.horz_blank + m_crtc.horz_display;
// TODO: unknown actual timings, with interval = 2 it should fire an irq every 16 scanlines in p47aces v1.1
// (excluding times where it is disabled) -> ~1000 Hz?
step = attotime::from_nsec(500000) * m_timer.interval;
}
else
{
step = attotime::never;
m_prg_timer_cb(0);
}
m_timer.prg_irq->adjust(step);
}
void jaleco_ms32_sysctrl_device::flush_scanline_timer(int current_scanline)
{
// in typical Jaleco fashion (cfr. mega system 1), both irqs are somehow configurable (a pin?).
// Examples are tp2ms32 and wpksocv2, wanting vblank as vector 9 and field as 10 otherwise they runs
// at half speed, but then their config can't possibly work with p47aces (i.e. wants 10 and 9 respectively),
// plus bnstars that locks up off the bat if the wrong irq runs at 60 Hz.
// We currently hardwire via an init time setter here, making the irq acks to trigger properly as well.
if (current_scanline == m_crtc.vert_display)
m_invert_vblank_lines ? m_field_cb(1) : m_vblank_cb(1);
// 30 Hz irq
// TODO: unknown mechanics where this happens, is it even tied to scanline?
if (current_scanline == 0 && m_screen->frame_number() & 1)
m_invert_vblank_lines ? m_vblank_cb(1) : m_field_cb(1);
uint32_t next_scanline = (current_scanline + 1) % crtc_vtotal();
m_timer_scanline->adjust(m_screen->time_until_pos(next_scanline), next_scanline);
}
void jaleco_ms32_sysctrl_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch (id)
{
case SCANLINE_TIMER:
flush_scanline_timer(param);
break;
case PRG_TIMER:
m_prg_timer_cb(1);
flush_prg_timer();
break;
}
}
//*****************************************************************************
// READ/WRITE HANDLERS
//*****************************************************************************
static constexpr u16 clamp_to_12bits_neg(u16 raw_data)
{
// each write has a 12 bit resolution, for both CRTC and timer interval
// TODO: nndmseal: on POST it sets up a 0x1000 for vblank, possibly for screen disable?
// TODO: rockn2: on POST it sets up a vertical size of 487, is it trying to setup an interlace setting?
return 0x1000 - (raw_data & 0xfff);
}
// ============================================================================
// CRTC
// ============================================================================
inline u32 jaleco_ms32_sysctrl_device::get_dotclock_frequency()
{
const u8 dot_divider = m_dotclock_setting & 1 ? 6 : 8;
return clock() / dot_divider;
}
inline u16 jaleco_ms32_sysctrl_device::crtc_vtotal()
{
return m_crtc.vert_blank + m_crtc.vert_display;
}
inline void jaleco_ms32_sysctrl_device::crtc_refresh_screen_params()
{
rectangle visarea;
const u16 htotal = m_crtc.horz_blank + m_crtc.horz_display;
const u16 vtotal = crtc_vtotal();
const attoseconds_t refresh = HZ_TO_ATTOSECONDS(get_dotclock_frequency()) * htotal * vtotal;
visarea.set(0, m_crtc.horz_display - 1, 0, m_crtc.vert_display - 1);
logerror("%s: CRTC setup total: %d x %d display: %d x %d\n", this->tag(), htotal, vtotal, m_crtc.horz_display, m_crtc.vert_display);
m_screen->configure(htotal, vtotal, visarea, refresh);
m_timer_scanline->adjust(m_screen->time_until_pos(vtotal), vtotal);
}
void jaleco_ms32_sysctrl_device::control_w(u16 data)
{
/*
* ---- x--- programmable irq timer enable
* ---- -x-- used by f1superb, stepstag, bnstars
* ---- --x- flip screen
* ---- ---x dotclock select (1) 8 MHz (0) 6 MHz
*/
if (BIT(data, 0) != m_dotclock_setting)
{
m_dotclock_setting = BIT(data, 0);
crtc_refresh_screen_params();
}
const bool current_flip = bool(BIT(data, 1));
if (current_flip != m_flip_screen_state)
{
m_flip_screen_state = current_flip;
m_flip_screen_cb(m_flip_screen_state ? ASSERT_LINE : CLEAR_LINE);
}
if (data & 0xf4)
logerror("%s: enabled unknown bit in control_w %02x\n", this->tag(), data & 0xf4);
m_timer.irq_enable = bool(BIT(data, 3));
flush_prg_timer();
}
void jaleco_ms32_sysctrl_device::hblank_w(u16 data)
{
m_crtc.horz_blank = clamp_to_12bits_neg(data);
crtc_refresh_screen_params();
}
void jaleco_ms32_sysctrl_device::hdisplay_w(u16 data)
{
m_crtc.horz_display = clamp_to_12bits_neg(data);
crtc_refresh_screen_params();
}
void jaleco_ms32_sysctrl_device::hbp_w(u16 data)
{
logerror("%s: HSYNC back porch %d\n", this->tag(), 0x1000 - data);
}
void jaleco_ms32_sysctrl_device::hfp_w(u16 data)
{
logerror("%s: HSYNC front porch %d\n", this->tag(), 0x1000 - data);
}
void jaleco_ms32_sysctrl_device::vblank_w(u16 data)
{
m_crtc.vert_blank = clamp_to_12bits_neg(data);
crtc_refresh_screen_params();
}
void jaleco_ms32_sysctrl_device::vdisplay_w(u16 data)
{
m_crtc.vert_display = clamp_to_12bits_neg(data);
crtc_refresh_screen_params();
}
void jaleco_ms32_sysctrl_device::vbp_w(u16 data)
{
logerror("%s: VSYNC back porch %d\n", this->tag(), clamp_to_12bits_neg(data));
}
void jaleco_ms32_sysctrl_device::vfp_w(u16 data)
{
logerror("%s: VSYNC front porch %d\n", this->tag(), clamp_to_12bits_neg(data));
}
// ============================================================================
// Timer
// ============================================================================
void jaleco_ms32_sysctrl_device::timer_interval_w(u16 data)
{
m_timer.interval = clamp_to_12bits_neg(data);
flush_prg_timer();
}
void jaleco_ms32_sysctrl_device::timer_ack_w(u16 data)
{
m_prg_timer_cb(0);
}
// ============================================================================
// ACK lines
// ============================================================================
void jaleco_ms32_sysctrl_device::sound_reset_w(u16 data)
{
m_sound_reset_cb(data & 1);
logerror("%s: sound_reset_w %02x\n", this->tag(), data);
}
void jaleco_ms32_sysctrl_device::vblank_ack_w(u16 data)
{
m_vblank_cb(0);
}
void jaleco_ms32_sysctrl_device::field_ack_w(u16 data)
{
m_field_cb(0);
}
void jaleco_ms32_sysctrl_device::sound_ack_w(u16 data)
{
m_sound_ack_cb(1);
}
void jaleco_ms32_sysctrl_device::irq_ack_w(u16 data)
{
// guess: 68k games calls this in vblank routine instead of
// the designated line, maybe it's a 68k version difference
// or maybe this is right
m_vblank_cb(0);
m_field_cb(0);
// TODO: f1superb definitely clears comms irq with this
}

View File

@ -0,0 +1,119 @@
// license:BSD-3-Clause
// copyright-holders:Angelo Salese, Alex Marshall
/******************************************************************************
Jaleco MS32 System Control Unit
******************************************************************************/
#ifndef MAME_MACHINE_JALECO_MS32_SYSCTRL_H
#define MAME_MACHINE_JALECO_MS32_SYSCTRL_H
#pragma once
#include "screen.h"
#include "machine/timer.h"
//*****************************************************************************
// TYPE DEFINITIONS
//*****************************************************************************
// ======================> jaleco_ms32_sysctrl_device
class jaleco_ms32_sysctrl_device : public device_t
{
public:
// construction/destruction
template <typename T>
jaleco_ms32_sysctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&screen_tag)
: jaleco_ms32_sysctrl_device(mconfig, tag, owner, clock)
{
m_screen.set_tag(std::forward<T>(screen_tag));
}
jaleco_ms32_sysctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// I/O operations
void amap(address_map &map);
auto flip_screen_cb() { return m_flip_screen_cb.bind(); }
auto vblank_cb() { return m_vblank_cb.bind(); }
auto field_cb() { return m_field_cb.bind(); }
auto prg_timer_cb() { return m_prg_timer_cb.bind(); }
auto sound_ack_cb() { return m_sound_ack_cb.bind(); }
auto sound_reset_cb() { return m_sound_reset_cb.bind(); }
void set_invert_vblank_lines(bool enable) { m_invert_vblank_lines = enable; }
// template <typename T> void set_screen(T &&screen_tag) { m_screen.set_tag(std::forward<T>(screen_tag)); printf("xxx"); }
protected:
// device-level overrides
//virtual void device_validity_check(validity_checker &valid) const override;
virtual void device_resolve_objects() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private:
required_device<screen_device> m_screen;
void control_w(u16 data);
void hblank_w(u16 data);
void hdisplay_w(u16 data);
void hbp_w(u16 data);
void hfp_w(u16 data);
void vblank_w(u16 data);
void vdisplay_w(u16 data);
void vbp_w(u16 data);
void vfp_w(u16 data);
void timer_interval_w(u16 data);
void sound_reset_w(u16 data);
void vblank_ack_w(u16 data);
void field_ack_w(u16 data);
void timer_ack_w(u16 data);
void sound_ack_w(u16 data);
void irq_ack_w(u16 data);
devcb_write_line m_flip_screen_cb;
devcb_write_line m_vblank_cb;
devcb_write_line m_field_cb;
devcb_write_line m_prg_timer_cb;
devcb_write_line m_sound_ack_cb;
devcb_write_line m_sound_reset_cb;
u8 m_dotclock_setting;
inline u32 get_dotclock_frequency();
bool m_flip_screen_state;
struct {
u16 horz_blank, horz_display, vert_blank, vert_display;
}m_crtc;
inline u16 crtc_vtotal();
inline void crtc_refresh_screen_params();
struct {
bool irq_enable;
u16 interval;
emu_timer *prg_irq;
}m_timer;
emu_timer *m_timer_scanline;
enum timer_id
{
SCANLINE_TIMER = 1,
PRG_TIMER
};
inline void flush_prg_timer();
inline void flush_scanline_timer(int current_scanline);
bool m_invert_vblank_lines;
};
// device type definition
DECLARE_DEVICE_TYPE(JALECO_MS32_SYSCTRL, jaleco_ms32_sysctrl_device)
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#endif // MAME_MACHINE_JALECO_MS32_SYSCTRL_H

View File

@ -18,8 +18,6 @@ priority should be given to
#include "includes/ms32.h"
// kirarast, tp2m32, and suchie2 require the sprites in a different order
/********** Tilemaps **********/
TILE_GET_INFO_MEMBER(ms32_state::get_ms32_tx_tile_info)
@ -52,12 +50,12 @@ TILE_GET_INFO_MEMBER(ms32_state::get_ms32_bg_tile_info)
tileinfo.set(1,tileno,colour,0);
}
TILE_GET_INFO_MEMBER(ms32_state::get_ms32_extra_tile_info)
TILE_GET_INFO_MEMBER(ms32_f1superbattle_state::get_ms32_extra_tile_info)
{
int tileno,colour;
tileno = m_f1superb_extraram[tile_index *2] & 0xffff;
colour = m_f1superb_extraram[tile_index *2+1] & 0x000f;
tileno = m_road_vram[tile_index *2] & 0xffff;
colour = m_road_vram[tile_index *2+1] & 0x000f;
tileinfo.set(3,tileno,colour+0x50,0);
}
@ -68,11 +66,12 @@ void ms32_state::video_start()
{
m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_tx_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 64, 64);
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_bg_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 64, 64);
m_bg_tilemap_alt = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_bg_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 256, 16); // alt layout, controller by register?
// alt layout, controller by register
m_bg_tilemap_alt = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_bg_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 256, 16);
m_roz_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_roz_tile_info)), TILEMAP_SCAN_ROWS, 16,16, 128,128);
size_t size = m_sprram.bytes() / 4;
m_sprram_buffer = make_unique_clear<u16[]>(size);
m_objectram_size = m_sprram.length();
m_sprram_buffer = make_unique_clear<u16[]>(m_objectram_size);
/* set up tile layers */
m_screen->register_screen_bitmap(m_temp_bitmap_tilemaps);
@ -88,64 +87,63 @@ void ms32_state::video_start()
m_bg_tilemap_alt->set_transparent_pen(0);
m_roz_tilemap->set_transparent_pen(0);
m_reverse_sprite_order = 1;
/* i hate per game patches...how should priority really work? tetrisp2.c ? i can't follow it */
if (!strcmp(machine().system().name,"kirarast")) m_reverse_sprite_order = 0;
if (!strcmp(machine().system().name,"tp2m32")) m_reverse_sprite_order = 0;
if (!strcmp(machine().system().name,"suchie2")) m_reverse_sprite_order = 0;
if (!strcmp(machine().system().name,"suchie2o")) m_reverse_sprite_order = 0;
if (!strcmp(machine().system().name,"hayaosi3")) m_reverse_sprite_order = 0;
if (!strcmp(machine().system().name,"bnstars")) m_reverse_sprite_order = 0;
if (!strcmp(machine().system().name,"wpksocv2")) m_reverse_sprite_order = 0;
// tp2m32 doesn't set the brightness registers so we need sensible defaults
m_brt[0] = m_brt[1] = 0xffff;
m_sprite_ctrl[0x10/4] = 0x8000;
save_pointer(NAME(m_sprram_buffer), size);
save_item(NAME(m_irqreq));
save_pointer(NAME(m_sprram_buffer), m_objectram_size);
save_item(NAME(m_temp_bitmap_tilemaps));
save_item(NAME(m_temp_bitmap_sprites));
save_item(NAME(m_temp_bitmap_sprites_pri));
save_item(NAME(m_tilemaplayoutcontrol));
save_item(NAME(m_reverse_sprite_order));
save_item(NAME(m_flipscreen));
save_item(NAME(m_brt));
save_item(NAME(m_brt_r));
save_item(NAME(m_brt_g));
save_item(NAME(m_brt_b));
}
VIDEO_START_MEMBER(ms32_state,f1superb)
void ms32_f1superbattle_state::video_start()
{
ms32_state::video_start();
m_extra_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_state::get_ms32_extra_tile_info)), TILEMAP_SCAN_ROWS, 2048, 1, 1, 0x400);
m_extra_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ms32_f1superbattle_state::get_ms32_extra_tile_info)), TILEMAP_SCAN_ROWS, 2048, 1, 1, 0x400);
}
/********** PALETTE WRITES **********/
// TODO: fix p47aces brightness
// intro text should actually appear one line at a time instead of fading-in altogether,
// see https://youtu.be/PQsefFtqAwA
void ms32_state::update_color(int color)
{
// anything above text layer is unaffected (maybe a priority setting?)
// that means this must happen at mixing time rather than here ...
// bnstars gameplay: 0x0000 0x0000 0x8080 0x0080
// desertwr ranking: 0x8080 0xff80 0x0000 0x0000
// gametngk: sets upper words of first two regs as 0x0100xxxx (discarded?)
// gameplay:0x0000 0x0000 0x2020 0x0020
// continue:0x5050 0x0050 0x2020 0x0020
// hayaosi3 title: 0x7070 0x0070 0x0000 0x0000
// p47aces: bomb on stage clear fade out (untested, tbd)
int r,g,b;
/* I'm not sure how the brightness should be applied, currently I'm only
affecting bg & sprites, not fg.
The second brightness control might apply to shadows, see gametngk.
*/
// TODO : p47aces : brightness are disabled sometimes, see https://youtu.be/PQsefFtqAwA
if (~color & 0x4000)
{
r = ((m_palram[color*2] & 0xff00) >>8 ) * m_brt_r / 0x100;
g = ((m_palram[color*2] & 0x00ff) >>0 ) * m_brt_g / 0x100;
b = ((m_palram[color*2+1] & 0x00ff) >>0 ) * m_brt_b / 0x100;
r = ((m_palram[color*2] & 0xff00) >> 8 ) * m_brt_r / 0x100;
g = ((m_palram[color*2] & 0x00ff) >> 0 ) * m_brt_g / 0x100;
b = ((m_palram[color*2+1] & 0x00ff) >> 0 ) * m_brt_b / 0x100;
}
else
{
r = ((m_palram[color*2] & 0xff00) >>8 );
g = ((m_palram[color*2] & 0x00ff) >>0 );
b = ((m_palram[color*2+1] & 0x00ff) >>0 );
r = ((m_palram[color*2] & 0xff00) >> 8 );
g = ((m_palram[color*2] & 0x00ff) >> 0 );
b = ((m_palram[color*2+1] & 0x00ff) >> 0 );
}
m_palette->set_pen_color(color,rgb_t(r,g,b));
@ -156,8 +154,10 @@ void ms32_state::ms32_brightness_w(offs_t offset, u32 data, u32 mem_mask)
int oldword = m_brt[offset];
COMBINE_DATA(&m_brt[offset]);
if (m_brt[offset] != oldword)
{
// TODO: bank "1" is for sprite colors
int bank = ((offset & 2) >> 1) * 0x4000;
//int i;
@ -171,45 +171,23 @@ void ms32_state::ms32_brightness_w(offs_t offset, u32 data, u32 mem_mask)
// update_color(machine(), i);
}
}
//popmessage("%04x %04x %04x %04x",m_brt[0],m_brt[1],m_brt[2],m_brt[3]);
}
void ms32_state::ms32_gfxctrl_w(offs_t offset, u32 data, u32 mem_mask)
{
if (ACCESSING_BITS_0_7)
{
/* bit 1 = flip screen */
m_flipscreen = data & 0x02;
m_tx_tilemap->set_flip(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
m_bg_tilemap->set_flip(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
m_bg_tilemap_alt->set_flip(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
/* bit 2 used by f1superb, unknown */
/* bit 3 used by several games, unknown */
//popmessage("%08x",data);
}
}
/* SPRITES based on tetrisp2 for now, readd priority bits later */
void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u16 *sprram_top, size_t sprram_size, int reverseorder)
void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u16 *sprram_top)
{
u16 *source = sprram_top;
u16 *finish = sprram_top + (sprram_size - 0x10) / 2;
const size_t sprite_tail = m_objectram_size - 8; //(0x20000 - 0x10) / 2;
u16 *source = sprram_top;
u16 *finish = sprram_top + sprite_tail;
// TODO: sprite control 0x10 also uses bits 0-11 for sprite start address?
// akiss uses it for double buffer animations, flips between 0 and 0x800 (and is ugly for latter)
const bool reverseorder = (m_sprite_ctrl[0x10/4] & 0x8000) == 0x0000;
if (reverseorder == 1)
if (reverseorder == true)
{
source = sprram_top + (sprram_size - 0x10) / 2;
finish = sprram_top;
source = sprram_top + sprite_tail;
finish = sprram_top;
}
for (;reverseorder ? (source>=finish) : (source<finish); reverseorder ? (source-=8) : (source+=8))
@ -222,8 +200,8 @@ void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, con
u16 xsize, ysize;
s32 sx, sy;
u16 xzoom, yzoom;
m_sprite->extract_parameters(true, false, source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom);
m_sprite->extract_parameters(source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom);
if (disable || !xzoom || !yzoom)
continue;
@ -244,20 +222,21 @@ void ms32_state::draw_sprites(bitmap_ind16 &bitmap, bitmap_ind8 &bitmap_pri, con
void ms32_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect,int priority)
{
// TODO: registers 0x40 / 0x44 and 0x50 / 0x54 are used, unknown meaning
// Given how this works out it is most likely that 0x*0 controls X axis while 0x*4 Y,
// nothing is known to diverge between settings so far (i.e. bbbxing sets 0xffff to 0x4* and 0x0000 to 0x5*).
// 0x4* 0x5* ROZ should wrap?
// bbbxing: 0xffff 0x0000 0 (match presentation)
// gratia: 0x0000 0x0000 1 (sky in stage 2)
// p47aces: 0xffff 0x0651 0 (title screen)
// desertwr: 0xffff 0x0651 1 (any stage)
// f1superb: 0xffff 0x0000 ?
// suchie2: 0x0000 0x0000 0?
// bnstars: 0x0000 0x0000 ?
// hayaosi3: 0x0000 0x0000 ?
// Maybe wrapping is done by limit boundaries rather than individual bits, so that bbbxing and p47aces abuses of this behaviour?
// Are we missing a ROZ plane size as well?
// Given how this works out it is most likely that 0x*0 controls X axis while 0x*4 Y,
// nothing is known to diverge between settings so far (i.e. bbbxing sets 0xffff to 0x4* and 0x0000 to 0x5*).
// 0x4* 0x5* ROZ should wrap?
// bbbxing: 0xffff 0x0000 0 (match presentation)
// gratia: 0x0000 0x0000 1 (sky in stage 2)
// p47aces: 0xffff 0x0651 0 (title screen)
// desertwr: 0xffff 0x0651 1 (any stage)
// f1superb: 0xffff 0x0000 ?
// suchie2: 0x0000 0x0000 0?
// bnstars: 0x0000 0x0000 ?
// hayaosi3: 0x0000 0x0000 ?
// akiss: 0xffff 0x0000 0 (gal riichi, cfr. attract mode)
// Maybe wrapping is done by limit boundaries rather than individual bits, so that bbbxing and p47aces abuses of this behaviour?
// Are we missing a ROZ plane size as well?
if (m_roz_ctrl[0x5c/4] & 1) /* "super" mode */
{
rectangle my_clip;
@ -336,13 +315,36 @@ void ms32_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const rec
u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
u32 ms32_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int scrollx,scrolly;
int asc_pri;
int scr_pri;
int rot_pri;
/*
sprite control regs
0x1c 0x20 0x40 <prihack>
akiss 0 0 0 0
bbbxing 0 0 0 0
bnstars 1 0 0 1
bnstars1 ? ? ? 1
desertwr 1 0 0 0
f1superb 0 0 0 0
gametngk 0 0140 0 0
gratia 0 0 0 0
hayaosi2 0 0 0 0
hayaosi3 0 0140 0 1
kirarast 0 0 0 1
p47aces 1 0 0 0
suchie2 0 0 0 1
tetrisp 0 0 0 0
tp2m32 0 0140 0 1
wpksocv2 0 0140 0 1
*/
// popmessage("%04x %04x %04x",m_sprite_ctrl[0x1c/4], m_sprite_ctrl[0x20/4], m_sprite_ctrl[0x40/4]);
// popmessage("%04x %04x %04x %04x|%04x %04x %04x",m_sprite_ctrl[0x00/4],m_sprite_ctrl[0x04/4],m_sprite_ctrl[0x08/4],m_sprite_ctrl[0x0c/4]
// ,m_sprite_ctrl[0x10/4],m_sprite_ctrl[0x14/4],m_sprite_ctrl[0x18/4]);
/* TODO: registers 0x04/4 and 0x10/4 are used too; the most interesting case
is gametngk, where they are *usually*, but not always, copies of 0x00/4
and 0x0c/4 (used for scrolling).
@ -351,9 +353,9 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap,
The two registers might be somewhat related to the width and height of the
tilemaps, but there's something that just doesn't fit.
*/
int i;
for (i = 0;i < 0x10000;i++) // colors 0x3000-0x3fff are not used
// TODO: move to a cache system
for (int i = 0; i < m_palette->entries(); i++) // colors 0x3000-0x3fff are not used
update_color(i);
scrollx = m_tx_scroll[0x00/4] + m_tx_scroll[0x08/4] + 0x18;
@ -368,11 +370,8 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap,
m_bg_tilemap_alt->set_scrollx(0, scrollx);
m_bg_tilemap_alt->set_scrolly(0, scrolly);
screen.priority().fill(0, cliprect);
/* TODO: 0 is correct for gametngk, but break f1superb scrolling grid (text at
top and bottom of the screen becomes black on black) */
m_temp_bitmap_tilemaps.fill(0, cliprect); /* bg color */
@ -381,8 +380,7 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap,
m_temp_bitmap_sprites.fill(0, cliprect);
m_temp_bitmap_sprites_pri.fill(0, cliprect);
draw_sprites(m_temp_bitmap_sprites, m_temp_bitmap_sprites_pri, cliprect, m_sprram_buffer.get(), 0x20000, m_reverse_sprite_order);
draw_sprites(m_temp_bitmap_sprites, m_temp_bitmap_sprites_pri, cliprect, m_sprram_buffer.get());
// TODO: actually understand this (per-scanline priority and alpha-blend over every layer?)
asc_pri = scr_pri = rot_pri = 0;
@ -431,31 +429,32 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap,
}
// tile-sprite mixing
/* this mixing isn't 100% accurate, it should be using ALL the data in
the priority ram, probably for per-pixel / pen mixing, or more levels
than are supported here.. I don't know, it will need hw tests I think */
// TODO: spaghetti code
// TODO: complete guesswork and missing many spots
// TODO: move to a reusable function
/* it should be using ALL the data in the priority ram, probably for
per-pixel / pen mixing, or more levels than are supported here..
I don't know, it will need hw tests I think */
{
int width = screen.width();
int height = screen.height();
pen_t const *const paldata = m_palette->pens();
bitmap.fill(0, cliprect);
for (int yy=0;yy<height;yy++)
for (int yy = cliprect.min_y; yy <= cliprect.max_y; yy++)
{
u16 const *const srcptr_tile = &m_temp_bitmap_tilemaps.pix(yy);
u8 const *const srcptr_tilepri = &screen.priority().pix(yy);
u16 const *const srcptr_spri = &m_temp_bitmap_sprites.pix(yy);
//u8 const *const srcptr_spripri = &m_temp_bitmap_sprites_pri.pix(yy);
u32 *const dstptr_bitmap = &bitmap.pix(yy);
for (int xx=0;xx<width;xx++)
for (int xx = cliprect.min_x; xx <= cliprect.max_x; xx++)
{
u16 src_tile = srcptr_tile[xx];
u8 src_tilepri = srcptr_tilepri[xx];
u16 src_spri = srcptr_spri[xx];
//u8 src_spripri;// = srcptr_spripri[xx];
u16 spridat = ((src_spri&0x0fff));
u8 spritepri = ((src_spri&0xf000) >> 8);
u16 spridat = (src_spri & 0x0fff);
u8 spritepri = ((src_spri & 0xf000) >> 8);
int primask = 0;
// get sprite priority value back out of bitmap/colour data (this is done in draw_sprite for standalone hw)
@ -468,7 +467,6 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap,
if (m_priram[(spritepri | 0x0a00 | 0x0100) / 2] & 0x38) primask |= 1 << 6;
if (m_priram[(spritepri | 0x0a00 | 0x0000) / 2] & 0x38) primask |= 1 << 7;
// TODO: spaghetti code ...
if (primask == 0x00)
{
if (src_tilepri==0x00)
@ -691,22 +689,26 @@ u32 ms32_state::screen_update_ms32(screen_device &screen, bitmap_rgb32 &bitmap,
dstptr_bitmap[xx] = 0;
popmessage("unhandled priority type %02x, contact MAMEdev",primask);
}
}
}
}
return 0;
}
WRITE_LINE_MEMBER(ms32_state::screen_vblank_ms32)
WRITE_LINE_MEMBER(ms32_state::screen_vblank)
{
if (state)
{
std::copy_n(&m_sprram[0], m_sprram.bytes() / 4, &m_sprram_buffer[0]);
std::copy_n(&m_sprram[0], m_objectram_size, &m_sprram_buffer[0]);
}
}
WRITE_LINE_MEMBER(ms32_state::flipscreen_w)
{
m_tx_tilemap->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
m_bg_tilemap->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
m_bg_tilemap_alt->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
m_roz_tilemap->set_flip(state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
// TODO: sprite device
}

View File

@ -4,24 +4,25 @@
Jaleco Megasystem 32 sprite hardware
TODO:
verify hardware configuration
- verify hardware configuration;
- suchie2: on attract gals background display is cut off on the right side;
used by:
ms32.cpp
bnstars.cpp (Dual screen configuration)
tetrisp2.cpp (Slightly different - no zoom, etc)
tetrisp2.cpp (Slightly different - no zoom, stepstag with YUV)
Sprite format (16 byte per each sprite):
Offset Bits Description
fedcba98 76543210
00 -xxxxxxx -------- Palette Select (some hardwares with YUV color format)
00 -xxxxxxx -------- stepstage only: Palette Select for YUV format
-------- xxxx---- Priority
-------- -----x-- Visible
-------- ------x- Flip Y
-------- -------x Flip X
02 xxxxxxxx -------- Source Y offset (1 pixel each)
-------- xxxxxxxx Source X offset (1 pixel each)
04 xxxx---- -------- Palette Select (most of hardwares)
04 xxxx---- -------- Palette Select (normal)
----xxxx xxxxxxxx Source Texture Select (each texture is 256 x 256 pixels)
06 xxxxxxxx -------- Source Width - 1 (1 pixel each)
-------- xxxxxxxx Source Height - 1 (1 pixel each)
@ -44,6 +45,8 @@ ms32_sprite_device::ms32_sprite_device(const machine_config &mconfig, const char
, device_gfx_interface(mconfig, *this, nullptr)
, m_color_base(0)
, m_color_entries(0x10)
, m_has_zoom(true)
, m_has_yuv(false)
{
}
@ -101,7 +104,7 @@ void ms32_sprite_device::device_start()
gfx(0)->set_colors(m_color_entries);
}
void ms32_sprite_device::extract_parameters(bool has_zoom, bool is_yuv, const u16 *ram, bool &disable, u8 &pri, bool &flipx, bool &flipy, u32 &code, u32 &color, u8 &tx, u8 &ty, u16 &srcwidth, u16 &srcheight, s32 &sx, s32 &sy, u16 &incx, u16 &incy)
void ms32_sprite_device::extract_parameters(const u16 *ram, bool &disable, u8 &pri, bool &flipx, bool &flipy, u32 &code, u32 &color, u8 &tx, u8 &ty, u16 &srcwidth, u16 &srcheight, s32 &sx, s32 &sy, u16 &incx, u16 &incy)
{
const u16 attr = ram[0];
pri = ( attr & 0x00f0);
@ -116,7 +119,7 @@ void ms32_sprite_device::extract_parameters(bool has_zoom, bool is_yuv, const u1
code = (color & 0x0fff);
// encoded to first word when YUV sprites are used
if (is_yuv)
if (m_has_yuv)
color = (attr & 0x7f00) >> 8;
else
color = (color >> 12) & 0xf;
@ -128,7 +131,7 @@ void ms32_sprite_device::extract_parameters(bool has_zoom, bool is_yuv, const u1
sx = (ram[5] & 0x3ff) - (ram[5] & 0x400);
sy = (ram[4] & 0x1ff) - (ram[4] & 0x200);
if (has_zoom)
if (m_has_zoom)
{
incx = (ram[6] & 0xffff);
incy = (ram[7] & 0xffff);

View File

@ -18,8 +18,10 @@ public:
// configuration
void set_color_base(u16 base) { m_color_base = base; }
void set_color_entries(u16 entries) { m_color_entries = entries; }
void set_zoom(bool enable) { m_has_zoom = enable; }
void set_yuv(bool enable) { m_has_yuv = enable; }
void extract_parameters(bool has_zoom, bool is_yuv, const u16 *ram, bool &disable, u8 &pri, bool &flipx, bool &flipy, u32 &code, u32 &color, u8 &tx, u8 &ty, u16 &srcwidth, u16 &srcheight, s32 &sx, s32 &sy, u16 &incx, u16 &incy);
void extract_parameters(const u16 *ram, bool &disable, u8 &pri, bool &flipx, bool &flipy, u32 &code, u32 &color, u8 &tx, u8 &ty, u16 &srcwidth, u16 &srcheight, s32 &sx, s32 &sy, u16 &incx, u16 &incy);
// ----- core graphics drawing -----
@ -83,6 +85,8 @@ private:
// configurations
u16 m_color_base, m_color_entries;
bool m_has_zoom;
bool m_has_yuv;
};
DECLARE_DEVICE_TYPE(JALECO_MEGASYSTEM32_SPRITE, ms32_sprite_device)

View File

@ -34,10 +34,22 @@ To Do:
#include "emu.h"
#include "includes/tetrisp2.h"
#include "machine/jalcrpt.h"
#include "screen.h"
WRITE_LINE_MEMBER(tetrisp2_state::flipscreen_w)
{
machine().tilemap().set_flip_all(state ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
// TODO: sprite device(s)
m_rot_ofsx = state ? 0x053f : 0x400;
m_rot_ofsy = state ? 0x04df : 0x400;
}
WRITE_LINE_MEMBER(rocknms_state::sub_flipscreen_w)
{
// ...
}
/***************************************************************************
@ -54,7 +66,7 @@ void tetrisp2_state::tetrisp2_palette_w(offs_t offset, u16 data, u16 mem_mask)
m_palette->set_pen_color(offset/2,pal5bit(data >> 1),pal5bit(data >> 6),pal5bit(data >> 11));
}
void tetrisp2_state::rocknms_sub_palette_w(offs_t offset, u16 data, u16 mem_mask)
void rocknms_state::rocknms_sub_palette_w(offs_t offset, u16 data, u16 mem_mask)
{
data = COMBINE_DATA(&m_sub_paletteram[offset]);
if ((offset & 1) == 0)
@ -84,7 +96,7 @@ u16 tetrisp2_state::tetrisp2_priority_r(offs_t offset)
return m_priority[offset] | 0xff00;
}
void tetrisp2_state::rocknms_sub_priority_w(offs_t offset, u16 data, u16 mem_mask)
void rocknms_state::rocknms_sub_priority_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
m_rocknms_sub_priority[offset] = data;
@ -165,7 +177,7 @@ void tetrisp2_state::tetrisp2_vram_rot_w(offs_t offset, u16 data, u16 mem_mask)
m_tilemap_rot->mark_tile_dirty(offset/2);
}
TILE_GET_INFO_MEMBER(tetrisp2_state::get_tile_info_rocknms_sub_bg)
TILE_GET_INFO_MEMBER(rocknms_state::get_tile_info_rocknms_sub_bg)
{
u16 code_hi = m_rocknms_sub_vram_bg[ 2 * tile_index + 0];
u16 code_lo = m_rocknms_sub_vram_bg[ 2 * tile_index + 1];
@ -175,14 +187,14 @@ TILE_GET_INFO_MEMBER(tetrisp2_state::get_tile_info_rocknms_sub_bg)
0);
}
void tetrisp2_state::rocknms_sub_vram_bg_w(offs_t offset, u16 data, u16 mem_mask)
void rocknms_state::rocknms_sub_vram_bg_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_rocknms_sub_vram_bg[offset]);
m_tilemap_sub_bg->mark_tile_dirty(offset/2);
}
TILE_GET_INFO_MEMBER(tetrisp2_state::get_tile_info_rocknms_sub_fg)
TILE_GET_INFO_MEMBER(rocknms_state::get_tile_info_rocknms_sub_fg)
{
u16 code_hi = m_rocknms_sub_vram_fg[ 2 * tile_index + 0];
u16 code_lo = m_rocknms_sub_vram_fg[ 2 * tile_index + 1];
@ -192,14 +204,14 @@ TILE_GET_INFO_MEMBER(tetrisp2_state::get_tile_info_rocknms_sub_fg)
0);
}
void tetrisp2_state::rocknms_sub_vram_fg_w(offs_t offset, u16 data, u16 mem_mask)
void rocknms_state::rocknms_sub_vram_fg_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_rocknms_sub_vram_fg[offset]);
m_tilemap_sub_fg->mark_tile_dirty(offset/2);
}
TILE_GET_INFO_MEMBER(tetrisp2_state::get_tile_info_rocknms_sub_rot)
TILE_GET_INFO_MEMBER(rocknms_state::get_tile_info_rocknms_sub_rot)
{
u16 code_hi = m_rocknms_sub_vram_rot[ 2 * tile_index + 0];
u16 code_lo = m_rocknms_sub_vram_rot[ 2 * tile_index + 1];
@ -209,7 +221,7 @@ TILE_GET_INFO_MEMBER(tetrisp2_state::get_tile_info_rocknms_sub_rot)
0);
}
void tetrisp2_state::rocknms_sub_vram_rot_w(offs_t offset, u16 data, u16 mem_mask)
void rocknms_state::rocknms_sub_vram_rot_w(offs_t offset, u16 data, u16 mem_mask)
{
COMBINE_DATA(&m_rocknms_sub_vram_rot[offset]);
m_tilemap_sub_rot->mark_tile_dirty(offset/2);
@ -219,8 +231,6 @@ void tetrisp2_state::rocknms_sub_vram_rot_w(offs_t offset, u16 data, u16 mem_mas
VIDEO_START_MEMBER(tetrisp2_state,tetrisp2)
{
m_flipscreen_old = -1;
m_tilemap_bg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_bg)), TILEMAP_SCAN_ROWS, 16,16, NX_0,NY_0);
m_tilemap_fg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_fg)), TILEMAP_SCAN_ROWS, 8,8, NX_1,NY_1);
m_tilemap_rot = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_rot)), TILEMAP_SCAN_ROWS, 16,16, NX_0*2,NY_0*2);
@ -231,7 +241,6 @@ VIDEO_START_MEMBER(tetrisp2_state,tetrisp2)
// should be smaller and mirrored like m32 I guess
m_priority = std::make_unique<u8[]>(0x40000);
save_item(NAME(m_flipscreen_old));
save_pointer(NAME(m_priority), 0x40000);
}
@ -243,8 +252,6 @@ VIDEO_START_MEMBER(tetrisp2_state,nndmseal)
VIDEO_START_MEMBER(tetrisp2_state,rockntread)
{
m_flipscreen_old = -1;
m_tilemap_bg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_bg)), TILEMAP_SCAN_ROWS, 16,16, 256,16); // rockn ms(main),1,2,3,4
m_tilemap_fg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_fg)), TILEMAP_SCAN_ROWS, 8,8, 64,64);
m_tilemap_rot = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_rot)), TILEMAP_SCAN_ROWS, 16,16, 128,128);
@ -256,18 +263,19 @@ VIDEO_START_MEMBER(tetrisp2_state,rockntread)
// should be smaller and mirrored like m32 I guess
m_priority = std::make_unique<u8[]>(0x40000);
save_item(NAME(m_flipscreen_old));
save_item(NAME(m_rot_ofsx));
save_item(NAME(m_rot_ofsy));
save_pointer(NAME(m_priority), 0x40000);
}
VIDEO_START_MEMBER(tetrisp2_state,rocknms)
VIDEO_START_MEMBER(rocknms_state,rocknms)
{
VIDEO_START_CALL_MEMBER( rockntread );
m_tilemap_sub_bg = &machine().tilemap().create(*m_sub_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_rocknms_sub_bg)), TILEMAP_SCAN_ROWS, 16,16, 32,256); // rockn ms(sub)
m_tilemap_sub_fg = &machine().tilemap().create(*m_sub_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_rocknms_sub_fg)), TILEMAP_SCAN_ROWS, 8,8, 64,64);
m_tilemap_sub_rot = &machine().tilemap().create(*m_sub_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_rocknms_sub_rot)), TILEMAP_SCAN_ROWS, 16,16, 128,128);
m_tilemap_sub_bg = &machine().tilemap().create(*m_sub_gfxdecode, tilemap_get_info_delegate(*this, FUNC(rocknms_state::get_tile_info_rocknms_sub_bg)), TILEMAP_SCAN_ROWS, 16,16, 32,256);
m_tilemap_sub_fg = &machine().tilemap().create(*m_sub_gfxdecode, tilemap_get_info_delegate(*this, FUNC(rocknms_state::get_tile_info_rocknms_sub_fg)), TILEMAP_SCAN_ROWS, 8,8, 64,64);
m_tilemap_sub_rot = &machine().tilemap().create(*m_sub_gfxdecode, tilemap_get_info_delegate(*this, FUNC(rocknms_state::get_tile_info_rocknms_sub_rot)), TILEMAP_SCAN_ROWS, 16,16, 128,128);
m_tilemap_sub_bg->set_transparent_pen(0);
m_tilemap_sub_fg->set_transparent_pen(0);
@ -318,7 +326,7 @@ VIDEO_START_MEMBER(tetrisp2_state,rocknms)
*/
template<class BitmapClass>
static void tetrisp2_draw_sprites(BitmapClass &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u8* priority_ram,
u16 *sprram_top, size_t sprram_size, ms32_sprite_device *chip, int flip, bool is_yuv)
u16 *sprram_top, size_t sprram_size, ms32_sprite_device *chip)
{
u16 *source = sprram_top;
u16 *finish = sprram_top + (sprram_size - 0x10) / 2;
@ -334,7 +342,7 @@ static void tetrisp2_draw_sprites(BitmapClass &bitmap, bitmap_ind8 &bitmap_pri,
s32 sx, sy;
u16 xzoom, yzoom;
chip->extract_parameters(false, is_yuv, source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom);
chip->extract_parameters(source, disable, pri, flipx, flipy, code, color, tx, ty, xsize, ysize, sx, sy, xzoom, yzoom);
if (disable || !xzoom || !yzoom)
continue;
@ -375,45 +383,22 @@ static void tetrisp2_draw_sprites(BitmapClass &bitmap, bitmap_ind8 &bitmap_pri,
u32 tetrisp2_state::screen_update_tetrisp2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int flipscreen;
int asc_pri;
int scr_pri;
int rot_pri;
int rot_ofsx, rot_ofsy;
flipscreen = (m_systemregs[0x00] & 0x02);
/* Black background color */
bitmap.fill(0, cliprect);
screen.priority().fill(0);
/* Flip Screen */
if (flipscreen != m_flipscreen_old)
{
m_flipscreen_old = flipscreen;
machine().tilemap().set_flip_all(flipscreen ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
}
/* Flip Screen */
if (flipscreen)
{
rot_ofsx = 0x053f;
rot_ofsy = 0x04df;
}
else
{
rot_ofsx = 0x400;
rot_ofsy = 0x400;
}
m_tilemap_bg->set_scrollx(0, (((m_scroll_bg[ 0 ] + 0x0014) + m_scroll_bg[ 2 ] ) & 0xffff));
m_tilemap_bg->set_scrolly(0, (((m_scroll_bg[ 3 ] + 0x0000) + m_scroll_bg[ 5 ] ) & 0xffff));
m_tilemap_fg->set_scrollx(0, m_scroll_fg[ 2 ]);
m_tilemap_fg->set_scrolly(0, m_scroll_fg[ 5 ]);
m_tilemap_rot->set_scrollx(0, (m_rotregs[ 0 ] - rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - rot_ofsy));
m_tilemap_rot->set_scrollx(0, (m_rotregs[ 0 ] - m_rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - m_rot_ofsy));
asc_pri = scr_pri = rot_pri = 0;
@ -454,51 +439,28 @@ u32 tetrisp2_state::screen_update_tetrisp2(screen_device &screen, bitmap_ind16 &
m_tilemap_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram, m_spriteram.bytes(), m_sprite, (m_systemregs[0x00] & 0x02), false);
m_spriteram, m_spriteram.bytes(), m_sprite);
return 0;
}
u32 tetrisp2_state::screen_update_rockntread(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int flipscreen;
int asc_pri;
int scr_pri;
int rot_pri;
int rot_ofsx, rot_ofsy;
flipscreen = (m_systemregs[0x00] & 0x02);
/* Black background color */
bitmap.fill(0, cliprect);
screen.priority().fill(0);
/* Flip Screen */
if (flipscreen != m_flipscreen_old)
{
m_flipscreen_old = flipscreen;
machine().tilemap().set_flip_all(flipscreen ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
}
/* Flip Screen */
if (flipscreen)
{
rot_ofsx = 0x053f;
rot_ofsy = 0x04df;
}
else
{
rot_ofsx = 0x400;
rot_ofsy = 0x400;
}
m_tilemap_bg->set_scrollx(0, (((m_scroll_bg[ 0 ] + 0x0014) + m_scroll_bg[ 2 ] ) & 0xffff));
m_tilemap_bg->set_scrolly(0, (((m_scroll_bg[ 3 ] + 0x0000) + m_scroll_bg[ 5 ] ) & 0xffff));
m_tilemap_fg->set_scrollx(0, m_scroll_fg[ 2 ]);
m_tilemap_fg->set_scrolly(0, m_scroll_fg[ 5 ]);
m_tilemap_rot->set_scrollx(0, (m_rotregs[ 0 ] - rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - rot_ofsy));
m_tilemap_rot->set_scrollx(0, (m_rotregs[ 0 ] - m_rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - m_rot_ofsy));
asc_pri = scr_pri = rot_pri = 0;
@ -539,14 +501,14 @@ u32 tetrisp2_state::screen_update_rockntread(screen_device &screen, bitmap_ind16
m_tilemap_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram, m_spriteram.bytes(), m_sprite, (m_systemregs[0x00] & 0x02), false);
m_spriteram, m_spriteram.bytes(), m_sprite);
return 0;
}
u32 tetrisp2_state::screen_update_rocknms_left(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
u32 rocknms_state::screen_update_rocknms_left(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int asc_pri;
int scr_pri;
@ -601,12 +563,12 @@ u32 tetrisp2_state::screen_update_rocknms_left(screen_device &screen, bitmap_rgb
m_tilemap_sub_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram2, m_spriteram2.bytes(), m_rocknms_sub_sprite, (m_systemregs[0x00] & 0x02), false);
m_spriteram2, m_spriteram2.bytes(), m_rocknms_sub_sprite);
return 0;
}
u32 tetrisp2_state::screen_update_rocknms_right(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
u32 rocknms_state::screen_update_rocknms_right(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int asc_pri;
int scr_pri;
@ -662,7 +624,7 @@ u32 tetrisp2_state::screen_update_rocknms_right(screen_device &screen, bitmap_rg
m_tilemap_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram, m_spriteram.bytes(), m_sprite, (m_systemregs[0x00] & 0x02), false);
m_spriteram, m_spriteram.bytes(), m_sprite);
return 0;
}
@ -675,7 +637,7 @@ u32 tetrisp2_state::screen_update_rocknms_right(screen_device &screen, bitmap_rg
// Temporary hack for stpestag: unaltered ASCII bytes are written in the most significant byte
// of code_hi, one of the CPUs probably reads them and writes the actual tile codes somewhere.
TILE_GET_INFO_MEMBER(tetrisp2_state::stepstag_get_tile_info_fg)
TILE_GET_INFO_MEMBER(stepstag_state::stepstag_get_tile_info_fg)
{
u16 const code_hi = m_vram_fg[ 2 * tile_index ] >> 8;
u16 const code_lo = m_vram_fg[ 2 * tile_index ] & 0xf;
@ -690,11 +652,9 @@ TILE_GET_INFO_MEMBER(tetrisp2_state::stepstag_get_tile_info_fg)
VIDEO_START_MEMBER(stepstag_state,stepstag)
{
m_flipscreen_old = -1;
m_tilemap_bg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_bg)), TILEMAP_SCAN_ROWS, 16,16, NX_0,NY_0);
m_tilemap_fg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::stepstag_get_tile_info_fg)), TILEMAP_SCAN_ROWS, 8,8, NX_1,NY_1);
m_tilemap_rot = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(tetrisp2_state::get_tile_info_rot)), TILEMAP_SCAN_ROWS, 16,16, NX_0*2,NY_0*2);
m_tilemap_bg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(stepstag_state::get_tile_info_bg)), TILEMAP_SCAN_ROWS, 16,16, NX_0,NY_0);
m_tilemap_fg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(stepstag_state::stepstag_get_tile_info_fg)), TILEMAP_SCAN_ROWS, 8,8, NX_1,NY_1);
m_tilemap_rot = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(stepstag_state::get_tile_info_rot)), TILEMAP_SCAN_ROWS, 16,16, NX_0*2,NY_0*2);
m_tilemap_bg->set_transparent_pen(0);
m_tilemap_fg->set_transparent_pen(0);
m_tilemap_rot->set_transparent_pen(0);
@ -710,7 +670,7 @@ u32 stepstag_state::screen_update_stepstag_left(screen_device &screen, bitmap_rg
tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram1, m_spriteram1.bytes(), m_vj_sprite_l, (m_systemregs[0x00] & 0x02), true);
m_spriteram1, m_spriteram1.bytes(), m_vj_sprite_l);
return 0;
}
@ -722,7 +682,7 @@ u32 stepstag_state::screen_update_stepstag_mid(screen_device &screen, bitmap_rgb
tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram2, m_spriteram2.bytes(), m_vj_sprite_m, (m_systemregs[0x00] & 0x02), true);
m_spriteram2, m_spriteram2.bytes(), m_vj_sprite_m);
// m_tilemap_rot->draw(screen, bitmap, cliprect, 0, 1 << 1);
// m_tilemap_bg->draw(screen, bitmap, cliprect, 0, 1 << 0);
@ -731,46 +691,32 @@ u32 stepstag_state::screen_update_stepstag_mid(screen_device &screen, bitmap_rgb
return 0;
}
u32 stepstag_state::screen_update_stepstag_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 stepstag_state::screen_update_stepstag_right(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
// TODO: doesn't like pen 0?
bitmap.fill(m_vj_palette_r->black_pen(), cliprect);
bitmap.fill(0, cliprect);
screen.priority().fill(0);
tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram3, m_spriteram3.bytes(), m_vj_sprite_r, (m_systemregs[0x00] & 0x02), true);
m_spriteram3, m_spriteram3.bytes(), m_vj_sprite_r);
return 0;
}
u32 stepstag_state::screen_update_stepstag_main(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
bool const flipscreen = bool(m_systemregs[0x00] & 0x02);
/* Black background color */
bitmap.fill(0, cliprect);
screen.priority().fill(0);
/* Flip Screen */
if (flipscreen != m_flipscreen_old)
{
m_flipscreen_old = flipscreen;
machine().tilemap().set_flip_all(flipscreen ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
}
/* Flip Screen */
int const rot_ofsx = flipscreen ? 0x053f : 0x400;
int const rot_ofsy = flipscreen ? 0x04df : 0x400;
m_tilemap_bg->set_scrollx(0, (((m_scroll_bg[ 0 ] + 0x0014) + m_scroll_bg[ 2 ] ) & 0xffff));
m_tilemap_bg->set_scrolly(0, (((m_scroll_bg[ 3 ] + 0x0000) + m_scroll_bg[ 5 ] ) & 0xffff));
m_tilemap_fg->set_scrollx(0, m_scroll_fg[ 2 ]);
m_tilemap_fg->set_scrolly(0, m_scroll_fg[ 5 ]);
m_tilemap_rot->set_scrollx(0, (m_rotregs[ 0 ] - rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - rot_ofsy));
m_tilemap_rot->set_scrollx(0, (m_rotregs[ 0 ] - m_rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - m_rot_ofsy));
int asc_pri = 0, scr_pri = 0, rot_pri = 0;
@ -812,7 +758,7 @@ u32 stepstag_state::screen_update_stepstag_main(screen_device &screen, bitmap_in
tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(),
m_spriteram, m_spriteram.bytes(), m_sprite, (m_systemregs[0x00] & 0x02), false);
m_spriteram, m_spriteram.bytes(), m_sprite);
return 0;
}