dynax.cpp: Make "Rev. 2" blitter a device

This commit is contained in:
AJR 2018-06-19 20:42:51 -04:00
parent 7e40e1f662
commit bd97af6363
7 changed files with 1037 additions and 986 deletions

View File

@ -1708,6 +1708,8 @@ files {
MAME_DIR .. "src/mame/includes/realbrk.h", MAME_DIR .. "src/mame/includes/realbrk.h",
MAME_DIR .. "src/mame/video/realbrk.cpp", MAME_DIR .. "src/mame/video/realbrk.cpp",
MAME_DIR .. "src/mame/drivers/royalmah.cpp", MAME_DIR .. "src/mame/drivers/royalmah.cpp",
MAME_DIR .. "src/mame/video/dynax_blitter_rev2.cpp",
MAME_DIR .. "src/mame/video/dynax_blitter_rev2.h",
} }
createMAMEProjects(_target, _subtarget, "edevices") createMAMEProjects(_target, _subtarget, "edevices")

View File

@ -4303,7 +4303,7 @@ WRITE8_MEMBER(ddenlovr_state::htengoku_blit_romregion_w)
void ddenlovr_state::htengoku_io_map(address_map &map) void ddenlovr_state::htengoku_io_map(address_map &map)
{ {
map.global_mask(0xff); map.global_mask(0xff);
map(0x01, 0x07).w(FUNC(ddenlovr_state::dynax_blitter_rev2_w)); // Blitter map(0x01, 0x07).w("blitter", FUNC(dynax_blitter_rev2_device::regs_w)); // Blitter
map(0x20, 0x20).w(FUNC(ddenlovr_state::htengoku_select_w)); // Controls map(0x20, 0x20).w(FUNC(ddenlovr_state::htengoku_select_w)); // Controls
map(0x21, 0x21).w(FUNC(ddenlovr_state::htengoku_coin_w)); // map(0x21, 0x21).w(FUNC(ddenlovr_state::htengoku_coin_w)); //
map(0x22, 0x22).r(FUNC(ddenlovr_state::htengoku_coin_r)); // map(0x22, 0x22).r(FUNC(ddenlovr_state::htengoku_coin_r)); //
@ -4326,7 +4326,7 @@ void ddenlovr_state::htengoku_io_map(address_map &map)
map(0xc0, 0xc0).w(FUNC(ddenlovr_state::dynax_extra_scrollx_w)); // screen scroll X map(0xc0, 0xc0).w(FUNC(ddenlovr_state::dynax_extra_scrollx_w)); // screen scroll X
map(0xc1, 0xc1).w(FUNC(ddenlovr_state::dynax_extra_scrolly_w)); // screen scroll Y map(0xc1, 0xc1).w(FUNC(ddenlovr_state::dynax_extra_scrolly_w)); // screen scroll Y
map(0xc3, 0xc3).w(FUNC(ddenlovr_state::dynax_vblank_ack_w)); // VBlank IRQ Ack map(0xc3, 0xc3).w(FUNC(ddenlovr_state::dynax_vblank_ack_w)); // VBlank IRQ Ack
map(0xc4, 0xc4).w(FUNC(ddenlovr_state::dynax_blit_pen_w)); // Destination Pen map(0xc4, 0xc4).w("blitter", FUNC(dynax_blitter_rev2_device::pen_w)); // Destination Pen
map(0xc5, 0xc5).w(FUNC(ddenlovr_state::dynax_blit_dest_w)); // Destination Layer map(0xc5, 0xc5).w(FUNC(ddenlovr_state::dynax_blit_dest_w)); // Destination Layer
map(0xc6, 0xc6).w(FUNC(ddenlovr_state::htengoku_blit_romregion_w)); // Blitter ROM bank map(0xc6, 0xc6).w(FUNC(ddenlovr_state::htengoku_blit_romregion_w)); // Blitter ROM bank
map(0xe0, 0xe7).w(m_mainlatch, FUNC(ls259_device::write_d1)); map(0xe0, 0xe7).w(m_mainlatch, FUNC(ls259_device::write_d1));
@ -4389,6 +4389,12 @@ MACHINE_CONFIG_START(ddenlovr_state::htengoku)
MCFG_SCREEN_PALETTE("palette") MCFG_SCREEN_PALETTE("palette")
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, ddenlovr_state, sprtmtch_vblank_w)) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, ddenlovr_state, sprtmtch_vblank_w))
MCFG_DEVICE_ADD("blitter", DYNAX_BLITTER_REV2, 0)
MCFG_DYNAX_BLITTER_REV2_VRAM_OUT_CB(WRITE8(*this, dynax_state, hnoridur_blit_pixel_w))
MCFG_DYNAX_BLITTER_REV2_SCROLLX_CB(WRITE8(*this, dynax_state, dynax_blit_scrollx_w))
MCFG_DYNAX_BLITTER_REV2_SCROLLY_CB(WRITE8(*this, dynax_state, dynax_blit_scrolly_w))
MCFG_DYNAX_BLITTER_REV2_READY_CB(WRITELINE(*this, dynax_state, sprtmtch_blitter_irq_w))
MCFG_PALETTE_ADD("palette", 16*256) MCFG_PALETTE_ADD("palette", 16*256)
MCFG_VIDEO_START_OVERRIDE(ddenlovr_state,htengoku) MCFG_VIDEO_START_OVERRIDE(ddenlovr_state,htengoku)
@ -13036,20 +13042,16 @@ ROM_START( htengoku )
ROM_LOAD( "6501.4b", 0x00000, 0x40000, CRC(29a7fc83) SHA1(5d3cf0a72918e58b5b60f7c978e559c7c1306bce) ) ROM_LOAD( "6501.4b", 0x00000, 0x40000, CRC(29a7fc83) SHA1(5d3cf0a72918e58b5b60f7c978e559c7c1306bce) )
ROM_RELOAD( 0x10000, 0x40000 ) ROM_RELOAD( 0x10000, 0x40000 )
ROM_REGION( 0x80000, "gfx1", 0 ) // blitter data ROM_REGION( 0x300000, "blitter", 0 ) // blitter data
ROM_LOAD( "6506.4c", 0x00000, 0x80000, CRC(7de17b26) SHA1(326667063ab045ac50e850f2f7821a65317879ad) ) ROM_LOAD( "6506.4c", 0x000000, 0x80000, CRC(7de17b26) SHA1(326667063ab045ac50e850f2f7821a65317879ad) )
ROM_LOAD( "6507.5c", 0x100000, 0x20000, CRC(ced3155b) SHA1(658e3947781f1be2ee87b43952999281c66683a6) )
ROM_REGION( 0xc0000, "gfx2", 0 ) // blitter data ROM_LOAD( "6508.6c", 0x120000, 0x20000, CRC(ca46ed48) SHA1(0769ac0b211181b7b57033f09f72828c885186cc) )
ROM_LOAD( "6507.5c", 0x00000, 0x20000, CRC(ced3155b) SHA1(658e3947781f1be2ee87b43952999281c66683a6) ) ROM_LOAD( "6505.2b", 0x140000, 0x20000, CRC(161058fd) SHA1(cfc21abdc036e874d34bfa3c60486a5ab87cf9cd) )
ROM_LOAD( "6508.6c", 0x20000, 0x20000, CRC(ca46ed48) SHA1(0769ac0b211181b7b57033f09f72828c885186cc) ) ROM_LOAD( "6504.1b", 0x160000, 0x20000, CRC(b2ca9838) SHA1(7104697802a0466fab40414a467146a224eb6a74) )
ROM_LOAD( "6505.2b", 0x40000, 0x20000, CRC(161058fd) SHA1(cfc21abdc036e874d34bfa3c60486a5ab87cf9cd) ) ROM_LOAD( "6503.2a", 0x180000, 0x20000, CRC(6ac42304) SHA1(ce822da6d61e68578c08c9f1d0af1557c64ac5ae) )
ROM_LOAD( "6504.1b", 0x60000, 0x20000, CRC(b2ca9838) SHA1(7104697802a0466fab40414a467146a224eb6a74) ) ROM_LOAD( "6502.1a", 0x1a0000, 0x20000, CRC(9276a10a) SHA1(5a68fff20631a2002509d6cace06b5a9fa0e75d2) )
ROM_LOAD( "6503.2a", 0x80000, 0x20000, CRC(6ac42304) SHA1(ce822da6d61e68578c08c9f1d0af1557c64ac5ae) ) ROM_LOAD( "6509.10b", 0x200000, 0x80000, CRC(f8524c28) SHA1(d50b99664c9f0735838adb55aa7db53e58a43f99) )
ROM_LOAD( "6502.1a", 0xa0000, 0x20000, CRC(9276a10a) SHA1(5a68fff20631a2002509d6cace06b5a9fa0e75d2) ) ROM_LOAD( "6510.11b", 0x280000, 0x20000, CRC(0fdd6edf) SHA1(c6870ab538987110337e6e154cba98391c68fb98) )
ROM_REGION( 0xa0000, "gfx3", 0 ) // blitter data
ROM_LOAD( "6509.10b", 0x00000, 0x80000, CRC(f8524c28) SHA1(d50b99664c9f0735838adb55aa7db53e58a43f99) )
ROM_LOAD( "6510.11b", 0x80000, 0x20000, CRC(0fdd6edf) SHA1(c6870ab538987110337e6e154cba98391c68fb98) )
ROM_END ROM_END
GAME( 1992, htengoku, 0, htengoku, htengoku, ddenlovr_state, empty_init, ROT180, "Dynax", "Hanafuda Hana Tengoku (Japan)", 0) GAME( 1992, htengoku, 0, htengoku, htengoku, ddenlovr_state, empty_init, ROT180, "Dynax", "Hanafuda Hana Tengoku (Japan)", 0)

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@
#include "sound/msm5205.h" #include "sound/msm5205.h"
#include "sound/okim6295.h" #include "sound/okim6295.h"
#include "machine/74259.h" #include "machine/74259.h"
#include "video/dynax_blitter_rev2.h"
#include "emupal.h" #include "emupal.h"
#include "screen.h" #include "screen.h"
@ -31,14 +32,9 @@ public:
, m_mainirq(*this, "mainirq") , m_mainirq(*this, "mainirq")
, m_soundirq(*this, "soundirq") , m_soundirq(*this, "soundirq")
, m_soundlatch(*this, "soundlatch") , m_soundlatch(*this, "soundlatch")
, m_gfx_region1(*this, "gfx1") , m_blitter(*this, "blitter")
, m_gfx_region2(*this, "gfx2") , m_blitter2(*this, "blitter2")
, m_gfx_region3(*this, "gfx3") , m_blitter_gfx(*this, "blitter")
, m_gfx_region4(*this, "gfx4")
, m_gfx_region5(*this, "gfx5")
, m_gfx_region6(*this, "gfx6")
, m_gfx_region7(*this, "gfx7")
, m_gfx_region8(*this, "gfx8")
, m_led(*this, "led0") , m_led(*this, "led0")
{ {
} }
@ -47,9 +43,12 @@ public:
DECLARE_WRITE8_MEMBER(dynax_vblank_ack_w); DECLARE_WRITE8_MEMBER(dynax_vblank_ack_w);
DECLARE_WRITE_LINE_MEMBER(blitter_ack_w); DECLARE_WRITE_LINE_MEMBER(blitter_ack_w);
DECLARE_WRITE_LINE_MEMBER(sprtmtch_blitter_irq_w);
DECLARE_WRITE8_MEMBER(jantouki_vblank_ack_w); DECLARE_WRITE8_MEMBER(jantouki_vblank_ack_w);
DECLARE_WRITE_LINE_MEMBER(jantouki_blitter_ack_w); DECLARE_WRITE_LINE_MEMBER(jantouki_blitter_ack_w);
DECLARE_WRITE_LINE_MEMBER(jantouki_blitter_irq_w);
DECLARE_WRITE_LINE_MEMBER(jantouki_blitter2_ack_w); DECLARE_WRITE_LINE_MEMBER(jantouki_blitter2_ack_w);
DECLARE_WRITE_LINE_MEMBER(jantouki_blitter2_irq_w);
DECLARE_WRITE8_MEMBER(jantouki_sound_vblank_ack_w); DECLARE_WRITE8_MEMBER(jantouki_sound_vblank_ack_w);
DECLARE_WRITE_LINE_MEMBER(coincounter_0_w); DECLARE_WRITE_LINE_MEMBER(coincounter_0_w);
DECLARE_WRITE_LINE_MEMBER(coincounter_1_w); DECLARE_WRITE_LINE_MEMBER(coincounter_1_w);
@ -110,14 +109,12 @@ public:
DECLARE_WRITE8_MEMBER(gekisha_p4_w); DECLARE_WRITE8_MEMBER(gekisha_p4_w);
DECLARE_WRITE8_MEMBER(dynax_extra_scrollx_w); DECLARE_WRITE8_MEMBER(dynax_extra_scrollx_w);
DECLARE_WRITE8_MEMBER(dynax_extra_scrolly_w); DECLARE_WRITE8_MEMBER(dynax_extra_scrolly_w);
DECLARE_WRITE8_MEMBER(dynax_blit_pen_w); //DECLARE_WRITE8_MEMBER(dynax_blit_pen_w);
DECLARE_WRITE8_MEMBER(dynax_blit2_pen_w);
DECLARE_WRITE8_MEMBER(dynax_blit_dest_w); DECLARE_WRITE8_MEMBER(dynax_blit_dest_w);
DECLARE_WRITE8_MEMBER(dynax_blit2_dest_w); DECLARE_WRITE8_MEMBER(dynax_blit2_dest_w);
DECLARE_WRITE8_MEMBER(tenkai_blit_dest_w); DECLARE_WRITE8_MEMBER(tenkai_blit_dest_w);
DECLARE_WRITE8_MEMBER(mjembase_blit_dest_w); DECLARE_WRITE8_MEMBER(mjembase_blit_dest_w);
DECLARE_WRITE8_MEMBER(dynax_blit_backpen_w); DECLARE_WRITE8_MEMBER(dynax_blit_backpen_w);
DECLARE_WRITE8_MEMBER(dynax_blit_flags_w);
DECLARE_WRITE8_MEMBER(dynax_blit_palette01_w); DECLARE_WRITE8_MEMBER(dynax_blit_palette01_w);
DECLARE_WRITE8_MEMBER(tenkai_blit_palette01_w); DECLARE_WRITE8_MEMBER(tenkai_blit_palette01_w);
DECLARE_WRITE8_MEMBER(dynax_blit_palette45_w); DECLARE_WRITE8_MEMBER(dynax_blit_palette45_w);
@ -138,14 +135,19 @@ public:
DECLARE_WRITE_LINE_MEMBER(flipscreen_w); DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
DECLARE_WRITE8_MEMBER(dynax_blit_romregion_w); DECLARE_WRITE8_MEMBER(dynax_blit_romregion_w);
DECLARE_WRITE8_MEMBER(dynax_blit2_romregion_w); DECLARE_WRITE8_MEMBER(dynax_blit2_romregion_w);
DECLARE_WRITE8_MEMBER(dynax_blit_scroll_w); DECLARE_WRITE8_MEMBER(hanamai_blit_pixel_w);
DECLARE_WRITE8_MEMBER(tenkai_blit_scroll_w); DECLARE_WRITE8_MEMBER(cdracula_blit_pixel_w);
DECLARE_WRITE8_MEMBER(dynax_blit2_scroll_w); DECLARE_WRITE8_MEMBER(hnoridur_blit_pixel_w);
DECLARE_WRITE8_MEMBER(dynax_blitter_rev2_w); DECLARE_WRITE8_MEMBER(drgpunch_blit_pixel_w);
DECLARE_WRITE8_MEMBER(tenkai_blitter_rev2_w); DECLARE_WRITE8_MEMBER(jantouki_blit_pixel_w);
DECLARE_WRITE8_MEMBER(cdracula_blitter_rev2_w); DECLARE_WRITE8_MEMBER(jantouki_blit2_pixel_w);
DECLARE_WRITE8_MEMBER(jantouki_blitter_rev2_w); DECLARE_WRITE8_MEMBER(mjdialq2_blit_pixel_w);
DECLARE_WRITE8_MEMBER(jantouki_blitter2_rev2_w); DECLARE_WRITE8_MEMBER(dynax_blit_scrollx_w);
DECLARE_WRITE8_MEMBER(dynax_blit_scrolly_w);
DECLARE_WRITE8_MEMBER(dynax_blit2_scrollx_w);
DECLARE_WRITE8_MEMBER(dynax_blit2_scrolly_w);
DECLARE_WRITE8_MEMBER(tenkai_blit_scrollx_w);
DECLARE_WRITE8_MEMBER(tenkai_blit_scrolly_w);
DECLARE_WRITE8_MEMBER(hanamai_priority_w); DECLARE_WRITE8_MEMBER(hanamai_priority_w);
DECLARE_WRITE8_MEMBER(tenkai_priority_w); DECLARE_WRITE8_MEMBER(tenkai_priority_w);
DECLARE_WRITE8_MEMBER(mjembase_priority_w); DECLARE_WRITE8_MEMBER(mjembase_priority_w);
@ -179,6 +181,7 @@ public:
DECLARE_WRITE_LINE_MEMBER(adpcm_reset_kludge_w); DECLARE_WRITE_LINE_MEMBER(adpcm_reset_kludge_w);
DECLARE_WRITE8_MEMBER(tenkai_dswsel_w); DECLARE_WRITE8_MEMBER(tenkai_dswsel_w);
DECLARE_READ8_MEMBER(tenkai_dsw_r); DECLARE_READ8_MEMBER(tenkai_dsw_r);
DECLARE_WRITE_LINE_MEMBER(tenkai_blitter_irq_w);
DECLARE_WRITE_LINE_MEMBER(tenkai_blitter_ack_w); DECLARE_WRITE_LINE_MEMBER(tenkai_blitter_ack_w);
DECLARE_MACHINE_RESET(dynax); DECLARE_MACHINE_RESET(dynax);
DECLARE_MACHINE_START(dynax); DECLARE_MACHINE_START(dynax);
@ -198,20 +201,13 @@ public:
DECLARE_VIDEO_START(neruton); DECLARE_VIDEO_START(neruton);
DECLARE_VIDEO_START(tenkai); DECLARE_VIDEO_START(tenkai);
inline void blitter_plot_pixel( int layer, int mask, int x, int y, int pen, int wrap, int flags ); //int blitter_drawgfx( int layer, int mask, memory_region *gfx, int src, int pen, int x, int y, int wrap, int flags );
int blitter_drawgfx( int layer, int mask, memory_region *gfx, int src, int pen, int x, int y, int wrap, int flags );
void dynax_blitter_start( int flags );
void jantouki_blitter_start( int flags );
void jantouki_blitter2_start( int flags );
void jantouki_copylayer( bitmap_ind16 &bitmap, const rectangle &cliprect, int i, int y ); void jantouki_copylayer( bitmap_ind16 &bitmap, const rectangle &cliprect, int i, int y );
void mjdialq2_copylayer( bitmap_ind16 &bitmap, const rectangle &cliprect, int i ); void mjdialq2_copylayer( bitmap_ind16 &bitmap, const rectangle &cliprect, int i );
void hanamai_copylayer(bitmap_ind16 &bitmap, const rectangle &cliprect, int i ); void hanamai_copylayer(bitmap_ind16 &bitmap, const rectangle &cliprect, int i );
int debug_mask(); int debug_mask();
int debug_viewer( bitmap_ind16 &bitmap, const rectangle &cliprect ); int debug_viewer( bitmap_ind16 &bitmap, const rectangle &cliprect );
void dynax_common_reset(); void dynax_common_reset();
void sprtmtch_update_irq();
void jantouki_update_irq();
void mjelctrn_update_irq();
void tenkai_update_irq(); void tenkai_update_irq();
void tenkai_show_6c(); void tenkai_show_6c();
void mjfriday(machine_config &config); void mjfriday(machine_config &config);
@ -284,26 +280,17 @@ protected:
optional_device<rst_pos_buffer_device> m_mainirq; optional_device<rst_pos_buffer_device> m_mainirq;
optional_device<rst_pos_buffer_device> m_soundirq; optional_device<rst_pos_buffer_device> m_soundirq;
optional_device<generic_latch_8_device> m_soundlatch; optional_device<generic_latch_8_device> m_soundlatch;
optional_region_ptr<uint8_t> m_gfx_region1; optional_device<dynax_blitter_rev2_device> m_blitter;
optional_region_ptr<uint8_t> m_gfx_region2; optional_device<dynax_blitter_rev2_device> m_blitter2;
optional_region_ptr<uint8_t> m_gfx_region3; optional_region_ptr<uint8_t> m_blitter_gfx;
optional_region_ptr<uint8_t> m_gfx_region4;
optional_region_ptr<uint8_t> m_gfx_region5;
optional_region_ptr<uint8_t> m_gfx_region6;
optional_region_ptr<uint8_t> m_gfx_region7;
optional_region_ptr<uint8_t> m_gfx_region8;
output_finder<> m_led; output_finder<> m_led;
memory_region * m_gfxregions[8];
// up to 8 layers, 2 images per layer (interleaved on screen) // up to 8 layers, 2 images per layer (interleaved on screen)
std::unique_ptr<uint8_t[]> m_pixmap[8][2]; std::unique_ptr<uint8_t[]> m_pixmap[8][2];
/* irq */ /* irq */
irq_func m_update_irq_func;
bool m_blitter_irq; bool m_blitter_irq;
bool m_blitter_irq_mask; bool m_blitter_irq_mask;
bool m_blitter2_irq;
bool m_blitter2_irq_mask; bool m_blitter2_irq_mask;
/* blitters */ /* blitters */
@ -311,20 +298,8 @@ protected:
int m_blit2_scroll_x; int m_blit2_scroll_x;
int m_blit_scroll_y; int m_blit_scroll_y;
int m_blit2_scroll_y; int m_blit2_scroll_y;
int m_blit_wrap_enable;
int m_blit2_wrap_enable;
int m_blit_x;
int m_blit_y;
int m_blit2_x;
int m_blit2_y;
int m_blit_src;
int m_blit2_src;
int m_blit_romregion;
int m_blit2_romregion;
int m_blit_dest; int m_blit_dest;
int m_blit2_dest; int m_blit2_dest;
int m_blit_pen;
int m_blit2_pen;
int m_blit_palbank; int m_blit_palbank;
int m_blit2_palbank; int m_blit2_palbank;
int m_blit_palettes; int m_blit_palettes;

View File

@ -88,20 +88,6 @@ WRITE8_MEMBER(dynax_state::dynax_extra_scrolly_w)
} }
/* Destination Pen */
WRITE8_MEMBER(dynax_state::dynax_blit_pen_w)
{
m_blit_pen = data;
LOG(("P=%02X ", data));
}
WRITE8_MEMBER(dynax_state::dynax_blit2_pen_w)
{
m_blit2_pen = data;
LOG(("P'=%02X ", data));
}
/* Destination Layers */ /* Destination Layers */
WRITE8_MEMBER(dynax_state::dynax_blit_dest_w) WRITE8_MEMBER(dynax_state::dynax_blit_dest_w)
{ {
@ -293,501 +279,153 @@ WRITE_LINE_MEMBER(dynax_state::flipscreen_w)
WRITE8_MEMBER(dynax_state::dynax_blit_romregion_w) WRITE8_MEMBER(dynax_state::dynax_blit_romregion_w)
{ {
if (data < 8) if (data < 8)
m_blit_romregion = data; m_blitter->set_rom_bank(data);
LOG(("GFX%X ", data + 1)); LOG(("GFX%X ", data + 1));
} }
WRITE8_MEMBER(dynax_state::dynax_blit2_romregion_w) WRITE8_MEMBER(dynax_state::dynax_blit2_romregion_w)
{ {
if (data + 1 < 8) if (data + 1 < 8)
m_blit2_romregion = data + 1; m_blitter2->set_rom_bank(data);
LOG(("GFX%X' ", data + 2)); LOG(("GFX%X' ", data + 2));
} }
/***************************************************************************
Blitter Data Format WRITE8_MEMBER(dynax_state::hanamai_blit_pixel_w)
The blitter reads its commands from the gfx ROMs. They are
instructions to draw an image pixel by pixel (in a compressed
form) in a frame buffer.
Fetch 1 Byte from the ROM:
7654 ---- Pen to draw with
---- 3210 Command
Other bytes may follow, depending on the command
Commands:
0 Stop.
1-b Draw 1-b pixels along X.
c Followed by 1 byte (N): draw N pixels along X.
d Followed by 2 bytes (X,N): skip X pixels, draw N pixels along X.
e ? unused
f Increment Y
***************************************************************************/
/* Plot a pixel (in the pixmaps specified by dynax_blit_dest) */
void dynax_state::blitter_plot_pixel( int layer, int mask, int x, int y, int pen, int wrap, int flags )
{ {
int addr;
if ((y > 0xff) && (!(wrap & 2))) return; // fixes mjdialq2 & mjangels title screens
if ((x > 0xff) && (!(wrap & 1))) return;
x &= 0xff; // confirmed by some mjdialq2 gfx and especially by mjfriday, which
// uses the front layer to mask out the right side of the screen as
// it draws stuff on the left, when it shows the girls scrolling
// horizontally after you win.
y &= 0xff; // seems confirmed by mjdialq2 last picture of gal 6, but it breaks
// mjdialq2 title screen so there's something we are missing. <fixed, see above>
/* "Flip Screen" just means complement the coordinates to 255 */
if (m_flipscreen) { x ^= 0xff; y ^= 0xff; }
/* Rotate: rotation = SWAPXY + FLIPY */
if (flags & 0x08) { int t = x; x = y; y = t; }
addr = x + (y << 8);
switch (m_layer_layout)
{
case LAYOUT_HANAMAI:
if (BIT(mask, 0)) m_pixmap[layer + 0][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 1)) m_pixmap[layer + 1][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 2)) m_pixmap[layer + 2][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 3)) m_pixmap[layer + 3][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
break;
case LAYOUT_HNORIDUR:
if (BIT(mask, 0)) m_pixmap[layer + 0][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 1)) m_pixmap[layer + 1][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 2)) m_pixmap[layer + 2][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 3)) m_pixmap[layer + 3][m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (!m_hnoridur_layer_half2)
break;
if (BIT(mask, 0)) m_pixmap[layer + 0][1 ^ m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 1)) m_pixmap[layer + 1][1 ^ m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 2)) m_pixmap[layer + 2][1 ^ m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
if (BIT(mask, 3)) m_pixmap[layer + 3][1 ^ m_hanamai_layer_half ^ m_flipscreen][addr] = pen;
break;
case LAYOUT_JANTOUKI:
if (BIT(mask, 7)) m_pixmap[layer + 3][1 ^ m_flipscreen][addr] = pen;
if (BIT(mask, 6)) m_pixmap[layer + 3][0 ^ m_flipscreen][addr] = pen;
case LAYOUT_DRGPUNCH:
if (BIT(mask, 5)) m_pixmap[layer + 2][1 ^ m_flipscreen][addr] = pen;
if (BIT(mask, 4)) m_pixmap[layer + 2][0 ^ m_flipscreen][addr] = pen;
if (BIT(mask, 3)) m_pixmap[layer + 1][1 ^ m_flipscreen][addr] = pen;
if (BIT(mask, 2)) m_pixmap[layer + 1][0 ^ m_flipscreen][addr] = pen;
if (BIT(mask, 1)) m_pixmap[layer + 0][1 ^ m_flipscreen][addr] = pen;
if (BIT(mask, 0)) m_pixmap[layer + 0][0 ^ m_flipscreen][addr] = pen;
break;
case LAYOUT_MJDIALQ2:
if (BIT(mask, 0)) m_pixmap[layer + 0][0][addr] = pen;
if (BIT(mask, 1)) m_pixmap[layer + 1][0][addr] = pen;
break;
}
}
/*
Flags:
7654 ---- -
---- 3--- Rotation = SWAPXY + FLIPY
---- -2-- -
---- --1- 0 = Ignore the pens specified in ROM, draw everything with the pen supplied as parameter
---- ---0 Clear
*/
int dynax_state::blitter_drawgfx( int layer, int mask, memory_region *gfx, int src, int pen, int x, int y, int wrap, int flags )
{
if (!gfx)
return 0;
size_t rom_size = gfx->bytes();
uint8_t* rom_data = gfx->base();
if (m_layer_layout == LAYOUT_HNORIDUR) // e.g. yarunara
pen = ((pen >> 4) & 0xf) | ((mask & 0x10) ? ((pen & 0x08) << 1) : 0);
else
pen = (pen >> 4) & 0xf;
if (flags & 0xf4)
popmessage("flags %02x", flags);
if (flags & 1)
{
/* Clear the buffer(s) starting from the given scanline and exit */
int addr = x + (y << 8);
int start = addr;
if (m_flipscreen) if (m_flipscreen)
start = 0; offset ^= 0xffff;
int len = 0x10000 - addr; for (int layer = 0; layer < 4; layer++)
switch (m_layer_layout)
{ {
case LAYOUT_HANAMAI: if (BIT(m_blit_dest, layer))
if (BIT(mask, 0)) memset(&m_pixmap[layer + 0][0][start], pen, len);
if (BIT(mask, 0)) memset(&m_pixmap[layer + 0][1][start], pen, len);
if (BIT(mask, 1)) memset(&m_pixmap[layer + 1][0][start], pen, len);
if (BIT(mask, 1)) memset(&m_pixmap[layer + 1][1][start], pen, len);
if (BIT(mask, 2)) memset(&m_pixmap[layer + 2][0][start], pen, len);
if (BIT(mask, 2)) memset(&m_pixmap[layer + 2][1][start], pen, len);
if (BIT(mask, 3)) memset(&m_pixmap[layer + 3][0][start], pen, len);
if (BIT(mask, 3)) memset(&m_pixmap[layer + 3][1][start], pen, len);
break;
case LAYOUT_HNORIDUR:
if (BIT(mask, 0)) memset(&m_pixmap[layer + 0][m_hanamai_layer_half][start], pen, len);
if (BIT(mask, 1)) memset(&m_pixmap[layer + 1][m_hanamai_layer_half][start], pen, len);
if (BIT(mask, 2)) memset(&m_pixmap[layer + 2][m_hanamai_layer_half][start], pen, len);
if (BIT(mask, 3)) memset(&m_pixmap[layer + 3][m_hanamai_layer_half][start], pen, len);
if (!m_hnoridur_layer_half2)
break;
if (BIT(mask, 0)) memset(&m_pixmap[layer + 0][1 - m_hanamai_layer_half][start], pen, len);
if (BIT(mask, 1)) memset(&m_pixmap[layer + 1][1 - m_hanamai_layer_half][start], pen, len);
if (BIT(mask, 2)) memset(&m_pixmap[layer + 2][1 - m_hanamai_layer_half][start], pen, len);
if (BIT(mask, 3)) memset(&m_pixmap[layer + 3][1 - m_hanamai_layer_half][start], pen, len);
break;
case LAYOUT_JANTOUKI:
if (BIT(mask, 7)) memset(&m_pixmap[layer + 3][1][start], pen, len);
if (BIT(mask, 6)) memset(&m_pixmap[layer + 3][0][start], pen, len);
case LAYOUT_DRGPUNCH:
if (BIT(mask, 5)) memset(&m_pixmap[layer + 2][1][start], pen, len);
if (BIT(mask, 4)) memset(&m_pixmap[layer + 2][0][start], pen, len);
if (BIT(mask, 3)) memset(&m_pixmap[layer + 1][1][start], pen, len);
if (BIT(mask, 2)) memset(&m_pixmap[layer + 1][0][start], pen, len);
if (BIT(mask, 1)) memset(&m_pixmap[layer + 0][1][start], pen, len);
if (BIT(mask, 0)) memset(&m_pixmap[layer + 0][0][start], pen, len);
break;
case LAYOUT_MJDIALQ2:
if (BIT(mask, 0)) memset(&m_pixmap[layer + 0][0][start], pen, len);
if (BIT(mask, 1)) memset(&m_pixmap[layer + 1][0][start], pen, len);
break;
}
return src;
}
int sx = x;
src &= 0xfffff;
for ( ;; )
{ {
if (src >= rom_size) if (BIT(m_hanamai_priority, 4))
{ m_pixmap[layer][m_hanamai_layer_half ^ m_flipscreen][offset] = data;
popmessage("GFXROM %s OVER %08x",gfx,src);
LOG(("\nGFXROM %s OVER %08x",gfx,src));
return src;
}
uint8_t cmd = rom_data[src++];
src &= 0xfffff;
if (!(flags & 0x02)) // Ignore the pens specified in ROM, draw everything with the pen supplied as parameter
pen = (pen & 0xf0) | ((cmd & 0xf0) >> 4);
cmd = (cmd & 0x0f);
switch (cmd)
{
case 0xf: // Increment Y
/* Rotate: rotation = SWAPXY + FLIPY */
if (flags & 0x08)
y--;
else else
y++; m_pixmap[layer][0][offset] = m_pixmap[layer][1][offset] = data;
x = sx;
break;
case 0xe: // unused ? was "change dest mask" in the "rev1" blitter
popmessage("Blitter unknown command %06X: %02X\n", src - 1, cmd);
case 0xd: // Skip X pixels
if (src >= rom_size)
{
popmessage("GFXROM %s OVER %08x",gfx,src);
LOG(("\nGFXROM %s OVER %08x",gfx,src));
return src;
}
x = sx + rom_data[src++];
src &= 0xfffff;
/* fall through into next case */
case 0xc: // Draw N pixels
if (src >= rom_size)
{
popmessage("GFXROM %s OVER %08x",gfx,src);
LOG(("\nGFXROM %s OVER %08x",gfx,src));
return src;
}
cmd = rom_data[src++];
src &= 0xfffff;
/* fall through into next case */
case 0xb:
case 0xa:
case 0x9:
case 0x8:
case 0x7:
case 0x6:
case 0x5:
case 0x4:
case 0x3:
case 0x2:
case 0x1: // Draw N pixels
while (cmd--)
blitter_plot_pixel(layer, mask, x++, y, pen, wrap, flags);
break;
case 0x0: // Stop
return src;
} }
} }
} }
WRITE8_MEMBER(dynax_state::cdracula_blit_pixel_w)
void dynax_state::dynax_blitter_start(int flags )
{ {
int blit_newsrc; if (m_flipscreen)
offset ^= 0xffff;
LOG(("XY=%X,%X SRC=%X BLIT=%X\n", m_blit_x, m_blit_y, m_blit_src, flags)); for (int layer = 0; layer < 4; layer++)
blit_newsrc = blitter_drawgfx(
0, // layer
m_blit_dest, // layer mask
m_gfxregions[m_blit_romregion], // rom region
m_blit_src, // rom address
m_blit_pen, // pen
m_blit_x, m_blit_y, // x,y
m_blit_wrap_enable, // wrap around
flags // flags
);
m_blit_src = (m_blit_src & ~0x0fffff) | (blit_newsrc & 0x0fffff);
/* Generate an IRQ */
if (m_update_irq_func)
{ {
m_blitter_irq = 1; if (BIT(m_blit_dest, layer + 4))
(this->*m_update_irq_func)(); m_pixmap[layer][1 ^ m_flipscreen][offset] = data;
if (BIT(m_blit_dest, layer))
m_pixmap[layer][0 ^ m_flipscreen][offset] = data;
} }
} }
void dynax_state::jantouki_blitter_start( int flags ) WRITE8_MEMBER(dynax_state::hnoridur_blit_pixel_w)
{ {
int blit_newsrc; if (m_flipscreen)
offset ^= 0xffff;
if (BIT(m_blit_dest, 4))
data |= (m_blitter->blit_pen() & 0x08) << 1;
LOG(("XY=%X,%X SRC=%X BLIT=%X\n", m_blit_x, m_blit_y, m_blit_src, flags)); for (int layer = 0; layer < 4; layer++)
blit_newsrc = blitter_drawgfx(
0, // layer
m_blit_dest, // layer mask
m_gfxregions[m_blit_romregion], // rom region
m_blit_src, // rom address
m_blit_pen, // pen
m_blit_x, m_blit_y, // x,y
m_blit_wrap_enable, // wrap around
flags // flags
);
m_blit_src = (m_blit_src & ~0x0fffff) | (blit_newsrc & 0x0fffff);
/* Generate an IRQ */
if (m_update_irq_func)
{ {
m_blitter_irq = 1; if (BIT(m_blit_dest, layer))
(this->*m_update_irq_func)(); {
m_pixmap[layer][m_hanamai_layer_half ^ m_flipscreen][offset] = data;
if (m_hnoridur_layer_half2)
m_pixmap[layer][1 ^ m_hanamai_layer_half ^ m_flipscreen][offset] = data;
}
} }
} }
void dynax_state::jantouki_blitter2_start( int flags ) WRITE8_MEMBER(dynax_state::drgpunch_blit_pixel_w)
{ {
int blit2_newsrc; if (m_flipscreen)
offset ^= 0xffff;
LOG(("XY'=%X,%X SRC'=%X BLIT'=%02X\n", m_blit2_x, m_blit2_y, m_blit2_src, flags)); for (int layer = 2; layer >= 0; layer--)
blit2_newsrc = blitter_drawgfx(
4, // layer
m_blit2_dest, // layer mask
m_gfxregions[m_blit2_romregion], // rom region
m_blit2_src, // rom address
m_blit2_pen, // pen
m_blit2_x, m_blit2_y, // x,y
m_blit2_wrap_enable, // wrap around
flags // flags
);
m_blit2_src = (m_blit2_src & ~0x0fffff) | (blit2_newsrc & 0x0fffff);
/* Generate an IRQ */
if (m_update_irq_func)
{ {
m_blitter2_irq = 1; if (BIT(m_blit_dest, 2 * layer + 1))
(this->*m_update_irq_func)(); m_pixmap[layer][1 ^ m_flipscreen][offset] = data;
if (BIT(m_blit_dest, 2 * layer))
m_pixmap[layer][0 ^ m_flipscreen][offset] = data;
} }
} }
// two blitters/screens
WRITE8_MEMBER(dynax_state::jantouki_blit_pixel_w)
{
if (m_flipscreen)
offset ^= 0xffff;
for (int layer = 3; layer >= 0; layer--)
{
if (BIT(m_blit_dest, 2 * layer + 1))
m_pixmap[layer][1 ^ m_flipscreen][offset] = data;
if (BIT(m_blit_dest, 2 * layer))
m_pixmap[layer][0 ^ m_flipscreen][offset] = data;
}
}
WRITE8_MEMBER(dynax_state::jantouki_blit2_pixel_w)
{
if (m_flipscreen)
offset ^= 0xffff;
for (int layer = 3; layer >= 0; layer--)
{
if (BIT(m_blit2_dest, 2 * layer + 1))
m_pixmap[layer + 4][1 ^ m_flipscreen][offset] = data;
if (BIT(m_blit2_dest, 2 * layer))
m_pixmap[layer + 4][0 ^ m_flipscreen][offset] = data;
}
}
WRITE8_MEMBER(dynax_state::mjdialq2_blit_pixel_w)
{
if (m_flipscreen)
offset ^= 0xffff;
for (int layer = 0; layer < 2; layer++)
if (BIT(m_blit_dest, layer))
m_pixmap[layer][0][offset] = data;
}
WRITE8_MEMBER(dynax_state::dynax_blit_scroll_w) WRITE8_MEMBER(dynax_state::dynax_blit_scrollx_w)
{ {
switch (m_blit_src & 0xc00000) m_blit_scroll_x = data;
{ }
case 0x000000: m_blit_scroll_x = data;
LOG(("SX=%02X ", data)); WRITE8_MEMBER(dynax_state::dynax_blit_scrolly_w)
break; {
case 0x400000: m_blit_scroll_y = data; m_blit_scroll_y = data;
LOG(("SY=%02X ", data)); }
break;
case 0x800000: WRITE8_MEMBER(dynax_state::dynax_blit2_scrollx_w)
case 0xc00000: m_blit_wrap_enable = data; {
LOG(("WE=%02X ", data)); m_blit2_scroll_x = data;
break; }
}
WRITE8_MEMBER(dynax_state::dynax_blit2_scrolly_w)
{
m_blit2_scroll_y = data;
} }
// inverted scroll values // inverted scroll values
WRITE8_MEMBER(dynax_state::tenkai_blit_scroll_w) WRITE8_MEMBER(dynax_state::tenkai_blit_scrollx_w)
{ {
switch (m_blit_src & 0xc00000) m_blit_scroll_x = ((data ^ 0xff) + 1) & 0xff;
{
case 0x000000: m_blit_scroll_x = ((data ^ 0xff) + 1) & 0xff;
LOG(("SX=%02X ", data));
break;
case 0x400000: m_blit_scroll_y = data ^ 0xff;
LOG(("SY=%02X ", data));
break;
case 0x800000:
case 0xc00000: m_blit_wrap_enable = data;
LOG(("WE=%02X ", data));
break;
}
} }
WRITE8_MEMBER(dynax_state::dynax_blit2_scroll_w) WRITE8_MEMBER(dynax_state::tenkai_blit_scrolly_w)
{ {
switch (m_blit2_src & 0xc00000) m_blit_scroll_y = data ^ 0xff;
{
case 0x000000: m_blit2_scroll_x = data;
LOG(("SX'=%02X ", data));
break;
case 0x400000: m_blit2_scroll_y = data;
LOG(("SY'=%02X ", data));
break;
case 0x800000:
case 0xc00000: m_blit2_wrap_enable = data;
LOG(("WE'=%02X ", data));
break;
}
} }
WRITE8_MEMBER(dynax_state::dynax_blitter_rev2_w)
{
switch (offset)
{
case 0: dynax_blitter_start(data); break;
case 1: m_blit_x = data; break;
case 2: m_blit_y = data; break;
case 3: m_blit_src = (m_blit_src & 0xffff00) | (data << 0); break;
case 4: m_blit_src = (m_blit_src & 0xff00ff) | (data << 8); break;
case 5: m_blit_src = (m_blit_src & 0x00ffff) | (data << 16); break;
case 6: dynax_blit_scroll_w(space, 0, data); break;
}
}
// different scroll_w
WRITE8_MEMBER(dynax_state::tenkai_blitter_rev2_w)
{
switch (offset)
{
case 0: dynax_blitter_start(data); break;
case 1: m_blit_x = data; break;
case 2: m_blit_y = data; break;
case 3: m_blit_src = (m_blit_src & 0xffff00) | (data << 0); break;
case 4: m_blit_src = (m_blit_src & 0xff00ff) | (data << 8); break;
case 5: m_blit_src = (m_blit_src & 0x00ffff) | (data << 16); break;
case 6: tenkai_blit_scroll_w(space, 0, data); break;
}
}
// two blitters/screens
WRITE8_MEMBER(dynax_state::jantouki_blitter_rev2_w)
{
switch (offset)
{
case 0: jantouki_blitter_start(data); break;
case 1: m_blit_x = data; break;
case 2: m_blit_y = data; break;
case 3: m_blit_src = (m_blit_src & 0xffff00) | (data << 0); break;
case 4: m_blit_src = (m_blit_src & 0xff00ff) | (data << 8); break;
case 5: m_blit_src = (m_blit_src & 0x00ffff) | (data << 16); break;
case 6: dynax_blit_scroll_w(space, 0, data); break;
}
}
WRITE8_MEMBER(dynax_state::jantouki_blitter2_rev2_w)
{
switch (offset)
{
case 0: jantouki_blitter2_start(data); break;
case 1: m_blit2_x = data; break;
case 2: m_blit2_y = data; break;
case 3: m_blit2_src = (m_blit2_src & 0xffff00) | (data << 0); break;
case 4: m_blit2_src = (m_blit2_src & 0xff00ff) | (data << 8); break;
case 5: m_blit2_src = (m_blit2_src & 0x00ffff) | (data << 16); break;
case 6: dynax_blit2_scroll_w(space, 0, data); break;
}
}
// first register does not trigger a blit, it sets the destination
WRITE8_MEMBER(dynax_state::cdracula_blitter_rev2_w)
{
switch (offset)
{
case 0:
LOG(("DD=%02X ", data));
if (data & 0xf0)
{
layer_half_w(0);
dynax_blit_dest_w(space, offset, data >> 4, mem_mask);
}
if (data & 0x0f)
{
layer_half_w(1);
dynax_blit_dest_w(space, offset, data & 0x0f, mem_mask);
}
break;
case 1: m_blit_x = data; break;
case 2: m_blit_y = data; break;
case 3: m_blit_src = (m_blit_src & 0xffff00) | (data << 0); break;
case 4: m_blit_src = (m_blit_src & 0xff00ff) | (data << 8); break;
case 5: m_blit_src = (m_blit_src & 0x00ffff) | (data << 16); break;
case 6: dynax_blit_scroll_w(space, 0, data); break;
}
}
WRITE8_MEMBER(dynax_state::dynax_blit_flags_w)
{
LOG(("FLG=%02X ", data));
int flags = (data & 0x08) ? 0x08 : 0x00;
flags |= (data & 0x10) ? 0x02 : 0x00;
flags |= (data & 0x80) ? 0x01 : 0x00;
dynax_blitter_start(flags);
}
/*************************************************************************** /***************************************************************************
@ -806,22 +444,8 @@ static const int priority_mjembase[8] = { 0x0231, 0x2031, 0x0321, 0x3021, 0x2301
void dynax_state::dynax_common_reset() void dynax_state::dynax_common_reset()
{ {
m_gfxregions[0] = memregion("gfx1");
m_gfxregions[1] = memregion("gfx2");
m_gfxregions[2] = memregion("gfx3");
m_gfxregions[3] = memregion("gfx4");
m_gfxregions[4] = memregion("gfx5");
m_gfxregions[5] = memregion("gfx6");
m_gfxregions[6] = memregion("gfx7");
m_gfxregions[7] = memregion("gfx8");
m_blit_romregion = 0;
m_blit2_romregion = 0;
m_blit_dest = -1; m_blit_dest = -1;
m_blit2_dest = -1; m_blit2_dest = -1;
m_blit_pen = 0x7;
m_blit2_pen = 0x7;
m_blit_palbank = 0; m_blit_palbank = 0;
m_blit2_palbank = 0; m_blit2_palbank = 0;
m_blit_palettes = 0; m_blit_palettes = 0;
@ -834,30 +458,16 @@ void dynax_state::dynax_common_reset()
m_hnoridur_layer_half2 = 0; m_hnoridur_layer_half2 = 0;
m_update_irq_func = &dynax_state::sprtmtch_update_irq;
m_blit_scroll_x = 0; m_blit_scroll_x = 0;
m_blit2_scroll_x = 0; m_blit2_scroll_x = 0;
m_blit_scroll_y = 0; m_blit_scroll_y = 0;
m_blit2_scroll_y = 0; m_blit2_scroll_y = 0;
m_blit_wrap_enable = 0;
m_blit2_wrap_enable = 0;
m_blit_x = 0;
m_blit_y = 0;
m_blit2_x = 0;
m_blit2_y = 0;
m_blit_src = 0;
m_blit2_src = 0;
m_hanamai_layer_half = 0; m_hanamai_layer_half = 0;
m_flipscreen = 0; m_flipscreen = 0;
m_hanamai_priority = 0; m_hanamai_priority = 0;
save_item(NAME(m_blit_romregion));
save_item(NAME(m_blit2_romregion));
save_item(NAME(m_blit_dest)); save_item(NAME(m_blit_dest));
save_item(NAME(m_blit2_dest)); save_item(NAME(m_blit2_dest));
save_item(NAME(m_blit_pen));
save_item(NAME(m_blit2_pen));
save_item(NAME(m_blit_palbank)); save_item(NAME(m_blit_palbank));
save_item(NAME(m_blit2_palbank)); save_item(NAME(m_blit2_palbank));
save_item(NAME(m_blit_palettes)); save_item(NAME(m_blit_palettes));
@ -872,14 +482,6 @@ void dynax_state::dynax_common_reset()
save_item(NAME(m_blit2_scroll_x)); save_item(NAME(m_blit2_scroll_x));
save_item(NAME(m_blit_scroll_y)); save_item(NAME(m_blit_scroll_y));
save_item(NAME(m_blit2_scroll_y)); save_item(NAME(m_blit2_scroll_y));
save_item(NAME(m_blit_wrap_enable));
save_item(NAME(m_blit2_wrap_enable));
save_item(NAME(m_blit_x));
save_item(NAME(m_blit_y));
save_item(NAME(m_blit2_x));
save_item(NAME(m_blit2_y));
save_item(NAME(m_blit_src));
save_item(NAME(m_blit2_src));
save_item(NAME(m_hanamai_layer_half)); save_item(NAME(m_hanamai_layer_half));
save_item(NAME(m_flipscreen)); save_item(NAME(m_flipscreen));
save_item(NAME(m_hanamai_priority)); save_item(NAME(m_hanamai_priority));
@ -982,7 +584,6 @@ VIDEO_START_MEMBER(dynax_state,jantouki)
dynax_common_reset(); dynax_common_reset();
m_layer_layout = LAYOUT_JANTOUKI; m_layer_layout = LAYOUT_JANTOUKI;
m_update_irq_func = &dynax_state::jantouki_update_irq;
save_pointer(NAME(m_pixmap[0][0].get()), 256 * 256); save_pointer(NAME(m_pixmap[0][0].get()), 256 * 256);
save_pointer(NAME(m_pixmap[0][1].get()), 256 * 256); save_pointer(NAME(m_pixmap[0][1].get()), 256 * 256);
@ -1009,7 +610,6 @@ VIDEO_START_MEMBER(dynax_state,mjdialq2)
dynax_common_reset(); dynax_common_reset();
m_layer_layout = LAYOUT_MJDIALQ2; m_layer_layout = LAYOUT_MJDIALQ2;
m_update_irq_func = nullptr;
save_pointer(NAME(m_pixmap[0][0].get()), 256 * 256); save_pointer(NAME(m_pixmap[0][0].get()), 256 * 256);
save_pointer(NAME(m_pixmap[1][0].get()), 256 * 256); save_pointer(NAME(m_pixmap[1][0].get()), 256 * 256);
@ -1020,7 +620,6 @@ VIDEO_START_MEMBER(dynax_state,mjelctrn)
VIDEO_START_CALL_MEMBER(hnoridur); VIDEO_START_CALL_MEMBER(hnoridur);
m_priority_table = priority_mjelctrn; m_priority_table = priority_mjelctrn;
m_update_irq_func = &dynax_state::mjelctrn_update_irq;
} }
VIDEO_START_MEMBER(dynax_state,mjembase) VIDEO_START_MEMBER(dynax_state,mjembase)
@ -1028,7 +627,6 @@ VIDEO_START_MEMBER(dynax_state,mjembase)
VIDEO_START_CALL_MEMBER(hnoridur); VIDEO_START_CALL_MEMBER(hnoridur);
m_priority_table = priority_mjembase; m_priority_table = priority_mjembase;
m_update_irq_func = &dynax_state::mjelctrn_update_irq;
} }
VIDEO_START_MEMBER(dynax_state,neruton) VIDEO_START_MEMBER(dynax_state,neruton)
@ -1036,7 +634,6 @@ VIDEO_START_MEMBER(dynax_state,neruton)
VIDEO_START_CALL_MEMBER(hnoridur); VIDEO_START_CALL_MEMBER(hnoridur);
// m_priority_table = priority_mjelctrn; // m_priority_table = priority_mjelctrn;
m_update_irq_func = &dynax_state::mjelctrn_update_irq;
} }
VIDEO_START_MEMBER(dynax_state,tenkai) VIDEO_START_MEMBER(dynax_state,tenkai)
@ -1044,7 +641,6 @@ VIDEO_START_MEMBER(dynax_state,tenkai)
VIDEO_START_CALL_MEMBER(hnoridur); VIDEO_START_CALL_MEMBER(hnoridur);
m_priority_table = priority_mjelctrn; m_priority_table = priority_mjelctrn;
m_update_irq_func = &dynax_state::tenkai_update_irq;
} }
/*************************************************************************** /***************************************************************************
@ -1290,13 +886,13 @@ int dynax_state::debug_mask()
R - move "tile" to the next 1/8th of the gfx */ R - move "tile" to the next 1/8th of the gfx */
int dynax_state::debug_viewer(bitmap_ind16 &bitmap, const rectangle &cliprect ) int dynax_state::debug_viewer(bitmap_ind16 &bitmap, const rectangle &cliprect )
{ {
#ifdef MAME_DEBUG #if 0 // needs rewrite
static int toggle; static int toggle;
if (machine().input().code_pressed_once(KEYCODE_T)) toggle = 1 - toggle; if (machine().input().code_pressed_once(KEYCODE_T)) toggle = 1 - toggle;
if (m_gfxregions[0] && toggle) if (m_blitter_gfx.found() && toggle)
{ {
uint8_t *RAM = m_gfxregions[0]->base(); uint8_t *RAM = &m_blitter_gfx[0];
size_t size = m_gfxregions[0]->bytes(); size_t size = m_blitter_gfx.bytes();
static int i = 0, c = 0, r = 0; static int i = 0, c = 0, r = 0;
if (machine().input().code_pressed_once(KEYCODE_I)) c = (c - 1) & 0x1f; if (machine().input().code_pressed_once(KEYCODE_I)) c = (c - 1) & 0x1f;
@ -1323,7 +919,7 @@ int dynax_state::debug_viewer(bitmap_ind16 &bitmap, const rectangle &cliprect )
if (m_layer_layout != LAYOUT_MJDIALQ2) if (m_layer_layout != LAYOUT_MJDIALQ2)
memset(m_pixmap[0][1].get(), 0, sizeof(uint8_t) * 0x100 * 0x100); memset(m_pixmap[0][1].get(), 0, sizeof(uint8_t) * 0x100 * 0x100);
for (m_hanamai_layer_half = 0; m_hanamai_layer_half < 2; m_hanamai_layer_half++) for (m_hanamai_layer_half = 0; m_hanamai_layer_half < 2; m_hanamai_layer_half++)
blitter_drawgfx(0, 1, m_gfxregions[0], i, 0, cliprect.min_x, cliprect.min_y, 3, 0); blitter_drawgfx(0, 1, m_blitter_gfx, i, 0, cliprect.min_x, cliprect.min_y, 3, 0);
if (m_layer_layout != LAYOUT_MJDIALQ2) if (m_layer_layout != LAYOUT_MJDIALQ2)
hanamai_copylayer(bitmap, cliprect, 0); hanamai_copylayer(bitmap, cliprect, 0);
@ -1500,5 +1096,6 @@ uint32_t dynax_state::screen_update_cdracula(screen_device &screen, bitmap_ind16
if (BIT(layers_ctrl, 1)) hanamai_copylayer(bitmap, cliprect, 1); if (BIT(layers_ctrl, 1)) hanamai_copylayer(bitmap, cliprect, 1);
if (BIT(layers_ctrl, 2)) hanamai_copylayer(bitmap, cliprect, 2); if (BIT(layers_ctrl, 2)) hanamai_copylayer(bitmap, cliprect, 2);
if (BIT(layers_ctrl, 0)) hanamai_copylayer(bitmap, cliprect, 0); if (BIT(layers_ctrl, 0)) hanamai_copylayer(bitmap, cliprect, 0);
return 0; return 0;
} }

View File

@ -0,0 +1,404 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia, Nicola Salmoria, AJR
/**********************************************************************
Dynax blitter, "revision 2" (TC17G032AP-0246 custom DIP64)
***********************************************************************
Blitter Data Format
The blitter reads its commands from the gfx ROMs. They are
instructions to draw an image pixel by pixel (in a compressed
form) in a frame buffer.
Fetch 1 Byte from the ROM:
7654 ---- Pen to draw with
---- 3210 Command
Other bytes may follow, depending on the command
Commands:
0 Stop.
1-b Draw 1-b pixels along X.
c Followed by 1 byte (N): draw N pixels along X.
d Followed by 2 bytes (X,N): skip X pixels, draw N pixels along X.
e ? unused
f Increment Y
**********************************************************************/
#include "emu.h"
#include "dynax_blitter_rev2.h"
#define VERBOSE 1
#include "logmacro.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(DYNAX_BLITTER_REV2, dynax_blitter_rev2_device, "tc17g032ap", "Dynax TC17G032AP Blitter")
DEFINE_DEVICE_TYPE(CDRACULA_BLITTER, cdracula_blitter_device, "cdracula_blitter", "Castle of Dracula TPC1020AFN Blitter")
//**************************************************************************
// DEVICE DEFINITION
//**************************************************************************
//-------------------------------------------------
// dynax_blitter_rev2_device - constructor
//-------------------------------------------------
dynax_blitter_rev2_device::dynax_blitter_rev2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: dynax_blitter_rev2_device(mconfig, DYNAX_BLITTER_REV2, tag, owner, clock)
{
}
dynax_blitter_rev2_device::dynax_blitter_rev2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, device_rom_interface(mconfig, *this, 20, ENDIANNESS_LITTLE, 8)
, m_vram_out_cb(*this)
, m_scrollx_cb(*this)
, m_scrolly_cb(*this)
, m_ready_cb(*this)
{
}
//-------------------------------------------------
// device_resolve_objects - resolve objects that
// may be needed for other devices to set
// initial conditions at start time
//-------------------------------------------------
void dynax_blitter_rev2_device::device_resolve_objects()
{
m_vram_out_cb.resolve_safe();
m_scrollx_cb.resolve_safe();
m_scrolly_cb.resolve_safe();
m_ready_cb.resolve_safe();
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void dynax_blitter_rev2_device::device_start()
{
m_blit_pen = 0x7;
m_blit_wrap_enable = 0;
m_blit_x = 0;
m_blit_y = 0;
m_blit_flags = 0;
m_blit_src = 0;
save_item(NAME(m_blit_pen));
save_item(NAME(m_blit_wrap_enable));
save_item(NAME(m_blit_x));
save_item(NAME(m_blit_y));
save_item(NAME(m_blit_flags));
save_item(NAME(m_blit_src));
}
//-------------------------------------------------
// plot_pixel - send data for one pixel to VRAM
//-------------------------------------------------
void dynax_blitter_rev2_device::plot_pixel(int x, int y, int pen)
{
if (y > 0xff && !BIT(m_blit_wrap_enable, 1))
return; // fixes mjdialq2 & mjangels title screens
if (x > 0xff && !BIT(m_blit_wrap_enable, 0))
return;
x &= 0xff; // confirmed by some mjdialq2 gfx and especially by mjfriday, which
// uses the front layer to mask out the right side of the screen as
// it draws stuff on the left, when it shows the girls scrolling
// horizontally after you win.
y &= 0xff; // seems confirmed by mjdialq2 last picture of gal 6, but it breaks
// mjdialq2 title screen so there's something we are missing. <fixed, see above>
// Rotate: rotation = SWAPXY + FLIPY
if (BIT(m_blit_flags, 3))
std::swap(x, y);
// Flip screen and destination layer selection are handled externally
m_vram_out_cb(x | (y << 8), pen, 0xff);
}
//-------------------------------------------------
// blitter_draw - perform a blit operation
//-------------------------------------------------
/*
Flags:
7654 ---- -
---- 3--- Rotation = SWAPXY + FLIPY
---- -2-- -
---- --1- 0 = Ignore the pens specified in ROM, draw everything with the pen supplied as parameter
---- ---0 Clear
*/
u32 dynax_blitter_rev2_device::blitter_draw(u32 src, int pen, int x, int y)
{
pen = (pen >> 4) & 0xf;
if (BIT(m_blit_flags, 0))
{
// Clear the buffer(s) starting from the given scanline and exit
int addr = x | (y << 8);
while (addr < 0x10000)
m_vram_out_cb(addr++, pen, 0xff);
return src;
}
int sx = x;
src &= 0xfffff;
for ( ;; )
{
u8 cmd = read_byte(src++);
src &= 0xfffff;
if (!BIT(m_blit_flags, 1)) // Ignore the pens specified in ROM, draw everything with the pen supplied as parameter
pen = (cmd & 0xf0) >> 4;
cmd = (cmd & 0x0f);
switch (cmd)
{
case 0xf: // Increment Y
/* Rotate: rotation = SWAPXY + FLIPY */
if (BIT(m_blit_flags, 3))
y--;
else
y++;
x = sx;
break;
case 0xe: // unused ? was "change dest mask" in the "rev1" blitter
LOG("Blitter unknown command %06X: %02X\n", src - 1, cmd);
break;
case 0xd: // Skip X pixels
x = sx + read_byte(src++);
src &= 0xfffff;
/* fall through into next case */
case 0xc: // Draw N pixels
cmd = read_byte(src++);
src &= 0xfffff;
/* fall through into next case */
case 0xb:
case 0xa:
case 0x9:
case 0x8:
case 0x7:
case 0x6:
case 0x5:
case 0x4:
case 0x3:
case 0x2:
case 0x1: // Draw N pixels
while (cmd--)
plot_pixel(x++, y, pen);
break;
case 0x0: // Stop
return src;
}
}
}
//-------------------------------------------------
// blitter_start - start and finish a blit
//-------------------------------------------------
void dynax_blitter_rev2_device::blitter_start()
{
LOG("%s: XY=%X,%X SRC=%X BLIT=%X\n", machine().describe_context(), m_blit_x, m_blit_y, m_blit_src, m_blit_flags);
// Blitter is busy
m_ready_cb(0);
u32 blit_newsrc = blitter_draw(m_blit_src, m_blit_pen, m_blit_x, m_blit_y);
m_blit_src = (m_blit_src & ~0x0fffff) | (blit_newsrc & 0x0fffff);
// Blitter is ready; generate an IRQ
m_ready_cb(1);
}
//-------------------------------------------------
// scroll_w - handle scroll/wrap register writes
//-------------------------------------------------
void dynax_blitter_rev2_device::scroll_w(u8 data)
{
switch (m_blit_src & 0xc00000)
{
case 0x000000:
m_scrollx_cb(data);
LOG("%s: SX=%02X\n", machine().describe_context(), data);
break;
case 0x400000:
m_scrolly_cb(data);
LOG("%s: SY=%02X\n", machine().describe_context(), data);
break;
case 0x800000:
case 0xc00000:
m_blit_wrap_enable = data;
LOG("%s: WE=%02X\n", machine().describe_context(), data);
break;
}
}
//-------------------------------------------------
// pen_w - set the destination pen
//-------------------------------------------------
WRITE8_MEMBER(dynax_blitter_rev2_device::pen_w)
{
m_blit_pen = data;
LOG("%s: P=%02X\n", machine().describe_context(), data);
}
//-------------------------------------------------
// regs_w - handle blitter register writes
//-------------------------------------------------
WRITE8_MEMBER(dynax_blitter_rev2_device::regs_w)
{
switch (offset)
{
case 0:
m_blit_flags = data;
blitter_start();
break;
case 1:
m_blit_x = data;
break;
case 2:
m_blit_y = data;
break;
case 3:
m_blit_src = (m_blit_src & 0xffff00) | (data << 0);
break;
case 4:
m_blit_src = (m_blit_src & 0xff00ff) | (data << 8);
break;
case 5:
m_blit_src = (m_blit_src & 0x00ffff) | (data << 16);
break;
case 6:
scroll_w(data);
break;
}
}
//**************************************************************************
// DEVICE DEFINITION (BOOTLEG FPGA VARIANT)
//**************************************************************************
//-------------------------------------------------
// cdracula_blitter_device - constructor
//-------------------------------------------------
cdracula_blitter_device::cdracula_blitter_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: dynax_blitter_rev2_device(mconfig, CDRACULA_BLITTER, tag, owner, clock)
, m_blit_dest_cb(*this)
{
}
//-------------------------------------------------
// device_resolve_objects -
//-------------------------------------------------
void cdracula_blitter_device::device_resolve_objects()
{
dynax_blitter_rev2_device::device_resolve_objects();
m_blit_dest_cb.resolve_safe();
}
//-------------------------------------------------
// flags_w - separate flags/start register for
// bootleg blitter
//-------------------------------------------------
WRITE8_MEMBER(cdracula_blitter_device::flags_w)
{
LOG("%s: FLG=%02X\n", machine().describe_context(), data);
m_blit_flags = (data & 0x08) ? 0x08 : 0x00;
m_blit_flags |= (data & 0x10) ? 0x02 : 0x00;
m_blit_flags |= (data & 0x80) ? 0x01 : 0x00;
blitter_start();
}
//-------------------------------------------------
// regs_w - handle blitter register writes
// (slightly different for bootleg)
//-------------------------------------------------
WRITE8_MEMBER(cdracula_blitter_device::regs_w)
{
// first register does not trigger a blit, it sets the destination
switch (offset)
{
case 0:
LOG("%s: DD=%02X\n", machine().describe_context(), data);
m_blit_dest_cb(data);
break;
case 1:
m_blit_x = data;
break;
case 2:
m_blit_y = data;
break;
case 3:
m_blit_src = (m_blit_src & 0xffff00) | (data << 0);
break;
case 4:
m_blit_src = (m_blit_src & 0xff00ff) | (data << 8);
break;
case 5:
m_blit_src = (m_blit_src & 0x00ffff) | (data << 16);
break;
case 6:
scroll_w(data);
break;
}
}

View File

@ -0,0 +1,121 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia, Nicola Salmoria, AJR
/**********************************************************************
Dynax blitter, "revision 2" (TC17G032AP-0246 custom DIP64)
**********************************************************************/
#pragma once
#ifndef MAME_VIDEO_DYNAX_BLITTER_REV2_H
#define MAME_VIDEO_DYNAX_BLITTER_REV2_H
//**************************************************************************
// CONFIGURATION MACROS
//**************************************************************************
#define MCFG_DYNAX_BLITTER_REV2_VRAM_OUT_CB(_devcb) \
devcb = &downcast<dynax_blitter_rev2_device &>(*device).set_vram_out_cb(DEVCB_##_devcb);
#define MCFG_DYNAX_BLITTER_REV2_SCROLLX_CB(_devcb) \
devcb = &downcast<dynax_blitter_rev2_device &>(*device).set_scrollx_cb(DEVCB_##_devcb);
#define MCFG_DYNAX_BLITTER_REV2_SCROLLY_CB(_devcb) \
devcb = &downcast<dynax_blitter_rev2_device &>(*device).set_scrolly_cb(DEVCB_##_devcb);
#define MCFG_DYNAX_BLITTER_REV2_READY_CB(_devcb) \
devcb = &downcast<dynax_blitter_rev2_device &>(*device).set_ready_cb(DEVCB_##_devcb);
#define MCFG_CDRACULA_BLITTER_VRAM_OUT_CB(_devcb) \
devcb = &downcast<cdracula_blitter_device &>(*device).set_vram_out_cb(DEVCB_##_devcb);
#define MCFG_CDRACULA_BLITTER_SCROLLX_CB(_devcb) \
devcb = &downcast<cdracula_blitter_device &>(*device).set_scrollx_cb(DEVCB_##_devcb);
#define MCFG_CDRACULA_BLITTER_SCROLLY_CB(_devcb) \
devcb = &downcast<cdracula_blitter_device &>(*device).set_scrolly_cb(DEVCB_##_devcb);
#define MCFG_CDRACULA_BLITTER_READY_CB(_devcb) \
devcb = &downcast<cdracula_blitter_device &>(*device).set_ready_cb(DEVCB_##_devcb);
#define MCFG_CDRACULA_BLITTER_DEST_CB(_devcb) \
devcb = &downcast<cdracula_blitter_device &>(*device).set_blit_dest_cb(DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> dynax_blitter_rev2_device
class dynax_blitter_rev2_device : public device_t, public device_rom_interface
{
public:
// construction/destruction
dynax_blitter_rev2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// static configuration
template<class Object> devcb_base &set_vram_out_cb(Object &&object) { return m_vram_out_cb.set_callback(std::forward<Object>(object)); }
template<class Object> devcb_base &set_scrollx_cb(Object &&object) { return m_scrollx_cb.set_callback(std::forward<Object>(object)); }
template<class Object> devcb_base &set_scrolly_cb(Object &&object) { return m_scrolly_cb.set_callback(std::forward<Object>(object)); }
template<class Object> devcb_base &set_ready_cb(Object &&object) { return m_ready_cb.set_callback(std::forward<Object>(object)); }
// write handlers
DECLARE_WRITE8_MEMBER(pen_w);
virtual DECLARE_WRITE8_MEMBER(regs_w);
// getter
u8 blit_pen() const { return m_blit_pen; }
protected:
// delegated construction
dynax_blitter_rev2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// device-level overrides
virtual void device_resolve_objects() override;
virtual void device_start() override;
// device_rom_interface overrides
virtual void rom_bank_updated() override { }
// internal helpers
void plot_pixel(int x, int y, int pen);
u32 blitter_draw(u32 src, int pen, int x, int y);
void blitter_start();
void scroll_w(u8 data);
// device callbacks
devcb_write8 m_vram_out_cb;
devcb_write8 m_scrollx_cb;
devcb_write8 m_scrolly_cb;
devcb_write_line m_ready_cb;
// internal registers
u8 m_blit_pen;
u8 m_blit_wrap_enable;
u8 m_blit_x;
u8 m_blit_y;
u8 m_blit_flags;
u32 m_blit_src;
};
// ======================> cdracula_blitter_device
class cdracula_blitter_device : public dynax_blitter_rev2_device
{
public:
// construction/destruction
cdracula_blitter_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
template<class Object> devcb_base &set_blit_dest_cb(Object &&object) { return m_blit_dest_cb.set_callback(std::forward<Object>(object)); }
// write handlers
DECLARE_WRITE8_MEMBER(flags_w);
virtual DECLARE_WRITE8_MEMBER(regs_w) override;
private:
// device-level overrides
virtual void device_resolve_objects() override;
// device callbacks
devcb_write8 m_blit_dest_cb;
};
// device type declarations
DECLARE_DEVICE_TYPE(DYNAX_BLITTER_REV2, dynax_blitter_rev2_device)
DECLARE_DEVICE_TYPE(CDRACULA_BLITTER, cdracula_blitter_device)
#endif // MAME_VIDEO_DYNAX_BLITTER_REV2_H