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/ms1_tmap.h",
MAME_DIR .. "src/mame/video/ms32_sprite.cpp", MAME_DIR .. "src/mame/video/ms32_sprite.cpp",
MAME_DIR .. "src/mame/video/ms32_sprite.h", 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") 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 for the time being most of this driver is copied
from ms32.cpp, with some adjustments for dual screen. from ms32.cpp, with some adjustments for dual screen.
Main PCB Main PCB
-------- --------
@ -93,7 +92,6 @@ ROMs : MR96004-10.1 [125661cd] (IC5 - Samples)
#include "cpu/z80/z80.h" #include "cpu/z80/z80.h"
#include "cpu/v60/v60.h" #include "cpu/v60/v60.h"
#include "sound/ymf271.h"
#include "machine/jalcrpt.h" #include "machine/jalcrpt.h"
#include "rendlay.h" #include "rendlay.h"
@ -101,25 +99,27 @@ ROMs : MR96004-10.1 [125661cd] (IC5 - Samples)
#include "tilemap.h" #include "tilemap.h"
class bnstars_state : public ms32_state class ms32_bnstars_state : public ms32_base_state
{ {
public: public:
bnstars_state(const machine_config &mconfig, device_type type, const char *tag) ms32_bnstars_state(const machine_config &mconfig, device_type type, const char *tag)
: ms32_state(mconfig, type, tag) : ms32_base_state(mconfig, type, tag)
, m_ms32_tx0_ram(*this, "tx0_ram", 0x4000, ENDIANNESS_LITTLE) , m_sysctrl(*this, "sysctrl")
, m_ms32_tx1_ram(*this, "tx1_ram", 0x4000, ENDIANNESS_LITTLE) , m_screen(*this, "screen.%u", 0U)
, m_ms32_bg0_ram(*this, "bg0_ram", 0x4000, ENDIANNESS_LITTLE) , m_gfxdecode(*this, "gfxdecode.%u", 0U)
, m_ms32_bg1_ram(*this, "bg1_ram", 0x4000, ENDIANNESS_LITTLE) , m_palette(*this, "palette.%u", 0U)
, m_ms32_roz0_ram(*this, "roz0_ram", 0x10000, ENDIANNESS_LITTLE) , m_paletteram(*this, "paletteram.%u", 0U, 0x20000U, ENDIANNESS_LITTLE)
, m_ms32_roz1_ram(*this, "roz1_ram", 0x10000, ENDIANNESS_LITTLE) , m_ascii_vram(*this, "ascii_vram_%u", 0U, 0x4000U, ENDIANNESS_LITTLE)
, m_ms32_roz_ctrl(*this, "roz_ctrl.%u", 0) , m_ascii_ctrl(*this, "ascii_ctrl.%u", 0U)
, m_ms32_spram(*this, "spram", 0x20000, ENDIANNESS_LITTLE) , m_scroll_vram(*this, "scroll_vram_%u", 0U, 0x4000U, ENDIANNESS_LITTLE)
, m_ms32_tx0_scroll(*this, "tx0_scroll") , m_scroll_ctrl(*this, "scroll_ctrl.%u", 0U)
, m_ms32_bg0_scroll(*this, "bg0_scroll") , m_rotate_vram(*this, "rotate_vram_%u", 0U, 0x10000U, ENDIANNESS_LITTLE)
, m_ms32_tx1_scroll(*this, "tx1_scroll") , m_rotate_ctrl(*this, "rotate_ctrl.%u", 0U)
, m_ms32_bg1_scroll(*this, "bg1_scroll") , m_sprite(*this, "sprite.%u", 0U)
, m_object_vram(*this, "objram_%u", 0U, 0x10000U, ENDIANNESS_LITTLE)
, m_p1_keys(*this, "P1KEY.%u", 0) , m_p1_keys(*this, "P1KEY.%u", 0)
, m_p2_keys(*this, "P2KEY.%u", 0) , m_p2_keys(*this, "P2KEY.%u", 0)
, m_ymf(*this, "ymf.%u", 1U)
{ } { }
void bnstars(machine_config &config); void bnstars(machine_config &config);
@ -130,185 +130,170 @@ public:
private: private:
tilemap_t *m_ms32_tx_tilemap[2]; // TODO: subclass this device for dual screen config
tilemap_t *m_ms32_bg_tilemap[2]; required_device<jaleco_ms32_sysctrl_device> m_sysctrl;
tilemap_t *m_ms32_roz_tilemap[2];
memory_share_creator<u16> m_ms32_tx0_ram; required_device_array<screen_device, 2> m_screen;
memory_share_creator<u16> m_ms32_tx1_ram;
memory_share_creator<u16> m_ms32_bg0_ram; required_device_array<gfxdecode_device, 2> m_gfxdecode;
memory_share_creator<u16> m_ms32_bg1_ram; required_device_array<palette_device, 2> m_palette;
memory_share_creator<u16> m_ms32_roz0_ram; memory_share_array_creator<u16, 2> m_paletteram;
memory_share_creator<u16> m_ms32_roz1_ram;
required_shared_ptr_array<u32, 2> m_ms32_roz_ctrl; memory_share_array_creator<u16, 2> m_ascii_vram;
memory_share_creator<u16> m_ms32_spram; required_shared_ptr_array<u32, 2> m_ascii_ctrl;
required_shared_ptr<u32> m_ms32_tx0_scroll; memory_share_array_creator<u16, 2> m_scroll_vram;
required_shared_ptr<u32> m_ms32_bg0_scroll; required_shared_ptr_array<u32, 2> m_scroll_ctrl;
required_shared_ptr<u32> m_ms32_tx1_scroll; memory_share_array_creator<u16, 2> m_rotate_vram;
required_shared_ptr<u32> m_ms32_bg1_scroll; 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_p1_keys;
required_ioport_array<4> m_p2_keys; required_ioport_array<4> m_p2_keys;
u32 m_bnstars1_mahjong_select; u32 m_bnstars1_mahjong_select;
void ms32_tx0_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0); template <int chip> void ascii_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_tx1_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0); template <int chip> u16 ascii_vram_r(offs_t offset);
void ms32_bg0_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0); template <int chip> void scroll_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_bg1_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0); template <int chip> u16 scroll_vram_r(offs_t offset);
void ms32_roz0_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0); template <int chip> void rotate_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void ms32_roz1_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0); template <int chip> u16 rotate_vram_r(offs_t offset);
void bnstars1_mahjong_select_w(u32 data); template <int chip> void object_vram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
TILE_GET_INFO_MEMBER(get_ms32_tx0_tile_info); template <int chip> u16 object_vram_r(offs_t offset);
TILE_GET_INFO_MEMBER(get_ms32_tx1_tile_info); template <int chip> void palette_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
TILE_GET_INFO_MEMBER(get_ms32_bg0_tile_info); template <int chip> u16 palette_ram_r(offs_t offset);
TILE_GET_INFO_MEMBER(get_ms32_bg1_tile_info); DECLARE_WRITE_LINE_MEMBER(flipscreen_dual_w);
TILE_GET_INFO_MEMBER(get_ms32_roz0_tile_info); template <int chip> TILE_GET_INFO_MEMBER(get_ascii_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_roz1_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; virtual void video_start() override;
u32 screen_update_bnstars_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); template <int which> u32 screen_update_dual(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);
void bnstars_map(address_map &map); void bnstars_map(address_map &map);
void bnstars_sound_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; int tileno, colour;
// const int gfx_region[2] = {2, 5};
tileno = m_ms32_tx0_ram[tile_index *2+0] & 0x0000ffff; tileno = m_ascii_vram[chip][tile_index *2+0] & 0x0000ffff;
colour = m_ms32_tx0_ram[tile_index *2+1] & 0x0000000f; 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; int tileno, colour;
// const int gfx_region[2] = {1, 4};
tileno = m_ms32_tx1_ram[tile_index *2+0] & 0x0000ffff; tileno = m_scroll_vram[chip][tile_index *2+0] & 0x0000ffff;
colour = m_ms32_tx1_ram[tile_index *2+1] & 0x0000000f; 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]); int tileno, colour;
m_ms32_tx_tilemap[0]->mark_tile_dirty(offset/2); // 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 */ /* 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 */ if (m_rotate_ctrl[chip][0x5c/4] & 1) /* "super" mode */
{ throw emu_fatalerror("Super mode in bnstars1?");
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++;
}
*/
}
else /* "simple" mode */ else /* "simple" mode */
{ {
int startx = (m_ms32_roz_ctrl[chip][0x00/4] & 0xffff) | ((m_ms32_roz_ctrl[chip][0x04/4] & 3) << 16); int startx = (m_rotate_ctrl[chip][0x00/4] & 0xffff) | ((m_rotate_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 starty = (m_rotate_ctrl[chip][0x08/4] & 0xffff) | ((m_rotate_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 incxx = (m_rotate_ctrl[chip][0x10/4] & 0xffff) | ((m_rotate_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 incxy = (m_rotate_ctrl[chip][0x18/4] & 0xffff) | ((m_rotate_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 incyy = (m_rotate_ctrl[chip][0x20/4] & 0xffff) | ((m_rotate_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 incyx = (m_rotate_ctrl[chip][0x28/4] & 0xffff) | ((m_rotate_ctrl[chip][0x2c/4] & 1) << 16);
int offsx = m_ms32_roz_ctrl[chip][0x30/4]; int offsx = m_rotate_ctrl[chip][0x30/4];
int offsy = m_ms32_roz_ctrl[chip][0x34/4]; int offsy = m_rotate_ctrl[chip][0x34/4];
offsx += (m_ms32_roz_ctrl[chip][0x38/4] & 1) * 0x400; // ??? gratia, hayaosi1... offsx += (m_rotate_ctrl[chip][0x38/4] & 1) * 0x400; // ??? gratia, hayaosi1...
offsy += (m_ms32_roz_ctrl[chip][0x3c/4] & 1) * 0x400; // ??? gratia, hayaosi1... offsy += (m_rotate_ctrl[chip][0x3c/4] & 1) * 0x400; // ??? gratia, hayaosi1...
/* extend sign */ /* extend sign */
if (startx & 0x20000) startx |= ~0x3ffff; 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 (incyy & 0x10000) incyy |= ~0x1ffff;
if (incyx & 0x10000) incyx |= ~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, (startx+offsx)<<16, (starty+offsy)<<16,
incxx<<8, incxy<<8, incyx<<8, incyy<<8, incxx<<8, incxy<<8, incyx<<8, incyy<<8,
1, // Wrap 1, // Wrap
@ -326,92 +311,22 @@ void bnstars_state::draw_roz(screen_device &screen, bitmap_ind16 &bitmap, const
} }
} }
// TODO: move to the sprite chip, fix priority
TILE_GET_INFO_MEMBER(bnstars_state::get_ms32_roz0_tile_info) 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; if (reverseorder == true)
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)
{ {
source = sprram_top + (sprram_size - 0x10) / 2; source = sprram_top + sprite_tail;
finish = sprram_top; finish = sprram_top;
} }
for (;reverseorder ? (source>=finish) : (source<finish); reverseorder ? (source-=8) : (source+=8))
for (;m_reverse_sprite_order ? (source>=finish) : (source<finish); m_reverse_sprite_order ? (source-=8) : (source+=8))
{ {
bool disable; bool disable;
u8 pri; u8 pri;
@ -423,14 +338,14 @@ void bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
u16 xzoom, yzoom; u16 xzoom, yzoom;
u32 pri_mask = 0; 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) if (disable || !xzoom || !yzoom)
continue; continue;
// there are surely also shadows (see gametngk) but how they're enabled we don't know // 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 yscale = 0x1000000/yzoom;
int xscale = 0x1000000/xzoom; 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; sy = 224 - ((ysize*yscale)>>16) - sy;
flipx = !flipx; flipx = !flipx;
flipy = !flipy; flipy = !flipy;
} }*/
pri >>= 4; pri >>= 4;
/* TODO: priority handling is completely wrong, but better than nothing */
if (pri == 0x0) if (pri == 0x0)
pri_mask = 0x00; pri_mask = 0x00;
else if (pri <= 0xd) else if (pri <= 0xd)
@ -452,7 +366,7 @@ void bnstars_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co
else else
pri_mask = 0xfe; pri_mask = 0xfe;
m_sprite->prio_zoom_transpen(bitmap,cliprect, m_sprite[chip]->prio_zoom_transpen(bitmap,cliprect,
code, code,
color, color,
flipx, flipy, 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_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_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_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_ms32_tx_tilemap[0]->set_transparent_pen(0); m_ascii_tilemap[0]->set_transparent_pen(0);
m_ms32_tx_tilemap[1]->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_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_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_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_ms32_bg_tilemap[0]->set_transparent_pen(0); m_scroll_tilemap[0]->set_transparent_pen(0);
m_ms32_bg_tilemap[1]->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_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_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_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_ms32_roz_tilemap[0]->set_transparent_pen(0); m_rotate_tilemap[0]->set_transparent_pen(0);
m_ms32_roz_tilemap[1]->set_transparent_pen(0); m_rotate_tilemap[1]->set_transparent_pen(0);
} }
template <int which> u32 ms32_bnstars_state::screen_update_dual(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
u32 bnstars_state::screen_update_bnstars_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
screen.priority().fill(0, cliprect); screen.priority().fill(0, cliprect);
bitmap.fill(0, cliprect); /* bg color */ 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 ); draw_roz<which>(screen,bitmap,cliprect, 2);
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(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); draw_sprites<which>(screen, bitmap, cliprect);
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);
return 0; 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); return m_paletteram[chip][offset];
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;
} }
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 ) static INPUT_PORTS_START( bnstars )
PORT_START("P1") 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( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNKNOWN ) 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_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("P2") 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( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNKNOWN ) 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? PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNUSED ) // Unused?
INPUT_PORTS_END INPUT_PORTS_END
static GFXLAYOUT_RAW( bglayout, 16, 16, 16*8, 16*16*8 ) static GFXLAYOUT_RAW( bglayout, 16, 16, 16*8, 16*16*8 )
static GFXLAYOUT_RAW( txlayout, 8, 8, 8*8, 8*8*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( "gfx2", 0, bglayout, 0x5000, 0x10 ) /* Roz scr1 */
GFXDECODE_ENTRY( "gfx4", 0, bglayout, 0x1000, 0x10 ) /* Bg scr1 */ GFXDECODE_ENTRY( "gfx4", 0, bglayout, 0x1000, 0x10 ) /* Bg scr1 */
GFXDECODE_ENTRY( "gfx5", 0, txlayout, 0x6000, 0x10 ) /* Tx 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( "gfx3", 0, bglayout, 0x5000, 0x10 ) /* Roz scr2 */
GFXDECODE_ENTRY( "gfx6", 0, bglayout, 0x1000, 0x10 ) /* Bg scr2 */ GFXDECODE_ENTRY( "gfx6", 0, bglayout, 0x1000, 0x10 ) /* Bg scr2 */
GFXDECODE_ENTRY( "gfx7", 0, txlayout, 0x6000, 0x10 ) /* Tx scr2 */ GFXDECODE_ENTRY( "gfx7", 0, txlayout, 0x6000, 0x10 ) /* Tx scr2 */
GFXDECODE_END GFXDECODE_END
template <int P> void ms32_bnstars_state::bnstars(machine_config &config)
CUSTOM_INPUT_MEMBER(bnstars_state::mahjong_ctrl_r)
{ {
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) 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_addrmap(AS_PROGRAM, &ms32_bnstars_state::bnstars_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(ms32_state::irq_callback)); m_maincpu->set_irq_acknowledge_callback(FUNC(ms32_bnstars_state::irq_callback));
TIMER(config, "scantimer").configure_scanline(FUNC(bnstars_state::ms32_interrupt), "lscreen", 0, 1);
Z80(config, m_audiocpu, XTAL(8'000'000)); // 8MHz present on sound PCB, Verified 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)); 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); config.set_default_layout(layout_dualhsxs);
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER)); for (unsigned i=0; i < 2; i++)
lscreen.set_refresh_hz(60); {
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); PALETTE(config, m_palette[i]).set_entries(0x8000);
lscreen.set_size(40*8, 32*8);
lscreen.set_visarea(0*8, 40*8-1, 0*8, 28*8-1); SCREEN(config, m_screen[i], SCREEN_TYPE_RASTER);
lscreen.set_screen_update(FUNC(bnstars_state::screen_update_bnstars_left)); m_screen[i]->set_raw(XTAL(48'000'000)/8, 384, 0, 320, 263, 0, 224); // default CRTC setup
lscreen.set_palette("palette"); 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)); GFXDECODE(config, m_gfxdecode[0], m_palette[0], gfx_bnstars_left);
rscreen.set_refresh_hz(60); GFXDECODE(config, m_gfxdecode[1], m_palette[1], gfx_bnstars_right);
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_screen[0]->set_screen_update(FUNC(ms32_bnstars_state::screen_update_dual<0>));
rscreen.set_size(40*8, 32*8); m_screen[1]->set_screen_update(FUNC(ms32_bnstars_state::screen_update_dual<1>));
rscreen.set_visarea(0*8, 40*8-1, 0*8, 28*8-1);
rscreen.set_screen_update(FUNC(bnstars_state::screen_update_bnstars_right)); JALECO_MS32_SYSCTRL(config, m_sysctrl, XTAL(48'000'000), m_screen[0]);
rscreen.set_palette("palette2"); 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 */ /* sound hardware */
SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "lspeaker").front_left();
@ -843,17 +712,19 @@ void bnstars_state::bnstars(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch); GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI); m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI);
ymf271_device &ymf1(YMF271(config, "ymf1", XTAL(16'934'400))); // 16.9344MHz YMF271(config, m_ymf[0], XTAL(16'934'400)); // 16.9344MHz
ymf1.add_route(0, "lspeaker", 1.0); m_ymf[0]->add_route(0, "lspeaker", 1.0);
ymf1.add_route(1, "rspeaker", 1.0); m_ymf[0]->add_route(1, "rspeaker", 1.0);
// ymf1.add_route(2, "lspeaker", 1.0); Output 2/3 not used? // Output 2/3 not used?
// ymf1.add_route(3, "rspeaker", 1.0); // 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 YMF271(config, m_ymf[1], XTAL(16'934'400)); // 16.9344MHz
ymf2.add_route(0, "lspeaker", 1.0); m_ymf[1]->add_route(0, "lspeaker", 1.0);
ymf2.add_route(1, "rspeaker", 1.0); m_ymf[1]->add_route(1, "rspeaker", 1.0);
// ymf2.add_route(2, "lspeaker", 1.0); Output 2/3 not used? // Output 2/3 not used?
// ymf2.add_route(3, "rspeaker", 1.0); // 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) ) ROM_LOAD32_BYTE( "mb-93142.39", 0x000000, 0x80000, CRC(56b98539) SHA1(5eb0e77729b31e6a100c1b43813a39fea57bedee) )
/* Sprites - shared by both screens? */ /* 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-01.20", 0x0000000, 0x200000, CRC(3366d104) SHA1(2de0cabe2ead777b5b02cade7f2003ef7f90b75b) )
ROM_LOAD32_WORD( "mr96004-02.28", 0x0000002, 0x200000, CRC(ad556664) SHA1(4b36f8d8d9efa37cf515af41d14433e7eafa27a2) ) ROM_LOAD32_WORD( "mr96004-02.28", 0x0000002, 0x200000, CRC(ad556664) SHA1(4b36f8d8d9efa37cf515af41d14433e7eafa27a2) )
ROM_LOAD32_WORD( "mr96004-03.21", 0x0400000, 0x200000, CRC(b399e2b1) SHA1(9b6a00a219db8d66dcf592160b7b5f7a86b8f0c9) ) 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-07.23", 0x0c00000, 0x200000, CRC(177e32fa) SHA1(3ca1f397dc28f1fa3a4136705b92c63e4e438f05) )
ROM_LOAD32_WORD( "mr96004-08.31", 0x0c00002, 0x200000, CRC(f6df27b2) SHA1(60590976020d86bdccd4eaf57b349ea31bec6830) ) 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) */ /* Roz Tiles #1 (Screen 1) */
ROM_REGION( 0x400000, "gfx2", 0 ) /* roz tiles */ ROM_REGION( 0x400000, "gfx2", 0 ) /* roz tiles */
ROM_LOAD( "mr96004-09.1", 0x000000, 0x400000, CRC(7f8ea9f0) SHA1(f1fe682dcb884f1aa4a5536e17ab94157a99f519) ) 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) ) ROM_LOAD( "sb93145.5", 0x000000, 0x040000, CRC(0424e899) SHA1(fbcdebfa3d5f52b10cf30f7e416f5f53994e4d55) )
/* Samples #1 (Screen 1?) */ /* 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) ) ROM_LOAD( "mr96004-10.1", 0x000000, 0x400000, CRC(83f4303a) SHA1(90ee010591afe1d35744925ef0e8d9a7e2ef3378) )
/* Samples #2 (Screen 2?) */ /* 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_LOAD( "mr96004-10.1", 0x000000, 0x400000, CRC(83f4303a) SHA1(90ee010591afe1d35744925ef0e8d9a7e2ef3378) )
ROM_END ROM_END
/* SS92046_01: bbbxing, f1superb, tetrisp, hayaosi1 */ /* 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_tx(machine(), 0x00020,0x7e, "gfx5");
decrypt_ms32_bg(machine(), 0x00001,0x9b, "gfx4"); decrypt_ms32_bg(machine(), 0x00001,0x9b, "gfx4");
@ -924,4 +798,4 @@ void bnstars_state::init_bnstars()
configure_banks(); 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/z80/z80.h"
#include "cpu/v60/v60.h" #include "cpu/v60/v60.h"
#include "sound/ymf271.h"
#include "speaker.h" #include "speaker.h"
#include "f1superb.lh"
/********** READ INPUTS **********/ /********** READ INPUTS **********/
@ -509,19 +510,7 @@ CUSTOM_INPUT_MEMBER(ms32_state::mahjong_ctrl_r)
return mj_input & 0xff; return mj_input & 0xff;
} }
void ms32_base_state::sound_command_w(u32 data)
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)
{ {
m_soundlatch->write(data & 0xff); 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)); 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; 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) u8 ms32_state::ms32_nvram_r8(offs_t offset)
{ {
return m_nvram_8[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); 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; m_tilemaplayoutcontrol = data;
@ -648,41 +628,72 @@ void ms32_state::coin_counter_w(u32 data)
void ms32_state::ms32_map(address_map &map) void ms32_state::ms32_map(address_map &map)
{ {
/* RAM areas verified by testing on real hw - usually accessed at the 0xfc000000 + mirror */ /* 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 */ // 0xfc000000 NVRAM (8-bits wide, 0x2000 in size)
/* map(0xc0008000, 0xc01fffff) // mirrors of nvramram, handled above */ map(0xc0000000, 0xc0007fff).rw(FUNC(ms32_state::ms32_nvram_r8), FUNC(ms32_state::ms32_nvram_w8)).umask32(0x000000ff).mirror(0x3c1f8000);
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(0xc0008000, 0xc01fffff) // mirrors of nvramram, handled above
/* 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 */
/* todo: clean up the mapping of these */ // 0xfd180000 Priority RAM (8-bits wide, 0x2000 in size)
map(0xfc800000, 0xfc800003).nopr(); /* sound? */ map(0xc1180000, 0xc1187fff).rw(FUNC(ms32_state::ms32_priram_r8), FUNC(ms32_state::ms32_priram_w8)).umask32(0x000000ff).mirror(0x3c038000);
map(0xfc800000, 0xfc800003).w(FUNC(ms32_state::ms32_sound_w)); /* sound? */ // 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(0xfcc00004, 0xfcc00007).portr("INPUTS");
map(0xfcc00010, 0xfcc00013).portr("DSW"); map(0xfcc00010, 0xfcc00013).portr("DSW");
map(0xfce00034, 0xfce00037).nopw(); // irq ack? // System Registers
map(0xfce00038, 0xfce0003b).w(FUNC(ms32_state::reset_sub_w)); map(0xfce00000, 0xfce0005f).m(m_sysctrl, FUNC(jaleco_ms32_sysctrl_device::amap)).umask32(0x0000ffff);
map(0xfce00050, 0xfce0005f).nopw(); // watchdog? I haven't investigated map(0xfce00200, 0xfce0027f).ram().share("sprite_ctrl");
// map(0xfce00000, 0xfce0007f).writeonly().share("ms32_fce00000"); /* registers not ram? */ map(0xfce00280, 0xfce0028f).w(FUNC(ms32_state::ms32_brightness_w)); // global brightness control
map(0xfce00000, 0xfce00003).w(FUNC(ms32_state::ms32_gfxctrl_w)); /* flip screen + other unknown bits */ // map(0xfce00400, 0xfce0045f) // ROZ0 control registers
map(0xfce00280, 0xfce0028f).w(FUNC(ms32_state::ms32_brightness_w)); // global brightness control /**/map(0xfce00600, 0xfce0065f).ram().share("roz_ctrl"); // ROZ1 control registers
/**/map(0xfce00600, 0xfce0065f).ram().share("roz_ctrl"); /* roz control registers */ /**/map(0xfce00a00, 0xfce00a17).ram().share("tx_scroll"); // ASCII layer scroll
/**/map(0xfce00a00, 0xfce00a17).ram().share("tx_scroll"); /* tx layer scroll */ /**/map(0xfce00a20, 0xfce00a37).ram().share("bg_scroll"); // Background layer scroll
/**/map(0xfce00a20, 0xfce00a37).ram().share("bg_scroll"); /* bg layer scroll */ map(0xfce00a7c, 0xfce00a7f).w(FUNC(ms32_state::bgmode_w));
map(0xfce00a7c, 0xfce00a7f).w(FUNC(ms32_state::pip_w)); // ??? layer related? seems to be always 0 // map(0xfce00c00, 0xfce00c1f) // ???
map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_state::coin_counter_w)); // coin counters + something else map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_state::coin_counter_w)); // coin counters + something else
map(0xfd000000, 0xfd000003).r(FUNC(ms32_state::ms32_sound_r)); 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"); 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. */ /* 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 */ /* 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); 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); 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(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(0xfce00800, 0xfce0085f).ram(); // ROZ0 control register (mirrored from 0x400?)
map(0xfce00200, 0xfce0021f).ram(); // regs?
map(0xfce00800, 0xfce0085f).ram(); // regs?
/* these two are almost certainly wrong, they just let you see what /* these two are almost certainly wrong, they just let you see what
happens if you generate the FPU ints without breaking other games */ happens if you generate the FPU ints without breaking other games */
map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_state::ms32_irq5_guess_w)); // map(0xfce00e00, 0xfce00e03).w(FUNC(ms32_f1superbattle_state::ms32_irq5_guess_w));
map(0xfd0f0000, 0xfd0f0003).w(FUNC(ms32_state::ms32_irq2_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(0xfd100000, 0xfd103fff).ram(); // used when you start enabling fpu ints
map(0xfd104000, 0xfd105fff).ram(); // uploads data here map(0xfd104000, 0xfd105fff).ram(); // uploads data here
// COPRO 2
map(0xfd140000, 0xfd143fff).ram(); // used when you start enabling fpu ints map(0xfd140000, 0xfd143fff).ram(); // used when you start enabling fpu ints
map(0xfd144000, 0xfd145fff).ram(); // same data here 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(0xfde00000, 0xfde1ffff).ram(); // scroll info for lineram?
// map(0xfe202000, 0xfe2fffff).ram(); // vram?
} }
/* F1 Super Battle speculation from nuapete /* 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" ) PORT_DIPUNKNOWN_DIPLOC( 0x00000004, 0x00000004, "SW2:6" )
INPUT_PORTS_END INPUT_PORTS_END
static INPUT_PORTS_START( kirarast ) // player 1 inputs done? others? static INPUT_PORTS_START( kirarast )
PORT_INCLUDE( ms32_mahjong ) PORT_INCLUDE( ms32_mahjong )
PORT_MODIFY("DSW") 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_DIPNAME( 0x00000004, 0x00000004, "Campaign Mode" ) PORT_DIPLOCATION("SW2:6")
PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000004, DEF_STR( On ) ) 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( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000008, DEF_STR( On ) ) PORT_DIPSETTING( 0x00000008, DEF_STR( On ) )
PORT_DIPNAME( 0x00000010, 0x00000010, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:4") 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 ) ) PORT_DIPSETTING( 0x00000020, DEF_STR( Hardest ) )
INPUT_PORTS_END INPUT_PORTS_END
static INPUT_PORTS_START( suchie2 ) // player 1 inputs done? others? static INPUT_PORTS_START( suchie2 )
PORT_INCLUDE( kirarast ) PORT_INCLUDE( kirarast )
PORT_MODIFY("INPUTS") PORT_MODIFY("INPUTS")
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNUSED ) /* coin 2 is unused */ PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_UNUSED ) /* coin 2 is unused */
PORT_MODIFY("DSW") 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( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000400, DEF_STR( On ) ) 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( 0x00000000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00000800, DEF_STR( On ) ) PORT_DIPSETTING( 0x00000800, DEF_STR( On ) )
PORT_DIPNAME( 0x00001000, 0x00001000, DEF_STR( Demo_Sounds) ) PORT_DIPLOCATION("SW1:4") 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 ) ) PORT_DIPSETTING( 0x00000080, DEF_STR( Hardest ) )
INPUT_PORTS_END INPUT_PORTS_END
static INPUT_PORTS_START( wpksocv2 ) static INPUT_PORTS_START( wpksocv2 )
PORT_INCLUDE( ms32 ) PORT_INCLUDE( ms32 )
PORT_MODIFY("INPUTS") 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( 0x0000000f, 0x00000000, IPT_PEDAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(7) PORT_PLAYER(1)
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x00000020, 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_DIPSETTING( 0x00200000, DEF_STR( On ) )
PORT_DIPNAME( 0x00c00000, 0x00000000, DEF_STR( Region ) ) PORT_DIPLOCATION("SW3:2,1") PORT_DIPNAME( 0x00c00000, 0x00000000, DEF_STR( Region ) ) PORT_DIPLOCATION("SW3:2,1")
PORT_DIPSETTING( 0x00400000, DEF_STR( USA ) ) PORT_DIPSETTING( 0x00400000, DEF_STR( USA ) )
PORT_DIPSETTING( 0x00000000, DEF_STR( World ) ) PORT_DIPSETTING( 0x00000000, DEF_STR( Asia ) )
// PORT_DIPSETTING( 0x00800000, "?" ) // PORT_DIPSETTING( 0x00800000, "?" )
PORT_DIPSETTING( 0x00c00000, DEF_STR( Japan ) ) PORT_DIPSETTING( 0x00c00000, DEF_STR( Japan ) )
INPUT_PORTS_END INPUT_PORTS_END
static INPUT_PORTS_START( f1superb ) static INPUT_PORTS_START( f1superb )
PORT_INCLUDE( ms32 ) PORT_INCLUDE( ms32 )
PORT_MODIFY("INPUTS") 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( 0x00000002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Brake")
PORT_BIT( 0x0000fffc, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x0000fffc, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x00400000, 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( 0x0c, "7" )
PORT_DIPSETTING( 0x0e, "8" ) PORT_DIPSETTING( 0x0e, "8" )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END INPUT_PORTS_END
/********** GFX DECODE **********/ /********** GFX DECODE **********/
@ -1585,7 +1610,7 @@ static GFXDECODE_START( gfx_f1superb )
GFXDECODE_ENTRY( "gfx2", 0, bglayout, 0x2000, 0x10 ) GFXDECODE_ENTRY( "gfx2", 0, bglayout, 0x2000, 0x10 )
GFXDECODE_ENTRY( "gfx3", 0, bglayout, 0x1000, 0x10 ) GFXDECODE_ENTRY( "gfx3", 0, bglayout, 0x1000, 0x10 )
GFXDECODE_ENTRY( "gfx4", 0, txlayout, 0x6000, 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 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; int i;
// TODO: confirm irq priority
for(i=15; i>=0 && !(m_irqreq & (1<<i)); i--); 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; return i;
} }
void ms32_state::irq_init() void ms32_base_state::irq_init()
{ {
m_irqreq = 0; m_irqreq = 0;
m_maincpu->set_input_line(0, CLEAR_LINE); m_maincpu->set_input_line(0, CLEAR_LINE);
} }
void ms32_state::irq_raise(int level) void ms32_base_state::irq_raise(int level, bool state)
{ {
m_irqreq |= (1<<level); if (state == true)
m_maincpu->set_input_line(0, ASSERT_LINE); 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) */ WRITE_LINE_MEMBER(ms32_base_state::timer_irq_w)
TIMER_DEVICE_CALLBACK_MEMBER(ms32_state::ms32_interrupt)
{ {
int scanline = param; irq_raise(0, state);
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) WRITE_LINE_MEMBER(ms32_base_state::vblank_irq_w)
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) irq_raise(10, state);
in different points. Could this be a raster interrupt? }
Other games using it but not needing it to work:
desertwr WRITE_LINE_MEMBER(ms32_base_state::field_irq_w)
p47aces {
*/ irq_raise(9, state);
if( (scanline % 8) == 0 && scanline <= 224 ) irq_raise(0); }
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 ?? code at $38 reads the 2nd command latch ??
*/ */
u8 ms32_state::latch_r() u8 ms32_base_state::latch_r()
{ {
return m_soundlatch->read()^0xff; 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[0]->set_entry((data >> 0) & 0x0f);
m_z80bank[1]->set_entry((data >> 4) & 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; m_to_main = data;
irq_raise(1); 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(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(0x3f10, 0x3f10).rw(FUNC(ms32_state::latch_r), FUNC(ms32_state::to_main_w));
map(0x3f20, 0x3f20).nopr(); /* 2nd latch ? */ map(0x3f20, 0x3f20).nopr(); /* 2nd latch ? */
map(0x3f20, 0x3f20).nopw(); /* to_main2_w ? */ 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"); 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 **********/ /********** 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++) for (int bank = 0; bank < 2; bank++)
m_z80bank[bank]->set_entry(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_addrmap(AS_PROGRAM, &ms32_state::ms32_map);
m_maincpu->set_irq_acknowledge_callback(FUNC(ms32_state::irq_callback)); 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?) 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); m_audiocpu->set_addrmap(AS_PROGRAM, &ms32_state::ms32_sound_map);
config.set_maximum_quantum(attotime::from_hz(60000)); 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 */ /* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60); // dot clock is 48/8 MHz, settable with /6 thru system register [0]
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_screen->set_raw(XTAL(48'000'000)/8, 384, 0, 320, 263, 0, 224); // default CRTC setup
m_screen->set_size(40*8, 28*8); m_screen->set_screen_update(FUNC(ms32_state::screen_update));
m_screen->set_visarea(0*8, 40*8-1, 0*8, 28*8-1); m_screen->screen_vblank().set(FUNC(ms32_state::screen_vblank));
m_screen->set_screen_update(FUNC(ms32_state::screen_update_ms32));
m_screen->screen_vblank().set(FUNC(ms32_state::screen_vblank_ms32));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_ms32); 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_palette(m_palette);
m_sprite->set_color_base(0); m_sprite->set_color_base(0);
m_sprite->set_color_entries(16); m_sprite->set_color_entries(16);
@ -1745,22 +1803,28 @@ void ms32_state::ms32(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch); GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI); m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, INPUT_LINE_NMI);
ymf271_device &ymf(YMF271(config, "ymf", XTAL(16'934'400))); // 16.9344MHz YMF271(config, m_ymf, XTAL(16'934'400)); // 16.9344MHz
ymf.add_route(0, "lspeaker", 1.0); m_ymf->add_route(0, "lspeaker", 1.0);
ymf.add_route(1, "rspeaker", 1.0); m_ymf->add_route(1, "rspeaker", 1.0);
// ymf.add_route(2, "lspeaker", 1.0); Output 2/3 not used? // Output 2/3 not used?
// ymf.add_route(3, "rspeaker", 1.0); // 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); ms32(config);
/* basic machine hardware */ m_sysctrl->set_invert_vblank_lines(true);
m_maincpu->set_addrmap(AS_PROGRAM, &ms32_state::f1superb_map); }
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); 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 ROM_END
void ms32_state::configure_banks() void ms32_base_state::configure_banks()
{ {
save_item(NAME(m_to_main)); save_item(NAME(m_to_main));
for (int bank = 0; bank < 2; bank++) for (int bank = 0; bank < 2; bank++)
@ -2647,11 +2711,13 @@ void ms32_state::init_suchie2()
init_ss92048_01(); 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(); u32 *pROM = (u32 *)memregion("maincpu")->base();
pROM[0x19d04/4]=0x167a021a; // bne->br : sprite Y offset table is always copied to RAM pROM[0x19d04/4]=0x167a021a; // bne->br : sprite Y offset table is always copied to RAM
// the x offsets are never copied either ...
#endif #endif
init_ss92046_01(); init_ss92046_01();
} }
@ -2664,25 +2730,25 @@ void ms32_state::init_bnstars()
/********** GAME DRIVERS **********/ /********** 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, 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, 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, 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, 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( 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, 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_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_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_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_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( 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, 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_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_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, 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, 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_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, wpksocv2, ms32_state, init_ss92046_01, ROT0, "Jaleco", "World PK Soccer V2 (ver 1.1)", MACHINE_IMPERFECT_GRAPHICS | 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 */ /* 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" #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) void tetrisp2_state::rockn_soundvolume_w(u16 data)
{ {
m_rockn_soundvolume = 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; 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) if (ACCESSING_BITS_0_7)
m_rocknms_main2sub = (data ^ 0xffff); 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) if (ACCESSING_BITS_0_7)
m_rocknms_sub2main = (data ^ 0xffff); 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(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers 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(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs
map(0xbe0004, 0xbe0005).r(FUNC(tetrisp2_state::tetrisp2_ip_1_word_r)); // Inputs & protection 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(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(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("BUTTONS"); // Inputs 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(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers 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(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs
map(0xbe0004, 0xbe0005).portr("SYSTEM"); // 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(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers 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(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs map(0xbe0002, 0xbe0003).portr("PLAYERS"); // Inputs
map(0xbe0004, 0xbe0005).portr("SYSTEM"); // 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(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x103fff).ram().share("spriteram"); // Object RAM map(0x100000, 0x103fff).ram().share("spriteram"); // Object RAM
map(0x104000, 0x107fff).ram(); // Spare Object RAM map(0x104000, 0x107fff).ram(); // Spare Object RAM
map(0x108000, 0x10ffff).ram(); // Work RAM map(0x108000, 0x10ffff).ram(); // Work RAM
map(0x200000, 0x23ffff).rw(FUNC(tetrisp2_state::tetrisp2_priority_r), FUNC(tetrisp2_state::tetrisp2_priority_w)); map(0x200000, 0x23ffff).rw(FUNC(rocknms_state::tetrisp2_priority_r), FUNC(rocknms_state::tetrisp2_priority_w));
map(0x300000, 0x31ffff).ram().w(FUNC(tetrisp2_state::tetrisp2_palette_w)).share("paletteram"); // Palette map(0x300000, 0x31ffff).ram().w(FUNC(rocknms_state::tetrisp2_palette_w)).share("paletteram"); // Palette
// map(0x500000, 0x50ffff).ram(); // Line // map(0x500000, 0x50ffff).ram(); // Line
map(0x600000, 0x60ffff).ram().w(FUNC(tetrisp2_state::tetrisp2_vram_rot_w)).share("vram_rot"); // Rotation map(0x600000, 0x60ffff).ram().w(FUNC(rocknms_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(0x800000, 0x803fff).ram().w(FUNC(rocknms_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(0x804000, 0x807fff).ram().w(FUNC(rocknms_state::tetrisp2_vram_bg_w)).share("vram_bg"); // Background
// map(0x808000, 0x809fff).ram(); // ??? // 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(0x900000, 0x903fff).r(FUNC(rocknms_state::rockn_nvram_r)).w(FUNC(rocknms_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(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(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(0xa48000, 0xa48001).nopw(); // YMZ280 Reset
map(0xa00000, 0xa00001).w(FUNC(tetrisp2_state::rocknms_main2sub_w)); // MAIN -> SUB Communication map(0xa00000, 0xa00001).w(FUNC(rocknms_state::rocknms_main2sub_w)); // MAIN -> SUB Communication
map(0xb00000, 0xb00001).w(FUNC(tetrisp2_state::tetrisp2_coincounter_w)); // Coin Counter map(0xb00000, 0xb00001).w(FUNC(rocknms_state::tetrisp2_coincounter_w)); // Coin Counter
map(0xb20000, 0xb20001).nopw(); // ??? map(0xb20000, 0xb20001).nopw(); // ???
map(0xb40000, 0xb4000b).writeonly().share("scroll_fg"); // Foreground Scrolling map(0xb40000, 0xb4000b).writeonly().share("scroll_fg"); // Foreground Scrolling
map(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling map(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers 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(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("PLAYERS"); map(0xbe0002, 0xbe0003).portr("PLAYERS");
map(0xbe0004, 0xbe0005).portr("SYSTEM"); // Inputs 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(0x000000, 0x0fffff).rom(); // ROM
map(0x100000, 0x103fff).ram().share("spriteram2"); // Object RAM map(0x100000, 0x103fff).ram().share("spriteram2"); // Object RAM
map(0x104000, 0x107fff).ram(); // Spare Object RAM map(0x104000, 0x107fff).ram(); // Spare Object RAM
map(0x108000, 0x10ffff).ram(); // Work RAM map(0x108000, 0x10ffff).ram(); // Work RAM
map(0x200000, 0x23ffff).ram().w(FUNC(tetrisp2_state::rocknms_sub_priority_w)).share("sub_priority"); // Priority map(0x200000, 0x23ffff).ram().w(FUNC(rocknms_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(0x300000, 0x31ffff).ram().w(FUNC(rocknms_state::rocknms_sub_palette_w)).share("sub_paletteram"); // Palette
// map(0x500000, 0x50ffff).ram(); // Line // map(0x500000, 0x50ffff).ram(); // Line
map(0x600000, 0x60ffff).ram().w(FUNC(tetrisp2_state::rocknms_sub_vram_rot_w)).share("sub_vram_rot"); // Rotation map(0x600000, 0x60ffff).ram().w(FUNC(rocknms_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(0x800000, 0x803fff).ram().w(FUNC(rocknms_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(0x804000, 0x807fff).ram().w(FUNC(rocknms_state::rocknms_sub_vram_bg_w)).share("sub_vram_bg"); // Background
// map(0x808000, 0x809fff).ram(); // ??? // map(0x808000, 0x809fff).ram(); // ???
map(0x900000, 0x907fff).ram(); // NVRAM 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(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(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(0xb20000, 0xb20001).nopw(); // ???
map(0xb40000, 0xb4000b).writeonly().share("sub_scroll_fg"); // Foreground Scrolling map(0xb40000, 0xb4000b).writeonly().share("sub_scroll_fg"); // Foreground Scrolling
map(0xb40010, 0xb4001b).writeonly().share("sub_scroll_bg"); // Background Scrolling map(0xb40010, 0xb4001b).writeonly().share("sub_scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).nopw(); // scr_size map(0xb4003e, 0xb4003f).nopw(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("sub_rotregs"); // Rotation Registers 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(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 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(0xb40010, 0xb4001b).writeonly().share("scroll_bg"); // Background Scrolling
map(0xb4003e, 0xb4003f).ram(); // scr_size map(0xb4003e, 0xb4003f).ram(); // scr_size
map(0xb60000, 0xb6002f).writeonly().share("rotregs"); // Rotation Registers 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(0xbe0000, 0xbe0001).nopr(); // INT-level1 dummy read
map(0xbe0002, 0xbe0003).portr("BUTTONS"); // Inputs map(0xbe0002, 0xbe0003).portr("BUTTONS"); // Inputs
map(0xbe0004, 0xbe0005).r(FUNC(stepstag_state::stepstag_coins_r)); // Inputs & protection map(0xbe0004, 0xbe0005).r(FUNC(stepstag_state::stepstag_coins_r)); // Inputs & protection
@ -1081,7 +1037,7 @@ INPUT_PORTS_END
static INPUT_PORTS_START( rocknms ) static INPUT_PORTS_START( rocknms )
PORT_START("PLAYERS") // IN0 - $be0002.w 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( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) 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) 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() 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_protectdata));
save_item(NAME(m_rockn_adpcmbank)); save_item(NAME(m_rockn_adpcmbank));
save_item(NAME(m_rockn_soundvolume)); save_item(NAME(m_rockn_soundvolume));
save_item(NAME(m_rocknms_main2sub));
save_item(NAME(m_rocknms_sub2main));
} }
void tetrisp2_state::init_rockn() void tetrisp2_state::init_rockn()
@ -1648,17 +1574,12 @@ void tetrisp2_state::init_rockn2()
m_rockn_protectdata = 2; m_rockn_protectdata = 2;
} }
void tetrisp2_state::init_rocknms() void rocknms_state::init_rocknms()
{ {
init_rockn_timer(); 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; m_rockn_protectdata = 3;
save_item(NAME(m_rocknms_main2sub));
save_item(NAME(m_rocknms_sub2main));
} }
void tetrisp2_state::init_rockn3() void tetrisp2_state::init_rockn3()
@ -1673,34 +1594,68 @@ void stepstag_state::init_stepstag()
m_rockn_protectdata = 1; // unused? 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) void tetrisp2_state::tetrisp2(machine_config &config)
{ {
/* basic machine hardware */ /* basic machine hardware */
M68000(config, m_maincpu, 12_MHz_XTAL); // 12MHz M68000(config, m_maincpu, 12_MHz_XTAL); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::tetrisp2_map); 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); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog").set_vblank_count("screen", 8); /* guess */ WATCHDOG_TIMER(config, "watchdog").set_vblank_count("screen", 8); /* guess */
/* video hardware */ /* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); constexpr XTAL pixel_clock = XTAL(48'000'000)/8;
screen.set_refresh_hz(60); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224); // default CRTC setup
screen.set_size(0x140, 0xe0); m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2));
screen.set_visarea(0, 0x140-1, 0, 0xe0-1); m_screen->set_palette(m_palette);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2); GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000); PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video? setup_main_sprite(config, pixel_clock);
m_sprite->set_palette(m_palette); setup_main_sysctrl(config, XTAL(48'000'000));
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,tetrisp2) 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, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right(); 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(0, "lspeaker", 1.0);
ymz.add_route(1, "rspeaker", 1.0); ymz.add_route(1, "rspeaker", 1.0);
} }
@ -1719,28 +1674,25 @@ void tetrisp2_state::nndmseal(machine_config &config)
/* basic machine hardware */ /* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::nndmseal_map); 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); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog"); WATCHDOG_TIMER(config, "watchdog");
/* video hardware */ /* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); // An odd one: it uses the faster dot clock divider setting
screen.set_refresh_hz(60); // but they replaced the xtal to a OSC1(42.9545MHz), I guess they compensated to not go out of ~60 Hz
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); constexpr XTAL pixel_clock = XTAL(42'954'545)/6;
screen.set_size(0x180, 0xf0); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
screen.set_visarea(0, 0x180-1, 0, 0xf0-1); m_screen->set_raw(pixel_clock, 455, 0, 384, 262, 0, 240);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2)); m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_tetrisp2));
screen.set_palette(m_palette); m_screen->set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2); GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000); PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, 42954500); // OSC1(42.9545MHz) for video? setup_main_sprite(config, pixel_clock);
m_sprite->set_palette(m_palette); setup_main_sysctrl(config, XTAL(42'954'545));
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,nndmseal) // bg layer offset MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,nndmseal) // bg layer offset
@ -1756,28 +1708,23 @@ void tetrisp2_state::rockn(machine_config &config)
/* basic machine hardware */ /* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rockn1_map); 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); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog"); WATCHDOG_TIMER(config, "watchdog");
/* video hardware */ /* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); constexpr XTAL pixel_clock = XTAL(48'000'000)/8;
screen.set_refresh_hz(60); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224);
screen.set_size(0x140, 0xe0); m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
screen.set_visarea(0, 0x140-1, 0, 0xe0-1); m_screen->set_palette(m_palette);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2); GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000); PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video? setup_main_sprite(config, pixel_clock);
m_sprite->set_palette(m_palette); setup_main_sysctrl(config, XTAL(48'000'000));
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,rockntread) MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,rockntread)
@ -1796,28 +1743,23 @@ void tetrisp2_state::rockn2(machine_config &config)
/* basic machine hardware */ /* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rockn2_map); 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); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog"); WATCHDOG_TIMER(config, "watchdog");
/* video hardware */ /* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); constexpr XTAL pixel_clock = XTAL(48'000'000)/8;
screen.set_refresh_hz(60); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_screen->set_raw(pixel_clock, 384, 0, 320, 263, 0, 224);
screen.set_size(0x140, 0xe0); m_screen->set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
screen.set_visarea(0, 0x140-1, 0, 0xe0-1); m_screen->set_palette(m_palette);
screen.set_screen_update(FUNC(tetrisp2_state::screen_update_rockntread));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2); GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000); PALETTE(config, m_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video? setup_main_sprite(config, pixel_clock);
m_sprite->set_palette(m_palette); setup_main_sysctrl(config, XTAL(48'000'000));
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
MCFG_VIDEO_START_OVERRIDE(tetrisp2_state,rockntread) 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); 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 */ /* basic machine hardware */
M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz
m_maincpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rocknms_main_map); m_maincpu->set_addrmap(AS_PROGRAM, &rocknms_state::rocknms_main_map);
m_maincpu->set_vblank_int("lscreen", FUNC(tetrisp2_state::irq2_line_hold));
M68000(config, m_subcpu, XTAL(12'000'000)); // 12MHz M68000(config, m_subcpu, XTAL(12'000'000)); // 12MHz
m_subcpu->set_addrmap(AS_PROGRAM, &tetrisp2_state::rocknms_sub_map); m_subcpu->set_addrmap(AS_PROGRAM, &rocknms_state::rocknms_sub_map);
m_subcpu->set_vblank_int("lscreen", FUNC(tetrisp2_state::irq2_line_hold));
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
@ -1848,42 +1807,44 @@ void tetrisp2_state::rocknms(machine_config &config)
/* video hardware */ /* 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); GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000); PALETTE(config, m_palette).set_entries(0x8000);
GFXDECODE(config, m_sub_gfxdecode, m_sub_palette, gfx_rocknms_sub); GFXDECODE(config, m_sub_gfxdecode, m_sub_palette, gfx_rocknms_sub);
PALETTE(config, m_sub_palette).set_entries(0x8000); PALETTE(config, m_sub_palette).set_entries(0x8000);
JALECO_MEGASYSTEM32_SPRITE(config, m_sprite, XTAL(48'000'000)); // 48MHz for video? setup_main_sprite(config, pixel_clock);
m_sprite->set_palette(m_palette);
m_sprite->set_color_base(0);
m_sprite->set_color_entries(16);
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_palette(m_sub_palette);
m_rocknms_sub_sprite->set_color_base(0); m_rocknms_sub_sprite->set_color_base(0);
m_rocknms_sub_sprite->set_color_entries(16); m_rocknms_sub_sprite->set_color_entries(16);
m_rocknms_sub_sprite->set_zoom(false);
config.set_default_layout(layout_rocknms); setup_main_sysctrl(config, XTAL(48'000'000));
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER)); JALECO_MS32_SYSCTRL(config, m_sub_sysctrl, XTAL(48'000'000), m_sub_screen);
lscreen.set_orientation(ROT0); m_sub_sysctrl->flip_screen_cb().set(FUNC(rocknms_state::sub_flipscreen_w));
lscreen.set_refresh_hz(60); m_sub_sysctrl->vblank_cb().set(FUNC(rocknms_state::sub_vblank_irq_w));
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_sub_sysctrl->field_cb().set(FUNC(rocknms_state::sub_field_irq_w));
lscreen.set_size(0x140, 0xe0); m_sub_sysctrl->prg_timer_cb().set(FUNC(rocknms_state::sub_timer_irq_w));
lscreen.set_visarea(0, 0x140-1, 0, 0xe0-1); m_sub_sysctrl->sound_reset_cb().set(FUNC(rocknms_state::sub_sound_reset_line_w));
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)
MCFG_VIDEO_START_OVERRIDE(rocknms_state,rocknms)
/* sound hardware */ /* sound hardware */
SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right(); SPEAKER(config, "rspeaker").front_right();
@ -1893,51 +1854,62 @@ void tetrisp2_state::rocknms(machine_config &config)
ymz.add_route(1, "rspeaker", 1.0); 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) 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_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_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); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog"); WATCHDOG_TIMER(config, "watchdog");
// video hardware // 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)); screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
lscreen.set_orientation(ROT270); lscreen.set_orientation(ROT270);
// lscreen.set_raw(12288000*2, 768, 0, 496, 264*2,0,480); setup_non_sysctrl_screen(config, &lscreen, subxtal);
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);
lscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_left)); 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)); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
mscreen.set_orientation(ROT0); m_screen->set_orientation(ROT0);
mscreen.set_refresh_hz(60); // TODO: connected to the non sysctrl CRTC anyway?
mscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_screen->set_raw(XTAL(48'000'000)/8, 384, 0, 320, 263, 0, 224);
mscreen.set_size(0x160, 0xf0); m_screen->set_screen_update(FUNC(stepstag_state::screen_update_stepstag_mid));
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_device &rscreen(SCREEN(config, "rscreen", SCREEN_TYPE_RASTER)); screen_device &rscreen(SCREEN(config, "rscreen", SCREEN_TYPE_RASTER));
rscreen.set_orientation(ROT270); rscreen.set_orientation(ROT270);
rscreen.set_refresh_hz(30); setup_non_sysctrl_screen(config, &rscreen, subxtal);
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(0x160, 0xf0);
rscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
rscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_right)); 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); GFXDECODE(config, m_gfxdecode, m_palette, gfx_tetrisp2);
PALETTE(config, m_palette).set_entries(0x8000); 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_m).set_entries(0x8000);
PALETTE(config, m_vj_palette_r).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_palette(m_palette);
m_sprite->set_color_base(0); m_sprite->set_color_base(0);
m_sprite->set_color_entries(16); m_sprite->set_color_entries(16);
m_sprite->set_zoom(false);
// (left screen, vertical in stepping stage) // (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_palette(m_vj_palette_l);
m_vj_sprite_l->set_color_base(0); m_vj_sprite_l->set_color_base(0);
m_vj_sprite_l->set_color_entries(0x80); 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) // (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_palette(m_vj_palette_m);
m_vj_sprite_m->set_color_base(0); m_vj_sprite_m->set_color_base(0);
m_vj_sprite_m->set_color_entries(0x80); 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) // (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_palette(m_vj_palette_r);
m_vj_sprite_r->set_color_base(0); m_vj_sprite_r->set_color_base(0);
m_vj_sprite_r->set_color_entries(0x80); 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); config.set_default_layout(layout_stepstag);
@ -1976,7 +1957,7 @@ void stepstag_state::stepstag(machine_config &config)
GENERIC_LATCH_16(config, m_soundlatch); 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(0, "lspeaker", 1.0);
ymz.add_route(1, "rspeaker", 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? M68000(config, m_maincpu, XTAL(12'000'000)); // 12MHz?
m_maincpu->set_addrmap(AS_PROGRAM, &stepstag_state::vjdash_map); 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_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); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
WATCHDOG_TIMER(config, "watchdog"); WATCHDOG_TIMER(config, "watchdog");
// video hardware // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); // same as stepstag, we assume that this screen is effectively connected to the system CRTC
screen.set_refresh_hz(60); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); m_screen->set_raw(main_pixel_clock, 384, 0, 320, 263, 0, 224);
screen.set_size(0x160, 0xf0); m_screen->set_screen_update(FUNC(stepstag_state::screen_update_stepstag_main));
screen.set_visarea(0, 0x140-1, 0, 0xe0-1); m_screen->set_palette(m_palette);
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);
screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER)); screen_device &lscreen(SCREEN(config, "lscreen", SCREEN_TYPE_RASTER));
lscreen.set_refresh_hz(30); setup_non_sysctrl_screen(config, &lscreen, subxtal);
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
lscreen.set_size(0x160, 0xf0);
lscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
lscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_left)); 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)); screen_device &mscreen(SCREEN(config, "mscreen", SCREEN_TYPE_RASTER));
mscreen.set_refresh_hz(30); setup_non_sysctrl_screen(config, &mscreen, subxtal);
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_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)); screen_device &rscreen(SCREEN(config, "rscreen", SCREEN_TYPE_RASTER));
rscreen.set_refresh_hz(30); setup_non_sysctrl_screen(config, &rscreen, subxtal);
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(0x160, 0xf0);
rscreen.set_visarea(0, 0x160-1, 0, 0xf0-1);
rscreen.set_screen_update(FUNC(stepstag_state::screen_update_stepstag_right)); 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); 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_m).set_entries(0x8000);
PALETTE(config, m_vj_palette_r).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_palette(m_palette);
m_sprite->set_color_base(0); m_sprite->set_color_base(0);
m_sprite->set_color_entries(16); m_sprite->set_color_entries(16);
// (left screen, vertical in stepping stage) // (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_palette(m_vj_palette_l);
m_vj_sprite_l->set_color_base(0); m_vj_sprite_l->set_color_base(0);
m_vj_sprite_l->set_color_entries(0x80); m_vj_sprite_l->set_color_entries(0x80);
m_vj_sprite_l->set_zoom(false);
// (mid screen, horizontal) // (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_palette(m_vj_palette_m);
m_vj_sprite_m->set_color_base(0); m_vj_sprite_m->set_color_base(0);
m_vj_sprite_m->set_color_entries(0x80); m_vj_sprite_m->set_color_entries(0x80);
m_vj_sprite_m->set_zoom(false);
// (right screens, vertical in stepping stage) // (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_palette(m_vj_palette_r);
m_vj_sprite_r->set_color_base(0); m_vj_sprite_r->set_color_base(0);
m_vj_sprite_r->set_color_entries(0x80); 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); 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); 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(0, "lspeaker", 1.0);
ymz.add_route(1, "rspeaker", 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, 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, 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, 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( 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 ) GAME( 2000, rockn4, 0, rockn2, rockn, tetrisp2_state, init_rockn3, ROT270, "Jaleco / PCCWJ", "Rock'n 4 (Japan, prototype)", MACHINE_SUPPORTS_SAVE )
// Undumped: // Undumped:
// - Stepping Stage <- the original Game // - Stepping Stage <- the original Game
// - Stepping Stage 2 Supreme // - 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, 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, 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) 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> // copyright-holders:<author_name>
/*************************************************************************** /***************************************************************************
Template for skeleton device <device_longname>
***************************************************************************/ ***************************************************************************/
#include "emu.h" #include "emu.h"
#include "xxx.h" #include "<device_classname>.h"
//************************************************************************** //**************************************************************************
// GLOBAL VARIABLES // GLOBAL VARIABLES
//************************************************************************** //**************************************************************************
// device type definition // 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 // 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 // device_add_mconfig - device-specific machine
// configuration addiitons // configuration addiitons
//------------------------------------------------- //-------------------------------------------------
void xxx_device::device_add_mconfig(machine_config &config)
void <device_classname>_device::device_add_mconfig(machine_config &config)
{ {
//DEVICE(config, ...); //DEVICE(config, ...);
} }
@ -50,7 +51,8 @@ void xxx_device::device_add_mconfig(machine_config &config)
// device_start - device-specific startup // 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 // 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 // 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; 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> // copyright-holders:<author_name>
/*************************************************************************** /***************************************************************************
Template for skeleton device <device_longname>
***************************************************************************/ ***************************************************************************/
#ifndef MAME_MACHINE_XXX_H #ifndef MAME_MACHINE_<device_header>_H
#define MAME_MACHINE_XXX_H #define MAME_MACHINE_<device_header>_H
#pragma once #pragma once
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//************************************************************************** //**************************************************************************
// TYPE DEFINITIONS // TYPE DEFINITIONS
//************************************************************************** //**************************************************************************
// ======================> xxx_device class <device_classname>_device : public device_t
class xxx_device : public device_t
{ {
public: public:
// construction/destruction // 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 // I/O operations
void write(address_space &space, offs_t offset, uint8_t data, uint8_t mem_mask = ~0); void write(address_space &space, offs_t offset, uint8_t data, uint8_t mem_mask = ~0);
@ -45,13 +35,6 @@ protected:
// device type definition // device type definition
DECLARE_DEVICE_TYPE(XXX, xxx_device) DECLARE_DEVICE_TYPE(<device_typename>, <device_classname>_device)
#endif // MAME_MACHINE_<device_header>_H
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#endif // MAME_MACHINE_XXX_H

View File

@ -7,41 +7,83 @@
#include "machine/gen_latch.h" #include "machine/gen_latch.h"
#include "machine/timer.h" #include "machine/timer.h"
#include "machine/jaleco_ms32_sysctrl.h"
#include "video/ms32_sprite.h" #include "video/ms32_sprite.h"
#include "sound/ymf271.h"
#include "emupal.h" #include "emupal.h"
#include "screen.h" #include "screen.h"
#include "tilemap.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: public:
ms32_state(const machine_config &mconfig, device_type type, const char *tag) : ms32_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag), ms32_base_state(mconfig, type, tag)
m_palette(*this, "palette"), , m_sysctrl(*this, "sysctrl")
m_gfxdecode(*this, "gfxdecode"), , m_screen(*this, "screen")
m_maincpu(*this, "maincpu"), , m_sprite(*this, "sprite")
m_audiocpu(*this, "audiocpu"), , m_palette(*this, "palette")
m_sprite(*this, "sprite"), , m_gfxdecode(*this, "gfxdecode")
m_soundlatch(*this, "soundlatch"), , m_ymf(*this, "ymf")
m_screen(*this, "screen"), , m_roz_ctrl(*this, "roz_ctrl")
m_mainram(*this, "mainram"), , m_tx_scroll(*this, "tx_scroll")
m_roz_ctrl(*this, "roz_ctrl"), , m_bg_scroll(*this, "bg_scroll")
m_tx_scroll(*this, "tx_scroll"), , m_mahjong_input_select(*this, "mahjong_select")
m_bg_scroll(*this, "bg_scroll"), , m_priram(*this, "priram", 0x2000, ENDIANNESS_LITTLE)
m_mahjong_input_select(*this, "mahjong_select"), , m_palram(*this, "palram", 0x20000, ENDIANNESS_LITTLE)
m_priram(*this, "priram"), , m_rozram(*this, "rozram", 0x10000, ENDIANNESS_LITTLE)
m_palram(*this, "palram"), , m_lineram(*this, "lineram", 0x1000, ENDIANNESS_LITTLE)
m_rozram(*this, "rozram"), , m_sprram(*this, "sprram", 0x10000, ENDIANNESS_LITTLE)
m_lineram(*this, "lineram"), , m_txram(*this, "txram", 0x4000, ENDIANNESS_LITTLE)
m_sprram(*this, "sprram"), , m_bgram(*this, "bgram", 0x4000, ENDIANNESS_LITTLE)
m_txram(*this, "txram"),
m_bgram(*this, "bgram"),
m_f1superb_extraram(*this, "f1sb_extraram"),
m_z80bank(*this, "z80bank%u", 1)
{ } { }
void ms32(machine_config &config); void ms32(machine_config &config);
void f1superb(machine_config &config); void ms32_invert_lines(machine_config &config);
void init_ss92047_01(); void init_ss92047_01();
void init_ss91022_10(); void init_ss91022_10();
@ -49,63 +91,47 @@ public:
void init_suchie2(); void init_suchie2();
void init_ss92048_01(); void init_ss92048_01();
void init_bnstars(); void init_bnstars();
void init_f1superb();
void init_ss92046_01(); void init_ss92046_01();
IRQ_CALLBACK_MEMBER(irq_callback);
DECLARE_CUSTOM_INPUT_MEMBER(mahjong_ctrl_r); DECLARE_CUSTOM_INPUT_MEMBER(mahjong_ctrl_r);
protected: protected:
required_device<jaleco_ms32_sysctrl_device> m_sysctrl;
void configure_banks(); required_device<screen_device> m_screen;
required_device<ms32_sprite_device> m_sprite;
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<palette_device> m_palette; required_device<palette_device> m_palette;
required_device<gfxdecode_device> m_gfxdecode; required_device<gfxdecode_device> m_gfxdecode;
required_device<ymf271_device> m_ymf;
int m_reverse_sprite_order; DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
int m_flipscreen; virtual void video_start() override;
required_device<cpu_device> m_maincpu; void ms32_map(address_map &map);
required_device<cpu_device> m_audiocpu; void ms32_sound_map(address_map &map);
required_device<ms32_sprite_device> m_sprite;
optional_device<generic_latch_8_device> m_soundlatch;
private: private:
optional_device<screen_device> m_screen; required_shared_ptr<u32> m_roz_ctrl;
optional_shared_ptr<u32> m_mainram; required_shared_ptr<u32> m_tx_scroll;
optional_shared_ptr<u32> m_roz_ctrl; required_shared_ptr<u32> m_bg_scroll;
optional_shared_ptr<u32> m_tx_scroll; required_shared_ptr<u32> m_mahjong_input_select;
optional_shared_ptr<u32> m_bg_scroll; memory_share_creator<u8> m_priram;
optional_shared_ptr<u32> m_mahjong_input_select; memory_share_creator<u16> m_palram;
optional_shared_ptr<u8> m_priram; memory_share_creator<u16> m_rozram;
optional_shared_ptr<u16> m_palram; memory_share_creator<u16> m_lineram;
optional_shared_ptr<u16> m_rozram; memory_share_creator<u16> m_sprram;
optional_shared_ptr<u16> m_lineram; memory_share_creator<u16> m_txram;
optional_shared_ptr<u16> m_sprram; memory_share_creator<u16> m_bgram;
optional_shared_ptr<u16> m_txram;
optional_shared_ptr<u16> m_bgram;
optional_shared_ptr<u16> m_f1superb_extraram;
optional_memory_bank_array<2> m_z80bank;
std::unique_ptr<u8[]> m_nvram_8; std::unique_ptr<u8[]> m_nvram_8;
std::unique_ptr<u16[]> m_sprram_buffer; std::unique_ptr<u16[]> m_sprram_buffer;
u32 m_to_main; size_t m_objectram_size;
u16 m_irqreq;
tilemap_t *m_tx_tilemap; tilemap_t *m_tx_tilemap;
tilemap_t *m_roz_tilemap; tilemap_t *m_roz_tilemap;
tilemap_t *m_bg_tilemap; tilemap_t *m_bg_tilemap;
tilemap_t *m_bg_tilemap_alt; tilemap_t *m_bg_tilemap_alt;
u32 m_tilemaplayoutcontrol; u32 m_tilemaplayoutcontrol;
tilemap_t* m_extra_tilemap;
bitmap_ind16 m_temp_bitmap_tilemaps; bitmap_ind16 m_temp_bitmap_tilemaps;
bitmap_ind16 m_temp_bitmap_sprites; bitmap_ind16 m_temp_bitmap_sprites;
bitmap_ind8 m_temp_bitmap_sprites_pri; bitmap_ind8 m_temp_bitmap_sprites_pri;
@ -113,7 +139,6 @@ private:
int m_brt_r; int m_brt_r;
int m_brt_g; int m_brt_g;
int m_brt_b; int m_brt_b;
u32 ms32_read_inputs3();
u8 ms32_nvram_r8(offs_t offset); u8 ms32_nvram_r8(offs_t offset);
void ms32_nvram_w8(offs_t offset, u8 data); void ms32_nvram_w8(offs_t offset, u8 data);
u8 ms32_priram_r8(offs_t offset); 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); void ms32_txram_w16(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 ms32_bgram_r16(offs_t offset); u16 ms32_bgram_r16(offs_t offset);
void ms32_bgram_w16(offs_t offset, u16 data, u16 mem_mask = ~0); void ms32_bgram_w16(offs_t offset, u16 data, u16 mem_mask = ~0);
void pip_w(u32 data); void bgmode_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 ms32_brightness_w(offs_t offset, u32 data, u32 mem_mask = ~0); 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 coin_counter_w(u32 data);
void init_ms32_common(); void init_ms32_common();
TILE_GET_INFO_MEMBER(get_ms32_tx_tile_info); TILE_GET_INFO_MEMBER(get_ms32_tx_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_roz_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_bg_tile_info);
TILE_GET_INFO_MEMBER(get_ms32_extra_tile_info);
virtual void machine_reset() override; u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
virtual void video_start() override; DECLARE_WRITE_LINE_MEMBER(screen_vblank);
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);
void update_color(int color); 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); 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 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 #endif // MAME_INCLUDES_MS32_H

View File

@ -2,6 +2,7 @@
// copyright-holders:Luca Elia // copyright-holders:Luca Elia
#include "machine/gen_latch.h" #include "machine/gen_latch.h"
#include "machine/jaleco_ms32_sysctrl.h"
#include "video/ms32_sprite.h" #include "video/ms32_sprite.h"
#include "emupal.h" #include "emupal.h"
#include "tilemap.h" #include "tilemap.h"
@ -10,57 +11,49 @@ class tetrisp2_state : public driver_device
{ {
public: public:
tetrisp2_state(const machine_config &mconfig, device_type type, const char *tag) : tetrisp2_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag), driver_device(mconfig, type, tag)
m_maincpu(*this, "maincpu"), , m_maincpu(*this, "maincpu")
m_subcpu(*this, "sub"), , m_sysctrl(*this, "sysctrl")
m_sprite(*this, "sprite"), , m_sprite(*this, "sprite")
m_rocknms_sub_sprite(*this, "sub_sprite"), , m_screen(*this, "screen")
m_spriteram(*this, "spriteram"), , m_spriteram(*this, "spriteram")
m_spriteram2(*this, "spriteram2"), , m_spriteram2(*this, "spriteram2")
m_vram_fg(*this, "vram_fg"), , m_vram_fg(*this, "vram_fg")
m_vram_bg(*this, "vram_bg"), , m_vram_bg(*this, "vram_bg")
m_vram_rot(*this, "vram_rot"), , m_vram_rot(*this, "vram_rot")
m_nvram(*this, "nvram"), , m_nvram(*this, "nvram")
m_scroll_fg(*this, "scroll_fg"), , m_scroll_fg(*this, "scroll_fg")
m_scroll_bg(*this, "scroll_bg"), , m_scroll_bg(*this, "scroll_bg")
m_rotregs(*this, "rotregs"), , m_rotregs(*this, "rotregs")
m_rocknms_sub_priority(*this, "sub_priority"), , m_gfxdecode(*this, "gfxdecode")
m_rocknms_sub_vram_rot(*this, "sub_vram_rot"), , m_sub_gfxdecode(*this, "sub_gfxdecode")
m_rocknms_sub_vram_fg(*this, "sub_vram_fg"), , m_palette(*this, "palette")
m_rocknms_sub_vram_bg(*this, "sub_vram_bg"), , m_paletteram(*this, "paletteram")
m_rocknms_sub_scroll_fg(*this, "sub_scroll_fg"), , m_leds(*this, "led%u", 0U)
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)
{ } { }
void rockn2(machine_config &config); void rockn2(machine_config &config);
void tetrisp2(machine_config &config); void tetrisp2(machine_config &config);
void nndmseal(machine_config &config); void nndmseal(machine_config &config);
void rocknms(machine_config &config);
void rockn(machine_config &config); void rockn(machine_config &config);
void init_rockn2(); void init_rockn2();
void init_rockn1(); void init_rockn1();
void init_rockn(); void init_rockn();
void init_rockn3(); 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(get_tile_info_bg);
TILE_GET_INFO_MEMBER(stepstag_get_tile_info_fg);
TILE_GET_INFO_MEMBER(get_tile_info_rot); TILE_GET_INFO_MEMBER(get_tile_info_rot);
protected: protected:
void rockn_systemregs_w(offs_t offset, u16 data, u16 mem_mask = ~0); void setup_main_sysctrl(machine_config &config, const XTAL clock);
void rocknms_sub_systemregs_w(offs_t offset, u16 data, u16 mem_mask = ~0); 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(); u16 rockn_adpcmbank_r();
void rockn_adpcmbank_w(u16 data); void rockn_adpcmbank_w(u16 data);
void rockn2_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); void nndmseal_sound_bank_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u16 tetrisp2_ip_1_word_r(); u16 tetrisp2_ip_1_word_r();
u16 rockn_nvram_r(offs_t offset); 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 tetrisp2_coincounter_w(u16 data);
void nndmseal_coincounter_w(offs_t offset, u16 data, u16 mem_mask = ~0); void nndmseal_coincounter_w(offs_t offset, u16 data, u16 mem_mask = ~0);
void nndmseal_b20000_w(u16 data); 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); u16 tetrisp2_nvram_r(offs_t offset);
void tetrisp2_nvram_w(offs_t offset, u16 data, u16 mem_mask = ~0); 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 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 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); u16 tetrisp2_priority_r(offs_t offset);
void tetrisp2_vram_bg_w(offs_t offset, u16 data, u16 mem_mask = ~0); 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_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 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_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(tetrisp2);
DECLARE_VIDEO_START(nndmseal); DECLARE_VIDEO_START(nndmseal);
DECLARE_VIDEO_START(rockntread); DECLARE_VIDEO_START(rockntread);
DECLARE_VIDEO_START(rocknms);
u32 screen_update_tetrisp2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); 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_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 init_rockn_timer();
void nndmseal_map(address_map &map); void nndmseal_map(address_map &map);
void rockn1_map(address_map &map); void rockn1_map(address_map &map);
void rockn2_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); void tetrisp2_map(address_map &map);
virtual void machine_start() override { m_leds.resolve(); } virtual void machine_start() override { m_leds.resolve(); }
required_device<cpu_device> m_maincpu; 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; 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; required_shared_ptr<u16> m_spriteram;
optional_shared_ptr<u16> m_spriteram2; optional_shared_ptr<u16> m_spriteram2;
u16 m_systemregs[0x10];
required_shared_ptr<u16> m_vram_fg; required_shared_ptr<u16> m_vram_fg;
required_shared_ptr<u16> m_vram_bg; required_shared_ptr<u16> m_vram_bg;
required_shared_ptr<u16> m_vram_rot; required_shared_ptr<u16> m_vram_rot;
@ -137,59 +106,114 @@ protected:
required_shared_ptr<u16> m_scroll_bg; required_shared_ptr<u16> m_scroll_bg;
required_shared_ptr<u16> m_rotregs; required_shared_ptr<u16> m_rotregs;
std::unique_ptr<u8[]> m_priority; 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; required_device<gfxdecode_device> m_gfxdecode;
optional_device<gfxdecode_device> m_sub_gfxdecode; optional_device<gfxdecode_device> m_sub_gfxdecode;
required_device<palette_device> m_palette; required_device<palette_device> m_palette;
optional_device<palette_device> m_sub_palette;
required_shared_ptr<u16> m_paletteram; required_shared_ptr<u16> m_paletteram;
optional_shared_ptr<u16> m_sub_paletteram;
output_finder<45> m_leds; output_finder<45> m_leds;
u16 m_rocknms_sub_systemregs[0x10];
u16 m_rockn_protectdata; u16 m_rockn_protectdata;
u16 m_rockn_adpcmbank; u16 m_rockn_adpcmbank;
u16 m_rockn_soundvolume; u16 m_rockn_soundvolume;
emu_timer *m_rockn_timer_l4; int m_rot_ofsx, m_rot_ofsy;
emu_timer *m_rockn_timer_sub_l4;
emu_timer *m_rockn_timer_l1;
emu_timer *m_rockn_timer_sub_l1;
int m_bank_lo; int m_bank_lo;
int m_bank_hi; 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_bg;
tilemap_t *m_tilemap_fg; tilemap_t *m_tilemap_fg;
tilemap_t *m_tilemap_rot; 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_bg;
tilemap_t *m_tilemap_sub_fg; tilemap_t *m_tilemap_sub_fg;
tilemap_t *m_tilemap_sub_rot; 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 class stepstag_state : public tetrisp2_state
{ {
public: public:
stepstag_state(const machine_config &mconfig, device_type type, const char *tag) : stepstag_state(const machine_config &mconfig, device_type type, const char *tag) :
tetrisp2_state(mconfig, type, tag), tetrisp2_state(mconfig, type, tag)
m_vj_sprite_l(*this, "sprite_l"), , m_subcpu(*this, "sub")
m_vj_sprite_m(*this, "sprite_m"), , m_vj_sprite_l(*this, "sprite_l")
m_vj_sprite_r(*this, "sprite_r"), , m_vj_sprite_m(*this, "sprite_m")
m_spriteram1(*this, "spriteram1"), , m_vj_sprite_r(*this, "sprite_r")
m_spriteram3(*this, "spriteram3"), , m_spriteram1(*this, "spriteram1")
m_vj_palette_l(*this, "lpalette"), , m_spriteram3(*this, "spriteram3")
m_vj_palette_m(*this, "mpalette"), , m_vj_palette_l(*this, "lpalette")
m_vj_palette_r(*this, "rpalette"), , m_vj_palette_m(*this, "mpalette")
m_vj_paletteram_l(*this, "paletteram1"), , m_vj_palette_r(*this, "rpalette")
m_vj_paletteram_m(*this, "paletteram2"), , m_vj_paletteram_l(*this, "paletteram1")
m_vj_paletteram_r(*this, "paletteram3"), , m_vj_paletteram_m(*this, "paletteram2")
m_soundlatch(*this, "soundlatch") , m_vj_paletteram_r(*this, "paletteram3")
, m_soundlatch(*this, "soundlatch")
{ } { }
void stepstag(machine_config &config); 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_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); 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_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_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); u32 screen_update_stepstag_main(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
// inline int mypal(int x); // inline int mypal(int x);
@ -227,6 +252,10 @@ private:
void stepstag_sub_map(address_map &map); void stepstag_sub_map(address_map &map);
void vjdash_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_l;
optional_device<ms32_sprite_device> m_vj_sprite_m; optional_device<ms32_sprite_device> m_vj_sprite_m;
optional_device<ms32_sprite_device> m_vj_sprite_r; 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"> <mamelayout version="2">
<view name="Rockn Megasession Custom"> <view name="Rockn Megasession Custom">
<screen tag="lscreen"> <screen tag="screen">
<bounds x="0" y="0" width="12" height="9" /> <bounds x="0" y="0" width="12" height="9" />
</screen> </screen>
<screen tag="rscreen"> <screen tag="sub_screen">
<bounds x="0" y="9" width="12" height="16" /> <bounds x="0" y="9" width="12" height="16" />
</screen> </screen>
</view> </view>

View File

@ -8,7 +8,7 @@ license:CC0
<screen tag="lscreen"> <screen tag="lscreen">
<bounds x="0" y="0" width="9" height="13.2" /> <bounds x="0" y="0" width="9" height="13.2" />
</screen> </screen>
<screen tag="mscreen"> <screen tag="screen">
<bounds x="9.1" y="0" width="16" height="13.2" /> <bounds x="9.1" y="0" width="16" height="13.2" />
</screen> </screen>
<screen tag="rscreen"> <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; uint8_t *source_data;
int source_size; 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(); source_size = machine.root_device().memregion( region )->bytes();
std::vector<uint8_t> result_data(source_size); 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; uint8_t *source_data;
int source_size; 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(); source_size = machine.root_device().memregion( region )->bytes();
std::vector<uint8_t> result_data(source_size); 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" #include "includes/ms32.h"
// kirarast, tp2m32, and suchie2 require the sprites in a different order
/********** Tilemaps **********/ /********** Tilemaps **********/
TILE_GET_INFO_MEMBER(ms32_state::get_ms32_tx_tile_info) 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); 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; int tileno,colour;
tileno = m_f1superb_extraram[tile_index *2] & 0xffff; tileno = m_road_vram[tile_index *2] & 0xffff;
colour = m_f1superb_extraram[tile_index *2+1] & 0x000f; colour = m_road_vram[tile_index *2+1] & 0x000f;
tileinfo.set(3,tileno,colour+0x50,0); 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_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 = &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); 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_objectram_size = m_sprram.length();
m_sprram_buffer = make_unique_clear<u16[]>(size); m_sprram_buffer = make_unique_clear<u16[]>(m_objectram_size);
/* set up tile layers */ /* set up tile layers */
m_screen->register_screen_bitmap(m_temp_bitmap_tilemaps); 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_bg_tilemap_alt->set_transparent_pen(0);
m_roz_tilemap->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 // tp2m32 doesn't set the brightness registers so we need sensible defaults
m_brt[0] = m_brt[1] = 0xffff; m_brt[0] = m_brt[1] = 0xffff;
m_sprite_ctrl[0x10/4] = 0x8000;
save_pointer(NAME(m_sprram_buffer), size); save_pointer(NAME(m_sprram_buffer), m_objectram_size);
save_item(NAME(m_irqreq));
save_item(NAME(m_temp_bitmap_tilemaps)); save_item(NAME(m_temp_bitmap_tilemaps));
save_item(NAME(m_temp_bitmap_sprites)); save_item(NAME(m_temp_bitmap_sprites));
save_item(NAME(m_temp_bitmap_sprites_pri)); save_item(NAME(m_temp_bitmap_sprites_pri));
save_item(NAME(m_tilemaplayoutcontrol)); 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));
save_item(NAME(m_brt_r)); save_item(NAME(m_brt_r));
save_item(NAME(m_brt_g)); save_item(NAME(m_brt_g));
save_item(NAME(m_brt_b)); save_item(NAME(m_brt_b));
} }
VIDEO_START_MEMBER(ms32_state,f1superb) void ms32_f1superbattle_state::video_start()
{ {
ms32_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 **********/ /********** 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) 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; int r,g,b;
/* I'm not sure how the brightness should be applied, currently I'm only /* I'm not sure how the brightness should be applied, currently I'm only
affecting bg & sprites, not fg. affecting bg & sprites, not fg.
The second brightness control might apply to shadows, see gametngk. The second brightness control might apply to shadows, see gametngk.
*/ */
// TODO : p47aces : brightness are disabled sometimes, see https://youtu.be/PQsefFtqAwA
if (~color & 0x4000) if (~color & 0x4000)
{ {
r = ((m_palram[color*2] & 0xff00) >>8 ) * m_brt_r / 0x100; r = ((m_palram[color*2] & 0xff00) >> 8 ) * m_brt_r / 0x100;
g = ((m_palram[color*2] & 0x00ff) >>0 ) * m_brt_g / 0x100; g = ((m_palram[color*2] & 0x00ff) >> 0 ) * m_brt_g / 0x100;
b = ((m_palram[color*2+1] & 0x00ff) >>0 ) * m_brt_b / 0x100; b = ((m_palram[color*2+1] & 0x00ff) >> 0 ) * m_brt_b / 0x100;
} }
else else
{ {
r = ((m_palram[color*2] & 0xff00) >>8 ); r = ((m_palram[color*2] & 0xff00) >> 8 );
g = ((m_palram[color*2] & 0x00ff) >>0 ); g = ((m_palram[color*2] & 0x00ff) >> 0 );
b = ((m_palram[color*2+1] & 0x00ff) >>0 ); b = ((m_palram[color*2+1] & 0x00ff) >> 0 );
} }
m_palette->set_pen_color(color,rgb_t(r,g,b)); 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]; int oldword = m_brt[offset];
COMBINE_DATA(&m_brt[offset]); COMBINE_DATA(&m_brt[offset]);
if (m_brt[offset] != oldword) if (m_brt[offset] != oldword)
{ {
// TODO: bank "1" is for sprite colors
int bank = ((offset & 2) >> 1) * 0x4000; int bank = ((offset & 2) >> 1) * 0x4000;
//int i; //int i;
@ -171,45 +171,23 @@ void ms32_state::ms32_brightness_w(offs_t offset, u32 data, u32 mem_mask)
// update_color(machine(), i); // 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 */ /* 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; const size_t sprite_tail = m_objectram_size - 8; //(0x20000 - 0x10) / 2;
u16 *finish = sprram_top + (sprram_size - 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; source = sprram_top + sprite_tail;
finish = sprram_top; finish = sprram_top;
} }
for (;reverseorder ? (source>=finish) : (source<finish); reverseorder ? (source-=8) : (source+=8)) 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; u16 xsize, ysize;
s32 sx, sy; s32 sx, sy;
u16 xzoom, yzoom; 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) if (disable || !xzoom || !yzoom)
continue; 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) 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 // 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, // 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*). // 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? // 0x4* 0x5* ROZ should wrap?
// bbbxing: 0xffff 0x0000 0 (match presentation) // bbbxing: 0xffff 0x0000 0 (match presentation)
// gratia: 0x0000 0x0000 1 (sky in stage 2) // gratia: 0x0000 0x0000 1 (sky in stage 2)
// p47aces: 0xffff 0x0651 0 (title screen) // p47aces: 0xffff 0x0651 0 (title screen)
// desertwr: 0xffff 0x0651 1 (any stage) // desertwr: 0xffff 0x0651 1 (any stage)
// f1superb: 0xffff 0x0000 ? // f1superb: 0xffff 0x0000 ?
// suchie2: 0x0000 0x0000 0? // suchie2: 0x0000 0x0000 0?
// bnstars: 0x0000 0x0000 ? // bnstars: 0x0000 0x0000 ?
// hayaosi3: 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? // akiss: 0xffff 0x0000 0 (gal riichi, cfr. attract mode)
// Are we missing a ROZ plane size as well? // 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 */ if (m_roz_ctrl[0x5c/4] & 1) /* "super" mode */
{ {
rectangle my_clip; 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 scrollx,scrolly;
int asc_pri; int asc_pri;
int scr_pri; int scr_pri;
int rot_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 /* 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 is gametngk, where they are *usually*, but not always, copies of 0x00/4
and 0x0c/4 (used for scrolling). 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 The two registers might be somewhat related to the width and height of the
tilemaps, but there's something that just doesn't fit. 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); update_color(i);
scrollx = m_tx_scroll[0x00/4] + m_tx_scroll[0x08/4] + 0x18; 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_scrollx(0, scrollx);
m_bg_tilemap_alt->set_scrolly(0, scrolly); m_bg_tilemap_alt->set_scrolly(0, scrolly);
screen.priority().fill(0, cliprect); screen.priority().fill(0, cliprect);
/* TODO: 0 is correct for gametngk, but break f1superb scrolling grid (text at /* TODO: 0 is correct for gametngk, but break f1superb scrolling grid (text at
top and bottom of the screen becomes black on black) */ top and bottom of the screen becomes black on black) */
m_temp_bitmap_tilemaps.fill(0, cliprect); /* bg color */ 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.fill(0, cliprect);
m_temp_bitmap_sprites_pri.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?) // TODO: actually understand this (per-scanline priority and alpha-blend over every layer?)
asc_pri = scr_pri = rot_pri = 0; 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 // tile-sprite mixing
/* this mixing isn't 100% accurate, it should be using ALL the data in // TODO: spaghetti code
the priority ram, probably for per-pixel / pen mixing, or more levels // TODO: complete guesswork and missing many spots
than are supported here.. I don't know, it will need hw tests I think */ // 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(); pen_t const *const paldata = m_palette->pens();
bitmap.fill(0, cliprect); 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); u16 const *const srcptr_tile = &m_temp_bitmap_tilemaps.pix(yy);
u8 const *const srcptr_tilepri = &screen.priority().pix(yy); u8 const *const srcptr_tilepri = &screen.priority().pix(yy);
u16 const *const srcptr_spri = &m_temp_bitmap_sprites.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); //u8 const *const srcptr_spripri = &m_temp_bitmap_sprites_pri.pix(yy);
u32 *const dstptr_bitmap = &bitmap.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]; u16 src_tile = srcptr_tile[xx];
u8 src_tilepri = srcptr_tilepri[xx]; u8 src_tilepri = srcptr_tilepri[xx];
u16 src_spri = srcptr_spri[xx]; u16 src_spri = srcptr_spri[xx];
//u8 src_spripri;// = srcptr_spripri[xx]; //u8 src_spripri;// = srcptr_spripri[xx];
u16 spridat = ((src_spri&0x0fff)); u16 spridat = (src_spri & 0x0fff);
u8 spritepri = ((src_spri&0xf000) >> 8); u8 spritepri = ((src_spri & 0xf000) >> 8);
int primask = 0; int primask = 0;
// get sprite priority value back out of bitmap/colour data (this is done in draw_sprite for standalone hw) // 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 | 0x0100) / 2] & 0x38) primask |= 1 << 6;
if (m_priram[(spritepri | 0x0a00 | 0x0000) / 2] & 0x38) primask |= 1 << 7; if (m_priram[(spritepri | 0x0a00 | 0x0000) / 2] & 0x38) primask |= 1 << 7;
// TODO: spaghetti code ...
if (primask == 0x00) if (primask == 0x00)
{ {
if (src_tilepri==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; dstptr_bitmap[xx] = 0;
popmessage("unhandled priority type %02x, contact MAMEdev",primask); popmessage("unhandled priority type %02x, contact MAMEdev",primask);
} }
} }
} }
} }
return 0; return 0;
} }
WRITE_LINE_MEMBER(ms32_state::screen_vblank_ms32) WRITE_LINE_MEMBER(ms32_state::screen_vblank)
{ {
if (state) 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 Jaleco Megasystem 32 sprite hardware
TODO: TODO:
verify hardware configuration - verify hardware configuration;
- suchie2: on attract gals background display is cut off on the right side;
used by: used by:
ms32.cpp ms32.cpp
bnstars.cpp (Dual screen configuration) 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): Sprite format (16 byte per each sprite):
Offset Bits Description Offset Bits Description
fedcba98 76543210 fedcba98 76543210
00 -xxxxxxx -------- Palette Select (some hardwares with YUV color format) 00 -xxxxxxx -------- stepstage only: Palette Select for YUV format
-------- xxxx---- Priority -------- xxxx---- Priority
-------- -----x-- Visible -------- -----x-- Visible
-------- ------x- Flip Y -------- ------x- Flip Y
-------- -------x Flip X -------- -------x Flip X
02 xxxxxxxx -------- Source Y offset (1 pixel each) 02 xxxxxxxx -------- Source Y offset (1 pixel each)
-------- xxxxxxxx Source X 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) ----xxxx xxxxxxxx Source Texture Select (each texture is 256 x 256 pixels)
06 xxxxxxxx -------- Source Width - 1 (1 pixel each) 06 xxxxxxxx -------- Source Width - 1 (1 pixel each)
-------- xxxxxxxx Source Height - 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) , device_gfx_interface(mconfig, *this, nullptr)
, m_color_base(0) , m_color_base(0)
, m_color_entries(0x10) , 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); 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]; const u16 attr = ram[0];
pri = ( attr & 0x00f0); pri = ( attr & 0x00f0);
@ -116,7 +119,7 @@ void ms32_sprite_device::extract_parameters(bool has_zoom, bool is_yuv, const u1
code = (color & 0x0fff); code = (color & 0x0fff);
// encoded to first word when YUV sprites are used // encoded to first word when YUV sprites are used
if (is_yuv) if (m_has_yuv)
color = (attr & 0x7f00) >> 8; color = (attr & 0x7f00) >> 8;
else else
color = (color >> 12) & 0xf; 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); sx = (ram[5] & 0x3ff) - (ram[5] & 0x400);
sy = (ram[4] & 0x1ff) - (ram[4] & 0x200); sy = (ram[4] & 0x1ff) - (ram[4] & 0x200);
if (has_zoom) if (m_has_zoom)
{ {
incx = (ram[6] & 0xffff); incx = (ram[6] & 0xffff);
incy = (ram[7] & 0xffff); incy = (ram[7] & 0xffff);

View File

@ -18,8 +18,10 @@ public:
// configuration // configuration
void set_color_base(u16 base) { m_color_base = base; } void set_color_base(u16 base) { m_color_base = base; }
void set_color_entries(u16 entries) { m_color_entries = entries; } 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 ----- // ----- core graphics drawing -----
@ -83,6 +85,8 @@ private:
// configurations // configurations
u16 m_color_base, m_color_entries; u16 m_color_base, m_color_entries;
bool m_has_zoom;
bool m_has_yuv;
}; };
DECLARE_DEVICE_TYPE(JALECO_MEGASYSTEM32_SPRITE, ms32_sprite_device) DECLARE_DEVICE_TYPE(JALECO_MEGASYSTEM32_SPRITE, ms32_sprite_device)

View File

@ -34,10 +34,22 @@ To Do:
#include "emu.h" #include "emu.h"
#include "includes/tetrisp2.h" #include "includes/tetrisp2.h"
#include "machine/jalcrpt.h"
#include "screen.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)); 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]); data = COMBINE_DATA(&m_sub_paletteram[offset]);
if ((offset & 1) == 0) if ((offset & 1) == 0)
@ -84,7 +96,7 @@ u16 tetrisp2_state::tetrisp2_priority_r(offs_t offset)
return m_priority[offset] | 0xff00; 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) if (ACCESSING_BITS_0_7)
m_rocknms_sub_priority[offset] = data; 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); 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_hi = m_rocknms_sub_vram_bg[ 2 * tile_index + 0];
u16 code_lo = m_rocknms_sub_vram_bg[ 2 * tile_index + 1]; 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); 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]); COMBINE_DATA(&m_rocknms_sub_vram_bg[offset]);
m_tilemap_sub_bg->mark_tile_dirty(offset/2); 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_hi = m_rocknms_sub_vram_fg[ 2 * tile_index + 0];
u16 code_lo = m_rocknms_sub_vram_fg[ 2 * tile_index + 1]; 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); 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]); COMBINE_DATA(&m_rocknms_sub_vram_fg[offset]);
m_tilemap_sub_fg->mark_tile_dirty(offset/2); 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_hi = m_rocknms_sub_vram_rot[ 2 * tile_index + 0];
u16 code_lo = m_rocknms_sub_vram_rot[ 2 * tile_index + 1]; 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); 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]); COMBINE_DATA(&m_rocknms_sub_vram_rot[offset]);
m_tilemap_sub_rot->mark_tile_dirty(offset/2); 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) 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_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_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); 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 // should be smaller and mirrored like m32 I guess
m_priority = std::make_unique<u8[]>(0x40000); m_priority = std::make_unique<u8[]>(0x40000);
save_item(NAME(m_flipscreen_old));
save_pointer(NAME(m_priority), 0x40000); save_pointer(NAME(m_priority), 0x40000);
} }
@ -243,8 +252,6 @@ VIDEO_START_MEMBER(tetrisp2_state,nndmseal)
VIDEO_START_MEMBER(tetrisp2_state,rockntread) 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_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_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); 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 // should be smaller and mirrored like m32 I guess
m_priority = std::make_unique<u8[]>(0x40000); 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); save_pointer(NAME(m_priority), 0x40000);
} }
VIDEO_START_MEMBER(tetrisp2_state,rocknms) VIDEO_START_MEMBER(rocknms_state,rocknms)
{ {
VIDEO_START_CALL_MEMBER( rockntread ); 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_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(tetrisp2_state::get_tile_info_rocknms_sub_fg)), TILEMAP_SCAN_ROWS, 8,8, 64,64); 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(tetrisp2_state::get_tile_info_rocknms_sub_rot)), TILEMAP_SCAN_ROWS, 16,16, 128,128); 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_bg->set_transparent_pen(0);
m_tilemap_sub_fg->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> template<class BitmapClass>
static void tetrisp2_draw_sprites(BitmapClass &bitmap, bitmap_ind8 &bitmap_pri, const rectangle &cliprect, u8* priority_ram, 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 *source = sprram_top;
u16 *finish = sprram_top + (sprram_size - 0x10) / 2; 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; s32 sx, sy;
u16 xzoom, yzoom; 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) if (disable || !xzoom || !yzoom)
continue; 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) u32 tetrisp2_state::screen_update_tetrisp2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
int flipscreen;
int asc_pri; int asc_pri;
int scr_pri; int scr_pri;
int rot_pri; int rot_pri;
int rot_ofsx, rot_ofsy;
flipscreen = (m_systemregs[0x00] & 0x02);
/* Black background color */ /* Black background color */
bitmap.fill(0, cliprect); bitmap.fill(0, cliprect);
screen.priority().fill(0); 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_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_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_scrollx(0, m_scroll_fg[ 2 ]);
m_tilemap_fg->set_scrolly(0, m_scroll_fg[ 5 ]); 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_scrollx(0, (m_rotregs[ 0 ] - m_rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - rot_ofsy)); m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - m_rot_ofsy));
asc_pri = scr_pri = rot_pri = 0; 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); m_tilemap_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(), 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; return 0;
} }
u32 tetrisp2_state::screen_update_rockntread(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) u32 tetrisp2_state::screen_update_rockntread(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
int flipscreen;
int asc_pri; int asc_pri;
int scr_pri; int scr_pri;
int rot_pri; int rot_pri;
int rot_ofsx, rot_ofsy;
flipscreen = (m_systemregs[0x00] & 0x02);
/* Black background color */ /* Black background color */
bitmap.fill(0, cliprect); bitmap.fill(0, cliprect);
screen.priority().fill(0); 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_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_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_scrollx(0, m_scroll_fg[ 2 ]);
m_tilemap_fg->set_scrolly(0, m_scroll_fg[ 5 ]); 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_scrollx(0, (m_rotregs[ 0 ] - m_rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - rot_ofsy)); m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - m_rot_ofsy));
asc_pri = scr_pri = rot_pri = 0; 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); m_tilemap_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(), 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; 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 asc_pri;
int scr_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); m_tilemap_sub_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(), 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; 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 asc_pri;
int scr_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); m_tilemap_fg->draw(screen, bitmap, cliprect, 0, 1 << 2);
tetrisp2_draw_sprites(bitmap, screen.priority(), cliprect, m_priority.get(), 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; 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 // 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. // 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_hi = m_vram_fg[ 2 * tile_index ] >> 8;
u16 const code_lo = m_vram_fg[ 2 * tile_index ] & 0xf; 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) VIDEO_START_MEMBER(stepstag_state,stepstag)
{ {
m_flipscreen_old = -1; 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_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_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_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->set_transparent_pen(0); m_tilemap_bg->set_transparent_pen(0);
m_tilemap_fg->set_transparent_pen(0); m_tilemap_fg->set_transparent_pen(0);
m_tilemap_rot->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( tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(), 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; return 0;
} }
@ -722,7 +682,7 @@ u32 stepstag_state::screen_update_stepstag_mid(screen_device &screen, bitmap_rgb
tetrisp2_draw_sprites( tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(), 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_rot->draw(screen, bitmap, cliprect, 0, 1 << 1);
// m_tilemap_bg->draw(screen, bitmap, cliprect, 0, 1 << 0); // 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; 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(0, cliprect);
bitmap.fill(m_vj_palette_r->black_pen(), cliprect);
screen.priority().fill(0); screen.priority().fill(0);
tetrisp2_draw_sprites( tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(), 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; return 0;
} }
u32 stepstag_state::screen_update_stepstag_main(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) 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 */ /* Black background color */
bitmap.fill(0, cliprect); bitmap.fill(0, cliprect);
screen.priority().fill(0); 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_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_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_scrollx(0, m_scroll_fg[ 2 ]);
m_tilemap_fg->set_scrolly(0, m_scroll_fg[ 5 ]); 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_scrollx(0, (m_rotregs[ 0 ] - m_rot_ofsx));
m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - rot_ofsy)); m_tilemap_rot->set_scrolly(0, (m_rotregs[ 2 ] - m_rot_ofsy));
int asc_pri = 0, scr_pri = 0, rot_pri = 0; 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( tetrisp2_draw_sprites(
bitmap, screen.priority(), cliprect, m_priority.get(), 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; return 0;
} }