tugboat: shorthand variable types, add p1/p2 start lamps

This commit is contained in:
hap 2023-08-06 16:56:20 +02:00
parent 11a31d53ff
commit 914b10b6ee

View File

@ -6,9 +6,9 @@ Enter-Tech Tugboat (Moppet Video series, on improved El Grande hardware)
6502 hooked up + preliminary video by Ryan Holtz 6502 hooked up + preliminary video by Ryan Holtz
TODO: TODO:
- check how the score is displayed. I'm quite sure that tugboat_score_w is - check how the score is displayed. I'm quite sure that score_w is supposed to
supposed to access videoram scanning it by columns (like btime_mirrorvideoram_w), access videoram scanning it by columns (like btime_mirrorvideoram_w), but
but the current implementation is a big kludge, and it still looks wrong. the current implementation is a big kludge.
- why is fine x scroll latched differently for noahsark? or is something wrong - why is fine x scroll latched differently for noahsark? or is something wrong
with IRQ timing that causes it to dislike how tugboat does it? with IRQ timing that causes it to dislike how tugboat does it?
- colors might not be entirely accurate - colors might not be entirely accurate
@ -70,11 +70,12 @@ public:
tugboat_state(const machine_config &mconfig, device_type type, const char *tag) : tugboat_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag), driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_pia(*this, "pia%u", 0), m_pia(*this, "pia%u", 0U),
m_gfxdecode(*this, "gfxdecode"), m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"), m_screen(*this, "screen"),
m_palette(*this, "palette"), m_palette(*this, "palette"),
m_inputs(*this, "IN%u", 0) m_inputs(*this, "IN%u", 0U),
m_lamps(*this, "lamp%u", 0U)
{ } { }
void tugboat(machine_config &config); void tugboat(machine_config &config);
@ -91,23 +92,24 @@ private:
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
required_device<palette_device> m_palette; required_device<palette_device> m_palette;
required_ioport_array<4> m_inputs; required_ioport_array<4> m_inputs;
output_finder<2> m_lamps;
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program; memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program;
uint8_t m_hd46505_regs[2][0x20] = { }; u8 m_hd46505_regs[2][0x20] = { };
uint8_t m_hd46505_reglatch[2] = { }; u8 m_hd46505_reglatch[2] = { };
uint16_t m_start_address[2] = { }; u16 m_start_address[2] = { };
uint8_t m_control[2] = { }; u8 m_control[2] = { };
uint8_t m_fine_x_clock = 0; u8 m_fine_x_clock = 0;
uint8_t m_fine_y_clock = 0; u8 m_fine_y_clock = 0;
uint8_t m_fine_x_latch = 0; u8 m_fine_x_latch = 0;
uint8_t m_fine_y_latch = 0; u8 m_fine_y_latch = 0;
template<int N> void hd46505_w(offs_t offset, uint8_t data); template<int N> void hd46505_w(offs_t offset, u8 data);
void score_w(offs_t offset, uint8_t data); void score_w(offs_t offset, u8 data);
uint8_t input_r(); u8 input_r();
void control0_w(offs_t offset, uint8_t data, uint8_t mem_mask); void control0_w(offs_t offset, u8 data, u8 mem_mask);
void control1_w(offs_t offset, uint8_t data, uint8_t mem_mask); void control1_w(offs_t offset, u8 data, u8 mem_mask);
void latch_start_address(); void latch_start_address();
void tugboat_vblank_w(int state); void tugboat_vblank_w(int state);
@ -115,7 +117,7 @@ private:
void tugboat_palette(palette_device &palette) const; void tugboat_palette(palette_device &palette) const;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_tilemap(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer); void draw_tilemap(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer);
void main_map(address_map &map); void main_map(address_map &map);
@ -130,6 +132,7 @@ private:
void tugboat_state::machine_start() void tugboat_state::machine_start()
{ {
m_maincpu->space(AS_PROGRAM).specific(m_program); m_maincpu->space(AS_PROGRAM).specific(m_program);
m_lamps.resolve();
save_item(NAME(m_hd46505_regs)); save_item(NAME(m_hd46505_regs));
save_item(NAME(m_hd46505_reglatch)); save_item(NAME(m_hd46505_reglatch));
@ -156,7 +159,7 @@ void tugboat_state::video_start()
// there isn't the usual resistor array anywhere near the color PROM, just four 1k resistors. // there isn't the usual resistor array anywhere near the color PROM, just four 1k resistors.
void tugboat_state::tugboat_palette(palette_device &palette) const void tugboat_state::tugboat_palette(palette_device &palette) const
{ {
uint8_t const *const color_prom = memregion("proms")->base(); u8 const *const color_prom = memregion("proms")->base();
for (int i = 0; i < palette.entries(); i++) for (int i = 0; i < palette.entries(); i++)
{ {
int const brt = BIT(color_prom[i], 3) ? 0xff : 0x80; int const brt = BIT(color_prom[i], 3) ? 0xff : 0x80;
@ -170,9 +173,9 @@ void tugboat_state::tugboat_palette(palette_device &palette) const
} }
// see mc6845.cpp, I process the writes here because I need the start_addr register to handle coarse scrolling // see mc6845.cpp, coarse scrolling is performed changing the start_addr register (0C/0D)
template<int N> template<int N>
void tugboat_state::hd46505_w(offs_t offset, uint8_t data) void tugboat_state::hd46505_w(offs_t offset, u8 data)
{ {
if (offset == 0) if (offset == 0)
m_hd46505_reglatch[N] = data & 0x1f; m_hd46505_reglatch[N] = data & 0x1f;
@ -214,17 +217,15 @@ void tugboat_state::noahsark_vblank_w(int state)
} }
void tugboat_state::score_w(offs_t offset, uint8_t data) void tugboat_state::score_w(offs_t offset, u8 data)
{ {
if (offset < 8) // to vram layer 1 column 29
m_program.write_byte(0x291d + 32*offset + 32*9, data ^ 0x0f); m_program.write_byte(0x291d + 32 * (offset ^ 8), ~data & 0xf);
else
m_program.write_byte(0x291d + 32*offset + 32*(1-8), data ^ 0x0f);
} }
void tugboat_state::draw_tilemap(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer) void tugboat_state::draw_tilemap(bitmap_ind16 &bitmap, const rectangle &cliprect, int layer)
{ {
uint16_t addr = m_start_address[layer]; u16 addr = m_start_address[layer];
for (int y = 0; y < 32; y++) for (int y = 0; y < 32; y++)
{ {
@ -233,23 +234,19 @@ void tugboat_state::draw_tilemap(bitmap_ind16 &bitmap, const rectangle &cliprect
int attr = m_program.read_byte(addr + 0x400); int attr = m_program.read_byte(addr + 0x400);
int code = ((attr & 0x01) << 8) | m_program.read_byte(addr); int code = ((attr & 0x01) << 8) | m_program.read_byte(addr);
int color = (attr & 0x3c) >> 2; int color = (attr & 0x3c) >> 2;
int rgn, transpen, fx = 0, fy = 0; int rgn = layer * 2 + ((attr & 0x02) >> 1);
int transpen = -1, fx = 0, fy = 0;
if (attr & 0x02) if (layer == 1)
{ {
rgn = layer * 2 + 1; transpen = m_gfxdecode->gfx(rgn)->depth() - 1;
transpen = 7;
// score panel column doesn't scroll
if (x != 29)
fy = m_fine_y_latch;
} }
else else
{ fx = m_fine_x_latch;
rgn = layer * 2;
transpen = 1;
}
if (layer == 0)
fx = m_fine_x_latch & 7;
else if (attr & 0x02)
fy = m_fine_y_latch & 7;
m_gfxdecode->gfx(rgn)->transpen(bitmap,cliprect, m_gfxdecode->gfx(rgn)->transpen(bitmap,cliprect,
code, code,
@ -257,14 +254,14 @@ void tugboat_state::draw_tilemap(bitmap_ind16 &bitmap, const rectangle &cliprect
0, 0, 0, 0,
8 * x + fx, 8 * x + fx,
8 * y - fy, 8 * y - fy,
(layer == 1) ? transpen : -1); transpen);
addr = (addr & 0xfc00) | ((addr + 1) & 0x03ff); addr = (addr & 0xfc00) | ((addr + 1) & 0x03ff);
} }
} }
} }
uint32_t tugboat_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) u32 tugboat_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{ {
draw_tilemap(bitmap, cliprect, 0); draw_tilemap(bitmap, cliprect, 0);
draw_tilemap(bitmap, cliprect, 1); draw_tilemap(bitmap, cliprect, 1);
@ -278,9 +275,9 @@ uint32_t tugboat_state::screen_update(screen_device &screen, bitmap_ind16 &bitma
Misc. I/O Misc. I/O
*******************************************************************************/ *******************************************************************************/
uint8_t tugboat_state::input_r() u8 tugboat_state::input_r()
{ {
uint8_t data = 0xff; u8 data = 0xff;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
if (BIT(m_control[1], i ^ 7)) if (BIT(m_control[1], i ^ 7))
@ -289,17 +286,21 @@ uint8_t tugboat_state::input_r()
return data; return data;
} }
void tugboat_state::control0_w(offs_t offset, uint8_t data, uint8_t mem_mask) void tugboat_state::control0_w(offs_t offset, u8 data, u8 mem_mask)
{ {
data |= ~mem_mask; data |= ~mem_mask;
data = ~data; data = ~data;
// d1,d2: start lamps
m_lamps[0] = BIT(data, 1);
m_lamps[1] = BIT(data, 2);
// d5: coincounter // d5: coincounter
machine().bookkeeping().coin_counter_w(0, BIT(data, 5)); machine().bookkeeping().coin_counter_w(0, BIT(data, 5));
// d6: clock layer 1 fine x scroll // d6: clock layer 1 fine x scroll
if (data & ~m_control[0] & 0x40) if (data & ~m_control[0] & 0x40)
m_fine_x_clock++; m_fine_x_clock = (m_fine_x_clock + 1) & 7;
// d7: clear layer 1 fine x scroll // d7: clear layer 1 fine x scroll
if (data & 0x80) if (data & 0x80)
@ -308,14 +309,14 @@ void tugboat_state::control0_w(offs_t offset, uint8_t data, uint8_t mem_mask)
m_control[0] = data; m_control[0] = data;
} }
void tugboat_state::control1_w(offs_t offset, uint8_t data, uint8_t mem_mask) void tugboat_state::control1_w(offs_t offset, u8 data, u8 mem_mask)
{ {
data |= ~mem_mask; data |= ~mem_mask;
data = ~data; data = ~data;
// d2: clock layer 2 fine y scroll // d2: clock layer 2 fine y scroll
if (data & ~m_control[1] & 4) if (data & ~m_control[1] & 4)
m_fine_y_clock++; m_fine_y_clock = (m_fine_y_clock + 1) & 7;
// d0: clear layer 2 fine y scroll // d0: clear layer 2 fine y scroll
if (data & 1) if (data & 1)
@ -336,7 +337,7 @@ void tugboat_state::main_map(address_map &map)
map.global_mask(0x7fff); map.global_mask(0x7fff);
map(0x0000, 0x01ff).ram(); map(0x0000, 0x01ff).ram();
map(0x1060, 0x1061).w("aysnd", FUNC(ay8910_device::address_data_w)); map(0x1060, 0x1061).w("aysnd", FUNC(ay8910_device::address_data_w));
map(0x10a0, 0x10a1).w(FUNC(tugboat_state::hd46505_w<0>)); // coarse scrolling is performed changing the start_addr register (0C/0D) map(0x10a0, 0x10a1).w(FUNC(tugboat_state::hd46505_w<0>));
map(0x10c0, 0x10c1).w(FUNC(tugboat_state::hd46505_w<1>)); map(0x10c0, 0x10c1).w(FUNC(tugboat_state::hd46505_w<1>));
map(0x11e4, 0x11e7).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write)); map(0x11e4, 0x11e7).rw(m_pia[0], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
map(0x11e8, 0x11eb).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write)); map(0x11e8, 0x11eb).rw(m_pia[1], FUNC(pia6821_device::read), FUNC(pia6821_device::write));
@ -502,8 +503,9 @@ ROM_START( tugboat )
ROM_LOAD( "u69.bin", 0x1000, 0x1000, CRC(e6d25878) SHA1(de9096ef3108d031049be1e7f2c5e346d0bc0df1) ) ROM_LOAD( "u69.bin", 0x1000, 0x1000, CRC(e6d25878) SHA1(de9096ef3108d031049be1e7f2c5e346d0bc0df1) )
ROM_LOAD( "u70.bin", 0x2000, 0x1000, CRC(34ce2850) SHA1(8883126627ed8a1d2c3bed2a3d169ce35eafc8a3) ) ROM_LOAD( "u70.bin", 0x2000, 0x1000, CRC(34ce2850) SHA1(8883126627ed8a1d2c3bed2a3d169ce35eafc8a3) )
ROM_REGION( 0x0800, "gfx3", 0 ) ROM_REGION( 0x0800, "gfx3", ROMREGION_ERASEFF )
ROM_LOAD( "u168.bin", 0x0000, 0x0800, CRC(279042fd) SHA1(1361fff1bc532251bbd36b7b60776c2cc137cfba) ) /* labeled u-167 */ ROM_LOAD( "u168.bin", 0x0000, 0x0080, CRC(279042fd) SHA1(1361fff1bc532251bbd36b7b60776c2cc137cfba) ) /* labeled u-167 */
ROM_IGNORE( 0x0780 )
ROM_REGION( 0x1800, "gfx4", 0 ) ROM_REGION( 0x1800, "gfx4", 0 )
ROM_LOAD( "u170.bin", 0x0000, 0x0800, CRC(64d9f4d7) SHA1(3ff7fc099023512c33ec4583e91e6cbab903e7a8) ) /* labeled u-168 */ ROM_LOAD( "u170.bin", 0x0000, 0x0800, CRC(64d9f4d7) SHA1(3ff7fc099023512c33ec4583e91e6cbab903e7a8) ) /* labeled u-168 */
@ -530,8 +532,9 @@ ROM_START( noahsark )
ROM_LOAD( "u69.bin", 0x1000, 0x1000, CRC(fa2c279c) SHA1(332fcfcfe605c4132114399c32932507b16752e5) ) ROM_LOAD( "u69.bin", 0x1000, 0x1000, CRC(fa2c279c) SHA1(332fcfcfe605c4132114399c32932507b16752e5) )
ROM_LOAD( "u70.bin", 0x2000, 0x1000, CRC(dcabc7c5) SHA1(68abfdedea518e3a5c90f9f72173e8c05e190535) ) ROM_LOAD( "u70.bin", 0x2000, 0x1000, CRC(dcabc7c5) SHA1(68abfdedea518e3a5c90f9f72173e8c05e190535) )
ROM_REGION( 0x0800, "gfx3", 0 ) ROM_REGION( 0x0800, "gfx3", ROMREGION_ERASEFF )
ROM_LOAD( "u168.bin", 0x0000, 0x0800, CRC(7fc7280f) SHA1(93bf46e421b580edf81177db85cb220073761c57) ) /* labeled u-167 */ ROM_LOAD( "u168.bin", 0x0000, 0x0080, CRC(7fc7280f) SHA1(93bf46e421b580edf81177db85cb220073761c57) ) /* labeled u-167 */
ROM_IGNORE( 0x0780 )
ROM_REGION( 0x3000, "gfx4", 0 ) ROM_REGION( 0x3000, "gfx4", 0 )
ROM_LOAD( "u170.bin", 0x0000, 0x1000, CRC(ba36641c) SHA1(df206dc4b6f2da7b60bdaa72c8175de928a630a4) ) /* labeled u-168 */ ROM_LOAD( "u170.bin", 0x0000, 0x1000, CRC(ba36641c) SHA1(df206dc4b6f2da7b60bdaa72c8175de928a630a4) ) /* labeled u-168 */
@ -558,8 +561,9 @@ ROM_START( berenstn )
ROM_LOAD( "u69.bin", 0x1000, 0x1000, CRC(9dc770f6) SHA1(5dc16fac72d68b521dbb415935f5e7f682c26d7f) ) ROM_LOAD( "u69.bin", 0x1000, 0x1000, CRC(9dc770f6) SHA1(5dc16fac72d68b521dbb415935f5e7f682c26d7f) )
ROM_LOAD( "u70.bin", 0x2000, 0x1000, CRC(a810bd45) SHA1(8be531529174c5d4b4f164bd2397116b9d5350db) ) ROM_LOAD( "u70.bin", 0x2000, 0x1000, CRC(a810bd45) SHA1(8be531529174c5d4b4f164bd2397116b9d5350db) )
ROM_REGION( 0x0800, "gfx3", 0 ) ROM_REGION( 0x0800, "gfx3", ROMREGION_ERASEFF )
ROM_LOAD( "u167.bin", 0x0000, 0x0800, CRC(7fc7280f) SHA1(93bf46e421b580edf81177db85cb220073761c57) ) ROM_LOAD( "u167.bin", 0x0000, 0x0080, CRC(7fc7280f) SHA1(93bf46e421b580edf81177db85cb220073761c57) )
ROM_IGNORE( 0x0780 )
ROM_REGION( 0x3000, "gfx4", 0 ) ROM_REGION( 0x3000, "gfx4", 0 )
ROM_LOAD( "u168.bin", 0x0000, 0x0800, CRC(af532ba3) SHA1(b196e294eaf4c25549278fd040b1dad2799e18d5) ) ROM_LOAD( "u168.bin", 0x0000, 0x0800, CRC(af532ba3) SHA1(b196e294eaf4c25549278fd040b1dad2799e18d5) )
@ -567,7 +571,7 @@ ROM_START( berenstn )
ROM_LOAD( "u170.bin", 0x2000, 0x0800, CRC(73261eff) SHA1(19edd6957fceb3df12fd29cd5e156a5eb1c70710) ) ROM_LOAD( "u170.bin", 0x2000, 0x0800, CRC(73261eff) SHA1(19edd6957fceb3df12fd29cd5e156a5eb1c70710) )
ROM_REGION( 0x0100, "proms", 0 ) /* Same as Tugboat but is this actually correct? */ ROM_REGION( 0x0100, "proms", 0 ) /* Same as Tugboat but is this actually correct? */
ROM_LOAD( "n.t.2-031j.24s10", 0x0000, 0x0100, CRC(236672bf) SHA1(57482d0a23223ef7b211045ad28d3e41e90f961e) ) ROM_LOAD( "n.t.2-031j.24s10", 0x0000, 0x0100, BAD_DUMP CRC(236672bf) SHA1(57482d0a23223ef7b211045ad28d3e41e90f961e) )
ROM_END ROM_END
} // anonymous namespace } // anonymous namespace
@ -580,4 +584,4 @@ ROM_END
GAME( 1982, tugboat, 0, tugboat, tugboat, tugboat_state, empty_init, ROT90, "Enter-Tech, Ltd.", "Tugboat", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1982, tugboat, 0, tugboat, tugboat, tugboat_state, empty_init, ROT90, "Enter-Tech, Ltd.", "Tugboat", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1983, noahsark, 0, noahsark, noahsark, tugboat_state, empty_init, ROT90, "Enter-Tech, Ltd.", "Noah's Ark", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1983, noahsark, 0, noahsark, noahsark, tugboat_state, empty_init, ROT90, "Enter-Tech, Ltd.", "Noah's Ark", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1984, berenstn, 0, noahsark, noahsark, tugboat_state, empty_init, ROT90, "Enter-Tech, Ltd.", "The Berenstain Bears in Big Paw's Cave", MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE ) GAME( 1984, berenstn, 0, noahsark, noahsark, tugboat_state, empty_init, ROT90, "Enter-Tech, Ltd.", "The Berenstain Bears in Bigpaw's Cave", MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_SUPPORTS_SAVE )