mirror of
https://github.com/holub/mame
synced 2025-04-16 21:44:32 +03:00
Converted Williams SC1/SC2 blitter to a device. (#13030)
* -williams: Converted SC1/SC2 blitter to a device. [Ryan Holtz] * Flipped some always-present optional finders to required.
This commit is contained in:
parent
e1a3143378
commit
9197eb1445
@ -154,6 +154,8 @@ files{
|
|||||||
MAME_DIR .. "src/mame/shared/s11c_bg.h",
|
MAME_DIR .. "src/mame/shared/s11c_bg.h",
|
||||||
MAME_DIR .. "src/mame/shared/williamssound.cpp",
|
MAME_DIR .. "src/mame/shared/williamssound.cpp",
|
||||||
MAME_DIR .. "src/mame/shared/williamssound.h",
|
MAME_DIR .. "src/mame/shared/williamssound.h",
|
||||||
|
MAME_DIR .. "src/mame/midway/williamsblitter.cpp",
|
||||||
|
MAME_DIR .. "src/mame/midway/williamsblitter.h",
|
||||||
MAME_DIR .. "src/mame/midway/williams.cpp",
|
MAME_DIR .. "src/mame/midway/williams.cpp",
|
||||||
MAME_DIR .. "src/mame/midway/williams.h",
|
MAME_DIR .. "src/mame/midway/williams.h",
|
||||||
MAME_DIR .. "src/mame/midway/williams_m.cpp",
|
MAME_DIR .. "src/mame/midway/williams_m.cpp",
|
||||||
|
@ -41,25 +41,7 @@
|
|||||||
|
|
||||||
****************************************************************************
|
****************************************************************************
|
||||||
|
|
||||||
Blitter (Stargate and Defender do not have blitter)
|
CA00-CA07 blitter (Stargate and Defender do not have blitter)
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
CA00 start_blitter Each bits has a function
|
|
||||||
1000 0000 Do not process half the byte 4-7
|
|
||||||
0100 0000 Do not process half the byte 0-3
|
|
||||||
0010 0000 Shift the shape one pixel right (to display a shape on an odd pixel)
|
|
||||||
0001 0000 Remap, if shape != 0 then pixel = mask
|
|
||||||
0000 1000 Source 1 = take source 0 = take Mask only
|
|
||||||
0000 0100 ?
|
|
||||||
0000 0010 Transparent
|
|
||||||
0000 0001
|
|
||||||
CA01 blitter_mask Not really a mask, more a remap color, see Blitter
|
|
||||||
CA02 blitter_source hi
|
|
||||||
CA03 blitter_source lo
|
|
||||||
CA04 blitter_dest hi
|
|
||||||
CA05 blitter_dest lo
|
|
||||||
CA06 blitter_w_h H Do a XOR with 4 to have the real value (Except Splat)
|
|
||||||
CA07 blitter_w_h W Do a XOR with 4 to have the real value (Except Splat)
|
|
||||||
|
|
||||||
CB00 6 bits of the video counters bits 2-7
|
CB00 6 bits of the video counters bits 2-7
|
||||||
|
|
||||||
@ -553,17 +535,21 @@ void williams_state::main_map(address_map &map)
|
|||||||
map(0xc804, 0xc807).mirror(0x00f0).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
map(0xc804, 0xc807).mirror(0x00f0).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
||||||
map(0xc80c, 0xc80f).mirror(0x00f0).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
map(0xc80c, 0xc80f).mirror(0x00f0).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
||||||
map(0xc900, 0xc9ff).w(FUNC(williams_state::vram_select_w));
|
map(0xc900, 0xc9ff).w(FUNC(williams_state::vram_select_w));
|
||||||
map(0xca00, 0xca07).mirror(0x00f8).w(FUNC(williams_state::blitter_w));
|
|
||||||
map(0xcb00, 0xcbff).r(FUNC(williams_state::video_counter_r));
|
map(0xcb00, 0xcbff).r(FUNC(williams_state::video_counter_r));
|
||||||
map(0xcbff, 0xcbff).w(FUNC(williams_state::watchdog_reset_w));
|
map(0xcbff, 0xcbff).w(FUNC(williams_state::watchdog_reset_w));
|
||||||
map(0xcc00, 0xcfff).ram().w(FUNC(williams_state::cmos_4bit_w)).share("nvram");
|
map(0xcc00, 0xcfff).ram().w(FUNC(williams_state::cmos_4bit_w)).share("nvram");
|
||||||
map(0xd000, 0xffff).rom();
|
map(0xd000, 0xffff).rom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void williams_state::main_map_blitter(address_map &map)
|
||||||
|
{
|
||||||
|
main_map(map);
|
||||||
|
map(0xca00, 0xca07).mirror(0x00f8).m(m_blitter, FUNC(williams_blitter_device::map));
|
||||||
|
}
|
||||||
|
|
||||||
void williams_state::sinistar_main_map(address_map &map)
|
void williams_state::sinistar_main_map(address_map &map)
|
||||||
{
|
{
|
||||||
main_map(map);
|
main_map_blitter(map);
|
||||||
|
|
||||||
map(0xc900, 0xc9ff).w(FUNC(williams_state::sinistar_vram_select_w));
|
map(0xc900, 0xc9ff).w(FUNC(williams_state::sinistar_vram_select_w));
|
||||||
|
|
||||||
@ -574,7 +560,7 @@ void williams_state::sinistar_main_map(address_map &map)
|
|||||||
|
|
||||||
void williams_state::bubbles_main_map(address_map &map)
|
void williams_state::bubbles_main_map(address_map &map)
|
||||||
{
|
{
|
||||||
main_map(map);
|
main_map_blitter(map);
|
||||||
|
|
||||||
// bubbles has additional CMOS for a full 8 bits
|
// bubbles has additional CMOS for a full 8 bits
|
||||||
map(0xcc00, 0xcfff).ram().share("nvram");
|
map(0xcc00, 0xcfff).ram().share("nvram");
|
||||||
@ -583,7 +569,7 @@ void williams_state::bubbles_main_map(address_map &map)
|
|||||||
|
|
||||||
void williams_state::spdball_main_map(address_map &map)
|
void williams_state::spdball_main_map(address_map &map)
|
||||||
{
|
{
|
||||||
main_map(map);
|
main_map_blitter(map);
|
||||||
|
|
||||||
// install extra input handlers
|
// install extra input handlers
|
||||||
map(0xc800, 0xc800).portr("AN0");
|
map(0xc800, 0xc800).portr("AN0");
|
||||||
@ -598,7 +584,7 @@ void williams_state::spdball_main_map(address_map &map)
|
|||||||
|
|
||||||
void williams_state::alienar_main_map(address_map &map)
|
void williams_state::alienar_main_map(address_map &map)
|
||||||
{
|
{
|
||||||
main_map(map);
|
main_map_blitter(map);
|
||||||
|
|
||||||
map(0xcbff, 0xcbff).nopw();
|
map(0xcbff, 0xcbff).nopw();
|
||||||
}
|
}
|
||||||
@ -621,10 +607,10 @@ void blaster_state::blaster_main_map(address_map &map)
|
|||||||
map(0xc804, 0xc807).mirror(0x00f0).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
map(0xc804, 0xc807).mirror(0x00f0).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
||||||
map(0xc80c, 0xc80f).mirror(0x00f0).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
map(0xc80c, 0xc80f).mirror(0x00f0).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
||||||
map(0xc900, 0xc93f).w(FUNC(blaster_state::blaster_vram_select_w));
|
map(0xc900, 0xc93f).w(FUNC(blaster_state::blaster_vram_select_w));
|
||||||
map(0xc940, 0xc97f).w(FUNC(blaster_state::remap_select_w));
|
map(0xc940, 0xc97f).w(m_blitter, FUNC(williams_blitter_device::remap_select_w));
|
||||||
map(0xc980, 0xc9bf).w(FUNC(blaster_state::bank_select_w));
|
map(0xc980, 0xc9bf).w(FUNC(blaster_state::bank_select_w));
|
||||||
map(0xc9c0, 0xc9ff).w(FUNC(blaster_state::video_control_w));
|
map(0xc9c0, 0xc9ff).w(FUNC(blaster_state::video_control_w));
|
||||||
map(0xca00, 0xca07).mirror(0x00f8).w(FUNC(blaster_state::blitter_w));
|
map(0xca00, 0xca07).mirror(0x00f8).m(m_blitter, FUNC(williams_blitter_device::map));
|
||||||
map(0xcb00, 0xcbff).r(FUNC(blaster_state::video_counter_r));
|
map(0xcb00, 0xcbff).r(FUNC(blaster_state::video_counter_r));
|
||||||
map(0xcbff, 0xcbff).w(FUNC(blaster_state::watchdog_reset_w));
|
map(0xcbff, 0xcbff).w(FUNC(blaster_state::watchdog_reset_w));
|
||||||
map(0xcc00, 0xcfff).ram().w(FUNC(blaster_state::cmos_4bit_w)).share("nvram");
|
map(0xcc00, 0xcfff).ram().w(FUNC(blaster_state::cmos_4bit_w)).share("nvram");
|
||||||
@ -648,7 +634,7 @@ void williams2_state::common_map(address_map &map)
|
|||||||
m_palette_view[0](0x8000, 0x87ff).ram().w(FUNC(williams2_state::paletteram_w)).share(m_paletteram);
|
m_palette_view[0](0x8000, 0x87ff).ram().w(FUNC(williams2_state::paletteram_w)).share(m_paletteram);
|
||||||
map(0xc000, 0xc7ff).ram().w(FUNC(williams2_state::tileram_w)).share(m_tileram);
|
map(0xc000, 0xc7ff).ram().w(FUNC(williams2_state::tileram_w)).share(m_tileram);
|
||||||
map(0xc800, 0xc87f).w(FUNC(williams2_state::bank_select_w));
|
map(0xc800, 0xc87f).w(FUNC(williams2_state::bank_select_w));
|
||||||
map(0xc880, 0xc887).mirror(0x0078).w(FUNC(williams2_state::blitter_w));
|
map(0xc880, 0xc887).mirror(0x0078).m(m_blitter, FUNC(williams_blitter_device::map));
|
||||||
map(0xc900, 0xc97f).w(FUNC(williams2_state::watchdog_reset_w));
|
map(0xc900, 0xc97f).w(FUNC(williams2_state::watchdog_reset_w));
|
||||||
map(0xc980, 0xc983).mirror(0x0070).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
map(0xc980, 0xc983).mirror(0x0070).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
||||||
map(0xc984, 0xc987).mirror(0x0070).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
map(0xc984, 0xc987).mirror(0x0070).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
||||||
@ -658,7 +644,7 @@ void williams2_state::common_map(address_map &map)
|
|||||||
map(0xcb40, 0xcb5f).w(FUNC(williams2_state::xscroll_low_w));
|
map(0xcb40, 0xcb5f).w(FUNC(williams2_state::xscroll_low_w));
|
||||||
map(0xcb60, 0xcb7f).w(FUNC(williams2_state::xscroll_high_w));
|
map(0xcb60, 0xcb7f).w(FUNC(williams2_state::xscroll_high_w));
|
||||||
map(0xcb80, 0xcb9f).w(FUNC(williams2_state::video_control_w));
|
map(0xcb80, 0xcb9f).w(FUNC(williams2_state::video_control_w));
|
||||||
map(0xcba0, 0xcbbf).w(FUNC(williams2_state::blit_window_enable_w));
|
map(0xcba0, 0xcbbf).w(m_blitter, FUNC(williams_blitter_device::window_enable_w));
|
||||||
map(0xcbe0, 0xcbef).r(FUNC(williams2_state::video_counter_r));
|
map(0xcbe0, 0xcbef).r(FUNC(williams2_state::video_counter_r));
|
||||||
map(0xcc00, 0xcfff).ram().w(FUNC(williams2_state::cmos_4bit_w)).share("nvram");
|
map(0xcc00, 0xcfff).ram().w(FUNC(williams2_state::cmos_4bit_w)).share("nvram");
|
||||||
}
|
}
|
||||||
@ -1596,31 +1582,17 @@ void williams_state::williams_base(machine_config &config)
|
|||||||
m_pia[2]->irqb_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<1>));
|
m_pia[2]->irqb_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<1>));
|
||||||
}
|
}
|
||||||
|
|
||||||
void williams_state::williams_b0(machine_config &config)
|
|
||||||
{
|
|
||||||
williams_base(config);
|
|
||||||
m_blitter_config = WILLIAMS_BLITTER_NONE;
|
|
||||||
m_blitter_clip_address = 0x0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
void williams_state::williams_b1(machine_config &config)
|
void williams_state::williams_b1(machine_config &config)
|
||||||
{
|
{
|
||||||
williams_base(config);
|
williams_base(config);
|
||||||
m_blitter_config = WILLIAMS_BLITTER_SC1;
|
WILLIAMS_BLITTER_SC1(config, m_blitter, 0xc000, m_maincpu, m_videoram);
|
||||||
m_blitter_clip_address = 0xc000;
|
m_maincpu->set_addrmap(AS_PROGRAM, &williams_state::main_map_blitter);
|
||||||
}
|
|
||||||
|
|
||||||
void williams_state::williams_b2(machine_config &config)
|
|
||||||
{
|
|
||||||
williams_base(config);
|
|
||||||
m_blitter_config = WILLIAMS_BLITTER_SC2;
|
|
||||||
m_blitter_clip_address = 0xc000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void defender_state::defender(machine_config &config)
|
void defender_state::defender(machine_config &config)
|
||||||
{
|
{
|
||||||
williams_b0(config);
|
williams_base(config);
|
||||||
|
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &defender_state::defender_main_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &defender_state::defender_main_map);
|
||||||
m_soundcpu->set_addrmap(AS_PROGRAM, &defender_state::defender_sound_map);
|
m_soundcpu->set_addrmap(AS_PROGRAM, &defender_state::defender_sound_map);
|
||||||
@ -1681,7 +1653,8 @@ void williams_state::joust(machine_config &config)
|
|||||||
|
|
||||||
void williams_state::splat(machine_config &config)
|
void williams_state::splat(machine_config &config)
|
||||||
{
|
{
|
||||||
williams_b2(config);
|
williams_base(config);
|
||||||
|
WILLIAMS_BLITTER_SC2(config, m_blitter, 0xc000, m_maincpu, m_videoram);
|
||||||
williams_muxed(config);
|
williams_muxed(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1704,8 +1677,8 @@ void williams_state::bubbles(machine_config &config)
|
|||||||
void williams_state::sinistar_upright(machine_config &config)
|
void williams_state::sinistar_upright(machine_config &config)
|
||||||
{
|
{
|
||||||
// Sinistar: blitter window clip
|
// Sinistar: blitter window clip
|
||||||
williams_b1(config);
|
williams_base(config);
|
||||||
m_blitter_clip_address = 0x7400;
|
WILLIAMS_BLITTER_SC1(config, m_blitter, 0x7400, m_maincpu, m_videoram);
|
||||||
|
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &williams_state::sinistar_main_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &williams_state::sinistar_main_map);
|
||||||
|
|
||||||
@ -1786,8 +1759,8 @@ void williams_state::lottofun(machine_config &config)
|
|||||||
|
|
||||||
void blaster_state::blastkit(machine_config &config)
|
void blaster_state::blastkit(machine_config &config)
|
||||||
{
|
{
|
||||||
williams_b2(config);
|
williams_base(config);
|
||||||
m_blitter_clip_address = 0x9700;
|
WILLIAMS_BLITTER_SC2(config, m_blitter, 0x9700, m_maincpu, m_videoram, "proms");
|
||||||
|
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &blaster_state::blaster_main_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &blaster_state::blaster_main_map);
|
||||||
|
|
||||||
@ -1899,8 +1872,7 @@ void williams2_state::williams2_base(machine_config &config)
|
|||||||
m_pia[2]->irqa_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<0>));
|
m_pia[2]->irqa_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<0>));
|
||||||
m_pia[2]->irqb_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<1>));
|
m_pia[2]->irqb_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<1>));
|
||||||
|
|
||||||
m_blitter_config = WILLIAMS_BLITTER_SC2;
|
WILLIAMS_BLITTER_SC2(config, m_blitter, 0x9000, m_maincpu, m_videoram);
|
||||||
m_blitter_clip_address = 0x9000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3953,7 +3925,7 @@ GAME( 1982, jin, 0, jin, jin, defender_state, e
|
|||||||
|
|
||||||
|
|
||||||
// Standard Williams hardware
|
// Standard Williams hardware
|
||||||
GAME( 1981, stargate, 0, williams_b0, stargate, williams_state, empty_init, ROT0, "Williams / Vid Kidz", "Stargate", MACHINE_SUPPORTS_SAVE )
|
GAME( 1981, stargate, 0, williams_base, stargate, williams_state, empty_init, ROT0, "Williams / Vid Kidz", "Stargate", MACHINE_SUPPORTS_SAVE )
|
||||||
|
|
||||||
GAME( 1982, conquest, 0, williams_b1, conquest, conquest_state, empty_init, ROT270, "Williams / Vid Kidz", "Conquest (prototype)", MACHINE_IS_INCOMPLETE | MACHINE_SUPPORTS_SAVE )
|
GAME( 1982, conquest, 0, williams_b1, conquest, conquest_state, empty_init, ROT270, "Williams / Vid Kidz", "Conquest (prototype)", MACHINE_IS_INCOMPLETE | MACHINE_SUPPORTS_SAVE )
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "s11c_bg.h"
|
#include "s11c_bg.h"
|
||||||
#include "williamssound.h"
|
#include "williamssound.h"
|
||||||
|
#include "williamsblitter.h"
|
||||||
|
|
||||||
#include "cpu/m6800/m6800.h"
|
#include "cpu/m6800/m6800.h"
|
||||||
#include "cpu/m6809/m6809.h"
|
#include "cpu/m6809/m6809.h"
|
||||||
@ -39,6 +40,7 @@ public:
|
|||||||
m_screen(*this, "screen"),
|
m_screen(*this, "screen"),
|
||||||
m_palette(*this, "palette"),
|
m_palette(*this, "palette"),
|
||||||
m_paletteram(*this, "paletteram"),
|
m_paletteram(*this, "paletteram"),
|
||||||
|
m_blitter(*this, "blitter"),
|
||||||
m_pia(*this, "pia_%u", 0U),
|
m_pia(*this, "pia_%u", 0U),
|
||||||
m_nvram(*this, "nvram"),
|
m_nvram(*this, "nvram"),
|
||||||
m_videoram(*this, "videoram"),
|
m_videoram(*this, "videoram"),
|
||||||
@ -47,9 +49,8 @@ public:
|
|||||||
m_49way_y(*this, "49WAYY")
|
m_49way_y(*this, "49WAYY")
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void williams_b0(machine_config &config);
|
void williams_base(machine_config &config);
|
||||||
void williams_b1(machine_config &config);
|
void williams_b1(machine_config &config);
|
||||||
void williams_b2(machine_config &config);
|
|
||||||
|
|
||||||
void joust(machine_config &config);
|
void joust(machine_config &config);
|
||||||
void bubbles(machine_config &config);
|
void bubbles(machine_config &config);
|
||||||
@ -71,33 +72,13 @@ public:
|
|||||||
void palette_init(palette_device &palette) const;
|
void palette_init(palette_device &palette) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// blitter type
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
WILLIAMS_BLITTER_NONE = 0, // no blitter
|
|
||||||
WILLIAMS_BLITTER_SC1 = 1, // Special Chip 1 blitter
|
|
||||||
WILLIAMS_BLITTER_SC2 = 2 // Special Chip 2 "bugfixed" blitter
|
|
||||||
};
|
|
||||||
|
|
||||||
// controlbyte (0xCA00) bit definitions
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
WMS_BLITTER_CONTROLBYTE_NO_EVEN = 0x80,
|
|
||||||
WMS_BLITTER_CONTROLBYTE_NO_ODD = 0x40,
|
|
||||||
WMS_BLITTER_CONTROLBYTE_SHIFT = 0x20,
|
|
||||||
WMS_BLITTER_CONTROLBYTE_SOLID = 0x10,
|
|
||||||
WMS_BLITTER_CONTROLBYTE_FOREGROUND_ONLY = 0x08,
|
|
||||||
WMS_BLITTER_CONTROLBYTE_SLOW = 0x04, // 2us blits instead of 1us
|
|
||||||
WMS_BLITTER_CONTROLBYTE_DST_STRIDE_256 = 0x02,
|
|
||||||
WMS_BLITTER_CONTROLBYTE_SRC_STRIDE_256 = 0x01
|
|
||||||
};
|
|
||||||
|
|
||||||
required_device<cpu_device> m_maincpu;
|
required_device<cpu_device> m_maincpu;
|
||||||
required_device<cpu_device> m_soundcpu;
|
required_device<cpu_device> m_soundcpu;
|
||||||
required_device<watchdog_timer_device> m_watchdog;
|
required_device<watchdog_timer_device> m_watchdog;
|
||||||
required_device<screen_device> m_screen;
|
required_device<screen_device> m_screen;
|
||||||
optional_device<palette_device> m_palette;
|
required_device<palette_device> m_palette;
|
||||||
optional_shared_ptr<uint8_t> m_paletteram;
|
required_shared_ptr<uint8_t> m_paletteram;
|
||||||
|
optional_device<williams_blitter_device> m_blitter;
|
||||||
optional_device_array<pia6821_device, 4> m_pia;
|
optional_device_array<pia6821_device, 4> m_pia;
|
||||||
|
|
||||||
required_shared_ptr<uint8_t> m_nvram;
|
required_shared_ptr<uint8_t> m_nvram;
|
||||||
@ -108,16 +89,8 @@ protected:
|
|||||||
optional_ioport m_49way_x;
|
optional_ioport m_49way_x;
|
||||||
optional_ioport m_49way_y;
|
optional_ioport m_49way_y;
|
||||||
|
|
||||||
uint8_t m_blitter_config;
|
|
||||||
uint16_t m_blitter_clip_address;
|
|
||||||
uint8_t m_blitter_window_enable;
|
|
||||||
uint8_t m_cocktail;
|
uint8_t m_cocktail;
|
||||||
std::unique_ptr<rgb_t[]> m_palette_lookup;
|
std::unique_ptr<rgb_t[]> m_palette_lookup;
|
||||||
uint8_t m_blitterram[8];
|
|
||||||
uint8_t m_blitter_xor;
|
|
||||||
uint8_t m_blitter_remap_index;
|
|
||||||
const uint8_t *m_blitter_remap;
|
|
||||||
std::unique_ptr<uint8_t[]> m_blitter_remap_lookup;
|
|
||||||
|
|
||||||
virtual void machine_reset() override ATTR_COLD;
|
virtual void machine_reset() override ATTR_COLD;
|
||||||
virtual void video_start() override ATTR_COLD;
|
virtual void video_start() override ATTR_COLD;
|
||||||
@ -126,7 +99,6 @@ protected:
|
|||||||
void vram_select_w(u8 data);
|
void vram_select_w(u8 data);
|
||||||
void sinistar_vram_select_w(u8 data);
|
void sinistar_vram_select_w(u8 data);
|
||||||
void cmos_4bit_w(offs_t offset, u8 data);
|
void cmos_4bit_w(offs_t offset, u8 data);
|
||||||
void blitter_w(address_space &space, offs_t offset, u8 data);
|
|
||||||
|
|
||||||
template <unsigned A, unsigned... B>
|
template <unsigned A, unsigned... B>
|
||||||
TIMER_CALLBACK_MEMBER(deferred_snd_cmd_w);
|
TIMER_CALLBACK_MEMBER(deferred_snd_cmd_w);
|
||||||
@ -134,15 +106,10 @@ protected:
|
|||||||
void playball_snd_cmd_w(u8 data);
|
void playball_snd_cmd_w(u8 data);
|
||||||
void cockpit_snd_cmd_w(u8 data);
|
void cockpit_snd_cmd_w(u8 data);
|
||||||
|
|
||||||
void state_save_register();
|
|
||||||
void blitter_init(int blitter_config, const uint8_t *remap_prom);
|
|
||||||
inline void blit_pixel(address_space &space, int dstaddr, int srcdata, int controlbyte);
|
|
||||||
int blitter_core(address_space &space, int sstart, int dstart, int w, int h, int data);
|
|
||||||
|
|
||||||
void williams_base(machine_config &config);
|
|
||||||
void williams_muxed(machine_config &config);
|
void williams_muxed(machine_config &config);
|
||||||
|
|
||||||
void main_map(address_map &map) ATTR_COLD;
|
void main_map(address_map &map) ATTR_COLD;
|
||||||
|
void main_map_blitter(address_map &map) ATTR_COLD;
|
||||||
void bubbles_main_map(address_map &map) ATTR_COLD;
|
void bubbles_main_map(address_map &map) ATTR_COLD;
|
||||||
void sinistar_main_map(address_map &map) ATTR_COLD;
|
void sinistar_main_map(address_map &map) ATTR_COLD;
|
||||||
void spdball_main_map(address_map &map) ATTR_COLD;
|
void spdball_main_map(address_map &map) ATTR_COLD;
|
||||||
@ -237,7 +204,6 @@ private:
|
|||||||
|
|
||||||
void blaster_vram_select_w(u8 data);
|
void blaster_vram_select_w(u8 data);
|
||||||
void bank_select_w(u8 data);
|
void bank_select_w(u8 data);
|
||||||
void remap_select_w(u8 data);
|
|
||||||
void video_control_w(u8 data);
|
void video_control_w(u8 data);
|
||||||
TIMER_CALLBACK_MEMBER(deferred_snd_cmd_w);
|
TIMER_CALLBACK_MEMBER(deferred_snd_cmd_w);
|
||||||
void blaster_snd_cmd_w(u8 data);
|
void blaster_snd_cmd_w(u8 data);
|
||||||
|
@ -375,7 +375,7 @@ void williams_state::sinistar_vram_select_w(u8 data)
|
|||||||
vram_select_w(data);
|
vram_select_w(data);
|
||||||
|
|
||||||
// window enable from bit 2 (clips to 0x7400)
|
// window enable from bit 2 (clips to 0x7400)
|
||||||
m_blitter_window_enable = BIT(data, 2);
|
m_blitter->window_enable_w(BIT(data, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -421,7 +421,7 @@ void blaster_state::blaster_vram_select_w(u8 data)
|
|||||||
m_cocktail = BIT(data, 1);
|
m_cocktail = BIT(data, 1);
|
||||||
|
|
||||||
// window enable from bit 2 (clips to 0x9700)
|
// window enable from bit 2 (clips to 0x9700)
|
||||||
m_blitter_window_enable = BIT(data, 2);
|
m_blitter->window_enable_w(BIT(data, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,26 +160,15 @@ The full silkscreen markings of SC2 (under the "Special Chip 2" sticker, if it i
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
void williams_state::state_save_register()
|
|
||||||
{
|
|
||||||
save_item(NAME(m_blitter_window_enable));
|
|
||||||
save_item(NAME(m_cocktail));
|
|
||||||
save_item(NAME(m_blitterram));
|
|
||||||
save_item(NAME(m_blitter_remap_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void williams_state::video_start()
|
void williams_state::video_start()
|
||||||
{
|
{
|
||||||
blitter_init(m_blitter_config, nullptr);
|
save_item(NAME(m_cocktail));
|
||||||
state_save_register();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void blaster_state::video_start()
|
void blaster_state::video_start()
|
||||||
{
|
{
|
||||||
blitter_init(m_blitter_config, memregion("proms")->base());
|
williams_state::video_start();
|
||||||
state_save_register();
|
|
||||||
save_item(NAME(m_color0));
|
save_item(NAME(m_color0));
|
||||||
save_item(NAME(m_video_control));
|
save_item(NAME(m_video_control));
|
||||||
}
|
}
|
||||||
@ -187,13 +176,12 @@ void blaster_state::video_start()
|
|||||||
|
|
||||||
void williams2_state::video_start()
|
void williams2_state::video_start()
|
||||||
{
|
{
|
||||||
blitter_init(m_blitter_config, nullptr);
|
williams_state::video_start();
|
||||||
|
|
||||||
/* create the tilemap */
|
/* create the tilemap */
|
||||||
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(williams2_state::get_tile_info)), TILEMAP_SCAN_COLS, 24,16, 128,16);
|
m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(williams2_state::get_tile_info)), TILEMAP_SCAN_COLS, 24,16, 128,16);
|
||||||
m_bg_tilemap->set_scrolldx(2, 0);
|
m_bg_tilemap->set_scrolldx(2, 0);
|
||||||
|
|
||||||
state_save_register();
|
|
||||||
save_item(NAME(m_tilemap_xscroll));
|
save_item(NAME(m_tilemap_xscroll));
|
||||||
save_item(NAME(m_fg_color));
|
save_item(NAME(m_fg_color));
|
||||||
save_item(NAME(m_gain));
|
save_item(NAME(m_gain));
|
||||||
@ -313,7 +301,6 @@ uint32_t mysticm_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma
|
|||||||
rgb_t pens[16];
|
rgb_t pens[16];
|
||||||
|
|
||||||
/* draw the background */
|
/* draw the background */
|
||||||
//printf("y %d %d %d\n", cliprect.min_y, cliprect.max_y, m_screen->vpos());
|
|
||||||
m_bg_tilemap->mark_all_dirty();
|
m_bg_tilemap->mark_all_dirty();
|
||||||
m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0);
|
m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE | TILEMAP_DRAW_ALL_CATEGORIES, 0);
|
||||||
|
|
||||||
@ -644,205 +631,7 @@ void williams2_state::xscroll_high_w(u8 data)
|
|||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
void blaster_state::remap_select_w(u8 data)
|
|
||||||
{
|
|
||||||
m_blitter_remap_index = data;
|
|
||||||
m_blitter_remap = m_blitter_remap_lookup.get() + data * 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void blaster_state::video_control_w(u8 data)
|
void blaster_state::video_control_w(u8 data)
|
||||||
{
|
{
|
||||||
m_video_control = data;
|
m_video_control = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
*
|
|
||||||
* Blitter setup and control
|
|
||||||
*
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
void williams_state::blitter_init(int blitter_config, const uint8_t *remap_prom)
|
|
||||||
{
|
|
||||||
std::fill(std::begin(m_blitterram), std::end(m_blitterram), 0);
|
|
||||||
static const uint8_t dummy_table[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
|
|
||||||
|
|
||||||
/* by default, there is no clipping window - this will be touched only by games that have one */
|
|
||||||
m_blitter_window_enable = 0;
|
|
||||||
|
|
||||||
/* switch off the video config */
|
|
||||||
m_blitter_xor = (blitter_config == WILLIAMS_BLITTER_SC1) ? 4 : 0;
|
|
||||||
|
|
||||||
/* create the remap table; if no PROM, make an identity remap table */
|
|
||||||
m_blitter_remap_lookup = std::make_unique<uint8_t[]>(256 * 256);
|
|
||||||
m_blitter_remap_index = 0;
|
|
||||||
m_blitter_remap = m_blitter_remap_lookup.get();
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
const uint8_t *table = remap_prom ? (remap_prom + (i & 0x7f) * 16) : dummy_table;
|
|
||||||
for (int j = 0; j < 256; j++)
|
|
||||||
m_blitter_remap_lookup[i * 256 + j] = (table[j >> 4] << 4) | table[j & 0x0f];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void williams_state::blitter_w(address_space &space, offs_t offset, u8 data)
|
|
||||||
{
|
|
||||||
/* store the data */
|
|
||||||
m_blitterram[offset] = data;
|
|
||||||
|
|
||||||
/* only writes to location 0 trigger the blit */
|
|
||||||
if (offset != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* compute the starting locations */
|
|
||||||
int sstart = (m_blitterram[2] << 8) + m_blitterram[3];
|
|
||||||
int dstart = (m_blitterram[4] << 8) + m_blitterram[5];
|
|
||||||
|
|
||||||
/* compute the width and height */
|
|
||||||
int w = m_blitterram[6] ^ m_blitter_xor;
|
|
||||||
int h = m_blitterram[7] ^ m_blitter_xor;
|
|
||||||
|
|
||||||
/* adjust the width and height */
|
|
||||||
if (w == 0) w = 1;
|
|
||||||
if (h == 0) h = 1;
|
|
||||||
|
|
||||||
/* do the actual blit */
|
|
||||||
int const accesses = blitter_core(space, sstart, dstart, w, h, data);
|
|
||||||
|
|
||||||
/* based on the number of memory accesses needed to do the blit, compute how long the blit will take */
|
|
||||||
int estimated_clocks_at_4MHz = 4;
|
|
||||||
if(data & WMS_BLITTER_CONTROLBYTE_SLOW)
|
|
||||||
{
|
|
||||||
estimated_clocks_at_4MHz += 4 * (accesses + 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
estimated_clocks_at_4MHz += 2 * (accesses + 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_maincpu->adjust_icount(-((estimated_clocks_at_4MHz + 3) / 4));
|
|
||||||
|
|
||||||
/* Log blits */
|
|
||||||
logerror("%04X:Blit @ %3d : %02X%02X -> %02X%02X, %3dx%3d, mask=%02X, flags=%02X, icount=%d, win=%d\n",
|
|
||||||
m_maincpu->pc(), m_screen->vpos(),
|
|
||||||
m_blitterram[2], m_blitterram[3],
|
|
||||||
m_blitterram[4], m_blitterram[5],
|
|
||||||
m_blitterram[6], m_blitterram[7],
|
|
||||||
m_blitterram[1], m_blitterram[0],
|
|
||||||
((estimated_clocks_at_4MHz + 3) / 4), m_blitter_window_enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void williams2_state::blit_window_enable_w(u8 data)
|
|
||||||
{
|
|
||||||
m_blitter_window_enable = BIT(data, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************
|
|
||||||
*
|
|
||||||
* Blitter core
|
|
||||||
*
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
inline void williams_state::blit_pixel(address_space &space, int dstaddr, int srcdata, int controlbyte)
|
|
||||||
{
|
|
||||||
/* always read from video RAM regardless of the bank setting */
|
|
||||||
int curpix = (dstaddr < 0xc000) ? m_videoram[dstaddr] : space.read_byte(dstaddr); // current pixel values at dest
|
|
||||||
|
|
||||||
int const solid = m_blitterram[1];
|
|
||||||
unsigned char keepmask = 0xff; // what part of original dst byte should be kept, based on NO_EVEN and NO_ODD flags
|
|
||||||
|
|
||||||
// even pixel (D7-D4)
|
|
||||||
if((controlbyte & WMS_BLITTER_CONTROLBYTE_FOREGROUND_ONLY) && !(srcdata & 0xf0)) // FG only and src even pixel=0
|
|
||||||
{
|
|
||||||
if(controlbyte & WMS_BLITTER_CONTROLBYTE_NO_EVEN)
|
|
||||||
keepmask &= 0x0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!(controlbyte & WMS_BLITTER_CONTROLBYTE_NO_EVEN))
|
|
||||||
keepmask &= 0x0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// odd pixel (D3-D0)
|
|
||||||
if((controlbyte & WMS_BLITTER_CONTROLBYTE_FOREGROUND_ONLY) && !(srcdata & 0x0f)) // FG only and src odd pixel=0
|
|
||||||
{
|
|
||||||
if(controlbyte & WMS_BLITTER_CONTROLBYTE_NO_ODD)
|
|
||||||
keepmask &= 0xf0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!(controlbyte & WMS_BLITTER_CONTROLBYTE_NO_ODD))
|
|
||||||
keepmask &= 0xf0;
|
|
||||||
}
|
|
||||||
|
|
||||||
curpix &= keepmask;
|
|
||||||
if(controlbyte & WMS_BLITTER_CONTROLBYTE_SOLID)
|
|
||||||
curpix |= (solid & ~keepmask);
|
|
||||||
else
|
|
||||||
curpix |= (srcdata & ~keepmask);
|
|
||||||
|
|
||||||
/* if the window is enabled, only blit to videoram below the clipping address */
|
|
||||||
/* note that we have to allow blits to non-video RAM (e.g. tileram, Sinistar $DXXX SRAM) because those */
|
|
||||||
/* are not blocked by the window enable */
|
|
||||||
if (!m_blitter_window_enable || dstaddr < m_blitter_clip_address || dstaddr >= 0xc000)
|
|
||||||
space.write_byte(dstaddr, curpix);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int williams_state::blitter_core(address_space &space, int sstart, int dstart, int w, int h, int controlbyte)
|
|
||||||
{
|
|
||||||
int accesses = 0;
|
|
||||||
|
|
||||||
/* compute how much to advance in the x and y loops */
|
|
||||||
int const sxadv = (controlbyte & WMS_BLITTER_CONTROLBYTE_SRC_STRIDE_256) ? 0x100 : 1;
|
|
||||||
int const syadv = (controlbyte & WMS_BLITTER_CONTROLBYTE_SRC_STRIDE_256) ? 1 : w;
|
|
||||||
int const dxadv = (controlbyte & WMS_BLITTER_CONTROLBYTE_DST_STRIDE_256) ? 0x100 : 1;
|
|
||||||
int const dyadv = (controlbyte & WMS_BLITTER_CONTROLBYTE_DST_STRIDE_256) ? 1 : w;
|
|
||||||
|
|
||||||
int pixdata = 0;
|
|
||||||
|
|
||||||
/* loop over the height */
|
|
||||||
for (int y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
int source = sstart & 0xffff;
|
|
||||||
int dest = dstart & 0xffff;
|
|
||||||
|
|
||||||
/* loop over the width */
|
|
||||||
for (int x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
if (!(controlbyte & WMS_BLITTER_CONTROLBYTE_SHIFT)) // no shift
|
|
||||||
{
|
|
||||||
blit_pixel(space, dest, m_blitter_remap[space.read_byte(source)], controlbyte);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// shift one pixel right
|
|
||||||
pixdata = (pixdata << 8) | m_blitter_remap[space.read_byte(source)];
|
|
||||||
blit_pixel(space, dest, (pixdata >> 4) & 0xff, controlbyte);
|
|
||||||
}
|
|
||||||
accesses += 2;
|
|
||||||
|
|
||||||
/* advance src and dst pointers */
|
|
||||||
source = (source + sxadv) & 0xffff;
|
|
||||||
dest = (dest + dxadv) & 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* note that PlayBall! indicates the X coordinate doesn't wrap */
|
|
||||||
if (controlbyte & WMS_BLITTER_CONTROLBYTE_DST_STRIDE_256)
|
|
||||||
dstart = (dstart & 0xff00) | ((dstart + dyadv) & 0xff);
|
|
||||||
else
|
|
||||||
dstart += dyadv;
|
|
||||||
|
|
||||||
if (controlbyte & WMS_BLITTER_CONTROLBYTE_SRC_STRIDE_256)
|
|
||||||
sstart = (sstart & 0xff00) | ((sstart + syadv) & 0xff);
|
|
||||||
else
|
|
||||||
sstart += syadv;
|
|
||||||
}
|
|
||||||
return accesses;
|
|
||||||
}
|
|
||||||
|
251
src/mame/midway/williamsblitter.cpp
Normal file
251
src/mame/midway/williamsblitter.cpp
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
Williams first-generation blitter
|
||||||
|
|
||||||
|
Register Description
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
CA00 start_blitter Control bits
|
||||||
|
CA01 mask Solid color to optionally use instead of source
|
||||||
|
CA02 source Source address MSB
|
||||||
|
CA03 source Source address LSB
|
||||||
|
CA04 dest Destination address MSB
|
||||||
|
CA05 dest Destination address LSB
|
||||||
|
CA06 w_h Blit width (XOR with 4 to have the real value on first-rev blitter)
|
||||||
|
CA07 w_h Blit height (XOR with 4 to have the real value on first-rev blitter)
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "williamsblitter.h"
|
||||||
|
|
||||||
|
#define VERBOSE (0)
|
||||||
|
#include "logmacro.h"
|
||||||
|
|
||||||
|
DEFINE_DEVICE_TYPE(WILLIAMS_BLITTER_SC1, williams_blitter_sc1_device, "williams_blitter_sc1_device", "Williams Blitter (SC1)")
|
||||||
|
DEFINE_DEVICE_TYPE(WILLIAMS_BLITTER_SC2, williams_blitter_sc2_device, "williams_blitter_sc2_device", "Williams Blitter (SC2)")
|
||||||
|
|
||||||
|
williams_blitter_device::williams_blitter_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) :
|
||||||
|
device_t(mconfig, type, tag, owner, clock),
|
||||||
|
m_cpu(*this, finder_base::DUMMY_TAG),
|
||||||
|
m_vram(*this, finder_base::DUMMY_TAG),
|
||||||
|
m_proms(*this, finder_base::DUMMY_TAG)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
williams_blitter_sc1_device::williams_blitter_sc1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||||
|
williams_blitter_device(mconfig, WILLIAMS_BLITTER_SC1, tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
williams_blitter_sc2_device::williams_blitter_sc2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||||
|
williams_blitter_device(mconfig, WILLIAMS_BLITTER_SC2, tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void williams_blitter_device::device_start()
|
||||||
|
{
|
||||||
|
static const u8 dummy_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||||
|
|
||||||
|
m_window_enable = 0;
|
||||||
|
|
||||||
|
// create the remap table; if no PROM, make an identity remap table
|
||||||
|
m_remap_lookup = std::make_unique<uint8_t[]>(256 * 256);
|
||||||
|
m_remap = m_remap_lookup.get();
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
const u8 *table = m_proms.found() ? &m_proms[(i & 0x7f) * 16] : dummy_table;
|
||||||
|
for (int j = 0; j < 256; j++)
|
||||||
|
{
|
||||||
|
m_remap_lookup[i * 256 + j] = (table[j >> 4] << 4) | table[j & 0x0f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_item(NAME(m_window_enable));
|
||||||
|
save_item(NAME(m_control));
|
||||||
|
save_item(NAME(m_no_even));
|
||||||
|
save_item(NAME(m_no_odd));
|
||||||
|
save_item(NAME(m_solid));
|
||||||
|
save_item(NAME(m_fg_only));
|
||||||
|
save_item(NAME(m_solid_color));
|
||||||
|
save_item(NAME(m_sstart));
|
||||||
|
save_item(NAME(m_dstart));
|
||||||
|
save_item(NAME(m_width));
|
||||||
|
save_item(NAME(m_height));
|
||||||
|
save_item(NAME(m_remap_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void williams_blitter_device::device_reset()
|
||||||
|
{
|
||||||
|
m_control = 0;
|
||||||
|
m_no_even = false;
|
||||||
|
m_no_odd = false;
|
||||||
|
m_solid = false;
|
||||||
|
m_fg_only = false;
|
||||||
|
m_solid_color = 0;
|
||||||
|
m_sstart = 0;
|
||||||
|
m_dstart = 0;
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
|
m_remap_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void williams_blitter_device::map(address_map &map)
|
||||||
|
{
|
||||||
|
map(0x0, 0x0).w(FUNC(williams_blitter_device::control_w));
|
||||||
|
map(0x1, 0x1).lw8(NAME([this](u8 data) { m_solid_color = data; }));
|
||||||
|
map(0x2, 0x2).lw8(NAME([this](u8 data) { m_sstart = (m_sstart & 0x00ff) | ((u16)data << 8); }));
|
||||||
|
map(0x3, 0x3).lw8(NAME([this](u8 data) { m_sstart = (m_sstart & 0xff00) | data; }));
|
||||||
|
map(0x4, 0x4).lw8(NAME([this](u8 data) { m_dstart = (m_dstart & 0x00ff) | ((u16)data << 8); }));
|
||||||
|
map(0x5, 0x5).lw8(NAME([this](u8 data) { m_dstart = (m_dstart & 0xff00) | data; }));
|
||||||
|
map(0x6, 0x6).lw8(NAME([this](u8 data) { m_width = data; }));
|
||||||
|
map(0x7, 0x7).lw8(NAME([this](u8 data) { m_height = data; }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void williams_blitter_device::control_w(address_space &space, offs_t offset, u8 data)
|
||||||
|
{
|
||||||
|
m_control = data;
|
||||||
|
m_no_even = BIT(data, CONTROLBYTE_NO_EVEN);
|
||||||
|
m_no_odd = BIT(data, CONTROLBYTE_NO_ODD);
|
||||||
|
m_solid = BIT(data, CONTROLBYTE_SOLID);
|
||||||
|
m_fg_only = BIT(data, CONTROLBYTE_FOREGROUND_ONLY);
|
||||||
|
|
||||||
|
int w = m_width ^ m_size_xor;
|
||||||
|
int h = m_height ^ m_size_xor;
|
||||||
|
|
||||||
|
if (w == 0)
|
||||||
|
w = 1;
|
||||||
|
if (h == 0)
|
||||||
|
h = 1;
|
||||||
|
|
||||||
|
const int accesses = blit_core(space, w, h);
|
||||||
|
|
||||||
|
// based on the number of memory accesses needed to do the blit, compute how long the blit will take
|
||||||
|
int estimated_clocks_at_4MHz = 4;
|
||||||
|
if (BIT(m_control, CONTROLBYTE_SLOW))
|
||||||
|
estimated_clocks_at_4MHz += 4 * (accesses + 2);
|
||||||
|
else
|
||||||
|
estimated_clocks_at_4MHz += 2 * (accesses + 3);
|
||||||
|
|
||||||
|
m_cpu->adjust_icount(-((estimated_clocks_at_4MHz + 3) / 4));
|
||||||
|
|
||||||
|
// log blits
|
||||||
|
LOG("%04X:Blit : %04X -> %04X, %3dx%3d, mask=%02X, flags=%02X, icount=%d, win=%d\n",
|
||||||
|
m_cpu->pc(), m_sstart, m_dstart, m_width, m_height, m_solid_color, m_control,
|
||||||
|
((estimated_clocks_at_4MHz + 3) / 4), m_window_enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void williams_blitter_device::remap_select_w(u8 data)
|
||||||
|
{
|
||||||
|
m_remap_index = data;
|
||||||
|
if (m_proms != nullptr)
|
||||||
|
m_remap = m_remap_lookup.get() + data * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
void williams_blitter_device::window_enable_w(u8 data)
|
||||||
|
{
|
||||||
|
m_window_enable = BIT(data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void williams_blitter_device::blit_pixel(address_space &space, int dstaddr, int srcdata)
|
||||||
|
{
|
||||||
|
// always read from video RAM regardless of the bank setting
|
||||||
|
int curpix = (dstaddr < 0xc000) ? m_vram[dstaddr] : space.read_byte(dstaddr); // current pixel values at dest
|
||||||
|
|
||||||
|
u8 keepmask = 0xff; // what part of original dst byte should be kept, based on NO_EVEN and NO_ODD flags
|
||||||
|
|
||||||
|
// even pixel (D7-D4)
|
||||||
|
if (m_fg_only && !(srcdata & 0xf0)) // FG only and src even pixel=0
|
||||||
|
{
|
||||||
|
if (m_no_even)
|
||||||
|
keepmask &= 0x0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!m_no_even)
|
||||||
|
keepmask &= 0x0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// odd pixel (D3-D0)
|
||||||
|
if (m_fg_only && !(srcdata & 0x0f)) // FG only and src odd pixel=0
|
||||||
|
{
|
||||||
|
if (m_no_odd)
|
||||||
|
keepmask &= 0xf0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!m_no_odd)
|
||||||
|
keepmask &= 0xf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
curpix &= keepmask;
|
||||||
|
if (m_solid)
|
||||||
|
curpix |= m_solid_color & ~keepmask;
|
||||||
|
else
|
||||||
|
curpix |= srcdata & ~keepmask;
|
||||||
|
|
||||||
|
/* if the window is enabled, only blit to videoram below the clipping address */
|
||||||
|
/* note that we have to allow blits to non-video RAM (e.g. tileram, Sinistar $DXXX SRAM) because those */
|
||||||
|
/* are not blocked by the window enable */
|
||||||
|
if (!m_window_enable || dstaddr < m_clip_address || dstaddr >= 0xc000)
|
||||||
|
space.write_byte(dstaddr, curpix);
|
||||||
|
}
|
||||||
|
|
||||||
|
int williams_blitter_device::blit_core(address_space &space, int w, int h)
|
||||||
|
{
|
||||||
|
// compute how much to advance in the x and y loops
|
||||||
|
const bool dst_stride_256 = BIT(m_control, CONTROLBYTE_DST_STRIDE_256);
|
||||||
|
const bool src_stride_256 = BIT(m_control, CONTROLBYTE_SRC_STRIDE_256);
|
||||||
|
const int sxadv = src_stride_256 ? 0x100 : 1;
|
||||||
|
const int syadv = src_stride_256 ? 1 : w;
|
||||||
|
const int dxadv = dst_stride_256 ? 0x100 : 1;
|
||||||
|
const int dyadv = dst_stride_256 ? 1 : w;
|
||||||
|
|
||||||
|
int accesses = 0;
|
||||||
|
int pixdata = 0;
|
||||||
|
|
||||||
|
// loop over the height
|
||||||
|
const bool shift = BIT(m_control, CONTROLBYTE_SHIFT);
|
||||||
|
u16 sstart = m_sstart;
|
||||||
|
u16 dstart = m_dstart;
|
||||||
|
for (int y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
u16 source = sstart;
|
||||||
|
u16 dest = dstart;
|
||||||
|
|
||||||
|
// loop over the width
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
const u8 rawval = m_remap[space.read_byte(source)];
|
||||||
|
if (shift)
|
||||||
|
{
|
||||||
|
// shift one pixel right
|
||||||
|
pixdata = (pixdata << 8) | rawval;
|
||||||
|
blit_pixel(space, dest, (pixdata >> 4) & 0xff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blit_pixel(space, dest, rawval);
|
||||||
|
}
|
||||||
|
accesses += 2;
|
||||||
|
|
||||||
|
// advance src and dst pointers
|
||||||
|
source += sxadv;
|
||||||
|
dest += dxadv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note that PlayBall! indicates the X coordinate doesn't wrap
|
||||||
|
if (dst_stride_256)
|
||||||
|
dstart = (dstart & 0xff00) | ((dstart + dyadv) & 0xff);
|
||||||
|
else
|
||||||
|
dstart += dyadv;
|
||||||
|
|
||||||
|
if (src_stride_256)
|
||||||
|
sstart = (sstart & 0xff00) | ((sstart + syadv) & 0xff);
|
||||||
|
else
|
||||||
|
sstart += syadv;
|
||||||
|
}
|
||||||
|
return accesses;
|
||||||
|
}
|
130
src/mame/midway/williamsblitter.h
Normal file
130
src/mame/midway/williamsblitter.h
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Aaron Giles
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
Williams first-generation blitter
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MAME_MIDWAY_WILLIAMSBLITTER_H
|
||||||
|
#define MAME_MIDWAY_WILLIAMSBLITTER_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class williams_blitter_device : public device_t {
|
||||||
|
public:
|
||||||
|
template <typename T> void set_cpu_tag(T &&cpu_tag) { m_cpu.set_tag(std::forward<T>(cpu_tag)); }
|
||||||
|
template <typename T> void set_vram_tag(T &&vram_tag) { m_vram.set_tag(std::forward<T>(vram_tag)); }
|
||||||
|
template <typename T> void set_proms_tag(T &&proms_tag) { m_proms.set_tag(std::forward<T>(proms_tag)); }
|
||||||
|
|
||||||
|
void map(address_map &map) ATTR_COLD;
|
||||||
|
|
||||||
|
void remap_select_w(u8 data);
|
||||||
|
void window_enable_w(u8 data);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
williams_blitter_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock = 0);
|
||||||
|
|
||||||
|
void set_clip_address(u16 clip_address) { m_clip_address = clip_address; }
|
||||||
|
void set_size_xor(u32 size_xor) { m_size_xor = size_xor; }
|
||||||
|
|
||||||
|
virtual void device_start() override ATTR_COLD;
|
||||||
|
virtual void device_reset() override ATTR_COLD;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// control byte bit definitions
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CONTROLBYTE_NO_EVEN = 7,
|
||||||
|
CONTROLBYTE_NO_ODD = 6,
|
||||||
|
CONTROLBYTE_SHIFT = 5,
|
||||||
|
CONTROLBYTE_SOLID = 4,
|
||||||
|
CONTROLBYTE_FOREGROUND_ONLY = 3,
|
||||||
|
CONTROLBYTE_SLOW = 2, // 2us blits instead of 1us
|
||||||
|
CONTROLBYTE_DST_STRIDE_256 = 1,
|
||||||
|
CONTROLBYTE_SRC_STRIDE_256 = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
required_device<cpu_device> m_cpu;
|
||||||
|
required_shared_ptr<u8> m_vram;
|
||||||
|
optional_region_ptr<u8> m_proms;
|
||||||
|
|
||||||
|
void control_w(address_space &space, offs_t offset, u8 data);
|
||||||
|
inline void blit_pixel(address_space &space, int dstaddr, int srcdata);
|
||||||
|
int blit_core(address_space &space, int w, int h);
|
||||||
|
|
||||||
|
u8 m_config;
|
||||||
|
u16 m_clip_address;
|
||||||
|
u8 m_window_enable;
|
||||||
|
u8 m_control;
|
||||||
|
bool m_no_even;
|
||||||
|
bool m_no_odd;
|
||||||
|
bool m_solid;
|
||||||
|
bool m_fg_only;
|
||||||
|
u8 m_solid_color;
|
||||||
|
u16 m_sstart;
|
||||||
|
u16 m_dstart;
|
||||||
|
u8 m_width;
|
||||||
|
u8 m_height;
|
||||||
|
u8 m_size_xor;
|
||||||
|
u8 m_remap_index;
|
||||||
|
const u8 *m_remap;
|
||||||
|
std::unique_ptr<u8[]> m_remap_lookup;
|
||||||
|
};
|
||||||
|
|
||||||
|
class williams_blitter_sc1_device : public williams_blitter_device {
|
||||||
|
public:
|
||||||
|
template <typename T, typename U>
|
||||||
|
williams_blitter_sc1_device(const machine_config &mconfig, const char *tag, device_t *owner, u16 clip_address, T &&cpu_tag, U &&vram_tag)
|
||||||
|
: williams_blitter_sc1_device(mconfig, tag, owner)
|
||||||
|
{
|
||||||
|
set_size_xor(4);
|
||||||
|
set_clip_address(clip_address);
|
||||||
|
set_cpu_tag(std::forward<T>(cpu_tag));
|
||||||
|
set_vram_tag(std::forward<U>(vram_tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, typename V>
|
||||||
|
williams_blitter_sc1_device(const machine_config &mconfig, const char *tag, device_t *owner, u16 clip_address, T &&cpu_tag, U &&vram_tag, V &&proms_tag)
|
||||||
|
: williams_blitter_sc1_device(mconfig, tag, owner)
|
||||||
|
{
|
||||||
|
set_size_xor(4);
|
||||||
|
set_clip_address(clip_address);
|
||||||
|
set_cpu_tag(std::forward<T>(cpu_tag));
|
||||||
|
set_vram_tag(std::forward<U>(vram_tag));
|
||||||
|
set_proms_tag(std::forward<V>(proms_tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
williams_blitter_sc1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
class williams_blitter_sc2_device : public williams_blitter_device {
|
||||||
|
public:
|
||||||
|
template <typename T, typename U>
|
||||||
|
williams_blitter_sc2_device(const machine_config &mconfig, const char *tag, device_t *owner, u16 clip_address, T &&cpu_tag, U &&vram_tag)
|
||||||
|
: williams_blitter_sc2_device(mconfig, tag, owner)
|
||||||
|
{
|
||||||
|
set_size_xor(0);
|
||||||
|
set_clip_address(clip_address);
|
||||||
|
set_cpu_tag(std::forward<T>(cpu_tag));
|
||||||
|
set_vram_tag(std::forward<U>(vram_tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U, typename V>
|
||||||
|
williams_blitter_sc2_device(const machine_config &mconfig, const char *tag, device_t *owner, u16 clip_address, T &&cpu_tag, U &&vram_tag, V &&proms_tag)
|
||||||
|
: williams_blitter_sc2_device(mconfig, tag, owner)
|
||||||
|
{
|
||||||
|
set_size_xor(0);
|
||||||
|
set_clip_address(clip_address);
|
||||||
|
set_cpu_tag(std::forward<T>(cpu_tag));
|
||||||
|
set_vram_tag(std::forward<U>(vram_tag));
|
||||||
|
set_proms_tag(std::forward<V>(proms_tag));
|
||||||
|
}
|
||||||
|
|
||||||
|
williams_blitter_sc2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_DEVICE_TYPE(WILLIAMS_BLITTER_SC1, williams_blitter_sc1_device)
|
||||||
|
DECLARE_DEVICE_TYPE(WILLIAMS_BLITTER_SC2, williams_blitter_sc2_device)
|
||||||
|
|
||||||
|
#endif // MAME_MIDWAY_WILLIAMSBLITTER_H
|
@ -148,7 +148,7 @@ void wmg_state::wmg_cpu1(address_map &map)
|
|||||||
m_io_view[0](0xc804, 0xc807).r(FUNC(wmg_state::wmg_pia_0_r)).w(m_pia[0], FUNC(pia6821_device::write));
|
m_io_view[0](0xc804, 0xc807).r(FUNC(wmg_state::wmg_pia_0_r)).w(m_pia[0], FUNC(pia6821_device::write));
|
||||||
m_io_view[0](0xc80c, 0xc80f).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
m_io_view[0](0xc80c, 0xc80f).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
|
||||||
m_io_view[0](0xc900, 0xc9ff).nopr().w(FUNC(wmg_state::wmg_vram_select_w));
|
m_io_view[0](0xc900, 0xc9ff).nopr().w(FUNC(wmg_state::wmg_vram_select_w));
|
||||||
m_io_view[0](0xca00, 0xca07).w(FUNC(wmg_state::blitter_w));
|
m_io_view[0](0xca00, 0xca07).m(m_blitter, FUNC(williams_blitter_device::map));
|
||||||
m_io_view[0](0xcb00, 0xcbff).r(FUNC(wmg_state::video_counter_r));
|
m_io_view[0](0xcb00, 0xcbff).r(FUNC(wmg_state::video_counter_r));
|
||||||
m_io_view[0](0xcbff, 0xcbff).w(FUNC(wmg_state::watchdog_reset_w));
|
m_io_view[0](0xcbff, 0xcbff).w(FUNC(wmg_state::watchdog_reset_w));
|
||||||
m_io_view[0](0xcc00, 0xcfff).bankrw(m_nvrambank);
|
m_io_view[0](0xcc00, 0xcfff).bankrw(m_nvrambank);
|
||||||
@ -539,8 +539,7 @@ void wmg_state::wmg(machine_config &config)
|
|||||||
pia2.irqa_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<0>));
|
pia2.irqa_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<0>));
|
||||||
pia2.irqb_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<1>));
|
pia2.irqb_handler().set("soundirq", FUNC(input_merger_any_high_device::in_w<1>));
|
||||||
|
|
||||||
m_blitter_config = WILLIAMS_BLITTER_SC1;
|
WILLIAMS_BLITTER_SC1(config, m_blitter, 0xc000, m_maincpu, m_videoram);
|
||||||
m_blitter_clip_address = 0xc000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user