diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 10b0cd72e2f..3e3d4a0133b 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -2557,8 +2557,6 @@ files { createMAMEProjects(_target, _subtarget, "metro") files { MAME_DIR .. "src/mame/drivers/hyprduel.cpp", - MAME_DIR .. "src/mame/includes/hyprduel.h", - MAME_DIR .. "src/mame/video/hyprduel.cpp", MAME_DIR .. "src/mame/drivers/metro.cpp", MAME_DIR .. "src/mame/includes/metro.h", MAME_DIR .. "src/mame/video/metro.cpp", diff --git a/src/devices/video/imagetek_i4100.cpp b/src/devices/video/imagetek_i4100.cpp index 18695df1d82..b7b33c083cb 100644 --- a/src/devices/video/imagetek_i4100.cpp +++ b/src/devices/video/imagetek_i4100.cpp @@ -66,7 +66,7 @@ #include "emu.h" #include "imagetek_i4100.h" - +#include //************************************************************************** // GLOBAL VARIABLES @@ -342,7 +342,7 @@ WRITE16_MEMBER(imagetek_i4100_device::vram_0_w){ COMBINE_DATA(&m_vram_0[offset]) WRITE16_MEMBER(imagetek_i4100_device::vram_1_w){ COMBINE_DATA(&m_vram_1[offset]); } WRITE16_MEMBER(imagetek_i4100_device::vram_2_w){ COMBINE_DATA(&m_vram_2[offset]); } -/* This game uses almost only the blitter to write to the tilemaps. +/* Some game uses almost only the blitter to write to the tilemaps. The CPU can only access a "window" of 512x256 pixels in the upper left corner of the big tilemap */ // TODO: Puzzlet, Sankokushi & Lady Killer contradicts with aformentioned description (more like RMW?) @@ -1052,11 +1052,38 @@ void imagetek_i4100_device::draw_tilemap( screen_device &screen, bitmap_ind16 &b int windowwidth = width >> 2; int windowheight = height >> 3; + + int dx = m_tilemap_scrolldx[layer] * (m_screen_flip ? 1 : -1); + int dy = m_tilemap_scrolldy[layer] * (m_screen_flip ? 1 : -1); - sx += m_tilemap_scrolldx[layer] * (m_screen_flip ? 1 : -1); - sy += m_tilemap_scrolldy[layer] * (m_screen_flip ? 1 : -1); + sx += dx; + sy += dy; - for (y = 0; y < scrheight; y++) + int min_x, max_x, min_y, max_y; + + if (dx != 0) + { + min_x = 0; + max_x = scrwidth-1; + } + else + { + min_x = cliprect.min_x; + max_x = cliprect.max_x; + } + + if (dy != 0) + { + min_y = 0; + max_y = scrheight-1; + } + else + { + min_y = cliprect.min_y; + max_y = cliprect.max_y; + } + + for (y = min_y; y <= max_y; y++) { int scrolly = (sy+y-wy)&(windowheight-1); int x; @@ -1070,7 +1097,7 @@ void imagetek_i4100_device::draw_tilemap( screen_device &screen, bitmap_ind16 &b dst = &bitmap.pix16(y); priority_baseaddr = &priority_bitmap.pix8(y); - for (x = 0; x < scrwidth; x++) + for (x = min_x; x <= max_x; x++) { int scrollx = (sx+x-wx)&(windowwidth-1); int srccol = (wx+scrollx)&(width-1); @@ -1094,7 +1121,7 @@ void imagetek_i4100_device::draw_tilemap( screen_device &screen, bitmap_ind16 &b dst = &bitmap.pix16(scrheight-y-1); priority_baseaddr = &priority_bitmap.pix8(scrheight-y-1); - for (x = 0; x < scrwidth; x++) + for (x = min_x; x <= max_x; x++) { int scrollx = (sx+x-wx)&(windowwidth-1); int srccol = (wx+scrollx)&(width-1); diff --git a/src/mame/drivers/hyprduel.cpp b/src/mame/drivers/hyprduel.cpp index d28c9e238f2..bdb5c5c49a2 100644 --- a/src/mame/drivers/hyprduel.cpp +++ b/src/mame/drivers/hyprduel.cpp @@ -37,16 +37,81 @@ fix comms so it boots, it's a bit of a hack for hyperduel at the moment ;-) ***************************************************************************/ #include "emu.h" -#include "includes/hyprduel.h" #include "cpu/m68000/m68000.h" +#include "machine/timer.h" #include "sound/okim6295.h" #include "sound/ym2151.h" #include "sound/ym2413.h" +#include "video/imagetek_i4100.h" +#include "screen.h" #include "speaker.h" +#define RASTER_LINES 262 +#define FIRST_VISIBLE_LINE 0 +#define LAST_VISIBLE_LINE 223 + +class hyprduel_state : public driver_device +{ +public: + hyprduel_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_irq_enable(*this, "irq_enable") + , m_sharedram(*this, "sharedram%u", 1) + , m_maincpu(*this, "maincpu") + , m_subcpu(*this, "sub") + , m_vdp(*this, "vdp") + { } + + DECLARE_READ16_MEMBER(irq_cause_r); + DECLARE_WRITE16_MEMBER(irq_cause_w); + DECLARE_WRITE16_MEMBER(subcpu_control_w); + DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger1_r); + DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger1_w); + DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger2_r); + DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger2_w); + DECLARE_DRIVER_INIT(magerror); + DECLARE_DRIVER_INIT(hyprduel); + DECLARE_MACHINE_START(hyprduel); + DECLARE_MACHINE_START(magerror); + TIMER_CALLBACK_MEMBER(vblank_end_callback); + DECLARE_WRITE_LINE_MEMBER(vdp_blit_end_w); + TIMER_DEVICE_CALLBACK_MEMBER(interrupt); + + void magerror(machine_config &config); + void hyprduel(machine_config &config); + void i4220_config(machine_config &config); + void hyprduel_map(address_map &map); + void hyprduel_map2(address_map &map); + void magerror_map(address_map &map); + void magerror_map2(address_map &map); +protected: + virtual void machine_reset() override; + +private: + /* memory pointers */ + required_shared_ptr m_irq_enable; + required_shared_ptr_array m_sharedram; + + /* misc */ + emu_timer *m_vblank_end_timer; + int m_blitter_bit; + int m_requested_int; + int m_subcpu_resetline; + int m_cpu_trigger; + int m_int_num; + + /* devices */ + required_device m_maincpu; + required_device m_subcpu; + required_device m_vdp; + + void update_irq_state( ); +}; + + /*************************************************************************** Interrupts ***************************************************************************/ @@ -139,14 +204,14 @@ READ16_MEMBER(hyprduel_state::hyprduel_cpusync_trigger1_r) m_cpu_trigger = 0; } - return m_sharedram1[0x000408 / 2 + offset]; + return m_sharedram[0][0x000408 / 2 + offset]; } WRITE16_MEMBER(hyprduel_state::hyprduel_cpusync_trigger1_w) { - COMBINE_DATA(&m_sharedram1[0x00040e / 2 + offset]); + COMBINE_DATA(&m_sharedram[0][0x00040e / 2 + offset]); - if (((m_sharedram1[0x00040e / 2] << 16) + m_sharedram1[0x000410 / 2]) != 0x00) + if (((m_sharedram[0][0x00040e / 2] << 16) + m_sharedram[0][0x000410 / 2]) != 0x00) { if (!m_cpu_trigger && !m_subcpu_resetline) { @@ -165,12 +230,12 @@ READ16_MEMBER(hyprduel_state::hyprduel_cpusync_trigger2_r) m_cpu_trigger = 0; } - return m_sharedram3[(0xfff34c - 0xfe4000) / 2 + offset]; + return m_sharedram[2][(0xfff34c - 0xfe4000) / 2 + offset]; } WRITE16_MEMBER(hyprduel_state::hyprduel_cpusync_trigger2_w) { - COMBINE_DATA(&m_sharedram1[0x000408 / 2 + offset]); + COMBINE_DATA(&m_sharedram[0][0x000408 / 2 + offset]); if (ACCESSING_BITS_8_15) { @@ -182,260 +247,21 @@ WRITE16_MEMBER(hyprduel_state::hyprduel_cpusync_trigger2_w) } } - -TIMER_CALLBACK_MEMBER(hyprduel_state::magerror_irq_callback) -{ - m_subcpu->set_input_line(1, HOLD_LINE); -} - -/*************************************************************************** - Banked ROM access -***************************************************************************/ - -/* - The main CPU has access to the ROMs that hold the graphics through - a banked window of 64k. Those ROMs also usually store the tables for - the virtual tiles set. The tile codes to be written to the tilemap - memory to render the backgrounds are also stored here, in a format - that the blitter can readily use (which is a form of compression) -*/ - -READ16_MEMBER(hyprduel_state::bankedrom_r) -{ - uint8_t *ROM = memregion("gfx1")->base(); - size_t len = memregion("gfx1")->bytes(); - - offset = offset * 2 + 0x10000 * (*m_rombank); - - if (offset < len) - return ((ROM[offset + 0] << 8) + ROM[offset + 1]); - else - return 0xffff; -} - -/*************************************************************************** - - Blitter - - [ Registers ] - - Offset: Value: - - 0.l Destination Tilemap (1,2,3) - 4.l Blitter Data Address (byte offset into the gfx ROMs) - 8.l Destination Address << 7 (byte offset into the tilemap) - - The Blitter reads a byte and looks at the most significative - bits for the opcode, while the remaining bits define a value - (usually how many bytes to write). The opcode byte may be - followed by a number of other bytes: - - 76------ Opcode - --543210 N - (at most N+1 bytes follow) - - - The blitter is designed to write every other byte (e.g. it - writes a byte and skips the next). Hence 2 blits are needed - to fill a tilemap (first even, then odd addresses) - - [ Opcodes ] - - 0 Copy the following N+1 bytes. If the whole byte - is $00: stop and generate an IRQ - - 1 Fill N+1 bytes with a sequence, starting with - the value in the following byte - - 2 Fill N+1 bytes with the value in the following - byte - - 3 Skip N+1 bytes. If the whole byte is $C0: - skip to the next row of the tilemap (+0x200 bytes) - but preserve the column passed at the start of the - blit (destination address % 0x200) - -***************************************************************************/ - -TIMER_CALLBACK_MEMBER(hyprduel_state::blit_done) +WRITE_LINE_MEMBER(hyprduel_state::vdp_blit_end_w) { m_requested_int |= 1 << m_blitter_bit; update_irq_state(); } -inline int hyprduel_state::blt_read( const uint8_t *ROM, const int offs ) -{ - return ROM[offs]; -} - -void hyprduel_state::blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ) -{ - switch( tmap ) - { - case 1: vram_0_w(space, offs,data,mask); break; - case 2: vram_1_w(space, offs, data, mask); break; - case 3: vram_2_w(space, offs, data, mask); break; - } -// logerror("%s : Blitter %X] %04X <- %04X & %04X\n", machine().describe_context(), tmap, offs, data, mask); -} - - -WRITE16_MEMBER(hyprduel_state::blitter_w) -{ - COMBINE_DATA(&m_blitter_regs[offset]); - - if (offset == 0xc / 2) - { - uint8_t *src = memregion("gfx1")->base(); - size_t src_len = memregion("gfx1")->bytes(); - - uint32_t tmap = (m_blitter_regs[0x00 / 2] << 16) + m_blitter_regs[0x02 / 2]; - uint32_t src_offs = (m_blitter_regs[0x04 / 2] << 16) + m_blitter_regs[0x06 / 2]; - uint32_t dst_offs = (m_blitter_regs[0x08 / 2] << 16) + m_blitter_regs[0x0a / 2]; - - int shift = (dst_offs & 0x80) ? 0 : 8; - uint16_t mask = (dst_offs & 0x80) ? 0x00ff : 0xff00; - -// logerror("CPU #0 PC %06X : Blitter regs %08X, %08X, %08X\n", m_maincpu->pc(), tmap, src_offs, dst_offs); - - dst_offs >>= 7 + 1; - switch (tmap) - { - case 1: - case 2: - case 3: - break; - default: - logerror("CPU #0 PC %06X : Blitter unknown destination: %08X\n", m_maincpu->pc(), tmap); - return; - } - - while (1) - { - uint16_t b1, b2, count; - - src_offs %= src_len; - b1 = blt_read(src, src_offs); -// logerror("CPU #0 PC %06X : Blitter opcode %02X at %06X\n", m_maincpu->pc(), b1, src_offs); - src_offs++; - - count = ((~b1) & 0x3f) + 1; - - switch ((b1 & 0xc0) >> 6) - { - case 0: - - /* Stop and Generate an IRQ. We can't generate it now - both because it's unlikely that the blitter is so - fast and because some games (e.g. lastfort) need to - complete the blitter irq service routine before doing - another blit. */ - if (b1 == 0) - { - m_blit_done_timer->adjust(attotime::from_usec(500)); - return; - } - - /* Copy */ - while (count--) - { - src_offs %= src_len; - b2 = blt_read(src, src_offs) << shift; - src_offs++; - - dst_offs &= 0xffff; - blt_write(space, tmap, dst_offs, b2, mask); - dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); - } - break; - - - case 1: - - /* Fill with an increasing value */ - src_offs %= src_len; - b2 = blt_read(src, src_offs); - src_offs++; - - while (count--) - { - dst_offs &= 0xffff; - blt_write(space, tmap, dst_offs, b2 << shift, mask); - dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); - b2++; - } - break; - - - case 2: - - /* Fill with a fixed value */ - src_offs %= src_len; - b2 = blt_read(src, src_offs) << shift; - src_offs++; - - while (count--) - { - dst_offs &= 0xffff; - blt_write(space, tmap, dst_offs, b2, mask); - dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); - } - break; - - - case 3: - - /* Skip to the next line ?? */ - if (b1 == 0xC0) - { - dst_offs += 0x100; - dst_offs &= ~(0x100 - 1); - dst_offs |= (0x100 - 1) & (m_blitter_regs[0x0a / 2] >> (7 + 1)); - } - else - { - dst_offs += count; - } - break; - - - default: - logerror("CPU #0 PC %06X : Blitter unknown opcode %02X at %06X\n", m_maincpu->pc(), b1, src_offs - 1); - return; - } - - } - } - -} - /*************************************************************************** Memory Maps ***************************************************************************/ ADDRESS_MAP_START(hyprduel_state::hyprduel_map) AM_RANGE(0x000000, 0x07ffff) AM_ROM - AM_RANGE(0x400000, 0x41ffff) AM_RAM_WRITE(vram_0_w) AM_SHARE("vram_0") /* Layer 0 */ - AM_RANGE(0x420000, 0x43ffff) AM_RAM_WRITE(vram_1_w) AM_SHARE("vram_1") /* Layer 1 */ - AM_RANGE(0x440000, 0x45ffff) AM_RAM_WRITE(vram_2_w) AM_SHARE("vram_2") /* Layer 2 */ - AM_RANGE(0x460000, 0x46ffff) AM_READ(bankedrom_r) /* Banked ROM */ - AM_RANGE(0x470000, 0x473fff) AM_RAM_WRITE(paletteram_w) AM_SHARE("paletteram") /* Palette */ - AM_RANGE(0x474000, 0x474fff) AM_RAM AM_SHARE("spriteram") /* Sprites */ - AM_RANGE(0x475000, 0x477fff) AM_RAM /* only used memory test */ - AM_RANGE(0x478000, 0x4787ff) AM_RAM AM_SHARE("tiletable") /* Tiles Set */ - AM_RANGE(0x478840, 0x47884d) AM_WRITE(blitter_w) AM_SHARE("blitter_regs") /* Tiles Blitter */ - AM_RANGE(0x478850, 0x478853) AM_RAM AM_SHARE("spriteregs") - AM_RANGE(0x478860, 0x47886b) AM_WRITE(window_w) AM_SHARE("window") /* Tilemap Window */ - AM_RANGE(0x478870, 0x47887b) AM_RAM_WRITE(scrollreg_w) AM_SHARE("scroll") /* Scroll Regs */ - AM_RANGE(0x47887c, 0x47887d) AM_WRITE(scrollreg_init_w) - AM_RANGE(0x478880, 0x478881) AM_WRITENOP - AM_RANGE(0x478890, 0x478891) AM_WRITENOP - AM_RANGE(0x4788a0, 0x4788a1) AM_WRITENOP + AM_RANGE(0x400000, 0x47ffff) AM_DEVICE("vdp", imagetek_i4220_device, v2_map) AM_RANGE(0x4788a2, 0x4788a3) AM_READWRITE(irq_cause_r, irq_cause_w) /* IRQ Cause,Acknowledge */ AM_RANGE(0x4788a4, 0x4788a5) AM_RAM AM_SHARE("irq_enable") /* IRQ Enable */ - AM_RANGE(0x4788aa, 0x4788ab) AM_RAM AM_SHARE("rombank") /* Rom Bank */ - AM_RANGE(0x4788ac, 0x4788ad) AM_RAM AM_SHARE("screenctrl") /* Screen Control */ - AM_RANGE(0x479700, 0x479713) AM_RAM AM_SHARE("videoregs") /* Video Registers */ AM_RANGE(0x800000, 0x800001) AM_WRITE(subcpu_control_w) AM_RANGE(0xc00000, 0xc07fff) AM_RAM AM_SHARE("sharedram1") AM_RANGE(0xe00000, 0xe00001) AM_READ_PORT("SERVICE") AM_WRITENOP @@ -449,7 +275,7 @@ ADDRESS_MAP_END ADDRESS_MAP_START(hyprduel_state::hyprduel_map2) AM_RANGE(0x000000, 0x003fff) AM_RAM AM_SHARE("sharedram1") /* shadow ($c00000 - $c03fff : vector) */ AM_RANGE(0x004000, 0x007fff) AM_READONLY AM_WRITENOP AM_SHARE("sharedram3") /* shadow ($fe4000 - $fe7fff : read only) */ - AM_RANGE(0x400000, 0x400003) AM_DEVREADWRITE8("ymsnd", ym2151_device, read, write, 0x00ff ) + AM_RANGE(0x400000, 0x400003) AM_DEVREADWRITE8("ymsnd", ym2151_device, read, write, 0x00ff) AM_RANGE(0x400004, 0x400005) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) AM_RANGE(0x800000, 0x800001) AM_NOP AM_RANGE(0xc00000, 0xc07fff) AM_RAM AM_SHARE("sharedram1") @@ -463,27 +289,9 @@ ADDRESS_MAP_END ADDRESS_MAP_START(hyprduel_state::magerror_map) AM_RANGE(0x000000, 0x07ffff) AM_ROM AM_RANGE(0x400000, 0x400001) AM_WRITE(subcpu_control_w) - AM_RANGE(0x800000, 0x81ffff) AM_RAM_WRITE(vram_0_w) AM_SHARE("vram_0") /* Layer 0 */ - AM_RANGE(0x820000, 0x83ffff) AM_RAM_WRITE(vram_1_w) AM_SHARE("vram_1") /* Layer 1 */ - AM_RANGE(0x840000, 0x85ffff) AM_RAM_WRITE(vram_2_w) AM_SHARE("vram_2") /* Layer 2 */ - AM_RANGE(0x860000, 0x86ffff) AM_READ(bankedrom_r) /* Banked ROM */ - AM_RANGE(0x870000, 0x873fff) AM_RAM_WRITE(paletteram_w) AM_SHARE("paletteram") /* Palette */ - AM_RANGE(0x874000, 0x874fff) AM_RAM AM_SHARE("spriteram") /* Sprites */ - AM_RANGE(0x875000, 0x877fff) AM_RAM /* only used memory test */ - AM_RANGE(0x878000, 0x8787ff) AM_RAM AM_SHARE("tiletable") /* Tiles Set */ - AM_RANGE(0x878840, 0x87884d) AM_WRITE(blitter_w) AM_SHARE("blitter_regs") /* Tiles Blitter */ - AM_RANGE(0x878850, 0x878853) AM_RAM AM_SHARE("spriteregs") - AM_RANGE(0x878860, 0x87886b) AM_WRITE(window_w) AM_SHARE("window") /* Tilemap Window */ - AM_RANGE(0x878870, 0x87887b) AM_RAM_WRITE(scrollreg_w) AM_SHARE("scroll") /* Scroll Regs */ - AM_RANGE(0x87887c, 0x87887d) AM_WRITE(scrollreg_init_w) - AM_RANGE(0x878880, 0x878881) AM_WRITENOP - AM_RANGE(0x878890, 0x878891) AM_WRITENOP - AM_RANGE(0x8788a0, 0x8788a1) AM_WRITENOP + AM_RANGE(0x800000, 0x87ffff) AM_DEVICE("vdp", imagetek_i4220_device, v2_map) AM_RANGE(0x8788a2, 0x8788a3) AM_READWRITE(irq_cause_r, irq_cause_w) /* IRQ Cause, Acknowledge */ AM_RANGE(0x8788a4, 0x8788a5) AM_RAM AM_SHARE("irq_enable") /* IRQ Enable */ - AM_RANGE(0x8788aa, 0x8788ab) AM_RAM AM_SHARE("rombank") /* Rom Bank */ - AM_RANGE(0x8788ac, 0x8788ad) AM_RAM AM_SHARE("screenctrl") /* Screen Control */ - AM_RANGE(0x879700, 0x879713) AM_RAM AM_SHARE("videoregs") /* Video Registers */ AM_RANGE(0xc00000, 0xc1ffff) AM_RAM AM_SHARE("sharedram1") AM_RANGE(0xe00000, 0xe00001) AM_READ_PORT("SERVICE") AM_WRITENOP AM_RANGE(0xe00002, 0xe00003) AM_READ_PORT("DSW") @@ -611,11 +419,28 @@ static const gfx_layout layout_8x8x4 = }; /* 8x8x8 tiles for later games */ -static GFXLAYOUT_RAW( layout_8x8x8h, 8, 8, 8*8, 32*8 ) +static GFXLAYOUT_RAW( layout_8x8x8, 8, 8, 8*8, 32*8 ) -static GFXDECODE_START( 14220 ) - GFXDECODE_ENTRY( "gfx1", 0, layout_8x8x4, 0x0, 0x200 ) // [0] 4 Bit Tiles - GFXDECODE_ENTRY( "gfx1", 0, layout_8x8x8h, 0x0, 0x20 ) // [1] 8 Bit Tiles +/* 16x16x4 tiles for later games */ +static const gfx_layout layout_16x16x4 = +{ + 16,16, + RGN_FRAC(1,1), + 4, + { STEP4(0,1) }, + { 4*1,4*0, 4*3,4*2, 4*5,4*4, 4*7,4*6, 4*9,4*8, 4*11,4*10, 4*13,4*12, 4*15,4*14 }, + { STEP16(0,4*16) }, + 4*8*8 +}; + +/* 16x16x8 tiles for later games */ +static GFXLAYOUT_RAW( layout_16x16x8, 16, 16, 16*8, 32*8 ) + +static GFXDECODE_START( i4220 ) + GFXDECODE_ENTRY( "gfx1", 0, layout_8x8x4, 0x0, 0x100 ) // [0] 4 Bit Tiles + GFXDECODE_ENTRY( "gfx1", 0, layout_8x8x8, 0x0, 0x10 ) // [1] 8 Bit Tiles + GFXDECODE_ENTRY( "gfx1", 0, layout_16x16x4, 0x0, 0x100 ) // [2] 4 Bit Tiles 16x16 + GFXDECODE_ENTRY( "gfx1", 0, layout_16x16x8, 0x0, 0x10 ) // [3] 8 Bit Tiles 16x16 GFXDECODE_END /*************************************************************************** @@ -641,15 +466,25 @@ MACHINE_START_MEMBER(hyprduel_state,hyprduel) save_item(NAME(m_subcpu_resetline)); save_item(NAME(m_cpu_trigger)); - m_blit_done_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hyprduel_state::blit_done), this)); m_vblank_end_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hyprduel_state::vblank_end_callback), this)); } -MACHINE_START_MEMBER(hyprduel_state,magerror) -{ - MACHINE_START_CALL_MEMBER(hyprduel); - m_magerror_irq_timer->adjust(attotime::zero, 0, attotime::from_hz(968)); /* tempo? */ -} +MACHINE_CONFIG_START(hyprduel_state::i4220_config) + MCFG_DEVICE_ADD("vdp", I4220, XTAL(26'666'000)) + MCFG_I4100_GFXDECODE("gfxdecode") + MCFG_I4100_BLITTER_END_CALLBACK(WRITELINE(hyprduel_state,vdp_blit_end_w)) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_SCANLINE) + MCFG_SCREEN_REFRESH_RATE(60) // Unknown/Unverified + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_SIZE(320, 224) + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, FIRST_VISIBLE_LINE, LAST_VISIBLE_LINE) + MCFG_SCREEN_UPDATE_DEVICE("vdp", imagetek_i4100_device, screen_update) + MCFG_SCREEN_PALETTE(":vdp:palette") + + MCFG_GFXDECODE_ADD("gfxdecode", ":vdp:palette", i4220) +MACHINE_CONFIG_END MACHINE_CONFIG_START(hyprduel_state::hyprduel) @@ -664,31 +499,17 @@ MACHINE_CONFIG_START(hyprduel_state::hyprduel) MCFG_MACHINE_START_OVERRIDE(hyprduel_state,hyprduel) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_SCANLINE) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, FIRST_VISIBLE_LINE, LAST_VISIBLE_LINE) - MCFG_SCREEN_UPDATE_DRIVER(hyprduel_state, screen_update) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", 14220) - MCFG_PALETTE_ADD("palette", 8192) - - MCFG_VIDEO_START_OVERRIDE(hyprduel_state,hyprduel_14220) + i4220_config(config); /* sound hardware */ - MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") + MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_YM2151_ADD("ymsnd", 4000000) MCFG_YM2151_IRQ_HANDLER(INPUTLINE("sub", 1)) - MCFG_SOUND_ROUTE(0, "lspeaker", 0.80) - MCFG_SOUND_ROUTE(1, "rspeaker", 0.80) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) MCFG_OKIM6295_ADD("oki", 4000000/16/16*132, PIN7_HIGH) // clock frequency & pin 7 not verified - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.57) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.57) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.57) MACHINE_CONFIG_END @@ -701,34 +522,21 @@ MACHINE_CONFIG_START(hyprduel_state::magerror) MCFG_CPU_ADD("sub", M68000,20000000/2) /* 10MHz */ MCFG_CPU_PROGRAM_MAP(magerror_map2) + MCFG_CPU_PERIODIC_INT_DRIVER(hyprduel_state, irq1_line_hold, 968) /* tempo? */ - MCFG_MACHINE_START_OVERRIDE(hyprduel_state,magerror) + MCFG_MACHINE_START_OVERRIDE(hyprduel_state,hyprduel) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_SCANLINE) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, FIRST_VISIBLE_LINE, LAST_VISIBLE_LINE) - MCFG_SCREEN_UPDATE_DRIVER(hyprduel_state, screen_update) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", 14220) - MCFG_PALETTE_ADD("palette", 8192) - - MCFG_VIDEO_START_OVERRIDE(hyprduel_state,magerror_14220) + i4220_config(config); /* sound hardware */ - MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") + MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("ymsnd", YM2413, 3579545) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.00) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.00) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MCFG_OKIM6295_ADD("oki", 4000000/16/16*132, PIN7_HIGH) // clock frequency & pin 7 not verified - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.57) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.57) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.57) MACHINE_CONFIG_END /*************************************************************************** @@ -795,7 +603,6 @@ DRIVER_INIT_MEMBER(hyprduel_state,hyprduel) DRIVER_INIT_MEMBER(hyprduel_state,magerror) { m_int_num = 0x01; - m_magerror_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hyprduel_state::magerror_irq_callback),this)); } diff --git a/src/mame/includes/hyprduel.h b/src/mame/includes/hyprduel.h deleted file mode 100644 index 54630d8066e..00000000000 --- a/src/mame/includes/hyprduel.h +++ /dev/null @@ -1,137 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Luca Elia, Hau - -#include "machine/timer.h" -#include "screen.h" - -#define RASTER_LINES 262 -#define FIRST_VISIBLE_LINE 0 -#define LAST_VISIBLE_LINE 223 - -class hyprduel_state : public driver_device -{ -public: - hyprduel_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_vram_0(*this, "vram_0"), - m_vram_1(*this, "vram_1"), - m_vram_2(*this, "vram_2"), - m_paletteram(*this, "paletteram"), - m_spriteram(*this, "spriteram"), - m_spriteregs(*this, "spriteregs"), - m_tiletable(*this, "tiletable"), - m_blitter_regs(*this, "blitter_regs"), - m_window(*this, "window"), - m_scroll(*this, "scroll"), - m_irq_enable(*this, "irq_enable"), - m_rombank(*this, "rombank"), - m_screenctrl(*this, "screenctrl"), - m_videoregs(*this, "videoregs"), - m_sharedram1(*this, "sharedram1"), - m_sharedram3(*this, "sharedram3"), - m_maincpu(*this, "maincpu"), - m_subcpu(*this, "sub"), - m_gfxdecode(*this, "gfxdecode"), - m_screen(*this, "screen"), - m_palette(*this, "palette") { } - - DECLARE_READ16_MEMBER(irq_cause_r); - DECLARE_WRITE16_MEMBER(irq_cause_w); - DECLARE_WRITE16_MEMBER(subcpu_control_w); - DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger1_r); - DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger1_w); - DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger2_r); - DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger2_w); - DECLARE_READ16_MEMBER(bankedrom_r); - DECLARE_WRITE16_MEMBER(blitter_w); - DECLARE_WRITE16_MEMBER(paletteram_w); - DECLARE_WRITE16_MEMBER(vram_0_w); - DECLARE_WRITE16_MEMBER(vram_1_w); - DECLARE_WRITE16_MEMBER(vram_2_w); - DECLARE_WRITE16_MEMBER(window_w); - DECLARE_WRITE16_MEMBER(scrollreg_w); - DECLARE_WRITE16_MEMBER(scrollreg_init_w); - DECLARE_DRIVER_INIT(magerror); - DECLARE_DRIVER_INIT(hyprduel); - TILE_GET_INFO_MEMBER(get_tile_info_0_8bit); - TILE_GET_INFO_MEMBER(get_tile_info_1_8bit); - TILE_GET_INFO_MEMBER(get_tile_info_2_8bit); - DECLARE_MACHINE_START(hyprduel); - DECLARE_VIDEO_START(hyprduel_14220); - DECLARE_MACHINE_START(magerror); - DECLARE_VIDEO_START(magerror_14220); - DECLARE_VIDEO_START(common_14220); - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(vblank_end_callback); - TIMER_CALLBACK_MEMBER(magerror_irq_callback); - TIMER_CALLBACK_MEMBER(blit_done); - TIMER_DEVICE_CALLBACK_MEMBER(interrupt); - - void magerror(machine_config &config); - void hyprduel(machine_config &config); - void hyprduel_map(address_map &map); - void hyprduel_map2(address_map &map); - void magerror_map(address_map &map); - void magerror_map2(address_map &map); -protected: - virtual void machine_reset() override; - -private: - /* memory pointers */ - required_shared_ptr m_vram_0; - required_shared_ptr m_vram_1; - required_shared_ptr m_vram_2; - required_shared_ptr m_paletteram; - required_shared_ptr m_spriteram; - required_shared_ptr m_spriteregs; - required_shared_ptr m_tiletable; - required_shared_ptr m_blitter_regs; - required_shared_ptr m_window; - required_shared_ptr m_scroll; - required_shared_ptr m_irq_enable; - required_shared_ptr m_rombank; - required_shared_ptr m_screenctrl; - required_shared_ptr m_videoregs; - required_shared_ptr m_sharedram1; - required_shared_ptr m_sharedram3; - std::unique_ptr m_tiletable_old; - - /* video-related */ - tilemap_t *m_bg_tilemap[3]; - std::unique_ptr m_empty_tiles; - std::unique_ptr m_dirtyindex; - int m_sprite_xoffs; - int m_sprite_yoffs; - std::unique_ptr m_expanded_gfx1; - - /* misc */ - emu_timer *m_magerror_irq_timer; - emu_timer *m_vblank_end_timer; - emu_timer *m_blit_done_timer; - int m_blitter_bit; - int m_requested_int; - int m_subcpu_resetline; - int m_cpu_trigger; - int m_int_num; - - /* devices */ - required_device m_maincpu; - required_device m_subcpu; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - - void postload(); - inline void get_tile_info( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram); - inline void get_tile_info_8bit( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram ); - inline void get_tile_info_16x16_8bit( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram ); - inline void vram_w( offs_t offset, uint16_t data, uint16_t mem_mask, int layer, uint16_t *vram ); - void alloc_empty_tiles( ); - void expand_gfx1( ); - void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ); - void draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, int layers_ctrl ); - void dirty_tiles( int layer, uint16_t *vram ); - void update_irq_state( ); - inline int blt_read( const uint8_t *ROM, const int offs ); - void blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ); -}; diff --git a/src/mame/video/hyprduel.cpp b/src/mame/video/hyprduel.cpp deleted file mode 100644 index a5dfa1b7417..00000000000 --- a/src/mame/video/hyprduel.cpp +++ /dev/null @@ -1,730 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Luca Elia, Hau - -/* based on driver from video/metro.c by Luca Elia */ -/* modified by Hau */ - -/*************************************************************************** - - -= Metro Games =- - - driver by Luca Elia (l.elia@tin.it) - - -Note: if MAME_DEBUG is defined, pressing Z with: - - Q Shows Layer 0 - W Shows Layer 1 - E Shows Layer 2 - A Shows Sprites - - Keys can be used together! - - - [ 3 Scrolling Layers ] - - There is memory for a huge layer, but the actual tilemap - is a smaller window (of fixed size) carved from anywhere - inside that layer. - - Tile Size: 8 x 8 x 4 - (later games can switch to 8 x 8 x 8, 16 x 16 x 4/8 at run time) - - Big Layer Size: 2048 x 2048 (8x8 tiles) or 4096 x 4096 (16x16 tiles) - - Tilemap Window Size: 512 x 256 (8x8 tiles) or 1024 x 512 (16x16 tiles) - - The tile codes in memory do not map directly to tiles. They - are indexes into a table (with 0x200 entries) that defines - a virtual set of tiles for the 3 layers. Each entry in that - table adds 16 tiles to the set of available tiles, and decides - their color code. - - Tile code with their msbit set are different as they mean: - draw a tile filled with a single color (0-1ff) - - - [ 512 Zooming Sprites ] - - The sprites are NOT tile based: the "tile" size can vary from - 8 to 64 (independently for width and height) with an 8 pixel - granularity. The "tile" address is a multiple of 8x8 pixels. - - Each sprite can be shrinked to ~1/4 or enlarged to ~32x following - an exponential curve of sizes (with one zoom value for both width - and height) - -***************************************************************************/ - -#include "emu.h" -#include "includes/hyprduel.h" - -/*************************************************************************** - Palette GGGGGRRRRRBBBBBx -***************************************************************************/ - -WRITE16_MEMBER(hyprduel_state::paletteram_w) -{ - data = COMBINE_DATA(&m_paletteram[offset]); - m_palette->set_pen_color(offset, pal5bit(data >> 6), pal5bit(data >> 11), pal5bit(data >> 1)); -} - - -/*************************************************************************** - Tilemaps: Tiles Set & Window - - Each entry in the Tiles Set RAM uses 2 words to specify a starting - tile code and a color code. This adds 16 consecutive tiles with - that color code to the set of available tiles. - - Offset: Bits: Value: - - 0.w fedc ---- ---- ---- - ---- ba98 7654 ---- Color Code - ---- ---- ---- 3210 Code High Bits - - 2.w Code Low Bits -***************************************************************************/ - - -/*************************************************************************** - Tilemaps: Rendering -***************************************************************************/ - -/* A 2048 x 2048 virtual tilemap */ - -#define BIG_NX (0x100) -#define BIG_NY (0x100) - -/* A smaller 512 x 256 window defines the actual tilemap */ - -#define WIN_NX (0x40) -#define WIN_NY (0x20) -//#define WIN_NX (0x40+1) -//#define WIN_NY (0x20+1) - - -/* 8x8x4 tiles only */ -inline void hyprduel_state::get_tile_info( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram) -{ - uint16_t code; - int table_index; - uint32_t tile; - - /* The actual tile index depends on the window */ - tile_index = ((tile_index / WIN_NX + m_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX + - ((tile_index % WIN_NX + m_window[layer * 2 + 1] / 8) % BIG_NX); - - /* Fetch the code */ - code = vram[tile_index]; - - /* Use it as an index into the tiles set table */ - table_index = ((code & 0x1ff0) >> 4 ) * 2; - tile = (m_tiletable[table_index + 0] << 16) + m_tiletable[table_index + 1]; - - if (code & 0x8000) /* Special: draw a tile of a single color (i.e. not from the gfx ROMs) */ - { - int _code = code & 0x000f; - tileinfo.pen_data = m_empty_tiles.get() + _code * 16 * 16; - tileinfo.palette_base = ((code & 0x0ff0)) + 0x1000; - tileinfo.flags = 0; - tileinfo.group = 0; - } - else - { - tileinfo.group = 0; - SET_TILE_INFO_MEMBER(0, - (tile & 0xfffff) + (code & 0xf), - (((tile & 0x0ff00000) >> 20)) + 0x100, - TILE_FLIPXY((code & 0x6000) >> 13)); - } -} - -/* 8x8x4 or 8x8x8 tiles. It's the tile's color that decides: if its low 4 - bits are high ($f,$1f,$2f etc) the tile is 8bpp, otherwise it's 4bpp */ -inline void hyprduel_state::get_tile_info_8bit( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram ) -{ - uint16_t code; - int table_index; - uint32_t tile; - - /* The actual tile index depends on the window */ - tile_index = ((tile_index / WIN_NX + m_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX + - ((tile_index % WIN_NX + m_window[layer * 2 + 1] / 8) % BIG_NX); - - /* Fetch the code */ - code = vram[tile_index]; - - /* Use it as an index into the tiles set table */ - table_index = ((code & 0x1ff0) >> 4) * 2; - tile = (m_tiletable[table_index + 0] << 16) + m_tiletable[table_index + 1]; - - if (code & 0x8000) /* Special: draw a tile of a single color (i.e. not from the gfx ROMs) */ - { - int _code = code & 0x000f; - tileinfo.pen_data = m_empty_tiles.get() + _code * 16 * 16; - tileinfo.palette_base = ((code & 0x0ff0)) + 0x1000; - tileinfo.flags = 0; - tileinfo.group = 0; - } - else if ((tile & 0x00f00000) == 0x00f00000) /* draw tile as 8bpp */ - { - tileinfo.group = 1; - SET_TILE_INFO_MEMBER(1, - (tile & 0xfffff) + 2*(code & 0xf), - ((tile & 0x0f000000) >> 24) + 0x10, - TILE_FLIPXY((code & 0x6000) >> 13)); - } - else - { - tileinfo.group = 0; - SET_TILE_INFO_MEMBER(0, - (tile & 0xfffff) + (code & 0xf), - (((tile & 0x0ff00000) >> 20)) + 0x100, - TILE_FLIPXY((code & 0x6000) >> 13)); - } -} - -/* 16x16x4 or 16x16x8 tiles. It's the tile's color that decides: if its low 4 - bits are high ($f,$1f,$2f etc) the tile is 8bpp, otherwise it's 4bpp */ -inline void hyprduel_state::get_tile_info_16x16_8bit( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram ) -{ - uint16_t code; - int table_index; - uint32_t tile; - - /* The actual tile index depends on the window */ - tile_index = ((tile_index / WIN_NX + m_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX + - ((tile_index % WIN_NX + m_window[layer * 2 + 1] / 8) % BIG_NX); - - /* Fetch the code */ - code = vram[tile_index]; - - /* Use it as an index into the tiles set table */ - table_index = ((code & 0x1ff0) >> 4) * 2; - tile = (m_tiletable[table_index + 0] << 16) + m_tiletable[table_index + 1]; - - if (code & 0x8000) /* Special: draw a tile of a single color (i.e. not from the gfx ROMs) */ - { - int _code = code & 0x000f; - tileinfo.pen_data = m_empty_tiles.get() + _code * 16 * 16; - tileinfo.palette_base = ((code & 0x0ff0)) + 0x1000; - tileinfo.flags = 0; - tileinfo.group = 0; - } - else if ((tile & 0x00f00000) == 0x00f00000) /* draw tile as 8bpp */ - { - tileinfo.group = 1; - SET_TILE_INFO_MEMBER(3, - (tile & 0xfffff) + 8*(code & 0xf), - ((tile & 0x0f000000) >> 24) + 0x10, - TILE_FLIPXY((code & 0x6000) >> 13)); - } - else - { - tileinfo.group = 0; - SET_TILE_INFO_MEMBER(2, - (tile & 0xfffff) + 4*(code & 0xf), - (((tile & 0x0ff00000) >> 20)) + 0x100, - TILE_FLIPXY((code & 0x6000) >> 13)); - - } -} - -inline void hyprduel_state::vram_w( offs_t offset, uint16_t data, uint16_t mem_mask, int layer, uint16_t *vram ) -{ - COMBINE_DATA(&vram[offset]); - { - /* Account for the window */ - int col = (offset % BIG_NX) - ((m_window[layer * 2 + 1] / 8) % BIG_NX); - int row = (offset / BIG_NX) - ((m_window[layer * 2 + 0] / 8) % BIG_NY); - if (col < -(BIG_NX-WIN_NX)) - col += (BIG_NX-WIN_NX) + WIN_NX; - if (row < -(BIG_NY-WIN_NY)) - row += (BIG_NY-WIN_NY) + WIN_NY; - if ((col >= 0) && (col < WIN_NX) && (row >= 0) && (row < WIN_NY)) - m_bg_tilemap[layer]->mark_tile_dirty(row * WIN_NX + col); - } -} - - - -TILE_GET_INFO_MEMBER(hyprduel_state::get_tile_info_0_8bit) -{ - get_tile_info_8bit(tileinfo, tile_index, 0, m_vram_0); -} - -TILE_GET_INFO_MEMBER(hyprduel_state::get_tile_info_1_8bit) -{ - get_tile_info_8bit(tileinfo, tile_index, 1, m_vram_1); -} - -TILE_GET_INFO_MEMBER(hyprduel_state::get_tile_info_2_8bit) -{ - get_tile_info_8bit(tileinfo, tile_index, 2, m_vram_2); -} - -WRITE16_MEMBER(hyprduel_state::vram_0_w) -{ - vram_w(offset, data, mem_mask, 0, m_vram_0); -} - -WRITE16_MEMBER(hyprduel_state::vram_1_w) -{ - vram_w(offset, data, mem_mask, 1, m_vram_1); -} - -WRITE16_MEMBER(hyprduel_state::vram_2_w) -{ - vram_w(offset, data, mem_mask, 2, m_vram_2); -} - - -/* Dirty the relevant tilemap when its window changes */ -WRITE16_MEMBER(hyprduel_state::window_w) -{ - uint16_t olddata = m_window[offset]; - uint16_t newdata = COMBINE_DATA(&m_window[offset]); - if (newdata != olddata) - { - offset /= 2; - m_bg_tilemap[offset]->mark_all_dirty(); - } -} - -/*************************************************************************** - Video Init Routines -***************************************************************************/ - -/* - Sprites are not tile based, so we decode their graphics at runtime. -*/ - -void hyprduel_state::alloc_empty_tiles( ) -{ - int code,i; - - m_empty_tiles = std::make_unique(16*16*16); - save_pointer(NAME(m_empty_tiles.get()), 16*16*16); - - for (code = 0; code < 0x10; code++) - for (i = 0; i < 16 * 16; i++) - m_empty_tiles[16 * 16 * code + i] = code; -} - - -void hyprduel_state::postload() -{ - int i; - - for (i = 0; i < 3; i++) - { - uint16_t wx = m_window[i * 2 + 1]; - uint16_t wy = m_window[i * 2 + 0]; - - m_bg_tilemap[i]->set_scrollx(0, m_scroll[i * 2 + 1] - wx - (wx & 7)); - m_bg_tilemap[i]->set_scrolly(0, m_scroll[i * 2 + 0] - wy - (wy & 7)); - - m_bg_tilemap[i]->mark_all_dirty(); - } -} - - -void hyprduel_state::expand_gfx1() -{ - uint8_t *base_gfx = memregion("gfx1")->base(); - uint32_t length = 2 * memregion("gfx1")->bytes(); - m_expanded_gfx1 = std::make_unique(length); - for (int i = 0; i < length; i += 2) - { - uint8_t src = base_gfx[i / 2]; - m_expanded_gfx1[i+0] = src & 15; - m_expanded_gfx1[i+1] = src >> 4; - } -} - -VIDEO_START_MEMBER(hyprduel_state,common_14220) -{ - expand_gfx1(); - alloc_empty_tiles(); - m_tiletable_old = std::make_unique(m_tiletable.bytes() / 2); - m_dirtyindex = std::make_unique(m_tiletable.bytes() / 4); - - save_pointer(NAME(m_tiletable_old.get()), m_tiletable.bytes() / 2); - save_pointer(NAME(m_dirtyindex.get()), m_tiletable.bytes() / 4); - - m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(hyprduel_state::get_tile_info_0_8bit),this), TILEMAP_SCAN_ROWS, 8, 8, WIN_NX, WIN_NY); - m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(hyprduel_state::get_tile_info_1_8bit),this), TILEMAP_SCAN_ROWS, 8, 8, WIN_NX, WIN_NY); - m_bg_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(hyprduel_state::get_tile_info_2_8bit),this), TILEMAP_SCAN_ROWS, 8, 8, WIN_NX, WIN_NY); - - m_bg_tilemap[0]->map_pen_to_layer(0, 15, TILEMAP_PIXEL_TRANSPARENT); - m_bg_tilemap[0]->map_pen_to_layer(1, 255, TILEMAP_PIXEL_TRANSPARENT); - - m_bg_tilemap[1]->map_pen_to_layer(0, 15, TILEMAP_PIXEL_TRANSPARENT); - m_bg_tilemap[1]->map_pen_to_layer(1, 255, TILEMAP_PIXEL_TRANSPARENT); - - m_bg_tilemap[2]->map_pen_to_layer(0, 15, TILEMAP_PIXEL_TRANSPARENT); - m_bg_tilemap[2]->map_pen_to_layer(1, 255, TILEMAP_PIXEL_TRANSPARENT); - - m_bg_tilemap[0]->set_scrolldx(0, 0); - m_bg_tilemap[1]->set_scrolldx(0, 0); - m_bg_tilemap[2]->set_scrolldx(0, 0); - - /* Set up save state */ - save_item(NAME(m_sprite_xoffs)); - save_item(NAME(m_sprite_yoffs)); - machine().save().register_postload(save_prepost_delegate(FUNC(hyprduel_state::postload), this)); -} - -VIDEO_START_MEMBER(hyprduel_state,hyprduel_14220) -{ - VIDEO_START_CALL_MEMBER(common_14220); -} - -VIDEO_START_MEMBER(hyprduel_state,magerror_14220) -{ - VIDEO_START_CALL_MEMBER(common_14220); -} - -/*************************************************************************** - - Video Registers - - - Offset: Bits: Value: - - 0.w Number Of Sprites To Draw - 2.w f--- ---- ---- ---- Disabled Sprites Layer Priority - -edc ---- ---- ---- - ---- ba-- ---- ---- Sprites Masked Layer - ---- --98 ---- ---- Sprites Priority - ---- ---- 765- ---- - ---- ---- ---4 3210 Sprites Masked Number - 4.w Sprites Y Offset - 6.w Sprites X Offset - 8.w Sprites Color Codes Start - - - - - 10.w fedc ba98 76-- ---- - ---- ---- --54 ---- Layer 2 Priority (3 backmost, 0 frontmost) - ---- ---- ---- 32-- Layer 1 Priority - ---- ---- ---- --10 Layer 0 Priority - - 12.w Backround Color - -***************************************************************************/ - -/*************************************************************************** - - Sprites Drawing - - - Offset: Bits: Value: - - 0.w fedc b--- ---- ---- Priority (0 = Max) - ---- -a98 7654 3210 X - - 2.w fedc ba-- ---- ---- Zoom (Both X & Y) - ---- --98 7654 3210 Y - - 4.w f--- ---- ---- ---- Flip X - -e-- ---- ---- ---- Flip Y - --dc b--- ---- ---- Size X * - ---- -a98 ---- ---- Size Y * - ---- ---- 7654 ---- Color - ---- ---- ---- 3210 Code High Bits ** - - 6.w Code Low Bits ** - -* 8 pixel increments -** 8x8 pixel increments -***************************************************************************/ - -/* Draw sprites */ - -void hyprduel_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) -{ - uint8_t *base_gfx4 = m_expanded_gfx1.get(); - uint8_t *base_gfx8 = memregion("gfx1")->base(); - uint32_t gfx_size = memregion("gfx1")->bytes(); - - int max_x = (m_spriteregs[1]+1) * 2; - int max_y = (m_spriteregs[0]+1) * 2; - - int max_sprites = m_spriteram.bytes() / 8; - int sprites = m_videoregs[0x00 / 2] % max_sprites; - - int color_start = ((m_videoregs[0x08 / 2] & 0xf) << 4) + 0x100; - - int i, j, pri; - static const int primask[4] = { 0x0000, 0xff00, 0xff00|0xf0f0, 0xff00|0xf0f0|0xcccc }; - - uint16_t *src; - int inc; - - if (sprites == 0) - return; - - for (i = 0; i < 0x20; i++) - { - if (!(m_videoregs[0x02 / 2] & 0x8000)) - { - src = m_spriteram + (sprites - 1) * (8 / 2); - inc = -(8 / 2); - } else { - src = m_spriteram; - inc = (8 / 2); - } - - for (j = 0; j < sprites; j++) - { - int x, y, attr, code, color, flipx, flipy, zoom, curr_pri, width, height; - - /* Exponential zoom table extracted from daitoride */ - static const int zoomtable[0x40] = - { - 0xAAC,0x800,0x668,0x554,0x494,0x400,0x390,0x334, - 0x2E8,0x2AC,0x278,0x248,0x224,0x200,0x1E0,0x1C8, - 0x1B0,0x198,0x188,0x174,0x164,0x154,0x148,0x13C, - 0x130,0x124,0x11C,0x110,0x108,0x100,0x0F8,0x0F0, - 0x0EC,0x0E4,0x0DC,0x0D8,0x0D4,0x0CC,0x0C8,0x0C4, - 0x0C0,0x0BC,0x0B8,0x0B4,0x0B0,0x0AC,0x0A8,0x0A4, - 0x0A0,0x09C,0x098,0x094,0x090,0x08C,0x088,0x080, - 0x078,0x070,0x068,0x060,0x058,0x050,0x048,0x040 - }; - - x = src[0]; - curr_pri = (x & 0xf800) >> 11; - - if ((curr_pri == 0x1f) || (curr_pri != i)) - { - src += inc; - continue; - } - - pri = (m_videoregs[0x02 / 2] & 0x0300) >> 8; - - if (!(m_videoregs[0x02 / 2] & 0x8000)) - { - if (curr_pri > (m_videoregs[0x02 / 2] & 0x1f)) - pri = (m_videoregs[0x02 / 2] & 0x0c00) >> 10; - } - - y = src[1]; - attr = src[2]; - code = src[3]; - - flipx = attr & 0x8000; - flipy = attr & 0x4000; - color = (attr & 0xf0) >> 4; - - zoom = zoomtable[(y & 0xfc00) >> 10] << (16 - 8); - - x = (x & 0x07ff) - m_sprite_xoffs; - y = (y & 0x03ff) - m_sprite_yoffs; - - width = (((attr >> 11) & 0x7) + 1) * 8; - height = (((attr >> 8) & 0x7) + 1) * 8; - - uint32_t gfxstart = (8 * 8 * 4 / 8) * (((attr & 0x000f) << 16) + code); - - if (flip_screen()) - { - flipx = !flipx; x = max_x - x - width; - flipy = !flipy; y = max_y - y - height; - } - - if (color == 0xf) /* 8bpp */ - { - /* Bounds checking */ - if ((gfxstart + width * height - 1) >= gfx_size) - continue; - - gfx_element gfx(m_palette, base_gfx8 + gfxstart, width, height, width, m_palette->entries(), 0, 256); - - gfx.prio_zoom_transpen(bitmap,cliprect, - 0, - color_start >> 4, - flipx, flipy, - x, y, - zoom, zoom, - screen.priority(),primask[pri], 255); - } - else - { - /* Bounds checking */ - if ((gfxstart + width / 2 * height - 1) >= gfx_size) - continue; - - gfx_element gfx(m_palette, base_gfx4 + 2 * gfxstart, width, height, width, m_palette->entries(), 0, 16); - - gfx.prio_zoom_transpen(bitmap,cliprect, - 0, - color + color_start, - flipx, flipy, - x, y, - zoom, zoom, - screen.priority(),primask[pri], 15); - } -#if 0 -{ /* Display priority + zoom on each sprite */ - char buf[80]; - sprintf(buf, "%02X %02X",((src[ 0 ] & 0xf800) >> 11)^0x1f,((src[ 1 ] & 0xfc00) >> 10) ); - ui_draw_text(buf, x, y); -} -#endif - src += inc; - } - } -} - -/*************************************************************************** - Screen Drawing -***************************************************************************/ - -WRITE16_MEMBER(hyprduel_state::scrollreg_w) -{ - uint16_t window = m_window[offset]; - - COMBINE_DATA(&m_scroll[offset]); - - if (offset & 0x01) - m_bg_tilemap[offset / 2]->set_scrollx(0, m_scroll[offset] - window - (window & 7)); - else - m_bg_tilemap[offset / 2]->set_scrolly(0, m_scroll[offset] - window - (window & 7)); -} - -WRITE16_MEMBER(hyprduel_state::scrollreg_init_w) -{ - int i; - - for (i = 0; i < 3; i++) - { - uint16_t wx = m_window[i * 2 + 1]; - uint16_t wy = m_window[i * 2 + 0]; - - m_scroll[i * 2 + 1] = data; - m_scroll[i * 2 + 0] = data; - - m_bg_tilemap[i]->set_scrollx(0, data - wx - (wx & 7)); - m_bg_tilemap[i]->set_scrolly(0, data - wy - (wy & 7)); - } -} - - -void hyprduel_state::draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, int layers_ctrl ) -{ - uint16_t layers_pri = m_videoregs[0x10/2]; - int layer; - - /* Draw all the layers with priority == pri */ - for (layer = 2; layer >= 0; layer--) // tilemap[2] below? - { - if ( pri == ((layers_pri >> (layer*2)) & 3) ) - { - if (layers_ctrl & (1 << layer)) // for debug - m_bg_tilemap[layer]->draw(screen, bitmap, cliprect, 0, 1 << (3 - pri)); - } - } -} - -/* Dirty tilemaps when the tiles set changes */ -void hyprduel_state::dirty_tiles( int layer, uint16_t *vram ) -{ - int col, row; - - for (row = 0; row < WIN_NY; row++) - { - for (col = 0; col < WIN_NX; col++) - { - int offset = (col + m_window[layer * 2 + 1] / 8) % BIG_NX + ((row + m_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX; - uint16_t code = vram[offset]; - - if (!(code & 0x8000) && m_dirtyindex[(code & 0x1ff0) >> 4]) - m_bg_tilemap[layer]->mark_tile_dirty(row * WIN_NX + col); - } - } -} - - -uint32_t hyprduel_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int i, pri, layers_ctrl = -1; - uint16_t screenctrl = *m_screenctrl; - - { - int dirty = 0; - - memset(m_dirtyindex.get(), 0, m_tiletable.bytes() / 4); - for (i = 0; i < m_tiletable.bytes() / 4; i++) - { - uint32_t tile_new = (m_tiletable[2 * i + 0] << 16 ) + m_tiletable[2 * i + 1]; - uint32_t tile_old = (m_tiletable_old[2 * i + 0] << 16 ) + m_tiletable_old[2 * i + 1]; - - if ((tile_new ^ tile_old) & 0x0fffffff) - { - m_dirtyindex[i] = 1; - dirty = 1; - } - } - memcpy(m_tiletable_old.get(), m_tiletable, m_tiletable.bytes()); - - if (dirty) - { - dirty_tiles(0, m_vram_0); - dirty_tiles(1, m_vram_1); - dirty_tiles(2, m_vram_2); - } - } - - m_sprite_xoffs = m_videoregs[0x06 / 2] - (m_spriteregs[1]+1); - m_sprite_yoffs = m_videoregs[0x04 / 2] - (m_spriteregs[0]+1); - - /* The background color is selected by a register */ - screen.priority().fill(0, cliprect); - bitmap.fill((m_videoregs[0x12 / 2] & 0x0fff) + 0x1000, cliprect); - - /* Screen Control Register: - - f--- ---- ---- ---- ? - -edc b--- ---- ---- - ---- -a98 ---- ---- ? Leds - ---- ---- 7--- ---- 16x16 Tiles (Layer 2) - ---- ---- -6-- ---- 16x16 Tiles (Layer 1) - ---- ---- --5- ---- 16x16 Tiles (Layer 0) - ---- ---- ---4 32-- - ---- ---- ---- --1- ? Blank Screen - ---- ---- ---- ---0 Flip Screen */ - if (screenctrl & 2) - return 0; - flip_screen_set(screenctrl & 1); - -#if 0 -if (machine().input().code_pressed(KEYCODE_Z)) -{ int msk = 0; - if (machine().input().code_pressed(KEYCODE_Q)) msk |= 0x01; - if (machine().input().code_pressed(KEYCODE_W)) msk |= 0x02; - if (machine().input().code_pressed(KEYCODE_E)) msk |= 0x04; - if (machine().input().code_pressed(KEYCODE_A)) msk |= 0x08; - if (msk != 0) - { - bitmap.fill(0, cliprect); - layers_ctrl &= msk; - } - - popmessage("%x-%x-%x:%04x %04x %04x", - m_videoregs[0x10/2]&3,(m_videoregs[0x10/2] & 0xc) >> 2, (m_videoregs[0x10/2] & 0x30) >> 4, - m_videoregs[0x02/2], m_videoregs[0x08/2], - *m_screenctrl); -} -#endif - - for (pri = 3; pri >= 0; pri--) - draw_layers(screen, bitmap, cliprect, pri, layers_ctrl); - - if (layers_ctrl & 0x08) - draw_sprites(screen, bitmap, cliprect); - - return 0; -}