summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--docs/source/debugger/exceptionpoint.rst134
-rw-r--r--docs/source/debugger/index.rst1
-rw-r--r--src/devices/cpu/z80/z80.cpp30
-rw-r--r--src/devices/imagedev/midiin.cpp4
-rw-r--r--src/devices/imagedev/midiin.h1
-rw-r--r--src/devices/imagedev/midiout.cpp6
-rw-r--r--src/devices/imagedev/midiout.h1
-rw-r--r--src/devices/machine/am79c90.h2
-rw-r--r--src/devices/machine/cs8900a.h2
-rw-r--r--src/devices/machine/dp8390.h2
-rw-r--r--src/devices/machine/dp83932c.h2
-rw-r--r--src/devices/machine/edlc.h1
-rw-r--r--src/devices/machine/i82586.h2
-rw-r--r--src/devices/machine/mb8795.h2
-rw-r--r--src/devices/machine/smc91c9x.h2
-rw-r--r--src/emu/debug/debugcmd.cpp269
-rw-r--r--src/emu/debug/debugcmd.h4
-rw-r--r--src/emu/debug/debugcpu.cpp211
-rw-r--r--src/emu/debug/debugcpu.h45
-rw-r--r--src/emu/debug/debughlp.cpp99
-rw-r--r--src/emu/debug/dvbpoints.cpp2
-rw-r--r--src/emu/debug/dvrpoints.cpp2
-rw-r--r--src/emu/debug/points.cpp68
-rw-r--r--src/emu/debug/points.h48
-rw-r--r--src/emu/dinetwork.cpp2
-rw-r--r--src/emu/emu.h2
-rw-r--r--src/emu/emufwd.h5
-rw-r--r--src/emu/gamedrv.h2
-rw-r--r--src/emu/network.cpp7
-rw-r--r--src/frontend/mame/ui/mainmenu.cpp1
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp1
-rw-r--r--src/lib/formats/fs_fat.cpp2
-rw-r--r--src/mame/arcade.flt4
-rw-r--r--src/mame/atari/atarisy1.cpp1
-rw-r--r--src/mame/atari/atarisy2.cpp10
-rw-r--r--src/mame/atari/atarisy2.h1
-rw-r--r--src/mame/atari/gauntlet.cpp1
-rw-r--r--src/mame/atari/starwars.cpp4
-rw-r--r--src/mame/atari/starwars.h1
-rw-r--r--src/mame/atari/starwars_a.cpp7
-rw-r--r--src/mame/facit/f4431.cpp359
-rw-r--r--src/mame/facit/facit4440.cpp (renamed from src/mame/skeleton/facit4440.cpp)0
-rw-r--r--src/mame/mame.lst23
-rw-r--r--src/mame/mess.flt3
-rw-r--r--src/mame/pinball/de_3.cpp2
-rw-r--r--src/mame/pinball/wpc_s.cpp160
-rw-r--r--src/mame/rm/rmnimbus.h7
-rw-r--r--src/mame/rm/rmnimbus_m.cpp687
-rw-r--r--src/mame/robotron/z1013.cpp63
-rw-r--r--src/mame/sega/eshockey.cpp233
-rw-r--r--src/mame/sega/model3.cpp6
-rw-r--r--src/mame/sega/segaybd.cpp1
-rw-r--r--src/mame/taito/groundfx.cpp417
-rw-r--r--src/mame/taito/groundfx.h72
-rw-r--r--src/mame/taito/groundfx_v.cpp261
-rw-r--r--src/mame/taito/pitnrun.cpp663
-rw-r--r--src/mame/taito/pitnrun.h103
-rw-r--r--src/mame/taito/pitnrun_m.cpp162
-rw-r--r--src/mame/taito/pitnrun_v.cpp276
-rw-r--r--src/mame/taito/rollrace.cpp493
-rw-r--r--src/mame/taito/rollrace.h81
-rw-r--r--src/mame/taito/rollrace_v.cpp212
-rw-r--r--src/mame/taito/ssrj.cpp370
-rw-r--r--src/mame/taito/ssrj.h68
-rw-r--r--src/mame/taito/ssrj_v.cpp293
-rw-r--r--src/mame/taito/volfied.cpp313
-rw-r--r--src/mame/taito/volfied.h72
-rw-r--r--src/mame/taito/volfied_v.cpp129
-rw-r--r--src/mame/taito/warriorb.cpp444
-rw-r--r--src/mame/taito/warriorb.h75
-rw-r--r--src/mame/taito/warriorb_v.cpp108
-rw-r--r--src/mame/tecmo/spbactn.cpp22
-rw-r--r--src/mame/universal/getaway.cpp164
-rw-r--r--src/mame/universal/ladybug.cpp651
-rw-r--r--src/mame/universal/ladybug.h159
-rw-r--r--src/mame/universal/ladybug_v.cpp513
-rw-r--r--src/mame/universal/ladybug_video.cpp111
-rw-r--r--src/mame/universal/ladybug_video.h (renamed from src/mame/universal/ladybug_v.h)35
-rw-r--r--src/mame/universal/redclash.h73
-rw-r--r--src/mame/universal/redclash_v.cpp259
-rw-r--r--src/mame/universal/sraider.cpp756
-rw-r--r--src/mame/universal/zerohour.cpp (renamed from src/mame/universal/redclash.cpp)779
-rw-r--r--src/mame/universal/zerohour_stars.cpp127
-rw-r--r--src/mame/universal/zerohour_stars.h42
-rw-r--r--src/osd/modules/debugger/debuggdbstub.cpp6
-rw-r--r--src/osd/modules/debugger/osx/disassemblyviewer.mm2
-rw-r--r--src/osd/modules/debugger/qt/dasmwindow.cpp2
-rw-r--r--src/osd/modules/debugger/win/disasmbasewininfo.cpp2
-rw-r--r--src/osd/modules/lib/osdobj_common.cpp1
-rw-r--r--src/osd/modules/midi/portmidi.cpp5
-rw-r--r--src/osd/modules/netdev/pcap.cpp1
-rw-r--r--src/osd/modules/netdev/taptun.cpp1
-rw-r--r--src/osd/modules/render/bgfx/statereader.cpp1
-rw-r--r--src/osd/osdcore.h23
-rw-r--r--src/osd/osdepend.h19
-rw-r--r--src/osd/osdnet.cpp3
-rw-r--r--src/osd/osdnet.h1
-rw-r--r--src/tools/imgtool/imgtool.cpp1
-rw-r--r--src/tools/imgtool/stream.cpp1
99 files changed, 5791 insertions, 5116 deletions
diff --git a/docs/source/debugger/exceptionpoint.rst b/docs/source/debugger/exceptionpoint.rst
new file mode 100644
index 00000000000..52a8ee67a19
--- /dev/null
+++ b/docs/source/debugger/exceptionpoint.rst
@@ -0,0 +1,134 @@
+.. _debugger-exceptionpoint-list:
+
+Exception Point Debugger Commands
+=================================
+
+:ref:`debugger-command-epset`
+ sets a new exception point
+:ref:`debugger-command-epclear`
+ clears a specific exception point or all exception points
+:ref:`debugger-command-epdisable`
+ disables a specific exception point or all exception points
+:ref:`debugger-command-epenable`
+ enables a specific exception point or all exception points
+:ref:`debugger-command-eplist`
+ lists exception points
+
+Exception points halt execution and activate the debugger when
+a CPU raises a particular exception number.
+
+
+.. _debugger-command-epset:
+
+epset
+-----
+
+**ep[set] <type>[,<condition>[,<action>]]**
+
+Sets a new exception point for exceptions of type **<type>**. The
+optional **<condition>** parameter lets you specify an expression that
+will be evaluated each time the exception point is hit. If the result
+of the expression is true (non-zero), the exception point will actually
+halt execution at the start of the exception handler; otherwise,
+execution will continue with no notification. The optional **<action>**
+parameter provides a command that is executed whenever the exception
+point is hit and the **<condition>** is true. Note that you may need to
+embed the action within braces ``{ }`` in order to prevent commas and
+semicolons from being interpreted as applying to the ``epset`` command
+itself.
+
+The numbering of exceptions depends upon the CPU type. Causes of
+exceptions may include internally or externally vectored interrupts,
+errors occurring within instructions and system calls.
+
+Each exception point that is set is assigned an index which can be used
+in other exception point commands to reference this exception point.
+
+Examples:
+
+``ep 2``
+ Set an exception that will halt execution whenever the visible CPU
+ raises exception number 2.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-epclear:
+
+epclear
+-------
+
+**epclear [<epnum>[,…]]**
+
+The epclear command clears exception points. If **<epnum>** is
+specified, only the requested exception points are cleared, otherwise
+all exception points are cleared.
+
+Examples:
+
+``epclear 3``
+ Clear exception point index 3.
+
+``epclear``
+ Clear all exception points.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-epdisable:
+
+epdisable
+---------
+
+**epdisable [<epnum>[,…]]**
+
+The epdisable command disables exception points. If **<epnum>** is
+specified, only the requested exception points are disabled, otherwise
+all exception points are disabled. Note that disabling an exception
+point does not delete it, it just temporarily marks the exception
+point as inactive.
+
+Examples:
+
+``epdisable 3``
+ Disable exception point index 3.
+
+``epdisable``
+ Disable all exception points.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-epenable:
+
+epenable
+--------
+
+**epenable [<epnum>[,…]]**
+
+The epenable command enables exception points. If **<epnum>** is
+specified, only the requested exception points are enabled, otherwise
+all exception points are enabled.
+
+Examples:
+
+``epenable 3``
+ Enable exception point index 3.
+
+``epenable``
+ Enable all exception points.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-eplist:
+
+eplist
+------
+
+**eplist**
+
+The eplist command lists all the current exception points, along with
+their index and any conditions or actions attached to them.
+
+Back to :ref:`debugger-exceptionpoint-list`
diff --git a/docs/source/debugger/index.rst b/docs/source/debugger/index.rst
index 4b6cd02d2ba..3db394f7516 100644
--- a/docs/source/debugger/index.rst
+++ b/docs/source/debugger/index.rst
@@ -50,6 +50,7 @@ name of a command, to see documentation directly in MAME.
breakpoint
watchpoint
registerpoints
+ exceptionpoint
annotation
cheats
image
diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp
index a43fec45327..86d9d29469b 100644
--- a/src/devices/cpu/z80/z80.cpp
+++ b/src/devices/cpu/z80/z80.cpp
@@ -640,7 +640,7 @@ inline void z80_device::jr_cond(bool cond, uint8_t opcode)
}
else
{
- WZ = arg();
+ arg();
//nomreq_addr(PCD, 3);
//PC++;
}
@@ -2714,8 +2714,8 @@ OP(ed,3d) { illegal_2(); } /* DB ED
OP(ed,3e) { illegal_2(); } /* DB ED */
OP(ed,3f) { illegal_2(); } /* DB ED */
-OP(ed,40) { B = in(BC); F = (F & CF) | SZP[B]; } /* IN B,(C) */
-OP(ed,41) { out(BC, B); } /* OUT (C),B */
+OP(ed,40) { B = in(BC); F = (F & CF) | SZP[B]; WZ = BC + 1; } /* IN B,(C) */
+OP(ed,41) { out(BC, B); WZ = BC + 1; } /* OUT (C),B */
OP(ed,42) { sbc_hl(m_bc); } /* SBC HL,BC */
OP(ed,43) { m_ea = arg16(); wm16(m_ea, m_bc); WZ = m_ea + 1; } /* LD (w),BC */
OP(ed,44) { neg(); } /* NEG */
@@ -2723,8 +2723,8 @@ OP(ed,45) { retn(); } /* RETN
OP(ed,46) { m_im = 0; } /* IM 0 */
OP(ed,47) { ld_i_a(); } /* LD i,A */
-OP(ed,48) { C = in(BC); F = (F & CF) | SZP[C]; } /* IN C,(C) */
-OP(ed,49) { out(BC, C); } /* OUT (C),C */
+OP(ed,48) { C = in(BC); F = (F & CF) | SZP[C]; WZ = BC + 1; } /* IN C,(C) */
+OP(ed,49) { out(BC, C); WZ = BC + 1; } /* OUT (C),C */
OP(ed,4a) { adc_hl(m_bc); } /* ADC HL,BC */
OP(ed,4b) { m_ea = arg16(); rm16(m_ea, m_bc); WZ = m_ea + 1; } /* LD BC,(w) */
OP(ed,4c) { neg(); } /* NEG */
@@ -2732,8 +2732,8 @@ OP(ed,4d) { reti(); } /* RETI
OP(ed,4e) { m_im = 0; } /* IM 0 */
OP(ed,4f) { ld_r_a(); } /* LD r,A */
-OP(ed,50) { D = in(BC); F = (F & CF) | SZP[D]; } /* IN D,(C) */
-OP(ed,51) { out(BC, D); } /* OUT (C),D */
+OP(ed,50) { D = in(BC); F = (F & CF) | SZP[D]; WZ = BC + 1; } /* IN D,(C) */
+OP(ed,51) { out(BC, D); WZ = BC + 1; } /* OUT (C),D */
OP(ed,52) { sbc_hl(m_de); } /* SBC HL,DE */
OP(ed,53) { m_ea = arg16(); wm16(m_ea, m_de); WZ = m_ea + 1; } /* LD (w),DE */
OP(ed,54) { neg(); } /* NEG */
@@ -2741,8 +2741,8 @@ OP(ed,55) { retn(); } /* RETN
OP(ed,56) { m_im = 1; } /* IM 1 */
OP(ed,57) { ld_a_i(); } /* LD A,i */
-OP(ed,58) { E = in(BC); F = (F & CF) | SZP[E]; } /* IN E,(C) */
-OP(ed,59) { out(BC, E); } /* OUT (C),E */
+OP(ed,58) { E = in(BC); F = (F & CF) | SZP[E]; WZ = BC + 1; } /* IN E,(C) */
+OP(ed,59) { out(BC, E); WZ = BC + 1; } /* OUT (C),E */
OP(ed,5a) { adc_hl(m_de); } /* ADC HL,DE */
OP(ed,5b) { m_ea = arg16(); rm16(m_ea, m_de); WZ = m_ea + 1; } /* LD DE,(w) */
OP(ed,5c) { neg(); } /* NEG */
@@ -2750,8 +2750,8 @@ OP(ed,5d) { reti(); } /* RETI
OP(ed,5e) { m_im = 2; } /* IM 2 */
OP(ed,5f) { ld_a_r(); } /* LD A,r */
-OP(ed,60) { H = in(BC); F = (F & CF) | SZP[H]; } /* IN H,(C) */
-OP(ed,61) { out(BC, H); } /* OUT (C),H */
+OP(ed,60) { H = in(BC); F = (F & CF) | SZP[H]; WZ = BC + 1; } /* IN H,(C) */
+OP(ed,61) { out(BC, H); WZ = BC + 1; } /* OUT (C),H */
OP(ed,62) { sbc_hl(m_hl); } /* SBC HL,HL */
OP(ed,63) { m_ea = arg16(); wm16(m_ea, m_hl); WZ = m_ea + 1; } /* LD (w),HL */
OP(ed,64) { neg(); } /* NEG */
@@ -2759,8 +2759,8 @@ OP(ed,65) { retn(); } /* RETN
OP(ed,66) { m_im = 0; } /* IM 0 */
OP(ed,67) { rrd(); } /* RRD (HL) */
-OP(ed,68) { L = in(BC); F = (F & CF) | SZP[L]; } /* IN L,(C) */
-OP(ed,69) { out(BC, L); } /* OUT (C),L */
+OP(ed,68) { L = in(BC); F = (F & CF) | SZP[L]; WZ = BC + 1; } /* IN L,(C) */
+OP(ed,69) { out(BC, L); WZ = BC + 1; } /* OUT (C),L */
OP(ed,6a) { adc_hl(m_hl); } /* ADC HL,HL */
OP(ed,6b) { m_ea = arg16(); rm16(m_ea, m_hl); WZ = m_ea + 1; } /* LD HL,(w) */
OP(ed,6c) { neg(); } /* NEG */
@@ -2768,8 +2768,8 @@ OP(ed,6d) { reti(); } /* RETI
OP(ed,6e) { m_im = 0; } /* IM 0 */
OP(ed,6f) { rld(); } /* RLD (HL) */
-OP(ed,70) { uint8_t res = in(BC); F = (F & CF) | SZP[res]; } /* IN 0,(C) */
-OP(ed,71) { out(BC, 0); } /* OUT (C),0 */
+OP(ed,70) { u8 res = in(BC); F = (F & CF) | SZP[res]; WZ = BC + 1; } /* IN 0,(C) */
+OP(ed,71) { out(BC, 0); WZ = BC + 1; } /* OUT (C),0 */
OP(ed,72) { sbc_hl(m_sp); } /* SBC HL,SP */
OP(ed,73) { m_ea = arg16(); wm16(m_ea, m_sp); WZ = m_ea + 1; } /* LD (w),SP */
OP(ed,74) { neg(); } /* NEG */
diff --git a/src/devices/imagedev/midiin.cpp b/src/devices/imagedev/midiin.cpp
index dc15ea3980f..59211d06f88 100644
--- a/src/devices/imagedev/midiin.cpp
+++ b/src/devices/imagedev/midiin.cpp
@@ -62,6 +62,10 @@ midiin_device::midiin_device(const machine_config &mconfig, const char *tag, dev
{
}
+midiin_device::~midiin_device()
+{
+}
+
ioport_constructor midiin_device::device_input_ports() const
{
return INPUT_PORTS_NAME(midiin);
diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h
index 3d39a88c845..aed7d3b15a9 100644
--- a/src/devices/imagedev/midiin.h
+++ b/src/devices/imagedev/midiin.h
@@ -27,6 +27,7 @@ class midiin_device : public device_t,
public:
// construction/destruction
midiin_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ ~midiin_device();
auto input_callback() { return m_input_cb.bind(); }
diff --git a/src/devices/imagedev/midiout.cpp b/src/devices/imagedev/midiout.cpp
index e9551a50d17..026b6520143 100644
--- a/src/devices/imagedev/midiout.cpp
+++ b/src/devices/imagedev/midiout.cpp
@@ -9,8 +9,8 @@
*********************************************************************/
#include "emu.h"
-#include "osdepend.h"
#include "midiout.h"
+#include "osdepend.h"
/***************************************************************************
IMPLEMENTATION
@@ -30,6 +30,10 @@ midiout_device::midiout_device(const machine_config &mconfig, const char *tag, d
{
}
+midiout_device::~midiout_device()
+{
+}
+
/*-------------------------------------------------
device_start
-------------------------------------------------*/
diff --git a/src/devices/imagedev/midiout.h b/src/devices/imagedev/midiout.h
index 0701c9b3d83..7b39e4fff5e 100644
--- a/src/devices/imagedev/midiout.h
+++ b/src/devices/imagedev/midiout.h
@@ -27,6 +27,7 @@ class midiout_device : public device_t,
public:
// construction/destruction
midiout_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ ~midiout_device();
// image-level overrides
virtual image_init_result call_load() override;
diff --git a/src/devices/machine/am79c90.h b/src/devices/machine/am79c90.h
index 06ec00558b7..80c66ff58ce 100644
--- a/src/devices/machine/am79c90.h
+++ b/src/devices/machine/am79c90.h
@@ -6,7 +6,7 @@
#pragma once
-#include "hashing.h"
+#include "dinetwork.h"
class am7990_device_base : public device_t, public device_network_interface
{
diff --git a/src/devices/machine/cs8900a.h b/src/devices/machine/cs8900a.h
index 74e4c8b20b3..a0a6f88dbb4 100644
--- a/src/devices/machine/cs8900a.h
+++ b/src/devices/machine/cs8900a.h
@@ -16,6 +16,8 @@
#pragma once
+#include "dinetwork.h"
+
#include <queue>
/***************************************************************************
diff --git a/src/devices/machine/dp8390.h b/src/devices/machine/dp8390.h
index 1dfde1f01a5..7e87ffe44db 100644
--- a/src/devices/machine/dp8390.h
+++ b/src/devices/machine/dp8390.h
@@ -5,6 +5,8 @@
#pragma once
+#include "dinetwork.h"
+
// device stuff
diff --git a/src/devices/machine/dp83932c.h b/src/devices/machine/dp83932c.h
index ef91d08313d..2a7d271eb11 100644
--- a/src/devices/machine/dp83932c.h
+++ b/src/devices/machine/dp83932c.h
@@ -6,6 +6,8 @@
#pragma once
+#include "dinetwork.h"
+
class dp83932c_device
: public device_t
, public device_network_interface
diff --git a/src/devices/machine/edlc.h b/src/devices/machine/edlc.h
index 1a57841212a..bbcd91d2589 100644
--- a/src/devices/machine/edlc.h
+++ b/src/devices/machine/edlc.h
@@ -7,6 +7,7 @@
#pragma once
#include "machine/bankdev.h"
+#include "dinetwork.h"
class seeq8003_device :
public device_t,
diff --git a/src/devices/machine/i82586.h b/src/devices/machine/i82586.h
index 89d421a2cf9..82f48163620 100644
--- a/src/devices/machine/i82586.h
+++ b/src/devices/machine/i82586.h
@@ -6,6 +6,8 @@
#pragma once
+#include "dinetwork.h"
+
class i82586_base_device :
public device_t,
public device_memory_interface,
diff --git a/src/devices/machine/mb8795.h b/src/devices/machine/mb8795.h
index 7129f047ebe..57daf378f66 100644
--- a/src/devices/machine/mb8795.h
+++ b/src/devices/machine/mb8795.h
@@ -3,6 +3,8 @@
#ifndef MAME_MACHINE_MB8795_H
#define MAME_MACHINE_MB8795_H
+#include "dinetwork.h"
+
class mb8795_device : public device_t,
public device_network_interface
{
diff --git a/src/devices/machine/smc91c9x.h b/src/devices/machine/smc91c9x.h
index 2942e77572a..e1c91a3e566 100644
--- a/src/devices/machine/smc91c9x.h
+++ b/src/devices/machine/smc91c9x.h
@@ -13,6 +13,8 @@
#pragma once
+#include "dinetwork.h"
+
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index 7ef0110031e..30ad53d762b 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -282,6 +282,13 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("rpenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_rpdisenable, this, true, _1));
m_console.register_command("rplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rplist, this, _1));
+ m_console.register_command("epset", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_epset, this, _1));
+ m_console.register_command("ep", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_epset, this, _1));
+ m_console.register_command("epclear", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epclear, this, _1));
+ m_console.register_command("epdisable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epdisenable, this, false, _1));
+ m_console.register_command("epenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epdisenable, this, true, _1));
+ m_console.register_command("eplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_eplist, this, _1));
+
m_console.register_command("statesave", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1));
m_console.register_command("ss", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1));
m_console.register_command("stateload", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1));
@@ -471,8 +478,9 @@ bool debugger_commands::validate_boolean_parameter(std::string_view param, bool
return true;
// evaluate the expression; success if no error
- bool const is_true = util::streqlower(param, "true");
- bool const is_false = util::streqlower(param, "false");
+ using namespace std::literals;
+ bool const is_true = util::streqlower(param, "true"sv);
+ bool const is_false = util::streqlower(param, "false"sv);
if (is_true || is_false)
{
@@ -1153,7 +1161,7 @@ void debugger_commands::execute_tracelog(const std::vector<std::string_view> &pa
/* then do a printf */
std::ostringstream buffer;
if (mini_printf(buffer, params[0], params.size() - 1, &values[1]))
- m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str().c_str());
+ m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str());
}
@@ -1189,7 +1197,7 @@ void debugger_commands::execute_tracesym(const std::vector<std::string_view> &pa
// then do a printf
std::ostringstream buffer;
if (mini_printf(buffer, format.str(), params.size(), values))
- m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str().c_str());
+ m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str());
}
@@ -1819,12 +1827,12 @@ void debugger_commands::execute_bpset(const std::vector<std::string_view> &param
return;
// param 3 is the action
- std::string action;
+ std::string_view action;
if (params.size() > 2 && !debug_command_parameter_command(action = params[2]))
return;
// set the breakpoint
- int const bpnum = debug->breakpoint_set(address, condition.is_empty() ? nullptr : condition.original_string(), action.c_str());
+ int const bpnum = debug->breakpoint_set(address, condition.is_empty() ? nullptr : condition.original_string(), action);
m_console.printf("Breakpoint %X set\n", bpnum);
}
@@ -1966,16 +1974,20 @@ void debugger_commands::execute_wpset(int spacenum, const std::vector<std::strin
// param 3 is the type
read_or_write type;
- if (util::streqlower(params[2], "r"))
- type = read_or_write::READ;
- else if (util::streqlower(params[2], "w"))
- type = read_or_write::WRITE;
- else if (util::streqlower(params[2], "rw") || util::streqlower(params[2], "wr"))
- type = read_or_write::READWRITE;
- else
{
- m_console.printf("Invalid watchpoint type: expected r, w, or rw\n");
- return;
+ using util::streqlower;
+ using namespace std::literals;
+ if (streqlower(params[2], "r"sv))
+ type = read_or_write::READ;
+ else if (streqlower(params[2], "w"sv))
+ type = read_or_write::WRITE;
+ else if (streqlower(params[2], "rw"sv) || streqlower(params[2], "wr"sv))
+ type = read_or_write::READWRITE;
+ else
+ {
+ m_console.printf("Invalid watchpoint type: expected r, w, or rw\n");
+ return;
+ }
}
// param 4 is the condition
@@ -1984,12 +1996,12 @@ void debugger_commands::execute_wpset(int spacenum, const std::vector<std::strin
return;
// param 5 is the action
- std::string action;
+ std::string_view action;
if (params.size() > 4 && !debug_command_parameter_command(action = params[4]))
return;
// set the watchpoint
- int const wpnum = debug->watchpoint_set(*space, type, address, length, (condition.is_empty()) ? nullptr : condition.original_string(), action.c_str());
+ int const wpnum = debug->watchpoint_set(*space, type, address, length, (condition.is_empty()) ? nullptr : condition.original_string(), action);
m_console.printf("Watchpoint %X set\n", wpnum);
}
@@ -2133,12 +2145,12 @@ void debugger_commands::execute_rpset(const std::vector<std::string_view> &param
return;
// param 2 is the action
- std::string action;
+ std::string_view action;
if (params.size() > 1 && !debug_command_parameter_command(action = params[1]))
return;
// set the registerpoint
- int const rpnum = cpu->debug()->registerpoint_set(condition.original_string(), action.c_str());
+ int const rpnum = cpu->debug()->registerpoint_set(condition.original_string(), action);
m_console.printf("Registerpoint %X set\n", rpnum);
}
@@ -2201,6 +2213,148 @@ void debugger_commands::execute_rpdisenable(bool enable, const std::vector<std::
}
+//-------------------------------------------------
+// execute_epset - execute the exception point
+// set command
+//-------------------------------------------------
+
+void debugger_commands::execute_epset(const std::vector<std::string_view> &params)
+{
+ // CPU is implicit
+ device_t *cpu;
+ if (!validate_cpu_parameter(std::string_view(), cpu))
+ return;
+
+ // param 1 is the exception type
+ u64 type;
+ if (!validate_number_parameter(params[0], type))
+ return;
+
+ // param 2 is the condition
+ parsed_expression condition(cpu->debug()->symtable());
+ if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition))
+ return;
+
+ // param 3 is the action
+ std::string_view action;
+ if (params.size() > 2 && !debug_command_parameter_command(action = params[2]))
+ return;
+
+ // set the exception point
+ int epnum = cpu->debug()->exceptionpoint_set(type, (condition.is_empty()) ? nullptr : condition.original_string(), action);
+ m_console.printf("Exception point %X set\n", epnum);
+}
+
+
+//-------------------------------------------------
+// execute_epclear - execute the exception point
+// clear command
+//-------------------------------------------------
+
+void debugger_commands::execute_epclear(const std::vector<std::string_view> &params)
+{
+ if (params.empty()) // if no parameters, clear all
+ {
+ for (device_t &device : device_enumerator(m_machine.root_device()))
+ device.debug()->exceptionpoint_clear_all();
+ m_console.printf("Cleared all exception points\n");
+ }
+ else // otherwise, clear the specific ones
+ {
+ execute_index_command(
+ params,
+ [this] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->exceptionpoint_clear(param))
+ return false;
+ m_console.printf("Exception point %X cleared\n", param);
+ return true;
+ },
+ "Invalid exception point number %X\n");
+ }
+}
+
+
+//-------------------------------------------------
+// execute_epdisenable - execute the exception
+// point disable/enable commands
+//-------------------------------------------------
+
+void debugger_commands::execute_epdisenable(bool enable, const std::vector<std::string_view> &params)
+{
+ if (params.empty()) // if no parameters, disable/enable all
+ {
+ for (device_t &device : device_enumerator(m_machine.root_device()))
+ device.debug()->exceptionpoint_enable_all(enable);
+ m_console.printf(enable ? "Enabled all exception points\n" : "Disabled all exception points\n");
+ }
+ else // otherwise, disable/enable the specific ones
+ {
+ execute_index_command(
+ params,
+ [this, enable] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->exceptionpoint_enable(param, enable))
+ return false;
+ m_console.printf(enable ? "Exception point %X enabled\n" : "Exception point %X disabled\n", param);
+ return true;
+ },
+ "Invalid exception point number %X\n");
+ }
+}
+
+
+//-------------------------------------------------
+// execute_eplist - execute the exception point
+// list command
+//-------------------------------------------------
+
+void debugger_commands::execute_eplist(const std::vector<std::string_view> &params)
+{
+ int printed = 0;
+ std::string buffer;
+ auto const apply =
+ [this, &printed, &buffer] (device_t &device)
+ {
+ if (!device.debug()->exceptionpoint_list().empty())
+ {
+ m_console.printf("Device '%s' exception points:\n", device.tag());
+
+ // loop over the exception points
+ for (const auto &epp : device.debug()->exceptionpoint_list())
+ {
+ debug_exceptionpoint &ep = *epp.second;
+ buffer = string_format("%c%4X : %X", ep.enabled() ? ' ' : 'D', ep.index(), ep.type());
+ if (std::string(ep.condition()).compare("1") != 0)
+ buffer.append(string_format(" if %s", ep.condition()));
+ if (!ep.action().empty())
+ buffer.append(string_format(" do %s", ep.action()));
+ m_console.printf("%s\n", buffer);
+ printed++;
+ }
+ }
+ };
+
+ if (!params.empty())
+ {
+ device_t *cpu;
+ if (!validate_cpu_parameter(params[0], cpu))
+ return;
+ apply(*cpu);
+ if (!printed)
+ m_console.printf("No exception points currently installed for CPU %s\n", cpu->tag());
+ }
+ else
+ {
+ // loop over all CPUs
+ for (device_t &device : device_enumerator(m_machine.root_device()))
+ apply(device);
+ if (!printed)
+ m_console.printf("No exception points currently installed\n");
+ }
+}
+
+
/*-------------------------------------------------
execute_rplist - execute the registerpoint list
command
@@ -2221,7 +2375,7 @@ void debugger_commands::execute_rplist(const std::vector<std::string_view> &para
for (const auto &rp : device.debug()->registerpoint_list())
{
buffer = string_format("%c%4X if %s", rp.enabled() ? ' ' : 'D', rp.index(), rp.condition());
- if (rp.action() && *rp.action())
+ if (!rp.action().empty())
buffer.append(string_format(" do %s", rp.action()));
m_console.printf("%s\n", buffer);
printed++;
@@ -3129,30 +3283,34 @@ void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::s
// decode condition
u8 condition;
- if (util::streqlower(params[0], "all"))
- condition = CHEAT_ALL;
- else if (util::streqlower(params[0], "equal") || util::streqlower(params[0], "eq"))
- condition = (params.size() > 1) ? CHEAT_EQUALTO : CHEAT_EQUAL;
- else if (util::streqlower(params[0], "notequal") || util::streqlower(params[0], "ne"))
- condition = (params.size() > 1) ? CHEAT_NOTEQUALTO : CHEAT_NOTEQUAL;
- else if (util::streqlower(params[0], "decrease") || util::streqlower(params[0], "de") || params[0] == "-")
- condition = (params.size() > 1) ? CHEAT_DECREASEOF : CHEAT_DECREASE;
- else if (util::streqlower(params[0], "increase") || util::streqlower(params[0], "in") || params[0] == "+")
- condition = (params.size() > 1) ? CHEAT_INCREASEOF : CHEAT_INCREASE;
- else if (util::streqlower(params[0], "decreaseorequal") || util::streqlower(params[0], "deeq"))
- condition = CHEAT_DECREASE_OR_EQUAL;
- else if (util::streqlower(params[0], "increaseorequal") || util::streqlower(params[0], "ineq"))
- condition = CHEAT_INCREASE_OR_EQUAL;
- else if (util::streqlower(params[0], "smallerof") || util::streqlower(params[0], "lt") || params[0] == "<")
- condition = CHEAT_SMALLEROF;
- else if (util::streqlower(params[0], "greaterof") || util::streqlower(params[0], "gt") || params[0] == ">")
- condition = CHEAT_GREATEROF;
- else if (util::streqlower(params[0], "changedby") || util::streqlower(params[0], "ch") || params[0] == "~")
- condition = CHEAT_CHANGEDBY;
- else
{
- m_console.printf("Invalid condition type\n");
- return;
+ using util::streqlower;
+ using namespace std::literals;
+ if (streqlower(params[0], "all"sv))
+ condition = CHEAT_ALL;
+ else if (streqlower(params[0], "equal"sv) || streqlower(params[0], "eq"sv))
+ condition = (params.size() > 1) ? CHEAT_EQUALTO : CHEAT_EQUAL;
+ else if (streqlower(params[0], "notequal"sv) || streqlower(params[0], "ne"sv))
+ condition = (params.size() > 1) ? CHEAT_NOTEQUALTO : CHEAT_NOTEQUAL;
+ else if (streqlower(params[0], "decrease"sv) || streqlower(params[0], "de"sv) || params[0] == "-"sv)
+ condition = (params.size() > 1) ? CHEAT_DECREASEOF : CHEAT_DECREASE;
+ else if (streqlower(params[0], "increase"sv) || streqlower(params[0], "in"sv) || params[0] == "+"sv)
+ condition = (params.size() > 1) ? CHEAT_INCREASEOF : CHEAT_INCREASE;
+ else if (streqlower(params[0], "decreaseorequal"sv) || streqlower(params[0], "deeq"sv))
+ condition = CHEAT_DECREASE_OR_EQUAL;
+ else if (streqlower(params[0], "increaseorequal"sv) || streqlower(params[0], "ineq"sv))
+ condition = CHEAT_INCREASE_OR_EQUAL;
+ else if (streqlower(params[0], "smallerof"sv) || streqlower(params[0], "lt"sv) || params[0] == "<"sv)
+ condition = CHEAT_SMALLEROF;
+ else if (streqlower(params[0], "greaterof"sv) || streqlower(params[0], "gt"sv) || params[0] == ">"sv)
+ condition = CHEAT_GREATEROF;
+ else if (streqlower(params[0], "changedby"sv) || streqlower(params[0], "ch"sv) || params[0] == "~"sv)
+ condition = CHEAT_CHANGEDBY;
+ else
+ {
+ m_console.printf("Invalid condition type\n");
+ return;
+ }
}
m_cheat.undo++;
@@ -3754,17 +3912,16 @@ void debugger_commands::execute_dasm(const std::vector<std::string_view> &params
void debugger_commands::execute_trace(const std::vector<std::string_view> &params, bool trace_over)
{
- std::string action;
+ std::string_view action;
bool detect_loops = true;
bool logerror = false;
- device_t *cpu;
- const char *mode;
std::string filename(params[0]);
// replace macros
strreplace(filename, "{game}", m_machine.basename());
// validate parameters
+ device_t *cpu;
if (!validate_cpu_parameter(params.size() > 1 ? params[1] : std::string_view(), cpu))
return;
if (params.size() > 2)
@@ -3775,9 +3932,10 @@ void debugger_commands::execute_trace(const std::vector<std::string_view> &param
std::string flag;
while (std::getline(stream, flag, '|'))
{
- if (util::streqlower(flag, "noloop"))
+ using namespace std::literals;
+ if (util::streqlower(flag, "noloop"sv))
detect_loops = false;
- else if (util::streqlower(flag, "logerror"))
+ else if (util::streqlower(flag, "logerror"sv))
logerror = true;
else
{
@@ -3790,19 +3948,22 @@ void debugger_commands::execute_trace(const std::vector<std::string_view> &param
return;
// open the file
- FILE *f = nullptr;
- if (!util::streqlower(filename, "off"))
+ std::unique_ptr<std::ofstream> f;
+ using namespace std::literals;
+ if (!util::streqlower(filename, "off"sv))
{
- mode = "w";
+ std::ios_base::openmode mode = std::ios_base::out;
// opening for append?
if ((filename[0] == '>') && (filename[1] == '>'))
{
- mode = "a";
+ mode |= std::ios_base::ate;
filename = filename.substr(2);
}
+ else
+ mode |= std::ios_base::trunc;
- f = fopen(filename.c_str(), mode);
+ f = std::make_unique<std::ofstream>(filename.c_str(), mode);
if (!f)
{
m_console.printf("Error opening file '%s'\n", params[0]);
@@ -3811,7 +3972,7 @@ void debugger_commands::execute_trace(const std::vector<std::string_view> &param
}
// do it
- cpu->debug()->trace(f, trace_over, detect_loops, logerror, action.c_str());
+ cpu->debug()->trace(std::move(f), trace_over, detect_loops, logerror, action);
if (f)
m_console.printf("Tracing CPU '%s' to file %s\n", cpu->tag(), filename);
else
diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h
index 9ede662511a..8c5e29fecae 100644
--- a/src/emu/debug/debugcmd.h
+++ b/src/emu/debug/debugcmd.h
@@ -148,6 +148,10 @@ private:
void execute_rpclear(const std::vector<std::string_view> &params);
void execute_rpdisenable(bool enable, const std::vector<std::string_view> &params);
void execute_rplist(const std::vector<std::string_view> &params);
+ void execute_epset(const std::vector<std::string_view> &params);
+ void execute_epclear(const std::vector<std::string_view> &params);
+ void execute_epdisenable(bool enable, const std::vector<std::string_view> &params);
+ void execute_eplist(const std::vector<std::string_view> &params);
void execute_statesave(const std::vector<std::string_view> &params);
void execute_stateload(const std::vector<std::string_view> &params);
void execute_rewind(const std::vector<std::string_view> &params);
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 820d9e72688..aba79d74036 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -47,6 +47,7 @@ debugger_cpu::debugger_cpu(running_machine &machine)
, m_bpindex(1)
, m_wpindex(1)
, m_rpindex(1)
+ , m_epindex(1)
, m_wpdata(0)
, m_wpaddr(0)
, m_wpsize(0)
@@ -424,7 +425,6 @@ device_debug::device_debug(device_t &device)
, m_disasm(nullptr)
, m_flags(0)
, m_symtable(std::make_unique<symbol_table>(device.machine(), &device.machine().debugger().cpu().global_symtable(), &device))
- , m_instrhook(nullptr)
, m_stepaddr(0)
, m_stepsleft(0)
, m_delay_steps(0)
@@ -438,7 +438,8 @@ device_debug::device_debug(device_t &device)
, m_pc_history_index(0)
, m_pc_history_valid(0)
, m_bplist()
- , m_rplist(std::make_unique<std::forward_list<debug_registerpoint>>())
+ , m_rplist()
+ , m_eplist()
, m_triggered_breakpoint(nullptr)
, m_triggered_watchpoint(nullptr)
, m_trace(nullptr)
@@ -549,6 +550,7 @@ device_debug::~device_debug()
breakpoint_clear_all();
watchpoint_clear_all();
registerpoint_clear_all();
+ exceptionpoint_clear_all();
}
void device_debug::write_tracking(address_space &space, offs_t address, u64 data)
@@ -672,10 +674,39 @@ void device_debug::exception_hook(int exception)
if (matched)
{
m_device.machine().debugger().cpu().set_execution_stopped();
- m_device.machine().debugger().console().printf("Stopped on exception (CPU '%s', exception %d, PC=%X)\n", m_device.tag(), exception, m_state->pcbase());
+ m_device.machine().debugger().console().printf("Stopped on exception (CPU '%s', exception %X, PC=%X)\n", m_device.tag(), exception, m_state->pcbase());
compute_debug_flags();
}
}
+
+ // see if any exception points match
+ if (!m_eplist.empty())
+ {
+ auto epitp = m_eplist.equal_range(exception);
+ for (auto epit = epitp.first; epit != epitp.second; ++epit)
+ {
+ debug_exceptionpoint &ep = *epit->second;
+ if (ep.hit(exception))
+ {
+ // halt in the debugger by default
+ debugger_cpu &debugcpu = m_device.machine().debugger().cpu();
+ debugcpu.set_execution_stopped();
+
+ // if we hit, evaluate the action
+ if (!ep.m_action.empty())
+ m_device.machine().debugger().console().execute_command(ep.m_action, false);
+
+ // print a notification, unless the action made us go again
+ if (debugcpu.is_stopped())
+ {
+ debugcpu.set_execution_stopped();
+ m_device.machine().debugger().console().printf("Stopped at exception point %X (CPU '%s', PC=%X)\n", ep.m_index, m_device.tag(), exception, m_state->pcbase());
+ compute_debug_flags();
+ }
+ break;
+ }
+ }
+ }
}
@@ -744,10 +775,6 @@ void device_debug::instruction_hook(offs_t curpc)
if (m_trace != nullptr)
m_trace->update(curpc);
- // per-instruction hook?
- if (!debugcpu.is_stopped() && (m_flags & DEBUG_FLAG_HOOKED) != 0 && (*m_instrhook)(m_device, curpc))
- debugcpu.set_execution_stopped();
-
// handle single stepping
if (!debugcpu.is_stopped() && (m_flags & DEBUG_FLAG_STEPPING_ANY) != 0)
{
@@ -893,22 +920,6 @@ void device_debug::instruction_hook(offs_t curpc)
//-------------------------------------------------
-// set_instruction_hook - set a hook to be
-// called on each instruction for a given device
-//-------------------------------------------------
-
-void device_debug::set_instruction_hook(debug_instruction_hook_func hook)
-{
- // set the hook and also the CPU's flag for fast knowledge of the hook
- m_instrhook = hook;
- if (hook != nullptr)
- m_flags |= DEBUG_FLAG_HOOKED;
- else
- m_flags &= ~DEBUG_FLAG_HOOKED;
-}
-
-
-//-------------------------------------------------
// ignore - ignore/observe a given device
//-------------------------------------------------
@@ -1151,7 +1162,7 @@ const debug_breakpoint *device_debug::breakpoint_find(offs_t address) const
// returning its index
//-------------------------------------------------
-int device_debug::breakpoint_set(offs_t address, const char *condition, const char *action)
+int device_debug::breakpoint_set(offs_t address, const char *condition, std::string_view action)
{
// allocate a new one and hook it into our list
u32 id = m_device.machine().debugger().cpu().get_breakpoint_index();
@@ -1238,7 +1249,7 @@ void device_debug::breakpoint_enable_all(bool enable)
// returning its index
//-------------------------------------------------
-int device_debug::watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition, const char *action)
+int device_debug::watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition, std::string_view action)
{
if (space.spacenum() >= int(m_wplist.size()))
m_wplist.resize(space.spacenum()+1);
@@ -1325,15 +1336,15 @@ void device_debug::watchpoint_enable_all(bool enable)
// returning its index
//-------------------------------------------------
-int device_debug::registerpoint_set(const char *condition, const char *action)
+int device_debug::registerpoint_set(const char *condition, std::string_view action)
{
// allocate a new one
u32 id = m_device.machine().debugger().cpu().get_registerpoint_index();
- m_rplist->emplace_front(*m_symtable, id, condition, action);
+ m_rplist.emplace_front(*m_symtable, id, condition, action);
// update the flags and return the index
breakpoint_update_flags();
- return m_rplist->front().m_index;
+ return m_rplist.front().m_index;
}
@@ -1345,10 +1356,10 @@ int device_debug::registerpoint_set(const char *condition, const char *action)
bool device_debug::registerpoint_clear(int index)
{
// scan the list to see if we own this registerpoint
- for (auto brp = m_rplist->before_begin(); std::next(brp) != m_rplist->end(); ++brp)
+ for (auto brp = m_rplist.before_begin(); std::next(brp) != m_rplist.end(); ++brp)
if (std::next(brp)->m_index == index)
{
- m_rplist->erase_after(brp);
+ m_rplist.erase_after(brp);
breakpoint_update_flags();
return true;
}
@@ -1365,7 +1376,7 @@ bool device_debug::registerpoint_clear(int index)
void device_debug::registerpoint_clear_all()
{
// clear the list
- m_rplist->clear();
+ m_rplist.clear();
breakpoint_update_flags();
}
@@ -1378,7 +1389,7 @@ void device_debug::registerpoint_clear_all()
bool device_debug::registerpoint_enable(int index, bool enable)
{
// scan the list to see if we own this conditionpoint
- for (debug_registerpoint &rp : *m_rplist)
+ for (debug_registerpoint &rp : m_rplist)
if (rp.m_index == index)
{
rp.m_enabled = enable;
@@ -1399,12 +1410,97 @@ bool device_debug::registerpoint_enable(int index, bool enable)
void device_debug::registerpoint_enable_all(bool enable)
{
// apply the enable to all registerpoints we own
- for (debug_registerpoint &rp : *m_rplist)
+ for (debug_registerpoint &rp : m_rplist)
registerpoint_enable(rp.index(), enable);
}
//-------------------------------------------------
+// exceptionpoint_set - set a new exception
+// point, returning its index
+//-------------------------------------------------
+
+int device_debug::exceptionpoint_set(int exception, const char *condition, std::string_view action)
+{
+ // allocate a new one and hook it into our list
+ u32 id = m_device.machine().debugger().cpu().get_exceptionpoint_index();
+ m_eplist.emplace(exception, std::make_unique<debug_exceptionpoint>(this, *m_symtable, id, exception, condition, action));
+
+ // return the index
+ return id;
+}
+
+
+//-------------------------------------------------
+// exceptionpoint_clear - clear an exception
+// point by index, returning true if we found it
+//-------------------------------------------------
+
+bool device_debug::exceptionpoint_clear(int index)
+{
+ // scan the list to see if we own this breakpoint
+ for (auto epit = m_eplist.begin(); epit != m_eplist.end(); ++epit)
+ if (epit->second->m_index == index)
+ {
+ m_eplist.erase(epit);
+ return true;
+ }
+
+ // we don't own it, return false
+ return false;
+}
+
+
+//-------------------------------------------------
+// exceptionpoint_clear_all - clear all exception
+// points
+//-------------------------------------------------
+
+void device_debug::exceptionpoint_clear_all()
+{
+ // clear the list
+ m_eplist.clear();
+}
+
+
+//-------------------------------------------------
+// exceptionpoint_enable - enable/disable an
+// exception point by index, returning true if we
+// found it
+//-------------------------------------------------
+
+bool device_debug::exceptionpoint_enable(int index, bool enable)
+{
+ // scan the list to see if we own this exception point
+ for (auto &epp : m_eplist)
+ {
+ debug_exceptionpoint &ep = *epp.second;
+ if (ep.m_index == index)
+ {
+ ep.m_enabled = enable;
+ return true;
+ }
+ }
+
+ // we don't own it, return false
+ return false;
+}
+
+
+//-------------------------------------------------
+// exceptionpoint_enable_all - enable/disable all
+// exception points
+//-------------------------------------------------
+
+void device_debug::exceptionpoint_enable_all(bool enable)
+{
+ // apply the enable to all exception points we own
+ for (auto &epp : m_eplist)
+ exceptionpoint_enable(epp.second->index(), enable);
+}
+
+
+//-------------------------------------------------
// history_pc - return an entry from the PC
// history
//-------------------------------------------------
@@ -1600,31 +1696,14 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const
// trace - trace execution of a given device
//-------------------------------------------------
-void device_debug::trace(FILE *file, bool trace_over, bool detect_loops, bool logerror, const char *action)
+void device_debug::trace(std::unique_ptr<std::ostream> &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action)
{
// delete any existing tracers
m_trace = nullptr;
// if we have a new file, make a new tracer
if (file != nullptr)
- m_trace = std::make_unique<tracer>(*this, *file, trace_over, detect_loops, logerror, action);
-}
-
-
-//-------------------------------------------------
-// trace_printf - output data into the given
-// device's tracefile, if tracing
-//-------------------------------------------------
-
-void device_debug::trace_printf(const char *fmt, ...)
-{
- if (m_trace != nullptr)
- {
- va_list va;
- va_start(va, fmt);
- m_trace->vprintf(fmt, va);
- va_end(va);
- }
+ m_trace = std::make_unique<tracer>(*this, std::move(file), trace_over, detect_loops, logerror, action);
}
@@ -1652,7 +1731,7 @@ void device_debug::compute_debug_flags()
// if we're tracking history, or we're hooked, or stepping, or stopping at a breakpoint
// make sure we call the hook
- if ((m_flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_HOOKED | DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
+ if ((m_flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
machine.debug_flags |= DEBUG_FLAG_CALL_HOOK;
// also call if we are tracing
@@ -1753,7 +1832,7 @@ void device_debug::breakpoint_update_flags()
if (!(m_flags & DEBUG_FLAG_LIVE_BP))
{
// see if there are any enabled registerpoints
- for (debug_registerpoint &rp : *m_rplist)
+ for (debug_registerpoint &rp : m_rplist)
{
if (rp.m_enabled)
{
@@ -1803,7 +1882,7 @@ void device_debug::breakpoint_check(offs_t pc)
}
// see if we have any matching registerpoints
- for (debug_registerpoint &rp : *m_rplist)
+ for (debug_registerpoint &rp : m_rplist)
{
if (rp.hit())
{
@@ -1836,10 +1915,10 @@ void device_debug::breakpoint_check(offs_t pc)
// tracer - constructor
//-------------------------------------------------
-device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, bool logerror, const char *action)
+device_debug::tracer::tracer(device_debug &debug, std::unique_ptr<std::ostream> &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action)
: m_debug(debug)
- , m_file(file)
- , m_action((action != nullptr) ? action : "")
+ , m_file(std::move(file))
+ , m_action(action)
, m_detect_loops(detect_loops)
, m_logerror(logerror)
, m_loops(0)
@@ -1858,7 +1937,7 @@ device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, b
device_debug::tracer::~tracer()
{
// make sure we close the file if we can
- fclose(&m_file);
+ m_file.reset();
}
@@ -1894,7 +1973,7 @@ void device_debug::tracer::update(offs_t pc)
// if we just finished looping, indicate as much
if (m_loops != 0)
- fprintf(&m_file, "\n (loops for %d instructions)\n\n", m_loops);
+ util::stream_format(*m_file, "\n (loops for %d instructions)\n\n", m_loops);
m_loops = 0;
}
@@ -1909,7 +1988,7 @@ void device_debug::tracer::update(offs_t pc)
buffer.disassemble(pc, instruction, next_pc, size, dasmresult);
// output the result
- fprintf(&m_file, "%s: %s\n", buffer.pc_to_string(pc).c_str(), instruction.c_str());
+ util::stream_format(*m_file, "%s: %s\n", buffer.pc_to_string(pc), instruction);
// do we need to step the trace over this instruction?
if (m_trace_over && (dasmresult & util::disasm_interface::SUPPORTED) != 0 && (dasmresult & util::disasm_interface::STEP_OVER) != 0)
@@ -1927,7 +2006,7 @@ void device_debug::tracer::update(offs_t pc)
// log this PC
m_nextdex = (m_nextdex + 1) % TRACE_LOOPS;
m_history[m_nextdex] = pc;
- fflush(&m_file);
+ m_file->flush();
}
@@ -1935,11 +2014,11 @@ void device_debug::tracer::update(offs_t pc)
// vprintf - generic print to the trace file
//-------------------------------------------------
-void device_debug::tracer::vprintf(const char *format, va_list va)
+void device_debug::tracer::vprintf(util::format_argument_pack<std::ostream> const &args)
{
// pass through to the file
- vfprintf(&m_file, format, va);
- fflush(&m_file);
+ util::stream_format(*m_file, args);
+ m_file->flush();
}
@@ -1950,7 +2029,7 @@ void device_debug::tracer::vprintf(const char *format, va_list va)
void device_debug::tracer::flush()
{
- fflush(&m_file);
+ m_file->flush();
}
diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h
index d9fc3f64eae..416581071a7 100644
--- a/src/emu/debug/debugcpu.h
+++ b/src/emu/debug/debugcpu.h
@@ -29,9 +29,6 @@ constexpr int COMMENT_VERSION = 1;
// TYPE DEFINITIONS
//**************************************************************************
-typedef int (*debug_instruction_hook_func)(device_t &device, offs_t curpc);
-
-
// ======================> device_debug
// [TODO] This whole thing is terrible.
@@ -59,9 +56,6 @@ public:
void privilege_hook();
void instruction_hook(offs_t curpc);
- // hooks into our operations
- void set_instruction_hook(debug_instruction_hook_func hook);
-
// debugger focus
void ignore(bool ignore = true);
bool observing() const { return ((m_flags & DEBUG_FLAG_OBSERVING) != 0); }
@@ -94,7 +88,7 @@ public:
// breakpoints
const auto &breakpoint_list() const { return m_bplist; }
const debug_breakpoint *breakpoint_find(offs_t address) const;
- int breakpoint_set(offs_t address, const char *condition = nullptr, const char *action = nullptr);
+ int breakpoint_set(offs_t address, const char *condition = nullptr, std::string_view action = {});
bool breakpoint_clear(int index);
void breakpoint_clear_all();
bool breakpoint_enable(int index, bool enable = true);
@@ -104,7 +98,7 @@ public:
// watchpoints
int watchpoint_space_count() const { return m_wplist.size(); }
const std::vector<std::unique_ptr<debug_watchpoint>> &watchpoint_vector(int spacenum) const { return m_wplist[spacenum]; }
- int watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition, const char *action);
+ int watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition = nullptr, std::string_view action = {});
bool watchpoint_clear(int wpnum);
void watchpoint_clear_all();
bool watchpoint_enable(int index, bool enable = true);
@@ -113,12 +107,20 @@ public:
debug_watchpoint *triggered_watchpoint() { debug_watchpoint *ret = m_triggered_watchpoint; m_triggered_watchpoint = nullptr; return ret; }
// registerpoints
- const std::forward_list<debug_registerpoint> &registerpoint_list() const { return *m_rplist; }
- int registerpoint_set(const char *condition, const char *action = nullptr);
+ const std::forward_list<debug_registerpoint> &registerpoint_list() const { return m_rplist; }
+ int registerpoint_set(const char *condition, std::string_view action = {});
bool registerpoint_clear(int index);
void registerpoint_clear_all();
bool registerpoint_enable(int index, bool enable = true);
- void registerpoint_enable_all(bool enable = true );
+ void registerpoint_enable_all(bool enable = true);
+
+ // exception points
+ const auto &exceptionpoint_list() const { return m_eplist; }
+ int exceptionpoint_set(int exception, const char *condition = nullptr, std::string_view action = {});
+ bool exceptionpoint_clear(int index);
+ void exceptionpoint_clear_all();
+ bool exceptionpoint_enable(int index, bool enable = true);
+ void exceptionpoint_enable_all(bool enable = true);
// comments
void comment_add(offs_t address, const char *comment, rgb_t color);
@@ -147,8 +149,12 @@ public:
void track_mem_data_clear() { m_track_mem_set.clear(); }
// tracing
- void trace(FILE *file, bool trace_over, bool detect_loops, bool logerror, const char *action);
- void trace_printf(const char *fmt, ...) ATTR_PRINTF(2,3);
+ void trace(std::unique_ptr<std::ostream> &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action);
+ template <typename Format, typename... Params> void trace_printf(Format &&fmt, Params &&...args)
+ {
+ if (m_trace != nullptr)
+ m_trace->vprintf(util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(args)...));
+ }
void trace_flush() { if (m_trace != nullptr) m_trace->flush(); }
void reset_transient_flag() { m_flags &= ~DEBUG_FLAG_TRANSIENT; }
@@ -182,7 +188,6 @@ private:
// global state
u32 m_flags; // debugging flags for this CPU
std::unique_ptr<symbol_table> m_symtable; // symbol table for expression evaluation
- debug_instruction_hook_func m_instrhook; // per-instruction callback hook
// stepping information
offs_t m_stepaddr; // step target address for DEBUG_FLAG_STEPPING_OVER or DEBUG_FLAG_STEPPING_BRANCH
@@ -208,7 +213,8 @@ private:
// breakpoints and watchpoints
std::multimap<offs_t, std::unique_ptr<debug_breakpoint>> m_bplist; // list of breakpoints
std::vector<std::vector<std::unique_ptr<debug_watchpoint>>> m_wplist; // watchpoint lists for each address space
- std::unique_ptr<std::forward_list<debug_registerpoint>> m_rplist; // list of registerpoints
+ std::forward_list<debug_registerpoint> m_rplist; // list of registerpoints
+ std::multimap<offs_t, std::unique_ptr<debug_exceptionpoint>> m_eplist; // list of exception points
debug_breakpoint * m_triggered_breakpoint; // latest breakpoint that was triggered
debug_watchpoint * m_triggered_watchpoint; // latest watchpoint that was triggered
@@ -217,11 +223,11 @@ private:
class tracer
{
public:
- tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, bool logerror, const char *action);
+ tracer(device_debug &debug, std::unique_ptr<std::ostream> &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action);
~tracer();
void update(offs_t pc);
- void vprintf(const char *format, va_list va);
+ void vprintf(util::format_argument_pack<std::ostream> const &args);
void flush();
bool logerror() const { return m_logerror; }
@@ -229,7 +235,7 @@ private:
static const int TRACE_LOOPS = 64;
device_debug & m_debug; // reference to our owner
- FILE & m_file; // tracing file for this CPU
+ std::unique_ptr<std::ostream> m_file; // tracing file for this CPU
std::string m_action; // action to perform during a trace
offs_t m_history[TRACE_LOOPS]; // history of recent PCs
bool m_detect_loops; // whether or not we should detect loops
@@ -312,7 +318,6 @@ private:
static constexpr u32 DEBUG_FLAG_HISTORY = 0x00000002; // tracking this CPU's history
static constexpr u32 DEBUG_FLAG_TRACING = 0x00000004; // tracing this CPU
static constexpr u32 DEBUG_FLAG_TRACING_OVER = 0x00000008; // tracing this CPU with step over behavior
- static constexpr u32 DEBUG_FLAG_HOOKED = 0x00000010; // per-instruction callback hook
static constexpr u32 DEBUG_FLAG_STEPPING = 0x00000020; // CPU is single stepping
static constexpr u32 DEBUG_FLAG_STEPPING_OVER = 0x00000040; // CPU is stepping over a function
static constexpr u32 DEBUG_FLAG_STEPPING_OUT = 0x00000080; // CPU is stepping out of a function
@@ -384,6 +389,7 @@ public:
u32 get_breakpoint_index() { return m_bpindex++; }
u32 get_watchpoint_index() { return m_wpindex++; }
u32 get_registerpoint_index() { return m_rpindex++; }
+ u32 get_exceptionpoint_index() { return m_epindex++; }
// setters
void set_break_cpu(device_t * breakcpu) { m_breakcpu = breakcpu; }
@@ -426,6 +432,7 @@ private:
u32 m_bpindex;
u32 m_wpindex;
u32 m_rpindex;
+ u32 m_epindex;
u64 m_wpdata;
u64 m_wpaddr;
diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp
index a62704c5472..85de3984020 100644
--- a/src/emu/debug/debughlp.cpp
+++ b/src/emu/debug/debughlp.cpp
@@ -46,6 +46,7 @@ const help_item f_static_help_list[] =
" Breakpoints\n"
" Watchpoints\n"
" Registerpoints\n"
+ " Exception Points\n"
" Expressions\n"
" Comments\n"
" Cheats\n"
@@ -191,6 +192,18 @@ const help_item f_static_help_list[] =
" rplist [<CPU>] -- lists all the registerpoints\n"
},
{
+ "exceptionpoints",
+ "\n"
+ "Exception Point Commands\n"
+ "Type help <command> for further details on each command\n"
+ "\n"
+ " ep[set] <type>[,<condition>[,<action>]] -- sets exception point on <type>\n"
+ " epclear [<epnum>] -- clears a given exception point or all if no <epnum> specified\n"
+ " epdisable [<epnum>] -- disabled a given exception point or all if no <epnum> specified\n"
+ " epenable [<epnum>] -- enables a given exception point or all if no <epnum> specified\n"
+ " eplist -- lists all the registerpoints\n"
+ },
+ {
"expressions",
"\n"
"Expressions can be used anywhere a numeric parameter is expected. The syntax for expressions is "
@@ -1555,6 +1568,92 @@ const help_item f_static_help_list[] =
"actions attached to them.\n"
},
{
+ "epset",
+ "\n"
+ " ep[set] <type>[,<condition>[,<action>]]\n"
+ "\n"
+ "Sets a new exception point for exceptions of type <type> on the currently visible CPU. "
+ "The optional <condition> parameter lets you specify an expression that will be evaluated "
+ "each time the exception point is hit. If the result of the expression is true (non-zero), "
+ "the exception point will actually halt execution at the start of the exception handler; "
+ "otherwise, execution will continue with no notification. The optional <action> parameter "
+ "provides a command that is executed whenever the exception point is hit and the "
+ "<condition> is true. Note that you may need to embed the action within braces { } in order "
+ "to prevent commas and semicolons from being interpreted as applying to the epset command "
+ "itself.\n"
+ "\n"
+ "The numbering of exceptions depends upon the CPU type. Causes of exceptions may include "
+ "internally or externally vectored interrupts, errors occurring within instructions and "
+ "system calls.\n"
+ "\n"
+ "Each exception point that is set is assigned an index which can be used in other "
+ "exception point commands to reference this exception point.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ "ep 2\n"
+ " Set an exception that will halt execution whenever the visible CPU raises exception "
+ "number 2.\n"
+ },
+ {
+ "epclear",
+ "\n"
+ " epclear [<epnum>[,...]]\n"
+ "\n"
+ "The epclear command clears exception points. If <epnum> is specified, only the requested "
+ "exception points are cleared, otherwise all exception points are cleared.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ "epclear 3\n"
+ " Clear exception point index 3.\n"
+ "\n"
+ "epclear\n"
+ " Clear all exception points.\n"
+ },
+ {
+ "epdisable",
+ "\n"
+ " epdisable [<epnum>[,...]]\n"
+ "\n"
+ "The epdisable command disables exception points. If <epnum> is specified, only the requested "
+ "exception points are disabled, otherwise all exception points are disabled. Note that "
+ "disabling an exception point does not delete it, it just temporarily marks the exception "
+ "point as inactive.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ "epdisable 3\n"
+ " Disable exception point index 3.\n"
+ "\n"
+ "epdisable\n"
+ " Disable all exception points.\n"
+ },
+ {
+ "epenable",
+ "\n"
+ " epenable [<epnum>[,...]]\n"
+ "\n"
+ "The epenable command enables exception points. If <epnum> is specified, only the "
+ "requested exception points are enabled, otherwise all exception points are enabled.\n"
+ "\n"
+ "Examples:\n"
+ "\n"
+ "epenable 3\n"
+ " Enable exception point index 3.\n"
+ "\n"
+ "epenable\n"
+ " Enable all exception points.\n"
+ },
+ {
+ "eplist",
+ "\n"
+ " eplist\n"
+ "\n"
+ "The eplist command lists all the current exception points, along with their index and "
+ "any conditions or actions attached to them.\n"
+ },
+ {
"map",
"\n"
" map[{d|i|o}] <address>[:<space>]\n"
diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp
index b42b86a0e90..d7be62c1eaa 100644
--- a/src/emu/debug/dvbpoints.cpp
+++ b/src/emu/debug/dvbpoints.cpp
@@ -71,7 +71,7 @@ static bool cConditionDescending(const debug_breakpoint *a, const debug_breakpoi
static bool cActionAscending(const debug_breakpoint *a, const debug_breakpoint *b)
{
- return strcmp(a->action(), b->action()) < 0;
+ return a->action() < b->action();
}
static bool cActionDescending(const debug_breakpoint *a, const debug_breakpoint *b)
diff --git a/src/emu/debug/dvrpoints.cpp b/src/emu/debug/dvrpoints.cpp
index 3ecadaec8e5..7295a1b2170 100644
--- a/src/emu/debug/dvrpoints.cpp
+++ b/src/emu/debug/dvrpoints.cpp
@@ -62,7 +62,7 @@ bool cConditionDescending(std::pair<device_t *, debug_registerpoint const *> con
bool cActionAscending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
{
- return strcmp(a.second->action(), b.second->action()) < 0;
+ return a.second->action() < b.second->action();
}
bool cActionDescending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
diff --git a/src/emu/debug/points.cpp b/src/emu/debug/points.cpp
index a19f0ab5619..961488eebb2 100644
--- a/src/emu/debug/points.cpp
+++ b/src/emu/debug/points.cpp
@@ -28,13 +28,13 @@ debug_breakpoint::debug_breakpoint(
int index,
offs_t address,
const char *condition,
- const char *action) :
+ std::string_view action) :
m_debugInterface(debugInterface),
m_index(index),
m_enabled(true),
m_address(address),
m_condition(symbols, condition ? condition : "1"),
- m_action(action ? action : "")
+ m_action(action)
{
}
@@ -88,7 +88,7 @@ debug_watchpoint::debug_watchpoint(
offs_t address,
offs_t length,
const char *condition,
- const char *action) :
+ std::string_view action) :
m_debugInterface(debugInterface),
m_phr(nullptr),
m_phw(nullptr),
@@ -99,7 +99,7 @@ debug_watchpoint::debug_watchpoint(
m_address(address & space.addrmask()),
m_length(length),
m_condition(symbols, condition ? condition : "1"),
- m_action(action ? action : ""),
+ m_action(action),
m_installing(false)
{
std::fill(std::begin(m_start_address), std::end(m_start_address), 0);
@@ -431,11 +431,11 @@ void debug_watchpoint::triggered(read_or_write type, offs_t address, u64 data, u
// debug_registerpoint - constructor
//-------------------------------------------------
-debug_registerpoint::debug_registerpoint(symbol_table &symbols, int index, const char *condition, const char *action)
+debug_registerpoint::debug_registerpoint(symbol_table &symbols, int index, const char *condition, std::string_view action)
: m_index(index),
m_enabled(true),
m_condition(symbols, (condition != nullptr) ? condition : "1"),
- m_action((action != nullptr) ? action : "")
+ m_action(action)
{
}
@@ -465,3 +465,59 @@ bool debug_registerpoint::hit()
return true;
}
+
+
+//**************************************************************************
+// DEBUG EXCEPTION POINT
+//**************************************************************************
+
+//-------------------------------------------------
+// debug_exceptionpoint - constructor
+//-------------------------------------------------
+
+debug_exceptionpoint::debug_exceptionpoint(
+ device_debug *debugInterface,
+ symbol_table &symbols,
+ int index,
+ int type,
+ const char *condition,
+ std::string_view action)
+ : m_debugInterface(debugInterface),
+ m_index(index),
+ m_enabled(true),
+ m_type(type),
+ m_condition(symbols, (condition != nullptr) ? condition : "1"),
+ m_action(action)
+{
+}
+
+
+//-------------------------------------------------
+// hit - detect a hit
+//-------------------------------------------------
+
+bool debug_exceptionpoint::hit(int exception)
+{
+ // don't hit if disabled
+ if (!m_enabled)
+ return false;
+
+ // must match our type
+ if (m_type != exception)
+ return false;
+
+ // must satisfy the condition
+ if (!m_condition.is_empty())
+ {
+ try
+ {
+ return (m_condition.execute() != 0);
+ }
+ catch (expression_error &)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/src/emu/debug/points.h b/src/emu/debug/points.h
index 62ad953626c..42abd46398f 100644
--- a/src/emu/debug/points.h
+++ b/src/emu/debug/points.h
@@ -36,7 +36,7 @@ public:
int index,
offs_t address,
const char *condition = nullptr,
- const char *action = nullptr);
+ std::string_view action = {});
// getters
const device_debug *debugInterface() const { return m_debugInterface; }
@@ -44,7 +44,7 @@ public:
bool enabled() const { return m_enabled; }
offs_t address() const { return m_address; }
const char *condition() const { return m_condition.original_string(); }
- const char *action() const { return m_action.c_str(); }
+ const std::string &action() const { return m_action; }
// setters
void setEnabled(bool value) { m_enabled = value; } // FIXME: need to update breakpoint flags but it's a private method
@@ -77,7 +77,7 @@ public:
offs_t address,
offs_t length,
const char *condition = nullptr,
- const char *action = nullptr);
+ std::string_view action = {});
~debug_watchpoint();
// getters
@@ -128,13 +128,13 @@ class debug_registerpoint
public:
// construction/destruction
- debug_registerpoint(symbol_table &symbols, int index, const char *condition, const char *action = nullptr);
+ debug_registerpoint(symbol_table &symbols, int index, const char *condition, std::string_view action = {});
// getters
int index() const { return m_index; }
bool enabled() const { return m_enabled; }
const char *condition() const { return m_condition.original_string(); }
- const char *action() const { return m_action.c_str(); }
+ const std::string &action() const { return m_action; }
private:
// internals
@@ -146,4 +146,42 @@ private:
std::string m_action; // action
};
+// ======================> debug_exceptionpoint
+
+class debug_exceptionpoint
+{
+ friend class device_debug;
+
+public:
+ // construction/destruction
+ debug_exceptionpoint(
+ device_debug* debugInterface,
+ symbol_table &symbols,
+ int index,
+ int type,
+ const char *condition = nullptr,
+ std::string_view action = {});
+
+ // getters
+ const device_debug *debugInterface() const { return m_debugInterface; }
+ int index() const { return m_index; }
+ bool enabled() const { return m_enabled; }
+ int type() const { return m_type; }
+ const char *condition() const { return m_condition.original_string(); }
+ const std::string &action() const { return m_action; }
+
+ // setters
+ void setEnabled(bool value) { m_enabled = value; }
+
+private:
+ // internals
+ bool hit(int exception);
+ const device_debug * m_debugInterface; // the interface we were created from
+ int m_index; // user reported index
+ bool m_enabled; // enabled?
+ int m_type; // exception type
+ parsed_expression m_condition; // condition
+ std::string m_action; // action
+};
+
#endif // MAME_EMU_DEBUG_POINTS_H
diff --git a/src/emu/dinetwork.cpp b/src/emu/dinetwork.cpp
index 3ad9f4c925b..2091ac6a2c3 100644
--- a/src/emu/dinetwork.cpp
+++ b/src/emu/dinetwork.cpp
@@ -1,6 +1,8 @@
// license:BSD-3-Clause
// copyright-holders:Carl, Miodrag Milanovic
+
#include "emu.h"
+#include "dinetwork.h"
#include "osdnet.h"
device_network_interface::device_network_interface(const machine_config &mconfig, device_t &device, u32 bandwidth, u32 mtu)
diff --git a/src/emu/emu.h b/src/emu/emu.h
index f4fa0c21888..6f564f258ab 100644
--- a/src/emu/emu.h
+++ b/src/emu/emu.h
@@ -28,6 +28,7 @@
#include <map>
#include <unordered_map>
#include <unordered_set>
+#include <cstdarg>
// core emulator headers -- must be first (profiler needs attotime, attotime needs xtal)
#include "emucore.h"
@@ -72,7 +73,6 @@
#include "divideo.h"
#include "dinvram.h"
#include "schedule.h"
-#include "dinetwork.h"
// machine and driver configuration
#include "mconfig.h"
diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h
index 9dde867df54..323a0f14898 100644
--- a/src/emu/emufwd.h
+++ b/src/emu/emufwd.h
@@ -36,6 +36,7 @@ class output_module;
// declared in osdepend.h
class osd_font;
class osd_interface;
+class osd_midi_device;
@@ -98,6 +99,7 @@ class symbol_table;
class debug_breakpoint;
class debug_watchpoint;
class debug_registerpoint;
+class debug_exceptionpoint;
// declared in debugger.h
class debugger_manager;
@@ -129,6 +131,9 @@ class device_image_interface;
// declared in dimemory.h
class device_memory_interface;
+// declared in dinetwork.h
+class device_network_interface;
+
// declared in dipalette.h
class device_palette_interface;
diff --git a/src/emu/gamedrv.h b/src/emu/gamedrv.h
index a1cb8a40155..5ca3a653506 100644
--- a/src/emu/gamedrv.h
+++ b/src/emu/gamedrv.h
@@ -208,7 +208,7 @@ driver_device_creator< \
///
/// Use this macro to define most systems intended for public use,
/// including arcade games, gambling machines, vending machines, and
-/// information kiosks. Muse be used in the global namespace.
+/// information kiosks. Must be used in the global namespace.
///
/// Creates an appropriately named and populated #game_driver structure
/// describing the system.
diff --git a/src/emu/network.cpp b/src/emu/network.cpp
index 68c9f93c196..0ffff1616cc 100644
--- a/src/emu/network.cpp
+++ b/src/emu/network.cpp
@@ -8,13 +8,16 @@
***************************************************************************/
-#include <cctype>
-
#include "emu.h"
#include "network.h"
+
#include "config.h"
+#include "dinetwork.h"
+
#include "xmlfile.h"
+#include <cctype>
+
//**************************************************************************
// NETWORK MANAGER
//**************************************************************************
diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp
index aebe9a5886b..0ef893dfd1c 100644
--- a/src/frontend/mame/ui/mainmenu.cpp
+++ b/src/frontend/mame/ui/mainmenu.cpp
@@ -37,6 +37,7 @@
#include "machine/bcreader.h"
#include "crsshair.h"
+#include "dinetwork.h"
#include "dipty.h"
#include "emuopts.h"
diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp
index b621581ee89..0733f554506 100644
--- a/src/frontend/mame/ui/miscmenu.cpp
+++ b/src/frontend/mame/ui/miscmenu.cpp
@@ -23,6 +23,7 @@
#include "osdnet.h"
#include "mameopts.h"
#include "pluginopts.h"
+#include "dinetwork.h"
#include "drivenum.h"
#include "fileio.h"
#include "romload.h"
diff --git a/src/lib/formats/fs_fat.cpp b/src/lib/formats/fs_fat.cpp
index e60d1dcfa5c..a2e5a4a5cc1 100644
--- a/src/lib/formats/fs_fat.cpp
+++ b/src/lib/formats/fs_fat.cpp
@@ -483,7 +483,7 @@ impl::impl(fsblk_t &blockdev, fsblk_t::block_t &&boot_sector_block, std::vector<
, m_starting_sector(starting_sector)
, m_sector_count(sector_count)
, m_reserved_sector_count(reserved_sector_count)
- , m_bytes_per_sector(boot_sector_block.r16l(11))
+ , m_bytes_per_sector(m_boot_sector_block.r16l(11))
, m_bits_per_fat_entry(bits_per_fat_entry)
{
}
diff --git a/src/mame/arcade.flt b/src/mame/arcade.flt
index 6797ec5d77b..9237027e177 100644
--- a/src/mame/arcade.flt
+++ b/src/mame/arcade.flt
@@ -1197,6 +1197,7 @@ sega/coolridr.cpp
sega/dc_atomiswave.cpp
sega/deniam.cpp
sega/dotrikun.cpp
+sega/eshockey.cpp
sega/flashbeats.cpp
sega/fwheel.cpp
sega/gpworld.cpp
@@ -1494,8 +1495,9 @@ universal/docastle.cpp
universal/getaway.cpp
universal/ladybug.cpp
universal/mrdo.cpp
-universal/redclash.cpp
+universal/sraider.cpp
universal/superdq.cpp
+universal/zerohour.cpp
upl/mouser.cpp
upl/ninjakd2.cpp
upl/nova2001.cpp
diff --git a/src/mame/atari/atarisy1.cpp b/src/mame/atari/atarisy1.cpp
index bcd12646eba..4c05546d020 100644
--- a/src/mame/atari/atarisy1.cpp
+++ b/src/mame/atari/atarisy1.cpp
@@ -778,6 +778,7 @@ void atarisy1_state::atarisy1(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, m6502_device::NMI_LINE);
+ m_soundlatch->data_pending_callback().append([this](int state) { if (state) machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100)); });
GENERIC_LATCH_8(config, m_mainlatch);
m_mainlatch->data_pending_callback().set_inputline(m_maincpu, M68K_IRQ_6);
diff --git a/src/mame/atari/atarisy2.cpp b/src/mame/atari/atarisy2.cpp
index 0f63d9c596c..16ce74a0bbd 100644
--- a/src/mame/atari/atarisy2.cpp
+++ b/src/mame/atari/atarisy2.cpp
@@ -303,14 +303,6 @@ void atarisy2_state::sound_irq_ack_w(uint8_t data)
}
-WRITE_LINE_MEMBER(atarisy2_state::boost_interleave_hack)
-{
- // apb3 fails the self-test with a 100 µs delay or less
- if (state)
- machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(200));
-}
-
-
/*************************************
*
@@ -1267,7 +1259,7 @@ void atarisy2_state::atarisy2(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, m6502_device::NMI_LINE);
- m_soundlatch->data_pending_callback().append(FUNC(atarisy2_state::boost_interleave_hack));
+ m_soundlatch->data_pending_callback().append([this](int state) { if (state) machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(200)); });
GENERIC_LATCH_8(config, m_mainlatch);
diff --git a/src/mame/atari/atarisy2.h b/src/mame/atari/atarisy2.h
index 2d3e59dd80c..a83571b26d4 100644
--- a/src/mame/atari/atarisy2.h
+++ b/src/mame/atari/atarisy2.h
@@ -127,7 +127,6 @@ private:
void int_enable_w(uint8_t data);
INTERRUPT_GEN_MEMBER(sound_irq_gen);
void sound_irq_ack_w(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(boost_interleave_hack);
void bankselect_w(offs_t offset, uint16_t data);
uint16_t switch_r();
uint8_t switch_6502_r();
diff --git a/src/mame/atari/gauntlet.cpp b/src/mame/atari/gauntlet.cpp
index cda4c5ad381..eedf636b223 100644
--- a/src/mame/atari/gauntlet.cpp
+++ b/src/mame/atari/gauntlet.cpp
@@ -507,6 +507,7 @@ void gauntlet_state::gauntlet_base(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set_inputline(m_audiocpu, m6502_device::NMI_LINE);
+ m_soundlatch->data_pending_callback().append([this](int state) { if (state) machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100)); });
GENERIC_LATCH_8(config, m_mainlatch);
m_mainlatch->data_pending_callback().set_inputline(m_maincpu, M68K_IRQ_6);
diff --git a/src/mame/atari/starwars.cpp b/src/mame/atari/starwars.cpp
index ce52d4dc4e0..d0e8d5a1190 100644
--- a/src/mame/atari/starwars.cpp
+++ b/src/mame/atari/starwars.cpp
@@ -315,11 +315,11 @@ void starwars_state::starwars(machine_config &config)
GENERIC_LATCH_8(config, m_soundlatch);
m_soundlatch->data_pending_callback().set(m_riot, FUNC(riot6532_device::pa7_w));
- m_soundlatch->data_pending_callback().append(FUNC(starwars_state::boost_interleave_hack));
+ m_soundlatch->data_pending_callback().append([this](int state) { if (state) machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100)); });
GENERIC_LATCH_8(config, m_mainlatch);
m_mainlatch->data_pending_callback().set(m_riot, FUNC(riot6532_device::pa6_w));
- m_mainlatch->data_pending_callback().append(FUNC(starwars_state::boost_interleave_hack));
+ m_mainlatch->data_pending_callback().append([this](int state) { if (state) machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100)); });
}
diff --git a/src/mame/atari/starwars.h b/src/mame/atari/starwars.h
index 7f3706ee3fb..dd575314948 100644
--- a/src/mame/atari/starwars.h
+++ b/src/mame/atari/starwars.h
@@ -84,7 +84,6 @@ private:
void starwars_math_w(offs_t offset, uint8_t data);
uint8_t starwars_main_ready_flag_r();
- DECLARE_WRITE_LINE_MEMBER(boost_interleave_hack);
void starwars_soundrst_w(uint8_t data);
void quad_pokeyn_w(offs_t offset, uint8_t data);
virtual void machine_reset() override;
diff --git a/src/mame/atari/starwars_a.cpp b/src/mame/atari/starwars_a.cpp
index 9ae8b02a147..a4dc4afb354 100644
--- a/src/mame/atari/starwars_a.cpp
+++ b/src/mame/atari/starwars_a.cpp
@@ -53,13 +53,6 @@ void starwars_state::r6532_porta_w(uint8_t data)
*
*************************************/
-WRITE_LINE_MEMBER(starwars_state::boost_interleave_hack)
-{
- if (state)
- machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100));
-}
-
-
uint8_t starwars_state::starwars_main_ready_flag_r()
{
return m_riot->porta_in_get() & 0xc0; /* only upper two flag bits mapped */
diff --git a/src/mame/facit/f4431.cpp b/src/mame/facit/f4431.cpp
new file mode 100644
index 00000000000..2dc8a4efbc6
--- /dev/null
+++ b/src/mame/facit/f4431.cpp
@@ -0,0 +1,359 @@
+// license: BSD-3-Clause
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Facit 4431
+
+ VT100 compatible terminal
+
+ Hardware:
+ - Z80
+ - TMS9927 CRTC
+ - Z80A-DART
+ - Z80A-CTC
+ - ER1400
+ - 6116
+ - 6116 x2
+ - 2114 x4
+ - XTAL 9.828 MHz (B1), 14.976 MHz (B2), 4 MHz (B3)
+ - AY-5-1013A UART
+
+ TODO:
+ - Almost everything
+ - Move ergo201 driver here? The hardware is very similar
+
+ Notes:
+
+***************************************************************************/
+
+#include "emu.h"
+#include "cpu/z80/z80.h"
+#include "machine/ay31015.h"
+#include "machine/clock.h"
+#include "machine/er1400.h"
+#include "machine/z80ctc.h"
+#include "machine/z80sio.h"
+#include "video/tms9927.h"
+#include "emupal.h"
+#include "screen.h"
+
+
+namespace {
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class f4431_state : public driver_device
+{
+public:
+ f4431_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_earom(*this, "earom"),
+ m_ctc(*this, "ctc"),
+ m_dart(*this, "dart"),
+ m_vtc(*this, "vtc"),
+ m_screen(*this, "screen"),
+ m_uart(*this, "uart"),
+ m_ascii(*this, "ascii"),
+ m_chargen(*this, "chargen"),
+ m_switches(*this, "switches"),
+ m_display_enabled(false),
+ m_nmi_disabled(true)
+ { }
+
+ void f4431(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ required_device<z80_device> m_maincpu;
+ required_device<er1400_device> m_earom;
+ required_device<z80ctc_device> m_ctc;
+ required_device<z80dart_device> m_dart;
+ required_device<tms9927_device> m_vtc;
+ required_device<screen_device> m_screen;
+ required_device<ay31015_device> m_uart;
+ required_shared_ptr<uint8_t> m_ascii;
+ required_region_ptr<uint8_t> m_chargen;
+ required_ioport m_switches;
+
+ void mem_map(address_map &map);
+ void io_map(address_map &map);
+
+ uint8_t latch_r();
+ void latch_w(uint8_t data);
+
+ void scanline_cb(uint32_t data);
+ uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ void brightness_w(uint8_t data);
+
+ bool m_display_enabled;
+ bool m_nmi_disabled;
+};
+
+
+//**************************************************************************
+// ADDRESS MAPS
+//**************************************************************************
+
+void f4431_state::mem_map(address_map &map)
+{
+ map(0x0000, 0x5fff).rom();
+ map(0x2000, 0x2000).w(FUNC(f4431_state::brightness_w));
+ map(0x3000, 0x300f).w(m_vtc, FUNC(tms9927_device::write));
+ map(0x4000, 0x4000).w(FUNC(f4431_state::latch_w));
+ map(0x5000, 0x5000).w(m_uart, FUNC(ay31015_device::transmit));
+ map(0x6000, 0x6000).r(m_uart, FUNC(ay31015_device::receive));
+ map(0x6001, 0x6001).r(FUNC(f4431_state::latch_r));
+ map(0x7000, 0x77ff).ram(); // scratchpad ram
+ map(0x8000, 0x8fff).ram().share(m_ascii);
+ map(0xc000, 0xcfff).ram(); // attribute ram
+}
+
+void f4431_state::io_map(address_map &map)
+{
+ map.global_mask(0xff);
+ map(0xf4, 0xf7).rw(m_dart, FUNC(z80dart_device::cd_ba_r), FUNC(z80dart_device::cd_ba_w));
+ map(0xf8, 0xfb).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
+}
+
+
+//**************************************************************************
+// INPUT PORT DEFINITIONS
+//**************************************************************************
+
+static INPUT_PORTS_START( f4431 )
+ PORT_START("switches")
+ PORT_DIPNAME(0x01, 0x01, "W4 (Production Test)")
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ))
+ PORT_DIPSETTING( 0x00, DEF_STR( On ))
+ PORT_DIPNAME(0x02, 0x02, "W5 (Disable EAROM Save)")
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ))
+ PORT_DIPSETTING( 0x00, DEF_STR( On ))
+INPUT_PORTS_END
+
+
+//**************************************************************************
+// VIDEO EMULATION
+//**************************************************************************
+
+void f4431_state::scanline_cb(uint32_t data)
+{
+ // in the actual system this would be generated
+ // by the r0 and r3 output of the vtc
+
+ if (!m_nmi_disabled && ((data % 10) == 0))
+ {
+ m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
+ m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
+ }
+}
+
+uint32_t f4431_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ if (m_display_enabled)
+ {
+ for (int y = 0; y < 25; y++)
+ {
+ for (int x = 0; x < 80; x++)
+ {
+ uint8_t code = m_ascii[y * 80 + x];
+
+ for (int i = 0; i < 10; i++)
+ {
+ uint8_t data = m_chargen[(i << 7) | code];
+
+ bitmap.pix(y * 10 + i, x * 10 + 0) = BIT(data, 7) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 1) = (BIT(data, 7) || BIT(data, 6)) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 2) = (BIT(data, 6) || BIT(data, 5)) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 3) = (BIT(data, 5) || BIT(data, 4)) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 4) = (BIT(data, 4) || BIT(data, 3)) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 5) = (BIT(data, 3) || BIT(data, 2)) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 6) = (BIT(data, 2) || BIT(data, 1)) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 7) = (BIT(data, 1) || BIT(data, 0)) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 8) = BIT(data, 0) ? rgb_t::white() : rgb_t::black();
+ bitmap.pix(y * 10 + i, x * 10 + 9) = rgb_t::black();
+ }
+ }
+ }
+ }
+ else
+ {
+ bitmap.fill(rgb_t::black(), cliprect);
+ }
+
+ return 0;
+}
+
+void f4431_state::brightness_w(uint8_t data)
+{
+ logerror("brightness_w: %02x\n", data);
+}
+
+
+//**************************************************************************
+// MACHINE EMULATION
+//**************************************************************************
+
+uint8_t f4431_state::latch_r()
+{
+ // 7------- vsync
+ // -6------ not connected
+ // --5----- earom data
+ // ---4---- not connected
+ // ----3--- switch w5 (disable earom save)
+ // -----2-- switch w4 (production test)
+ // ------1- uart dav
+ // -------0 uart tbe/boc
+
+ uint8_t data = 0;
+
+ data |= (m_uart->tbmt_r() | m_uart->eoc_r()) << 0;
+ data |= m_uart->dav_r() << 1;
+ data |= m_switches->read() << 2;
+ data |= m_earom->data_r() << 5;
+ data |= m_screen->vblank() << 7;
+
+ return data;
+}
+
+void f4431_state::latch_w(uint8_t data)
+{
+ // 7------- 80/132 columns
+ // -6------ interrupt disable
+ // --5----- screen blank
+ // ---4---- earom clock
+ // ----3--- earom c2
+ // -----2-- earom c3
+ // ------1- earom data
+ // -------0 earom c1
+
+ logerror("latch_w: %02x\n", data);
+
+ m_earom->c1_w(BIT(data, 0));
+
+ // correct?
+ m_earom->data_w(BIT(data, 4) ? 0 : BIT(data, 1));
+
+ m_earom->c3_w(BIT(data, 2));
+ m_earom->c2_w(BIT(data, 3));
+ m_earom->clock_w(BIT(data, 4));
+
+ m_display_enabled = bool(BIT(data, 5));
+ m_nmi_disabled = bool(BIT(data, 6));
+}
+
+void f4431_state::machine_start()
+{
+ // register for save states
+ save_item(NAME(m_display_enabled));
+ save_item(NAME(m_nmi_disabled));
+}
+
+void f4431_state::machine_reset()
+{
+ m_display_enabled = false;
+ m_nmi_disabled = true;
+}
+
+
+//**************************************************************************
+// MACHINE DEFINTIONS
+//**************************************************************************
+
+static const z80_daisy_config daisy_chain[] =
+{
+ { "dart" },
+ { "ctc" },
+ { nullptr }
+};
+
+void f4431_state::f4431(machine_config &config)
+{
+ Z80(config, m_maincpu, 4_MHz_XTAL);
+ m_maincpu->set_addrmap(AS_PROGRAM, &f4431_state::mem_map);
+ m_maincpu->set_addrmap(AS_IO, &f4431_state::io_map);
+ m_maincpu->set_daisy_config(daisy_chain);
+
+ ER1400(config, m_earom);
+
+ Z80CTC(config, m_ctc, 4_MHz_XTAL);
+ m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
+ m_ctc->set_clk<0>(4_MHz_XTAL / 13);
+ m_ctc->zc_callback<0>().set(m_dart, FUNC(z80dart_device::rxca_w));
+ m_ctc->set_clk<1>(4_MHz_XTAL / 13);
+ m_ctc->zc_callback<1>().set(m_dart, FUNC(z80dart_device::txca_w));
+ m_ctc->set_clk<2>(4_MHz_XTAL / 13);
+ m_ctc->zc_callback<2>().set(m_dart, FUNC(z80dart_device::rxtxcb_w));
+
+ Z80DART(config, m_dart, 4_MHz_XTAL);
+ m_dart->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
+ // port a: serial i/o
+ // port b: printer
+
+ SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
+ m_screen->set_color(rgb_t::green());
+ m_screen->set_raw(9.828_MHz_XTAL * 2, 1020, 0, 800, 268, 0, 250); // probably wrong
+ m_screen->set_screen_update(FUNC(f4431_state::screen_update));
+ m_screen->scanline().set(FUNC(f4431_state::scanline_cb));
+
+ PALETTE(config, "palette", palette_device::MONOCHROME);
+
+ TMS9927(config, m_vtc, 9.828_MHz_XTAL / 6); // ?
+ m_vtc->set_char_width(10); // renders in half-dots?
+ m_vtc->set_screen("screen");
+ m_vtc->hsyn_callback().set(m_ctc, FUNC(z80ctc_device::trg3));
+
+ AY31015(config, m_uart);
+}
+
+
+//**************************************************************************
+// ROM DEFINITIONS
+//**************************************************************************
+
+ROM_START( f4431 )
+ ROM_REGION(0x6000, "maincpu", 0)
+ ROM_LOAD("11420050-00_4431.d73", 0x0000, 0x1000, CRC(e7a9c982) SHA1(60c2eb769bd6051b4acaf38750ef40b9d02c568c))
+ ROM_COPY("maincpu", 0x0000, 0x1000, 0x1000)
+ ROM_LOAD("11420060-00_4431.d74", 0x2000, 0x1000, CRC(e9703cf0) SHA1(9eef6d4f0b57a6430a034f9405d4d8279723e2a0))
+ ROM_COPY("maincpu", 0x2000, 0x3000, 0x1000)
+ ROM_LOAD("11420070-00_4431.d75", 0x4000, 0x1000, CRC(a0d5b59e) SHA1(fca5b25163d942ec688d82004253850a3e08b0af))
+ ROM_COPY("maincpu", 0x4000, 0x5000, 0x1000)
+
+ ROM_REGION(0x800, "chargen", 0)
+ ROM_LOAD("11419840-00_cg30.d40", 0x000, 0x800, CRC(d2988792) SHA1(bc3b59882c351fb503371e358e396e7d683c9467))
+ // National variants (not dumped):
+ // 1141 89 50-00/0 UK
+ // 1141 98 60-00/9 FRA
+ // 1141 90 70-00/8 GER
+ // 1141 98 80-00/7 NOR
+ // 1141 98 90-00/6 SWE/FIN
+ // 1141 99 00-00/3 SPA
+ // 1141 99 10-00/2 DEN
+
+ ROM_REGION(0x800, "attr", 0)
+ ROM_LOAD("11419950-00_4431.d57", 0x000, 0x800, CRC(066dc6bd) SHA1(1ad17c9ec96544278d9f8494c19b4b3bce8e3a8e))
+
+ ROM_REGION(0x20, "prom", 0)
+ ROM_LOAD("11419960-00_4431.d19", 0x00, 0x20, CRC(daae0c28) SHA1(58c55b8b9d4161a9d38259a4375cf19799ea0b7a))
+
+ ROM_REGION(0x800, "keyb", 0)
+ ROM_LOAD("11419660-00_kb31.u3", 0x000, 0x800, CRC(45b90749) SHA1(91d0ef181fe05e9474871e26dc75c313cb67c337))
+ROM_END
+
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// SYSTEM DRIVERS
+//**************************************************************************
+
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+COMP( 1981, f4431, 0, 0, f4431, f4431, f4431_state, empty_init, "Facit", "4431", MACHINE_IS_SKELETON )
diff --git a/src/mame/skeleton/facit4440.cpp b/src/mame/facit/facit4440.cpp
index d203d085319..d203d085319 100644
--- a/src/mame/skeleton/facit4440.cpp
+++ b/src/mame/facit/facit4440.cpp
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 683fcc8cfeb..8ef781c095c 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -13615,6 +13615,9 @@ esh // (c) 1984 Funai / Gakken
esha // (c) 1984 Funai / Gakken
eshb // (c) 1984 Funai / Gakken
+@source:sega/eshockey.cpp
+eshockey //
+
@source:orca/espial.cpp
espial // (c) 1983 Thunderbolt, Orca logo is hidden in title screen
espialu // (c) 1983 Thunderbolt, Orca logo is hidden in title screen
@@ -13872,12 +13875,15 @@ f1gpb // bootleg
mosaicf2 // (c) 1999 F2 System
royalpk2 //
-@source:fairchild/f387x.cpp
-f387x // (c) 1979 Fairchild
+@source:facit/f4431.cpp
+f4431 // 1981 Facit
-@source:skeleton/facit4440.cpp
+@source:facit/facit4440.cpp
facit4440 // 1984
+@source:fairchild/f387x.cpp
+f387x // (c) 1979 Fairchild
+
@source:falco/falco500.cpp
falco5220e // 1987
falco500e // 1991
@@ -20132,9 +20138,7 @@ dorodon2 // Falcon
ladybug // 8110 (c) 1981
ladybugb // bootleg
ladybugb2 // bootleg
-mrsdyna // 8203 (c) 1982 Universal
snapjack // ???? (c)
-sraider // 8203 (c) 1982 Universal
@source:misc/ladyfrog.cpp
ladyfrog // (c) 1990 Mondial Games
@@ -36794,7 +36798,7 @@ panther // M27 no copyright notice
redalert // M27 (c) 1981 + "GDI presents"
ww3 // M27 (c) 1981
-@source:universal/redclash.cpp
+@source:universal/zerohour.cpp
redclash // (c) Kaneko
redclasht // (c) 1981 Tehkan
redclashta // (c) 1981 Tehkan
@@ -40013,6 +40017,10 @@ spyhuntpr // (c) 1985 Recreativos Franco S.A.
@source:skeleton/squale.cpp
squale //
+@source:universal/sraider.cpp
+mrsdyna // 8203 (c) 1982 Universal
+sraider // 8203 (c) 1982 Universal
+
@source:seta/srmp2.cpp
mjyuugi // (c) 1990 Visco
mjyuugia // (c) 1990 Visco
@@ -44065,7 +44073,7 @@ jm_05r //
jm_12b //
jm_12r //
nf_08x //
-nf_10 //
+nf_10f //
nf_20 //
nf_22 //
nf_23 //
@@ -44078,6 +44086,7 @@ rs_lx2 //
rs_lx3 //
rs_lx4 //
rs_lx5 //
+rs_pa2 //
tfs_12 //
tom_06 //
tom_10f //
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 0833caea983..d7e2de3674b 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -247,6 +247,8 @@ epson/qx10.cpp
ericsson/e9161.cpp
ericsson/eispc.cpp
exidy/sorcerer.cpp
+facit/f4431.cpp
+facit/facit4440.cpp
fairchild/channelf.cpp
fairchild/f387x.cpp
fairlight/cmi.cpp
@@ -827,7 +829,6 @@ skeleton/epic14e.cpp
skeleton/esprit.cpp
skeleton/eurit.cpp
skeleton/eurocom2.cpp
-skeleton/facit4440.cpp
skeleton/fanucs15.cpp
skeleton/fanucspmg.cpp
skeleton/fc100.cpp
diff --git a/src/mame/pinball/de_3.cpp b/src/mame/pinball/de_3.cpp
index c738fc66fdc..404eb3b40f1 100644
--- a/src/mame/pinball/de_3.cpp
+++ b/src/mame/pinball/de_3.cpp
@@ -1965,7 +1965,7 @@ GAME(1992, hook_401_p, hook_408, de_3_dmd1, de3, de_3_state, empty_init, ROT
GAME(1992, hook_e406, hook_408, de_3_dmd1, de3, de_3_state, empty_init, ROT0, "Data East", "Hook (UK 4.06, display A4.01)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // HOOK U.K. 4.06
GAME(1993, jupk_513, 0, de_3_dmd2, de3, de_3_state, empty_init, ROT0, "Data East", "Jurassic Park (USA 5.13, display A5.10)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // JURASSIC PARK SEP. 28, 1993 USA CPU 5.13. DISPLAY VERSION- JURASSIC A5.10 8/24/1993
GAME(1993, jupk_501, jupk_513, de_3_dmd2, de3, de_3_state, empty_init, ROT0, "Data East", "Jurassic Park (USA 5.01, display A5.01)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // JURASSIC PARK JUNE 28, 1993 USA CPU 5.01. DISPLAY VERSION- JURASSIC A5.01 6/24/1993
-GAME(1993, jupk_501g, jupk_513, de_3_dmd2, de3, de_3_state, empty_init, ROT0, "Data East", "Jurassic Park (USA 5.01 Germany, display G5.01)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // JURASSIC PARK JUNE 28, 1993 USA CPU 5.01. DISPLAY VERSION- JURASSIC G5.01 6/24/1993
+GAME(1993, jupk_501g, jupk_513, de_3_dmd2, de3, de_3_state, empty_init, ROT0, "Data East", "Jurassic Park (USA 5.01, display G5.01)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // JURASSIC PARK JUNE 28, 1993 USA CPU 5.01. DISPLAY VERSION- JURASSIC G5.01 6/24/1993
GAME(1993, jupk_307, jupk_513, de_3_dmd2, de3, de_3_state, empty_init, ROT0, "Data East", "Jurassic Park (USA 3.07, display A4.00)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // JURASSIC PARK. MAY 25, 1993. USA CPU 3.05
GAME(1993, jupk_305, jupk_513, de_3_dmd2, de3, de_3_state, empty_init, ROT0, "Data East", "Jurassic Park (USA 3.05, display A4.00)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // JURASSIC PARK. MAY 25, 1993. USA CPU 3.05
GAME(1993, lah_112, 0, de_3_dmd2, de3, de_3_state, empty_init, ROT0, "Data East", "Last Action Hero (USA 1.12, display A1.06)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE ) // LAST ACTION HERO NOV. 10, 1993 USA CPU 1.12. DISPLAY VERSION- ACTION HERO A1.06 11/11/1993
diff --git a/src/mame/pinball/wpc_s.cpp b/src/mame/pinball/wpc_s.cpp
index c2c2d49a4d3..e21c6119e04 100644
--- a/src/mame/pinball/wpc_s.cpp
+++ b/src/mame/pinball/wpc_s.cpp
@@ -2340,23 +2340,23 @@ ROM_START(nf_20)
ROM_LOAD16_BYTE("nfu7s", 0xa00000, 0x080000, CRC(61002bdd) SHA1(e623399ff95f59a4ab7efdd7c69b1a1370479398))
ROM_END
-ROM_START(nf_10)
+ROM_START(nf_10f)
ROM_REGION(0x80000, "maincpu", 0)
ROM_LOAD("nofe1_0.rom", 0x00000, 0x80000, CRC(f8f6521c) SHA1(5c26f4878f257b157c2a1c46995ec8100fa20723))
ROM_REGION(0x800000, "dcs", 0)
- ROM_LOAD16_BYTE("nfu2s", 0x000000, 0x080000, CRC(136caeb9) SHA1(61a56b29a7655e8aab4987d300173e1acf27c77c))
- ROM_LOAD16_BYTE("nfu3s", 0x100000, 0x080000, CRC(983e5578) SHA1(374b1397abbdde5fd9257fd45fd8613c94fbd02d))
- ROM_LOAD16_BYTE("nfu4s", 0x200000, 0x080000, CRC(9469cd40) SHA1(8a1dd1088f24018f48b114c0b27f0331263d4eea))
- ROM_LOAD16_BYTE("nfu5s", 0x300000, 0x080000, CRC(e14d4315) SHA1(63d5ae800cc8a750ea2e3a87c646ab175b60abc7))
- ROM_LOAD16_BYTE("nfu6s", 0x400000, 0x080000, CRC(40a58903) SHA1(78f7e99f39efc83f3cf17801a30e6dc6e4864125))
- ROM_LOAD16_BYTE("nfu7s", 0x500000, 0x080000, CRC(61002bdd) SHA1(e623399ff95f59a4ab7efdd7c69b1a1370479398))
+ ROM_LOAD16_BYTE("snd-u2.sl1", 0x000000, 0x080000, CRC(84f48e27) SHA1(cdf0ff55c1493ea5ac7cef618c985f41442c6f60))
+ ROM_LOAD16_BYTE("nfu3s", 0x100000, 0x080000, CRC(983e5578) SHA1(374b1397abbdde5fd9257fd45fd8613c94fbd02d))
+ ROM_LOAD16_BYTE("nfu4s", 0x200000, 0x080000, CRC(9469cd40) SHA1(8a1dd1088f24018f48b114c0b27f0331263d4eea))
+ ROM_LOAD16_BYTE("nfu5s", 0x300000, 0x080000, CRC(e14d4315) SHA1(63d5ae800cc8a750ea2e3a87c646ab175b60abc7))
+ ROM_LOAD16_BYTE("nfu6s", 0x400000, 0x080000, CRC(40a58903) SHA1(78f7e99f39efc83f3cf17801a30e6dc6e4864125))
+ ROM_LOAD16_BYTE("nfu7s", 0x500000, 0x080000, CRC(61002bdd) SHA1(e623399ff95f59a4ab7efdd7c69b1a1370479398))
ROM_END
ROM_START(nf_08x)
ROM_REGION(0x80000, "maincpu", 0)
ROM_LOAD("nofe0_8x.rom", 0x00000, 0x80000, CRC(64871e6a) SHA1(0e116104b06446b0d435f715c33535080cdd2378))
ROM_REGION(0x800000, "dcs", 0)
- ROM_LOAD16_BYTE("snd-u2.sl1", 0x000000, 0x080000, CRC(84f48e27) SHA1(cdf0ff55c1493ea5ac7cef618c985f41442c6f60))// this was found separate from nofe0_8x.rom, but it's added to the oldest revision available
+ ROM_LOAD16_BYTE("snd-u2.sl1", 0x000000, 0x080000, CRC(84f48e27) SHA1(cdf0ff55c1493ea5ac7cef618c985f41442c6f60))
ROM_LOAD16_BYTE("nfu3s", 0x100000, 0x080000, CRC(983e5578) SHA1(374b1397abbdde5fd9257fd45fd8613c94fbd02d))
ROM_LOAD16_BYTE("nfu4s", 0x200000, 0x080000, CRC(9469cd40) SHA1(8a1dd1088f24018f48b114c0b27f0331263d4eea))
ROM_LOAD16_BYTE("nfu5s", 0x300000, 0x080000, CRC(e14d4315) SHA1(63d5ae800cc8a750ea2e3a87c646ab175b60abc7))
@@ -2458,6 +2458,19 @@ ROM_START(rs_lx2)
ROM_LOAD16_BYTE("rs_u8_s.l1", 0xc00000, 0x080000, CRC(c70f2210) SHA1(9be9f271d81d15a4eb123f1377b0c077eef97774))
ROM_END
+ROM_START(rs_pa2)
+ ROM_REGION(0x80000, "maincpu", 0)
+ ROM_LOAD("rs-u6.pa2", 0x00000, 0x80000, CRC(674fd680) SHA1(68a4ef5c40fea6b5eae69fbd0ea4339b5757d572))
+ ROM_REGION16_LE(0x1000000, "dcs", ROMREGION_ERASEFF)
+ ROM_LOAD16_BYTE("rs_u2_s.p3", 0x000000, 0x080000, CRC(3a987553) SHA1(bb174cc48533e19906b5ef9d099670e03a04cc89))
+ ROM_LOAD16_BYTE("rs_u3_s.l1", 0x200000, 0x080000, CRC(719be036) SHA1(fa975a6a93fcaefddcbd1c0b97c49bd9f9608ad4))
+ ROM_LOAD16_BYTE("rs_u4_s.l1", 0x400000, 0x080000, CRC(d452d007) SHA1(b850bc8e17d8940f93c1e7b6a0ab786b092694b3))
+ ROM_LOAD16_BYTE("rs_u5_s.l1", 0x600000, 0x080000, CRC(1faa04c9) SHA1(817bbd7fc0781d84af6c40cb477adf83cef07ab2))
+ ROM_LOAD16_BYTE("rs_u6_s.l1", 0x800000, 0x080000, CRC(eee00add) SHA1(96d664ca73ac896e918d7011c1cda3e55e3731b7))
+ ROM_LOAD16_BYTE("rs_u7_s.l1", 0xa00000, 0x080000, CRC(3a222a54) SHA1(2a788e4ac573bf1d128e5bef9357e62c805014b9))
+ ROM_LOAD16_BYTE("rs_u8_s.l1", 0xc00000, 0x080000, CRC(c70f2210) SHA1(9be9f271d81d15a4eb123f1377b0c077eef97774))
+ROM_END
+
/*------------------------
/ The Flintstones #50029
/------------------------*/
@@ -2903,68 +2916,69 @@ ROM_END
} // Anonymous namespace
-GAME(1994, corv_21, 0, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (2.1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, corv_px4, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (PX4 Prototype)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, corv_px3, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (PX3 Prototype)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, corv_lx1, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (LX1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, corv_lx2, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (LX2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, corv_la1, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (LA1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, dh_lx2, 0, wpc_s, dh, wpc_s_state, init_dh, ROT0, "Williams", "Dirty Harry (LX-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, dh_lf2, dh_lx2, wpc_s, dh, wpc_s_state, init_dh, ROT0, "Williams", "Dirty Harry (LF-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, i500_11r, 0, wpc_s, i500, wpc_s_state, init_i500, ROT0, "Bally", "Indianapolis 500 (1.1R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, i500_10r, i500_11r, wpc_s, i500, wpc_s_state, init_i500, ROT0, "Bally", "Indianapolis 500 (1.0R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, i500_11b, i500_11r, wpc_s, i500, wpc_s_state, init_i500, ROT0, "Bally", "Indianapolis 500 (1.1 Belgium)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, jb_10r, 0, wpc_s, jb, wpc_s_state, init_jb, ROT0, "Williams", "Jack*Bot (1.0R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, jb_10b, jb_10r, wpc_s, jb, wpc_s_state, init_jb, ROT0, "Williams", "Jack*Bot (1.0B) (Belgium/Canada)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, jb_04a, jb_10r, wpc_s, jb, wpc_s_state, init_jb, ROT0, "Williams", "Jack*Bot (0.4A prototype)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, jm_12r, 0, wpc_s, jm, wpc_s_state, init_jm, ROT0, "Williams", "Johnny Mnemonic (1.2R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, jm_12b, jm_12r, wpc_s, jm, wpc_s_state, init_jm, ROT0, "Williams", "Johnny Mnemonic (1.2B) Belgium", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, jm_05r, jm_12r, wpc_s, jm, wpc_s_state, init_jm, ROT0, "Williams", "Johnny Mnemonic (0.5R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, nf_23x, 0, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.3X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, nf_23, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, nf_23f, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.3F)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, nf_22, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, nf_20, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.0)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, nf_10, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (1.0)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, nf_08x, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (0.8X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, rs_l6, 0, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (L-6)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, rs_la5, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (La-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, rs_lx5, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, rs_la4, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (La-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, rs_lx4, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, rs_lx3, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, rs_lx2, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, fs_lx5, 0, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, fs_lx2, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, fs_sp2, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (SP-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, fs_lx3, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, fs_lx4, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, fs_la5, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LA-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, ts_lx5, 0, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LX-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, ts_lh6, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LH-6)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, ts_lx4, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LX-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, ts_la4, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LA-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, ts_la2, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LA-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, ts_pa1, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (PA-1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, ts_lf6, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LF-6) French", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, ts_lm6, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LM-6) Mild", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, tom_13, 0, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.3X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(2005, tom_14h, tom_13, wpc_s, tom, wpc_s_state, init_tom14, ROT0, "Bally", "Theatre Of Magic (1.4H)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, tom_12, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.2X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, tom_12a, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.2A)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, tom_10f, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.0 French)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, tom_06, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (0.6a)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_12, 0, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_12g, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.2 Germany)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_11, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_10r, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.0 R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_10g, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.0 Germany)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_10f, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.0 French)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_03r, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (0.3 R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1995, wd_048r, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (0.48 R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, wcs_l2, 0, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Lx-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, wcs_l1, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Lx-1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, wcs_la2, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (La-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, wcs_p2, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Pa-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, wcs_p3, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Px-3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
-GAME(1994, tfs_12, 0, wpc_s, tfs, wpc_s_state, init_tfs, ROT0, "Bally", "WPC Test Fixture: Security (1.2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, corv_21, 0, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (2.1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, corv_px4, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (PX4 Prototype)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, corv_px3, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (PX3 Prototype)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, corv_lx1, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (LX1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, corv_lx2, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (LX2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, corv_la1, corv_21, wpc_s, corv, wpc_s_state, init_corv, ROT0, "Bally", "Corvette (LA1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, dh_lx2, 0, wpc_s, dh, wpc_s_state, init_dh, ROT0, "Williams", "Dirty Harry (LX-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, dh_lf2, dh_lx2, wpc_s, dh, wpc_s_state, init_dh, ROT0, "Williams", "Dirty Harry (LF-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, i500_11r, 0, wpc_s, i500, wpc_s_state, init_i500, ROT0, "Bally", "Indianapolis 500 (1.1R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, i500_10r, i500_11r, wpc_s, i500, wpc_s_state, init_i500, ROT0, "Bally", "Indianapolis 500 (1.0R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, i500_11b, i500_11r, wpc_s, i500, wpc_s_state, init_i500, ROT0, "Bally", "Indianapolis 500 (1.1 Belgium)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, jb_10r, 0, wpc_s, jb, wpc_s_state, init_jb, ROT0, "Williams", "Jack*Bot (1.0R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, jb_10b, jb_10r, wpc_s, jb, wpc_s_state, init_jb, ROT0, "Williams", "Jack*Bot (1.0B) (Belgium/Canada)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, jb_04a, jb_10r, wpc_s, jb, wpc_s_state, init_jb, ROT0, "Williams", "Jack*Bot (0.4A prototype)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, jm_12r, 0, wpc_s, jm, wpc_s_state, init_jm, ROT0, "Williams", "Johnny Mnemonic (1.2R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, jm_12b, jm_12r, wpc_s, jm, wpc_s_state, init_jm, ROT0, "Williams", "Johnny Mnemonic (1.2B) Belgium", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, jm_05r, jm_12r, wpc_s, jm, wpc_s_state, init_jm, ROT0, "Williams", "Johnny Mnemonic (0.5R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, nf_23x, 0, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.3X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, nf_23, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, nf_23f, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.3F)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, nf_22, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, nf_20, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (2.0)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, nf_10f, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (1.0F)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, nf_08x, nf_23x, wpc_s, nf, wpc_s_state, init_nf, ROT0, "Williams", "No Fear: Dangerous Sports (0.8X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_l6, 0, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (L-6)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_la5, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (La-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_lx5, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_la4, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (La-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_lx4, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_lx3, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_lx2, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (Lx-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, rs_pa2, rs_l6, wpc_s, rs, wpc_s_state, init_rs, ROT0, "Williams", "Red and Ted's Road Show (PA-2 prototype)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, fs_lx5, 0, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, fs_lx2, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, fs_sp2, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (SP-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, fs_lx3, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, fs_lx4, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LX-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, fs_la5, fs_lx5, wpc_s, fs, wpc_s_state, init_fs, ROT0, "Williams", "The Flintstones (LA-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, ts_lx5, 0, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LX-5)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, ts_lh6, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LH-6)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, ts_lx4, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LX-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, ts_la4, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LA-4)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, ts_la2, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LA-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, ts_pa1, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (PA-1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, ts_lf6, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LF-6) French", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, ts_lm6, ts_lx5, wpc_s, ts, wpc_s_state, init_ts, ROT0, "Bally", "The Shadow (LM-6) Mild", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, tom_13, 0, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.3X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(2005, tom_14h, tom_13, wpc_s, tom, wpc_s_state, init_tom14, ROT0, "Bally", "Theatre Of Magic (1.4H)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, tom_12, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.2X)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, tom_12a, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.2A)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, tom_10f, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (1.0 French)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, tom_06, tom_13, wpc_s, tom, wpc_s_state, init_tom, ROT0, "Bally", "Theatre Of Magic (0.6a)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_12, 0, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_12g, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.2 Germany)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_11, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_10r, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.0 R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_10g, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.0 Germany)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_10f, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (1.0 French)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_03r, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (0.3 R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1995, wd_048r, wd_12, wpc_s, wd, wpc_s_state, init_wd, ROT0, "Bally", "Who Dunnit (0.48 R)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, wcs_l2, 0, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Lx-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, wcs_l1, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Lx-1)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, wcs_la2, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (La-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, wcs_p2, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Pa-2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, wcs_p3, wcs_l2, wpc_s, wcs, wpc_s_state, init_wcs, ROT0, "Bally", "World Cup Soccer (Px-3)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
+GAME(1994, tfs_12, 0, wpc_s, tfs, wpc_s_state, init_tfs, ROT0, "Bally", "WPC Test Fixture: Security (1.2)", MACHINE_IS_SKELETON_MECHANICAL | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/rm/rmnimbus.h b/src/mame/rm/rmnimbus.h
index 0fe2e2d83da..fd8ed6909bf 100644
--- a/src/mame/rm/rmnimbus.h
+++ b/src/mame/rm/rmnimbus.h
@@ -87,13 +87,6 @@ public:
void nimbus(machine_config &config);
- uint32_t m_debug_machine = 0;
- uint32_t m_debug_trap = 0;
-
- void decode_subbios(device_t *device, offs_t pc);
- void decode_subbios_return(device_t *device, offs_t pc);
- void decode_dos21(device_t *device, offs_t pc);
-
private:
required_device<i80186_cpu_device> m_maincpu;
required_device<i8031_device> m_iocpu;
diff --git a/src/mame/rm/rmnimbus_m.cpp b/src/mame/rm/rmnimbus_m.cpp
index 39b9ea304f2..cc1bde464de 100644
--- a/src/mame/rm/rmnimbus_m.cpp
+++ b/src/mame/rm/rmnimbus_m.cpp
@@ -63,10 +63,6 @@ chdman createhd -o ST125N.chd -chs 41921,1,1 -ss 512
#include <functional>
#include "rmnimbus.h"
-#include "debugger.h"
-#include "debug/debugcmd.h"
-#include "debug/debugcon.h"
-#include "debug/debugcpu.h"
#include "imagedev/floppy.h"
@@ -136,52 +132,6 @@ chdman createhd -o ST125N.chd -chs 41921,1,1 -ss 512
#define LOG_IOU 0
#define LOG_RAM 0
-/* Debugging */
-
-#define DEBUG_SET(flags) ((m_debug_machine & (flags))==(flags))
-#define DEBUG_SET_STATE(flags) ((state->m_debug_machine & (flags))==(flags))
-
-#define DEBUG_NONE 0x0000000
-#define DECODE_BIOS 0x0000002
-#define DECODE_BIOS_RAW 0x0000004
-#define DECODE_DOS21 0x0000008
-
-/* Nimbus sub-bios structures for debugging */
-
-struct t_area_params
-{
- uint16_t ofs_brush;
- uint16_t seg_brush;
- uint16_t ofs_data;
- uint16_t seg_data;
- uint16_t count;
-};
-
-struct t_plot_string_params
-{
- uint16_t ofs_font;
- uint16_t seg_font;
- uint16_t ofs_data;
- uint16_t seg_data;
- uint16_t x;
- uint16_t y;
- uint16_t length;
-};
-
-struct t_nimbus_brush
-{
- uint16_t style;
- uint16_t style_index;
- uint16_t colour1;
- uint16_t colour2;
- uint16_t transparency;
- uint16_t boundary_spec;
- uint16_t boundary_colour;
- uint16_t save_colour;
-};
-
-
-static int instruction_hook(device_t &device, offs_t curpc);
void rmnimbus_state::external_int(uint8_t vector, bool state)
{
@@ -218,648 +168,11 @@ void rmnimbus_state::machine_start()
{
m_nimbus_mouse.m_mouse_timer = timer_alloc(FUNC(rmnimbus_state::do_mouse), this);
- /* setup debug commands */
- if (machine().debug_flags & DEBUG_FLAG_ENABLED)
- {
- using namespace std::placeholders;
- machine().debugger().console().register_command("nimbus_debug", CMDFLAG_NONE, 0, 1, std::bind(&rmnimbus_state::debug_command, this, _1));
-
- /* set up the instruction hook */
- m_maincpu->debug()->set_instruction_hook(instruction_hook);
- }
-
- m_debug_machine=DEBUG_NONE;
- m_debug_trap=0;
m_voice_enabled=false;
m_fdc->dden_w(0);
//m_fdc->overide_delays(64,m_fdc->get_cmd_delay());
}
-void rmnimbus_state::debug_command(const std::vector<std::string_view> &params)
-{
- if (params.size() > 0)
- {
- uint64_t temp;
- if (!machine().debugger().commands().validate_number_parameter(params[0], temp))
- return;
- m_debug_machine = temp;
- }
- else
- {
- machine().debugger().console().printf("Error usage : nimbus_debug <debuglevel>\n");
- machine().debugger().console().printf("Current debuglevel=%02X\n", m_debug_machine);
- }
-}
-
-/*-----------------------------------------------
- instruction_hook - per-instruction hook
------------------------------------------------*/
-
-static int instruction_hook(device_t &device, offs_t curpc)
-{
- rmnimbus_state *state = device.machine().driver_data<rmnimbus_state>();
- address_space &space = device.memory().space(AS_PROGRAM);
- uint8_t *addr_ptr;
- uint8_t first;
-
- addr_ptr = (uint8_t*)space.get_read_ptr(curpc);
-
- first = (curpc & 0x01) ? 1 : 0;
-
- if(DEBUG_SET_STATE(DECODE_BIOS) && (curpc == state->m_debug_trap) && (0 != state->m_debug_trap))
- {
- state->decode_subbios_return(&device,curpc);
- }
-
- if ((addr_ptr !=nullptr) && (addr_ptr[first]==0xCD))
- {
- if(DEBUG_SET_STATE(DECODE_BIOS) && (addr_ptr[first+1]==0xF0))
- state->decode_subbios(&device,curpc);
-
- if(DEBUG_SET_STATE(DECODE_DOS21) && (addr_ptr[first+1]==0x21))
- state->decode_dos21(&device,curpc);
- }
-
- return 0;
-}
-
-void rmnimbus_state::decode_subbios_return(device_t *device, offs_t pc)
-{
- uint16_t ax = m_maincpu->state_int(I8086_AX);
- uint16_t ds = m_maincpu->state_int(I8086_DS);
- uint16_t si = m_maincpu->state_int(I8086_SI);
-
- if(!DEBUG_SET(DECODE_BIOS_RAW))
- {
- logerror("at %05X sub-bios return code : %04X\n",pc,ax);
- decode_dssi_generic(ds,si);
- logerror("=======================================================================\n");
- }
- else
- logerror("%05X :: %04X\n",pc,ax);
-
- m_debug_trap=0;
-}
-
-#define set_type(type_name) sprintf(type_str,type_name)
-#define set_drv(drv_name) sprintf(drv_str,drv_name)
-#define set_func(func_name) sprintf(func_str,func_name)
-
-void rmnimbus_state::decode_subbios(device_t *device,offs_t pc)
-{
- char type_str[80];
- char drv_str[80];
- char func_str[80];
-
- void (rmnimbus_state::*dump_dssi)(uint16_t, uint16_t) = &rmnimbus_state::decode_dssi_none;
-
- uint16_t ax = m_maincpu->state_int(I8086_AX);
- uint16_t bx = m_maincpu->state_int(I8086_BX);
- uint16_t cx = m_maincpu->state_int(I8086_CX);
- uint16_t ds = m_maincpu->state_int(I8086_DS);
- uint16_t si = m_maincpu->state_int(I8086_SI);
-
- // Set the address to trap after the sub-bios call.
- m_debug_trap=pc+2;
-
- // *** TEMP Don't show f_enquire_display_line calls !
- if((cx==6) && (ax==43))
- return;
- // *** END TEMP
-
- if(!DEBUG_SET(DECODE_BIOS_RAW))
- {
- logerror("=======================================================================\n");
- logerror("Sub-bios call at %08X, AX=%04X, BX=%04X, CX=%04X, DS:SI=%04X:%04X\n",pc,ax,bx,cx,ds,si);
- }
-
- set_type("invalid");
- set_drv("invalid");
- set_func("invalid");
-
- switch (cx)
- {
- case 0 :
- {
- set_type("t_mummu");
- set_drv("d_mummu");
-
- switch (ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_add_type_code"); break;
- case 2 : set_func("f_del_typc_code"); break;
- case 3 : set_func("f_get_TCB"); break;
- case 4 : set_func("f_add_driver_code"); break;
- case 5 : set_func("f_del_driver_code"); break;
- case 6 : set_func("f_get_DCB"); break;
- case 7 : set_func("f_get_copyright"); break;
- }
- }; break;
-
- case 1 :
- {
- set_type("t_character");
- set_drv("d_printer");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_get_output_status"); break;
- case 2 : set_func("f_output_character"); break;
- case 3 : set_func("f_get_input_status"); break;
- case 4 : set_func("f_get_and_remove"); break;
- case 5 : set_func("f_get_no_remove"); break;
- case 6 : set_func("f_get_last_and_remove"); break;
- case 7 : set_func("f_get_last_no_remove"); break;
- case 8 : set_func("f_set_IO_parameters"); break;
- }
- }; break;
-
- case 2 :
- {
- set_type("t_disk");
-
- switch(bx)
- {
- case 0 : set_drv("d_floppy"); break;
- case 1 : set_drv("d_winchester"); break;
- case 2 : set_drv("d_tape"); break;
- case 3 : set_drv("d_rompack"); break;
- case 4 : set_drv("d_eeprom"); break;
- }
-
- dump_dssi = &rmnimbus_state::decode_dssi_generic;
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_initialise_unit"); break;
- case 2 : set_func("f_pseudo_init_unit"); break;
- case 3 : set_func("f_get_device_status"); break;
- case 4 : set_func("f_read_n_sectors"); dump_dssi = &rmnimbus_state::decode_dssi_f_rw_sectors; break;
- case 5 : set_func("f_write_n_sectors"); dump_dssi = &rmnimbus_state::decode_dssi_f_rw_sectors; break;
- case 6 : set_func("f_verify_n_sectors"); dump_dssi = &rmnimbus_state::decode_dssi_f_rw_sectors; break;
- case 7 : set_func("f_media_check"); break;
- case 8 : set_func("f_recalibrate"); break;
- case 9 : set_func("f_motors_off"); break;
- }
-
- }; break;
-
- case 3 :
- {
- set_type("t_piconet");
- set_drv("d_piconet");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_get_slave_status"); break;
- case 2 : set_func("f_get_slave_map"); break;
- case 3 : set_func("f_change_slave_addr"); break;
- case 4 : set_func("f_read_slave_control"); break;
- case 5 : set_func("f_write_slave_control"); break;
- case 6 : set_func("f_send_data_byte"); break;
- case 7 : set_func("f_request_data_byte"); break;
- case 8 : set_func("f_send_data_block"); break;
- case 9 : set_func("f_request_data_block"); break;
- case 10 : set_func("f_reset_slave"); break;
-
- }
- }; break;
-
- case 4 :
- {
- set_type("t_tick");
- set_drv("d_tick");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_ticks_per_second"); break;
- case 2 : set_func("f_link_tick_routine"); break;
- case 3 : set_func("f_unlink_tick_routine"); break;
- }
- }; break;
-
- case 5 :
- {
- set_type("t_graphics_input");
-
- switch(bx)
- {
- case 0 : set_drv("d_mouse"); break;
- case 1 : set_drv("d_joystick_1"); break;
- case 2 : set_drv("d_joystick_2"); break;
- }
-
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_graphics_input_cold_start"); break;
- case 2 : set_func("f_graphics_input_device_off"); break;
- case 3 : set_func("f_return_button_status"); break;
- case 4 : set_func("f_return_switch_and_button_stat"); break;
- case 5 : set_func("f_start_tracking"); break;
- case 6 : set_func("f_stop_tracking"); break;
- case 7 : set_func("f_enquire_position"); break;
- case 8 : set_func("f_set_position"); break;
-
- case 10 : set_func("f_return_button_press_info"); break;
- case 11 : set_func("f_return_button_release_info"); break;
- case 12 : set_func("f_set_gain/f_set_squeaks_per_pixel_ratio"); break;
- case 13 : set_func("f_enquire_graphics_in_misc_data"); break;
- }
- }; break;
-
- case 6 :
- {
- set_type("t_graphics_output");
- set_drv("d_ngc_screen");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_graphics_output_cold_start"); break;
- case 2 : set_func("f_graphics_output_warm_start"); break;
- case 3 : set_func("f_graphics_output_off"); break;
- case 4 : set_func("f_reinit_graphics_output"); break;
- case 5 : set_func("f_polymarker"); break;
- case 6 : set_func("f_polyline"); dump_dssi = &rmnimbus_state::decode_dssi_f_fill_area; break;
- case 7 : set_func("f_fill_area"); dump_dssi = &rmnimbus_state::decode_dssi_f_fill_area; break;
- case 8 : set_func("f_flood_fill_area"); break;
- case 9 : set_func("f_plot_character_string"); dump_dssi = &rmnimbus_state::decode_dssi_f_plot_character_string; break;
- case 10 : set_func("f_define_graphics_clipping_area"); break;
- case 11 : set_func("f_enquire_clipping_area_limits"); break;
- case 12 : set_func("f_select_graphics_clipping_area"); break;
- case 13 : set_func("f_enq_selctd_graphics_clip_area"); break;
- case 14 : set_func("f_set_clt_element"); break;
- case 15 : set_func("f_enquire_clt_element"); break;
- case 16 : set_func("f_set_new_clt"); dump_dssi = &rmnimbus_state::decode_dssi_f_set_new_clt; break;
- case 17 : set_func("f_enquire_clt_contents"); break;
- case 18 : set_func("f_define_dithering_pattern"); break;
- case 19 : set_func("f_enquire_dithering_pattern"); break;
- case 20 : set_func("f_draw_sprite"); break;
- case 21 : set_func("f_move_sprite"); break;
- case 22 : set_func("f_erase_sprite"); break;
- case 23 : set_func("f_read_pixel"); break;
- case 24 : set_func("f_read_to_limit"); break;
- case 25 : set_func("f_read_area_pixel"); break;
- case 26 : set_func("f_write_area_pixel"); break;
- case 27 : set_func("f_copy_area_pixel"); break;
-
- case 29 : set_func("f_read_area_word"); break;
- case 30 : set_func("f_write_area_word"); break;
- case 31 : set_func("f_copy_area_word"); break;
- case 32 : set_func("f_swap_area_word"); break;
- case 33 : set_func("f_set_border_colour"); break;
- case 34 : set_func("f_enquire_border_colour"); break;
- case 35 : set_func("f_enquire_miscellaneous_data"); break;
- case 36 : set_func("f_circle"); break;
-
- case 38 : set_func("f_arc_of_ellipse"); break;
- case 39 : set_func("f_isin"); break;
- case 40 : set_func("f_icos"); break;
- case 41 : set_func("f_define_hatching_pattern"); break;
- case 42 : set_func("f_enquire_hatching_pattern"); break;
- case 43 : set_func("f_enquire_display_line"); break;
- case 44 : set_func("f_plonk_logo"); break;
- }
- }; break;
-
- case 7 :
- {
- set_type("t_zend");
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- }
- }; break;
-
- case 8 :
- {
- set_type("t_zep");
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- }
- }; break;
-
- case 9 :
- {
- set_type("t_raw_console");
-
- switch(bx)
- {
- case 0 :
- {
- set_drv("d_screen");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_plonk_char"); dump_dssi = &rmnimbus_state::decode_dssi_f_plonk_char; break;
- case 2 : set_func("f_plonk_cursor"); break;
- case 3 : set_func("f_kill_cursor"); break;
- case 4 : set_func("f_scroll"); break;
- case 5 : set_func("f_width"); dump_dssi = &rmnimbus_state::decode_dssi_generic; break;
- case 6 : set_func("f_get_char_set"); break;
- case 7 : set_func("f_set_char_set"); break;
- case 8 : set_func("f_reset_char_set"); break;
- case 9 : set_func("f_set_plonk_parameters"); break;
- case 10 : set_func("f_set_cursor_flash_rate"); break;
- }
- }; break;
-
- case 1 :
- {
- set_drv("d_keyboard");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_init_keyboard"); break;
- case 2 : set_func("f_get_last_key_code"); break;
- case 3 : set_func("f_get_bitmap"); break;
- }
- }; break;
- }
- }; break;
-
- case 10 :
- {
- set_type("t_acoustics");
-
- switch(bx)
- {
- case 0 :
- {
- set_drv("d_sound");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_sound_enable"); break;
- case 2 : set_func("f_play_note"); break;
- case 3 : set_func("f_get_queue_status"); break;
- }
- }; break;
-
- case 1 :
- {
- set_drv("d_voice");
-
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- case 1 : set_func("f_talk"); break;
- case 2 : set_func("f_wait_and_talk"); break;
- case 3 : set_func("f_test_talking"); break;
- }
- }
- }
- }; break;
-
- case 11 :
- {
- set_type("t_hard_sums");
- switch(ax)
- {
- case 0 : set_func("f_get_version_number"); break;
- }
- }; break;
- }
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- {
- (this->*dump_dssi)(ds, si);
- }
- else
- {
- logerror("Type=%s, Driver=%s, Function=%s\n",type_str,drv_str,func_str);
-
- (this->*dump_dssi)(ds, si);
- logerror("=======================================================================\n");
- }
-}
-
-static inline void *get_regpair_ptr(address_space &space, uint16_t segment, uint16_t offset)
-{
- int addr;
-
- addr=((segment<<4)+offset);
-
- return space.get_read_ptr(addr);
-}
-
-void rmnimbus_state::decode_dssi_none(uint16_t ds, uint16_t si)
-{
-}
-
-void rmnimbus_state::decode_dssi_generic(uint16_t ds, uint16_t si)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- uint16_t *params;
- int count;
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- return;
-
- params=(uint16_t *)get_regpair_ptr(space,ds,si);
-
- for(count=0; count<10; count++)
- logerror("%04X ",params[count]);
-
- logerror("\n");
-}
-
-
-void rmnimbus_state::decode_dssi_f_fill_area(uint16_t ds, uint16_t si)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
-
- uint16_t *addr_ptr;
- t_area_params *area_params;
- t_nimbus_brush *brush;
- int cocount;
-
- area_params = (t_area_params *)get_regpair_ptr(space,ds,si);
-
- if (!DEBUG_SET(DECODE_BIOS_RAW))
- OUTPUT_SEGOFS("SegBrush:OfsBrush",area_params->seg_brush,area_params->ofs_brush);
-
- brush=(t_nimbus_brush *)space.get_read_ptr(LINEAR_ADDR(area_params->seg_brush,area_params->ofs_brush));
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- {
- logerror("\tdw\t%04X, %04X, %04X, %04X, %04X, %04X, %04X, %04X, %04X, ",
- brush->style,brush->style_index,brush->colour1,brush->colour2,
- brush->transparency,brush->boundary_spec,brush->boundary_colour,brush->save_colour,
- area_params->count);
- }
- else
- {
- logerror("Brush params\n");
- logerror("Style=%04X, StyleIndex=%04X\n",brush->style,brush->style_index);
- logerror("Colour1=%04X, Colour2=%04X\n",brush->colour1,brush->colour2);
- logerror("transparency=%04X, boundary_spec=%04X\n",brush->transparency,brush->boundary_spec);
- logerror("boundary colour=%04X, save colour=%04X\n",brush->boundary_colour,brush->save_colour);
-
-
- OUTPUT_SEGOFS("SegData:OfsData",area_params->seg_data,area_params->ofs_data);
- }
-
- addr_ptr = (uint16_t *)space.get_read_ptr(LINEAR_ADDR(area_params->seg_data,area_params->ofs_data));
- for(cocount=0; cocount < area_params->count; cocount++)
- {
- if(DEBUG_SET(DECODE_BIOS_RAW))
- {
- if(cocount!=(area_params->count-1))
- logerror("%04X, %04X, ",addr_ptr[cocount*2],addr_ptr[(cocount*2)+1]);
- else
- logerror("%04X, %04X ",addr_ptr[cocount*2],addr_ptr[(cocount*2)+1]);
- }
- else
- logerror("x=%d y=%d\n",addr_ptr[cocount*2],addr_ptr[(cocount*2)+1]);
- }
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- logerror("\n");
-}
-
-void rmnimbus_state::decode_dssi_f_plot_character_string(uint16_t ds, uint16_t si)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
-
- uint8_t *char_ptr;
- t_plot_string_params *plot_string_params;
- int charno;
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- return;
-
- plot_string_params=(t_plot_string_params *)get_regpair_ptr(space,ds,si);
-
- OUTPUT_SEGOFS("SegFont:OfsFont",plot_string_params->seg_font,plot_string_params->ofs_font);
- OUTPUT_SEGOFS("SegData:OfsData",plot_string_params->seg_data,plot_string_params->ofs_data);
-
- logerror("x=%d, y=%d, length=%d\n",plot_string_params->x,plot_string_params->y,plot_string_params->length);
-
- char_ptr=(uint8_t*)space.get_read_ptr(LINEAR_ADDR(plot_string_params->seg_data,plot_string_params->ofs_data));
-
- if (plot_string_params->length==0xFFFF)
- logerror("%s",char_ptr);
- else
- for(charno=0;charno<plot_string_params->length;charno++)
- logerror("%c",char_ptr[charno]);
-
- logerror("\n");
-}
-
-void rmnimbus_state::decode_dssi_f_set_new_clt(uint16_t ds, uint16_t si)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- uint16_t *new_colours;
- int colour;
- new_colours=(uint16_t *)get_regpair_ptr(space,ds,si);
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- return;
-
- OUTPUT_SEGOFS("SegColours:OfsColours",ds,si);
-
- for(colour=0;colour<16;colour++)
- logerror("colour #%02X=%04X\n",colour,new_colours[colour]);
-
-}
-
-void rmnimbus_state::decode_dssi_f_plonk_char(uint16_t ds, uint16_t si)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- uint16_t *params;
- params=(uint16_t *)get_regpair_ptr(space,ds,si);
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- return;
-
- OUTPUT_SEGOFS("SegParams:OfsParams",ds,si);
-
- logerror("plonked_char=%c\n",params[0]);
-}
-
-void rmnimbus_state::decode_dssi_f_rw_sectors(uint16_t ds, uint16_t si)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- uint16_t *params;
- int param_no;
-
- if(DEBUG_SET(DECODE_BIOS_RAW))
- return;
-
- params=(uint16_t *)get_regpair_ptr(space,ds,si);
-
- logerror("unitno=%04X, count=%02X, first_sector=%08X buffer=%04X:%04X (%05X)\n",
- params[0],
- params[1],
- ((params[3] * 65536)+params[2]),
- params[5],params[4],
- ((params[5]*16)+params[4])
- );
-
- for(param_no=0;param_no<16;param_no++)
- logerror("%04X ",params[param_no]);
-
- logerror("\n");
-}
-
-void rmnimbus_state::decode_dos21(device_t *device,offs_t pc)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
- //uint16_t *params;
- char *path;
-
- uint16_t ax = m_maincpu->state_int(I8086_AX);
- uint16_t bx = m_maincpu->state_int(I8086_BX);
- uint16_t cx = m_maincpu->state_int(I8086_CX);
- uint16_t dx = m_maincpu->state_int(I8086_DX);
- uint16_t cs = m_maincpu->state_int(I8086_CS);
- uint16_t ds = m_maincpu->state_int(I8086_DS);
- uint16_t es = m_maincpu->state_int(I8086_ES);
- uint16_t ss = m_maincpu->state_int(I8086_SS);
-
- uint16_t si = m_maincpu->state_int(I8086_SI);
- uint16_t di = m_maincpu->state_int(I8086_DI);
- uint16_t bp = m_maincpu->state_int(I8086_BP);
-
- uint8_t dosfn = ax >> 8; // Dos function is AH, upper half of AX.
-
- logerror("=======================================================================\n");
- logerror("DOS Int 0x21 call at %05X\n",pc);
- logerror("AX=%04X, BX=%04X, CX=%04X, DX=%04X\n",ax,bx,cx,dx);
- logerror("CS=%04X, DS=%04X, ES=%04X, SS=%04X\n",cs,ds,es,ss);
- logerror("SI=%04X, DI=%04X, BP=%04X\n",si,di,bp);
- logerror("=======================================================================\n");
-
- if (((dosfn >= 0x39) && (dosfn <= 0x3d))
- || (0x43 == dosfn)
- || (0x4e == dosfn)
- || (0x56 == dosfn)
- || ((dosfn >= 0x5a) && (dosfn <= 0x5b)) )
- {
- path=(char *)get_regpair_ptr(space,ds,dx);
- logerror("Path at DS:DX=%s\n",path);
-
- if (0x56 == dosfn)
- {
- path=(char *)get_regpair_ptr(space,es,di);
- logerror("Path at ES:DI=%s\n",path);
- }
- logerror("=======================================================================\n");
- }
-}
-
#define CBUFLEN 32
offs_t rmnimbus_state::dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer &params)
diff --git a/src/mame/robotron/z1013.cpp b/src/mame/robotron/z1013.cpp
index 9bc0b8763f4..ae7cef2af39 100644
--- a/src/mame/robotron/z1013.cpp
+++ b/src/mame/robotron/z1013.cpp
@@ -67,6 +67,7 @@ public:
z1013_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
+ , m_mainpio(*this, "z80pio")
, m_rom(*this, "maincpu")
, m_ram(*this, "mainram")
, m_cass(*this, "cassette")
@@ -74,12 +75,19 @@ public:
, m_p_videoram(*this, "videoram")
, m_p_chargen(*this, "chargen")
, m_io_keyboard(*this, "X%u", 0U)
+ , m_clock_config(*this, "TAKT")
{ }
void z1013k76(machine_config &config);
void z1013a2(machine_config &config);
void z1013(machine_config &config);
+ DECLARE_INPUT_CHANGED_MEMBER(clock_config_changed);
+
+protected:
+ virtual void machine_reset() override;
+ virtual void machine_start() override;
+
private:
void z1013_keyboard_w(uint8_t data);
uint8_t port_a_r();
@@ -95,10 +103,9 @@ private:
uint8_t m_keyboard_line = 0U;
bool m_keyboard_part = false;
- virtual void machine_reset() override;
- virtual void machine_start() override;
required_device<cpu_device> m_maincpu;
+ required_device<z80pio_device> m_mainpio;
required_region_ptr<u8> m_rom;
required_shared_ptr<u8> m_ram;
required_device<cassette_image_device> m_cass;
@@ -106,6 +113,7 @@ private:
required_shared_ptr<uint8_t> m_p_videoram;
required_region_ptr<u8> m_p_chargen;
optional_ioport_array<9> m_io_keyboard;
+ required_ioport m_clock_config;
};
@@ -120,7 +128,7 @@ void z1013_state::mem_map(address_map &map)
void z1013_state::io_map(address_map &map)
{
map.global_mask(0xff);
- map(0x00, 0x03).rw("z80pio", FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
+ map(0x00, 0x03).rw(m_mainpio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
map(0x08, 0x08).w(FUNC(z1013_state::z1013_keyboard_w));
}
@@ -171,6 +179,11 @@ static INPUT_PORTS_START( z1013_8x4 )
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
+ PORT_START("TAKT")
+ PORT_CONFNAME(3, 3, "System Clock") PORT_CHANGED_MEMBER(DEVICE_SELF, z1013_state, clock_config_changed, 0)
+ PORT_CONFSETTING(3, "1 MHz")
+ PORT_CONFSETTING(2, "2 MHz")
+ PORT_CONFSETTING(1, "4 MHz")
INPUT_PORTS_END
static INPUT_PORTS_START( z1013_8x8 )
@@ -251,6 +264,11 @@ static INPUT_PORTS_START( z1013_8x8 )
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
+ PORT_START("TAKT")
+ PORT_CONFNAME(3, 3, "System Clock") PORT_CHANGED_MEMBER(DEVICE_SELF, z1013_state, clock_config_changed, 0)
+ PORT_CONFSETTING(3, "1 MHz")
+ PORT_CONFSETTING(2, "2 MHz")
+ PORT_CONFSETTING(1, "4 MHz")
INPUT_PORTS_END
static INPUT_PORTS_START( z1013 )
@@ -259,6 +277,11 @@ static INPUT_PORTS_START( z1013 )
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
+ PORT_START("TAKT")
+ PORT_CONFNAME(3, 3, "System Clock") PORT_CHANGED_MEMBER(DEVICE_SELF, z1013_state, clock_config_changed, 0)
+ PORT_CONFSETTING(3, "1 MHz")
+ PORT_CONFSETTING(2, "2 MHz")
+ PORT_CONFSETTING(1, "4 MHz")
INPUT_PORTS_END
@@ -301,6 +324,17 @@ void z1013_state::machine_reset()
m_keyboard_line = 0U;
m_maincpu->set_state_int(Z80_PC, 0xf000);
+
+ const XTAL clock = 8_MHz_XTAL / (1 << m_clock_config->read());
+ m_maincpu->set_unscaled_clock(clock);
+ m_mainpio->set_unscaled_clock(clock);
+}
+
+INPUT_CHANGED_MEMBER(z1013_state::clock_config_changed)
+{
+ const XTAL clock = 8_MHz_XTAL / (1 << newval);
+ m_maincpu->set_unscaled_clock(clock);
+ m_mainpio->set_unscaled_clock(clock);
}
void z1013_state::machine_start()
@@ -422,16 +456,13 @@ GFXDECODE_END
void z1013_state::z1013(machine_config &config)
{
/* basic machine hardware */
- Z80(config, m_maincpu, XTAL(1'000'000));
+ Z80(config, m_maincpu, 8_MHz_XTAL / 8);
m_maincpu->set_addrmap(AS_PROGRAM, &z1013_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &z1013_state::io_map);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_refresh_hz(50);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
- screen.set_size(32*8, 32*8);
- screen.set_visarea(0, 32*8-1, 0, 32*8-1);
+ screen.set_raw(8_MHz_XTAL, 512, 0, 256, 302, 0, 256);
screen.set_screen_update(FUNC(z1013_state::screen_update_z1013));
screen.set_palette("palette");
@@ -443,10 +474,10 @@ void z1013_state::z1013(machine_config &config)
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.50);
/* devices */
- z80pio_device& pio(Z80PIO(config, "z80pio", XTAL(1'000'000)));
- pio.in_pa_callback().set(FUNC(z1013_state::port_a_r));
- pio.in_pb_callback().set(FUNC(z1013_state::port_b_r));
- pio.out_pb_callback().set(FUNC(z1013_state::port_b_w));
+ Z80PIO(config, m_mainpio, 8_MHz_XTAL / 8);
+ m_mainpio->in_pa_callback().set(FUNC(z1013_state::port_a_r));
+ m_mainpio->in_pb_callback().set(FUNC(z1013_state::port_b_r));
+ m_mainpio->out_pb_callback().set(FUNC(z1013_state::port_b_w));
CASSETTE(config, m_cass);
m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED);
@@ -466,17 +497,15 @@ void z1013_state::z1013a2(machine_config &config)
{
z1013(config);
- z80pio_device &pio(*subdevice<z80pio_device>("z80pio"));
- pio.in_pb_callback().set(FUNC(z1013_state::a2_port_b_r));
+ m_mainpio->in_pb_callback().set(FUNC(z1013_state::a2_port_b_r));
}
void z1013_state::z1013k76(machine_config &config)
{
z1013(config);
- z80pio_device &pio(*subdevice<z80pio_device>("z80pio"));
- pio.in_pb_callback().set(FUNC(z1013_state::k7659_port_b_r));
- pio.out_pb_callback().set_nop();
+ m_mainpio->in_pb_callback().set(FUNC(z1013_state::k7659_port_b_r));
+ m_mainpio->out_pb_callback().set_nop();
}
/* ROM definition */
diff --git a/src/mame/sega/eshockey.cpp b/src/mame/sega/eshockey.cpp
new file mode 100644
index 00000000000..bf5afc57907
--- /dev/null
+++ b/src/mame/sega/eshockey.cpp
@@ -0,0 +1,233 @@
+// license:BSD-3-Clause
+// copyright-holders:
+
+/*****************************************************************************
+
+ Sega Exciting Speed Hockey @ 1993
+
+ Hardware is very similar to sega/segaufo.cpp (see 3rd gen hardware).
+ Kept separate because the mechanical parts are very different
+ (crane vs. air hockey), so they will need different simulations.
+
+ Board has two stickers: '834-9442 EXCITING SPEED HOCKEY' and '931105 1336 H'
+ Main components are:
+ 1x Z80 (sticker obscures exact type)
+ 16.000 MHz XTAL
+ 2x 8-dip banks
+ 2x Sega 315-5296(I/O)
+ 1x NEC uPD71054C
+ 1x YM3438
+
+*****************************************************************************/
+
+#include "emu.h"
+
+#include "315_5296.h"
+
+#include "cpu/z80/z80.h"
+#include "machine/pit8253.h"
+#include "sound/ymopn.h"
+
+#include "speaker.h"
+
+
+namespace {
+
+class eshockey_state : public driver_device
+{
+public:
+ eshockey_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu")
+ { }
+
+ void eshockey(machine_config &config);
+
+private:
+ required_device<cpu_device> m_maincpu;
+
+ DECLARE_WRITE_LINE_MEMBER(pit_out0);
+ DECLARE_WRITE_LINE_MEMBER(pit_out1);
+ DECLARE_WRITE_LINE_MEMBER(pit_out2);
+
+ void prg_map(address_map &map);
+ void io_map(address_map &map);
+};
+
+
+/***************************************************************************
+
+ I/O
+
+***************************************************************************/
+
+WRITE_LINE_MEMBER(eshockey_state::pit_out0)
+{
+ // ?
+}
+
+WRITE_LINE_MEMBER(eshockey_state::pit_out1)
+{
+ // NMI?
+ if (state)
+ m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
+}
+
+WRITE_LINE_MEMBER(eshockey_state::pit_out2)
+{
+ // ?
+}
+
+void eshockey_state::prg_map(address_map &map)
+{
+ map(0x0000, 0xbfff).rom();
+ map(0xe000, 0xffff).ram();
+}
+
+void eshockey_state::io_map(address_map &map)
+{
+ map.unmap_value_high();
+ map.global_mask(0xff);
+ map(0x00, 0x03).rw("pit", FUNC(pit8254_device::read), FUNC(pit8254_device::write));
+ map(0x40, 0x43).rw("ym", FUNC(ym3438_device::read), FUNC(ym3438_device::write));
+ map(0x80, 0xbf).rw("io1", FUNC(sega_315_5296_device::read), FUNC(sega_315_5296_device::write));
+ map(0xc0, 0xff).rw("io2", FUNC(sega_315_5296_device::read), FUNC(sega_315_5296_device::write));
+}
+
+
+/***************************************************************************
+
+ Inputs
+
+***************************************************************************/
+
+static INPUT_PORTS_START( eshockey )
+ PORT_START("IN1")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("IN2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("DSW1")
+ PORT_DIPNAME( 0x01, 0x01, "UNK1-01" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, "UNK1-02" )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, "UNK1-04" )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, "UNK1-08" )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, "UNK1-10" )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, "UNK1-20" )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, "UNK1-40" )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, "UNK1-80" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("DSW2")
+ PORT_DIPNAME( 0x01, 0x01, "UNK2-01" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, "UNK2-02" )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, "UNK2-04" )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, "UNK2-08" )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, "UNK2-10" )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, "UNK2-20" )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, "UNK2-40" )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, "UNK2-80" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+INPUT_PORTS_END
+
+
+/***************************************************************************
+
+ Machine Config
+
+***************************************************************************/
+
+void eshockey_state::eshockey(machine_config &config)
+{
+ // basic machine hardware
+ Z80(config, m_maincpu, 16_MHz_XTAL / 2); // divider not verified
+ m_maincpu->set_addrmap(AS_PROGRAM, &eshockey_state::prg_map);
+ m_maincpu->set_addrmap(AS_IO, &eshockey_state::io_map);
+
+ SEGA_315_5296(config, "io1", 16_MHz_XTAL);
+
+ SEGA_315_5296(config, "io2", 16_MHz_XTAL);
+
+ pit8254_device &pit(PIT8254(config, "pit", 16_MHz_XTAL / 2)); // uPD71054C, configuration is unknown, clocks not verified
+ pit.set_clk<0>(16_MHz_XTAL / 2 / 256);
+ pit.out_handler<0>().set(FUNC(eshockey_state::pit_out0));
+ pit.set_clk<1>(16_MHz_XTAL / 2 / 256);
+ pit.out_handler<1>().set(FUNC(eshockey_state::pit_out1));
+ pit.set_clk<2>(16_MHz_XTAL / 2/ 256);
+ pit.out_handler<2>().set(FUNC(eshockey_state::pit_out2));
+
+ // no video
+
+ // sound hardware
+ SPEAKER(config, "mono").front_center();
+
+ ym3438_device &ym(YM3438(config, "ym", 16_MHz_XTAL / 2)); // divider not verified
+ ym.irq_handler().set_inputline("maincpu", 0);
+ ym.add_route(0, "mono", 0.40);
+ ym.add_route(1, "mono", 0.40);
+}
+
+
+/***************************************************************************
+
+ Game drivers
+
+***************************************************************************/
+
+ROM_START( eshockey )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD( "epr-15424.ic21", 0x000000, 0x010000, CRC(e1ec8e6b) SHA1(90e106b23839cbd6ad2fe4d8a74a4fd5252a45cd) )
+
+ ROM_REGION( 0x200, "plds", 0 )
+ ROM_LOAD( "gal16v8a.ic11", 0x000, 0x117, NO_DUMP )
+ROM_END
+
+} // anonymous namespace
+
+
+GAME( 1993, eshockey, 0, eshockey, eshockey, eshockey_state, empty_init, ROT0, "Sega", "Exciting Speed Hockey (V19930325)", MACHINE_IS_SKELETON_MECHANICAL )
diff --git a/src/mame/sega/model3.cpp b/src/mame/sega/model3.cpp
index eb077df1288..a9548f0caec 100644
--- a/src/mame/sega/model3.cpp
+++ b/src/mame/sega/model3.cpp
@@ -5667,7 +5667,7 @@ ROM_START( spikeofe ) /* Step 2.1, Sega game ID# is 833-13746, ROM board ID# 8
ROM_PARAMETER( ":315_5881:key", "29236fc8" )
ROM_END
-ROM_START( eca ) /* Step 2.1 Export version */
+ROM_START( eca ) /* Step 2.1, Sega game ID# is 833-13945-03 ECA EXP, ROM board ID# 834-13946-03 ECA EXP, Security board ID# 837-13947-COM */
ROM_REGION64_BE( 0x8800000, "user1", 0 ) /* program + data ROMs */
// CROM
ROM_LOAD64_WORD_SWAP( "epr-22903.17", 0x000006, 0x200000, CRC(53882217) SHA1(163cbc92ff88671882cc1af377ceec80ba9f36db) )
@@ -5732,7 +5732,7 @@ ROM_START( eca ) /* Step 2.1 Export version */
ROM_PARAMETER( ":315_5881:key", "2923aa91" )
ROM_END
-ROM_START( ecaj ) /* Step 2.1, ROM board ID# 834-13946 ECA */
+ROM_START( ecaj ) /* Step 2.1, Sega game ID# is 833-13945 ECA, ROM board ID# 834-13946 ECA, Security board ID# 837-13947-COM */
ROM_REGION64_BE( 0x8800000, "user1", 0 ) /* program + data ROMs */
// CROM
ROM_LOAD64_WORD_SWAP( "epr-22891.17", 0x000006, 0x200000, CRC(823a251c) SHA1(d2cc4be9dffa860d9af519e1387e7b51322c5454) )
@@ -5797,7 +5797,7 @@ ROM_START( ecaj ) /* Step 2.1, ROM board ID# 834-13946 ECA */
ROM_PARAMETER( ":315_5881:key", "2923aa91" )
ROM_END
-ROM_START( ecau ) /* Step 2.1, ROM board ID# 834-13946-01 ECA */
+ROM_START( ecau ) /* Step 2.1, Sega game ID# is 833-13945-01 ECA, ROM board ID# 834-13946-01 ECA, Security board ID# 837-13947-COM */
ROM_REGION64_BE( 0x8800000, "user1", 0 ) /* program + data ROMs */
// CROM
ROM_LOAD64_WORD_SWAP( "epr-22895.17", 0x000006, 0x200000, CRC(07df16a0) SHA1(a9ad2b229854a5f4f761565141db738adde28720) )
diff --git a/src/mame/sega/segaybd.cpp b/src/mame/sega/segaybd.cpp
index b9d657fce44..52a595e7cf0 100644
--- a/src/mame/sega/segaybd.cpp
+++ b/src/mame/sega/segaybd.cpp
@@ -2665,6 +2665,7 @@ ROM_END
//*************************************************************************************************************************
// Rail Chase (Japan), Sega Y-board
// CPU: 68000 (317-????)
+// GAME BD 834-8072-03 RAIL CHASE
//
ROM_START( rchasej )
ROM_REGION( 0x080000, "maincpu", 0 ) // M
diff --git a/src/mame/taito/groundfx.cpp b/src/mame/taito/groundfx.cpp
index 73d33da7c61..2c0860b91cb 100644
--- a/src/mame/taito/groundfx.cpp
+++ b/src/mame/taito/groundfx.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, David Graves
+// copyright-holders: Bryan McPhail, David Graves
+
/***************************************************************************
Ground Effects / Super Ground FX (c) 1993 Taito
@@ -56,7 +57,7 @@
Ground Effects is effectively a 30Hz game - though the vblank interrupts
still come in at 60Hz, the game uses a hardware frame counter to limit
itself to 30Hz (it only updates things like the video registers every
- other vblank). There isn't enough cpu power in a 20MHz 68020 to run
+ other vblank). There isn't enough CPU power in a 20MHz 68020 to run
this game at 60Hz.
Ground Effects has a network mode - probably uses IRQ 6 and the unknown
@@ -65,18 +66,350 @@
***************************************************************************/
#include "emu.h"
-#include "groundfx.h"
+
#include "taito_en.h"
#include "taitoio.h"
+#include "tc0100scn.h"
+#include "tc0480scp.h"
#include "cpu/m68000/m68000.h"
#include "machine/adc0808.h"
#include "machine/eepromser.h"
#include "sound/es5506.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+namespace {
+
+class groundfx_state : public driver_device
+{
+public:
+ groundfx_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_ram(*this, "ram"),
+ m_spriteram(*this, "spriteram"),
+ m_maincpu(*this, "maincpu"),
+ m_tc0620scc(*this, "tc0620scc"),
+ m_tc0480scp(*this, "tc0480scp"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_spritemap(*this, "spritemap")
+ { }
+
+ void groundfx(machine_config &config);
+ void init_groundfx();
+
+protected:
+ virtual void video_start() override;
+
+private:
+ required_shared_ptr<u32> m_ram;
+ required_shared_ptr<u32> m_spriteram;
+
+ required_device<cpu_device> m_maincpu;
+ required_device<tc0620scc_device> m_tc0620scc;
+ required_device<tc0480scp_device> m_tc0480scp;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+ required_region_ptr<u16> m_spritemap;
+
+ struct gfx_tempsprite
+ {
+ u8 gfx = 0U;
+ u32 code = 0U, color = 0U;
+ bool flipx = false, flipy = false;
+ int x = 0, y = 0;
+ int zoomx = 0, zoomy = 0;
+ u8 pri = 0;
+ };
+
+ u16 m_frame_counter = 0U;
+ u8 m_port_sel = 0U;
+ std::unique_ptr<gfx_tempsprite[]> m_spritelist{};
+ u16 m_rotate_ctrl[8]{};
+ rectangle m_hack_cliprect{};
+
+ void rotate_control_w(offs_t offset, u16 data);
+ void motor_control_w(u32 data);
+ u32 irq_speedup_r();
+ DECLARE_READ_LINE_MEMBER(frame_counter_r);
+ void coin_word_w(u8 data);
+ u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ INTERRUPT_GEN_MEMBER(interrupt);
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int do_hack, int x_offs, int y_offs);
+
+ void prg_map(address_map &map);
+};
+
+
+// video
+
+/******************************************************************/
+
+void groundfx_state::video_start()
+{
+ m_spritelist = std::make_unique<gfx_tempsprite[]>(0x4000);
+
+ save_item(NAME(m_frame_counter));
+ save_item(NAME(m_port_sel));
+ save_item(NAME(m_rotate_ctrl));
+
+ // Hack
+ m_hack_cliprect.set(69, 250, 24 + 5, 24 + 44);
+}
+
+/***************************************************************
+ SPRITE DRAW ROUTINES
+
+We draw a series of small tiles ("chunks") together to
+create each big sprite. The spritemap ROM provides the lookup
+table for this. The game hardware looks up 16x16 sprite chunks
+from the spritemap ROM, creating a 64x64 sprite like this:
+
+ 0 1 2 3
+ 4 5 6 7
+ 8 9 10 11
+ 12 13 14 15
+
+(where the number is the word offset into the spritemap ROM).
+It can also create 32x32 sprites.
+
+NB: unused portions of the spritemap ROM contain hex FF's.
+It is a useful coding check to warn in the log if these
+are being accessed. [They can be inadvertently while
+spriteram is being tested, take no notice of that.]
+
+Heavy use is made of sprite zooming.
+
+ ***
+
+ Sprite table layout (4 long words per entry)
+
+ ------------------------------------------
+ 0 | ........ x....... ........ ........ | Flip X
+ 0 | ........ .xxxxxxx ........ ........ | ZoomX
+ 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
+ | |
+ 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
+ 2 | ........ ......xx xxxxxx.. ........ | Palette bank
+ 2 | ........ ........ ......xx xxxxxxxx | X position
+ | |
+ 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
+ 3 | ........ ......x. ........ ........ | Flip Y
+ 3 | ........ .......x xxxxxx.. ........ | ZoomY
+ 3 | ........ ........ ......xx xxxxxxxx | Y position
+ ------------------------------------------
+
+ [* 00=over BG0, 01=BG1, 10=BG2, 11=BG3 ]
+ [or 00=over BG1, 01=BG2, 10=BG3, 11=BG3 ]
+
+***************************************************************/
+
+void groundfx_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int do_hack, int x_offs, int y_offs)
+{
+ int sprites_flipscreen = 0;
+ static const u32 primasks[4] = {0xffff, 0xfffc, 0xfff0, 0xff00 };
+
+ /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
+ while processing sprite ram and then draw them all at the end */
+ struct gfx_tempsprite *sprite_ptr = m_spritelist.get();
+
+ for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4)
+ {
+ u32 data = m_spriteram[offs+0];
+ int flipx = (data & 0x00800000) >> 23;
+ int zoomx = (data & 0x007f0000) >> 16;
+ const u32 tilenum = (data & 0x00007fff);
+
+ data = m_spriteram[offs+2];
+ const int priority = (data & 0x000c0000) >> 18;
+ u32 color = (data & 0x0003fc00) >> 10;
+ int x = (data & 0x000003ff);
+
+ data = m_spriteram[offs+3];
+ const int dblsize = (data & 0x00040000) >> 18;
+ int flipy = (data & 0x00020000) >> 17;
+ int zoomy = (data & 0x0001fc00) >> 10;
+ int y = (data & 0x000003ff);
+
+// color |= (0x100 + (priority << 6)); // priority bits select color bank
+ color /= 2; // as sprites are 5bpp
+ flipy = !flipy;
+ y = (-y & 0x3ff);
+
+ if (!tilenum) continue;
+
+ flipy = !flipy;
+ zoomx += 1;
+ zoomy += 1;
+
+ y += y_offs;
+
+ // treat coords as signed
+ if (x > 0x340) x -= 0x400;
+ if (y > 0x340) y -= 0x400;
+
+ x -= x_offs;
+
+ const int dimension = ((dblsize * 2) + 2); // 2 or 4
+ const int total_chunks = ((dblsize * 3) + 1) << 2; // 4 or 16
+ const int map_offset = tilenum << 2;
+
+ {
+ for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++)
+ {
+ const int j = sprite_chunk / dimension; // rows
+ const int k = sprite_chunk % dimension; // chunks per row
+
+ int px = k;
+ int py = j;
+ // pick tiles back to front for x and y flips
+ if (flipx) px = dimension - 1 - k;
+ if (flipy) py = dimension - 1 - j;
+
+ const u16 code = m_spritemap[map_offset + px + (py << (dblsize + 1))];
+
+ if (code == 0xffff)
+ {
+ continue;
+ }
+
+ int curx = x + ((k * zoomx) / dimension);
+ int cury = y + ((j * zoomy) / dimension);
+
+ const int zx = x + (((k + 1) * zoomx) / dimension) - curx;
+ const int zy = y + (((j + 1) * zoomy) / dimension) - cury;
+
+ if (sprites_flipscreen)
+ {
+ /* -zx/y is there to fix zoomed sprite coords in screenflip.
+ drawgfxzoom does not know to draw from flip-side of sprites when
+ screen is flipped; so we must correct the coords ourselves. */
+
+ curx = 320 - curx - zx;
+ cury = 256 - cury - zy;
+ flipx = !flipx;
+ flipy = !flipy;
+ }
+
+ sprite_ptr->gfx = 0;
+ sprite_ptr->code = code;
+ sprite_ptr->color = color;
+ sprite_ptr->flipx = !flipx;
+ sprite_ptr->flipy = flipy;
+ sprite_ptr->x = curx;
+ sprite_ptr->y = cury;
+ sprite_ptr->zoomx = zx << 12;
+ sprite_ptr->zoomy = zy << 12;
+ sprite_ptr->pri = priority;
+ sprite_ptr++;
+ }
+ }
+ }
+
+ // this happens only if primsks != nullptr
+ while (sprite_ptr != m_spritelist.get())
+ {
+ const rectangle *clipper;
+
+ sprite_ptr--;
+
+ if (do_hack && sprite_ptr->pri == 1 && sprite_ptr->y < 100)
+ clipper = &m_hack_cliprect;
+ else
+ clipper = &cliprect;
+
+ m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap, *clipper,
+ sprite_ptr->code,
+ sprite_ptr->color,
+ sprite_ptr->flipx, sprite_ptr->flipy,
+ sprite_ptr->x, sprite_ptr->y,
+ sprite_ptr->zoomx, sprite_ptr->zoomy,
+ screen.priority(), primasks[sprite_ptr->pri], 0);
+ }
+}
+
+/**************************************************************
+ SCREEN REFRESH
+**************************************************************/
+
+u32 groundfx_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ u8 layer[5];
+ u8 scclayer[3];
+
+ m_tc0620scc->tilemap_update();
+ m_tc0480scp->tilemap_update();
+
+ const u16 priority = m_tc0480scp->get_bg_priority();
+
+ layer[0] = (priority & 0xf000) >> 12; // tells us which bg layer is bottom
+ layer[1] = (priority & 0x0f00) >> 8;
+ layer[2] = (priority & 0x00f0) >> 4;
+ layer[3] = (priority & 0x000f) >> 0; // tells us which is top
+ layer[4] = 4; // text layer always over bg layers
+
+ scclayer[0] = m_tc0620scc->bottomlayer();
+ scclayer[1] = scclayer[0] ^ 1;
+ scclayer[2] = 2;
+
+ screen.priority().fill(0, cliprect);
+ bitmap.fill(0, cliprect); // wrong color?
+
+ m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[0], TILEMAP_DRAW_OPAQUE, 0);
+ m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[1], 0, 0);
+
+ /* BIG HACK!
+
+ The rear view mirror is a big priority trick - the text
+ layer of TC0100SCN is used as a stencil to display
+ the bottom layer of TC0480SCP and a particular sprite
+ priority. These never appear outside of the stencil.
+
+ I'm not sure how the game turns this effect on/off
+ (the 480 layer is used normally in the frontend
+ of the game).
+
+ I haven't implemented it properly yet, instead I'm
+ doing a hacky cliprect around the rearview and drawing
+ its contents the usual way.
+
+ */
+ if (m_tc0620scc->ram_r(0x4090 / 2) || m_tc0620scc->ram_r(0x4092 / 2) ||
+ ((m_tc0480scp->ram_r(0x20 / 2) == 0x24) && (m_tc0480scp->ram_r(0x22 / 2) == 0x0866))) // Anything in text layer - really stupid hack
+ {
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8);
+
+ //m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, 0, scclayer[2], 0, 0);
+
+ if ((m_tc0480scp->ram_r(0x20 / 2) != 0x24) && (m_tc0480scp->ram_r(0x22 / 2) != 0x0866)) // Stupid hack for start of race
+ m_tc0480scp->tilemap_draw(screen, bitmap, m_hack_cliprect, layer[0], 0, 0);
+ draw_sprites(screen, bitmap, cliprect, 1, 44, -574);
+ }
+ else
+ {
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], 0, 1);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4);
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8);
+
+ m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[2], 0, 0);
+
+ draw_sprites(screen, bitmap, cliprect, 0, 44, -574);
+ }
+
+ m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); // TC0480SCP text layer
+ return 0;
+}
+
+
+// machine
+
/**********************************************************
GAME INPUTS
**********************************************************/
@@ -88,13 +421,13 @@ READ_LINE_MEMBER(groundfx_state::frame_counter_r)
void groundfx_state::coin_word_w(u8 data)
{
- machine().bookkeeping().coin_lockout_w(0,~data & 0x01);
- machine().bookkeeping().coin_lockout_w(1,~data & 0x02);
+ machine().bookkeeping().coin_lockout_w(0, ~data & 0x01);
+ machine().bookkeeping().coin_lockout_w(1, ~data & 0x02);
machine().bookkeeping().coin_counter_w(0, data & 0x04);
machine().bookkeeping().coin_counter_w(1, data & 0x08);
}
-void groundfx_state::rotate_control_w(offs_t offset, u16 data) /* only a guess that it's rotation */
+void groundfx_state::rotate_control_w(offs_t offset, u16 data) // only a guess that it's rotation
{
if (offset & 1)
{
@@ -110,7 +443,7 @@ void groundfx_state::rotate_control_w(offs_t offset, u16 data) /* only a guess t
void groundfx_state::motor_control_w(u32 data)
{
/*
- Standard value poked is 0x00910200 (we ignore lsb and msb
+ Standard value poked is 0x00910200 (we ignore LSB and MSB
which seem to be always zero)
0x0, 0x8000 and 0x9100 are written at startup
@@ -128,28 +461,28 @@ void groundfx_state::motor_control_w(u32 data)
MEMORY STRUCTURES
***********************************************************/
-void groundfx_state::groundfx_map(address_map &map)
+void groundfx_state::prg_map(address_map &map)
{
map(0x000000, 0x1fffff).rom();
- map(0x200000, 0x21ffff).ram().share("ram"); /* main CPUA ram */
- map(0x300000, 0x303fff).ram().share("spriteram"); /* sprite ram */
- map(0x400000, 0x400003).w(FUNC(groundfx_state::motor_control_w)); /* gun vibration */
+ map(0x200000, 0x21ffff).ram().share(m_ram); // main CPUA RAM
+ map(0x300000, 0x303fff).ram().share(m_spriteram);
+ map(0x400000, 0x400003).w(FUNC(groundfx_state::motor_control_w)); // gun vibration
map(0x500000, 0x500007).rw("tc0510nio", FUNC(tc0510nio_device::read), FUNC(tc0510nio_device::write));
map(0x600000, 0x600007).rw("adc", FUNC(adc0808_device::data_r), FUNC(adc0808_device::address_offset_start_w)).umask32(0xffffffff);
map(0x700000, 0x7007ff).rw("taito_en:dpram", FUNC(mb8421_device::left_r), FUNC(mb8421_device::left_w));
- map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); /* tilemaps */
+ map(0x800000, 0x80ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); // tilemaps
map(0x830000, 0x83002f).rw(m_tc0480scp, FUNC(tc0480scp_device::ctrl_r), FUNC(tc0480scp_device::ctrl_w)); // debugging
- map(0x900000, 0x90ffff).rw(m_tc0620scc, FUNC(tc0620scc_device::ram_r), FUNC(tc0620scc_device::ram_w)); /* 6bpp tilemaps */
+ map(0x900000, 0x90ffff).rw(m_tc0620scc, FUNC(tc0620scc_device::ram_r), FUNC(tc0620scc_device::ram_w)); // 6bpp tilemaps
map(0x920000, 0x92000f).rw(m_tc0620scc, FUNC(tc0620scc_device::ctrl_r), FUNC(tc0620scc_device::ctrl_w));
map(0xa00000, 0xa0ffff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
map(0xb00000, 0xb003ff).ram(); // ?? single bytes, blending ??
- map(0xc00000, 0xc00007).nopr(); /* Network? */
- map(0xd00000, 0xd00003).w(FUNC(groundfx_state::rotate_control_w)); /* perhaps port based rotate control? */
- /* f00000 is seat control? */
+ map(0xc00000, 0xc00007).nopr(); // Network?
+ map(0xd00000, 0xd00003).w(FUNC(groundfx_state::rotate_control_w)); // perhaps port based rotate control?
+ // f00000 is seat control?
}
/***********************************************************
- INPUT PORTS (dips in eprom)
+ INPUT PORTS (dips in EPROM)
***********************************************************/
static INPUT_PORTS_START( groundfx )
@@ -186,13 +519,13 @@ INPUT_PORTS_END
static const gfx_layout tile16x16_layout =
{
- 16,16, /* 16*16 sprites */
+ 16,16, // 16*16 sprites
RGN_FRAC(1,5),
- 5, /* 5 bits per pixel */
+ 5, // 5 bits per pixel
{ 0, RGN_FRAC(1,5), RGN_FRAC(2,5), RGN_FRAC(3,5), RGN_FRAC(4,5) },
{ STEP16(0,1) },
{ STEP16(0,16) },
- 16*16 /* every sprite takes 128 consecutive bytes */
+ 16*16 // every sprite takes 128 consecutive bytes
};
static GFXDECODE_START( gfx_groundfx )
@@ -212,17 +545,17 @@ INTERRUPT_GEN_MEMBER(groundfx_state::interrupt)
void groundfx_state::groundfx(machine_config &config)
{
- /* basic machine hardware */
- M68EC020(config, m_maincpu, XTAL(40'000'000) / 2); /* 20MHz - verified */
- m_maincpu->set_addrmap(AS_PROGRAM, &groundfx_state::groundfx_map);
+ // basic machine hardware
+ M68EC020(config, m_maincpu, XTAL(40'000'000) / 2); // 20MHz - verified
+ m_maincpu->set_addrmap(AS_PROGRAM, &groundfx_state::prg_map);
m_maincpu->set_vblank_int("screen", FUNC(groundfx_state::interrupt));
EEPROM_93C46_16BIT(config, "eeprom");
- adc0809_device &adc(ADC0809(config, "adc", 500000)); // unknown clock
+ adc0809_device &adc(ADC0809(config, "adc", 500'000)); // unknown clock
adc.eoc_ff_callback().set_inputline("maincpu", 5);
adc.in_callback<0>().set_constant(0); // unknown
- adc.in_callback<1>().set_constant(0); // unknown (used to be labeled 'volume' - but doesn't seem to affect it
+ adc.in_callback<1>().set_constant(0); // unknown (used to be labeled 'volume' - but doesn't seem to affect it)
adc.in_callback<2>().set_ioport("WHEEL");
adc.in_callback<3>().set_ioport("ACCEL");
@@ -236,7 +569,7 @@ void groundfx_state::groundfx(machine_config &config)
tc0510nio.write_4_callback().set(FUNC(groundfx_state::coin_word_w));
tc0510nio.read_7_callback().set_ioport("SYSTEM");
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
@@ -257,7 +590,7 @@ void groundfx_state::groundfx(machine_config &config)
m_tc0480scp->set_offsets(0x24, 0);
m_tc0480scp->set_offsets_tx(-1, 0);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
@@ -271,7 +604,7 @@ void groundfx_state::groundfx(machine_config &config)
***************************************************************************/
ROM_START( groundfx )
- ROM_REGION( 0x200000, "maincpu", 0 ) /* 2048K for 68020 code (CPU A) */
+ ROM_REGION( 0x200000, "maincpu", 0 ) // 68020 code (CPU A)
ROM_LOAD32_BYTE( "d51-24.79", 0x00000, 0x80000, CRC(5caaa031) SHA1(03e727e26df701e3f5e16c5f933d5b29a528945a) )
ROM_LOAD32_BYTE( "d51-23.61", 0x00001, 0x80000, CRC(462e3c9b) SHA1(7f116ee755748497b911868a948d3e3b5134e475) )
ROM_LOAD32_BYTE( "d51-22.77", 0x00002, 0x80000, CRC(b6b04d88) SHA1(58685ee8fd788dcbfe318f1e3c06d93e2128034c) )
@@ -281,29 +614,29 @@ ROM_START( groundfx )
ROM_LOAD16_BYTE( "d51-29.54", 0x100000, 0x40000, CRC(4b64f41d) SHA1(040427668d13f7320d23805098d6d0e1aa8d121e) )
ROM_LOAD16_BYTE( "d51-30.56", 0x100001, 0x40000, CRC(45f339fe) SHA1(cc7adfb2b86070f5bb426542e3b7ed2a50b3c39e) )
- ROM_REGION( 0x400000, "tc0480scp", 0 )
- ROM_LOAD32_WORD( "d51-08.35", 0x000000, 0x200000, CRC(835b7a0f) SHA1(0131fceabd73b0045b5d4ae0bb2f03efdd407962) ) /* SCR 16x16 tiles */
+ ROM_REGION( 0x400000, "tc0480scp", 0 ) // SCR 16x16 tiles
+ ROM_LOAD32_WORD( "d51-08.35", 0x000000, 0x200000, CRC(835b7a0f) SHA1(0131fceabd73b0045b5d4ae0bb2f03efdd407962) )
ROM_LOAD32_WORD( "d51-09.34", 0x000002, 0x200000, CRC(6dabd83d) SHA1(3dbd7ea36b9900faa6420af1f1600efe295db74c) )
- ROM_REGION( 0xa00000, "sprites", 0 )
- ROM_LOAD16_WORD_SWAP( "d51-03.47", 0x000000, 0x200000, CRC(629a5c99) SHA1(cfc1c0b07ecefd6eddb83edcbcf710e8b8de19e4) ) /* OBJ 16x16 tiles */
+ ROM_REGION( 0xa00000, "sprites", 0 ) // OBJ 16x16 tiles
+ ROM_LOAD16_WORD_SWAP( "d51-03.47", 0x000000, 0x200000, CRC(629a5c99) SHA1(cfc1c0b07ecefd6eddb83edcbcf710e8b8de19e4) )
ROM_LOAD16_WORD_SWAP( "d51-04.48", 0x200000, 0x200000, CRC(f49b14b7) SHA1(31129771159c1295a074c8311344ece525302289) )
ROM_LOAD16_WORD_SWAP( "d51-05.49", 0x400000, 0x200000, CRC(3a2e2cbf) SHA1(ed2c1ca9211b1d70b4767a54e08263a3e4867199) )
ROM_LOAD16_WORD_SWAP( "d51-06.50", 0x600000, 0x200000, CRC(d33ce2a0) SHA1(92c4504344672ea798cd6dd34f4b46848bf9f82b) )
ROM_LOAD16_WORD_SWAP( "d51-07.51", 0x800000, 0x200000, CRC(24b2f97d) SHA1(6980e67b435d189ce897c0301e0411763410ab47) )
- ROM_REGION( 0x200000, "tc0620scc", 0 )
- ROM_LOAD16_BYTE( "d51-10.95", 0x000001, 0x100000, CRC(d5910604) SHA1(8efe13884cfdef208394ddfe19f43eb1b9f78ff3) ) /* SCC 8x8 tiles, 4bpp */
+ ROM_REGION( 0x200000, "tc0620scc", 0 ) // SCC 8x8 tiles, 4bpp
+ ROM_LOAD16_BYTE( "d51-10.95", 0x000001, 0x100000, CRC(d5910604) SHA1(8efe13884cfdef208394ddfe19f43eb1b9f78ff3) )
ROM_LOAD16_BYTE( "d51-11.96", 0x000000, 0x100000, CRC(fee5f5c6) SHA1(1be88747f9c71c348dd61a8f0040007df3a3e6a6) )
- ROM_REGION( 0x100000, "tc0620scc:hi_gfx", 0 )
- ROM_LOAD ( "d51-12.97", 0x000000, 0x100000, CRC(d630287b) SHA1(2fa09e1821b7280d193ca9a2a270759c3c3189d1) ) /* SCC 8x8 tiles, 2bpp */
+ ROM_REGION( 0x100000, "tc0620scc:hi_gfx", 0 ) // SCC 8x8 tiles, 2bpp
+ ROM_LOAD ( "d51-12.97", 0x000000, 0x100000, CRC(d630287b) SHA1(2fa09e1821b7280d193ca9a2a270759c3c3189d1) )
- ROM_REGION16_LE( 0x80000, "spritemap", 0 )
- ROM_LOAD16_WORD( "d51-13.7", 0x00000, 0x80000, CRC(36921b8b) SHA1(2130120f78a3b984618a53054fc937cf727177b9) ) /* STY, spritemap */
+ ROM_REGION16_LE( 0x80000, "spritemap", 0 ) // STY
+ ROM_LOAD16_WORD( "d51-13.7", 0x00000, 0x80000, CRC(36921b8b) SHA1(2130120f78a3b984618a53054fc937cf727177b9) )
ROM_REGION16_BE( 0x1000000, "taito_en:ensoniq", ROMREGION_ERASE00 )
- ROM_LOAD16_BYTE( "d51-01.73", 0x000000, 0x200000, CRC(92f09155) SHA1(8015e1997818bb480174394eb43840bf26679bcf) ) /* Ensoniq samples */
+ ROM_LOAD16_BYTE( "d51-01.73", 0x000000, 0x200000, CRC(92f09155) SHA1(8015e1997818bb480174394eb43840bf26679bcf) )
ROM_LOAD16_BYTE( "d51-02.74", 0xc00000, 0x200000, CRC(20a9428f) SHA1(c9033d02a49c72f704808f5f899101617d5814e5) )
ROM_REGION16_BE( 0x80, "eeprom", 0 )
@@ -333,9 +666,11 @@ u32 groundfx_state::irq_speedup_r()
void groundfx_state::init_groundfx()
{
- /* Speedup handlers */
+ // Speedup handlers
m_maincpu->space(AS_PROGRAM).install_read_handler(0x20b574, 0x20b577, read32smo_delegate(*this, FUNC(groundfx_state::irq_speedup_r)));
}
+} // anonymous namespace
+
-GAME( 1992, groundfx, 0, groundfx, groundfx, groundfx_state, init_groundfx, ROT0, "Taito Corporation", "Ground Effects / Super Ground Effects (Japan)", MACHINE_NODEVICE_LAN )
+GAME( 1992, groundfx, 0, groundfx, groundfx, groundfx_state, init_groundfx, ROT0, "Taito Corporation", "Ground Effects / Super Ground Effects (Japan)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/taito/groundfx.h b/src/mame/taito/groundfx.h
deleted file mode 100644
index 10f4e9ac63e..00000000000
--- a/src/mame/taito/groundfx.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, David Graves
-#ifndef MAME_INCLUDES_GROUNDFX_H
-#define MAME_INCLUDES_GROUNDFX_H
-
-#pragma once
-
-#include "tc0100scn.h"
-#include "tc0480scp.h"
-#include "emupal.h"
-
-struct gfx_tempsprite
-{
- u8 gfx = 0U;
- u32 code = 0U, color = 0U;
- bool flipx = false, flipy = false;
- int x = 0, y = 0;
- int zoomx = 0, zoomy = 0;
- int pri = 0;
-};
-
-class groundfx_state : public driver_device
-{
-public:
- groundfx_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_ram(*this, "ram"),
- m_spriteram(*this, "spriteram"),
- m_maincpu(*this, "maincpu"),
- m_tc0620scc(*this, "tc0620scc"),
- m_tc0480scp(*this, "tc0480scp"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_spritemap(*this, "spritemap")
- { }
-
- void groundfx(machine_config &config);
- void init_groundfx();
-
-protected:
- virtual void video_start() override;
-
-private:
- required_shared_ptr<u32> m_ram;
- required_shared_ptr<u32> m_spriteram;
-
- required_device<cpu_device> m_maincpu;
- required_device<tc0620scc_device> m_tc0620scc;
- required_device<tc0480scp_device> m_tc0480scp;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
- required_region_ptr<u16> m_spritemap;
-
- u16 m_frame_counter = 0U;
- u16 m_port_sel = 0U;
- std::unique_ptr<gfx_tempsprite[]> m_spritelist{};
- u16 m_rotate_ctrl[8]{};
- rectangle m_hack_cliprect{};
-
- void rotate_control_w(offs_t offset, u16 data);
- void motor_control_w(u32 data);
- u32 irq_speedup_r();
- DECLARE_READ_LINE_MEMBER(frame_counter_r);
- void coin_word_w(u8 data);
- u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- INTERRUPT_GEN_MEMBER(interrupt);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,int do_hack,int x_offs,int y_offs);
-
- void groundfx_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_GROUNDFX_H
diff --git a/src/mame/taito/groundfx_v.cpp b/src/mame/taito/groundfx_v.cpp
deleted file mode 100644
index 3f6ba5f6ce9..00000000000
--- a/src/mame/taito/groundfx_v.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, David Graves
-#include "emu.h"
-#include "groundfx.h"
-#include "screen.h"
-
-/******************************************************************/
-
-void groundfx_state::video_start()
-{
- m_spritelist = std::make_unique<gfx_tempsprite[]>(0x4000);
-
- /* Hack */
- m_hack_cliprect.set(69, 250, 24 + 5, 24 + 44);
-}
-
-/***************************************************************
- SPRITE DRAW ROUTINES
-
-We draw a series of small tiles ("chunks") together to
-create each big sprite. The spritemap rom provides the lookup
-table for this. The game hardware looks up 16x16 sprite chunks
-from the spritemap rom, creating a 64x64 sprite like this:
-
- 0 1 2 3
- 4 5 6 7
- 8 9 10 11
- 12 13 14 15
-
-(where the number is the word offset into the spritemap rom).
-It can also create 32x32 sprites.
-
-NB: unused portions of the spritemap rom contain hex FF's.
-It is a useful coding check to warn in the log if these
-are being accessed. [They can be inadvertently while
-spriteram is being tested, take no notice of that.]
-
-Heavy use is made of sprite zooming.
-
- ***
-
- Sprite table layout (4 long words per entry)
-
- ------------------------------------------
- 0 | ........ x....... ........ ........ | Flip X
- 0 | ........ .xxxxxxx ........ ........ | ZoomX
- 0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
- | |
- 2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
- 2 | ........ ......xx xxxxxx.. ........ | Palette bank
- 2 | ........ ........ ......xx xxxxxxxx | X position
- | |
- 3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
- 3 | ........ ......x. ........ ........ | Flip Y
- 3 | ........ .......x xxxxxx.. ........ | ZoomY
- 3 | ........ ........ ......xx xxxxxxxx | Y position
- ------------------------------------------
-
- [* 00=over BG0, 01=BG1, 10=BG2, 11=BG3 ]
- [or 00=over BG1, 01=BG2, 10=BG3, 11=BG3 ]
-
-***************************************************************/
-
-void groundfx_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap,const rectangle &cliprect,int do_hack,int x_offs,int y_offs)
-{
- int sprites_flipscreen = 0;
- static const u32 primasks[4] = {0xffff, 0xfffc, 0xfff0, 0xff00 };
-
- /* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
- while processing sprite ram and then draw them all at the end */
- struct gfx_tempsprite *sprite_ptr = m_spritelist.get();
-
- for (int offs = (m_spriteram.bytes() / 4 - 4); offs >= 0; offs -= 4)
- {
- u32 data = m_spriteram[offs+0];
- int flipx = (data & 0x00800000) >> 23;
- int zoomx = (data & 0x007f0000) >> 16;
- const u32 tilenum = (data & 0x00007fff);
-
- data = m_spriteram[offs+2];
- const int priority = (data & 0x000c0000) >> 18;
- u32 color = (data & 0x0003fc00) >> 10;
- int x = (data & 0x000003ff);
-
- data = m_spriteram[offs+3];
- const int dblsize = (data & 0x00040000) >> 18;
- int flipy = (data & 0x00020000) >> 17;
- int zoomy = (data & 0x0001fc00) >> 10;
- int y = (data & 0x000003ff);
-
-// color |= (0x100 + (priority << 6)); /* priority bits select color bank */
- color /= 2; /* as sprites are 5bpp */
- flipy = !flipy;
- y = (-y & 0x3ff);
-
- if (!tilenum) continue;
-
- flipy = !flipy;
- zoomx += 1;
- zoomy += 1;
-
- y += y_offs;
-
- /* treat coords as signed */
- if (x>0x340) x -= 0x400;
- if (y>0x340) y -= 0x400;
-
- x -= x_offs;
-
- const int dimension = ((dblsize*2) + 2); // 2 or 4
- const int total_chunks = ((dblsize*3) + 1) << 2; // 4 or 16
- const int map_offset = tilenum << 2;
-
- {
- for (int sprite_chunk = 0; sprite_chunk < total_chunks; sprite_chunk++)
- {
- const int j = sprite_chunk / dimension; /* rows */
- const int k = sprite_chunk % dimension; /* chunks per row */
-
- int px = k;
- int py = j;
- /* pick tiles back to front for x and y flips */
- if (flipx) px = dimension-1-k;
- if (flipy) py = dimension-1-j;
-
- const u16 code = m_spritemap[map_offset + px + (py << (dblsize + 1))];
-
- if (code==0xffff)
- {
- continue;
- }
-
- int curx = x + ((k * zoomx) / dimension);
- int cury = y + ((j * zoomy) / dimension);
-
- const int zx = x + (((k + 1) * zoomx) / dimension) - curx;
- const int zy = y + (((j + 1) * zoomy) / dimension) - cury;
-
- if (sprites_flipscreen)
- {
- /* -zx/y is there to fix zoomed sprite coords in screenflip.
- drawgfxzoom does not know to draw from flip-side of sprites when
- screen is flipped; so we must correct the coords ourselves. */
-
- curx = 320 - curx - zx;
- cury = 256 - cury - zy;
- flipx = !flipx;
- flipy = !flipy;
- }
-
- sprite_ptr->gfx = 0;
- sprite_ptr->code = code;
- sprite_ptr->color = color;
- sprite_ptr->flipx = !flipx;
- sprite_ptr->flipy = flipy;
- sprite_ptr->x = curx;
- sprite_ptr->y = cury;
- sprite_ptr->zoomx = zx << 12;
- sprite_ptr->zoomy = zy << 12;
- sprite_ptr->pri = priority;
- sprite_ptr++;
- }
- }
- }
-
- /* this happens only if primsks != nullptr */
- while (sprite_ptr != m_spritelist.get())
- {
- const rectangle *clipper;
-
- sprite_ptr--;
-
- if (do_hack && sprite_ptr->pri == 1 && sprite_ptr->y < 100)
- clipper = &m_hack_cliprect;
- else
- clipper = &cliprect;
-
- m_gfxdecode->gfx(sprite_ptr->gfx)->prio_zoom_transpen(bitmap,*clipper,
- sprite_ptr->code,
- sprite_ptr->color,
- sprite_ptr->flipx,sprite_ptr->flipy,
- sprite_ptr->x,sprite_ptr->y,
- sprite_ptr->zoomx,sprite_ptr->zoomy,
- screen.priority(),primasks[sprite_ptr->pri],0);
- }
-}
-
-/**************************************************************
- SCREEN REFRESH
-**************************************************************/
-
-u32 groundfx_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- u8 layer[5];
- u8 scclayer[3];
-
- m_tc0620scc->tilemap_update();
- m_tc0480scp->tilemap_update();
-
- const u16 priority = m_tc0480scp->get_bg_priority();
-
- layer[0] = (priority & 0xf000) >> 12; /* tells us which bg layer is bottom */
- layer[1] = (priority & 0x0f00) >> 8;
- layer[2] = (priority & 0x00f0) >> 4;
- layer[3] = (priority & 0x000f) >> 0; /* tells us which is top */
- layer[4] = 4; /* text layer always over bg layers */
-
- scclayer[0] = m_tc0620scc->bottomlayer();
- scclayer[1] = scclayer[0]^1;
- scclayer[2] = 2;
-
- screen.priority().fill(0, cliprect);
- bitmap.fill(0, cliprect); /* wrong color? */
-
- m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[0], TILEMAP_DRAW_OPAQUE, 0);
- m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[1], 0, 0);
-
- /* BIG HACK!
-
- The rear view mirror is a big priority trick - the text
- layer of TC0100SCN is used as a stencil to display
- the bottom layer of TC0480SCP and a particular sprite
- priority. These never appear outside of the stencil.
-
- I'm not sure how the game turns this effect on/off
- (the 480 layer is used normally in the frontend
- of the game).
-
- I haven't implemented it properly yet, instead I'm
- doing a hacky cliprect around the rearview and drawing
- it's contents the usual way.
-
- */
- if (m_tc0620scc->ram_r(0x4090 / 2) || m_tc0620scc->ram_r(0x4092 / 2) ||
- ((m_tc0480scp->ram_r(0x20 / 2) == 0x24) && (m_tc0480scp->ram_r(0x22 / 2) == 0x0866))) /* Anything in text layer - really stupid hack */
- {
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8);
-
- //m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, 0, scclayer[2], 0, 0);
-
- if ((m_tc0480scp->ram_r(0x20 / 2) != 0x24) && (m_tc0480scp->ram_r(0x22 / 2) != 0x0866)) /* Stupid hack for start of race */
- m_tc0480scp->tilemap_draw(screen, bitmap, m_hack_cliprect, layer[0], 0, 0);
- draw_sprites(screen, bitmap, cliprect, 1, 44, -574);
- }
- else
- {
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[0], 0, 1);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 2);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 4);
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[3], 0, 8);
-
- m_tc0620scc->tilemap_draw(screen, bitmap, cliprect, scclayer[2], 0, 0);
-
- draw_sprites(screen, bitmap, cliprect, 0, 44, -574);
- }
-
- m_tc0480scp->tilemap_draw(screen, bitmap, cliprect, layer[4], 0, 0); /* TC0480SCP text layer */
- return 0;
-}
diff --git a/src/mame/taito/pitnrun.cpp b/src/mame/taito/pitnrun.cpp
index 6e0c42fb097..5cbf7a7af34 100644
--- a/src/mame/taito/pitnrun.cpp
+++ b/src/mame/taito/pitnrun.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina, Pierpaolo Prazzoli
+// copyright-holders: Tomasz Slanina, Pierpaolo Prazzoli
+
/****************************************************
Pit&Run - Taito 1984
@@ -67,19 +68,563 @@ K1000233A
*/
#include "emu.h"
-#include "pitnrun.h"
+#include "cpu/m6805/m68705.h"
#include "cpu/z80/z80.h"
-
#include "machine/74259.h"
#include "machine/gen_latch.h"
#include "machine/watchdog.h"
-
#include "sound/ay8910.h"
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+namespace {
+
+class pitnrun_state : public driver_device
+{
+public:
+ pitnrun_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_videoram(*this, "videoram%u", 1U),
+ m_spriteram(*this, "spriteram"),
+ m_spotrom(*this, "spot")
+ { }
+
+ void pitnrun(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void video_start() override;
+
+ required_device<cpu_device> m_maincpu;
+
+ void main_map(address_map &map);
+
+private:
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+
+ required_shared_ptr_array<uint8_t, 2> m_videoram;
+ required_shared_ptr<uint8_t> m_spriteram;
+
+ required_region_ptr<uint8_t> m_spotrom;
+
+ uint8_t m_nmi = 0;
+ uint8_t m_h_heed = 0;
+ uint8_t m_v_heed = 0;
+ uint8_t m_ha = 0;
+ uint16_t m_scroll = 0;
+ uint8_t m_char_bank = 0;
+ uint8_t m_color_select = 0;
+ std::unique_ptr<bitmap_ind16> m_tmp_bitmap[4];
+ tilemap_t *m_bg = nullptr;
+ tilemap_t *m_fg = nullptr;
+
+ DECLARE_WRITE_LINE_MEMBER(nmi_enable_w);
+ DECLARE_WRITE_LINE_MEMBER(hflip_w);
+ DECLARE_WRITE_LINE_MEMBER(vflip_w);
+ template <uint8_t Which> void videoram_w(offs_t offset, uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER(char_bank_select_w);
+ void scroll_w(offs_t offset, uint8_t data);
+ void scroll_y_w(uint8_t data);
+ void ha_w(uint8_t data);
+ void h_heed_w(uint8_t data);
+ void v_heed_w(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER(color_select_w);
+
+ TILE_GET_INFO_MEMBER(get_tile_info_fg);
+ TILE_GET_INFO_MEMBER(get_tile_info_bg);
+
+ INTERRUPT_GEN_MEMBER(nmi_source);
+
+ void palette(palette_device &palette) const;
+
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void spotlights();
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void sound_io_map(address_map &map);
+ void sound_prg_map(address_map &map);
+};
+
+class pitnrun_mcu_state : public pitnrun_state
+{
+public:
+ pitnrun_mcu_state(const machine_config &mconfig, device_type type, const char *tag) :
+ pitnrun_state(mconfig, type, tag),
+ m_mcu(*this, "mcu")
+ { }
+
+ void pitnrun_mcu(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ required_device<m68705p5_device> m_mcu;
+ uint8_t m_fromz80 = 0;
+ uint8_t m_toz80 = 0;
+ uint8_t m_zaccept = 0;
+ uint8_t m_zready = 0;
+ uint8_t m_porta_in = 0;
+ uint8_t m_porta_out = 0;
+ uint16_t m_address = 0;
+
+ uint8_t mcu_data_r();
+ void mcu_data_w(uint8_t data);
+ uint8_t mcu_status_r();
+ uint8_t m68705_porta_r();
+ void m68705_porta_w(uint8_t data);
+ uint8_t m68705_portb_r();
+ void m68705_portb_w(uint8_t data);
+ uint8_t m68705_portc_r();
+
+ TIMER_CALLBACK_MEMBER(mcu_real_data_r);
+ TIMER_CALLBACK_MEMBER(mcu_real_data_w);
+ TIMER_CALLBACK_MEMBER(mcu_data_real_r);
+ TIMER_CALLBACK_MEMBER(mcu_status_real_w);
+
+ void mcu_map(address_map &map);
+};
+
+
+// video
+
+/***************************************************************************
+
+ - BG layer 32x128 , 8x8 tiles 4bpp , 2 palettes (2nd is black )
+ - TXT layer 32x32 , 8x8 tiles 4bpp , 2 palettes (2nd is black)
+ - Sprites 16x16 3bpp, 8 palettes (0-3 are black)
+
+ 'Special' effects :
+
+ - spotlight - gfx(BG+Sprites) outside spotlight is using black pals
+ spotlight masks are taken from ROM pr8
+ simulated using bitmaps and custom clipping rect
+
+ - lightning - BG color change (darkening ?) - simple analog circ.
+ simulated by additional palette
+In debug build press 'w' for spotlight and 'e' for lightning
+
+***************************************************************************/
+
+
+TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info_fg)
+{
+ int const code = m_videoram[0][tile_index];
+ tileinfo.set(0,
+ code,
+ 0,
+ 0);
+}
+
+TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info_bg)
+{
+ int const code = m_videoram[1][tile_index];
+ tileinfo.set(1,
+ code + (m_char_bank << 8),
+ m_color_select,
+ 0);
+}
+
+template <uint8_t Which>
+void pitnrun_state::videoram_w(offs_t offset, uint8_t data)
+{
+ m_videoram[Which][offset] = data;
+ Which ? m_bg->mark_all_dirty() : m_fg->mark_all_dirty();
+}
+
+WRITE_LINE_MEMBER(pitnrun_state::char_bank_select_w)
+{
+ m_char_bank = state;
+ m_bg->mark_all_dirty();
+}
+
+
+void pitnrun_state::scroll_w(offs_t offset, uint8_t data)
+{
+ m_scroll = (m_scroll & (0xff << ((offset) ? 0 : 8))) |( data << ((offset) ? 8 : 0));
+ m_bg->set_scrollx(0, m_scroll);
+}
+
+void pitnrun_state::scroll_y_w(uint8_t data)
+{
+ m_bg->set_scrolly(0, data);
+}
+
+void pitnrun_state::ha_w(uint8_t data)
+{
+ m_ha = data;
+}
+
+void pitnrun_state::h_heed_w(uint8_t data)
+{
+ m_h_heed = data;
+}
+
+void pitnrun_state::v_heed_w(uint8_t data)
+{
+ m_v_heed = data;
+}
+
+WRITE_LINE_MEMBER(pitnrun_state::color_select_w)
+{
+ m_color_select = state;
+ machine().tilemap().mark_all_dirty();
+}
+
+void pitnrun_state::spotlights()
+{
+ for (int i = 0; i < 4; i++)
+ {
+ for (int y = 0; y < 128; y++)
+ {
+ for (int x = 0; x < 16; x++)
+ {
+ int datapix = m_spotrom[128 * 16 * i + x + y * 16];
+ for (int b = 0; b < 8; b++)
+ {
+ m_tmp_bitmap[i]->pix(y, x * 8 + (7 - b)) = (datapix & 1);
+ datapix >>= 1;
+ }
+ }
+ }
+ }
+}
+
+
+void pitnrun_state::palette(palette_device &palette) const
+{
+ uint8_t const *const color_prom = memregion("proms")->base();
+
+ for (int i = 0; i < 32*3; i++)
+ {
+ int bit0, bit1, bit2;
+
+ bit0 = BIT(color_prom[i], 0);
+ bit1 = BIT(color_prom[i], 1);
+ bit2 = BIT(color_prom[i], 2);
+ int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ bit0 = BIT(color_prom[i], 3);
+ bit1 = BIT(color_prom[i], 4);
+ bit2 = BIT(color_prom[i], 5);
+ int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ bit0 = 0;
+ bit1 = BIT(color_prom[i], 6);
+ bit2 = BIT(color_prom[i], 7);
+ int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ palette.set_pen_color(i, rgb_t(r, g, b));
+ }
+
+ // fake bg palette for lightning effect
+ for (int i = 2 * 16; i < 2 * 16 + 16; i++)
+ {
+ int bit0, bit1, bit2;
+
+ bit0 = BIT(color_prom[i], 0);
+ bit1 = BIT(color_prom[i], 1);
+ bit2 = BIT(color_prom[i], 2);
+ int r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ bit0 = BIT(color_prom[i], 3);
+ bit1 = BIT(color_prom[i], 4);
+ bit2 = BIT(color_prom[i], 5);
+ int g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ bit0 = 0;
+ bit1 = BIT(color_prom[i], 6);
+ bit2 = BIT(color_prom[i], 7);
+ int b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ r /= 3;
+ g /= 3;
+ b /= 3;
+
+ palette.set_pen_color(i + 16, (r > 0xff) ? 0xff : r, (g > 0xff) ? 0xff : g, (b > 0xff) ? 0xff : b);
+
+ }
+}
+
+void pitnrun_state::video_start()
+{
+ m_fg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pitnrun_state::get_tile_info_fg)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+ m_bg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pitnrun_state::get_tile_info_bg)), TILEMAP_SCAN_ROWS, 8, 8, 32 * 4, 32);
+ m_fg->set_transparent_pen(0 );
+ m_tmp_bitmap[0] = std::make_unique<bitmap_ind16>(128, 128);
+ m_tmp_bitmap[1] = std::make_unique<bitmap_ind16>(128, 128);
+ m_tmp_bitmap[2] = std::make_unique<bitmap_ind16>(128, 128);
+ m_tmp_bitmap[3] = std::make_unique<bitmap_ind16>(128, 128);
+ spotlights();
+
+ save_item(NAME(m_h_heed));
+ save_item(NAME(m_v_heed));
+ save_item(NAME(m_ha));
+ save_item(NAME(m_scroll));
+ save_item(NAME(m_char_bank));
+ save_item(NAME(m_color_select));
+}
+
+void pitnrun_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ for (int offs = 0; offs < 0x100; offs += 4)
+ {
+ int const pal = m_spriteram[offs + 2] & 0x3;
+
+ int sy = 256 - m_spriteram[offs + 0] - 16;
+ int sx = m_spriteram[offs + 3] + 1; // +1 needed to properly align Jump Kun
+ int flipy = (m_spriteram[offs + 1] & 0x80) >> 7;
+ int flipx = (m_spriteram[offs + 1] & 0x40) >> 6;
+
+ if (flip_screen_x())
+ {
+ sx = 256 - sx;
+ flipx = !flipx;
+ }
+ if (flip_screen_y())
+ {
+ sy = 240 - sy;
+ flipy = !flipy;
+ }
+
+ m_gfxdecode->gfx(2)->transpen(bitmap, cliprect,
+ (m_spriteram[offs + 1] & 0x3f) + ((m_spriteram[offs + 2] & 0x80) >> 1)+ ((m_spriteram[offs + 2] & 0x40) << 1),
+ pal,
+ flipx, flipy,
+ sx, sy, 0);
+ }
+}
+
+uint32_t pitnrun_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ int dx = 0, dy = 0;
+ rectangle myclip = cliprect;
+
+#ifdef MAME_DEBUG
+ if (machine().input().code_pressed_once(KEYCODE_Q))
+ {
+ uint8_t *ROM = memregion("maincpu")->base();
+ ROM[0x84f6] = 0; // lap 0 - normal
+ }
+
+ if (machine().input().code_pressed_once(KEYCODE_W))
+ {
+ uint8_t *ROM = memregion("maincpu")->base();
+ ROM[0x84f6] = 6; // lap 6 = spotlight
+ }
+
+ if (machine().input().code_pressed_once(KEYCODE_E))
+ {
+ uint8_t *ROM = memregion("maincpu")->base();
+ ROM[0x84f6] = 2; // lap 3 (trial 2)= lightnings
+ ROM[0x8102] = 1;
+ }
+#endif
+
+ bitmap.fill(0, cliprect);
+
+ if (!(m_ha & 4))
+ m_bg->draw(screen, bitmap, cliprect, 0, 0);
+ else
+ {
+ dx = 128 - m_h_heed + ((m_ha & 8) << 5) + 3;
+ dy = 128 - m_v_heed + ((m_ha & 0x10) << 4);
+
+ if (flip_screen_x())
+ dx = 128 - dx + 16;
+
+ if (flip_screen_y())
+ dy = 128 - dy;
+
+ myclip.set(dx, dx + 127, dy, dy + 127);
+ myclip &= cliprect;
+
+ m_bg->draw(screen, bitmap, myclip, 0, 0);
+ }
+
+ draw_sprites(bitmap, myclip);
+
+ if (m_ha & 4)
+ copybitmap_trans(bitmap, *m_tmp_bitmap[m_ha & 3], flip_screen_x(), flip_screen_y(), dx, dy, myclip, 1);
+ m_fg->draw(screen, bitmap, cliprect, 0, 0);
+ return 0;
+}
+
+
+// MCU
+
+/***************************************************************************
+
+ Based on TaitsoSJ driver
+ 68705 has access to Z80 memory space
+
+***************************************************************************/
+
+TIMER_CALLBACK_MEMBER(pitnrun_mcu_state::mcu_real_data_r)
+{
+ m_zaccept = 1;
+}
+
+uint8_t pitnrun_mcu_state::mcu_data_r()
+{
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_mcu_state::mcu_real_data_r), this));
+ return m_toz80;
+}
+
+TIMER_CALLBACK_MEMBER(pitnrun_mcu_state::mcu_real_data_w)
+{
+ m_zready = 1;
+ m_mcu->set_input_line(0, ASSERT_LINE);
+ m_fromz80 = param;
+}
+
+void pitnrun_mcu_state::mcu_data_w(uint8_t data)
+{
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_mcu_state::mcu_real_data_w), this), data);
+ machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(5));
+}
+
+uint8_t pitnrun_mcu_state::mcu_status_r()
+{
+ /* MCU synchronization
+ bit 0 = the 68705 has read data from the Z80
+ bit 1 = the 68705 has written data for the Z80 */
+ return ~((m_zready << 1) | (m_zaccept << 0));
+}
+
+
+uint8_t pitnrun_mcu_state::m68705_porta_r()
+{
+ return m_porta_in;
+}
+
+void pitnrun_mcu_state::m68705_porta_w(uint8_t data)
+{
+ m_porta_out = data;
+}
+
+
+
+/*
+ * Port B connections:
+ *
+ * all bits are logical 1 when read (+5V pullup)
+ *
+ * 0 W !68INTRQ
+ * 1 W !68LRD (enables latch which holds command from the Z80)
+ * 2 W !68LWR (loads the latch which holds data for the Z80, and sets a
+ * status bit so the Z80 knows there's data waiting)
+ * 3 W to Z80 !BUSRQ (aka !WAIT) pin
+ * 4 W !68WRITE (triggers write to main Z80 memory area )
+ * 5 W !68READ (triggers read from main Z80 memory area )
+ * 6 W !LAL (loads the latch which holds the low 8 bits of the address of
+ * the main Z80 memory location to access)
+ * 7 W !UAL (loads the latch which holds the high 8 bits of the address of
+ * the main Z80 memory location to access)
+ */
+
+uint8_t pitnrun_mcu_state::m68705_portb_r()
+{
+ return 0xff;
+}
+
+
+TIMER_CALLBACK_MEMBER(pitnrun_mcu_state::mcu_data_real_r)
+{
+ m_zready = 0;
+}
+
+TIMER_CALLBACK_MEMBER(pitnrun_mcu_state::mcu_status_real_w)
+{
+ m_toz80 = param;
+ m_zaccept = 0;
+}
+
+void pitnrun_mcu_state::m68705_portb_w(uint8_t data)
+{
+ address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
+ if (~data & 0x02)
+ {
+ // 68705 is going to read data from the Z80
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_mcu_state::mcu_data_real_r), this));
+ m_mcu->set_input_line(0, CLEAR_LINE);
+ m_porta_in = m_fromz80;
+ }
+ if (~data & 0x04)
+ {
+ // 68705 is writing data for the Z80
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_mcu_state::mcu_status_real_w), this), m_porta_out);
+ }
+ if (~data & 0x10)
+ {
+ cpu0space.write_byte(m_address, m_porta_out);
+ }
+ if (~data & 0x20)
+ {
+ m_porta_in = cpu0space.read_byte(m_address);
+ }
+ if (~data & 0x40)
+ {
+ m_address = (m_address & 0xff00) | m_porta_out;
+ }
+ if (~data & 0x80)
+ {
+ m_address = (m_address & 0x00ff) | (m_porta_out << 8);
+ }
+}
+
+/*
+ * Port C connections:
+ *
+ * 0 R ZREADY (1 when the Z80 has written a command in the latch)
+ * 1 R ZACCEPT (1 when the Z80 has read data from the latch)
+ * 2 R from Z80 !BUSAK pin
+ * 3 R 68INTAK (goes 0 when the interrupt request done with 68INTRQ
+ * passes through)
+ */
+
+uint8_t pitnrun_mcu_state::m68705_portc_r()
+{
+ return (m_zready << 0) | (m_zaccept << 1);
+}
+
+
+// machine
+
+void pitnrun_state::machine_start()
+{
+ save_item(NAME(m_nmi));
+}
+
+void pitnrun_mcu_state::machine_start()
+{
+ pitnrun_state::machine_start();
+
+ save_item(NAME(m_fromz80));
+ save_item(NAME(m_toz80));
+ save_item(NAME(m_zaccept));
+ save_item(NAME(m_zready));
+ save_item(NAME(m_porta_in));
+ save_item(NAME(m_porta_out));
+ save_item(NAME(m_address));
+}
+
+void pitnrun_mcu_state::machine_reset()
+{
+ m_zaccept = 1;
+ m_zready = 0;
+ m_mcu->set_input_line(0, CLEAR_LINE);
+}
INTERRUPT_GEN_MEMBER(pitnrun_state::nmi_source)
{
@@ -104,44 +649,41 @@ WRITE_LINE_MEMBER(pitnrun_state::vflip_w)
flip_screen_y_set(state);
}
-void pitnrun_state::pitnrun_map(address_map &map)
+void pitnrun_state::main_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
map(0x8000, 0x87ff).ram();
- map(0x8800, 0x8fff).ram().w(FUNC(pitnrun_state::videoram_w)).share("videoram");
- map(0x9000, 0x9fff).ram().w(FUNC(pitnrun_state::videoram2_w)).share("videoram2");
- map(0xa000, 0xa0ff).ram().share("spriteram");
+ map(0x8800, 0x8fff).ram().w(FUNC(pitnrun_state::videoram_w<0>)).share(m_videoram[0]);
+ map(0x9000, 0x9fff).ram().w(FUNC(pitnrun_state::videoram_w<1>)).share(m_videoram[1]);
+ map(0xa000, 0xa0ff).ram().share(m_spriteram);
map(0xa800, 0xa800).portr("SYSTEM");
- map(0xa800, 0xa807).w("noiselatch", FUNC(ls259_device::write_d0)); /* Analog Sound */
+ map(0xa800, 0xa807).w("noiselatch", FUNC(ls259_device::write_d0)); // analog sound
map(0xb000, 0xb000).portr("DSW");
map(0xb000, 0xb007).w("mainlatch", FUNC(ls259_device::write_d0));
map(0xb800, 0xb800).portr("INPUTS").w("soundlatch", FUNC(generic_latch_8_device::write));
map(0xc800, 0xc801).w(FUNC(pitnrun_state::scroll_w));
map(0xc802, 0xc802).w(FUNC(pitnrun_state::scroll_y_w));
- //map(0xc804, 0xc804).w(FUNC(pitnrun_state::mcu_data_w));
map(0xc805, 0xc805).w(FUNC(pitnrun_state::h_heed_w));
map(0xc806, 0xc806).w(FUNC(pitnrun_state::v_heed_w));
map(0xc807, 0xc807).w(FUNC(pitnrun_state::ha_w));
- //map(0xd000, 0xd000).r(FUNC(pitnrun_state::mcu_data_r));
- //map(0xd800, 0xd800).r(FUNC(pitnrun_state::mcu_status_r));
map(0xf000, 0xf000).r("watchdog", FUNC(watchdog_timer_device::reset_r));
}
-void pitnrun_state::pitnrun_map_mcu(address_map &map)
+void pitnrun_mcu_state::mcu_map(address_map &map)
{
- pitnrun_map(map);
- map(0xc804, 0xc804).w(FUNC(pitnrun_state::mcu_data_w));
- map(0xd000, 0xd000).r(FUNC(pitnrun_state::mcu_data_r));
- map(0xd800, 0xd800).r(FUNC(pitnrun_state::mcu_status_r));
+ main_map(map);
+ map(0xc804, 0xc804).w(FUNC(pitnrun_mcu_state::mcu_data_w));
+ map(0xd000, 0xd000).r(FUNC(pitnrun_mcu_state::mcu_data_r));
+ map(0xd800, 0xd800).r(FUNC(pitnrun_mcu_state::mcu_status_r));
}
-void pitnrun_state::pitnrun_sound_map(address_map &map)
+void pitnrun_state::sound_prg_map(address_map &map)
{
- map(0x0000, 0x2fff).rom();
+ map(0x0000, 0x1fff).rom();
map(0x3800, 0x3bff).ram();
}
-void pitnrun_state::pitnrun_sound_io_map(address_map &map)
+void pitnrun_state::sound_io_map(address_map &map)
{
map.global_mask(0xff);
map(0x00, 0x00).w("soundlatch", FUNC(generic_latch_8_device::clear_w));
@@ -272,15 +814,15 @@ static const gfx_layout charlayout =
};
static GFXDECODE_START( gfx_pitnrun )
- GFXDECODE_ENTRY( "gfx3", 0, charlayout, 64, 2 )
- GFXDECODE_ENTRY( "gfx2", 0, charlayout, 32, 2 )
- GFXDECODE_ENTRY( "gfx1", 0, spritelayout, 0, 4 )
+ GFXDECODE_ENTRY( "fgtiles", 0, charlayout, 64, 2 )
+ GFXDECODE_ENTRY( "bgtiles", 0, charlayout, 32, 2 )
+ GFXDECODE_ENTRY( "sprites", 0, spritelayout, 0, 4 )
GFXDECODE_END
void pitnrun_state::pitnrun(machine_config &config)
{
- Z80(config, m_maincpu, XTAL(18'432'000)/6); /* verified on pcb */
- m_maincpu->set_addrmap(AS_PROGRAM, &pitnrun_state::pitnrun_map);
+ Z80(config, m_maincpu, XTAL(18'432'000) / 6); // verified on PCB
+ m_maincpu->set_addrmap(AS_PROGRAM, &pitnrun_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(pitnrun_state::nmi_source));
ls259_device &mainlatch(LS259(config, "mainlatch")); // 7B (mislabeled LS156 on schematic)
@@ -291,16 +833,16 @@ void pitnrun_state::pitnrun(machine_config &config)
mainlatch.q_out_cb<6>().set(FUNC(pitnrun_state::hflip_w)); // HFLIP
mainlatch.q_out_cb<7>().set(FUNC(pitnrun_state::vflip_w)); // VFLIP
- z80_device &audiocpu(Z80(config, "audiocpu", XTAL(5'000'000)/2)); /* verified on pcb */
- audiocpu.set_addrmap(AS_PROGRAM, &pitnrun_state::pitnrun_sound_map);
- audiocpu.set_addrmap(AS_IO, &pitnrun_state::pitnrun_sound_io_map);
+ z80_device &audiocpu(Z80(config, "audiocpu", XTAL(5'000'000) / 2)); // verified on PCB
+ audiocpu.set_addrmap(AS_PROGRAM, &pitnrun_state::sound_prg_map);
+ audiocpu.set_addrmap(AS_IO, &pitnrun_state::sound_io_map);
audiocpu.set_vblank_int("screen", FUNC(pitnrun_state::irq0_line_hold));
WATCHDOG_TIMER(config, "watchdog");
config.set_maximum_quantum(attotime::from_hz(6000));
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
@@ -310,19 +852,19 @@ void pitnrun_state::pitnrun(machine_config &config)
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_pitnrun);
- PALETTE(config, m_palette, FUNC(pitnrun_state::pitnrun_palette), 32 * 3);
+ PALETTE(config, m_palette, FUNC(pitnrun_state::palette), 32 * 3);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
GENERIC_LATCH_8(config, "soundlatch");
- ay8910_device &ay1(AY8910(config, "ay1", XTAL(18'432'000)/12)); /* verified on pcb */
+ ay8910_device &ay1(AY8910(config, "ay1", XTAL(18'432'000) / 12)); // verified on PCB
ay1.port_a_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
ay1.port_b_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
ay1.add_route(ALL_OUTPUTS, "mono", 0.50);
- ay8910_device &ay2(AY8910(config, "ay2", XTAL(18'432'000)/12)); /* verified on pcb */
+ ay8910_device &ay2(AY8910(config, "ay2", XTAL(18'432'000) / 12)); // verified on PCB
ay2.port_a_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
ay2.port_b_read_callback().set("soundlatch", FUNC(generic_latch_8_device::read));
ay2.add_route(ALL_OUTPUTS, "mono", 0.50);
@@ -330,43 +872,43 @@ void pitnrun_state::pitnrun(machine_config &config)
LS259(config, "noiselatch"); // 1J
}
-void pitnrun_state::pitnrun_mcu(machine_config &config)
+void pitnrun_mcu_state::pitnrun_mcu(machine_config &config)
{
pitnrun(config);
- m_maincpu->set_addrmap(AS_PROGRAM, &pitnrun_state::pitnrun_map_mcu);
+ m_maincpu->set_addrmap(AS_PROGRAM, &pitnrun_mcu_state::mcu_map);
- M68705P5(config, m_mcu, XTAL(18'432'000)/6); /* verified on pcb */
- m_mcu->porta_r().set(FUNC(pitnrun_state::m68705_porta_r));
- m_mcu->portb_r().set(FUNC(pitnrun_state::m68705_portb_r));
- m_mcu->portc_r().set(FUNC(pitnrun_state::m68705_portc_r));
- m_mcu->porta_w().set(FUNC(pitnrun_state::m68705_porta_w));
- m_mcu->portb_w().set(FUNC(pitnrun_state::m68705_portb_w));
+ M68705P5(config, m_mcu, XTAL(18'432'000) / 6); // verified on PCB
+ m_mcu->porta_r().set(FUNC(pitnrun_mcu_state::m68705_porta_r));
+ m_mcu->portb_r().set(FUNC(pitnrun_mcu_state::m68705_portb_r));
+ m_mcu->portc_r().set(FUNC(pitnrun_mcu_state::m68705_portc_r));
+ m_mcu->porta_w().set(FUNC(pitnrun_mcu_state::m68705_porta_w));
+ m_mcu->portb_w().set(FUNC(pitnrun_mcu_state::m68705_portb_w));
}
ROM_START( pitnrun )
- ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_REGION( 0x8000, "maincpu", 0 )
ROM_LOAD( "pr12", 0x0000, 0x2000, CRC(587a7b85) SHA1(f200ff9b706e13760a23e0187c6bffe496af0087) )
ROM_LOAD( "pr11", 0x2000, 0x2000, CRC(270cd6dd) SHA1(ad42562e18aa30319fc55c201e5507e8734a5b4d) )
ROM_LOAD( "pr10", 0x4000, 0x2000, CRC(65d92d89) SHA1(4030ccdb4d84e69c256e95431ee5a18cffeae5c0) )
ROM_LOAD( "pr9", 0x6000, 0x2000, CRC(3155286d) SHA1(45af8cb81d70f2e30b52bbc7abd9f8d15231735f) )
- ROM_REGION( 0x10000, "audiocpu", 0 )
+ ROM_REGION( 0x2000, "audiocpu", 0 )
ROM_LOAD( "pr13", 0x0000, 0x1000, CRC(fc8fd05c) SHA1(f40cc9c6fff6bda8411f4d638a0f5c5915aa3746) )
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "a11_17.3a", 0x0000, 0x0800, CRC(e7d5d6e1) SHA1(c1131d6fcc36926e287be26090a3c89f22feaa35) )
- ROM_REGION( 0x6000, "gfx1", 0 )
+ ROM_REGION( 0x6000, "sprites", 0 )
ROM_LOAD( "pr1", 0x0000, 0x2000, CRC(c3b3131e) SHA1(ed0463e7eef452d7fbdcb031f9477825e9780943) )
ROM_LOAD( "pr2", 0x2000, 0x2000, CRC(2fa1682a) SHA1(9daefb525fd69f0d9a45ff27e89865545e177a5a) )
ROM_LOAD( "pr3", 0x4000, 0x2000, CRC(e678fe39) SHA1(134e36fd30bf3cf5884732f3455ca4d9dab6b665) )
- ROM_REGION( 0x4000, "gfx2", 0 )
+ ROM_REGION( 0x4000, "bgtiles", 0 )
ROM_LOAD( "pr4", 0x0000, 0x2000, CRC(fbae3504) SHA1(ce799dfd653462c0814e7530f3f8a686ab0ad7f4) )
ROM_LOAD( "pr5", 0x2000, 0x2000, CRC(c9177180) SHA1(98c8f8f586b78b88dba254bd662642ee27f9b131) )
- ROM_REGION( 0x2000, "gfx3", 0 )
+ ROM_REGION( 0x2000, "fgtiles", 0 )
ROM_LOAD( "pr6", 0x0000, 0x1000, CRC(c53cb897) SHA1(81a73e6031b52fa45ec507ff4264b14474ef42a2) )
ROM_LOAD( "pr7", 0x1000, 0x1000, CRC(7cdf9a55) SHA1(404dface7e09186e486945981e39063929599efc) )
@@ -380,28 +922,28 @@ ROM_START( pitnrun )
ROM_END
ROM_START( pitnruna )
- ROM_REGION( 0x010000, "maincpu", 0 )
+ ROM_REGION( 0x8000, "maincpu", 0 )
ROM_LOAD( "pr_12-1.5d", 0x0000, 0x2000, CRC(2539aec3) SHA1(5ee87cf2379a6b6218f0c1f79374edafe5413616) )
ROM_LOAD( "pr_11-1.5c", 0x2000, 0x2000, CRC(818a49f8) SHA1(0a4c77055529967595984277f11dc1cd1eec4dae) )
ROM_LOAD( "pr_10-1.5b", 0x4000, 0x2000, CRC(69b3a864) SHA1(3d29e1f71f1a94650839696c3070d5739360bee0) )
ROM_LOAD( "pr_9-1.5a", 0x6000, 0x2000, CRC(ba0c4093) SHA1(0273e4bd09b9eebff490fdac27e6ae9b54bb3cd9) )
- ROM_REGION( 0x10000, "audiocpu", 0 )
+ ROM_REGION( 0x2000, "audiocpu", 0 )
ROM_LOAD( "pr-13", 0x0000, 0x1000, CRC(32a18d3b) SHA1(fcff1c13183b64ede0865dd04eee5182029bebdf) )
ROM_REGION( 0x0800, "mcu", 0 )
ROM_LOAD( "a11_17.3a", 0x0000, 0x0800, CRC(e7d5d6e1) SHA1(c1131d6fcc36926e287be26090a3c89f22feaa35) )
- ROM_REGION( 0x06000, "gfx1", 0 )
+ ROM_REGION( 0x06000, "sprites", 0 )
ROM_LOAD( "pr-1.1k", 0x0000, 0x2000, CRC(c3b3131e) SHA1(ed0463e7eef452d7fbdcb031f9477825e9780943) )
ROM_LOAD( "pr-2.1m", 0x2000, 0x2000, CRC(2fa1682a) SHA1(9daefb525fd69f0d9a45ff27e89865545e177a5a) )
ROM_LOAD( "pr-3.1n", 0x4000, 0x2000, CRC(e678fe39) SHA1(134e36fd30bf3cf5884732f3455ca4d9dab6b665) )
- ROM_REGION( 0x4000, "gfx2", 0 )
+ ROM_REGION( 0x4000, "bgtiles", 0 )
ROM_LOAD( "pr-4.6d", 0x0000, 0x2000, CRC(fbae3504) SHA1(ce799dfd653462c0814e7530f3f8a686ab0ad7f4) )
ROM_LOAD( "pr-5.6f", 0x2000, 0x2000, CRC(c9177180) SHA1(98c8f8f586b78b88dba254bd662642ee27f9b131) )
- ROM_REGION( 0x2000, "gfx3", 0 )
+ ROM_REGION( 0x2000, "fgtiles", 0 )
ROM_LOAD( "pr-6.3m", 0x0000, 0x1000, CRC(c53cb897) SHA1(81a73e6031b52fa45ec507ff4264b14474ef42a2) )
ROM_LOAD( "pr-7.3p", 0x1000, 0x1000, CRC(7cdf9a55) SHA1(404dface7e09186e486945981e39063929599efc) )
@@ -415,29 +957,29 @@ ROM_START( pitnruna )
ROM_END
ROM_START( jumpkun )
- ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_REGION( 0x8000, "maincpu", 0 )
ROM_LOAD( "pr1.5d.2764", 0x00000, 0x02000, CRC(b0eabe9f) SHA1(e662f3946efe72b0bbf6c6934201163f765bb7aa) )
ROM_LOAD( "pr2.5c.2764", 0x02000, 0x02000, CRC(d9240413) SHA1(f4d0491e125f1fe435b200b38fa125889784af0a) )
ROM_LOAD( "pr3.5b.2764", 0x04000, 0x02000, CRC(105e3fec) SHA1(06ea902e6647fc37a603146324e3d0a067e1f649) )
ROM_LOAD( "pr4.5a.2764", 0x06000, 0x02000, CRC(3a17ca88) SHA1(00516798d546098831e75547664c8fdaa2bbf050) )
- ROM_REGION( 0x10000, "audiocpu", 0 )
+ ROM_REGION( 0x2000, "audiocpu", 0 )
ROM_LOAD( "snd1.2732", 0x00000, 0x01000, CRC(1290f316) SHA1(13e393860c1f7d1f97343b9f936c60adb7641efc) )
ROM_LOAD( "snd2.2732", 0x01000, 0x01000, CRC(ec5e4489) SHA1(fc94fe798a1925e8e3dd15161648e9a960969fc4) )
ROM_REGION( 0x0800, "mcu", ROMREGION_ERASE00 )
// not populated
- ROM_REGION( 0x6000, "gfx1", 0 )
+ ROM_REGION( 0x6000, "sprites", 0 )
ROM_LOAD( "obj1.1k.2764", 0x00000, 0x02000, CRC(8929abfd) SHA1(978994af5816c20a8cd520263d04d1cc1e4df576) )
ROM_LOAD( "obj2.1m.2764", 0x02000, 0x02000, CRC(c7bf5819) SHA1(15d8e1dd1c0911785237e9063a75a42a2dc1bd50) )
ROM_LOAD( "obj3.1n.2764", 0x04000, 0x02000, CRC(5eeec986) SHA1(e58a0b98b90a1dd3971ed305100337aa2e5ec450) )
- ROM_REGION( 0x4000, "gfx2", 0 )
+ ROM_REGION( 0x4000, "bgtiles", 0 )
ROM_LOAD( "chr1.6d.2764", 0x00000, 0x02000, CRC(3c93d4ee) SHA1(003121c49bccbb95efb137e6d92d26eea1957fbd) )
ROM_LOAD( "chr2.6f.2764", 0x02000, 0x02000, CRC(154fad33) SHA1(7eddc794bd547053f185bb79a8220907bab13d85) )
- ROM_REGION( 0x2000, "gfx3", 0 )
+ ROM_REGION( 0x2000, "fgtiles", 0 )
ROM_LOAD( "bsc2.3m.2764", 0x00000, 0x01000, CRC(25445f17) SHA1(b1ada95d8f02623bb4a4562d2d278a882414e57e) )
ROM_LOAD( "bsc1.3p.2764", 0x01000, 0x01000, CRC(39ca2c37) SHA1(b8c71f443a0faf54df03ac5aca46ddd34c42d3a0) )
@@ -450,6 +992,9 @@ ROM_START( jumpkun )
ROM_LOAD( "8j.82s123.bin", 0x0040, 0x0020, CRC(223a6990) SHA1(06e16de037c2c7ad5733390859fa7ec1ab1e2f69) )
ROM_END
-GAME( 1984, pitnrun, 0, pitnrun_mcu, pitnrun, pitnrun_state, empty_init, ROT90, "Taito Corporation", "Pit & Run - F-1 Race (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
-GAME( 1984, pitnruna, pitnrun, pitnrun_mcu, pitnrun, pitnrun_state, empty_init, ROT90, "Taito Corporation", "Pit & Run - F-1 Race (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
-GAME( 1984, jumpkun, 0, pitnrun, jumpkun, pitnrun_state, empty_init, ROT90, "Kaneko", "Jump Kun (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // no copyright message
+} // anonymous namespace
+
+
+GAME( 1984, pitnrun, 0, pitnrun_mcu, pitnrun, pitnrun_mcu_state, empty_init, ROT90, "Taito Corporation", "Pit & Run - F-1 Race (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
+GAME( 1984, pitnruna, pitnrun, pitnrun_mcu, pitnrun, pitnrun_mcu_state, empty_init, ROT90, "Taito Corporation", "Pit & Run - F-1 Race (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
+GAME( 1984, jumpkun, 0, pitnrun, jumpkun, pitnrun_state, empty_init, ROT90, "Kaneko", "Jump Kun (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // no copyright message
diff --git a/src/mame/taito/pitnrun.h b/src/mame/taito/pitnrun.h
deleted file mode 100644
index 65ec773c641..00000000000
--- a/src/mame/taito/pitnrun.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina, Pierpaolo Prazzoli
-#ifndef MAME_INCLUDES_PITNRUN_H
-#define MAME_INCLUDES_PITNRUN_H
-
-#pragma once
-
-#include "cpu/m6805/m68705.h"
-#include "emupal.h"
-#include "tilemap.h"
-
-class pitnrun_state : public driver_device
-{
-public:
- pitnrun_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_mcu(*this, "mcu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_videoram(*this, "videoram"),
- m_videoram2(*this, "videoram2"),
- m_spriteram(*this, "spriteram")
- { }
-
- void pitnrun_mcu(machine_config &config);
- void pitnrun(machine_config &config);
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
-
-private:
- required_device<cpu_device> m_maincpu;
- optional_device<m68705p5_device> m_mcu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
-
- required_shared_ptr<uint8_t> m_videoram;
- required_shared_ptr<uint8_t> m_videoram2;
- required_shared_ptr<uint8_t> m_spriteram;
-
- int m_nmi = 0;
- uint8_t m_fromz80 = 0;
- uint8_t m_toz80 = 0;
- int m_zaccept = 0;
- int m_zready = 0;
- uint8_t m_porta_in = 0;
- uint8_t m_porta_out = 0;
- int m_address = 0;
- int m_h_heed = 0;
- int m_v_heed = 0;
- int m_ha = 0;
- int m_scroll = 0;
- int m_char_bank = 0;
- int m_color_select = 0;
- std::unique_ptr<bitmap_ind16> m_tmp_bitmap[4];
- tilemap_t *m_bg = nullptr;
- tilemap_t *m_fg = nullptr;
-
- DECLARE_WRITE_LINE_MEMBER(nmi_enable_w);
- DECLARE_WRITE_LINE_MEMBER(hflip_w);
- DECLARE_WRITE_LINE_MEMBER(vflip_w);
- uint8_t mcu_data_r();
- void mcu_data_w(uint8_t data);
- uint8_t mcu_status_r();
- uint8_t m68705_porta_r();
- void m68705_porta_w(uint8_t data);
- uint8_t m68705_portb_r();
- void m68705_portb_w(uint8_t data);
- uint8_t m68705_portc_r();
- void videoram_w(offs_t offset, uint8_t data);
- void videoram2_w(offs_t offset, uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(char_bank_select_w);
- void scroll_w(offs_t offset, uint8_t data);
- void scroll_y_w(uint8_t data);
- void ha_w(uint8_t data);
- void h_heed_w(uint8_t data);
- void v_heed_w(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(color_select_w);
-
- TILE_GET_INFO_MEMBER(get_tile_info1);
- TILE_GET_INFO_MEMBER(get_tile_info2);
-
- INTERRUPT_GEN_MEMBER(nmi_source);
- TIMER_CALLBACK_MEMBER(mcu_real_data_r);
- TIMER_CALLBACK_MEMBER(mcu_real_data_w);
- TIMER_CALLBACK_MEMBER(mcu_data_real_r);
- TIMER_CALLBACK_MEMBER(mcu_status_real_w);
-
- void pitnrun_palette(palette_device &palette) const;
-
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void spotlights();
- void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect );
- void pitnrun_map(address_map &map);
- void pitnrun_map_mcu(address_map &map);
- void pitnrun_sound_io_map(address_map &map);
- void pitnrun_sound_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_PITNRUN_H
diff --git a/src/mame/taito/pitnrun_m.cpp b/src/mame/taito/pitnrun_m.cpp
deleted file mode 100644
index a01934a59da..00000000000
--- a/src/mame/taito/pitnrun_m.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina, Pierpaolo Prazzoli
-/***************************************************************************
-
- Pit&Run
-
- Based on TaitsoSJ driver
- 68705 has access to Z80 memory space
-
-***************************************************************************/
-
-#include "emu.h"
-#include "cpu/m6805/m6805.h"
-#include "pitnrun.h"
-
-
-void pitnrun_state::machine_start()
-{
- save_item(NAME(m_nmi));
- save_item(NAME(m_fromz80));
- save_item(NAME(m_toz80));
- save_item(NAME(m_zaccept));
- save_item(NAME(m_zready));
- save_item(NAME(m_porta_in));
- save_item(NAME(m_porta_out));
- save_item(NAME(m_address));
-}
-
-void pitnrun_state::machine_reset()
-{
- m_zaccept = 1;
- m_zready = 0;
- if (m_mcu) m_mcu->set_input_line(0, CLEAR_LINE);
-}
-
-TIMER_CALLBACK_MEMBER(pitnrun_state::mcu_real_data_r)
-{
- m_zaccept = 1;
-}
-
-uint8_t pitnrun_state::mcu_data_r()
-{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_state::mcu_real_data_r),this));
- return m_toz80;
-}
-
-TIMER_CALLBACK_MEMBER(pitnrun_state::mcu_real_data_w)
-{
- m_zready = 1;
- m_mcu->set_input_line(0, ASSERT_LINE);
- m_fromz80 = param;
-}
-
-void pitnrun_state::mcu_data_w(uint8_t data)
-{
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_state::mcu_real_data_w),this), data);
- machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(5));
-}
-
-uint8_t pitnrun_state::mcu_status_r()
-{
- /* mcu synchronization */
- /* bit 0 = the 68705 has read data from the Z80 */
- /* bit 1 = the 68705 has written data for the Z80 */
- return ~((m_zready << 1) | (m_zaccept << 0));
-}
-
-
-uint8_t pitnrun_state::m68705_porta_r()
-{
- return m_porta_in;
-}
-
-void pitnrun_state::m68705_porta_w(uint8_t data)
-{
- m_porta_out = data;
-}
-
-
-
-/*
- * Port B connections:
- *
- * all bits are logical 1 when read (+5V pullup)
- *
- * 0 W !68INTRQ
- * 1 W !68LRD (enables latch which holds command from the Z80)
- * 2 W !68LWR (loads the latch which holds data for the Z80, and sets a
- * status bit so the Z80 knows there's data waiting)
- * 3 W to Z80 !BUSRQ (aka !WAIT) pin
- * 4 W !68WRITE (triggers write to main Z80 memory area )
- * 5 W !68READ (triggers read from main Z80 memory area )
- * 6 W !LAL (loads the latch which holds the low 8 bits of the address of
- * the main Z80 memory location to access)
- * 7 W !UAL (loads the latch which holds the high 8 bits of the address of
- * the main Z80 memory location to access)
- */
-
-uint8_t pitnrun_state::m68705_portb_r()
-{
- return 0xff;
-}
-
-
-TIMER_CALLBACK_MEMBER(pitnrun_state::mcu_data_real_r)
-{
- m_zready = 0;
-}
-
-TIMER_CALLBACK_MEMBER(pitnrun_state::mcu_status_real_w)
-{
- m_toz80 = param;
- m_zaccept = 0;
-}
-
-void pitnrun_state::m68705_portb_w(uint8_t data)
-{
- address_space &cpu0space = m_maincpu->space(AS_PROGRAM);
- if (~data & 0x02)
- {
- /* 68705 is going to read data from the Z80 */
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_state::mcu_data_real_r),this));
- m_mcu->set_input_line(0,CLEAR_LINE);
- m_porta_in = m_fromz80;
- }
- if (~data & 0x04)
- {
- /* 68705 is writing data for the Z80 */
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(pitnrun_state::mcu_status_real_w),this), m_porta_out);
- }
- if (~data & 0x10)
- {
- cpu0space.write_byte(m_address, m_porta_out);
- }
- if (~data & 0x20)
- {
- m_porta_in = cpu0space.read_byte(m_address);
- }
- if (~data & 0x40)
- {
- m_address = (m_address & 0xff00) | m_porta_out;
- }
- if (~data & 0x80)
- {
- m_address = (m_address & 0x00ff) | (m_porta_out << 8);
- }
-}
-
-/*
- * Port C connections:
- *
- * 0 R ZREADY (1 when the Z80 has written a command in the latch)
- * 1 R ZACCEPT (1 when the Z80 has read data from the latch)
- * 2 R from Z80 !BUSAK pin
- * 3 R 68INTAK (goes 0 when the interrupt request done with 68INTRQ
- * passes through)
- */
-
-uint8_t pitnrun_state::m68705_portc_r()
-{
- return (m_zready << 0) | (m_zaccept << 1);
-}
diff --git a/src/mame/taito/pitnrun_v.cpp b/src/mame/taito/pitnrun_v.cpp
deleted file mode 100644
index 4df85ac9db4..00000000000
--- a/src/mame/taito/pitnrun_v.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina, Pierpaolo Prazzoli
-/***************************************************************************
-
- - BG layer 32x128 , 8x8 tiles 4bpp , 2 palettes (2nd is black )
- - TXT layer 32x32 , 8x8 tiles 4bpp , 2 palettes (2nd is black)
- - Sprites 16x16 3bpp, 8 palettes (0-3 are black)
-
- 'Special' effects :
-
- - spotlight - gfx(BG+Sprites) outside spotlight is using black pals
- spotlight masks are taken from ROM pr8
- simulated using bitmaps and custom clipping rect
-
- - lightning - BG color change (darkening ?) - simple analog circ.
- simulated by additional palette
-
-In debug build press 'w' for spotlight and 'e' for lightning
-
-***************************************************************************/
-#include "emu.h"
-#include "pitnrun.h"
-
-
-
-TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info1)
-{
- int code = m_videoram[tile_index];
- tileinfo.set(0,
- code,
- 0,
- 0);
-}
-
-TILE_GET_INFO_MEMBER(pitnrun_state::get_tile_info2)
-{
- int code = m_videoram2[tile_index];
- tileinfo.set(1,
- code + (m_char_bank<<8),
- m_color_select&1,
- 0);
-}
-
-void pitnrun_state::videoram_w(offs_t offset, uint8_t data)
-{
- m_videoram[offset] = data;
- m_fg ->mark_all_dirty();
-}
-
-void pitnrun_state::videoram2_w(offs_t offset, uint8_t data)
-{
- m_videoram2[offset] = data;
- m_bg ->mark_all_dirty();
-}
-
-WRITE_LINE_MEMBER(pitnrun_state::char_bank_select_w)
-{
- m_char_bank = state;
- m_bg->mark_all_dirty();
-}
-
-
-void pitnrun_state::scroll_w(offs_t offset, uint8_t data)
-{
- m_scroll = (m_scroll & (0xff<<((offset)?0:8))) |( data<<((offset)?8:0));
- m_bg->set_scrollx(0, m_scroll);
-}
-
-void pitnrun_state::scroll_y_w(uint8_t data)
-{
- m_bg->set_scrolly(0, data);
-}
-
-void pitnrun_state::ha_w(uint8_t data)
-{
- m_ha=data;
-}
-
-void pitnrun_state::h_heed_w(uint8_t data)
-{
- m_h_heed=data;
-}
-
-void pitnrun_state::v_heed_w(uint8_t data)
-{
- m_v_heed=data;
-}
-
-WRITE_LINE_MEMBER(pitnrun_state::color_select_w)
-{
- m_color_select = state;
- machine().tilemap().mark_all_dirty();
-}
-
-void pitnrun_state::spotlights()
-{
- uint8_t const *const ROM = memregion("spot")->base();
- for (int i=0; i<4; i++)
- {
- for (int y=0; y<128; y++)
- {
- for (int x=0; x<16; x++)
- {
- int datapix = ROM[128*16*i + x + y*16];
- for(int b=0; b<8; b++)
- {
- m_tmp_bitmap[i]->pix(y, x*8 + (7 - b)) = (datapix & 1);
- datapix>>=1;
- }
- }
- }
- }
-}
-
-
-void pitnrun_state::pitnrun_palette(palette_device &palette) const
-{
- uint8_t const *const color_prom = memregion("proms")->base();
-
- for (int i = 0; i < 32*3; i++)
- {
- int bit0, bit1, bit2;
-
- bit0 = BIT(color_prom[i], 0);
- bit1 = BIT(color_prom[i], 1);
- bit2 = BIT(color_prom[i], 2);
- int const r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- bit0 = BIT(color_prom[i], 3);
- bit1 = BIT(color_prom[i], 4);
- bit2 = BIT(color_prom[i], 5);
- int const g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- bit0 = 0;
- bit1 = BIT(color_prom[i], 6);
- bit2 = BIT(color_prom[i], 7);
- int const b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- palette.set_pen_color(i, rgb_t(r, g, b));
- }
-
- // fake bg palette for lightning effect
- for (int i = 2*16; i < 2*16 + 16; i++)
- {
- int bit0, bit1, bit2;
-
- bit0 = BIT(color_prom[i], 0);
- bit1 = BIT(color_prom[i], 1);
- bit2 = BIT(color_prom[i], 2);
- int r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- bit0 = BIT(color_prom[i], 3);
- bit1 = BIT(color_prom[i], 4);
- bit2 = BIT(color_prom[i], 5);
- int g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- bit0 = 0;
- bit1 = BIT(color_prom[i], 6);
- bit2 = BIT(color_prom[i], 7);
- int b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- r /= 3;
- g /= 3;
- b /= 3;
-
- palette.set_pen_color(i + 16, (r > 0xff) ? 0xff : r, (g > 0xff) ? 0xff : g, (b > 0xff) ? 0xff : b);
-
- }
-}
-
-void pitnrun_state::video_start()
-{
- m_fg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pitnrun_state::get_tile_info1)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
- m_bg = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(pitnrun_state::get_tile_info2)), TILEMAP_SCAN_ROWS, 8, 8, 32*4, 32);
- m_fg->set_transparent_pen(0 );
- m_tmp_bitmap[0] = std::make_unique<bitmap_ind16>(128,128);
- m_tmp_bitmap[1] = std::make_unique<bitmap_ind16>(128,128);
- m_tmp_bitmap[2] = std::make_unique<bitmap_ind16>(128,128);
- m_tmp_bitmap[3] = std::make_unique<bitmap_ind16>(128,128);
- spotlights();
-
- save_item(NAME(m_h_heed));
- save_item(NAME(m_v_heed));
- save_item(NAME(m_ha));
- save_item(NAME(m_scroll));
- save_item(NAME(m_char_bank));
- save_item(NAME(m_color_select));
-}
-
-void pitnrun_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- uint8_t *spriteram = m_spriteram;
- int sx, sy, flipx, flipy, offs,pal;
-
- for (offs = 0 ; offs < 0x100; offs+=4)
- {
- pal=spriteram[offs+2]&0x3;
-
- sy = 256-spriteram[offs+0]-16;
- sx = spriteram[offs+3]+1; // +1 needed to properly align Jump Kun
- flipy = (spriteram[offs+1]&0x80)>>7;
- flipx = (spriteram[offs+1]&0x40)>>6;
-
- if (flip_screen_x())
- {
- sx = 256 - sx;
- flipx = !flipx;
- }
- if (flip_screen_y())
- {
- sy = 240 - sy;
- flipy = !flipy;
- }
-
- m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
- (spriteram[offs+1]&0x3f)+((spriteram[offs+2]&0x80)>>1)+((spriteram[offs+2]&0x40)<<1),
- pal,
- flipx,flipy,
- sx,sy,0);
- }
-}
-
-uint32_t pitnrun_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- int dx=0,dy=0;
- rectangle myclip=cliprect;
-
-#ifdef MAME_DEBUG
- if (machine().input().code_pressed_once(KEYCODE_Q))
- {
- uint8_t *ROM = memregion("maincpu")->base();
- ROM[0x84f6]=0; /* lap 0 - normal */
- }
-
- if (machine().input().code_pressed_once(KEYCODE_W))
- {
- uint8_t *ROM = memregion("maincpu")->base();
- ROM[0x84f6]=6; /* lap 6 = spotlight */
- }
-
- if (machine().input().code_pressed_once(KEYCODE_E))
- {
- uint8_t *ROM = memregion("maincpu")->base();
- ROM[0x84f6]=2; /* lap 3 (trial 2)= lightnings */
- ROM[0x8102]=1;
- }
-#endif
-
- bitmap.fill(0, cliprect);
-
- if(!(m_ha&4))
- m_bg->draw(screen, bitmap, cliprect, 0,0);
- else
- {
- dx=128-m_h_heed+((m_ha&8)<<5)+3;
- dy=128-m_v_heed+((m_ha&0x10)<<4);
-
- if (flip_screen_x())
- dx=128-dx+16;
-
- if (flip_screen_y())
- dy=128-dy;
-
- myclip.set(dx, dx+127, dy, dy+127);
- myclip &= cliprect;
-
- m_bg->draw(screen, bitmap, myclip, 0,0);
- }
-
- draw_sprites(bitmap,myclip);
-
- if(m_ha&4)
- copybitmap_trans(bitmap,*m_tmp_bitmap[m_ha&3],flip_screen_x(),flip_screen_y(),dx,dy,myclip, 1);
- m_fg->draw(screen, bitmap, cliprect, 0,0);
- return 0;
-}
diff --git a/src/mame/taito/rollrace.cpp b/src/mame/taito/rollrace.cpp
index 5bef99eb690..c78fb2ce10e 100644
--- a/src/mame/taito/rollrace.cpp
+++ b/src/mame/taito/rollrace.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Pierpaolo Prazzoli
+// copyright-holders: Pierpaolo Prazzoli
+
/***************************************************************************
Fighting Roller (c) 1983 Kaneko
@@ -10,15 +11,311 @@ Issues:
***************************************************************************/
#include "emu.h"
-#include "rollrace.h"
#include "cpu/z80/z80.h"
#include "machine/74259.h"
#include "machine/gen_latch.h"
#include "sound/ay8910.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+// configurable logging
+#define LOG_D900 (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_D900)
+
+#include "logmacro.h"
+
+#define LOGD900(...) LOGMASKED(LOG_D900, __VA_ARGS__)
+
+
+namespace {
+
+class rollrace_state : public driver_device
+{
+public:
+ rollrace_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_videoram(*this, "videoram"),
+ m_colorram(*this, "colorram"),
+ m_spriteram(*this, "spriteram"),
+ m_roadlay_rom(*this, "road_layout")
+ { }
+
+ void rollace2(machine_config &config);
+ void rollrace(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void video_start() override;
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+ required_shared_ptr<uint8_t> m_videoram;
+ required_shared_ptr<uint8_t> m_colorram;
+ required_shared_ptr<uint8_t> m_spriteram;
+ required_region_ptr<uint8_t> m_roadlay_rom;
+
+ tilemap_t *m_fg_tilemap = nullptr;
+ uint8_t m_bkgpage = 0;
+ uint8_t m_bkgflip = 0;
+ uint8_t m_chrbank = 0;
+ uint8_t m_bkgpen = 0;
+ uint8_t m_bkgcol = 0;
+ uint8_t m_flipy = 0;
+ uint8_t m_flipx = 0;
+ uint8_t m_spritebank = 0;
+
+ enum
+ {
+ RA_FGCHAR_BASE = 0,
+ RA_BGCHAR_BASE = 4,
+ RA_SP_BASE = 5
+ };
+
+ uint8_t m_nmi_mask = 0;
+ uint8_t m_sound_nmi_mask = 0;
+
+ uint8_t fake_d900_r();
+ void fake_d900_w(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER(nmi_mask_w);
+ void sound_nmi_mask_w(uint8_t data);
+ template <uint8_t Which> DECLARE_WRITE_LINE_MEMBER(coin_counter_w);
+ DECLARE_WRITE_LINE_MEMBER(charbank_0_w);
+ DECLARE_WRITE_LINE_MEMBER(charbank_1_w);
+ void bkgpen_w(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER(spritebank_w);
+ void backgroundpage_w(uint8_t data);
+ void backgroundcolor_w(uint8_t data);
+ void flipy_w(uint8_t data);
+ DECLARE_WRITE_LINE_MEMBER(flipx_w);
+ void vram_w(offs_t offset, uint8_t data);
+ void cram_w(offs_t offset, uint8_t data);
+ TILE_GET_INFO_MEMBER(get_fg_tile_info);
+ void tilemap_refresh_flip();
+
+ void palette(palette_device &palette) const;
+
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ DECLARE_WRITE_LINE_MEMBER(vblank_irq);
+ INTERRUPT_GEN_MEMBER(sound_timer_irq);
+ void main_map(address_map &map);
+ void sound_map(address_map &map);
+};
+
+
+// video
+
+TILE_GET_INFO_MEMBER(rollrace_state::get_fg_tile_info)
+{
+ int const code = m_videoram[tile_index];
+ int const color = m_colorram[(tile_index & 0x1f) * 2 + 1] & 0x1f;
+
+ tileinfo.set(RA_FGCHAR_BASE + m_chrbank,
+ code,
+ color,
+ TILE_FLIPY);
+}
+void rollrace_state::video_start()
+{
+ m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(rollrace_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+
+ m_fg_tilemap->set_transparent_pen(0);
+ m_fg_tilemap->set_scroll_cols(32);
+}
+
+void rollrace_state::vram_w(offs_t offset, uint8_t data)
+{
+ m_videoram[offset] = data;
+ m_fg_tilemap->mark_tile_dirty(offset);
+}
+
+void rollrace_state::cram_w(offs_t offset, uint8_t data)
+{
+ m_colorram[offset] = data;
+ if (offset & 1)
+ {
+ // TODO: optimize
+ m_fg_tilemap->mark_all_dirty();
+ //for(int x = 0; x < 32; x++)
+ // m_fg_tilemap->mark_tile_dirty(x + ((offset >> 1) * 32));
+ }
+ else
+ m_fg_tilemap->set_scrolly(offset >> 1,data);
+}
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ Stinger has three 256x4 palette PROMs (one per gun).
+ The palette PROMs are connected to the RGB output this way:
+
+ bit 3 -- 100 ohm resistor -- RED/GREEN/BLUE
+ -- 220 ohm resistor -- RED/GREEN/BLUE
+ -- 470 ohm resistor -- RED/GREEN/BLUE
+ bit 0 -- 1 kohm resistor -- RED/GREEN/BLUE
+
+***************************************************************************/
+void rollrace_state::palette(palette_device &palette) const
+{
+ const uint8_t *color_prom = memregion("proms")->base();
+
+ for (int i = 0; i < palette.entries(); i++)
+ {
+ int bit0, bit1, bit2, bit3;
+
+ bit0 = BIT(color_prom[0], 0);
+ bit1 = BIT(color_prom[0], 1);
+ bit2 = BIT(color_prom[0], 2);
+ bit3 = BIT(color_prom[0], 3);
+ int const r = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
+
+ bit0 = BIT(color_prom[palette.entries()], 0);
+ bit1 = BIT(color_prom[palette.entries()], 1);
+ bit2 = BIT(color_prom[palette.entries()], 2);
+ bit3 = BIT(color_prom[palette.entries()], 3);
+ int const g = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
+
+ bit0 = BIT(color_prom[2 * palette.entries()], 0);
+ bit1 = BIT(color_prom[2 * palette.entries()], 1);
+ bit2 = BIT(color_prom[2 * palette.entries()], 2);
+ bit3 = BIT(color_prom[2 * palette.entries()], 3);
+ int const b = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
+
+ palette.set_pen_color(i, rgb_t(r, g, b));
+
+ color_prom++;
+ }
+}
+
+WRITE_LINE_MEMBER(rollrace_state::charbank_0_w)
+{
+ m_chrbank = state | (m_chrbank & 2);
+ m_fg_tilemap->mark_all_dirty();
+}
+
+WRITE_LINE_MEMBER(rollrace_state::charbank_1_w)
+{
+ m_chrbank = (m_chrbank & 1) | (state << 1);
+ m_fg_tilemap->mark_all_dirty();
+}
+
+void rollrace_state::bkgpen_w(uint8_t data)
+{
+ m_bkgpen = data;
+}
+
+WRITE_LINE_MEMBER(rollrace_state::spritebank_w)
+{
+ m_spritebank = state;
+}
+
+void rollrace_state::backgroundpage_w(uint8_t data)
+{
+ m_bkgpage = data & 0x1f;
+ m_bkgflip = (data & 0x80) >> 7;
+
+ // 0x80 flip vertical
+}
+
+void rollrace_state::backgroundcolor_w(uint8_t data)
+{
+ m_bkgcol = data;
+}
+
+void rollrace_state::flipy_w(uint8_t data)
+{
+ m_flipy = data & 0x01;
+ // bit 2: cleared at night stage in attract, unknown purpose
+}
+
+WRITE_LINE_MEMBER(rollrace_state::flipx_w)
+{
+ m_flipx = state;
+ m_fg_tilemap->set_flip(m_flipx ? TILEMAP_FLIPX | TILEMAP_FLIPY : 0);
+}
+
+uint32_t rollrace_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // fill in background colour
+ bitmap.fill(m_bkgpen, cliprect);
+
+ // draw road
+ for (int offs = 0x3ff; offs >= 0; offs--)
+ {
+ int sy;
+
+ if (!(m_bkgflip))
+ sy = (31 - offs / 32);
+ else
+ sy = (offs / 32);
+
+ int sx = (offs % 32);
+
+ if (m_flipx)
+ sx = 31 - sx;
+
+ if (m_flipy)
+ sy = 31 - sy;
+
+ m_gfxdecode->gfx(RA_BGCHAR_BASE)->transpen(bitmap,
+ cliprect,
+ m_roadlay_rom[offs + (m_bkgpage * 1024)]
+ + (((m_roadlay_rom[offs + 0x4000 + (m_bkgpage * 1024)] & 0xc0) >> 6) * 256),
+ m_bkgcol,
+ m_flipx, (m_bkgflip ^ m_flipy),
+ sx * 8, sy * 8, 0);
+ }
+
+ // sprites
+ for (int offs = 0x80-4; offs >=0x0; offs -= 4)
+ {
+ int s_flipy = 0;
+
+ int sy = m_spriteram[offs] - 16;
+ int sx = m_spriteram[offs + 3] - 16;
+
+ if (sx && sy)
+ {
+ if (m_flipx)
+ sx = 224 - sx;
+ if (m_flipy)
+ sy = 224 - sy;
+
+ if (m_spriteram[offs + 1] & 0x80)
+ s_flipy = 1;
+
+ int bank = ((m_spriteram[offs + 1] & 0x40 ) >> 6);
+
+ if (bank)
+ bank += m_spritebank;
+
+ m_gfxdecode->gfx(RA_SP_BASE + bank)->transpen(bitmap, cliprect,
+ m_spriteram[offs + 1] & 0x3f,
+ m_spriteram[offs + 2] & 0x1f,
+ m_flipx, !(s_flipy ^ m_flipy),
+ sx, sy, 0);
+ }
+ }
+
+ m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
+ return 0;
+}
+
+
+// machine
void rollrace_state::machine_start()
{
@@ -34,14 +331,14 @@ void rollrace_state::machine_start()
save_item(NAME(m_sound_nmi_mask));
}
-uint8_t rollrace_state::fake_d800_r()
+uint8_t rollrace_state::fake_d900_r()
{
return 0x51;
}
-void rollrace_state::fake_d800_w(uint8_t data)
+void rollrace_state::fake_d900_w(uint8_t data)
{
-/* logerror("d900: %02X\n",data);*/
+ LOGD900("d900: %02X\n", data);
}
WRITE_LINE_MEMBER(rollrace_state::nmi_mask_w)
@@ -56,28 +353,24 @@ void rollrace_state::sound_nmi_mask_w(uint8_t data)
m_sound_nmi_mask = data & 1;
}
-WRITE_LINE_MEMBER(rollrace_state::coin_counter_1_w)
-{
- machine().bookkeeping().coin_counter_w(0, state);
-}
-
-WRITE_LINE_MEMBER(rollrace_state::coin_counter_2_w)
+template <uint8_t Which>
+WRITE_LINE_MEMBER(rollrace_state::coin_counter_w)
{
- machine().bookkeeping().coin_counter_w(1, state);
+ machine().bookkeeping().coin_counter_w(Which, state);
}
-void rollrace_state::rollrace_map(address_map &map)
+void rollrace_state::main_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
- map(0x8000, 0x9fff).rom(); /* only rollace2 */
+ map(0x8000, 0x9fff).rom(); // only rollace2
map(0xc000, 0xcfff).ram();
- map(0xd806, 0xd806).nopr(); /* looks like a watchdog, bit4 checked*/
- map(0xd900, 0xd900).rw(FUNC(rollrace_state::fake_d800_r), FUNC(rollrace_state::fake_d800_w)); /* protection ??*/
- map(0xe000, 0xe3ff).ram().w(FUNC(rollrace_state::vram_w)).share("videoram");
- map(0xe400, 0xe47f).ram().w(FUNC(rollrace_state::cram_w)).share("colorram");
+ map(0xd806, 0xd806).nopr(); // looks like a watchdog, bit 4 checked
+ map(0xd900, 0xd900).rw(FUNC(rollrace_state::fake_d900_r), FUNC(rollrace_state::fake_d900_w)); // protection ??
+ map(0xe000, 0xe3ff).ram().w(FUNC(rollrace_state::vram_w)).share(m_videoram);
+ map(0xe400, 0xe47f).ram().w(FUNC(rollrace_state::cram_w)).share(m_colorram);
map(0xe800, 0xe800).w("soundlatch", FUNC(generic_latch_8_device::write));
- map(0xec00, 0xec0f).noprw(); /* Analog sound effects ?? ec00 sound enable ?*/
- map(0xf000, 0xf0ff).ram().share("spriteram");
+ map(0xec00, 0xec0f).noprw(); // Analog sound effects ?? ec00 sound enable ?
+ map(0xf000, 0xf0ff).ram().share(m_spriteram);
map(0xf400, 0xf400).w(FUNC(rollrace_state::backgroundcolor_w));
map(0xf800, 0xf800).portr("P1");
map(0xf801, 0xf801).portr("P2").w(FUNC(rollrace_state::bkgpen_w));
@@ -89,7 +382,7 @@ void rollrace_state::rollrace_map(address_map &map)
}
-void rollrace_state::rollrace_sound_map(address_map &map)
+void rollrace_state::sound_map(address_map &map)
{
map(0x0000, 0x0fff).rom();
map(0x2000, 0x2fff).ram();
@@ -156,14 +449,14 @@ static INPUT_PORTS_START( rollrace )
PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x18, DEF_STR( 1C_6C ) )
-/* PORT_BIT( 0x40, IP_ACTIVE_HIGH , IPT_CUSTOM ) PORT_VBLANK("screen") freezes frame, could be vblank ?*/
+// PORT_BIT( 0x40, IP_ACTIVE_HIGH , IPT_CUSTOM ) PORT_VBLANK("screen") freezes frame, could be vblank ?
PORT_DIPNAME( 0x40, 0x00, "Freeze" )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x40, DEF_STR( On ) )
-/* PORT_DIPNAME( 0x80, 0x00, "Free Run" ) */
+// PORT_DIPNAME( 0x80, 0x00, "Free Run" )
PORT_DIPNAME( 0x80, 0x00, "Invulnerability (Cheat)" )
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) /* test mode, you are invulnerable */
- PORT_DIPSETTING( 0x80, DEF_STR( On ) ) /* to 'static' objects */
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) // test mode, you are invulnerable
+ PORT_DIPSETTING( 0x80, DEF_STR( On ) ) // to 'static' objects
PORT_START("DSW2")
PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) )
@@ -191,50 +484,50 @@ INPUT_PORTS_END
static const gfx_layout charlayout =
{
- 8,8, /* 8*8 characters */
- 256, /* 256 characters */
- 3, /* 3 bits per pixel */
- { 0,1024*8*8, 2*1024*8*8 }, /* the two bitplanes are separated */
+ 8,8, // 8*8 characters
+ 256, // 256 characters
+ 3, // 3 bits per pixel
+ { 0,1024*8*8, 2*1024*8*8 }, // the two bitplanes are separated
{ 0,1,2,3,4,5,6,7 },
{ 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
- 8*8 /* every char takes 8 consecutive bytes */
+ 8*8 // every char takes 8 consecutive bytes
};
static const gfx_layout charlayout2 =
{
- 8,8, /* 8*8 characters */
- 1024, /* 1024 characters */
- 3, /* 3 bits per pixel */
- { 0,1024*8*8, 2*1024*8*8 }, /* the two bitplanes are separated */
+ 8,8, // 8*8 characters
+ 1024, // 1024 characters
+ 3, // 3 bits per pixel
+ { 0,1024*8*8, 2*1024*8*8 }, // the two bitplanes are separated
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
// { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
- 8*8 /* every char takes 8 consecutive bytes */
+ 8*8 // every char takes 8 consecutive bytes
};
static const gfx_layout spritelayout =
{
- 32,32, /* 32*32 sprites */
- 64, /* 64 sprites */
- 3, /* 3 bits per pixel */
- { 0x4000*8, 0x2000*8, 0 }, /* the three bitplanes are separated */
+ 32,32, // 32*32 sprites
+ 64, // 64 sprites
+ 3, // 3 bits per pixel
+ { 0x4000*8, 0x2000*8, 0 }, // the three bitplanes are separated
{ 0, 1, 2, 3, 4, 5, 6, 7,
8*8+0, 8*8+1, 8*8+2, 8*8+3, 8*8+4, 8*8+5, 8*8+6, 8*8+7,16*8,16*8+1,16*8+2,16*8+3,16*8+4,16*8+5,16*8+6,16*8+7,24*8,24*8+1,24*8+2,24*8+3,24*8+4,24*8+5,24*8+6,24*8+7},
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
32*8, 33*8, 34*8, 35*8, 36*8, 37*8, 38*8, 39*8,
64*8,65*8,66*8,67*8,68*8,69*8,70*8,71*8, 96*8,97*8,98*8,99*8,100*8,101*8,102*8,103*8 },
- 32*32 /* every sprite takes 128 consecutive bytes */
+ 32*32 // every sprite takes 128 consecutive bytes
};
static GFXDECODE_START( gfx_rollrace )
- GFXDECODE_ENTRY( "gfx1", 0x0000, charlayout, 0, 32 ) /* foreground */
- GFXDECODE_ENTRY( "gfx1", 0x0800, charlayout, 0, 32 )
- GFXDECODE_ENTRY( "gfx1", 0x1000, charlayout, 0, 32 )
- GFXDECODE_ENTRY( "gfx1", 0x1800, charlayout, 0, 32 )
- GFXDECODE_ENTRY( "gfx2", 0x0000, charlayout2, 0, 32 ) /* for the road */
- GFXDECODE_ENTRY( "gfx3", 0x0000, spritelayout, 0, 32 ) /* sprites */
- GFXDECODE_ENTRY( "gfx4", 0x0000, spritelayout, 0, 32 )
- GFXDECODE_ENTRY( "gfx5", 0x0000, spritelayout, 0, 32 )
+ GFXDECODE_ENTRY( "chars", 0x0000, charlayout, 0, 32 )
+ GFXDECODE_ENTRY( "chars", 0x0800, charlayout, 0, 32 )
+ GFXDECODE_ENTRY( "chars", 0x1000, charlayout, 0, 32 )
+ GFXDECODE_ENTRY( "chars", 0x1800, charlayout, 0, 32 )
+ GFXDECODE_ENTRY( "road", 0x0000, charlayout2, 0, 32 )
+ GFXDECODE_ENTRY( "sprites_0", 0x0000, spritelayout, 0, 32 )
+ GFXDECODE_ENTRY( "sprites_1", 0x0000, spritelayout, 0, 32 )
+ GFXDECODE_ENTRY( "sprites_2", 0x0000, spritelayout, 0, 32 )
GFXDECODE_END
WRITE_LINE_MEMBER(rollrace_state::vblank_irq)
@@ -245,33 +538,33 @@ WRITE_LINE_MEMBER(rollrace_state::vblank_irq)
INTERRUPT_GEN_MEMBER(rollrace_state::sound_timer_irq)
{
- if(m_sound_nmi_mask)
+ if (m_sound_nmi_mask)
device.execute().pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
void rollrace_state::rollrace(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, XTAL(24'000'000)/8); /* verified on pcb */
- m_maincpu->set_addrmap(AS_PROGRAM, &rollrace_state::rollrace_map);
+ // basic machine hardware
+ Z80(config, m_maincpu, XTAL(24'000'000) / 8); // verified on PCB
+ m_maincpu->set_addrmap(AS_PROGRAM, &rollrace_state::main_map);
- z80_device &audiocpu(Z80(config, "audiocpu", XTAL(24'000'000)/16)); /* verified on pcb */
- audiocpu.set_addrmap(AS_PROGRAM, &rollrace_state::rollrace_sound_map);
- audiocpu.set_periodic_int(FUNC(rollrace_state::sound_timer_irq), attotime::from_hz(4*60));
+ z80_device &audiocpu(Z80(config, "audiocpu", XTAL(24'000'000) / 16)); // verified on PCB
+ audiocpu.set_addrmap(AS_PROGRAM, &rollrace_state::sound_map);
+ audiocpu.set_periodic_int(FUNC(rollrace_state::sound_timer_irq), attotime::from_hz(4 * 60));
ls259_device &mainlatch(LS259(config, "mainlatch"));
mainlatch.q_out_cb<0>().set(FUNC(rollrace_state::flipx_w));
mainlatch.q_out_cb<1>().set(FUNC(rollrace_state::nmi_mask_w));
- mainlatch.q_out_cb<2>().set(FUNC(rollrace_state::coin_counter_1_w));
- mainlatch.q_out_cb<3>().set(FUNC(rollrace_state::coin_counter_2_w));
+ mainlatch.q_out_cb<2>().set(FUNC(rollrace_state::coin_counter_w<0>));
+ mainlatch.q_out_cb<3>().set(FUNC(rollrace_state::coin_counter_w<1>));
mainlatch.q_out_cb<4>().set(FUNC(rollrace_state::charbank_0_w));
mainlatch.q_out_cb<5>().set(FUNC(rollrace_state::charbank_1_w));
mainlatch.q_out_cb<6>().set(FUNC(rollrace_state::spritebank_w));
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
- screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
+ screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate
screen.set_size(256, 256);
screen.set_visarea(0, 256-1, 16, 255-16);
screen.set_screen_update(FUNC(rollrace_state::screen_update));
@@ -279,26 +572,26 @@ void rollrace_state::rollrace(machine_config &config)
screen.screen_vblank().set(FUNC(rollrace_state::vblank_irq));
GFXDECODE(config, m_gfxdecode, m_palette, gfx_rollrace);
- PALETTE(config, m_palette, FUNC(rollrace_state::rollrace_palette), 256);
+ PALETTE(config, m_palette, FUNC(rollrace_state::palette), 256);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
GENERIC_LATCH_8(config, "soundlatch");
- AY8910(config, "ay1", XTAL(24'000'000)/16).add_route(ALL_OUTPUTS, "rspeaker", 0.10); /* verified on pcb */
+ AY8910(config, "ay1", XTAL(24'000'000) / 16).add_route(ALL_OUTPUTS, "rspeaker", 0.10); // verified on PCB
- AY8910(config, "ay2", XTAL(24'000'000)/16).add_route(ALL_OUTPUTS, "rspeaker", 0.10); /* verified on pcb */
+ AY8910(config, "ay2", XTAL(24'000'000) / 16).add_route(ALL_OUTPUTS, "rspeaker", 0.10); // verified on PCB
- AY8910(config, "ay3", XTAL(24'000'000)/16).add_route(ALL_OUTPUTS, "lspeaker", 0.10); /* verified on pcb */
+ AY8910(config, "ay3", XTAL(24'000'000) / 16).add_route(ALL_OUTPUTS, "lspeaker", 0.10); // verified on PCB
}
void rollrace_state::rollace2(machine_config &config)
{
rollrace(config);
- /* basic machine hardware */
+ // basic machine hardware
// subdevice<screen_device>("screen")->set_visarea(0, 256-1, 16, 255-16);
}
@@ -311,147 +604,149 @@ void rollrace_state::rollace2(machine_config &config)
***************************************************************************/
ROM_START( fightrol )
- ROM_REGION( 0x10000, "maincpu",0 )
+ ROM_REGION( 0xa000, "maincpu", 0 )
ROM_LOAD( "4.8k", 0x0000, 0x2000, CRC(efa2f430) SHA1(6aeb2a41e4fba97a0ac1b24fe5437e25b6c6b6c5) )
ROM_LOAD( "5.8h", 0x2000, 0x2000, CRC(2497d9f6) SHA1(4f4cfed47efc603bf057dd24b761beecf5b929f4) )
ROM_LOAD( "6.8f", 0x4000, 0x2000, CRC(f39727b9) SHA1(08a1300172b4100cb80c9a5d8942408255d8e330) )
ROM_LOAD( "7.8d", 0x6000, 0x2000, CRC(ee65b728) SHA1(871918d505ad8bab60c55bbb95fe37556a204dc9) )
- ROM_REGION( 0x6000,"gfx1",0 ) /* characters */
+ ROM_REGION( 0x6000, "chars", 0 )
ROM_LOAD( "3.7m", 0x0000, 0x2000, CRC(ca4f353c) SHA1(754838c6ad6886052a018966d55f40a7ed4b684d) )
ROM_LOAD( "2.8m", 0x2000, 0x2000, CRC(93786171) SHA1(3928aad8bc43adeaad5e53c1d4e9df64f1d23704) )
ROM_LOAD( "1.9m", 0x4000, 0x2000, CRC(dc072be1) SHA1(94d379a4c5a53050a18cd572cc82edb337182f3b) )
- ROM_REGION( 0x6000, "gfx2",0 ) /* road graphics */
+ ROM_REGION( 0x6000, "road", 0 )
ROM_LOAD ( "6.20k", 0x0000, 0x2000, CRC(003d7515) SHA1(d8d84d690478cad16101f2ef9a1ae1ae74d01c88) )
ROM_LOAD ( "7.18k", 0x2000, 0x2000, CRC(27843afa) SHA1(81d3031a2c06086461110696a0ee11d32992ecac) )
ROM_LOAD ( "5.20f", 0x4000, 0x2000, CRC(51dd0108) SHA1(138c0aba6c952204e794216193def17b390c4ba2) )
- ROM_REGION( 0x6000, "gfx3",0 ) /* sprite bank 0*/
+ ROM_REGION( 0x6000, "sprites_0", 0 )
ROM_LOAD ( "8.17m", 0x0000, 0x2000, CRC(08ad783e) SHA1(fea91e41916cfc7b29c5f9a578e2c82a54f66829) )
ROM_LOAD ( "9.17r", 0x2000, 0x2000, CRC(69b23461) SHA1(73eca5e721425f37df311454bd5b4e632b096eba) )
ROM_LOAD ( "10.17t", 0x4000, 0x2000, CRC(ba6ccd8c) SHA1(29a13e3161aba4db080434685869f8b79ad7997c) )
- ROM_REGION( 0x6000, "gfx4",0 ) /* sprite bank 1*/
+ ROM_REGION( 0x6000, "sprites_1", 0 )
ROM_LOAD ( "11.18m", 0x0000, 0x2000, CRC(06a5d849) SHA1(b9f604edf4fdc053b738041493aef91dd730fe6b) )
ROM_LOAD ( "12.18r", 0x2000, 0x2000, CRC(569815ef) SHA1(db261799892f60b2274b73fb25cde58219bb44db) )
ROM_LOAD ( "13.18t", 0x4000, 0x2000, CRC(4f8af872) SHA1(6c07ff0733b8d8440309c9ae0db0876587b740a6) )
- ROM_REGION( 0x6000, "gfx5",0 ) /* sprite bank 2*/
+ ROM_REGION( 0x6000, "sprites_2", 0 )
ROM_LOAD ( "14.19m", 0x0000, 0x2000, CRC(93f3c649) SHA1(38d6bb4b6108a67b135ae1a145532f4a0c2568b8) )
ROM_LOAD ( "15.19r", 0x2000, 0x2000, CRC(5b3d87e4) SHA1(e47f7b62bf7101afba8d5e181f4bd8f8eb6eeb08) )
ROM_LOAD ( "16.19u", 0x4000, 0x2000, CRC(a2c24b64) SHA1(e76558785ea337ab902fb6f94dc1a4bdfcd6335e) )
- ROM_REGION( 0x8000, "user1",0 ) /* road layout */
+ ROM_REGION( 0x8000, "road_layout", 0 )
ROM_LOAD ( "1.17a", 0x0000, 0x2000, CRC(f0fa72fc) SHA1(b73e794df635630f29a79adfe2951dc8f1d17e20) )
ROM_LOAD ( "3.18b", 0x2000, 0x2000, CRC(954268f7) SHA1(07057296e0281f90b18dfe4223aad18bff7cfa6e) )
ROM_LOAD ( "2.17d", 0x4000, 0x2000, CRC(2e38bb0e) SHA1(684f14a06ff957e40780be21c0ad5f10088a55ed) )
ROM_LOAD ( "4.18d", 0x6000, 0x2000, CRC(3d9e16ab) SHA1(e99628ffc54e3ff4818313a287ca111617120910) )
- ROM_REGION( 0x300, "proms",0 ) /* colour */
+ ROM_REGION( 0x300, "proms", 0 ) // colour
ROM_LOAD("tbp24s10.7u", 0x0000, 0x0100, CRC(9d199d33) SHA1(b8982f7da2b85f10d117177e4e73cbb486931cf5) )
ROM_LOAD("tbp24s10.7t", 0x0100, 0x0100, CRC(c0426582) SHA1(8e3e4d1e76243cce272aa099d2d6ad4fa6c99f7c) )
ROM_LOAD("tbp24s10.6t", 0x0200, 0x0100, CRC(c096e05c) SHA1(cb5b509e6124453f381a683ba446f8f4493d4610) )
- ROM_REGION( 0x10000,"audiocpu",0 )
+ ROM_REGION( 0x1000, "audiocpu", 0 )
ROM_LOAD( "8.6f", 0x0000, 0x1000, CRC(6ec3c545) SHA1(1a2477b9e1563734195b0743f5dbbb005e06022e) )
ROM_END
ROM_START( rollace )
- ROM_REGION( 0x10000, "maincpu",0 )
+ ROM_REGION( 0xa000, "maincpu", 0 )
ROM_LOAD( "w1.8k", 0x0000, 0x2000, CRC(c0bd3cf3) SHA1(a44d69b8c3249b5093261a32d0e0404992fa7f7a) )
ROM_LOAD( "w2.8h", 0x2000, 0x2000, CRC(c1900a75) SHA1(f7ec968b6bcb6ee6db98628cdf566ae0a501edba) )
ROM_LOAD( "w3.8f", 0x4000, 0x2000, CRC(16ceced6) SHA1(241119959ffdf26780258bcc5651eca0c6a6128f) )
ROM_LOAD( "w4.8d", 0x6000, 0x2000, CRC(ae826a96) SHA1(47979343c9fa7629ba6d62630c7c3fdfa2c8c28a) )
- ROM_REGION( 0x6000,"gfx1",0 ) /* characters */
+ ROM_REGION( 0x6000, "chars", 0 )
ROM_LOAD( "w3.7m", 0x0000, 0x2000, CRC(f9970aae) SHA1(ccb806cab3d3817c779e048f995d1f6fbe163679) )
ROM_LOAD( "w2.8m", 0x2000, 0x2000, CRC(80573091) SHA1(ea352abebc428db9e89eda5f369a3b1086aa8970) )
ROM_LOAD( "w1.9m", 0x4000, 0x2000, CRC(b37effd8) SHA1(d77d56d734834812b8d9b3c156577dbbcb2deac8) )
- ROM_REGION( 0x6000, "gfx2",0 ) /* road graphics */
+ ROM_REGION( 0x6000, "road", 0 )
ROM_LOAD ( "6.20k", 0x0000, 0x2000, CRC(003d7515) SHA1(d8d84d690478cad16101f2ef9a1ae1ae74d01c88) )
ROM_LOAD ( "7.18k", 0x2000, 0x2000, CRC(27843afa) SHA1(81d3031a2c06086461110696a0ee11d32992ecac) )
ROM_LOAD ( "5.20f", 0x4000, 0x2000, CRC(51dd0108) SHA1(138c0aba6c952204e794216193def17b390c4ba2) )
- ROM_REGION( 0x6000, "gfx3",0 ) /* sprite bank 0*/
+ ROM_REGION( 0x6000, "sprites_0", 0 )
ROM_LOAD ( "w8.17m", 0x0000, 0x2000, CRC(e2afe3a3) SHA1(a83a12c0c6c62e45add916a6993f0ad06840c4d9) )
ROM_LOAD ( "w9.17p", 0x2000, 0x2000, CRC(8a8e6b62) SHA1(6e7d4a84b7c78e009bce0641e357f74c8ac9e5ac) )
ROM_LOAD ( "w10.17t", 0x4000, 0x2000, CRC(70bf7b23) SHA1(6774eceb0bfea66156ecd837f9d0adbdf8dec8ee) )
- ROM_REGION( 0x6000, "gfx4",0 ) /* sprite bank 1*/
+ ROM_REGION( 0x6000, "sprites_1", 0 )
ROM_LOAD ( "11.18m", 0x0000, 0x2000, CRC(06a5d849) SHA1(b9f604edf4fdc053b738041493aef91dd730fe6b) )
ROM_LOAD ( "12.18r", 0x2000, 0x2000, CRC(569815ef) SHA1(db261799892f60b2274b73fb25cde58219bb44db) )
ROM_LOAD ( "13.18t", 0x4000, 0x2000, CRC(4f8af872) SHA1(6c07ff0733b8d8440309c9ae0db0876587b740a6) )
- ROM_REGION( 0x6000, "gfx5",0 ) /* sprite bank 2*/
+ ROM_REGION( 0x6000, "sprites_2", 0 )
ROM_LOAD ( "14.19m", 0x0000, 0x2000, CRC(93f3c649) SHA1(38d6bb4b6108a67b135ae1a145532f4a0c2568b8) )
ROM_LOAD ( "15.19r", 0x2000, 0x2000, CRC(5b3d87e4) SHA1(e47f7b62bf7101afba8d5e181f4bd8f8eb6eeb08) )
ROM_LOAD ( "16.19u", 0x4000, 0x2000, CRC(a2c24b64) SHA1(e76558785ea337ab902fb6f94dc1a4bdfcd6335e) )
- ROM_REGION( 0x8000, "user1",0 ) /* road layout */
+ ROM_REGION( 0x8000, "road_layout", 0 )
ROM_LOAD ( "1.17a", 0x0000, 0x2000, CRC(f0fa72fc) SHA1(b73e794df635630f29a79adfe2951dc8f1d17e20) )
ROM_LOAD ( "3.18b", 0x2000, 0x2000, CRC(954268f7) SHA1(07057296e0281f90b18dfe4223aad18bff7cfa6e) )
ROM_LOAD ( "2.17d", 0x4000, 0x2000, CRC(2e38bb0e) SHA1(684f14a06ff957e40780be21c0ad5f10088a55ed) )
ROM_LOAD ( "4.18d", 0x6000, 0x2000, CRC(3d9e16ab) SHA1(e99628ffc54e3ff4818313a287ca111617120910) )
- ROM_REGION( 0x300, "proms",0 ) /* colour */
+ ROM_REGION( 0x300, "proms", 0 ) // colour
ROM_LOAD("tbp24s10.7u", 0x0000, 0x0100, CRC(9d199d33) SHA1(b8982f7da2b85f10d117177e4e73cbb486931cf5) )
ROM_LOAD("tbp24s10.7t", 0x0100, 0x0100, CRC(c0426582) SHA1(8e3e4d1e76243cce272aa099d2d6ad4fa6c99f7c) )
ROM_LOAD("tbp24s10.6t", 0x0200, 0x0100, CRC(c096e05c) SHA1(cb5b509e6124453f381a683ba446f8f4493d4610) )
- ROM_REGION( 0x10000,"audiocpu",0 )
+ ROM_REGION( 0x1000, "audiocpu", 0 )
ROM_LOAD( "8.6f", 0x0000, 0x1000, CRC(6ec3c545) SHA1(1a2477b9e1563734195b0743f5dbbb005e06022e) )
ROM_END
ROM_START( rollace2 )
- ROM_REGION( 0x10000, "maincpu",0 )
+ ROM_REGION( 0xa000, "maincpu", 0 )
ROM_LOAD( "8k.764", 0x0000, 0x2000, CRC(a7abff82) SHA1(d49635f98b28b2b5e2833d25b0961addac2c3e6f) )
ROM_LOAD( "8h.764", 0x2000, 0x2000, CRC(9716ba03) SHA1(8a7bfc1dce3b1b0c634690e0637e0a30776c0334) )
ROM_LOAD( "8f.764", 0x4000, 0x2000, CRC(3eadb0e8) SHA1(6ff5b76360597f3a6a9718e505295c8557e569ae) )
ROM_LOAD( "8d.764", 0x6000, 0x2000, CRC(baac14db) SHA1(9707b59a6506eb11c0a6b88364a784469ccdbb96) )
ROM_LOAD( "8c.764", 0x8000, 0x2000, CRC(b418ce84) SHA1(876be297a671328138a9238d42871f22bb568cda) )
- ROM_REGION( 0x6000,"gfx1",0 ) /* characters */
+ ROM_REGION( 0x6000, "chars", 0 )
ROM_LOAD( "7m.764", 0x0000, 0x2000, CRC(8b9b27af) SHA1(a52894adb739f14a5949b6d15dd7b03ce5716d9a) )
ROM_LOAD( "8m.764", 0x2000, 0x2000, CRC(2dfc38f2) SHA1(c0ad3a7d1f5249c159c355d709cc3039fbb7a3b2) )
ROM_LOAD( "9m.764", 0x4000, 0x2000, CRC(2e3a825b) SHA1(d0d25d9a0fe31d46cb6cc999da3d9fc14f23251f) )
- ROM_REGION( 0x6000, "gfx2",0 ) /* road graphics */
+ ROM_REGION( 0x6000, "road", 0 )
ROM_LOAD ( "6.20k", 0x0000, 0x2000, CRC(003d7515) SHA1(d8d84d690478cad16101f2ef9a1ae1ae74d01c88) )
ROM_LOAD ( "7.18k", 0x2000, 0x2000, CRC(27843afa) SHA1(81d3031a2c06086461110696a0ee11d32992ecac) )
ROM_LOAD ( "5.20f", 0x4000, 0x2000, CRC(51dd0108) SHA1(138c0aba6c952204e794216193def17b390c4ba2) )
- ROM_REGION( 0x6000, "gfx3",0 ) /* sprite bank 0*/
- ROM_LOAD ( "17n.764",0x0000, 0x2000, CRC(3365703c) SHA1(7cf374ba25f4fd163a66c0aea74ddfd3003c7992) )
- ROM_LOAD ( "9.17r", 0x2000, 0x2000, CRC(69b23461) SHA1(73eca5e721425f37df311454bd5b4e632b096eba) )
- ROM_LOAD ( "17t.764",0x4000, 0x2000, CRC(5e84cc9b) SHA1(33cdf7b756ade8c0dd1dcdad583af4de02cd51eb) )
+ ROM_REGION( 0x6000, "sprites_0", 0 )
+ ROM_LOAD ( "17n.764", 0x0000, 0x2000, CRC(3365703c) SHA1(7cf374ba25f4fd163a66c0aea74ddfd3003c7992) )
+ ROM_LOAD ( "9.17r", 0x2000, 0x2000, CRC(69b23461) SHA1(73eca5e721425f37df311454bd5b4e632b096eba) )
+ ROM_LOAD ( "17t.764", 0x4000, 0x2000, CRC(5e84cc9b) SHA1(33cdf7b756ade8c0dd1dcdad583af4de02cd51eb) )
- ROM_REGION( 0x6000, "gfx4",0 ) /* sprite bank 1*/
+ ROM_REGION( 0x6000, "sprites_1", 0 )
ROM_LOAD ( "11.18m", 0x0000, 0x2000, CRC(06a5d849) SHA1(b9f604edf4fdc053b738041493aef91dd730fe6b) )
ROM_LOAD ( "12.18r", 0x2000, 0x2000, CRC(569815ef) SHA1(db261799892f60b2274b73fb25cde58219bb44db) )
ROM_LOAD ( "13.18t", 0x4000, 0x2000, CRC(4f8af872) SHA1(6c07ff0733b8d8440309c9ae0db0876587b740a6) )
- ROM_REGION( 0x6000, "gfx5",0 ) /* sprite bank 2*/
+ ROM_REGION( 0x6000, "sprites_2", 0 )
ROM_LOAD ( "14.19m", 0x0000, 0x2000, CRC(93f3c649) SHA1(38d6bb4b6108a67b135ae1a145532f4a0c2568b8) )
ROM_LOAD ( "15.19r", 0x2000, 0x2000, CRC(5b3d87e4) SHA1(e47f7b62bf7101afba8d5e181f4bd8f8eb6eeb08) )
ROM_LOAD ( "16.19u", 0x4000, 0x2000, CRC(a2c24b64) SHA1(e76558785ea337ab902fb6f94dc1a4bdfcd6335e) )
- ROM_REGION( 0x8000, "user1",0 ) /* road layout */
- ROM_LOAD ( "1.17a", 0x0000, 0x2000, CRC(f0fa72fc) SHA1(b73e794df635630f29a79adfe2951dc8f1d17e20) )
- ROM_LOAD ( "3.18b", 0x2000, 0x2000, CRC(954268f7) SHA1(07057296e0281f90b18dfe4223aad18bff7cfa6e) )
- ROM_LOAD ( "17d.764",0x4000, 0x2000, CRC(32e69320) SHA1(d399a8c3b0319178d75f68f1a9b65b3efd91e00a) )
- ROM_LOAD ( "4.18d", 0x6000, 0x2000, CRC(3d9e16ab) SHA1(e99628ffc54e3ff4818313a287ca111617120910) )
+ ROM_REGION( 0x8000, "road_layout", 0 )
+ ROM_LOAD ( "1.17a", 0x0000, 0x2000, CRC(f0fa72fc) SHA1(b73e794df635630f29a79adfe2951dc8f1d17e20) )
+ ROM_LOAD ( "3.18b", 0x2000, 0x2000, CRC(954268f7) SHA1(07057296e0281f90b18dfe4223aad18bff7cfa6e) )
+ ROM_LOAD ( "17d.764", 0x4000, 0x2000, CRC(32e69320) SHA1(d399a8c3b0319178d75f68f1a9b65b3efd91e00a) )
+ ROM_LOAD ( "4.18d", 0x6000, 0x2000, CRC(3d9e16ab) SHA1(e99628ffc54e3ff4818313a287ca111617120910) )
- ROM_REGION( 0x300, "proms",0 ) /* colour */
+ ROM_REGION( 0x300, "proms", 0 ) // colour
ROM_LOAD("tbp24s10.7u", 0x0000, 0x0100, CRC(9d199d33) SHA1(b8982f7da2b85f10d117177e4e73cbb486931cf5) )
ROM_LOAD("tbp24s10.7t", 0x0100, 0x0100, CRC(c0426582) SHA1(8e3e4d1e76243cce272aa099d2d6ad4fa6c99f7c) )
ROM_LOAD("tbp24s10.6t", 0x0200, 0x0100, CRC(c096e05c) SHA1(cb5b509e6124453f381a683ba446f8f4493d4610) )
- ROM_REGION( 0x10000,"audiocpu",0 )
+ ROM_REGION( 0x1000, "audiocpu", 0 )
ROM_LOAD( "8.6f", 0x0000, 0x1000, CRC(6ec3c545) SHA1(1a2477b9e1563734195b0743f5dbbb005e06022e) )
ROM_END
+} // anonymous namespace
+
GAME( 1983, fightrol, 0, rollrace, rollrace, rollrace_state, empty_init, ROT270, "Kaneko (Taito license)", "Fighting Roller", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1983, rollace, fightrol, rollrace, rollrace, rollrace_state, empty_init, ROT270, "Kaneko (Williams license)", "Roller Aces (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/taito/rollrace.h b/src/mame/taito/rollrace.h
deleted file mode 100644
index 2da99cf72e3..00000000000
--- a/src/mame/taito/rollrace.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Pierpaolo Prazzoli
-#ifndef MAME_INCLUDES_ROLLRACE_H
-#define MAME_INCLUDES_ROLLRACE_H
-
-#pragma once
-
-#include "emupal.h"
-#include "tilemap.h"
-
-class rollrace_state : public driver_device
-{
-public:
- rollrace_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_videoram(*this, "videoram"),
- m_colorram(*this, "colorram"),
- m_spriteram(*this, "spriteram")
- { }
-
- void rollace2(machine_config &config);
- void rollrace(machine_config &config);
-
-protected:
- virtual void machine_start() override;
- virtual void video_start() override;
-
-private:
- required_device<cpu_device> m_maincpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
- required_shared_ptr<uint8_t> m_videoram;
- required_shared_ptr<uint8_t> m_colorram;
- required_shared_ptr<uint8_t> m_spriteram;
-
- tilemap_t *m_fg_tilemap = nullptr;
- int m_bkgpage = 0;
- int m_bkgflip = 0;
- int m_chrbank = 0;
- int m_bkgpen = 0;
- int m_bkgcol = 0;
- int m_flipy = 0;
- int m_flipx = 0;
- int m_spritebank = 0;
-
- uint8_t m_nmi_mask = 0;
- uint8_t m_sound_nmi_mask = 0;
-
- uint8_t fake_d800_r();
- void fake_d800_w(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(nmi_mask_w);
- void sound_nmi_mask_w(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(coin_counter_1_w);
- DECLARE_WRITE_LINE_MEMBER(coin_counter_2_w);
- DECLARE_WRITE_LINE_MEMBER(charbank_0_w);
- DECLARE_WRITE_LINE_MEMBER(charbank_1_w);
- void bkgpen_w(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(spritebank_w);
- void backgroundpage_w(uint8_t data);
- void backgroundcolor_w(uint8_t data);
- void flipy_w(uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(flipx_w);
- void vram_w(offs_t offset, uint8_t data);
- void cram_w(offs_t offset, uint8_t data);
- TILE_GET_INFO_MEMBER(get_fg_tile_info);
- void tilemap_refresh_flip();
-
- void rollrace_palette(palette_device &palette) const;
-
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- DECLARE_WRITE_LINE_MEMBER(vblank_irq);
- INTERRUPT_GEN_MEMBER(sound_timer_irq);
- void rollrace_map(address_map &map);
- void rollrace_sound_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_ROLLRACE_H
diff --git a/src/mame/taito/rollrace_v.cpp b/src/mame/taito/rollrace_v.cpp
deleted file mode 100644
index a96a6aa52fc..00000000000
--- a/src/mame/taito/rollrace_v.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Pierpaolo Prazzoli
-#include "emu.h"
-#include "rollrace.h"
-
-
-#define RA_FGCHAR_BASE 0
-#define RA_BGCHAR_BASE 4
-#define RA_SP_BASE 5
-
-
-TILE_GET_INFO_MEMBER(rollrace_state::get_fg_tile_info)
-{
- int code = m_videoram[tile_index];
- int color = m_colorram[(tile_index & 0x1f)*2+1] & 0x1f;
-
- tileinfo.set(RA_FGCHAR_BASE + m_chrbank,
- code,
- color,
- TILE_FLIPY);
-}
-
-void rollrace_state::video_start()
-{
- m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(rollrace_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
-
- m_fg_tilemap->set_transparent_pen(0);
- m_fg_tilemap->set_scroll_cols(32);
-}
-
-void rollrace_state::vram_w(offs_t offset, uint8_t data)
-{
- m_videoram[offset] = data;
- m_fg_tilemap->mark_tile_dirty(offset);
-}
-
-void rollrace_state::cram_w(offs_t offset, uint8_t data)
-{
- m_colorram[offset] = data;
- if(offset & 1)
- {
- // TODO: optimize
- m_fg_tilemap->mark_all_dirty();
- //for(int x = 0; x < 32; x++)
- // m_fg_tilemap->mark_tile_dirty(x + ((offset >> 1)*32));
- }
- else
- m_fg_tilemap->set_scrolly(offset >> 1,data);
-}
-
-/***************************************************************************
-
- Convert the color PROMs into a more useable format.
-
- Stinger has three 256x4 palette PROMs (one per gun).
- The palette PROMs are connected to the RGB output this way:
-
- bit 3 -- 100 ohm resistor -- RED/GREEN/BLUE
- -- 220 ohm resistor -- RED/GREEN/BLUE
- -- 470 ohm resistor -- RED/GREEN/BLUE
- bit 0 -- 1 kohm resistor -- RED/GREEN/BLUE
-
-***************************************************************************/
-void rollrace_state::rollrace_palette(palette_device &palette) const
-{
- const uint8_t *color_prom = memregion("proms")->base();
-
- for (int i = 0; i < palette.entries(); i++)
- {
- int bit0, bit1, bit2, bit3;
-
- bit0 = BIT(color_prom[0], 0);
- bit1 = BIT(color_prom[0], 1);
- bit2 = BIT(color_prom[0], 2);
- bit3 = BIT(color_prom[0], 3);
- int const r = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
-
- bit0 = BIT(color_prom[palette.entries()], 0);
- bit1 = BIT(color_prom[palette.entries()], 1);
- bit2 = BIT(color_prom[palette.entries()], 2);
- bit3 = BIT(color_prom[palette.entries()], 3);
- int const g = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
-
- bit0 = BIT(color_prom[2 * palette.entries()], 0);
- bit1 = BIT(color_prom[2 * palette.entries()], 1);
- bit2 = BIT(color_prom[2 * palette.entries()], 2);
- bit3 = BIT(color_prom[2 * palette.entries()], 3);
- int const b = 0x0e * bit0 + 0x1f * bit1 + 0x42 * bit2 + 0x90 * bit3;
-
- palette.set_pen_color(i, rgb_t(r, g, b));
-
- color_prom++;
- }
-}
-
-WRITE_LINE_MEMBER(rollrace_state::charbank_0_w)
-{
- m_chrbank = state | (m_chrbank & 2);
- m_fg_tilemap->mark_all_dirty();
-}
-
-WRITE_LINE_MEMBER(rollrace_state::charbank_1_w)
-{
- m_chrbank = (m_chrbank & 1) | (state << 1);
- m_fg_tilemap->mark_all_dirty();
-}
-
-void rollrace_state::bkgpen_w(uint8_t data)
-{
- m_bkgpen = data;
-}
-
-WRITE_LINE_MEMBER(rollrace_state::spritebank_w)
-{
- m_spritebank = state;
-}
-
-void rollrace_state::backgroundpage_w(uint8_t data)
-{
- m_bkgpage = data & 0x1f;
- m_bkgflip = ( data & 0x80 ) >> 7;
-
- /* 0x80 flip vertical */
-}
-
-void rollrace_state::backgroundcolor_w(uint8_t data)
-{
- m_bkgcol = data;
-}
-
-void rollrace_state::flipy_w(uint8_t data)
-{
- m_flipy = data & 0x01;
- // bit 2: cleared at night stage in attract, unknown purpose
-}
-
-WRITE_LINE_MEMBER(rollrace_state::flipx_w)
-{
- m_flipx = state;
- m_fg_tilemap->set_flip(m_flipx ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
-}
-
-uint32_t rollrace_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- uint8_t *spriteram = m_spriteram;
- int offs;
- int sx, sy;
- const uint8_t *mem = memregion("user1")->base();
-
- /* fill in background colour*/
- bitmap.fill(m_bkgpen, cliprect);
-
- /* draw road */
- for (offs = 0x3ff; offs >= 0; offs--)
- {
- if(!(m_bkgflip))
- sy = ( 31 - offs / 32 ) ;
- else
- sy = ( offs / 32 ) ;
-
- sx = ( offs%32 ) ;
-
- if(m_flipx)
- sx = 31-sx ;
-
- if(m_flipy)
- sy = 31-sy ;
-
- m_gfxdecode->gfx(RA_BGCHAR_BASE)->transpen(bitmap,
- cliprect,
- mem[offs + ( m_bkgpage * 1024 )]
- + ((( mem[offs + 0x4000 + ( m_bkgpage * 1024 )] & 0xc0 ) >> 6 ) * 256 ) ,
- m_bkgcol,
- m_flipx,(m_bkgflip^m_flipy),
- sx*8,sy*8,0);
- }
-
- /* sprites */
- for ( offs = 0x80-4 ; offs >=0x0 ; offs -= 4)
- {
- int s_flipy = 0;
- int bank = 0;
-
- sy=spriteram[offs] - 16;
- sx=spriteram[offs+3] - 16;
-
- if(sx && sy)
- {
- if(m_flipx)
- sx = 224 - sx;
- if(m_flipy)
- sy = 224 - sy;
-
- if(spriteram[offs+1] & 0x80)
- s_flipy = 1;
-
- bank = (( spriteram[offs+1] & 0x40 ) >> 6 ) ;
-
- if(bank)
- bank += m_spritebank;
-
- m_gfxdecode->gfx( RA_SP_BASE + bank )->transpen(bitmap,cliprect,
- spriteram[offs+1] & 0x3f ,
- spriteram[offs+2] & 0x1f,
- m_flipx,!(s_flipy^m_flipy),
- sx,sy,0);
- }
- }
-
- m_fg_tilemap->draw(screen,bitmap,cliprect,0,0);
- return 0;
-}
diff --git a/src/mame/taito/ssrj.cpp b/src/mame/taito/ssrj.cpp
index 0c43a4e4508..a69ceff597d 100644
--- a/src/mame/taito/ssrj.cpp
+++ b/src/mame/taito/ssrj.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
+// copyright-holders: Tomasz Slanina
+
/***********************************
Super Speed Race Jr (c) 1985 Taito
driver by Tomasz Slanina
@@ -31,13 +32,313 @@ HW info :
************************************/
#include "emu.h"
-#include "ssrj.h"
#include "cpu/z80/z80.h"
#include "sound/ay8910.h"
+#include "video/bufsprite.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+
+namespace {
+
+class ssrj_state : public driver_device
+{
+public:
+ ssrj_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_gfxdecode(*this, "gfxdecode"),
+ m_palette(*this, "palette"),
+ m_buffered_spriteram(*this, "scrollram"),
+ m_vram(*this, "vram%u", 1U),
+ m_in1(*this, "IN1")
+ { }
+
+ void ssrj(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+ virtual void video_start() override;
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<palette_device> m_palette;
+ required_device<buffered_spriteram8_device> m_buffered_spriteram;
+
+ required_shared_ptr_array<uint8_t, 4> m_vram;
+
+ required_ioport m_in1;
+
+ int16_t m_oldport = 0;
+ tilemap_t *m_tilemap[4]{};
+
+ uint8_t wheel_r();
+ template <uint8_t Which> void vram_w(offs_t offset, uint8_t data);
+
+ template <uint8_t Which> TILE_GET_INFO_MEMBER(get_tile_info);
+
+ void palette(palette_device &palette) const;
+
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(screen_vblank);
+ void draw_objects(bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void prg_map(address_map &map);
+};
+
+
+// video
+
+
+template <uint8_t Which>
+void ssrj_state::vram_w(offs_t offset, uint8_t data)
+{
+ m_vram[Which][offset] = data;
+ m_tilemap[Which]->mark_tile_dirty(offset >> 1);
+}
+
+template <uint8_t Which>
+TILE_GET_INFO_MEMBER(ssrj_state::get_tile_info)
+{
+ int const code = m_vram[Which][tile_index << 1] + (m_vram[Which][(tile_index << 1) + 1] << 8);
+ tileinfo.set(0,
+ code & 0x3ff,
+ ((code >> 12) & 0x3) + Which * 4,
+ ((code & 0x8000) ? TILE_FLIPY : 0) |( (code & 0x4000) ? TILE_FLIPX : 0));
+}
+
+/*
+TODO: This table is nowhere near as accurate. If you bother, here's how colors should be:
+-"START" sign is red with dark blue background.
+-Sidewalk is yellow-ish.
+-first opponents have swapped colors (blue/yellow instead of yellow/blue)
+-after the first stage, houses have red/white colors.
+*/
+
+static constexpr rgb_t fakecols[4 * 4][8] =
+{
+{{0x00,0x00,0x00},
+ {42,87,140},
+ {0,0,0},
+ {33,75,160},
+ {0xff,0xff,0xff},
+ {37,56,81},
+ {0x1f,0x1f,0x2f},
+ {55,123,190}},
+
+{{0x00,0x00,0x00},
+ {0x00,99,41},
+ {0x00,0x00,0xff},
+ {0x00,0xff,0},
+ {255,255,255},
+ {0xff,0x00,0x00},
+ {0,45,105},
+ {0xff,0xff,0}},
+
+
+{{0x00,0x00,0x00},
+ {0x00,0x20,0x00},
+ {0x00,0x40,0x00},
+ {0x00,0x60,0x00},
+ {0x00,0x80,0x00},
+ {0x00,0xa0,0x00},
+ {0x00,0xc0,0x00},
+ {0x00,0xf0,0x00}},
+
+ {{0x00,0x00,0x00},
+ {0x20,0x00,0x20},
+ {0x40,0x00,0x40},
+ {0x60,0x00,0x60},
+ {0x80,0x00,0x80},
+ {0xa0,0x00,0xa0},
+ {0xc0,0x00,0xc0},
+ {0xf0,0x00,0xf0}},
+
+{{0x00,0x00,0x00},
+ {0xff,0x00,0x00},
+ {0x7f,0x00,0x00},
+ {0x00,0x00,0x00},
+ {0x00,0x00,0x00},
+ {0xaf,0x00,0x00},
+ {0xff,0xff,0xff},
+ {0xff,0x7f,0x7f}},
+
+{{0x00,0x00,0x00},
+ {0x20,0x20,0x20},
+ {0x40,0x40,0x40},
+ {0x60,0x60,0x60},
+ {0x80,0x80,0x80},
+ {0xa0,0xa0,0xa0},
+ {0xc0,0xc0,0xc0},
+ {0xf0,0xf0,0xf0}},
+
+{{0x00,0x00,0x00},
+ {0x20,0x20,0x20},
+ {0x40,0x40,0x40},
+ {0x60,0x60,0x60},
+ {0x80,0x80,0x80},
+ {0xa0,0xa0,0xa0},
+ {0xc0,0xc0,0xc0},
+ {0xf0,0xf0,0xf0}},
+
+{{0x00,0x00,0x00},
+ {0xff,0x00,0x00},
+ {0x00,0x00,0x9f},
+ {0x60,0x60,0x60},
+ {0x00,0x00,0x00},
+ {0xff,0xff,0x00},
+ {0x00,0xff,0x00},
+ {0xff,0xff,0xff}},
+
+{
+ {0x00,0x00,0x00},
+ {0x00,0x00,0xff},
+ {0x00,0x00,0x7f},
+ {0x00,0x00,0x00},
+ {0x00,0x00,0x00},
+ {0x00,0x00,0xaf},
+ {0xff,0xff,0xff},
+ {0x7f,0x7f,0xff}},
+
+{{0x00,0x00,0x00},
+ {0xff,0xff,0x00},
+ {0x7f,0x7f,0x00},
+ {0x00,0x00,0x00},
+ {0x00,0x00,0x00},
+ {0xaf,0xaf,0x00},
+ {0xff,0xff,0xff},
+ {0xff,0xff,0x7f}},
+
+{{0x00,0x00,0x00},
+ {0x00,0xff,0x00},
+ {0x00,0x7f,0x00},
+ {0x00,0x00,0x00},
+ {0x00,0x00,0x00},
+ {0x00,0xaf,0x00},
+ {0xff,0xff,0xff},
+ {0x7f,0xff,0x7f}},
+
+{{0x00,0x00,0x00},
+ {0x20,0x20,0x20},
+ {0x40,0x40,0x40},
+ {0x60,0x60,0x60},
+ {0x80,0x80,0x80},
+ {0xa0,0xa0,0xa0},
+ {0xc0,0xc0,0xc0},
+ {0xf0,0xf0,0xf0}},
+
+{{0x00,0x00,0x00},
+ {0x20,0x20,0x20},
+ {0x40,0x40,0x40},
+ {0x60,0x60,0x60},
+ {0x80,0x80,0x80},
+ {0xa0,0xa0,0xa0},
+ {0xc0,0xc0,0xc0},
+ {0xf0,0xf0,0xf0}},
+
+{{0x00,0x00,0x00},
+ {0x20,0x20,0x20},
+ {0x40,0x40,0x40},
+ {0x60,0x60,0x60},
+ {0x80,0x80,0x80},
+ {0xa0,0xa0,0xa0},
+ {0xc0,0xc0,0xc0},
+ {0xf0,0xf0,0xf0}},
+
+{{0x00,0x00,0x00},
+ {0x20,0x20,0x20},
+ {0x40,0x40,0x40},
+ {0x60,0x60,0x60},
+ {0x80,0x80,0x80},
+ {0xa0,0xa0,0xa0},
+ {0xc0,0xc0,0xc0},
+ {0xf0,0xf0,0xf0}},
+
+{
+ {0x00,0x00,0x00},
+ {0xff,0xaf,0xaf},
+ {0x00,0x00,0xff},
+ {0xff,0xff,0xff},
+ {0x00,0x00,0x00},
+ {0xff,0x50,0x50},
+ {0xff,0xff,0x00},
+ {0x00,0xff,0x00}
+}
+
+};
+
+void ssrj_state::video_start()
+{
+ m_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ssrj_state::get_tile_info<0>)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
+ m_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ssrj_state::get_tile_info<1>)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
+ m_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ssrj_state::get_tile_info<3>)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
+ m_tilemap[1]->set_transparent_pen(0);
+ m_tilemap[3]->set_transparent_pen(0);
+}
+
+
+void ssrj_state::draw_objects(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ uint8_t const *buffered_spriteram = m_buffered_spriteram->buffer();
+
+ for (int i = 0; i < 6; i++)
+ {
+ int const y = buffered_spriteram[0x80 + 20 * i];
+ int x = buffered_spriteram[0x80 + 20 * i + 2];
+ if (!buffered_spriteram[0x80 + 20 * i + 3])
+ {
+ for (int k = 0; k < 5; k++, x += 8)
+ {
+ for (int j = 0; j < 0x20; j++)
+ {
+ int const offs = (i * 5 + k) * 64 + (31 - j) * 2;
+
+ int const code = m_vram[2][offs] + 256 * m_vram[2][offs + 1];
+ m_gfxdecode->gfx(0)->transpen(bitmap,
+ cliprect,
+ code & 1023,
+ ((code >> 12) & 0x3) + 8,
+ code & 0x4000,
+ code & 0x8000,
+ x,
+ (247 - (y + (j << 3))) & 0xff,
+ 0);
+ }
+ }
+ }
+ }
+}
+
+
+void ssrj_state::palette(palette_device &palette) const
+{
+ for (int i = 0; i < 4 * 4; i++)
+ for (int j = 0; j < 8; j++)
+ palette.set_pen_color(i * 8 + j, fakecols[i][j]);
+}
+
+uint32_t ssrj_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ uint8_t const *buffered_spriteram = m_buffered_spriteram->live();
+ m_tilemap[0]->set_scrollx(0, 0xff - buffered_spriteram[2]);
+ m_tilemap[0]->set_scrolly(0, buffered_spriteram[0]);
+ m_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
+ draw_objects(bitmap, cliprect);
+ m_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
+
+ if (m_buffered_spriteram->live()[0x101] == 0xb) m_tilemap[3]->draw(screen, bitmap, cliprect, 0, 0); // hack to display 4th tilemap
+ return 0;
+}
+
+
+// machine
void ssrj_state::machine_start()
{
@@ -48,36 +349,36 @@ void ssrj_state::machine_reset()
{
uint8_t *rom = memregion("maincpu")->base();
- memset(&rom[0xc000], 0 ,0x3fff); /* req for some control types */
+ memset(&rom[0xc000], 0 ,0x3fff); // req for some control types
m_oldport = 0x80;
}
uint8_t ssrj_state::wheel_r()
{
- int port = ioport("IN1")->read() - 0x80;
- int retval = port - m_oldport;
+ int const port = m_in1->read() - 0x80;
+ int const retval = port - m_oldport;
m_oldport = port;
return retval;
}
-void ssrj_state::ssrj_map(address_map &map)
+void ssrj_state::prg_map(address_map &map)
{
map(0x0000, 0x7fff).rom();
- map(0xc000, 0xc7ff).ram().w(FUNC(ssrj_state::vram1_w)).share("vram1");
- map(0xc800, 0xcfff).ram().w(FUNC(ssrj_state::vram2_w)).share("vram2");
- map(0xd000, 0xd7ff).ram().share("vram3");
- map(0xd800, 0xdfff).ram().w(FUNC(ssrj_state::vram4_w)).share("vram4");
+ map(0xc000, 0xc7ff).ram().w(FUNC(ssrj_state::vram_w<0>)).share(m_vram[0]);
+ map(0xc800, 0xcfff).ram().w(FUNC(ssrj_state::vram_w<1>)).share(m_vram[1]);
+ map(0xd000, 0xd7ff).ram().share(m_vram[2]);
+ map(0xd800, 0xdfff).ram().w(FUNC(ssrj_state::vram_w<3>)).share(m_vram[3]);
map(0xe000, 0xe7ff).ram();
map(0xe800, 0xefff).ram().share("scrollram");
map(0xf000, 0xf000).portr("IN0");
map(0xf001, 0xf001).r(FUNC(ssrj_state::wheel_r));
map(0xf002, 0xf002).portr("IN2");
- map(0xf003, 0xf003).nopw(); /* unknown */
+ map(0xf003, 0xf003).nopw(); // unknown
map(0xf401, 0xf401).r("aysnd", FUNC(ay8910_device::data_r));
map(0xf400, 0xf401).w("aysnd", FUNC(ay8910_device::address_data_w));
- map(0xf800, 0xf800).nopw(); /* wheel ? */
- map(0xfc00, 0xfc00).nopw(); /* unknown */
+ map(0xf800, 0xf800).nopw(); // wheel ?
+ map(0xfc00, 0xfc00).nopw(); // unknown
}
static INPUT_PORTS_START( ssrj )
@@ -91,7 +392,7 @@ static INPUT_PORTS_START( ssrj )
PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(50) PORT_KEYDELTA(4) PORT_REVERSE
PORT_START("IN2")
- PORT_BIT( 0xf, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IN3", 0x30, EQUALS, 0x00) /* code @ $eef, tested when controls != type1 */
+ PORT_BIT( 0xf, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IN3", 0x30, EQUALS, 0x00) // code @ $eef, tested when controls != type1
PORT_BIT( 0x1, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("IN3", 0x30, NOTEQUALS, 0x00) PORT_NAME("Start (Easy)")
PORT_BIT( 0x2, IP_ACTIVE_LOW, IPT_START2 ) PORT_CONDITION("IN3", 0x30, NOTEQUALS, 0x00) PORT_NAME("Start (Normal)")
PORT_BIT( 0x4, IP_ACTIVE_LOW, IPT_START3 ) PORT_CONDITION("IN3", 0x30, NOTEQUALS, 0x00) PORT_NAME("Start (Difficult)")
@@ -120,53 +421,55 @@ static INPUT_PORTS_START( ssrj )
PORT_DIPNAME( 0x08, 0x08, "Freeze" )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x30, 0x00, DEF_STR( Controls ) ) /* Type 1 has no start button and uses difficulty DSW, type 2-4 have 4 start buttons that determine difficulty. MT07492 for more. */
+ PORT_DIPNAME( 0x30, 0x00, DEF_STR( Controls ) ) // Type 1 has no start button and uses difficulty DSW, type 2-4 have 4 start buttons that determine difficulty. MT07492 for more.
PORT_DIPSETTING( 0x00, "Type 1" )
PORT_DIPSETTING( 0x10, "Type 2" )
PORT_DIPSETTING( 0x20, "Type 3" )
PORT_DIPSETTING( 0x30, "Type 4" )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* sometimes hangs after game over ($69b) */
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) // sometimes hangs after game over ($69b)
INPUT_PORTS_END
static const gfx_layout charlayout =
{
- 8,8, /* 8*8 characters */
- RGN_FRAC(1,3), /* 1024 characters */
- 3, /* 3 bits per pixel */
- { 0, RGN_FRAC(2,3), RGN_FRAC(1,3) }, /* the bitplanes are separated */
+ 8,8, // 8*8 characters
+ RGN_FRAC(1,3), // 1024 characters
+ 3, // 3 bits per pixel
+ { 0, RGN_FRAC(2,3), RGN_FRAC(1,3) }, // the bitplanes are separated
{ 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
- 8*8 /* every char takes 8 consecutive bytes */
+ 8*8 // every char takes 8 consecutive bytes
};
static GFXDECODE_START( gfx_ssrj )
- GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 0x10 )
+ GFXDECODE_ENTRY( "gfx", 0, charlayout, 0, 0x10 )
GFXDECODE_END
void ssrj_state::ssrj(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, 8000000/2);
- m_maincpu->set_addrmap(AS_PROGRAM, &ssrj_state::ssrj_map);
+ // basic machine hardware
+ Z80(config, m_maincpu, 8000000 / 2);
+ m_maincpu->set_addrmap(AS_PROGRAM, &ssrj_state::prg_map);
m_maincpu->set_vblank_int("screen", FUNC(ssrj_state::irq0_line_hold));
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(60);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(40*8, 32*8);
screen.set_visarea(0*8, 34*8-1, 1*8, 31*8-1); // unknown res
screen.set_screen_update(FUNC(ssrj_state::screen_update));
- screen.screen_vblank().set(FUNC(ssrj_state::screen_vblank));
+ screen.screen_vblank().set(m_buffered_spriteram, FUNC(buffered_spriteram8_device::vblank_copy_rising));
screen.set_palette(m_palette);
GFXDECODE(config, m_gfxdecode, m_palette, gfx_ssrj);
- PALETTE(config, m_palette, FUNC(ssrj_state::ssrj_palette), 128);
+ PALETTE(config, m_palette, FUNC(ssrj_state::palette), 128);
- /* sound hardware */
+ BUFFERED_SPRITERAM8(config, m_buffered_spriteram);
+
+ // sound hardware
SPEAKER(config, "mono").front_center();
- ay8910_device &aysnd(AY8910(config, "aysnd", 8000000/5));
+ ay8910_device &aysnd(AY8910(config, "aysnd", 8000000 / 5));
aysnd.port_b_read_callback().set_ioport("IN3");
aysnd.add_route(ALL_OUTPUTS, "mono", 0.30);
}
@@ -182,7 +485,7 @@ ROM_START( ssrj )
ROM_LOAD( "a40-01.bin", 0x0000, 0x4000, CRC(1ff7dbff) SHA1(a9e676ee087141d62f880cd98e7748db1e6e9461) )
ROM_LOAD( "a40-02.bin", 0x4000, 0x4000, CRC(bbb36f9f) SHA1(9f85bac639d18ee932273a6c00b36ac969e69bb8) )
- ROM_REGION( 0x6000, "gfx1", 0 )
+ ROM_REGION( 0x6000, "gfx", 0 )
ROM_LOAD( "a40-03.bin", 0x0000, 0x2000, CRC(3753182a) SHA1(3eda34f967563b11416344da87b7be46cbecff2b) )
ROM_LOAD( "a40-04.bin", 0x2000, 0x2000, CRC(96471816) SHA1(e24b690085602b8bde079e596c2879deab128c83) )
ROM_LOAD( "a40-05.bin", 0x4000, 0x2000, CRC(dce9169e) SHA1(2cdda1453b2913fad931788e1db0bc01ce923a04) )
@@ -191,4 +494,7 @@ ROM_START( ssrj )
ROM_LOAD( "proms", 0x0000, 0x0100, NO_DUMP )
ROM_END
-GAME( 1985, ssrj, 0, ssrj, ssrj, ssrj_state, empty_init, ROT90, "Taito Corporation", "Super Speed Race Junior (Japan)", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
+} // anonymous namespace
+
+
+GAME( 1985, ssrj, 0, ssrj, ssrj, ssrj_state, empty_init, ROT90, "Taito Corporation", "Super Speed Race Junior (Japan)", MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/taito/ssrj.h b/src/mame/taito/ssrj.h
deleted file mode 100644
index 4794e9b4a8e..00000000000
--- a/src/mame/taito/ssrj.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
-#ifndef MAME_INCLUDES_SSRJ_H
-#define MAME_INCLUDES_SSRJ_H
-
-#pragma once
-
-#include "emupal.h"
-#include "tilemap.h"
-
-class ssrj_state : public driver_device
-{
-public:
- ssrj_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_vram1(*this, "vram1"),
- m_vram2(*this, "vram2"),
- m_vram3(*this, "vram3"),
- m_vram4(*this, "vram4"),
- m_scrollram(*this, "scrollram")
- { }
-
- void ssrj(machine_config &config);
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
-
-private:
- required_device<cpu_device> m_maincpu;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
-
- required_shared_ptr<uint8_t> m_vram1;
- required_shared_ptr<uint8_t> m_vram2;
- required_shared_ptr<uint8_t> m_vram3;
- required_shared_ptr<uint8_t> m_vram4;
- required_shared_ptr<uint8_t> m_scrollram;
-
- int m_oldport = 0;
- tilemap_t *m_tilemap1 = nullptr;
- tilemap_t *m_tilemap2 = nullptr;
- tilemap_t *m_tilemap4 = nullptr;
- std::unique_ptr<uint8_t[]> m_buffer_spriteram;
-
- uint8_t wheel_r();
- void vram1_w(offs_t offset, uint8_t data);
- void vram2_w(offs_t offset, uint8_t data);
- void vram4_w(offs_t offset, uint8_t data);
-
- TILE_GET_INFO_MEMBER(get_tile_info1);
- TILE_GET_INFO_MEMBER(get_tile_info2);
- TILE_GET_INFO_MEMBER(get_tile_info4);
-
- void ssrj_palette(palette_device &palette) const;
-
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- DECLARE_WRITE_LINE_MEMBER(screen_vblank);
- void draw_objects(bitmap_ind16 &bitmap, const rectangle &cliprect );
-
- void ssrj_map(address_map &map);
-};
-
-#endif // MAME_INCLUDES_SSRJ_H
diff --git a/src/mame/taito/ssrj_v.cpp b/src/mame/taito/ssrj_v.cpp
deleted file mode 100644
index 8ee4ddabc15..00000000000
--- a/src/mame/taito/ssrj_v.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Tomasz Slanina
-#include "emu.h"
-#include "ssrj.h"
-
-/* tilemap 1 */
-
-void ssrj_state::vram1_w(offs_t offset, uint8_t data)
-{
- m_vram1[offset] = data;
- m_tilemap1->mark_tile_dirty(offset>>1);
-}
-
-TILE_GET_INFO_MEMBER(ssrj_state::get_tile_info1)
-{
- int code;
- code = m_vram1[tile_index<<1] + (m_vram1[(tile_index<<1)+1]<<8);
- tileinfo.set(0,
- code&0x3ff,
- (code>>12)&0x3,
- ((code & 0x8000) ? TILE_FLIPY:0) |( (code & 0x4000) ? TILE_FLIPX:0) );
-}
-
-/* tilemap 2 */
-
-void ssrj_state::vram2_w(offs_t offset, uint8_t data)
-{
- m_vram2[offset] = data;
- m_tilemap2->mark_tile_dirty(offset>>1);
-}
-
-TILE_GET_INFO_MEMBER(ssrj_state::get_tile_info2)
-{
- int code;
- code = m_vram2[tile_index<<1] + (m_vram2[(tile_index<<1)+1]<<8);
- tileinfo.set(0,
- code&0x3ff,
- ((code>>12)&0x3)+4,
- ((code & 0x8000) ? TILE_FLIPY:0) |( (code & 0x4000) ? TILE_FLIPX:0) );
-}
-
-/* tilemap 4 */
-
-void ssrj_state::vram4_w(offs_t offset, uint8_t data)
-{
- m_vram4[offset] = data;
- m_tilemap4->mark_tile_dirty(offset>>1);
-}
-
-TILE_GET_INFO_MEMBER(ssrj_state::get_tile_info4)
-{
- int code;
- code = m_vram4[tile_index<<1] + (m_vram4[(tile_index<<1)+1]<<8);
- tileinfo.set(0,
- code&0x3ff,
- ((code>>12)&0x3)+12,
- ((code & 0x8000) ? TILE_FLIPY:0) |( (code & 0x4000) ? TILE_FLIPX:0) );
-}
-
-
-/*
-TODO: This table is nowhere near as accurate. If you bother, here's how colors should be:
--"START" sign is red with dark blue background.
--Sidewalk is yellow-ish.
--first opponents have swapped colors (blue/yellow instead of yellow/blue)
--after the first stage, houses have red/white colors.
-*/
-
-static constexpr rgb_t fakecols[4 * 4][8] =
-{
-{{0x00,0x00,0x00},
- {42,87,140},
- {0,0,0},
- {33,75,160},
- {0xff,0xff,0xff},
- {37,56,81},
- {0x1f,0x1f,0x2f},
- {55,123,190}},
-
-{{0x00,0x00,0x00},
- {0x00,99,41},
- {0x00,0x00,0xff},
- {0x00,0xff,0},
- {255,255,255},
- {0xff,0x00,0x00},
- {0,45,105},
- {0xff,0xff,0}},
-
-
-{{0x00,0x00,0x00},
- {0x00,0x20,0x00},
- {0x00,0x40,0x00},
- {0x00,0x60,0x00},
- {0x00,0x80,0x00},
- {0x00,0xa0,0x00},
- {0x00,0xc0,0x00},
- {0x00,0xf0,0x00}},
-
- {{0x00,0x00,0x00},
- {0x20,0x00,0x20},
- {0x40,0x00,0x40},
- {0x60,0x00,0x60},
- {0x80,0x00,0x80},
- {0xa0,0x00,0xa0},
- {0xc0,0x00,0xc0},
- {0xf0,0x00,0xf0}},
-
-{{0x00,0x00,0x00},
- {0xff,0x00,0x00},
- {0x7f,0x00,0x00},
- {0x00,0x00,0x00},
- {0x00,0x00,0x00},
- {0xaf,0x00,0x00},
- {0xff,0xff,0xff},
- {0xff,0x7f,0x7f}},
-
-{{0x00,0x00,0x00},
- {0x20,0x20,0x20},
- {0x40,0x40,0x40},
- {0x60,0x60,0x60},
- {0x80,0x80,0x80},
- {0xa0,0xa0,0xa0},
- {0xc0,0xc0,0xc0},
- {0xf0,0xf0,0xf0}},
-
-{{0x00,0x00,0x00},
- {0x20,0x20,0x20},
- {0x40,0x40,0x40},
- {0x60,0x60,0x60},
- {0x80,0x80,0x80},
- {0xa0,0xa0,0xa0},
- {0xc0,0xc0,0xc0},
- {0xf0,0xf0,0xf0}},
-
-{{0x00,0x00,0x00},
- {0xff,0x00,0x00},
- {0x00,0x00,0x9f},
- {0x60,0x60,0x60},
- {0x00,0x00,0x00},
- {0xff,0xff,0x00},
- {0x00,0xff,0x00},
- {0xff,0xff,0xff}},
-
-{
- {0x00,0x00,0x00},
- {0x00,0x00,0xff},
- {0x00,0x00,0x7f},
- {0x00,0x00,0x00},
- {0x00,0x00,0x00},
- {0x00,0x00,0xaf},
- {0xff,0xff,0xff},
- {0x7f,0x7f,0xff}},
-
-{{0x00,0x00,0x00},
- {0xff,0xff,0x00},
- {0x7f,0x7f,0x00},
- {0x00,0x00,0x00},
- {0x00,0x00,0x00},
- {0xaf,0xaf,0x00},
- {0xff,0xff,0xff},
- {0xff,0xff,0x7f}},
-
-{{0x00,0x00,0x00},
- {0x00,0xff,0x00},
- {0x00,0x7f,0x00},
- {0x00,0x00,0x00},
- {0x00,0x00,0x00},
- {0x00,0xaf,0x00},
- {0xff,0xff,0xff},
- {0x7f,0xff,0x7f}},
-
-{{0x00,0x00,0x00},
- {0x20,0x20,0x20},
- {0x40,0x40,0x40},
- {0x60,0x60,0x60},
- {0x80,0x80,0x80},
- {0xa0,0xa0,0xa0},
- {0xc0,0xc0,0xc0},
- {0xf0,0xf0,0xf0}},
-
-{{0x00,0x00,0x00},
- {0x20,0x20,0x20},
- {0x40,0x40,0x40},
- {0x60,0x60,0x60},
- {0x80,0x80,0x80},
- {0xa0,0xa0,0xa0},
- {0xc0,0xc0,0xc0},
- {0xf0,0xf0,0xf0}},
-
-{{0x00,0x00,0x00},
- {0x20,0x20,0x20},
- {0x40,0x40,0x40},
- {0x60,0x60,0x60},
- {0x80,0x80,0x80},
- {0xa0,0xa0,0xa0},
- {0xc0,0xc0,0xc0},
- {0xf0,0xf0,0xf0}},
-
-{{0x00,0x00,0x00},
- {0x20,0x20,0x20},
- {0x40,0x40,0x40},
- {0x60,0x60,0x60},
- {0x80,0x80,0x80},
- {0xa0,0xa0,0xa0},
- {0xc0,0xc0,0xc0},
- {0xf0,0xf0,0xf0}},
-
-{
- {0x00,0x00,0x00},
- {0xff,0xaf,0xaf},
- {0x00,0x00,0xff},
- {0xff,0xff,0xff},
- {0x00,0x00,0x00},
- {0xff,0x50,0x50},
- {0xff,0xff,0x00},
- {0x00,0xff,0x00}
-}
-
-};
-
-void ssrj_state::video_start()
-{
- m_tilemap1 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ssrj_state::get_tile_info1)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
- m_tilemap2 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ssrj_state::get_tile_info2)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
- m_tilemap4 = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ssrj_state::get_tile_info4)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
- m_tilemap2->set_transparent_pen(0);
- m_tilemap4->set_transparent_pen(0);
-
- m_buffer_spriteram = std::make_unique<uint8_t[]>(0x0800);
-}
-
-
-void ssrj_state::draw_objects(bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- int i,j,k,x,y;
-
- for(i=0;i<6;i++)
- {
- y = m_buffer_spriteram[0x80+20*i];
- x = m_buffer_spriteram[0x80+20*i+2];
- if (!m_buffer_spriteram[0x80+20*i+3])
- {
- for(k=0;k<5;k++,x+=8)
- {
- for(j=0;j<0x20;j++)
- {
- int code;
- int offs = (i * 5 + k) * 64 + (31 - j) * 2;
-
- code = m_vram3[offs] + 256 * m_vram3[offs + 1];
- m_gfxdecode->gfx(0)->transpen(bitmap,
- cliprect,
- code&1023,
- ((code>>12)&0x3)+8,
- code&0x4000,
- code&0x8000,
- x,
- (247-(y+(j<<3)))&0xff,
- 0);
- }
- }
- }
- }
-}
-
-
-void ssrj_state::ssrj_palette(palette_device &palette) const
-{
- for (int i = 0; i < 4*4; i++)
- for (int j = 0; j < 8; j++)
- palette.set_pen_color(i*8 + j, fakecols[i][j]);
-}
-
-uint32_t ssrj_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- m_tilemap1->set_scrollx(0, 0xff-m_scrollram[2] );
- m_tilemap1->set_scrolly(0, m_scrollram[0] );
- m_tilemap1->draw(screen, bitmap, cliprect, 0, 0);
- draw_objects(bitmap, cliprect);
- m_tilemap2->draw(screen, bitmap, cliprect, 0, 0);
-
- if (m_scrollram[0x101] == 0xb) m_tilemap4->draw(screen, bitmap, cliprect, 0, 0);/* hack to display 4th tilemap */
- return 0;
-}
-
-WRITE_LINE_MEMBER(ssrj_state::screen_vblank)
-{
- // rising edge
- if (state)
- {
- memcpy(m_buffer_spriteram.get(), m_scrollram, 0x800);
- }
-}
diff --git a/src/mame/taito/volfied.cpp b/src/mame/taito/volfied.cpp
index 5d9b71e1984..9a897e106f2 100644
--- a/src/mame/taito/volfied.cpp
+++ b/src/mame/taito/volfied.cpp
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, Nicola Salmoria
+// copyright-holders: Bryan McPhail, Nicola Salmoria
+
/******************************************************************
Volfied (c) 1989 Taito Corporation
@@ -46,22 +47,197 @@ Stephh's notes (based on the game M68000 code and some tests) :
********************************************************************/
#include "emu.h"
-#include "volfied.h"
+
+#include "pc090oj.h"
+#include "taitocchip.h"
#include "taitoipt.h"
#include "taitosnd.h"
#include "cpu/m68000/m68000.h"
#include "cpu/z80/z80.h"
+#include "machine/timer.h"
#include "sound/ymopn.h"
+
#include "emupal.h"
+#include "screen.h"
#include "speaker.h"
-/* Define clocks based on actual OSC on the PCB */
+namespace {
+
+class volfied_state : public driver_device
+{
+public:
+ volfied_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_video_ram(*this, "video_ram"),
+ m_maincpu(*this, "maincpu"),
+ m_audiocpu(*this, "audiocpu"),
+ m_cchip(*this, "cchip"),
+ m_pc090oj(*this, "pc090oj"),
+ m_screen(*this, "screen"),
+ m_cchip_irq_clear(*this, "cchip_irq_clear")
+ { }
+
+ void volfied(machine_config &config);
+
+protected:
+ virtual void video_start() override;
+
+private:
+ void video_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ void video_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ uint16_t video_ctrl_r();
+ void video_mask_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
+ void counters_w(uint8_t data);
+ void colpri_cb(uint32_t &sprite_colbank, uint32_t &pri_mask, uint16_t sprite_ctrl);
+ uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ INTERRUPT_GEN_MEMBER(interrupt);
+ TIMER_DEVICE_CALLBACK_MEMBER(cchip_irq_clear_cb);
+
+ void refresh_pixel_layer(bitmap_ind16 &bitmap);
+
+ void main_map(address_map &map);
+ void z80_map(address_map &map);
+
+ // memory pointers
+ required_shared_ptr<uint16_t> m_video_ram;
+
+ // video-related
+ uint16_t m_video_ctrl = 0;
+ uint16_t m_video_mask = 0;
+
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<cpu_device> m_audiocpu;
+ required_device<taito_cchip_device> m_cchip;
+ required_device<pc090oj_device> m_pc090oj;
+ required_device<screen_device> m_screen;
+ required_device<timer_device> m_cchip_irq_clear;
+};
+
+
+// video
+
+/******************************************************
+ INITIALISATION AND CLEAN-UP
+******************************************************/
+
+void volfied_state::video_start()
+{
+ m_video_ctrl = 0;
+ m_video_mask = 0;
+
+ save_item(NAME(m_video_ctrl));
+ save_item(NAME(m_video_mask));
+}
+
+
+/*******************************************************
+ READ AND WRITE HANDLERS
+*******************************************************/
+
+void volfied_state::video_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ mem_mask &= m_video_mask;
+
+ COMBINE_DATA(&m_video_ram[offset]);
+}
+
+void volfied_state::video_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ COMBINE_DATA(&m_video_ctrl);
+}
+
+uint16_t volfied_state::video_ctrl_r()
+{
+ /* Could this be some kind of hardware collision detection? If bit 6 is
+ set the game will check for collisions with the large enemy, whereas
+ bit 5 does the same for small enemies. Bit 7 is also used although
+ its purpose is unclear. This register is usually read during a VBI
+ and stored in work RAM for later use. */
+
+ return 0x60;
+}
+
+void volfied_state::video_mask_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ COMBINE_DATA(&m_video_mask);
+}
+
+void volfied_state::colpri_cb(uint32_t &sprite_colbank, uint32_t &pri_mask, uint16_t sprite_ctrl)
+{
+ sprite_colbank = 0x100 | ((sprite_ctrl & 0x3c) << 2);
+ pri_mask = 0; // sprites over everything
+}
+
+
+/*******************************************************
+ SCREEN REFRESH
+*******************************************************/
+
+void volfied_state::refresh_pixel_layer(bitmap_ind16 &bitmap)
+{
+ /*********************************************************
+
+ VIDEO RAM has 2 screens x 256 rows x 512 columns x 16 bits
+
+ x--------------- select image
+ -x-------------- ? (used for 3-D corners)
+ --x------------- ? (used for 3-D walls)
+ ---xxxx--------- image B
+ -------xxx------ palette index bits #8 to #A
+ ----------x----- ?
+ -----------x---- ?
+ ------------xxxx image A
+
+ '3d' corners & walls are made using unknown bits for each
+ line the player draws. However, on the PCB they just
+ appear as solid black. Perhaps it was prototype code that
+ was turned off at some stage.
+
+ *********************************************************/
+
+ uint16_t* p = m_video_ram.target();
+ int const width = m_screen->width();
+ int const height = m_screen->height();
+
+ if (m_video_ctrl & 1)
+ p += 0x20000;
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 1; x < width + 1; x++) // Hmm, 1 pixel offset is needed to align properly with sprites
+ {
+ int color = (p[x] << 2) & 0x700;
+
+ if (p[x] & 0x8000)
+ {
+ color |= 0x800 | ((p[x] >> 9) & 0xf);
+
+ if (p[x] & 0x2000)
+ color &= ~0xf; // hack
+ }
+ else
+ color |= p[x] & 0xf;
+
+ bitmap.pix(y, x - 1) = color;
+ }
+
+ p += 512;
+ }
+}
+
+uint32_t volfied_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ screen.priority().fill(0, cliprect);
+ refresh_pixel_layer(bitmap);
+ m_pc090oj->draw_sprites(screen, bitmap, cliprect);
+ return 0;
+}
-#define CPU_CLOCK (XTAL(32'000'000) / 4) /* 8 MHz clock for 68000 */
-#define SOUND_CPU_CLOCK (XTAL(32'000'000) / 8) /* 4 MHz clock for Z80 sound CPU */
+// machine
/***********************************************************
MEMORY STRUCTURES
@@ -69,11 +245,11 @@ Stephh's notes (based on the game M68000 code and some tests) :
void volfied_state::main_map(address_map &map)
{
- map(0x000000, 0x03ffff).rom(); /* program */
- map(0x080000, 0x0fffff).rom(); /* tiles */
- map(0x100000, 0x103fff).ram(); /* main */
+ map(0x000000, 0x03ffff).rom(); // program
+ map(0x080000, 0x0fffff).rom(); // tiles
+ map(0x100000, 0x103fff).ram(); // main
map(0x200000, 0x203fff).rw(m_pc090oj, FUNC(pc090oj_device::word_r), FUNC(pc090oj_device::word_w));
- map(0x400000, 0x47ffff).rw(FUNC(volfied_state::video_ram_r), FUNC(volfied_state::video_ram_w));
+ map(0x400000, 0x47ffff).ram().w(FUNC(volfied_state::video_ram_w)).share(m_video_ram);
map(0x500000, 0x503fff).ram().w("palette", FUNC(palette_device::write16)).share("palette");
map(0x600000, 0x600001).w(FUNC(volfied_state::video_mask_w));
map(0x700000, 0x700001).w(m_pc090oj, FUNC(pc090oj_device::sprite_ctrl_w));
@@ -91,7 +267,7 @@ void volfied_state::z80_map(address_map &map)
map(0x8800, 0x8800).w("ciu", FUNC(pc060ha_device::slave_port_w));
map(0x8801, 0x8801).rw("ciu", FUNC(pc060ha_device::slave_comm_r), FUNC(pc060ha_device::slave_comm_w));
map(0x9000, 0x9001).rw("ymsnd", FUNC(ym2203_device::read), FUNC(ym2203_device::write));
- map(0x9800, 0x9800).nopw(); /* ? */
+ map(0x9800, 0x9800).nopw(); // ?
}
@@ -100,14 +276,14 @@ void volfied_state::z80_map(address_map &map)
***********************************************************/
static INPUT_PORTS_START( volfied )
- /* Z80 CPU -> 0x10002c ($2c,A5) */
+ // Z80 CPU -> 0x10002c ($2c,A5)
PORT_START("DSWA")
TAITO_MACHINE_COCKTAIL_LOC(SW1)
TAITO_COINAGE_WORLD_LOC(SW1)
- /* Z80 CPU -> 0x10002e ($2e,A5) */
+ // Z80 CPU -> 0x10002e ($2e,A5)
PORT_START("DSWB")
- PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:1,2") /* table at 0x003140 - 4 * 6 words - LSB first */
+ PORT_DIPNAME( 0x03, 0x03, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:1,2") // table at 0x003140 - 4 * 6 words - LSB first
PORT_DIPSETTING( 0x02, "20k 40k 120k 480k 2400k" )
PORT_DIPSETTING( 0x03, "50k 150k 600k 3000k" )
PORT_DIPSETTING( 0x01, "70k 280k 1400k" )
@@ -122,7 +298,7 @@ static INPUT_PORTS_START( volfied )
PORT_DIPSETTING( 0x20, "4" )
PORT_DIPSETTING( 0x10, "5" )
PORT_DIPSETTING( 0x00, "6" )
- PORT_DIPNAME( 0x40, 0x40, "32768 Lives (Cheat)" ) PORT_DIPLOCATION("SW2:7") /* code at 0x0015cc - Manual shows unused and OFF */
+ PORT_DIPNAME( 0x40, 0x40, "32768 Lives (Cheat)" ) PORT_DIPLOCATION("SW2:7") // code at 0x0015cc - Manual shows unused and OFF
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("SW2:8")
@@ -174,9 +350,9 @@ static INPUT_PORTS_START( volfiedu )
PORT_INCLUDE(volfied)
PORT_MODIFY("DSWA")
- TAITO_COINAGE_US_COIN_START_LOC(SW1) /* see notes */
- PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW1:7" ) /* see notes */
- PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW1:8" ) /* see notes */
+ TAITO_COINAGE_US_COIN_START_LOC(SW1) // see notes
+ PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW1:7" ) // see notes
+ PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW1:8" ) // see notes
INPUT_PORTS_END
static INPUT_PORTS_START( volfiedj )
@@ -191,14 +367,6 @@ INPUT_PORTS_END
MACHINE DRIVERS
***********************************************************/
-void volfied_state::machine_start()
-{
-}
-
-void volfied_state::machine_reset()
-{
-}
-
void volfied_state::counters_w(uint8_t data)
{
machine().bookkeeping().coin_lockout_w(1, data & 0x80);
@@ -222,15 +390,20 @@ TIMER_DEVICE_CALLBACK_MEMBER(volfied_state::cchip_irq_clear_cb)
void volfied_state::volfied(machine_config &config)
{
- /* basic machine hardware */
- M68000(config, m_maincpu, CPU_CLOCK); /* 8MHz */
+ // Define clocks based on actual OSC on the PCB
+
+ static constexpr XTAL CPU_CLOCK = (32_MHz_XTAL / 4); // 8 MHz clock for 68000
+ static constexpr XTAL SOUND_CPU_CLOCK = (32_MHz_XTAL / 8); // 4 MHz clock for Z80 sound CPU
+
+ // basic machine hardware
+ M68000(config, m_maincpu, CPU_CLOCK); // 8MHz
m_maincpu->set_addrmap(AS_PROGRAM, &volfied_state::main_map);
m_maincpu->set_vblank_int("screen", FUNC(volfied_state::interrupt));
- Z80(config, m_audiocpu, SOUND_CPU_CLOCK); /* 4MHz sound CPU, required to run the game */
+ Z80(config, m_audiocpu, SOUND_CPU_CLOCK); // 4MHz sound CPU, required to run the game
m_audiocpu->set_addrmap(AS_PROGRAM, &volfied_state::z80_map);
- TAITO_CCHIP(config, m_cchip, 20_MHz_XTAL/2); // 20MHz OSC next to C-Chip
+ TAITO_CCHIP(config, m_cchip, 20_MHz_XTAL / 2); // 20MHz OSC next to C-Chip
m_cchip->in_pa_callback().set_ioport("F00007");
m_cchip->in_pb_callback().set_ioport("F00009");
m_cchip->in_pc_callback().set_ioport("F0000B");
@@ -241,7 +414,7 @@ void volfied_state::volfied(machine_config &config)
TIMER(config, m_cchip_irq_clear).configure_generic(FUNC(volfied_state::cchip_irq_clear_cb));
- /* video hardware */
+ // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
@@ -254,12 +427,12 @@ void volfied_state::volfied(machine_config &config)
PC090OJ(config, m_pc090oj, 0);
m_pc090oj->set_palette("palette");
- m_pc090oj->set_colpri_callback(FUNC(volfied_state::volfied_colpri_cb));
+ m_pc090oj->set_colpri_callback(FUNC(volfied_state::colpri_cb));
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "mono").front_center();
- ym2203_device &ymsnd(YM2203(config, "ymsnd", 4000000));
+ ym2203_device &ymsnd(YM2203(config, "ymsnd", SOUND_CPU_CLOCK));
ymsnd.irq_handler().set_inputline(m_audiocpu, 0);
ymsnd.port_a_read_callback().set_ioport("DSWA");
ymsnd.port_b_read_callback().set_ioport("DSWB");
@@ -279,7 +452,7 @@ void volfied_state::volfied(machine_config &config)
***************************************************************************/
ROM_START( volfied )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code and tile data */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code and tile data
ROM_LOAD16_BYTE( "c04-12-1.30", 0x00000, 0x10000, CRC(afb6a058) SHA1(fca488e86725a0a673332afeb0002f0e77ef2dbf) )
ROM_LOAD16_BYTE( "c04-08-1.10", 0x00001, 0x10000, CRC(19f7e66b) SHA1(51b5d0d00ec398ed717154286bec24b05c3f81b8) )
ROM_LOAD16_BYTE( "c04-11-1.29", 0x20000, 0x10000, CRC(1aaf6e9b) SHA1(4be643283dc78eb57e9fe4c5afebdc427e4354e8) )
@@ -292,7 +465,7 @@ ROM_START( volfied )
ROM_REGION( 0x2000, "cchip:cchip_eprom", 0 )
ROM_LOAD( "cchip_c04-23", 0x0000, 0x2000, CRC(46b0b479) SHA1(73aa2267eb468c5aa5db67183047e9aef8321215) )
- ROM_REGION( 0xc0000, "pc090oj", 0 ) /* sprites 16x16 */
+ ROM_REGION( 0xc0000, "pc090oj", 0 ) // sprites 16x16
ROM_LOAD16_BYTE( "c04-16.2", 0x00000, 0x20000, CRC(8c2476ef) SHA1(972ddc8e47a669f1aeca67d02b4a0bed867ddb7d) )
ROM_LOAD16_BYTE( "c04-18.4", 0x00001, 0x20000, CRC(7665212c) SHA1(b816ac2a95ee273aaf90991f53766d7f0d5d9238) )
ROM_LOAD16_BYTE( "c04-15.1", 0x40000, 0x20000, CRC(7c50b978) SHA1(aa9cad5f09f5d9dceaf4e06bcd347f1d5d02d292) )
@@ -302,16 +475,16 @@ ROM_START( volfied )
ROM_LOAD16_BYTE( "c04-09.14", 0x80001, 0x10000, CRC(c78cf057) SHA1(097982e57b1d20fbdf21986c23684adefe6f1ce1) )
ROM_RELOAD ( 0xa0001, 0x10000 )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "c04-06.71", 0x0000, 0x8000, CRC(b70106b2) SHA1(d71062f9d9b11492e13fc93982b95883f564f902) )
- ROM_REGION( 0x00400, "proms", 0 ) /* unused PROMs */
- ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) /* PROM type is a MB7116H or compatible */
- ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) /* PROM type is a MB7124E or compatible */
+ ROM_REGION( 0x00400, "proms", 0 ) // unused
+ ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) // PROM type is a MB7116H or compatible
+ ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) // PROM type is a MB7124E or compatible
ROM_END
ROM_START( volfiedo )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code and tile data */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code and tile data
ROM_LOAD16_BYTE( "c04-12.30", 0x00000, 0x10000, CRC(e319c7ec) SHA1(e76fb872191fce0186ed0ac5066385a9913fdc4c) )
ROM_LOAD16_BYTE( "c04-08.10", 0x00001, 0x10000, CRC(81c6f755) SHA1(43ad72bb05d847f58b3043c674fb9b1e317691df) )
ROM_LOAD16_BYTE( "c04-11.29", 0x20000, 0x10000, CRC(f05696a6) SHA1(8514e5751e2f11840379e8cc6883a23cf1b3a4eb) )
@@ -324,7 +497,7 @@ ROM_START( volfiedo )
ROM_REGION( 0x2000, "cchip:cchip_eprom", 0 )
ROM_LOAD( "cchip_c04-23", 0x0000, 0x2000, CRC(46b0b479) SHA1(73aa2267eb468c5aa5db67183047e9aef8321215) )
- ROM_REGION( 0xc0000, "pc090oj", 0 ) /* sprites 16x16 */
+ ROM_REGION( 0xc0000, "pc090oj", 0 ) // sprites 16x16
ROM_LOAD16_BYTE( "c04-16.2", 0x00000, 0x20000, CRC(8c2476ef) SHA1(972ddc8e47a669f1aeca67d02b4a0bed867ddb7d) )
ROM_LOAD16_BYTE( "c04-18.4", 0x00001, 0x20000, CRC(7665212c) SHA1(b816ac2a95ee273aaf90991f53766d7f0d5d9238) )
ROM_LOAD16_BYTE( "c04-15.1", 0x40000, 0x20000, CRC(7c50b978) SHA1(aa9cad5f09f5d9dceaf4e06bcd347f1d5d02d292) )
@@ -334,16 +507,16 @@ ROM_START( volfiedo )
ROM_LOAD16_BYTE( "c04-09.14", 0x80001, 0x10000, CRC(c78cf057) SHA1(097982e57b1d20fbdf21986c23684adefe6f1ce1) )
ROM_RELOAD ( 0xa0001, 0x10000 )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "c04-06.71", 0x0000, 0x8000, CRC(b70106b2) SHA1(d71062f9d9b11492e13fc93982b95883f564f902) )
- ROM_REGION( 0x00400, "proms", 0 ) /* unused PROMs */
- ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) /* PROM type is a MB7116H or compatible */
- ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) /* PROM type is a MB7124E or compatible */
+ ROM_REGION( 0x00400, "proms", 0 ) // unused
+ ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) // PROM type is a MB7116H or compatible
+ ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) // PROM type is a MB7124E or compatible
ROM_END
ROM_START( volfiedu )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code and tile data */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code and tile data
ROM_LOAD16_BYTE( "c04-12-1.30", 0x00000, 0x10000, CRC(afb6a058) SHA1(fca488e86725a0a673332afeb0002f0e77ef2dbf) )
ROM_LOAD16_BYTE( "c04-08-1.10", 0x00001, 0x10000, CRC(19f7e66b) SHA1(51b5d0d00ec398ed717154286bec24b05c3f81b8) )
ROM_LOAD16_BYTE( "c04-11-1.29", 0x20000, 0x10000, CRC(1aaf6e9b) SHA1(4be643283dc78eb57e9fe4c5afebdc427e4354e8) )
@@ -356,7 +529,7 @@ ROM_START( volfiedu )
ROM_REGION( 0x2000, "cchip:cchip_eprom", 0 )
ROM_LOAD( "cchip_c04-23", 0x0000, 0x2000, CRC(46b0b479) SHA1(73aa2267eb468c5aa5db67183047e9aef8321215) )
- ROM_REGION( 0xc0000, "pc090oj", 0 ) /* sprites 16x16 */
+ ROM_REGION( 0xc0000, "pc090oj", 0 ) // sprites 16x16
ROM_LOAD16_BYTE( "c04-16.2", 0x00000, 0x20000, CRC(8c2476ef) SHA1(972ddc8e47a669f1aeca67d02b4a0bed867ddb7d) )
ROM_LOAD16_BYTE( "c04-18.4", 0x00001, 0x20000, CRC(7665212c) SHA1(b816ac2a95ee273aaf90991f53766d7f0d5d9238) )
ROM_LOAD16_BYTE( "c04-15.1", 0x40000, 0x20000, CRC(7c50b978) SHA1(aa9cad5f09f5d9dceaf4e06bcd347f1d5d02d292) )
@@ -366,16 +539,16 @@ ROM_START( volfiedu )
ROM_LOAD16_BYTE( "c04-09.14", 0x80001, 0x10000, CRC(c78cf057) SHA1(097982e57b1d20fbdf21986c23684adefe6f1ce1) )
ROM_RELOAD ( 0xa0001, 0x10000 )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "c04-06.71", 0x0000, 0x8000, CRC(b70106b2) SHA1(d71062f9d9b11492e13fc93982b95883f564f902) )
- ROM_REGION( 0x00400, "proms", 0 ) /* unused PROMs */
- ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) /* PROM type is a MB7116H or compatible */
- ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) /* PROM type is a MB7124E or compatible */
+ ROM_REGION( 0x00400, "proms", 0 ) // unused
+ ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) // PROM type is a MB7116H or compatible
+ ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) // PROM type is a MB7124E or compatible
ROM_END
ROM_START( volfieduo )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code and tile data */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code and tile data
ROM_LOAD16_BYTE( "c04-12.30", 0x00000, 0x10000, CRC(e319c7ec) SHA1(e76fb872191fce0186ed0ac5066385a9913fdc4c) )
ROM_LOAD16_BYTE( "c04-08.10", 0x00001, 0x10000, CRC(81c6f755) SHA1(43ad72bb05d847f58b3043c674fb9b1e317691df) )
ROM_LOAD16_BYTE( "c04-11.29", 0x20000, 0x10000, CRC(f05696a6) SHA1(8514e5751e2f11840379e8cc6883a23cf1b3a4eb) )
@@ -388,7 +561,7 @@ ROM_START( volfieduo )
ROM_REGION( 0x2000, "cchip:cchip_eprom", 0 )
ROM_LOAD( "cchip_c04-23", 0x0000, 0x2000, CRC(46b0b479) SHA1(73aa2267eb468c5aa5db67183047e9aef8321215) )
- ROM_REGION( 0xc0000, "pc090oj", 0 ) /* sprites 16x16 */
+ ROM_REGION( 0xc0000, "pc090oj", 0 ) // sprites 16x16
ROM_LOAD16_BYTE( "c04-16.2", 0x00000, 0x20000, CRC(8c2476ef) SHA1(972ddc8e47a669f1aeca67d02b4a0bed867ddb7d) )
ROM_LOAD16_BYTE( "c04-18.4", 0x00001, 0x20000, CRC(7665212c) SHA1(b816ac2a95ee273aaf90991f53766d7f0d5d9238) )
ROM_LOAD16_BYTE( "c04-15.1", 0x40000, 0x20000, CRC(7c50b978) SHA1(aa9cad5f09f5d9dceaf4e06bcd347f1d5d02d292) )
@@ -398,16 +571,16 @@ ROM_START( volfieduo )
ROM_LOAD16_BYTE( "c04-09.14", 0x80001, 0x10000, CRC(c78cf057) SHA1(097982e57b1d20fbdf21986c23684adefe6f1ce1) )
ROM_RELOAD ( 0xa0001, 0x10000 )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "c04-06.71", 0x0000, 0x8000, CRC(b70106b2) SHA1(d71062f9d9b11492e13fc93982b95883f564f902) )
- ROM_REGION( 0x00400, "proms", 0 ) /* unused PROMs */
- ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) /* PROM type is a MB7116H or compatible */
- ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) /* PROM type is a MB7124E or compatible */
+ ROM_REGION( 0x00400, "proms", 0 ) // unused
+ ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) // PROM type is a MB7116H or compatible
+ ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) // PROM type is a MB7124E or compatible
ROM_END
ROM_START( volfiedj )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code and tile data */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code and tile data
ROM_LOAD16_BYTE( "c04-12-1.30", 0x00000, 0x10000, CRC(afb6a058) SHA1(fca488e86725a0a673332afeb0002f0e77ef2dbf) )
ROM_LOAD16_BYTE( "c04-08-1.10", 0x00001, 0x10000, CRC(19f7e66b) SHA1(51b5d0d00ec398ed717154286bec24b05c3f81b8) )
ROM_LOAD16_BYTE( "c04-11-1.29", 0x20000, 0x10000, CRC(1aaf6e9b) SHA1(4be643283dc78eb57e9fe4c5afebdc427e4354e8) )
@@ -420,7 +593,7 @@ ROM_START( volfiedj )
ROM_REGION( 0x2000, "cchip:cchip_eprom", 0 )
ROM_LOAD( "cchip_c04-23", 0x0000, 0x2000, CRC(46b0b479) SHA1(73aa2267eb468c5aa5db67183047e9aef8321215) )
- ROM_REGION( 0xc0000, "pc090oj", 0 ) /* sprites 16x16 */
+ ROM_REGION( 0xc0000, "pc090oj", 0 ) // sprites 16x16
ROM_LOAD16_BYTE( "c04-16.2", 0x00000, 0x20000, CRC(8c2476ef) SHA1(972ddc8e47a669f1aeca67d02b4a0bed867ddb7d) )
ROM_LOAD16_BYTE( "c04-18.4", 0x00001, 0x20000, CRC(7665212c) SHA1(b816ac2a95ee273aaf90991f53766d7f0d5d9238) )
ROM_LOAD16_BYTE( "c04-15.1", 0x40000, 0x20000, CRC(7c50b978) SHA1(aa9cad5f09f5d9dceaf4e06bcd347f1d5d02d292) )
@@ -430,16 +603,16 @@ ROM_START( volfiedj )
ROM_LOAD16_BYTE( "c04-09.14", 0x80001, 0x10000, CRC(c78cf057) SHA1(097982e57b1d20fbdf21986c23684adefe6f1ce1) )
ROM_RELOAD ( 0xa0001, 0x10000 )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "c04-06.71", 0x0000, 0x8000, CRC(b70106b2) SHA1(d71062f9d9b11492e13fc93982b95883f564f902) )
- ROM_REGION( 0x00400, "proms", 0 ) /* unused PROMs */
- ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) /* PROM type is a MB7116H or compatible */
- ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) /* PROM type is a MB7124E or compatible */
+ ROM_REGION( 0x00400, "proms", 0 ) // unused
+ ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) // PROM type is a MB7116H or compatible
+ ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) // PROM type is a MB7124E or compatible
ROM_END
ROM_START( volfiedjo )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 68000 code and tile data */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code and tile data
ROM_LOAD16_BYTE( "c04-12.30", 0x00000, 0x10000, CRC(e319c7ec) SHA1(e76fb872191fce0186ed0ac5066385a9913fdc4c) )
ROM_LOAD16_BYTE( "c04-08.10", 0x00001, 0x10000, CRC(81c6f755) SHA1(43ad72bb05d847f58b3043c674fb9b1e317691df) )
ROM_LOAD16_BYTE( "c04-11.29", 0x20000, 0x10000, CRC(f05696a6) SHA1(8514e5751e2f11840379e8cc6883a23cf1b3a4eb) )
@@ -452,7 +625,7 @@ ROM_START( volfiedjo )
ROM_REGION( 0x2000, "cchip:cchip_eprom", 0 )
ROM_LOAD( "cchip_c04-23", 0x0000, 0x2000, CRC(46b0b479) SHA1(73aa2267eb468c5aa5db67183047e9aef8321215) )
- ROM_REGION( 0xc0000, "pc090oj", 0 ) /* sprites 16x16 */
+ ROM_REGION( 0xc0000, "pc090oj", 0 ) // sprites 16x16
ROM_LOAD16_BYTE( "c04-16.2", 0x00000, 0x20000, CRC(8c2476ef) SHA1(972ddc8e47a669f1aeca67d02b4a0bed867ddb7d) )
ROM_LOAD16_BYTE( "c04-18.4", 0x00001, 0x20000, CRC(7665212c) SHA1(b816ac2a95ee273aaf90991f53766d7f0d5d9238) )
ROM_LOAD16_BYTE( "c04-15.1", 0x40000, 0x20000, CRC(7c50b978) SHA1(aa9cad5f09f5d9dceaf4e06bcd347f1d5d02d292) )
@@ -462,14 +635,16 @@ ROM_START( volfiedjo )
ROM_LOAD16_BYTE( "c04-09.14", 0x80001, 0x10000, CRC(c78cf057) SHA1(097982e57b1d20fbdf21986c23684adefe6f1ce1) )
ROM_RELOAD ( 0xa0001, 0x10000 )
- ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "c04-06.71", 0x0000, 0x8000, CRC(b70106b2) SHA1(d71062f9d9b11492e13fc93982b95883f564f902) )
- ROM_REGION( 0x00400, "proms", 0 ) /* unused PROMs */
- ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) /* PROM type is a MB7116H or compatible */
- ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) /* PROM type is a MB7124E or compatible */
+ ROM_REGION( 0x00400, "proms", 0 ) // unused
+ ROM_LOAD( "c04-4-1.3", 0x00000, 0x00200, CRC(ab9fae65) SHA1(e2b29606aa63e42e041d3c47216551f62846bd99) ) // PROM type is a MB7116H or compatible
+ ROM_LOAD( "c04-5.75", 0x00200, 0x00200, CRC(2763ec89) SHA1(1e8339e21ee35b526d8604a21cfed9a1ac6455e8) ) // PROM type is a MB7124E or compatible
ROM_END
+} // anonymous namespace
+
GAME( 1989, volfied, 0, volfied, volfied, volfied_state, empty_init, ROT270, "Taito Corporation Japan", "Volfied (World, revision 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1989, volfiedu, volfied, volfied, volfiedu, volfied_state, empty_init, ROT270, "Taito America Corporation", "Volfied (US, revision 1)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/taito/volfied.h b/src/mame/taito/volfied.h
deleted file mode 100644
index 72842847176..00000000000
--- a/src/mame/taito/volfied.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, Nicola Salmoria
-/*************************************************************************
-
- Volfied
-
-*************************************************************************/
-#ifndef MAME_INCLUDES_VOLFIED_H
-#define MAME_INCLUDES_VOLFIED_H
-
-#pragma once
-
-#include "taitocchip.h"
-#include "pc090oj.h"
-#include "screen.h"
-#include "machine/timer.h"
-
-class volfied_state : public driver_device
-{
-public:
- volfied_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_audiocpu(*this, "audiocpu"),
- m_cchip(*this, "cchip"),
- m_pc090oj(*this, "pc090oj"),
- m_screen(*this, "screen"),
- m_cchip_irq_clear(*this, "cchip_irq_clear")
- { }
-
- void volfied(machine_config &config);
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
-
-private:
- uint16_t video_ram_r(offs_t offset);
- void video_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
- void video_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
- uint16_t video_ctrl_r();
- void video_mask_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
- void counters_w(uint8_t data);
- void volfied_colpri_cb(u32 &sprite_colbank, u32 &pri_mask, u16 sprite_ctrl);
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- INTERRUPT_GEN_MEMBER(interrupt);
- TIMER_DEVICE_CALLBACK_MEMBER(cchip_irq_clear_cb);
-
- void refresh_pixel_layer( bitmap_ind16 &bitmap );
-
- void main_map(address_map &map);
- void z80_map(address_map &map);
-
- /* memory pointers */
- std::unique_ptr<uint16_t[]> m_video_ram;
-
- /* video-related */
- uint16_t m_video_ctrl = 0;
- uint16_t m_video_mask = 0;
-
- /* devices */
- required_device<cpu_device> m_maincpu;
- required_device<cpu_device> m_audiocpu;
- required_device<taito_cchip_device> m_cchip;
- required_device<pc090oj_device> m_pc090oj;
- required_device<screen_device> m_screen;
-
- required_device<timer_device> m_cchip_irq_clear;
-};
-
-#endif // MAME_INCLUDES_VOLFIED_H
diff --git a/src/mame/taito/volfied_v.cpp b/src/mame/taito/volfied_v.cpp
deleted file mode 100644
index b4d03171e14..00000000000
--- a/src/mame/taito/volfied_v.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Bryan McPhail, Nicola Salmoria
-#include "emu.h"
-#include "volfied.h"
-
-/******************************************************
- INITIALISATION AND CLEAN-UP
-******************************************************/
-
-void volfied_state::video_start()
-{
- m_video_ram = std::make_unique<uint16_t[]>(0x40000);
-
- m_video_ctrl = 0;
- m_video_mask = 0;
-
- save_pointer(NAME(m_video_ram), 0x40000);
- save_item(NAME(m_video_ctrl));
- save_item(NAME(m_video_mask));
-}
-
-
-/*******************************************************
- READ AND WRITE HANDLERS
-*******************************************************/
-
-uint16_t volfied_state::video_ram_r(offs_t offset)
-{
- return m_video_ram[offset];
-}
-
-void volfied_state::video_ram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
-{
- mem_mask &= m_video_mask;
-
- COMBINE_DATA(&m_video_ram[offset]);
-}
-
-void volfied_state::video_ctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
-{
- COMBINE_DATA(&m_video_ctrl);
-}
-
-uint16_t volfied_state::video_ctrl_r()
-{
- /* Could this be some kind of hardware collision detection? If bit 6 is
- set the game will check for collisions with the large enemy, whereas
- bit 5 does the same for small enemies. Bit 7 is also used although
- its purpose is unclear. This register is usually read during a VBI
- and stored in work RAM for later use. */
-
- return 0x60;
-}
-
-void volfied_state::video_mask_w(offs_t offset, uint16_t data, uint16_t mem_mask)
-{
- COMBINE_DATA(&m_video_mask);
-}
-
-void volfied_state::volfied_colpri_cb(u32 &sprite_colbank, u32 &pri_mask, u16 sprite_ctrl)
-{
- sprite_colbank = 0x100 | ((sprite_ctrl & 0x3c) << 2);
- pri_mask = 0; /* sprites over everything */
-}
-
-
-/*******************************************************
- SCREEN REFRESH
-*******************************************************/
-
-void volfied_state::refresh_pixel_layer( bitmap_ind16 &bitmap )
-{
- /*********************************************************
-
- VIDEO RAM has 2 screens x 256 rows x 512 columns x 16 bits
-
- x--------------- select image
- -x-------------- ? (used for 3-D corners)
- --x------------- ? (used for 3-D walls)
- ---xxxx--------- image B
- -------xxx------ palette index bits #8 to #A
- ----------x----- ?
- -----------x---- ?
- ------------xxxx image A
-
- '3d' corners & walls are made using unknown bits for each
- line the player draws. However, on the pcb they just
- appear as solid black. Perhaps it was prototype code that
- was turned off at some stage.
-
- *********************************************************/
-
- uint16_t* p = m_video_ram.get();
- int width = m_screen->width();
- int height = m_screen->height();
-
- if (m_video_ctrl & 1)
- p += 0x20000;
-
- for (int y = 0; y < height; y++)
- {
- for (int x = 1; x < width + 1; x++) // Hmm, 1 pixel offset is needed to align properly with sprites
- {
- int color = (p[x] << 2) & 0x700;
-
- if (p[x] & 0x8000)
- {
- color |= 0x800 | ((p[x] >> 9) & 0xf);
-
- if (p[x] & 0x2000)
- color &= ~0xf; /* hack */
- }
- else
- color |= p[x] & 0xf;
-
- bitmap.pix(y, x - 1) = color;
- }
-
- p += 512;
- }
-}
-
-uint32_t volfied_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- screen.priority().fill(0, cliprect);
- refresh_pixel_layer(bitmap);
- m_pc090oj->draw_sprites(screen, bitmap, cliprect);
- return 0;
-}
diff --git a/src/mame/taito/warriorb.cpp b/src/mame/taito/warriorb.cpp
index dcd2c19b2dc..a137bc2e9f0 100644
--- a/src/mame/taito/warriorb.cpp
+++ b/src/mame/taito/warriorb.cpp
@@ -1,6 +1,7 @@
// license:BSD-3-Clause
-// copyright-holders:David Graves
-// thanks-to:Richard Bush
+// copyright-holders: David Graves
+// thanks-to: Richard Bush
+
/***************************************************************************
Taito Dual Screen Games
@@ -18,12 +19,12 @@ source was very helpful in many areas particularly the sprites.)
*****
The dual screen games operate on hardware with various similarities to
-the Taito F2 system, as they share some custom ics e.g. the TC0100SCN.
+the Taito F2 system, as they share some custom ICs e.g. the TC0100SCN.
For each screen the games have 3 separate layers of graphics: - one
128x64 tiled scrolling background plane of 8x8 tiles, a similar
foreground plane, and a 128x32 text plane with character definitions
-held in ram. As well as this, there is a single sprite plane which
+held in RAM. As well as this, there is a single sprite plane which
covers both screens. The sprites are 16x16 and are not zoomable.
Writing to the first TC0100SCN "writes through" to the subsidiary one
@@ -147,17 +148,197 @@ Colscroll effects?
***************************************************************************/
#include "emu.h"
-#include "warriorb.h"
+
+#include "taitoio.h"
#include "taitoipt.h"
+#include "taitosnd.h"
+#include "tc0100scn.h"
+#include "tc0110pcr.h"
#include "cpu/z80/z80.h"
#include "cpu/m68000/m68000.h"
+#include "sound/flt_vol.h"
#include "sound/ymopn.h"
-#include "layout/generic.h"
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "layout/generic.h"
+
+
+// configurable logging
+#define LOG_PANDATA (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_PANDATA)
+
+#include "logmacro.h"
+
+#define LOGPANDATA(...) LOGMASKED(LOG_PANDATA, __VA_ARGS__)
+
+
+namespace {
+
+class warriorb_state : public driver_device
+{
+public:
+ warriorb_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu"),
+ m_tc0140syt(*this, "tc0140syt"),
+ m_tc0100scn(*this, "tc0100scn_%u", 1),
+ m_tc0110pcr(*this, "tc0110pcr_%u", 1),
+ m_2610_l(*this, "2610.%u.l", 1),
+ m_2610_r(*this, "2610.%u.r", 1),
+ m_gfxdecode(*this, "gfxdecode_%u", 1),
+ m_spriteram(*this, "spriteram"),
+ m_z80bank(*this, "z80bank")
+ { }
+
+ void warriorb(machine_config &config);
+ void darius2d(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ // devices
+ required_device<cpu_device> m_maincpu;
+ required_device<tc0140syt_device> m_tc0140syt;
+ required_device_array<tc0100scn_device, 2> m_tc0100scn;
+ required_device_array<tc0110pcr_device, 2> m_tc0110pcr;
+ required_device_array<filter_volume_device, 2> m_2610_l;
+ required_device_array<filter_volume_device, 2> m_2610_r;
+ required_device_array<gfxdecode_device, 2> m_gfxdecode;
+
+ // memory pointers
+ required_shared_ptr<u16> m_spriteram;
+
+ // memory regions
+ required_memory_bank m_z80bank;
+
+ // misc
+ u16 m_pandata[4]{};
+
+ void coin_control_w(u8 data);
+ void sound_bankswitch_w(u8 data);
+ void pancontrol_w(offs_t offset, u8 data);
+ void tc0100scn_dual_screen_w(offs_t offset, u16 data, u16 mem_mask = ~0);
+
+ void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int x_offs, int y_offs, int chip);
+ template <u8 Which> u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void darius2d_main_map(address_map &map);
+ void warriorb_main_map(address_map &map);
+ void z80_sound_map(address_map &map);
+};
+
+
+// video
+
+/************************************************************
+ SPRITE DRAW ROUTINE
+************************************************************/
+
+void warriorb_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int x_offs, int y_offs, int chip)
+{
+#ifdef MAME_DEBUG
+ int unknown = 0;
+#endif
+
+ // pdrawgfx() needs us to draw sprites front to back
+ for (int offs = 0; offs < m_spriteram.bytes() / 2; offs += 4)
+ {
+ int data = m_spriteram[offs + 1];
+ const u32 tilenum = data & 0x7fff;
+
+ data = m_spriteram[offs + 0];
+ int y = (-(data & 0x1ff) - 24) & 0x1ff; // (inverted y adjusted for vis area)
+ const bool flipy = (data & 0x200) >> 9;
+
+ const u16 data2 = m_spriteram[offs + 2];
+ // 8,4 also seen in msbyte
+ const int priority = (data2 & 0x0100) >> 8; // 1 = low
+
+ u32 pri_mask;
+
+ if (priority)
+ pri_mask = 0xfffe;
+ else
+ pri_mask = 0;
+
+ const u32 color = (data2 & 0x7f);
+
+ data = m_spriteram[offs + 3];
+ int x = (data & 0x3ff);
+ const bool flipx = (data & 0x400) >> 10;
+
+#ifdef MAME_DEBUG
+ if (data2 & 0xf280) unknown |= (data2 &0xf280);
+#endif
+
+ x -= x_offs;
+ y += y_offs;
+
+ // sprite wrap: coords become negative at high values
+ if (x > 0x3c0) x -= 0x400;
+ if (y > 0x180) y -= 0x200;
+
+ m_gfxdecode[chip]->gfx(0)->prio_transpen(bitmap, cliprect,
+ tilenum,
+ color,
+ flipx, flipy,
+ x, y,
+ screen.priority(), pri_mask, 0);
+ }
+
+#ifdef MAME_DEBUG
+ if (unknown)
+ popmessage("unknown sprite bits: %04x", unknown);
+#endif
+}
+
+
+/**************************************************************
+ SCREEN REFRESH
+**************************************************************/
+
+template <u8 Which>
+u32 warriorb_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ u8 layer[3];
+
+ m_tc0100scn[Which]->tilemap_update();
+
+ layer[0] = m_tc0100scn[Which]->bottomlayer();
+ layer[1] = layer[0] ^ 1;
+ layer[2] = 2;
+
+ // Clear priority bitmap */
+ screen.priority().fill(0, cliprect);
+
+ /* chip 0 does tilemaps on the left, chip 1 does the ones on the right */
+ // draw bottom layer
+ const u8 nodraw = m_tc0100scn[Which]->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0); // left
+
+ // Ensure screen blanked even when bottom layers not drawn due to disable bit
+ if (nodraw)
+ bitmap.fill(m_tc0110pcr[Which]->black_pen(), cliprect);
+
+ // draw middle layer
+ m_tc0100scn[Which]->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1);
+
+ // Sprites can be under/over the layer below text layer
+ const int xoffs = 40 * 8;
+ draw_sprites(screen, bitmap, cliprect, xoffs * Which, 8, Which);
+
+ // draw top (text) layer
+ m_tc0100scn[Which]->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 0);
+ return 0;
+}
+
+// machine
void warriorb_state::coin_control_w(u8 data)
{
@@ -192,8 +373,8 @@ void warriorb_state::pancontrol_w(offs_t offset, u8 data)
case 3: flt = m_2610_r[1]; break;
}
- m_pandata[offset] = (data << 1) + data; /* original volume*3 */
- //popmessage(" pan %02x %02x %02x %02x", m_pandata[0], m_pandata[1], m_pandata[2], m_pandata[3] );
+ m_pandata[offset] = (data << 1) + data; // original volume * 3
+ LOGPANDATA("pan %02x %02x %02x %02x", m_pandata[0], m_pandata[1], m_pandata[2], m_pandata[3]);
flt->flt_volume_set_volume(m_pandata[offset] / 100.0);
}
@@ -208,36 +389,36 @@ void warriorb_state::tc0100scn_dual_screen_w(offs_t offset, u16 data, u16 mem_ma
MEMORY STRUCTURES
***********************************************************/
-void warriorb_state::darius2d_map(address_map &map)
+void warriorb_state::darius2d_main_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
- map(0x100000, 0x10ffff).ram(); /* main ram */
- map(0x200000, 0x213fff).r(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r)).w(FUNC(warriorb_state::tc0100scn_dual_screen_w)); /* tilemaps (all screens) */
- map(0x214000, 0x2141ff).nopw(); /* error in screen clearing code ? */
+ map(0x100000, 0x10ffff).ram(); // main RAM
+ map(0x200000, 0x213fff).r(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r)).w(FUNC(warriorb_state::tc0100scn_dual_screen_w)); // tilemaps (all screens)
+ map(0x214000, 0x2141ff).nopw(); // error in screen clearing code ?
map(0x220000, 0x22000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
- map(0x240000, 0x253fff).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps (2nd screen) */
+ map(0x240000, 0x253fff).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); // tilemaps (2nd screen)
map(0x260000, 0x26000f).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
- map(0x400000, 0x400007).rw(m_tc0110pcr[0], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); /* palette (1st screen) */
- map(0x420000, 0x420007).rw(m_tc0110pcr[1], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); /* palette (2nd screen) */
- map(0x600000, 0x6013ff).ram().share("spriteram");
- map(0x800000, 0x80000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
+ map(0x400000, 0x400007).rw(m_tc0110pcr[0], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); // palette (1st screen)
+ map(0x420000, 0x420007).rw(m_tc0110pcr[1], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); // palette (2nd screen)
+ map(0x600000, 0x6013ff).ram().share(m_spriteram);
+ map(0x800000, 0x80000f).rw("tc0220ioc", FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
// map(0x820000, 0x820001).nopw(); // ???
map(0x830001, 0x830001).w(m_tc0140syt, FUNC(tc0140syt_device::master_port_w));
map(0x830003, 0x830003).rw(m_tc0140syt, FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
}
-void warriorb_state::warriorb_map(address_map &map)
+void warriorb_state::warriorb_main_map(address_map &map)
{
map(0x000000, 0x1fffff).rom();
map(0x200000, 0x213fff).ram();
- map(0x300000, 0x313fff).r(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r)).w(FUNC(warriorb_state::tc0100scn_dual_screen_w)); /* tilemaps (all screens) */
+ map(0x300000, 0x313fff).r(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r)).w(FUNC(warriorb_state::tc0100scn_dual_screen_w)); // tilemaps (all screens)
map(0x320000, 0x32000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
- map(0x340000, 0x353fff).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps (2nd screen) */
+ map(0x340000, 0x353fff).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); // tilemaps (2nd screen)
map(0x360000, 0x36000f).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
- map(0x400000, 0x400007).rw(m_tc0110pcr[0], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); /* palette (1st screen) */
- map(0x420000, 0x420007).rw(m_tc0110pcr[1], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); /* palette (2nd screen) */
- map(0x600000, 0x6013ff).ram().share("spriteram");
- map(0x800000, 0x80000f).rw(m_tc0510nio, FUNC(tc0510nio_device::read), FUNC(tc0510nio_device::write)).umask16(0x00ff);
+ map(0x400000, 0x400007).rw(m_tc0110pcr[0], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); // palette (1st screen)
+ map(0x420000, 0x420007).rw(m_tc0110pcr[1], FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::step1_word_w)); // palette (2nd screen)
+ map(0x600000, 0x6013ff).ram().share(m_spriteram);
+ map(0x800000, 0x80000f).rw("tc0510nio", FUNC(tc0510nio_device::read), FUNC(tc0510nio_device::write)).umask16(0x00ff);
// map(0x820000, 0x820001).nopw(); // ? uses bits 0,2,3
map(0x830001, 0x830001).w(m_tc0140syt, FUNC(tc0140syt_device::master_port_w));
map(0x830003, 0x830003).rw(m_tc0140syt, FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
@@ -248,15 +429,15 @@ void warriorb_state::warriorb_map(address_map &map)
void warriorb_state::z80_sound_map(address_map &map)
{
map(0x0000, 0x3fff).rom();
- map(0x4000, 0x7fff).bankr("z80bank");
+ map(0x4000, 0x7fff).bankr(m_z80bank);
map(0xc000, 0xdfff).ram();
map(0xe000, 0xe003).rw("ymsnd", FUNC(ym_generic_device::read), FUNC(ym_generic_device::write));
map(0xe200, 0xe200).nopr().w(m_tc0140syt, FUNC(tc0140syt_device::slave_port_w));
map(0xe201, 0xe201).rw(m_tc0140syt, FUNC(tc0140syt_device::slave_comm_r), FUNC(tc0140syt_device::slave_comm_w));
- map(0xe400, 0xe403).w(FUNC(warriorb_state::pancontrol_w)); /* pan */
+ map(0xe400, 0xe403).w(FUNC(warriorb_state::pancontrol_w));
map(0xea00, 0xea00).nopr();
- map(0xee00, 0xee00).nopw(); /* ? */
- map(0xf000, 0xf000).nopw(); /* ? */
+ map(0xee00, 0xee00).nopw(); // ?
+ map(0xf000, 0xf000).nopw(); // ?
map(0xf200, 0xf200).w(FUNC(warriorb_state::sound_bankswitch_w));
}
@@ -266,9 +447,9 @@ void warriorb_state::z80_sound_map(address_map &map)
***********************************************************/
static INPUT_PORTS_START( darius2d )
- /* 0x800000 -> 0x109e16 ($1e16,A5) and 0x109e1a ($1e1a,A5) */
+ // 0x800000 -> 0x109e16 ($1e16,A5) and 0x109e1a ($1e1a,A5)
PORT_START("DSWA")
- PORT_DIPNAME( 0x01, 0x01, "Difficulty Enhancement" ) PORT_DIPLOCATION("SW1:1") /* code at 0x0170f2 ('darius2d') or 0x01705c ('drius2do') */
+ PORT_DIPNAME( 0x01, 0x01, "Difficulty Enhancement" ) PORT_DIPLOCATION("SW1:1") // code at 0x0170f2 ('darius2d') or 0x01705c ('drius2do')
PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) // Easy Medium Hard Hardest // Japan factory default = "Off"
PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // Easy- Medium+ Hard+ Hardest+ // "Easy-" is easier than "Easy". "Medium+","Hard+" and "hardest+" are harder than "Medium","Hard" and "hardest".
PORT_DIPNAME( 0x02, 0x02, "Auto Fire" ) PORT_DIPLOCATION("SW1:2")
@@ -277,7 +458,7 @@ static INPUT_PORTS_START( darius2d )
TAITO_DSWA_BITS_2_TO_3_LOC(SW1)
TAITO_COINAGE_JAPAN_OLD_LOC(SW1)
- /* 0x800002 -> 0x109e18 ($1e18,A5) and 0x109e1c ($1e1c,A5) */
+ // 0x800002 -> 0x109e18 ($1e18,A5) and 0x109e1c ($1e1c,A5)
PORT_START("DSWB")
TAITO_DIFFICULTY_LOC(SW2)
PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:3,4")
@@ -323,7 +504,7 @@ static INPUT_PORTS_START( sagaia )
PORT_INCLUDE(darius2d)
PORT_MODIFY("DSWA")
- PORT_DIPNAME( 0x01, 0x00, "Difficulty Enhancement" ) PORT_DIPLOCATION("SW1:1") /* code at 0x0170f2 ('darius2d') or 0x01705c ('drius2do') */
+ PORT_DIPNAME( 0x01, 0x00, "Difficulty Enhancement" ) PORT_DIPLOCATION("SW1:1") // code at 0x0170f2 ('darius2d') or 0x01705c ('drius2do')
PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) // Easy Medium Hard Hardest
PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // Easy- Medium+ Hard+ Hardest+
// MAME 0.143u7 SW1:1="Unknown / Off / On" default="On"
@@ -334,9 +515,9 @@ INPUT_PORTS_END
static INPUT_PORTS_START( warriorb )
PORT_INCLUDE(darius2d)
- /* 0x800000 -> 0x202912.b (-$56ee,A5) */
+ // 0x800000 -> 0x202912.b (-$56ee,A5)
PORT_MODIFY("DSWA")
- PORT_DIPNAME( 0x03, 0x03, "Vitality Recovery" ) PORT_DIPLOCATION("SW1:1,2") /* table at 0x00d508 - 4 * 4 words */
+ PORT_DIPNAME( 0x03, 0x03, "Vitality Recovery" ) PORT_DIPLOCATION("SW1:1,2") // table at 0x00d508 - 4 * 4 words
PORT_DIPSETTING( 0x02, "Less" )
PORT_DIPSETTING( 0x03, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x01, "More" )
@@ -344,13 +525,13 @@ static INPUT_PORTS_START( warriorb )
TAITO_DSWA_BITS_2_TO_3_LOC(SW1)
TAITO_COINAGE_JAPAN_NEW_LOC(SW1)
- /* 0x800002 -> 0x202913.b (-$56ed,A5) */
+ // 0x800002 -> 0x202913.b (-$56ed,A5)
PORT_MODIFY("DSWB")
TAITO_DIFFICULTY_LOC(SW2)
PORT_DIPNAME( 0x04, 0x04, "Gold Sheep at" ) PORT_DIPLOCATION("SW2:3")
PORT_DIPSETTING( 0x04, "50k only" )
PORT_DIPSETTING( 0x00, "50k then every 70k" )
- PORT_DIPNAME( 0x08, 0x08, "Magic Energy Loss" ) PORT_DIPLOCATION("SW2:4") /* code at 0x0587de - when BUTTON3 pressed */
+ PORT_DIPNAME( 0x08, 0x08, "Magic Energy Loss" ) PORT_DIPLOCATION("SW2:4") // code at 0x0587de - when BUTTON3 pressed
PORT_DIPSETTING( 0x08, "Always Player" )
PORT_DIPSETTING( 0x00, "Player or Magician" )
PORT_DIPNAME( 0x10, 0x10, "Player Starting Strength" ) PORT_DIPLOCATION("SW2:5")
@@ -367,7 +548,7 @@ static INPUT_PORTS_START( warriorb )
PORT_DIPSETTING( 0x00, "Long (14)" )
PORT_MODIFY("IN0")
- /* Japanese version actually doesn't have the third button */
+ // Japanese version actually doesn't have the third button
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Button 3 (Cheat)")
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Button 3 (Cheat)")
INPUT_PORTS_END
@@ -378,7 +559,7 @@ INPUT_PORTS_END
***********************************************************/
static GFXDECODE_START( gfx_warriorb )
- GFXDECODE_ENTRY( "sprites", 0, gfx_16x16x4_packed_lsb, 0, 256 ) /* sprites */
+ GFXDECODE_ENTRY( "sprites", 0, gfx_16x16x4_packed_lsb, 0, 256 )
GFXDECODE_END
/***********************************************************
@@ -395,28 +576,28 @@ void warriorb_state::machine_start()
void warriorb_state::machine_reset()
{
/**** mixer control enable ****/
- machine().sound().system_mute(false); /* mixer enabled */
+ machine().sound().system_mute(false); // mixer enabled
}
void warriorb_state::darius2d(machine_config &config)
{
- /* basic machine hardware */
- M68000(config, m_maincpu, 16_MHz_XTAL); /* MC68000P12F 16 MHz, 16 MHz XTAL */
- m_maincpu->set_addrmap(AS_PROGRAM, &warriorb_state::darius2d_map);
+ // basic machine hardware */
+ M68000(config, m_maincpu, 16_MHz_XTAL); // MC68000P12F 16 MHz, 16 MHz XTAL
+ m_maincpu->set_addrmap(AS_PROGRAM, &warriorb_state::darius2d_main_map);
m_maincpu->set_vblank_int("lscreen", FUNC(warriorb_state::irq4_line_hold));
- z80_device &audiocpu(Z80(config, "audiocpu", 16_MHz_XTAL / 4)); /* 4 MHz (16 MHz XTAL / 4) */
+ z80_device &audiocpu(Z80(config, "audiocpu", 16_MHz_XTAL / 4)); // 4 MHz (16 MHz XTAL / 4)
audiocpu.set_addrmap(AS_PROGRAM, &warriorb_state::z80_sound_map);
- TC0220IOC(config, m_tc0220ioc, 0);
- m_tc0220ioc->read_0_callback().set_ioport("DSWA");
- m_tc0220ioc->read_1_callback().set_ioport("DSWB");
- m_tc0220ioc->read_2_callback().set_ioport("IN0");
- m_tc0220ioc->read_3_callback().set_ioport("IN1");
- m_tc0220ioc->write_4_callback().set(FUNC(warriorb_state::coin_control_w));
- m_tc0220ioc->read_7_callback().set_ioport("IN2");
+ tc0220ioc_device & tc0220ioc(TC0220IOC(config, "tc0220ioc", 0));
+ tc0220ioc.read_0_callback().set_ioport("DSWA");
+ tc0220ioc.read_1_callback().set_ioport("DSWB");
+ tc0220ioc.read_2_callback().set_ioport("IN0");
+ tc0220ioc.read_3_callback().set_ioport("IN1");
+ tc0220ioc.write_4_callback().set(FUNC(warriorb_state::coin_control_w));
+ tc0220ioc.read_7_callback().set_ioport("IN2");
- /* video hardware */
+ // video hardware
GFXDECODE(config, m_gfxdecode[0], m_tc0110pcr[0], gfx_warriorb);
GFXDECODE(config, m_gfxdecode[1], m_tc0110pcr[1], gfx_warriorb);
@@ -427,7 +608,7 @@ void warriorb_state::darius2d(machine_config &config)
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
lscreen.set_size(40*8, 32*8);
lscreen.set_visarea(0*8, 40*8-1, 3*8, 32*8-1);
- lscreen.set_screen_update(FUNC(warriorb_state::screen_update_left));
+ lscreen.set_screen_update(FUNC(warriorb_state::screen_update<0>));
lscreen.set_palette(m_tc0110pcr[0]);
TC0100SCN(config, m_tc0100scn[0], 0);
@@ -441,7 +622,7 @@ void warriorb_state::darius2d(machine_config &config)
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(40*8, 32*8);
rscreen.set_visarea(0*8, 40*8-1, 3*8, 32*8-1);
- rscreen.set_screen_update(FUNC(warriorb_state::screen_update_right));
+ rscreen.set_screen_update(FUNC(warriorb_state::screen_update<1>));
rscreen.set_palette(m_tc0110pcr[1]);
TC0100SCN(config, m_tc0100scn[1], 0);
@@ -451,7 +632,7 @@ void warriorb_state::darius2d(machine_config &config)
TC0110PCR(config, m_tc0110pcr[1], 0);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
SPEAKER(config, "subwoofer").seat();
@@ -476,21 +657,21 @@ void warriorb_state::darius2d(machine_config &config)
void warriorb_state::warriorb(machine_config &config)
{
- /* basic machine hardware */
- M68000(config, m_maincpu, 16_MHz_XTAL); /* MC68000P12F 16 MHz, 16 MHz XTAL */
- m_maincpu->set_addrmap(AS_PROGRAM, &warriorb_state::warriorb_map);
+ // basic machine hardware
+ M68000(config, m_maincpu, 16_MHz_XTAL); // MC68000P12F 16 MHz, 16 MHz XTAL
+ m_maincpu->set_addrmap(AS_PROGRAM, &warriorb_state::warriorb_main_map);
m_maincpu->set_vblank_int("lscreen", FUNC(warriorb_state::irq4_line_hold));
- z80_device &audiocpu(Z80(config, "audiocpu", 16_MHz_XTAL / 4)); /* 4 MHz (16 MHz XTAL / 4) */
+ z80_device &audiocpu(Z80(config, "audiocpu", 16_MHz_XTAL / 4)); // 4 MHz (16 MHz XTAL / 4)
audiocpu.set_addrmap(AS_PROGRAM, &warriorb_state::z80_sound_map);
- TC0510NIO(config, m_tc0510nio, 0);
- m_tc0510nio->read_0_callback().set_ioport("DSWA");
- m_tc0510nio->read_1_callback().set_ioport("DSWB");
- m_tc0510nio->read_2_callback().set_ioport("IN0");
- m_tc0510nio->read_3_callback().set_ioport("IN1");
- m_tc0510nio->write_4_callback().set(FUNC(warriorb_state::coin_control_w));
- m_tc0510nio->read_7_callback().set_ioport("IN2");
+ tc0510nio_device &tc0510nio(TC0510NIO(config, "tc0510nio", 0));
+ tc0510nio.read_0_callback().set_ioport("DSWA");
+ tc0510nio.read_1_callback().set_ioport("DSWB");
+ tc0510nio.read_2_callback().set_ioport("IN0");
+ tc0510nio.read_3_callback().set_ioport("IN1");
+ tc0510nio.write_4_callback().set(FUNC(warriorb_state::coin_control_w));
+ tc0510nio.read_7_callback().set_ioport("IN2");
/* video hardware */
GFXDECODE(config, m_gfxdecode[0], m_tc0110pcr[0], gfx_warriorb);
@@ -503,7 +684,7 @@ void warriorb_state::warriorb(machine_config &config)
lscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
lscreen.set_size(40*8, 32*8);
lscreen.set_visarea(0*8, 40*8-1, 2*8, 32*8-1);
- lscreen.set_screen_update(FUNC(warriorb_state::screen_update_left));
+ lscreen.set_screen_update(FUNC(warriorb_state::screen_update<0>));
lscreen.set_palette(m_tc0110pcr[0]);
TC0100SCN(config, m_tc0100scn[0], 0);
@@ -517,7 +698,7 @@ void warriorb_state::warriorb(machine_config &config)
rscreen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
rscreen.set_size(40*8, 32*8);
rscreen.set_visarea(0*8, 40*8-1, 2*8, 32*8-1);
- rscreen.set_screen_update(FUNC(warriorb_state::screen_update_right));
+ rscreen.set_screen_update(FUNC(warriorb_state::screen_update<1>));
rscreen.set_palette(m_tc0110pcr[1]);
TC0100SCN(config, m_tc0100scn[1], 0);
@@ -528,10 +709,10 @@ void warriorb_state::warriorb(machine_config &config)
TC0110PCR(config, m_tc0110pcr[1], 0);
- /* sound hardware */
+ // sound hardware
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
- // subwoofer under seat is exists like other taito multiscreen games?
+ // is there a subwoofer under the seat like other Taito multiscreen games?
ym2610b_device &ymsnd(YM2610B(config, "ymsnd", 16_MHz_XTAL / 2));
ymsnd.irq_handler().set_inputline("audiocpu", 0);
@@ -558,170 +739,171 @@ void warriorb_state::warriorb(machine_config &config)
***************************************************************************/
ROM_START( sagaia )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 512K for 68000 code */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "c07_44.74", 0x00000, 0x20000, CRC(d0ca72d8) SHA1(13b47a4fb976167141dd36968f9e8d932ba78dcb) )
ROM_LOAD16_BYTE( "c07_43.73", 0x00001, 0x20000, CRC(a34ea5ba) SHA1(300d168a8602b3c871fcd403fb72a8c8740eb013) )
ROM_LOAD16_BYTE( "c07_45.76", 0x40000, 0x20000, CRC(8a043c14) SHA1(018647f3d3f4850ed0319266258fb33223c8a9ea) )
ROM_LOAD16_BYTE( "c07_42.71", 0x40001, 0x20000, CRC(b6cb642f) SHA1(54f4848e0a411ac6e6cfc911800dfeba19c62936) )
- ROM_LOAD16_WORD_SWAP( "c07-09.75", 0x80000, 0x80000, CRC(cc69c2ce) SHA1(47883b9e14d8b6dd74db221bff396477231938f2) ) /* data rom */
+ ROM_LOAD16_WORD_SWAP( "c07-09.75", 0x80000, 0x80000, CRC(cc69c2ce) SHA1(47883b9e14d8b6dd74db221bff396477231938f2) ) // data ROM
- ROM_REGION( 0x20000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x20000, "audiocpu", 0 )
ROM_LOAD( "c07_41.69", 0x00000, 0x20000, CRC(b50256ea) SHA1(6ed271e4dafd1c759adaa55d5b2343d7374c721a) )
- ROM_REGION( 0x200000, "sprites", 0 )
- ROM_LOAD64_WORD( "c07-05.24", 0x00000, 0x80000, CRC(fb6d0550) SHA1(2d570ff5ef262cb4cb52e8584a7f167263194d37) ) /* OBJ */
+ ROM_REGION( 0x200000, "sprites", 0 ) // OBJ
+ ROM_LOAD64_WORD( "c07-05.24", 0x00000, 0x80000, CRC(fb6d0550) SHA1(2d570ff5ef262cb4cb52e8584a7f167263194d37) )
ROM_LOAD64_WORD( "c07-06.27", 0x00002, 0x80000, CRC(5eebbcd6) SHA1(d4d860bf6b099956c45c7273ad77b1d35deba4c1) )
ROM_LOAD64_WORD( "c07-07.26", 0x00004, 0x80000, CRC(fd9f9e74) SHA1(e89beb5cac844fe16662465b0c76337692591aae) )
ROM_LOAD64_WORD( "c07-08.25", 0x00006, 0x80000, CRC(a07dc846) SHA1(7199a604fcd693215ddb7670bfb2daf150145fd7) )
- ROM_REGION( 0x100000, "tc0100scn_1", 0 )
- ROM_LOAD16_WORD_SWAP( "c07-03.12", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) ) /* SCr(screen 1) */
+ ROM_REGION( 0x100000, "tc0100scn_1", 0 ) // SCr(screen 1)
+ ROM_LOAD16_WORD_SWAP( "c07-03.12", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) )
ROM_LOAD16_WORD_SWAP( "c07-04.11", 0x80000, 0x80000, CRC(50421e81) SHA1(27ac420602f1dac00dc32903543a518e6f47fb2f) )
- ROM_REGION( 0x100000, "tc0100scn_2", 0 )
- ROM_LOAD16_WORD_SWAP( "c07-03.47", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) ) /* SCr(screen 2) */
+ ROM_REGION( 0x100000, "tc0100scn_2", 0 ) // SCr(screen 2)
+ ROM_LOAD16_WORD_SWAP( "c07-03.47", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) )
ROM_LOAD16_WORD_SWAP( "c07-04.48", 0x80000, 0x80000, CRC(50421e81) SHA1(27ac420602f1dac00dc32903543a518e6f47fb2f) )
- ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) /* ADPCM samples */
+ ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) // ADPCM samples
ROM_LOAD( "c07-10.95", 0x00000, 0x80000, CRC(4bbe0ed9) SHA1(081b73c4e4d4fa548445e5548573099bcb1e9213) )
ROM_LOAD( "c07-11.96", 0x80000, 0x80000, CRC(3c815699) SHA1(0471ff5b0c0da905267f2cee52fd68c8661cccc9) )
- ROM_REGION( 0x080000, "ymsnd:adpcmb", 0 ) /* Delta-T samples */
+ ROM_REGION( 0x080000, "ymsnd:adpcmb", 0 ) // Delta-T samples
ROM_LOAD( "c07-12.107", 0x00000, 0x80000, CRC(e0b71258) SHA1(0258e308b643d723475824752ebffc4ea29d1ac4) )
- ROM_REGION( 0x001000, "user1", 0 ) /* unknown roms */
+ ROM_REGION( 0x000800, "proms", 0 ) // unknown
ROM_LOAD( "c07-13.37", 0x00000, 0x00400, CRC(3ca18eb3) SHA1(54560f02c2be67993940831222130e90cd171991) )
- ROM_LOAD( "c07-14.38", 0x00000, 0x00400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) )
+ ROM_LOAD( "c07-14.38", 0x00400, 0x00400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) )
-// Pals, not dumped
-// ROM_LOAD( "C07-15.78", 0x00000, 0x00?00, NO_DUMP )
-// ROM_LOAD( "C07-16.79", 0x00000, 0x00?00, NO_DUMP )
+ ROM_REGION( 0x400, "plds", 0 ) // type and size unknown
+ ROM_LOAD( "c07-15.78", 0x000, 0x144, NO_DUMP )
+ ROM_LOAD( "c07-16.79", 0x144, 0x144, NO_DUMP )
ROM_END
ROM_START( darius2d )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 512K for 68000 code */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "c07_20-2.74", 0x00000, 0x20000, CRC(a0f345b8) SHA1(1ce46e9707ec9ad51b26acf613eedc0536d227ae) )
ROM_LOAD16_BYTE( "c07_19-2.73", 0x00001, 0x20000, CRC(925412c6) SHA1(7f1f62b7b2261c440dccd512ebd3faea141b7c83) )
ROM_LOAD16_BYTE( "c07_21-2.76", 0x40000, 0x20000, CRC(bdd60e37) SHA1(777d3f67deba7df0da9d2605b2e2198f4bf47ebc) )
ROM_LOAD16_BYTE( "c07_18-2.71", 0x40001, 0x20000, CRC(23fcd89b) SHA1(8aaf4ac836773d9b064ded68a6f092fe9eec7ac2) )
- ROM_LOAD16_WORD_SWAP( "c07-09.75", 0x80000, 0x80000, CRC(cc69c2ce) SHA1(47883b9e14d8b6dd74db221bff396477231938f2) ) /* data rom */
+ ROM_LOAD16_WORD_SWAP( "c07-09.75", 0x80000, 0x80000, CRC(cc69c2ce) SHA1(47883b9e14d8b6dd74db221bff396477231938f2) ) // data ROM
- ROM_REGION( 0x20000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x20000, "audiocpu", 0 )
ROM_LOAD( "c07_17.69", 0x00000, 0x20000, CRC(ae16c905) SHA1(70ba5aacd8a8e00b94719e3955abad8827c67aa8) )
- ROM_REGION( 0x200000, "sprites", 0 )
- ROM_LOAD64_WORD( "c07-05.24", 0x00000, 0x80000, CRC(fb6d0550) SHA1(2d570ff5ef262cb4cb52e8584a7f167263194d37) ) /* OBJ */
+ ROM_REGION( 0x200000, "sprites", 0 ) // OBJ
+ ROM_LOAD64_WORD( "c07-05.24", 0x00000, 0x80000, CRC(fb6d0550) SHA1(2d570ff5ef262cb4cb52e8584a7f167263194d37) )
ROM_LOAD64_WORD( "c07-06.27", 0x00002, 0x80000, CRC(5eebbcd6) SHA1(d4d860bf6b099956c45c7273ad77b1d35deba4c1) )
ROM_LOAD64_WORD( "c07-07.26", 0x00004, 0x80000, CRC(fd9f9e74) SHA1(e89beb5cac844fe16662465b0c76337692591aae) )
ROM_LOAD64_WORD( "c07-08.25", 0x00006, 0x80000, CRC(a07dc846) SHA1(7199a604fcd693215ddb7670bfb2daf150145fd7) )
- ROM_REGION( 0x100000, "tc0100scn_1", 0 )
- ROM_LOAD16_WORD_SWAP( "c07-03.12", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) ) /* SCr(screen 1) */
+ ROM_REGION( 0x100000, "tc0100scn_1", 0 ) // SCr(screen 1)
+ ROM_LOAD16_WORD_SWAP( "c07-03.12", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) )
ROM_LOAD16_WORD_SWAP( "c07-04.11", 0x80000, 0x80000, CRC(50421e81) SHA1(27ac420602f1dac00dc32903543a518e6f47fb2f) )
- ROM_REGION( 0x100000, "tc0100scn_2", 0 )
- ROM_LOAD16_WORD_SWAP( "c07-03.47", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) ) /* SCr(screen 2) */
+ ROM_REGION( 0x100000, "tc0100scn_2", 0 ) // SCr(screen 2)
+ ROM_LOAD16_WORD_SWAP( "c07-03.47", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) )
ROM_LOAD16_WORD_SWAP( "c07-04.48", 0x80000, 0x80000, CRC(50421e81) SHA1(27ac420602f1dac00dc32903543a518e6f47fb2f) )
- ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) /* ADPCM samples */
+ ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) // ADPCM samples
ROM_LOAD( "c07-10.95", 0x00000, 0x80000, CRC(4bbe0ed9) SHA1(081b73c4e4d4fa548445e5548573099bcb1e9213) )
ROM_LOAD( "c07-11.96", 0x80000, 0x80000, CRC(3c815699) SHA1(0471ff5b0c0da905267f2cee52fd68c8661cccc9) )
- ROM_REGION( 0x080000, "ymsnd:adpcmb", 0 ) /* Delta-T samples */
+ ROM_REGION( 0x080000, "ymsnd:adpcmb", 0 ) // Delta-T samples
ROM_LOAD( "c07-12.107", 0x00000, 0x80000, CRC(e0b71258) SHA1(0258e308b643d723475824752ebffc4ea29d1ac4) )
- ROM_REGION( 0x001000, "user1", 0 ) /* unknown roms */
+ ROM_REGION( 0x000800, "proms", 0 ) // unknown
ROM_LOAD( "c07-13.37", 0x00000, 0x00400, CRC(3ca18eb3) SHA1(54560f02c2be67993940831222130e90cd171991) )
- ROM_LOAD( "c07-14.38", 0x00000, 0x00400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) )
+ ROM_LOAD( "c07-14.38", 0x00400, 0x00400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) )
-// Pals, not dumped
-// ROM_LOAD( "C07-15.78", 0x00000, 0x00?00, NO_DUMP )
-// ROM_LOAD( "C07-16.79", 0x00000, 0x00?00, NO_DUMP )
+ ROM_REGION( 0x400, "plds", 0 ) // type and size unknown
+ ROM_LOAD( "c07-15.78", 0x000, 0x144, NO_DUMP )
+ ROM_LOAD( "c07-16.79", 0x144, 0x144, NO_DUMP )
ROM_END
ROM_START( darius2do )
- ROM_REGION( 0x100000, "maincpu", 0 ) /* 512K for 68000 code */
+ ROM_REGION( 0x100000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "c07_20-1.74", 0x00000, 0x20000, CRC(48b0804a) SHA1(932fb2cd55e6bfef84cf3cfaf3e75b4297a92b34) )
ROM_LOAD16_BYTE( "c07_19-1.73", 0x00001, 0x20000, CRC(1f9a4f83) SHA1(d02caef350bdcac0ff771b5c92bb4e7435e0c9fa) )
ROM_LOAD16_BYTE( "c07_21-1.76", 0x40000, 0x20000, CRC(b491b0ca) SHA1(dd7aa196c6002abc8e2f885f3f997f2279e59769) )
ROM_LOAD16_BYTE( "c07_18-1.71", 0x40001, 0x20000, CRC(c552e42f) SHA1(dc952002a9a738cb1789f7c51acb71693ae03549) )
- ROM_LOAD16_WORD_SWAP( "c07-09.75", 0x80000, 0x80000, CRC(cc69c2ce) SHA1(47883b9e14d8b6dd74db221bff396477231938f2) ) /* data rom */
+ ROM_LOAD16_WORD_SWAP( "c07-09.75", 0x80000, 0x80000, CRC(cc69c2ce) SHA1(47883b9e14d8b6dd74db221bff396477231938f2) ) // data ROM
- ROM_REGION( 0x20000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x20000, "audiocpu", 0 )
ROM_LOAD( "c07_17.69", 0x00000, 0x20000, CRC(ae16c905) SHA1(70ba5aacd8a8e00b94719e3955abad8827c67aa8) )
- ROM_REGION( 0x200000, "sprites", 0 )
- ROM_LOAD64_WORD( "c07-05.24", 0x00000, 0x80000, CRC(fb6d0550) SHA1(2d570ff5ef262cb4cb52e8584a7f167263194d37) ) /* OBJ */
+ ROM_REGION( 0x200000, "sprites", 0 ) // OBJ
+ ROM_LOAD64_WORD( "c07-05.24", 0x00000, 0x80000, CRC(fb6d0550) SHA1(2d570ff5ef262cb4cb52e8584a7f167263194d37) )
ROM_LOAD64_WORD( "c07-06.27", 0x00002, 0x80000, CRC(5eebbcd6) SHA1(d4d860bf6b099956c45c7273ad77b1d35deba4c1) )
ROM_LOAD64_WORD( "c07-07.26", 0x00004, 0x80000, CRC(fd9f9e74) SHA1(e89beb5cac844fe16662465b0c76337692591aae) )
ROM_LOAD64_WORD( "c07-08.25", 0x00006, 0x80000, CRC(a07dc846) SHA1(7199a604fcd693215ddb7670bfb2daf150145fd7) )
- ROM_REGION( 0x100000, "tc0100scn_1", 0 )
- ROM_LOAD16_WORD_SWAP( "c07-03.12", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) ) /* SCr(screen 1) */
+ ROM_REGION( 0x100000, "tc0100scn_1", 0 ) // SCr(screen 1)
+ ROM_LOAD16_WORD_SWAP( "c07-03.12", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) )
ROM_LOAD16_WORD_SWAP( "c07-04.11", 0x80000, 0x80000, CRC(50421e81) SHA1(27ac420602f1dac00dc32903543a518e6f47fb2f) )
- ROM_REGION( 0x100000, "tc0100scn_2", 0 )
- ROM_LOAD16_WORD_SWAP( "c07-03.47", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) ) /* SCr(screen 2) */
+ ROM_REGION( 0x100000, "tc0100scn_2", 0 ) // SCr(screen 2)
+ ROM_LOAD16_WORD_SWAP( "c07-03.47", 0x00000, 0x80000, CRC(189bafce) SHA1(d885e444523489fe24269b90dec58e0d92cfbd6e) )
ROM_LOAD16_WORD_SWAP( "c07-04.48", 0x80000, 0x80000, CRC(50421e81) SHA1(27ac420602f1dac00dc32903543a518e6f47fb2f) )
- ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) /* ADPCM samples */
+ ROM_REGION( 0x100000, "ymsnd:adpcma", 0 ) // ADPCM samples
ROM_LOAD( "c07-10.95", 0x00000, 0x80000, CRC(4bbe0ed9) SHA1(081b73c4e4d4fa548445e5548573099bcb1e9213) )
ROM_LOAD( "c07-11.96", 0x80000, 0x80000, CRC(3c815699) SHA1(0471ff5b0c0da905267f2cee52fd68c8661cccc9) )
- ROM_REGION( 0x080000, "ymsnd:adpcmb", 0 ) /* Delta-T samples */
+ ROM_REGION( 0x080000, "ymsnd:adpcmb", 0 ) // Delta-T samples
ROM_LOAD( "c07-12.107", 0x00000, 0x80000, CRC(e0b71258) SHA1(0258e308b643d723475824752ebffc4ea29d1ac4) )
- ROM_REGION( 0x001000, "user1", 0 ) /* unknown roms */
+ ROM_REGION( 0x000800, "proms", 0 ) // unknown
ROM_LOAD( "c07-13.37", 0x00000, 0x00400, CRC(3ca18eb3) SHA1(54560f02c2be67993940831222130e90cd171991) )
- ROM_LOAD( "c07-14.38", 0x00000, 0x00400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) )
+ ROM_LOAD( "c07-14.38", 0x00400, 0x00400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) )
ROM_END
ROM_START( warriorb )
- ROM_REGION( 0x200000, "maincpu", 0 ) /* 1024K for 68000 code */
+ ROM_REGION( 0x200000, "maincpu", 0 ) // 68000 code
ROM_LOAD16_BYTE( "d24_20-1.74", 0x000000, 0x40000, CRC(4452dc25) SHA1(bbb4fbc25a3f263ce2716698cacaca201cb9591b) )
ROM_LOAD16_BYTE( "d24_19-1.73", 0x000001, 0x40000, CRC(15c16016) SHA1(5b28834d8d5296c562c90a861c6ccdd46cc3c204) )
ROM_LOAD16_BYTE( "d24_21-1.76", 0x080000, 0x40000, CRC(783ef8e1) SHA1(28a43d5231031b2ff3e437c3b6b8604f0d2b521b) )
ROM_LOAD16_BYTE( "d24_18-1.71", 0x080001, 0x40000, CRC(4502db60) SHA1(b29c441ab79f753378ea47e7c22924db0cd5eb89) )
- ROM_LOAD16_WORD_SWAP( "d24-09.75", 0x100000, 0x100000, CRC(ece5cc59) SHA1(337db41d5a74fa4202b1be1a672a068ec3b205a8) ) /* data rom */
- /* Note: Raine wrongly doubles up d24-09 as delta-t samples */
+ ROM_LOAD16_WORD_SWAP( "d24-09.75", 0x100000, 0x100000, CRC(ece5cc59) SHA1(337db41d5a74fa4202b1be1a672a068ec3b205a8) ) // data ROM
- ROM_REGION( 0x20000, "audiocpu", 0 ) /* sound cpu */
+ ROM_REGION( 0x20000, "audiocpu", 0 )
ROM_LOAD( "d24_17.69", 0x00000, 0x20000, CRC(e41e4aae) SHA1(9bf40b6e8aa5c6ec62c5d21edbb2214f6550c94f) )
- ROM_REGION( 0x400000, "sprites", 0 )
- ROM_LOAD64_WORD( "d24-03.24", 0x000000, 0x100000, CRC(46db9fd7) SHA1(f08f3c9833d80ce161b06f4ae484c5c79539639c) ) /* OBJ */
+ ROM_REGION( 0x400000, "sprites", 0 ) // OBJ
+ ROM_LOAD64_WORD( "d24-03.24", 0x000000, 0x100000, CRC(46db9fd7) SHA1(f08f3c9833d80ce161b06f4ae484c5c79539639c) )
ROM_LOAD64_WORD( "d24-06.27", 0x000002, 0x100000, CRC(918486fe) SHA1(cc9e287221ef33dba77a22975e23b250ba50b758) )
ROM_LOAD64_WORD( "d24-05.26", 0x000004, 0x100000, CRC(9f414317) SHA1(204cf47404e5e1085c1108abacd2b79a6cd0f74a) )
ROM_LOAD64_WORD( "d24-04.25", 0x000006, 0x100000, CRC(148e0493) SHA1(f1cb819830e5bd544b11762784e228b5cb62b7e4) )
- ROM_REGION( 0x200000, "tc0100scn_1", 0 )
- ROM_LOAD16_WORD_SWAP( "d24-02.12", 0x000000, 0x100000, CRC(9f50c271) SHA1(1a1b2ae7cb7785e7f66aa26258a6cd2921a29545) ) /* SCR A, screen 1 */
+ ROM_REGION( 0x200000, "tc0100scn_1", 0 )// SCR A, screen 1
+ ROM_LOAD16_WORD_SWAP( "d24-02.12", 0x000000, 0x100000, CRC(9f50c271) SHA1(1a1b2ae7cb7785e7f66aa26258a6cd2921a29545) )
ROM_LOAD16_WORD_SWAP( "d24-01.11", 0x100000, 0x100000, CRC(326dcca9) SHA1(1993776d71bca7d6dfc6f84dd9262d0dcae87f69) )
- ROM_REGION( 0x200000, "tc0100scn_2", 0 )
- ROM_LOAD16_WORD_SWAP( "d24-07.47", 0x000000, 0x100000, CRC(9f50c271) SHA1(1a1b2ae7cb7785e7f66aa26258a6cd2921a29545) ) /* SCR B, screen 2 */
+ ROM_REGION( 0x200000, "tc0100scn_2", 0 ) // SCR B, screen 2
+ ROM_LOAD16_WORD_SWAP( "d24-07.47", 0x000000, 0x100000, CRC(9f50c271) SHA1(1a1b2ae7cb7785e7f66aa26258a6cd2921a29545) )
ROM_LOAD16_WORD_SWAP( "d24-08.48", 0x100000, 0x100000, CRC(1e6d1528) SHA1(d6843aa67befd7db44f468be16ba2f0efb85d40f) )
- ROM_REGION( 0x300000, "ymsnd:adpcma", 0 ) /* ADPCM samples */
+ ROM_REGION( 0x300000, "ymsnd:adpcma", 0 ) // ADPCM samples
ROM_LOAD( "d24-12.107", 0x000000, 0x100000, CRC(279203a1) SHA1(ed75e811a1f0863c134034457ce2e97372726bdb) )
ROM_LOAD( "d24-10.95", 0x100000, 0x100000, CRC(0e0c716d) SHA1(5e2f334dd484678766c5a71196d9bad0ba0fe8d9) )
ROM_LOAD( "d24-11.118", 0x200000, 0x100000, CRC(15362573) SHA1(8602c9f24134cac6fe1375fb189b152f0c68aeb7) )
- /* No Delta-T samples */
+ // No Delta-T samples
+
+ ROM_REGION( 0x000800, "proms", 0 ) // unknown
+ ROM_LOAD( "d24-13.37", 0x00000, 0x400, CRC(3ca18eb3) SHA1(54560f02c2be67993940831222130e90cd171991) ) // AM27S33A or compatible like N82HS137A
+ ROM_LOAD( "d24-14.38", 0x00400, 0x400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) ) // AM27S33A or compatible like N82HS137A
- ROM_REGION( 0x01000, "user1", 0 ) /* unknown roms */
- ROM_LOAD( "d24-13.37", 0x00000, 0x400, CRC(3ca18eb3) SHA1(54560f02c2be67993940831222130e90cd171991) ) /* AM27S33A or compatible like N82HS137A */
- ROM_LOAD( "d24-14.38", 0x00000, 0x400, CRC(baf2a193) SHA1(b7f103b5f5aab0702dd21fd7e3a82261ae1760e9) ) /* AM27S33A or compatible like N82HS137A */
+ ROM_REGION( 0x000288, "plds", 0 )
ROM_LOAD( "d24-15.78", 0x00000, 0x144, CRC(04992a7d) SHA1(82ce7ab7e3e7045776b660c32dac4abc28cabfa5) ) // PAL20L8BCNS
- ROM_LOAD( "d24-16.79", 0x00000, 0x144, CRC(92c59a8d) SHA1(a83eb70cdc47af688a33505f60e5cb9960f8ba9f) ) // PAL20L8BCNS
+ ROM_LOAD( "d24-16.79", 0x00144, 0x144, CRC(92c59a8d) SHA1(a83eb70cdc47af688a33505f60e5cb9960f8ba9f) ) // PAL20L8BCNS
ROM_END
+} // anonymous namespace
-/* Working Games */
// YEAR, NAME, PARENT, MACHINE, INPUT, STATE, INIT, MONITOR,COMPANY,FULLNAME, FLAGS
GAME( 1989, sagaia, darius2, darius2d, sagaia, warriorb_state, empty_init, ROT0, "Taito Corporation Japan", "Sagaia (dual screen) (World)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND )
diff --git a/src/mame/taito/warriorb.h b/src/mame/taito/warriorb.h
deleted file mode 100644
index 90a8d61ec90..00000000000
--- a/src/mame/taito/warriorb.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Graves
-/*************************************************************************
-
- Taito Dual Screen Games
-
-*************************************************************************/
-
-#include "taitosnd.h"
-#include "taitoio.h"
-#include "sound/flt_vol.h"
-#include "tc0100scn.h"
-#include "tc0110pcr.h"
-#include "emupal.h"
-
-
-class warriorb_state : public driver_device
-{
-public:
- warriorb_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_tc0140syt(*this, "tc0140syt"),
- m_tc0100scn(*this, "tc0100scn_%u", 1),
- m_tc0110pcr(*this, "tc0110pcr_%u", 1),
- m_tc0220ioc(*this, "tc0220ioc"),
- m_tc0510nio(*this, "tc0510nio"),
- m_2610_l(*this, "2610.%u.l", 1),
- m_2610_r(*this, "2610.%u.r", 1),
- m_gfxdecode(*this, "gfxdecode_%u", 1),
- m_spriteram(*this, "spriteram"),
- m_z80bank(*this, "z80bank")
- { }
-
- void warriorb(machine_config &config);
- void darius2d(machine_config &config);
-
-private:
- /* devices */
- required_device<cpu_device> m_maincpu;
- required_device<tc0140syt_device> m_tc0140syt;
- required_device_array<tc0100scn_device, 2> m_tc0100scn;
- required_device_array<tc0110pcr_device, 2> m_tc0110pcr;
- optional_device<tc0220ioc_device> m_tc0220ioc;
- optional_device<tc0510nio_device> m_tc0510nio;
- required_device_array<filter_volume_device, 2> m_2610_l;
- required_device_array<filter_volume_device, 2> m_2610_r;
- required_device_array<gfxdecode_device, 2> m_gfxdecode;
-
- /* memory pointers */
- required_shared_ptr<u16> m_spriteram;
-
- /* memory regions */
- required_memory_bank m_z80bank;
-
- /* misc */
- int m_pandata[4]{};
-
- void coin_control_w(u8 data);
- void sound_bankswitch_w(u8 data);
- void pancontrol_w(offs_t offset, u8 data);
- void tc0100scn_dual_screen_w(offs_t offset, u16 data, u16 mem_mask = ~0);
-
- virtual void machine_start() override;
- virtual void machine_reset() override;
-
- u32 screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- u32 screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int x_offs, int y_offs, int chip);
- u32 update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int xoffs, int chip);
-
- void darius2d_map(address_map &map);
- void warriorb_map(address_map &map);
- void z80_sound_map(address_map &map);
-};
diff --git a/src/mame/taito/warriorb_v.cpp b/src/mame/taito/warriorb_v.cpp
deleted file mode 100644
index 5ccf2594cf1..00000000000
--- a/src/mame/taito/warriorb_v.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Graves
-#include "emu.h"
-#include "warriorb.h"
-#include "screen.h"
-
-/************************************************************
- SPRITE DRAW ROUTINE
-************************************************************/
-
-void warriorb_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int x_offs, int y_offs, int chip)
-{
- u32 pri_mask;
-
-#ifdef MAME_DEBUG
- int unknown = 0;
-#endif
-
- /* pdrawgfx() needs us to draw sprites front to back */
- for (int offs = 0; offs < m_spriteram.bytes() / 2; offs += 4)
- {
- int data = m_spriteram[offs + 1];
- const u32 tilenum = data & 0x7fff;
-
- data = m_spriteram[offs + 0];
- int y = (-(data & 0x1ff) - 24) & 0x1ff; /* (inverted y adjusted for vis area) */
- const bool flipy = (data & 0x200) >> 9;
-
- const u16 data2 = m_spriteram[offs + 2];
- /* 8,4 also seen in msbyte */
- const int priority = (data2 & 0x0100) >> 8; // 1 = low
-
- if(priority)
- pri_mask = 0xfffe;
- else
- pri_mask = 0;
-
- const u32 color = (data2 & 0x7f);
-
- data = m_spriteram[offs + 3];
- int x = (data & 0x3ff);
- const bool flipx = (data & 0x400) >> 10;
-
-#ifdef MAME_DEBUG
- if (data2 & 0xf280) unknown |= (data2 &0xf280);
-#endif
-
- x -= x_offs;
- y += y_offs;
-
- /* sprite wrap: coords become negative at high values */
- if (x > 0x3c0) x -= 0x400;
- if (y > 0x180) y -= 0x200;
-
- m_gfxdecode[chip]->gfx(0)->prio_transpen(bitmap,cliprect,
- tilenum,
- color,
- flipx,flipy,
- x,y,
- screen.priority(),pri_mask,0);
- }
-
-#ifdef MAME_DEBUG
- if (unknown)
- popmessage("unknown sprite bits: %04x",unknown);
-#endif
-}
-
-
-/**************************************************************
- SCREEN REFRESH
-**************************************************************/
-
-u32 warriorb_state::update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int xoffs, int chip)
-{
- tc0100scn_device *tc0100scn = m_tc0100scn[chip];
- u8 layer[3];
-
- tc0100scn->tilemap_update();
-
- layer[0] = tc0100scn->bottomlayer();
- layer[1] = layer[0] ^ 1;
- layer[2] = 2;
-
- /* Clear priority bitmap */
- screen.priority().fill(0, cliprect);
-
- /* chip 0 does tilemaps on the left, chip 1 does the ones on the right */
- // draw bottom layer
- const u8 nodraw = tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 0); /* left */
-
- /* Ensure screen blanked even when bottom layers not drawn due to disable bit */
- if (nodraw)
- bitmap.fill(m_tc0110pcr[chip]->black_pen(), cliprect);
-
- // draw middle layer
- tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[1], 0, 1);
-
- /* Sprites can be under/over the layer below text layer */
- draw_sprites(screen, bitmap, cliprect, xoffs * chip, 8, chip); // draw sprites
-
- // draw top(text) layer
- tc0100scn->tilemap_draw(screen, bitmap, cliprect, layer[2], 0, 0);
- return 0;
-}
-
-u32 warriorb_state::screen_update_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 40 * 8, 0); }
-u32 warriorb_state::screen_update_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 40 * 8, 1); }
diff --git a/src/mame/tecmo/spbactn.cpp b/src/mame/tecmo/spbactn.cpp
index d9f575e694b..326211c9c8b 100644
--- a/src/mame/tecmo/spbactn.cpp
+++ b/src/mame/tecmo/spbactn.cpp
@@ -634,7 +634,7 @@ static INPUT_PORTS_START( spbactnp )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME( "Launch Ball / Shake" )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_START("DSW") // TODO: double check these
+ PORT_START("DSW") // TODO: double check 0x0100, 0x0800, 0xc000
PORT_DIPNAME( 0x0003, 0x0003, "Balls" ) PORT_DIPLOCATION("SW1:8,7")
PORT_DIPSETTING( 0x0000, "2" )
PORT_DIPSETTING( 0x0003, "3" )
@@ -642,21 +642,21 @@ static INPUT_PORTS_START( spbactnp )
PORT_DIPSETTING( 0x0002, "5" )
PORT_DIPNAME( 0x001c, 0x001c, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:6,5,4")
PORT_DIPSETTING( 0x0008, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x000c, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0x0010, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x0004, "2 Coins/1 Credit 3/2" )
+ PORT_DIPSETTING( 0x0018, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x0004, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x0010, "2 Coins/1 Credit 3/2" )
PORT_DIPSETTING( 0x001c, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x0014, "1 Coin/1 Credit 2/3" )
- PORT_DIPSETTING( 0x0018, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x000c, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0000, "1 Coin/1 Credit 5/6" )
PORT_DIPNAME( 0x00e0, 0x00e0, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:3,2,1")
PORT_DIPSETTING( 0x0040, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x0060, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0x0080, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x0020, "2 Coins/1 Credit 3/2" )
+ PORT_DIPSETTING( 0x00c0, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x0080, "2 Coins/1 Credit 3/2" )
PORT_DIPSETTING( 0x00e0, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x00a0, "1 Coin/1 Credit 2/3" )
- PORT_DIPSETTING( 0x00c0, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x0060, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x0000, "1 Coin/1 Credit 5/6" )
PORT_DIPNAME( 0x0100, 0x0100, "Match" ) PORT_DIPLOCATION("SW2:8")
PORT_DIPSETTING( 0x0100, "1/20" )
@@ -671,9 +671,9 @@ static INPUT_PORTS_START( spbactnp )
PORT_DIPSETTING( 0x0800, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x0000, DEF_STR( Difficult ) )
PORT_DIPNAME( 0x3000, 0x3000, "Extra Ball" ) PORT_DIPLOCATION("SW2:4,3")
- PORT_DIPSETTING( 0x1000, "100k and 500k" )
+ PORT_DIPSETTING( 0x2000, "100k and 500k" )
PORT_DIPSETTING( 0x3000, "200k and 800k" )
- PORT_DIPSETTING( 0x2000, "200k" )
+ PORT_DIPSETTING( 0x1000, "200k" )
PORT_DIPSETTING( 0x0000, DEF_STR( None ) )
PORT_DIPNAME( 0xc000, 0xc000, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:2,1")
PORT_DIPSETTING( 0x8000, DEF_STR( Easy ) )
diff --git a/src/mame/universal/getaway.cpp b/src/mame/universal/getaway.cpp
index e4197c15a07..e552e19a0ae 100644
--- a/src/mame/universal/getaway.cpp
+++ b/src/mame/universal/getaway.cpp
@@ -15,23 +15,19 @@ Hardware notes:
Japanese-language flyers show an upright cabinet with a start button, steering
wheel and a control lever marked LOW at the upper end of the range and HIGH at
-the lower end. It appears to be spring-returned to the LOW position. The
-cabinet appears to have the position where an accelerator pedal would be
-located covered with a panel. The dumped set seems to be designed for this
-cabinet.
+the lower end. It appears to be spring-returned to the LOW position. The cabinet
+appears to have the position where an accelerator pedal would be located covered
+with a panel. The dumped set seems to be designed for this cabinet.
English-language flyers show a sit-down cabinet with a gear shift lever,
-accelerator pedal, and digital displays for high scores. The set dumped set
-doesn't have support for the additional I/O.
+accelerator pedal, and digital displays for high scores. The dumped set doesn't
+have support for the additional I/O.
TODO:
-- unknown DIP switches, and verify factory defaults;
+- verify DIP switches factory defaults (not mentioned in Japanese manual);
- several unknowns in the video emulation:
- score layer is a simplification hack, it is unknown how it should really
- cope RMW-wise against main layer. It also has wrong colors (different color
- base or overlay artwork, with extra bit output for taking priority?).
- The score background color should change from white(or is it cyan?) to red
- after Extended Play, the score digits themselves should always be black;
+ cope RMW-wise against main layer;
- According to flyers, screen sides should have a green background color,
it can't be an artwork overlay since it only occurs when the trees are
on screen. However, the German flyer contains a cabinet photo and there
@@ -65,7 +61,7 @@ public:
, m_gfxrom(*this, "gfx")
, m_screen(*this, "screen")
, m_inputs(*this, "IN.%u", 0)
- , m_dsw(*this, "DSW.%u", 0)
+ , m_dsw(*this, "DSW")
, m_wheel(*this, "WHEEL")
{ }
@@ -84,7 +80,7 @@ private:
required_region_ptr<u8> m_gfxrom;
required_device<screen_device> m_screen;
required_ioport_array<3> m_inputs;
- required_ioport_array<2> m_dsw;
+ required_ioport m_dsw;
required_ioport m_wheel;
void main_map(address_map &map);
@@ -94,7 +90,7 @@ private:
DECLARE_WRITE_LINE_MEMBER(vblank_irq);
void io_w(offs_t offset, u8 data);
- template <unsigned N> u8 dsw_r(offs_t offset);
+ u8 dsw_r(offs_t offset);
template <unsigned N> u8 input_r(offs_t offset);
u8 busy_r();
@@ -122,34 +118,22 @@ void getaway_state::machine_start()
u32 getaway_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- // apparently score overlay covers only the rightmost 3 columns
- const int x_overlay = 29*8;
-
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- for (int x = cliprect.min_x; x <= cliprect.max_x; x+=8)
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- u16 xi = x >> 3;
- u8 b = m_vram[0x0000 | (xi << 8 | y)];
- u8 g = m_vram[0x2000 | (xi << 8 | y)];
- u8 r = m_vram[0x4000 | (xi << 8 | y)];
-
- for (int i = 0; i < 8; i++)
- bitmap.pix(y, x + i) = BIT(r, i) << 2 | BIT(g, i) << 1 | BIT(b, i);
-
- if (x < x_overlay)
- continue;
+ // score panel covers the right(top) part of the screen
+ const u16 panel_offset = 29 * 8 - 1;
+ u8 *vram = (x < panel_offset) ? m_vram : m_score_vram;
- b = m_score_vram[0x0000 | (xi << 8 | y)];
- g = m_score_vram[0x2000 | (xi << 8 | y)];
- r = m_score_vram[0x4000 | (xi << 8 | y)];
+ u16 xi = x >> 3;
+ u8 bit0 = BIT(vram[0x0000 | (xi << 8 | y)], x & 7);
+ u8 bit1 = BIT(vram[0x2000 | (xi << 8 | y)], x & 7);
+ u8 bit2 = BIT(vram[0x4000 | (xi << 8 | y)], x & 7);
- for (int i = 0; i < 8; i++)
- {
- u8 pix_data = BIT(r, i) << 2 | BIT(g, i) << 1 | BIT(b, i);
- if (pix_data != 0)
- bitmap.pix(y, x + i) = pix_data;
- }
+ // palette is a bit scrambled
+ static const u8 clut[8] = { 0, 1, 6, 5, 4, 3, 2, 7 };
+ bitmap.pix(y, x) = clut[bit2 << 2 | bit1 << 1 | bit0];
}
}
@@ -207,7 +191,7 @@ void getaway_state::io_w(offs_t offset, u8 data)
[0x07]
???w wwww transfer width, in 8 pixel units
- Notice that 0xff is set on POST, either full clear or NOP
+ Notice that 0xff is set on POST, either full clear or NOP
[0x08]
hhhh hhhh transfer height, in scanline units
@@ -235,7 +219,6 @@ void getaway_state::io_w(offs_t offset, u8 data)
u16 src = m_regs[6] << 8 | m_regs[5];
// several valid entries are drawn with color=0 cfr. tyres
// flyer shows them as white so definitely xor-ed
- // TODO: may be applied at palette init time instead + score layer colors doesn't match flyer.
u8 color_mask = (src >> 13) ^ 7;
src &= 0x1fff;
src <<= 3;
@@ -263,13 +246,15 @@ void getaway_state::io_w(offs_t offset, u8 data)
if (fill_mode)
{
+ // different method for score panel?
+ u8 fill_mask = layer_bank ? 0 : color_mask;
for (int i = 0; i < 3; i++)
{
- // reversed for score VRAM?
- if (layer_bank)
- vram[i * 0x2000 + dest] &= ~pen_mask;
+ u16 out_bank = i * 0x2000 + dest;
+ if (BIT(fill_mask, i))
+ vram[out_bank] |= pen_mask;
else
- vram[i * 0x2000 + dest] |= pen_mask;
+ vram[out_bank] &= ~pen_mask;
}
}
else
@@ -308,9 +293,9 @@ template <unsigned N> u8 getaway_state::input_r(offs_t offset)
return BIT(m_inputs[N]->read(), offset);
}
-template <unsigned N> u8 getaway_state::dsw_r(offs_t offset)
+u8 getaway_state::dsw_r(offs_t offset)
{
- return BIT(m_dsw[N]->read(), offset);
+ return BIT(m_dsw->read(), offset);
}
@@ -330,8 +315,7 @@ void getaway_state::io_map(address_map &map)
map(0x00, 0xff).w(FUNC(getaway_state::io_w));
map(0x00, 0x09).r(FUNC(getaway_state::input_r<1>)); // accelerator
map(0x0a, 0x19).r(FUNC(getaway_state::input_r<2>)); // steering wheel
- map(0x1a, 0x21).r(FUNC(getaway_state::dsw_r<1>));
- map(0x22, 0x2f).r(FUNC(getaway_state::dsw_r<0>));
+ map(0x1a, 0x2f).r(FUNC(getaway_state::dsw_r));
map(0x32, 0x35).r(FUNC(getaway_state::input_r<0>)); // coin + start
map(0x36, 0x37).r(FUNC(getaway_state::busy_r));
}
@@ -357,46 +341,41 @@ static INPUT_PORTS_START( getaway )
PORT_START("WHEEL")
PORT_BIT( 0xff, 0x08, IPT_PADDLE ) PORT_MINMAX(0x00, 0x10) PORT_SENSITIVITY(5) PORT_KEYDELTA(15)
- PORT_START("DSW.0") // DTS-8 DIP switch @ location k6
- // TODO: defaults for these two, assume they have different quotas?
- PORT_DIPNAME( 0x07, 0x02, "Extended Play" )
- PORT_DIPSETTING( 0x00, "None" )
- PORT_DIPSETTING( 0x01, "2000" )
- PORT_DIPSETTING( 0x02, "3000" )
- PORT_DIPSETTING( 0x03, "4000" )
- PORT_DIPSETTING( 0x04, "5000" )
- PORT_DIPSETTING( 0x05, "6000" )
- PORT_DIPSETTING( 0x06, "7000" )
- PORT_DIPSETTING( 0x07, "8000" )
- PORT_DIPNAME( 0x38, 0x28, "Extra Play" )
- PORT_DIPSETTING( 0x00, "None" )
- PORT_DIPSETTING( 0x08, "2000" )
- PORT_DIPSETTING( 0x10, "3000" )
- PORT_DIPSETTING( 0x18, "4000" )
- PORT_DIPSETTING( 0x20, "5000" )
- PORT_DIPSETTING( 0x28, "6000" )
- PORT_DIPSETTING( 0x30, "7000" )
- PORT_DIPSETTING( 0x38, "8000" )
- PORT_DIPNAME( 0x40, 0x00, "Language" )
- PORT_DIPSETTING( 0x00, "English" )
- PORT_DIPSETTING( 0x40, "Japanese" )
- PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x80, DEF_STR( On ) )
-
- PORT_START("DSW.1") // DNS04 DIP switch @ location m7
+ PORT_START("DSW")
// credit display is shown if both extended plays are on "None"
- PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coinage ) )
- PORT_DIPSETTING( 0x02, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
- PORT_DIPSETTING( 0x03, "1 Coin/1 Credit (again)" )
- PORT_DIPSETTING( 0x01, DEF_STR( 1C_2C ) )
- PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x04, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x08, DEF_STR( On ) )
+ PORT_DIPNAME( 0x003, 0x000, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SWB:3,2")
+ PORT_DIPSETTING( 0x002, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x000, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x003, "1 Coin/1 Credit (again)" ) // not mentioned in manual
+ PORT_DIPSETTING( 0x001, DEF_STR( 1C_2C ) )
+ // game time setting determines duration of one 'second'
+ // As for the weird min/max terms? that's what the manual calls these settings.
+ PORT_DIPNAME( 0x00c, 0x004, "Game Time" ) PORT_DIPLOCATION("SWB:1,SWA:5")
+ PORT_DIPSETTING( 0x00c, "Min I" )
+ PORT_DIPSETTING( 0x008, "Min II" )
+ PORT_DIPSETTING( 0x004, "Max I" )
+ PORT_DIPSETTING( 0x000, "Max II" )
+ PORT_DIPNAME( 0x070, 0x020, "Extended Play" ) PORT_DIPLOCATION("SWA:6,7,8")
+ PORT_DIPSETTING( 0x000, "None" )
+ PORT_DIPSETTING( 0x010, "2000" )
+ PORT_DIPSETTING( 0x020, "3000" )
+ PORT_DIPSETTING( 0x030, "4000" )
+ PORT_DIPSETTING( 0x040, "5000" )
+ PORT_DIPSETTING( 0x050, "6000" )
+ PORT_DIPSETTING( 0x060, "7000" )
+ PORT_DIPSETTING( 0x070, "8000" )
+ PORT_DIPNAME( 0x380, 0x280, "Extra Play" ) PORT_DIPLOCATION("SWA:4,3,2")
+ PORT_DIPSETTING( 0x000, "None" )
+ PORT_DIPSETTING( 0x080, "2000" )
+ PORT_DIPSETTING( 0x100, "3000" )
+ PORT_DIPSETTING( 0x180, "4000" )
+ PORT_DIPSETTING( 0x200, "5000" )
+ PORT_DIPSETTING( 0x280, "6000" )
+ PORT_DIPSETTING( 0x300, "7000" )
+ PORT_DIPSETTING( 0x380, "8000" )
+ PORT_DIPNAME( 0x400, 0x000, "Language" ) PORT_DIPLOCATION("SWA:1")
+ PORT_DIPSETTING( 0x000, "English" )
+ PORT_DIPSETTING( 0x400, "Japanese" )
INPUT_PORTS_END
@@ -407,23 +386,24 @@ INPUT_PORTS_END
void getaway_state::getaway(machine_config &config)
{
- /* basic machine hardware */
+ // basic machine hardware
TMS9900(config, m_maincpu, 48_MHz_XTAL/16);
m_maincpu->set_addrmap(AS_PROGRAM, &getaway_state::main_map);
m_maincpu->set_addrmap(AS_IO, &getaway_state::io_map);
m_maincpu->intlevel_cb().set_constant(2);
- /* video hardware */
+ // video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
m_screen->set_size(32*8, 32*8);
- m_screen->set_visarea(0*8, 32*8-1, 0*8, 30*8-1);
+ m_screen->set_visarea(1*8, 32*8-1, 0*8, 30*8-1);
m_screen->set_screen_update(FUNC(getaway_state::screen_update));
m_screen->screen_vblank().set(FUNC(getaway_state::vblank_irq));
m_screen->set_palette("palette");
- PALETTE(config, "palette", palette_device::BGR_3BIT);
- /* sound hardware */
+ PALETTE(config, "palette", palette_device::BRG_3BIT);
+
+ // sound hardware
// TODO: discrete
}
@@ -454,4 +434,4 @@ ROM_END
******************************************************************************/
// YEAR NAME PARENT MACHINE INPUT CLASS INIT SCREEN COMPANY FULLNAME FLAGS
-GAME( 1979, getaway, 0, getaway, getaway, getaway_state, empty_init, ROT270, "Universal", "Get A Way (upright)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_COLORS | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS )
+GAME( 1979, getaway, 0, getaway, getaway, getaway_state, empty_init, ROT270, "Universal", "Get A Way (upright)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS )
diff --git a/src/mame/universal/ladybug.cpp b/src/mame/universal/ladybug.cpp
index d6e8b8869ae..512333b513e 100644
--- a/src/mame/universal/ladybug.cpp
+++ b/src/mame/universal/ladybug.cpp
@@ -50,76 +50,192 @@ TODO:
***************************************************************************/
-/***************************************************************************
-
-Universal 8203-A + 8203-B PCB set
-
-Mrs. Dynamite
-Space Raider
-
-Space Raider also uses the Starfield generator board from Zero Hour,
- Connected via flywires to these boards
-
-TODO:
-
-decode cpu#2 writes to port 0x30 and 0x38 - resistors for sound
-decode cpu#2 writes to port 0x28-0x2f - ???
-examine other bits from cpu#2 write to 0xe800
-unknown dips
-
- ***************************************************************************/
-
#include "emu.h"
-#include "ladybug.h"
+#include "ladybug_video.h"
#include "cpu/z80/z80.h"
#include "machine/74259.h"
-#include "machine/gen_latch.h"
#include "sound/sn76496.h"
+#include "video/resnet.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
-#include <algorithm>
+namespace {
-// documentation TBD - 556 dual timer
-uint8_t mrsdyna_state::mrsdyna_rnd_r()
+// base ladybug platform
+class ladybug_state : public driver_device
{
- return rand() % 4;
-}
+public:
+ ladybug_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_video(*this, "video")
+ , m_port_dsw0(*this, "DSW0")
+ , m_p1_control(*this, "CONTP1")
+ , m_p2_control(*this, "CONTP2")
+ { }
+
+ DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p1_control_r);
+ DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p2_control_r);
+ DECLARE_INPUT_CHANGED_MEMBER(coin1_inserted);
+ DECLARE_INPUT_CHANGED_MEMBER(coin2_inserted);
+ void ladybug(machine_config &config);
+
+protected:
+ DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
+ void ladybug_palette(palette_device &palette) const;
+ u32 screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void ladybug_map(address_map &map);
+
+ required_device<cpu_device> m_maincpu;
+
+private:
+ required_device<ladybug_video_device> m_video;
+
+ required_ioport m_port_dsw0;
+ optional_ioport m_p1_control;
+ optional_ioport m_p2_control;
+};
-// Protection - documentation TBD
-uint8_t mrsdyna_state::mrsdyna_protection_r()
+// ladybug plus program decryption
+class dorodon_state : public ladybug_state
{
- // This must return X011111X or cpu #1 will hang
- // see code at rst $10
- return 0x3e;
+public:
+ dorodon_state(const machine_config &mconfig, device_type type, const char *tag)
+ : ladybug_state(mconfig, type, tag)
+ , m_decrypted_opcodes(*this, "decrypted_opcodes")
+ { }
+
+ void init_dorodon();
+ void dorodon(machine_config &config);
+
+protected:
+ void decrypted_opcodes_map(address_map &map);
+
+private:
+ required_shared_ptr<u8> m_decrypted_opcodes;
+};
+
+void dorodon_state::init_dorodon()
+{
+ /* decode the opcodes */
+ u8 *rom = memregion("maincpu")->base();
+ u8 *table = memregion("user1")->base();
+
+ for (offs_t i = 0; i < 0x6000; i++)
+ m_decrypted_opcodes[i] = table[rom[i]];
}
-// Unknown IO - documentation TBD
-void mrsdyna_state::mrsdyna_weird_w(offs_t offset, uint8_t data)
+
+
+/***************************************************************************
+ Video
+***************************************************************************/
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ Lady Bug has a 32 bytes palette PROM and a 32 bytes sprite color lookup
+ table PROM.
+ The palette PROM is connected to the RGB output this way:
+
+ bit 7 -- inverter -- 220 ohm resistor -- BLUE
+ -- inverter -- 220 ohm resistor -- GREEN
+ -- inverter -- 220 ohm resistor -- RED
+ -- inverter -- 470 ohm resistor -- BLUE
+ -- unused
+ -- inverter -- 470 ohm resistor -- GREEN
+ -- unused
+ bit 0 -- inverter -- 470 ohm resistor -- RED
+
+***************************************************************************/
+
+void ladybug_state::ladybug_palette(palette_device &palette) const
{
- // These 8 bits are stored in the LS259 latch at A7,
- // and connected to all the select lines on 2 4066s at B7/C7
- m_weird_value[offset & 7] = data & 1;
+ static constexpr int resistances[2] = { 470, 220 };
+
+ // compute the color output resistor weights
+ double rweights[2], gweights[2], bweights[2];
+ compute_resistor_weights(0, 255, -1.0,
+ 2, resistances, rweights, 470, 0,
+ 2, resistances, gweights, 470, 0,
+ 2, resistances, bweights, 470, 0);
+
+ const u8 *color_prom = memregion("proms")->base();
+
+ // create a lookup table for the palette
+ for (int i = 0; i < 0x20; i++)
+ {
+ int bit0, bit1;
+
+ // red component
+ bit0 = BIT(~color_prom[i], 0);
+ bit1 = BIT(~color_prom[i], 5);
+ int const r = combine_weights(rweights, bit0, bit1);
+
+ // green component
+ bit0 = BIT(~color_prom[i], 2);
+ bit1 = BIT(~color_prom[i], 6);
+ int const g = combine_weights(gweights, bit0, bit1);
+
+ // blue component
+ bit0 = BIT(~color_prom[i], 4);
+ bit1 = BIT(~color_prom[i], 7);
+ int const b = combine_weights(bweights, bit0, bit1);
+
+ palette.set_indirect_color(i, rgb_t(r, g, b));
+ }
+
+ // color_prom now points to the beginning of the lookup table
+ color_prom += 0x20;
+
+ // characters
+ for (int i = 0; i < 0x20; i++)
+ {
+ u8 const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
+ palette.set_pen_indirect(i, ctabentry);
+ }
+
+ // sprites
+ for (int i = 0; i < 0x20; i++)
+ {
+ u8 ctabentry;
+
+ ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
+ palette.set_pen_indirect(i + 0x20, ctabentry);
+
+ ctabentry = bitswap<4>((color_prom[i] >> 4) & 0x0f, 0,1,2,3);
+ palette.set_pen_indirect(i + 0x40, ctabentry);
+ }
}
-// documentation TBD
-void mrsdyna_state::mrsdyna_0x30_w(offs_t offset, uint8_t data)
+WRITE_LINE_MEMBER(ladybug_state::flipscreen_w)
{
- // bits 0-2 select 4051s at M7 and M8
- // bits 3-5 select 4051s at K7 and K8
- m_0x30 = data & 0x3f;
+ if (flip_screen() != state)
+ {
+ flip_screen_set(state);
+ machine().tilemap().mark_all_dirty();
+ }
}
-// documentation TBD
-void mrsdyna_state::mrsdyna_0x38_w(offs_t offset, uint8_t data)
+u32 ladybug_state::screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- // These 6 bits are stored in the LS174 latch at N8
- // bits 0-2 select 4051s at H7 and H8
- // bits 3-5 select 4051s at E7 and E8
- m_0x38 = data & 0x3f;
+ bitmap.fill(0, cliprect);
+ m_video->draw(screen, bitmap, cliprect, flip_screen());
+ return 0;
}
+
+
+/***************************************************************************
+ Address Maps
+***************************************************************************/
+
void ladybug_state::ladybug_map(address_map &map)
{
map(0x0000, 0x5fff).rom();
@@ -137,84 +253,16 @@ void ladybug_state::ladybug_map(address_map &map)
map(0xe000, 0xe000).portr("IN2");
}
-
void dorodon_state::decrypted_opcodes_map(address_map &map)
{
map(0x0000, 0x5fff).rom().share("decrypted_opcodes");
}
-void mrsdyna_state::mrsdyna_cpu1_map(address_map &map)
-{
- // LS138 @ J4
- map(0x0000, 0x5fff).rom(); // 2764s at R4, N4, and M4
- // LS138 @ J4 and LS139 @ H4
- map(0x6000, 0x6fff).ram(); // 6116s @ K3 & M3, also connected to clk on PAL K2 (16R6, U001)
- map(0x7000, 0x73ff).w("video", FUNC(ladybug_video_device::spr_w)); // pin 29 on ribbon
- //map(0x77ff, 0x7fff); // LS139 @ H4 pin7 is NC
-
- // LS138 @ J4, Pin11 (0x8000-0x9fff) and
- // LS138 @ N3 (bottom 3 bits)
- // (all of these are read/write)
- map(0x8005, 0x8005).mirror(0x1ff8).r(FUNC(mrsdyna_state::mrsdyna_protection_r)); // OE on PAL @ K2 (16R6, U001) (100x xxxx xxxx x101)
- map(0x8006, 0x8006).mirror(0x1ff8).w("soundlatch_low", FUNC(generic_latch_8_device::write)); // LS374 @ P6
- map(0x8007, 0x8007).mirror(0x1ff8).w("soundlatch_high", FUNC(generic_latch_8_device::write)); // LS374 @ R6
- map(0x8000, 0x8000).mirror(0x1ff8).portr("IN0");
- map(0x8001, 0x8001).mirror(0x1ff8).portr("IN1");
- map(0x8002, 0x8002).mirror(0x1ff8).portr("DSW0");
- map(0x8003, 0x8003).mirror(0x1ff8).portr("DSW1");
- //map(0x8004, 0x8004).mirror(0x1ff8).portr("IN2"); // extra JAMMA pins
- // LS138 @ J4, Pin10 (0xa000-0xbfff) // NC
- // LS138 @ J4, Pin9 (0xc000-0xdfff)
- map(0xd000, 0xd7ff).w("video", FUNC(ladybug_video_device::bg_w)); // pin 27 on ribbon
- // LS138 @ J4, Pin7 (0xe000-0xffff)
- map(0xe000, 0xe000).nopw(); //unknown 0x10 when in attract, 0x20 when coined/playing - disabled watchdog based on LS123 @ F4
-}
-
-void mrsdyna_state::mrsdyna_cpu2_map(address_map &map)
-{
- // LS138 @ P7
- map(0x0000, 0x5fff).rom(); // 2764s at H6,J6, and L6
- map(0x6000, 0x63ff).mirror(0x0400).ram(); // 2x2114 @ M6/N6
- map(0x8000, 0x8000).mirror(0x1fff).r("soundlatch_low", FUNC(generic_latch_8_device::read)); // LS374 @ P6
- map(0xa000, 0xa000).mirror(0x1fff).r("soundlatch_high", FUNC(generic_latch_8_device::read)); // LS374 @ R6
- map(0xc000, 0xc000).mirror(0x1fff).r(FUNC(mrsdyna_state::mrsdyna_rnd_r)); // LS125 @ P8 - reads 556 outputs to D1 and D0?
- // LS138 @ P7 (nY7) and LS139 @ H4
- map(0xe000, 0xe0ff).mirror(0x0300).writeonly().share("grid_data"); // HD6148P @ D6
- map(0xe800, 0xefff).w(FUNC(mrsdyna_state::mrsdyna_io_w)); // LS273 @ D4
- //map(0xf000, 0xf7ff) // NC
- //map(0xf800, 0xffff) // NC
-}
-
-void sraider_state::sraider_cpu2_map(address_map &map)
-{
- // LS138 @ P7
- map(0x0000, 0x5fff).rom(); // 2764s at H6, J6, and L6
- map(0x6000, 0x63ff).mirror(0x0400).ram(); // 2x2114 @ M6/N6
- map(0x8000, 0x8000).mirror(0x1fff).r("soundlatch_low", FUNC(generic_latch_8_device::read)); // LS374 @ P6
- map(0xa000, 0xa000).mirror(0x1fff).r("soundlatch_high", FUNC(generic_latch_8_device::read)); // LS374 @ R6
- map(0xc000, 0xc000).mirror(0x1fff).r(FUNC(sraider_state::mrsdyna_rnd_r)); // LS125 @ P8 - reads 556 outputs to D1 and D0?
- // LS138 @ P7 (nY7) and LS139 @ H4
- map(0xe000, 0xe0ff).mirror(0x0300).writeonly().share("grid_data"); // HD6148P @ D6
- map(0xe800, 0xefff).w(FUNC(sraider_state::sraider_io_w)); // LS273 @ D4
- //map(0xf000, 0xf7ff) // NC
- //map(0xf800, 0xffff) // NC
-}
-
-void mrsdyna_state::mrsdyna_cpu2_io_map(address_map &map)
-{
- map.global_mask(0xff);
- // LS138 @ A8
- map(0x00, 0x07).w("sn1", FUNC(sn76489_device::write)); // J214X2 @ N9
- map(0x08, 0x0f).w("sn2", FUNC(sn76489_device::write)); // J214X2 @ M9
- map(0x10, 0x17).w("sn3", FUNC(sn76489_device::write)); // J214X2 @ L9
- map(0x18, 0x1f).w("sn4", FUNC(sn76489_device::write)); // J214X2 @ K9
- map(0x20, 0x27).w("sn5", FUNC(sn76489_device::write)); // J214X2 @ J9
- map(0x28, 0x2f).w(FUNC(sraider_state::mrsdyna_weird_w)); // LS259 @ A7 ************
- map(0x30, 0x37).w(FUNC(sraider_state::mrsdyna_0x30_w)); // LS174 @ N7 ************
- map(0x38, 0x3f).w(FUNC(sraider_state::mrsdyna_0x38_w)); // LS174 @ N8 ************
-}
+/***************************************************************************
+ Input Ports
+***************************************************************************/
INPUT_CHANGED_MEMBER(ladybug_state::coin1_inserted)
{
@@ -229,7 +277,6 @@ INPUT_CHANGED_MEMBER(ladybug_state::coin2_inserted)
m_maincpu->set_input_line(0, HOLD_LINE);
}
-
CUSTOM_INPUT_MEMBER(ladybug_state::ladybug_p1_control_r)
{
return m_p1_control->read();
@@ -586,157 +633,11 @@ static INPUT_PORTS_START( dorodon )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, ladybug_state,coin2_inserted, 0)
INPUT_PORTS_END
-static INPUT_PORTS_START( mrsdyna )
- PORT_START("IN0") /* IN0 */
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // JAMMA PIN 12
-
- PORT_START("IN1") /* IN1 */
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // VBLANK????
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
-
- PORT_START("DSW0") /* DSW0 @ R3 via '244 @ R2 */
- PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:8")
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:7")
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
- PORT_DIPSETTING( 0x00, "3 Letters" )
- PORT_DIPSETTING( 0x04, "12 Letters" )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:5")
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
- PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
- PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
- PORT_DIPSETTING( 0x00, "2" )
- PORT_DIPSETTING( 0xc0, "3" )
- PORT_DIPSETTING( 0x80, "4" )
- PORT_DIPSETTING( 0x40, "5" )
-
- /* Free Play setting works when it's set for both */
- PORT_START("DSW1") /* DSW1 @ P3 via '244 @ P2 */
- PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:8,7,6,5")
- /* settings 0x00 through 0x05 all give 1 Coin/1 Credit */
- PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
- PORT_DIPSETTING( 0x09, DEF_STR( 2C_2C ) )
- PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
- PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
- PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
- PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
- PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
- PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,3,2,1")
- /* settings 0x00 through 0x50 all give 1 Coin/1 Credit */
- PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
- PORT_DIPSETTING( 0x90, DEF_STR( 2C_2C ) )
- PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
- PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
- PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
- PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
- PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
-INPUT_PORTS_END
-
-static INPUT_PORTS_START( sraider )
- PORT_START("IN0") /* IN0 */
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // JAMMA PIN 12
-
- PORT_START("IN1") /* IN1 */
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // VBLANK????
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
-
- PORT_START("DSW0") /* DSW0 @ R3 via '244 @ R2 */
- PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW0:7,8")
- PORT_DIPSETTING( 0x03, DEF_STR( Easy ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Medium ) )
- PORT_DIPSETTING( 0x01, DEF_STR( Hard ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
- PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
- PORT_DIPSETTING( 0x00, "3 Letters" )
- PORT_DIPSETTING( 0x04, "10 Letters" )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW0:5")
- PORT_DIPSETTING( 0x08, DEF_STR( No ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Yes ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
- PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
- PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
- PORT_DIPSETTING( 0x00, "2" )
- PORT_DIPSETTING( 0xc0, "3" )
- PORT_DIPSETTING( 0x80, "4" )
- PORT_DIPSETTING( 0x40, "5" )
- /* Free Play setting works when it's set for both */
- PORT_START("DSW1") /* DSW1 @ P3 via '244 @ P2 */
- PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:8,7,6,5")
- /* settings 0x00 through 0x05 all give 1 Coin/1 Credit */
- PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
- PORT_DIPSETTING( 0x09, DEF_STR( 2C_2C ) )
- PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
- PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
- PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
- PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
- PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
- PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,3,2,1")
- /* settings 0x00 through 0x50 all give 1 Coin/1 Credit */
- PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
- PORT_DIPSETTING( 0x90, DEF_STR( 2C_2C ) )
- PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
- PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
- PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
- PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
- PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
- PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
-INPUT_PORTS_END
+/***************************************************************************
+ GFX Layouts
+***************************************************************************/
static const gfx_layout charlayout =
{
@@ -772,62 +673,17 @@ static const gfx_layout spritelayout2 =
16*8 /* every sprite takes 16 consecutive bytes */
};
-static const gfx_layout gridlayout =
-{
- 8,8, /* 8*8 characters */
- 512, /* 512 characters */
- 1, /* 1 bit per pixel */
- { 0 },
- { 7, 6, 5, 4, 3, 2, 1, 0 },
- { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8},
- 8*8 /* every char takes 8 consecutive bytes */
-};
-static const gfx_layout gridlayout2 =
-{
- 8,8, /* 8*8 characters */
- 512, /* 512 characters */
- 1, /* 1 bit per pixel */
- { 0 },
- { 7, 6, 5, 4, 3, 2, 1, 0 },
- { 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
- 8*8 /* every char takes 8 consecutive bytes */
-};
-
static GFXDECODE_START( gfx_ladybug )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
GFXDECODE_END
-static GFXDECODE_START( gfx_sraider )
- GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
- GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
- GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
- GFXDECODE_ENTRY( "gfx3", 0, gridlayout, 4*8+4*16+32, 1 )
- GFXDECODE_ENTRY( "gfx3", 0, gridlayout2, 4*8+4*16+32, 1 )
-GFXDECODE_END
-
-void mrsdyna_state::machine_start()
-{
- ladybug_base_state::machine_start();
-
- save_item(NAME(m_grid_color));
- save_item(NAME(m_0x30));
- save_item(NAME(m_0x38));
- save_item(NAME(m_weird_value));
-}
-
-void mrsdyna_state::machine_reset()
-{
- ladybug_base_state::machine_reset();
-
- m_grid_color = 0;
- m_0x30 = 0;
- m_0x38 = 0;
- std::fill(std::begin(m_weird_value), std::end(m_weird_value), 0);
-}
+/***************************************************************************
+ Machine Configs
+***************************************************************************/
void ladybug_state::ladybug(machine_config &config)
{
@@ -863,86 +719,10 @@ void dorodon_state::dorodon(machine_config &config)
m_maincpu->set_addrmap(AS_OPCODES, &dorodon_state::decrypted_opcodes_map);
}
-void mrsdyna_state::mrsdyna(machine_config &config)
-{
- /* basic machine hardware */
- z80_device &maincpu(Z80(config, "maincpu", 4000000)); /* 4 MHz */
- maincpu.set_addrmap(AS_PROGRAM, &mrsdyna_state::mrsdyna_cpu1_map);
- maincpu.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
-
- GENERIC_LATCH_8(config, "soundlatch_low");
- GENERIC_LATCH_8(config, "soundlatch_high");
-
- z80_device &sub(Z80(config, "sub", 4000000)); /* 4 MHz */
- sub.set_addrmap(AS_PROGRAM, &mrsdyna_state::mrsdyna_cpu2_map);
- sub.set_addrmap(AS_IO, &mrsdyna_state::mrsdyna_cpu2_io_map);
- sub.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
-
- /* video hardware */
- screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_raw(9'828'000 / 2, 312, 8, 248, 262, 32, 224);
- screen.set_screen_update(FUNC(mrsdyna_state::screen_update_mrsdyna));
- //screen.screen_vblank().set(FUNC(sraider_state::screen_vblank_sraider));
- screen.set_palette(m_palette);
-
- GFXDECODE(config, m_gfxdecode, m_palette, gfx_ladybug);
- PALETTE(config, m_palette, FUNC(mrsdyna_state::mrsdyna_palette), 4*8 + 4*16 + 32 + 2, 32 + 32 + 1);
-
- LADYBUG_VIDEO(config, m_video, 4000000).set_gfxdecode_tag(m_gfxdecode);
-
- /* sound hardware */
- SPEAKER(config, "mono").front_center();
-
- SN76489(config, "sn1", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn2", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn3", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn4", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn5", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
-}
-
-void sraider_state::sraider(machine_config &config)
-{
- /* basic machine hardware */
- z80_device &maincpu(Z80(config, "maincpu", 4000000)); /* 4 MHz */
- maincpu.set_addrmap(AS_PROGRAM, &sraider_state::mrsdyna_cpu1_map);
- maincpu.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
-
- GENERIC_LATCH_8(config, "soundlatch_low");
- GENERIC_LATCH_8(config, "soundlatch_high");
-
- z80_device &sub(Z80(config, "sub", 4000000)); /* 4 MHz */
- sub.set_addrmap(AS_PROGRAM, &sraider_state::sraider_cpu2_map);
- sub.set_addrmap(AS_IO, &sraider_state::mrsdyna_cpu2_io_map);
- sub.set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
-
- /* video hardware */
- screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
- screen.set_raw(9'828'000 / 2, 312, 8, 248, 262, 32, 224);
- screen.set_screen_update(FUNC(sraider_state::screen_update_sraider));
- screen.screen_vblank().set(FUNC(sraider_state::screen_vblank_sraider));
- screen.set_palette(m_palette);
-
- GFXDECODE(config, m_gfxdecode, m_palette, gfx_sraider);
- PALETTE(config, m_palette, FUNC(sraider_state::sraider_palette), 4*8 + 4*16 + 32 + 2, 32 + 32 + 1);
-
- LADYBUG_VIDEO(config, m_video, 4000000).set_gfxdecode_tag(m_gfxdecode);
- ZEROHOUR_STARS(config, m_stars, 0);
-
- /* sound hardware */
- SPEAKER(config, "mono").front_center();
-
- SN76489(config, "sn1", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn2", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn3", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn4", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
- SN76489(config, "sn5", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
-}
/***************************************************************************
-
- Game driver(s)
-
+ ROM Definitions
***************************************************************************/
ROM_START( ladybug )
@@ -1114,80 +894,19 @@ ROM_START( dorodon2 )
ROM_LOAD( "dorodon.bp2", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* timing?? */
ROM_END
-ROM_START( mrsdyna )
- ROM_REGION( 0x10000, "maincpu", 0 )
- // NOTE: Mrs. Dynamite returns ROM ERROR in test mode. It does an 8-bit checksum on these 3
- // ROMs and computes 0xFF. The answer to pass the test is 0x00.
- // However, these images were dumped twice, and seem to work fine.
- ROM_LOAD( "mrsd-8203a-r4.f3", 0x0000, 0x2000, CRC(c944062c) SHA1(c61fc327d67595e601f6a7e5e337646f5f9d351b) )
- ROM_LOAD( "mrsd-8203a-n4.f2", 0x2000, 0x2000, CRC(d1b9c7bb) SHA1(c139c8ae5b14924eb04a265095a7ab95ac5370af) )
- ROM_LOAD( "mrsd-8203a-m4.f1", 0x4000, 0x2000, CRC(d25b1dfe) SHA1(f68c6fb2cda37fcffbe7c3c2a3cc5cb372c4101b) )
-
- ROM_REGION( 0x10000, "sub", 0 )
- ROM_LOAD( "mrsd-8203a-h6.f4", 0x0000, 0x2000, CRC(04f8617b) SHA1(64deef2269790d8460d0ad510548e178f0f61607) )
- ROM_LOAD( "mrsd-8203a-j6.f5", 0x2000, 0x2000, CRC(1ffb5fc3) SHA1(e8fc7b95663a396ef7d46ba6ce24973a3c343381) )
- ROM_LOAD( "mrsd-8203a-l6.f6", 0x4000, 0x2000, CRC(5a0f5030) SHA1(d1530230fe6c666f7920cb82cb47f5fcc7e1ecc8) )
-
- ROM_REGION( 0x2000, "gfx1", 0 )
- ROM_LOAD( "mrsd-8203b-k6.f10", 0x0000, 0x1000, CRC(e33cb26e) SHA1(207fa986754f8d7cd0bb3e56fd271ee0c1990269) )
- ROM_LOAD( "mrsd-8203b-l6.f11", 0x1000, 0x1000, CRC(a327ba05) SHA1(5eac27b48d14fec179919fe0902a6c7ada95f2b2) )
-
- ROM_REGION( 0x2000, "gfx2", 0 )
- ROM_LOAD( "mrsd-8203b-m2.f7", 0x0000, 0x1000, CRC(a00ae797) SHA1(adff7f38870b7e8fa114886792a3acbb7a5726ab) )
- ROM_LOAD( "mrsd-8203b-n2.f8", 0x1000, 0x1000, CRC(81f2bdbd) SHA1(45ee1d62462cfadf7d2c46767f03ccfb3c876c08) )
-
- ROM_REGION( 0x0060, "proms", 0 )
- ROM_LOAD( "mrsd-10-1.a2", 0x0000, 0x0020, CRC(4a819ad4) SHA1(d9072af7e52b506c1bcf8a327242d470eb240857) )
- ROM_LOAD( "mrsd-10-2.l3", 0x0020, 0x0020, CRC(2d926a3a) SHA1(129fb60ce3df67614e39dcaac9c93f0652addbbb) )
- ROM_LOAD( "mrsd-10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
-ROM_END
-
-ROM_START( sraider )
- ROM_REGION( 0x10000, "maincpu", 0 )
- ROM_LOAD( "sraid3.r4", 0x0000, 0x2000, CRC(0f389774) SHA1(c67596e6bf00175ff0a241506cd2f88114d05933) )
- ROM_LOAD( "sraid2.n4", 0x2000, 0x2000, CRC(38a48db0) SHA1(6f4f384d702fb8ee4bb2ef579638239d57e32ddd) )
- ROM_LOAD( "sraid1.m4", 0x4000, 0x2000, CRC(2f302a4e) SHA1(3a902ce6858f38df88b60830bef4b1d45b09b2df) )
-
- ROM_REGION( 0x10000, "sub", 0 )
- ROM_LOAD( "sraid-s4.h6", 0x0000, 0x2000, CRC(57173a12) SHA1(6cb8fd4826e499f9a4e63621d58bc4b596cc261e) )
- ROM_LOAD( "sraid-s5.j6", 0x2000, 0x2000, CRC(5a459179) SHA1(a261c8f3c7c4cd4587c003bbbe815d2c4e01ffbc) )
- ROM_LOAD( "sraid-s6.l6", 0x4000, 0x2000, CRC(ea3aa25d) SHA1(353c0d075d5e0a3bc25a65e2748f5eb5212a844d) )
-
- ROM_REGION( 0x2000, "gfx1", 0 )
- ROM_LOAD( "sraid-s0.k6", 0x0000, 0x1000, CRC(a0373909) SHA1(00e3bd5dd90769d670fc3c51edd1cd4b69e6132d) )
- ROM_LOAD( "sraids11.l6", 0x1000, 0x1000, CRC(ba22d949) SHA1(83762ced1df92ff594887e44d5b783826bbfb0c9) )
-
- ROM_REGION( 0x2000, "gfx2", 0 )
- ROM_LOAD( "sraid-s7.m2", 0x0000, 0x1000, CRC(299f8e07) SHA1(1de71f251286088487da7285d6f8070147002af5) )
- ROM_LOAD( "sraid-s8.n2", 0x1000, 0x1000, CRC(57ba8888) SHA1(2aa1a5f682d146a55a96e471bb78e5c60da02bf9) )
-
- ROM_REGION( 0x1000, "gfx3", 0 ) /* fixed portion of the grid */
- ROM_LOAD( "sraid-s9.f6", 0x0000, 0x1000, CRC(2380b90f) SHA1(0310554e3f2ec973c2bb6e816d04e5c0c1e0a0b9) )
-
- ROM_REGION( 0x0060, "proms", 0 )
- ROM_LOAD( "srpr10-1.a2", 0x0000, 0x0020, CRC(121fdb99) SHA1(3bc092da40beb129a4df3db2f55d22bbbcf7bad8) )
- ROM_LOAD( "srpr10-2.l3", 0x0020, 0x0020, CRC(88b67e70) SHA1(e21ee2939e96dffee101bd92c62ed975b6b64001) )
- ROM_LOAD( "srpr10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
-ROM_END
-
+} // anonymous namespace
-void dorodon_state::init_dorodon()
-{
- /* decode the opcodes */
- uint8_t *rom = memregion("maincpu")->base();
- uint8_t *table = memregion("user1")->base();
- for (offs_t i = 0; i < 0x6000; i++)
- m_decrypted_opcodes[i] = table[rom[i]];
-}
+/***************************************************************************
+ Drivers
+***************************************************************************/
-GAME( 1981, cavenger, 0, ladybug, cavenger, ladybug_state, empty_init, ROT0, "Universal", "Cosmic Avenger", MACHINE_SUPPORTS_SAVE )
-GAME( 1981, ladybug, 0, ladybug, ladybug, ladybug_state, empty_init, ROT270, "Universal", "Lady Bug", MACHINE_SUPPORTS_SAVE )
-GAME( 1981, ladybugb, ladybug, ladybug, ladybug, ladybug_state, empty_init, ROT270, "bootleg", "Lady Bug (bootleg set 1)", MACHINE_SUPPORTS_SAVE )
-GAME( 1981, ladybugb2, ladybug, ladybug, ladybug, ladybug_state, empty_init, ROT270, "bootleg (Model Racing)", "Coccinelle (bootleg of Lady Bug, set 2)", MACHINE_SUPPORTS_SAVE ) // title removed, but manual names it Coccinelle
-GAME( 1981, snapjack, 0, ladybug, snapjack, ladybug_state, empty_init, ROT0, "Universal", "Snap Jack", MACHINE_SUPPORTS_SAVE )
-GAME( 1982, dorodon, 0, dorodon, dorodon, dorodon_state, init_dorodon, ROT270, "UPL (Falcon license?)", "Dorodon (set 1)", MACHINE_SUPPORTS_SAVE ) // license or bootleg?
-GAME( 1982, dorodon2, dorodon, dorodon, dorodon, dorodon_state, init_dorodon, ROT270, "UPL (Falcon license?)", "Dorodon (set 2)", MACHINE_SUPPORTS_SAVE ) // "
-GAME( 1982, mrsdyna, 0, mrsdyna, mrsdyna, mrsdyna_state, empty_init, ROT270, "Universal", "Mrs. Dynamite", MACHINE_SUPPORTS_SAVE )
-GAME( 1982, sraider, 0, sraider, sraider, sraider_state, empty_init, ROT270, "Universal", "Space Raider", MACHINE_SUPPORTS_SAVE )
+// YEAR NAME PARENT MACHINE INPUT STATE INIT SCREEN COMPANY FULLNAME FLAGS
+GAME( 1981, cavenger, 0, ladybug, cavenger, ladybug_state, empty_init, ROT0, "Universal", "Cosmic Avenger", MACHINE_SUPPORTS_SAVE )
+GAME( 1981, ladybug, 0, ladybug, ladybug, ladybug_state, empty_init, ROT270, "Universal", "Lady Bug", MACHINE_SUPPORTS_SAVE )
+GAME( 1981, ladybugb, ladybug, ladybug, ladybug, ladybug_state, empty_init, ROT270, "bootleg", "Lady Bug (bootleg)", MACHINE_SUPPORTS_SAVE )
+GAME( 1981, ladybugb2, ladybug, ladybug, ladybug, ladybug_state, empty_init, ROT270, "bootleg (Model Racing)", "Coccinelle (bootleg of Lady Bug)", MACHINE_SUPPORTS_SAVE ) // title removed, but manual names it Coccinelle
+GAME( 1981, snapjack, 0, ladybug, snapjack, ladybug_state, empty_init, ROT0, "Universal", "Snap Jack", MACHINE_SUPPORTS_SAVE )
+GAME( 1982, dorodon, 0, dorodon, dorodon, dorodon_state, init_dorodon, ROT270, "UPL (Falcon license?)", "Dorodon (set 1)", MACHINE_SUPPORTS_SAVE ) // license or bootleg?
+GAME( 1982, dorodon2, dorodon, dorodon, dorodon, dorodon_state, init_dorodon, ROT270, "UPL (Falcon license?)", "Dorodon (set 2)", MACHINE_SUPPORTS_SAVE ) // "
diff --git a/src/mame/universal/ladybug.h b/src/mame/universal/ladybug.h
deleted file mode 100644
index 8c34b2a1e16..00000000000
--- a/src/mame/universal/ladybug.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nicola Salmoria
-/*************************************************************************
-
- Universal 8106-A2 + 8106-B PCB set
-
-*************************************************************************/
-#ifndef MAME_INCLUDES_LADYBUG_H
-#define MAME_INCLUDES_LADYBUG_H
-
-#pragma once
-
-#include "ladybug_v.h"
-#include "emupal.h"
-#include "tilemap.h"
-
-
-class ladybug_base_state : public driver_device
-{
-protected:
- using driver_device::driver_device;
-
- void palette_init_common(
- palette_device &palette, const uint8_t *color_prom,
- int r_bit0, int r_bit1,
- int g_bit0, int g_bit1,
- int b_bit0, int b_bit1) const;
-};
-
-
-// ladybug platform
-class ladybug_state : public ladybug_base_state
-{
-public:
- ladybug_state(const machine_config &mconfig, device_type type, const char *tag)
- : ladybug_base_state(mconfig, type, tag)
- , m_maincpu(*this, "maincpu")
- , m_video(*this, "video")
- , m_port_dsw0(*this, "DSW0")
- , m_p1_control(*this, "CONTP1")
- , m_p2_control(*this, "CONTP2")
- { }
-
- DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p1_control_r);
- DECLARE_CUSTOM_INPUT_MEMBER(ladybug_p2_control_r);
- DECLARE_INPUT_CHANGED_MEMBER(coin1_inserted);
- DECLARE_INPUT_CHANGED_MEMBER(coin2_inserted);
- void ladybug(machine_config &config);
-
-protected:
- DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
- void ladybug_palette(palette_device &palette) const;
- uint32_t screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- void ladybug_map(address_map &map);
-
- required_device<cpu_device> m_maincpu;
-
-private:
- required_device<ladybug_video_device> m_video;
-
- required_ioport m_port_dsw0;
- optional_ioport m_p1_control;
- optional_ioport m_p2_control;
-};
-
-
-// ladybug plus program decryption
-class dorodon_state : public ladybug_state
-{
-public:
- dorodon_state(const machine_config &mconfig, device_type type, const char *tag)
- : ladybug_state(mconfig, type, tag)
- , m_decrypted_opcodes(*this, "decrypted_opcodes")
- { }
-
- void init_dorodon();
- void dorodon(machine_config &config);
-
-protected:
- void decrypted_opcodes_map(address_map &map);
-
-private:
- required_shared_ptr<uint8_t> m_decrypted_opcodes;
-};
-
-// 8203 hardware adds grid tilemap, 2nd audio CPU
-class mrsdyna_state : public ladybug_base_state
-{
-public:
- mrsdyna_state(const machine_config &mconfig, device_type type, const char *tag)
- : ladybug_base_state(mconfig, type, tag)
- , m_palette(*this, "palette")
- , m_gfxdecode(*this, "gfxdecode")
- , m_video(*this, "video")
- { }
-
- void mrsdyna(machine_config &config);
-
-protected:
- uint8_t mrsdyna_protection_r();
- void mrsdyna_weird_w(offs_t offset, uint8_t data);
- void mrsdyna_0x30_w(offs_t offset, uint8_t data);
- void mrsdyna_0x38_w(offs_t offset, uint8_t data);
- uint8_t mrsdyna_rnd_r();
- void mrsdyna_io_w(uint8_t data);
- void mrsdyna_palette(palette_device &palette) const;
- DECLARE_WRITE_LINE_MEMBER(screen_vblank_sraider);
- TILE_GET_INFO_MEMBER(get_grid_tile_info);
-
- virtual void machine_start() override;
- virtual void machine_reset() override;
- uint32_t screen_update_mrsdyna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- void mrsdyna_cpu1_map(address_map &map);
- void mrsdyna_cpu2_io_map(address_map &map);
- void mrsdyna_cpu2_map(address_map &map);
-
- required_device<palette_device> m_palette;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<ladybug_video_device> m_video;
-
- tilemap_t *m_grid_tilemap = nullptr;
-
- uint8_t m_grid_color = 0U;
- uint8_t m_0x30 = 0U;
- uint8_t m_0x38 = 0U;
- uint8_t m_weird_value[8]{};
-};
-
-// add stars from zerohour, uses grid layer
-class sraider_state : public mrsdyna_state
-{
-public:
- sraider_state(const machine_config &mconfig, device_type type, const char *tag)
- : mrsdyna_state(mconfig, type, tag)
- , m_grid_data(*this, "grid_data")
- , m_stars(*this, "stars")
- { }
-
- void sraider(machine_config &config);
-
-protected:
- void sraider_io_w(uint8_t data);
- void sraider_palette(palette_device &palette) const;
- DECLARE_WRITE_LINE_MEMBER(screen_vblank_sraider);
- TILE_GET_INFO_MEMBER(get_grid_tile_info);
-
- virtual void video_start() override;
- uint32_t screen_update_sraider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- void sraider_cpu2_map(address_map &map);
-
-private:
- required_shared_ptr<uint8_t> m_grid_data;
- required_device<zerohour_stars_device> m_stars;
-};
-
-#endif // MAME_INCLUDES_LADYBUG_H
diff --git a/src/mame/universal/ladybug_v.cpp b/src/mame/universal/ladybug_v.cpp
deleted file mode 100644
index 458c1b64e87..00000000000
--- a/src/mame/universal/ladybug_v.cpp
+++ /dev/null
@@ -1,513 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nicola Salmoria
-/***************************************************************************
-
- video.c
-
- Functions to emulate the video hardware of the machine.
-
-***************************************************************************/
-
-#include "emu.h"
-#include "ladybug_v.h"
-#include "ladybug.h"
-
-#include "video/resnet.h"
-
-#include <algorithm>
-
-
-DEFINE_DEVICE_TYPE(LADYBUG_VIDEO, ladybug_video_device, "ladybug_video", "Lady Bug/Space Raider background")
-DEFINE_DEVICE_TYPE(ZEROHOUR_STARS, zerohour_stars_device, "zerohour_stars", "Zero Hour/Red Clash/Space Raider starfield")
-
-
-/***************************************************************************
-
- ladybug/sraider video
-
-***************************************************************************/
-
-ladybug_video_device::ladybug_video_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
- : device_t(mconfig, LADYBUG_VIDEO, tag, owner, clock)
- , m_gfxdecode(*this, finder_base::DUMMY_TAG)
- , m_spr_ram()
- , m_bg_ram()
- , m_bg_tilemap(nullptr)
-{
-}
-
-void ladybug_video_device::bg_w(offs_t offset, uint8_t data)
-{
- m_bg_ram[offset & 0x07ff] = data;
- m_bg_tilemap->mark_tile_dirty(offset & 0x03ff);
-}
-
-void ladybug_video_device::draw(screen_device &screen, bitmap_ind16 &bitmap, rectangle const &cliprect, bool flip)
-{
- // TODO: confirm whether sraider hardware actually does this - not used by the game
- for (unsigned offs = 0; offs < 32; ++offs)
- {
- int const scroll = m_bg_ram[((offs & 0x03) << 5) | (offs >> 2)];
- m_bg_tilemap->set_scrollx(offs, flip ? -scroll : scroll);
- }
-
- m_bg_tilemap->draw(screen, bitmap, cliprect, 0);
-
- for (int offs = 0x400 - (0x40 << 1); (0x40 << 1) <= offs; offs -= 0x40)
- {
- int i = 0;
- while ((0x40 > i) && m_spr_ram[offs + i])
- i += 4;
-
- while (0 < i)
- {
- /*
- abccdddd eeeeeeee fffghhhh iiiiiiii
-
- a enable?
- b size (0 = 8x8, 1 = 16x16)
- cc flip
- dddd y offset
- eeeeeeee sprite code (shift right 2 bits for 16x16 sprites)
- fff unknown
- g sprite bank
- hhhh color
- iiiiiiii x position
- */
- i -= 4;
- bool const enable(m_spr_ram[offs + i] & 0x80);
- if (enable)
- {
- bool const big(m_spr_ram[offs + i] & 0x40);
- bool const xflip(m_spr_ram[offs + i] & 0x20);
- bool const yflip(m_spr_ram[offs + i] & 0x10);
- int const code(m_spr_ram[offs + i + 1] | (BIT(m_spr_ram[offs + i + 2], 4) << 8));
- int const color(m_spr_ram[offs + i + 2] & 0x0f);
- int const xpos(m_spr_ram[offs + i + 3]);
- int const ypos((offs >> 2) | (m_spr_ram[offs + i] & 0x0f));
- if (big) // 16x16
- m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code >> 2, color, xflip, yflip, xpos, ypos - 8, 0);
- else // 8x8
- m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, code, color, xflip, yflip, xpos, ypos, 0);
- }
- }
- }
-}
-
-void ladybug_video_device::device_start()
-{
- m_spr_ram = std::make_unique<u8 []>(0x0400);
- m_bg_ram = std::make_unique<u8 []>(0x0800);
- std::fill_n(m_spr_ram.get(), 0x0400, 0);
- std::fill_n(m_bg_ram.get(), 0x0800, 0);
-
- m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ladybug_video_device::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
- m_bg_tilemap->set_scroll_rows(32);
- m_bg_tilemap->set_transparent_pen(0);
-
- save_pointer(NAME(m_spr_ram), 0x0400);
- save_pointer(NAME(m_bg_ram), 0x0800);
-}
-
-TILE_GET_INFO_MEMBER(ladybug_video_device::get_bg_tile_info)
-{
- int const code = m_bg_ram[tile_index] + (BIT(m_bg_ram[0x0400 | tile_index], 3) << 8);
- int const color = m_bg_ram[0x0400 | tile_index] & 0x07;
-
- tileinfo.set(0, code, color, 0);
-}
-
-
-/***************************************************************************
-
- zerohour/redclash/sraider stars
-
- These functions emulate the star generator board
- All this comes from the schematics for Zero Hour
-
- It has a 17-bit LFSR which has a period of 2^17-1 clocks
- (This is one pixel shy of "two screens" worth.)
- So, there are two starfields drawn on alternate frames
- These will scroll at a rate controlled by the speed register
-
- I'm basically doing the same thing by drawing each
- starfield on alternate frames, and then offseting them
-
-***************************************************************************/
-
-zerohour_stars_device::zerohour_stars_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
- : device_t(mconfig, ZEROHOUR_STARS, tag, owner, clock)
- , m_enable(0)
- , m_speed(0)
- , m_offset(0)
- , m_count(0)
-{
-}
-
-// This line can reset the LFSR to zero and disables the star generator
-void zerohour_stars_device::set_enable(bool on)
-{
- if (!m_enable && on)
- m_offset = 0;
-
- m_enable = on ? 1 : 0;
-}
-
-// This sets up which starfield to draw and the offset, to be called from screen_vblank_*()
-void zerohour_stars_device::update_state()
-{
- if (m_enable)
- {
- m_count = m_count ? 0 : 1;
- if (!m_count)
- {
- m_offset += ((m_speed * 2) - 0x09);
- m_offset %= 256 * 256;
- m_state = 0;
- }
- else
- {
- m_state = 0x1fc71;
- }
- }
-}
-
-// Set the speed register (3 bits)
-void zerohour_stars_device::set_speed(u8 speed, u8 mask)
-{
- // 0 left/down fastest (-9/2 pix per frame)
- // 1 left/down faster (-7/2 pix per frame)
- // 2 left/down fast (-5/2 pix per frame)
- // 3 left/down medium (-3/2 pix per frame)
- // 4 left/down slow (-1/2 pix per frame)
- // 5 right/up slow (+1/2 pix per frame)
- // 6 right/up medium (+3/2 pix per frame)
- // 7 right/up fast (+5/2 pix per frame)
- m_speed = (m_speed & ~mask) | (speed & mask);
-}
-
-// Draw the stars
-// Space Raider doesn't use the Va bit, and it is also set up to window the stars to a certain x range
-void zerohour_stars_device::draw(bitmap_ind16 &bitmap, rectangle const &cliprect, u8 pal_offs, bool has_va, u8 firstx, u8 lastx)
-{
- if (m_enable)
- {
- u32 state(m_state);
- for (int i = 0; (256 * 256) > i; ++i)
- {
- u8 const xloc((m_offset + i) & 0x00ff);
- u8 const yloc(((m_offset + i) >> 8) & 0x00ff);
-
- bool const tempbit(!(state & 0x10000));
- bool const feedback((state & 0x00020) ? !tempbit : tempbit);
-
- bool const hcond(BIT(xloc + 8, 4));
- bool const vcond(!has_va || BIT(yloc, 0));
-
- if (cliprect.contains(xloc, yloc) && (hcond == vcond))
- {
- if (((state & 0x000ff) == 0x000ff) && !feedback && (xloc >= firstx) && (xloc <= lastx))
- bitmap.pix(yloc, xloc) = pal_offs + ((state >> 9) & 0x1f);
- }
-
- // update LFSR state
- state = ((state << 1) & 0x1fffe) | (feedback ? 1 : 0);
- }
- }
-}
-
-void zerohour_stars_device::device_start()
-{
- save_item(NAME(m_enable));
- save_item(NAME(m_speed));
- save_item(NAME(m_state));
- save_item(NAME(m_offset));
- save_item(NAME(m_count));
-}
-
-void zerohour_stars_device::device_reset()
-{
- m_enable = 0;
- m_speed = 0;
- m_state = 0;
- m_offset = 0;
- m_count = 0;
-}
-
-
-/***************************************************************************
-
- Convert the color PROMs into a more useable format.
-
- Lady Bug has a 32 bytes palette PROM and a 32 bytes sprite color lookup
- table PROM.
- The palette PROM is connected to the RGB output this way:
-
- bit 7 -- inverter -- 220 ohm resistor -- BLUE
- -- inverter -- 220 ohm resistor -- GREEN
- -- inverter -- 220 ohm resistor -- RED
- -- inverter -- 470 ohm resistor -- BLUE
- -- unused
- -- inverter -- 470 ohm resistor -- GREEN
- -- unused
- bit 0 -- inverter -- 470 ohm resistor -- RED
-
-***************************************************************************/
-/***************************************************************************
-
- Convert the color PROMs into a more useable format.
-
- Lady Bug has a 32 bytes palette PROM and a 32 bytes sprite color lookup
- table PROM.
- The palette PROM is connected to the RGB output this way:
-
- bit 7 -- inverter -- 220 ohm resistor -- BLUE
- -- inverter -- 220 ohm resistor -- GREEN
- -- inverter -- 220 ohm resistor -- RED
- -- inverter -- 470 ohm resistor -- BLUE
- -- unused
- -- inverter -- 470 ohm resistor -- GREEN
- -- unused
- bit 0 -- inverter -- 470 ohm resistor -- RED
-
-***************************************************************************/
-
-void ladybug_base_state::palette_init_common(palette_device &palette, const uint8_t *color_prom,
- int r_bit0, int r_bit1, int g_bit0, int g_bit1, int b_bit0, int b_bit1) const
-{
- static constexpr int resistances[2] = { 470, 220 };
-
- // compute the color output resistor weights
- double rweights[2], gweights[2], bweights[2];
- compute_resistor_weights(0, 255, -1.0,
- 2, resistances, rweights, 470, 0,
- 2, resistances, gweights, 470, 0,
- 2, resistances, bweights, 470, 0);
-
- // create a lookup table for the palette
- for (int i = 0; i < 0x20; i++)
- {
- int bit0, bit1;
-
- // red component
- bit0 = BIT(~color_prom[i], r_bit0);
- bit1 = BIT(~color_prom[i], r_bit1);
- int const r = combine_weights(rweights, bit0, bit1);
-
- // green component
- bit0 = BIT(~color_prom[i], g_bit0);
- bit1 = BIT(~color_prom[i], g_bit1);
- int const g = combine_weights(gweights, bit0, bit1);
-
- // blue component
- bit0 = BIT(~color_prom[i], b_bit0);
- bit1 = BIT(~color_prom[i], b_bit1);
- int const b = combine_weights(bweights, bit0, bit1);
-
- palette.set_indirect_color(i, rgb_t(r, g, b));
- }
-
- // color_prom now points to the beginning of the lookup table
- color_prom += 0x20;
-
- // characters
- for (int i = 0; i < 0x20; i++)
- {
- uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
- palette.set_pen_indirect(i, ctabentry);
- }
-
- // sprites
- for (int i = 0; i < 0x20; i++)
- {
- uint8_t ctabentry;
-
- ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
- palette.set_pen_indirect(i + 0x20, ctabentry);
-
- ctabentry = bitswap<4>((color_prom[i] >> 4) & 0x0f, 0,1,2,3);
- palette.set_pen_indirect(i + 0x40, ctabentry);
- }
-}
-
-
-void ladybug_state::ladybug_palette(palette_device &palette) const
-{
- palette_init_common(palette, memregion("proms")->base(), 0, 5, 2, 6, 4, 7);
-}
-
-WRITE_LINE_MEMBER(ladybug_state::flipscreen_w)
-{
- if (flip_screen() != state)
- {
- flip_screen_set(state);
- machine().tilemap().mark_all_dirty();
- }
-}
-
-uint32_t ladybug_state::screen_update_ladybug(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- bitmap.fill(0, cliprect);
- m_video->draw(screen, bitmap, cliprect, flip_screen());
- return 0;
-}
-
-
-void mrsdyna_state::mrsdyna_palette(palette_device &palette) const
-{
- const uint8_t *color_prom = memregion("proms")->base();
-
- // the resistor net may be probably different than Lady Bug
- palette_init_common(palette, color_prom, 3, 0, 5, 4, 7, 6);
-
- for (int i = 0; i < 0x20; i++)
- palette.set_pen_indirect(i + 0x60, i + 0x20);
-
- // stationary part of grid
- palette.set_pen_indirect(0x81, 0x40);
-}
-
-void sraider_state::sraider_palette(palette_device &palette) const
-{
- const uint8_t *color_prom = memregion("proms")->base();
-
- // the resistor net may be probably different than Lady Bug
- palette_init_common(palette, color_prom, 3, 0, 5, 4, 7, 6);
-
- // star colors
- for (int i = 0; i < 0x20; i++)
- {
- int bit0, bit1;
-
- // red component
- bit0 = BIT(i, 3);
- bit1 = BIT(i, 4);
- int const b = 0x47 * bit0 + 0x97 * bit1;
-
- // green component
- bit0 = BIT(i, 1);
- bit1 = BIT(i, 2);
- int const g = 0x47 * bit0 + 0x97 * bit1;
-
- // blue component
- bit0 = BIT(i, 0);
- int const r = 0x47 * bit0;
-
- palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
- }
-
- for (int i = 0; i < 0x20; i++)
- palette.set_pen_indirect(i + 0x60, i + 0x20);
-
- // stationary part of grid
- palette.set_pen_indirect(0x81, 0x40);
-}
-
-TILE_GET_INFO_MEMBER(sraider_state::get_grid_tile_info)
-{
- if (tile_index < 512)
- {
- tileinfo.set(3, tile_index, 0, 0);
- }
- else
- {
- int temp = tile_index / 32;
- tile_index = (31 - temp) * 32 + (tile_index % 32);
- tileinfo.set(4, tile_index, 0, 0);
- }
-}
-
-void mrsdyna_state::mrsdyna_io_w(uint8_t data)
-{
- // bit7 = flip
- // bit6 = grid red
- // bit5 = grid green
- // bit4 = grid blue
- // bit3 = enable stars
- // bit210 = stars speed/dir
-
- if (flip_screen() != (data & 0x80))
- {
- flip_screen_set(data & 0x80);
- machine().tilemap().mark_all_dirty();
- }
-
- m_grid_color = data & 0x70;
-}
-
-void sraider_state::sraider_io_w(uint8_t data)
-{
- mrsdyna_state::mrsdyna_io_w(data);
-
- m_stars->set_enable(BIT(data, 3));
-
- // There must be a subtle clocking difference between
- // Space Raider and the other games using this star generator,
- // hence the -1 here
- m_stars->set_speed((data & 0x07) - 1, 0x07);
-}
-
-void sraider_state::video_start()
-{
- mrsdyna_state::video_start();
-
- m_grid_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sraider_state::get_grid_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
- m_grid_tilemap->set_scroll_rows(32);
- m_grid_tilemap->set_transparent_pen(0);
-}
-
-WRITE_LINE_MEMBER(sraider_state::screen_vblank_sraider)/* update starfield position */
-{
- // falling edge
- if (!state)
- m_stars->update_state();
-}
-
-uint32_t mrsdyna_state::screen_update_mrsdyna(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- // clear the bg bitmap
- bitmap.fill(0, cliprect);
-
- // now the chars/sprites
- m_video->draw(screen, bitmap, cliprect, flip_screen());
-
- return 0;
-}
-
-uint32_t sraider_state::screen_update_sraider(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- // clear the bg bitmap
- bitmap.fill(0, cliprect);
-
- // draw the stars
- if (flip_screen())
- m_stars->draw(bitmap, cliprect, 0x60, false, 0x27, 0xff);
- else
- m_stars->draw(bitmap, cliprect, 0x60, false, 0x00, 0xd8);
-
- // draw the gridlines
- m_palette->set_indirect_color(0x40, rgb_t(
- m_grid_color & 0x40 ? 0xff : 0,
- m_grid_color & 0x20 ? 0xff : 0,
- m_grid_color & 0x10 ? 0xff : 0));
- m_grid_tilemap->draw(screen, bitmap, cliprect, 0, flip_screen());
-
- for (unsigned i = 0; i < 0x100; i++)
- {
- if (m_grid_data[i] != 0)
- {
- uint8_t x = i;
- int height = cliprect.max_y - cliprect.min_y + 1;
-
- if (flip_screen())
- x = ~x;
-
- bitmap.plot_box(x, cliprect.min_y, 1, height, 0x81);
- }
- }
-
- // now the chars/sprites
- m_video->draw(screen, bitmap, cliprect, flip_screen());
-
- return 0;
-}
diff --git a/src/mame/universal/ladybug_video.cpp b/src/mame/universal/ladybug_video.cpp
new file mode 100644
index 00000000000..82751ba3267
--- /dev/null
+++ b/src/mame/universal/ladybug_video.cpp
@@ -0,0 +1,111 @@
+// license:BSD-3-Clause
+// copyright-holders:Nicola Salmoria
+/***************************************************************************
+
+ ladybug/sraider tile/sprite hardware
+
+***************************************************************************/
+
+#include "emu.h"
+#include "ladybug_video.h"
+
+#include <algorithm>
+
+
+DEFINE_DEVICE_TYPE(LADYBUG_VIDEO, ladybug_video_device, "ladybug_video", "Lady Bug/Space Raider video")
+
+
+ladybug_video_device::ladybug_video_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, LADYBUG_VIDEO, tag, owner, clock)
+ , m_gfxdecode(*this, finder_base::DUMMY_TAG)
+{
+}
+
+void ladybug_video_device::device_start()
+{
+ m_spr_ram = std::make_unique<u8 []>(0x0400);
+ m_bg_ram = std::make_unique<u8 []>(0x0800);
+ std::fill_n(m_spr_ram.get(), 0x0400, 0);
+ std::fill_n(m_bg_ram.get(), 0x0800, 0);
+
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ladybug_video_device::get_bg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+ m_bg_tilemap->set_scroll_rows(32);
+ m_bg_tilemap->set_transparent_pen(0);
+
+ save_pointer(NAME(m_spr_ram), 0x0400);
+ save_pointer(NAME(m_bg_ram), 0x0800);
+}
+
+
+void ladybug_video_device::bg_w(offs_t offset, u8 data)
+{
+ m_bg_ram[offset & 0x07ff] = data;
+ m_bg_tilemap->mark_tile_dirty(offset & 0x03ff);
+}
+
+TILE_GET_INFO_MEMBER(ladybug_video_device::get_bg_tile_info)
+{
+ int const code = m_bg_ram[tile_index] + (BIT(m_bg_ram[0x0400 | tile_index], 3) << 8);
+ int const color = m_bg_ram[0x0400 | tile_index] & 0x07;
+
+ tileinfo.set(0, code, color, 0);
+}
+
+void ladybug_video_device::draw(screen_device &screen, bitmap_ind16 &bitmap, rectangle const &cliprect, bool flip)
+{
+ // TODO: confirm whether sraider hardware actually does this - not used by the game
+ for (unsigned offs = 0; offs < 32; ++offs)
+ {
+ int const scroll = m_bg_ram[((offs & 0x03) << 5) | (offs >> 2)];
+ m_bg_tilemap->set_scrollx(offs, flip ? -scroll : scroll);
+ }
+
+ m_bg_tilemap->draw(screen, bitmap, cliprect, 0);
+ draw_sprites(bitmap, cliprect);
+}
+
+void ladybug_video_device::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ for (int offs = 0x400 - (0x40 << 1); (0x40 << 1) <= offs; offs -= 0x40)
+ {
+ // find last valid sprite of current block
+ int i = 0;
+ while ((0x40 > i) && m_spr_ram[offs + i])
+ i += 4;
+
+ while (0 < i)
+ {
+ i -= 4;
+
+ /*
+ abccdddd eeeeeeee fffghhhh iiiiiiii
+
+ a: enable?
+ b: size (0 = 8x8, 1 = 16x16)
+ c: flip
+ d: fine-y (coarse-y is from offset)
+ e: sprite code (shift right 2 bits for 16x16 sprites)
+ f: unknown
+ g: sprite bank
+ h: color
+ i: x position
+ */
+
+ if (m_spr_ram[offs + i] & 0x80)
+ {
+ bool const big(m_spr_ram[offs + i] & 0x40);
+ bool const xflip(m_spr_ram[offs + i] & 0x20);
+ bool const yflip(m_spr_ram[offs + i] & 0x10);
+ int const code(m_spr_ram[offs + i + 1] | (BIT(m_spr_ram[offs + i + 2], 4) << 8));
+ int const color(m_spr_ram[offs + i + 2] & 0x0f);
+ int const xpos(m_spr_ram[offs + i + 3]);
+ int const ypos((offs >> 2) | (m_spr_ram[offs + i] & 0x0f));
+
+ if (big) // 16x16
+ m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, code >> 2, color, xflip, yflip, xpos, ypos - 8, 0);
+ else // 8x8
+ m_gfxdecode->gfx(2)->transpen(bitmap, cliprect, code, color, xflip, yflip, xpos, ypos, 0);
+ }
+ }
+ }
+}
diff --git a/src/mame/universal/ladybug_v.h b/src/mame/universal/ladybug_video.h
index c6b168b085f..add6b8f3bd9 100644
--- a/src/mame/universal/ladybug_v.h
+++ b/src/mame/universal/ladybug_video.h
@@ -17,10 +17,10 @@ public:
template <typename T> void set_gfxdecode_tag(T &&tag) { m_gfxdecode.set_tag(std::forward<T>(tag)); }
- uint8_t spr_r(offs_t offset) { return m_spr_ram[offset & 0x03ff]; }
- void spr_w(offs_t offset, uint8_t data) { m_spr_ram[offset & 0x03ff] = data; }
- uint8_t bg_r(offs_t offset) { return m_bg_ram[offset & 0x07ff]; }
- void bg_w(offs_t offset, uint8_t data);
+ u8 spr_r(offs_t offset) { return m_spr_ram[offset & 0x03ff]; }
+ void spr_w(offs_t offset, u8 data) { m_spr_ram[offset & 0x03ff] = data; }
+ u8 bg_r(offs_t offset) { return m_bg_ram[offset & 0x07ff]; }
+ void bg_w(offs_t offset, u8 data);
void draw(screen_device &screen, bitmap_ind16 &bitmap, rectangle const &cliprect, bool flip);
@@ -30,6 +30,8 @@ protected:
TILE_GET_INFO_MEMBER(get_bg_tile_info);
private:
+ void draw_sprites(bitmap_ind16 &bitmap, rectangle const &cliprect);
+
required_device<gfxdecode_device> m_gfxdecode;
std::unique_ptr<u8 []> m_spr_ram;
std::unique_ptr<u8 []> m_bg_ram;
@@ -37,31 +39,6 @@ private:
};
-// used by zerohour, redclash and sraider
-class zerohour_stars_device : public device_t
-{
-public:
- zerohour_stars_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
-
- void set_enable(bool on);
- void update_state();
- void set_speed(u8 speed, u8 mask);
- void draw(bitmap_ind16 &bitmap, rectangle const &cliprect, u8 pal_offs, bool has_va, u8 firstx, u8 lastx);
-
-protected:
- virtual void device_start() override;
- virtual void device_reset() override;
-
-private:
- u8 m_enable;
- u8 m_speed;
- u32 m_state = 0;
- u16 m_offset;
- u8 m_count;
-};
-
-
DECLARE_DEVICE_TYPE(LADYBUG_VIDEO, ladybug_video_device)
-DECLARE_DEVICE_TYPE(ZEROHOUR_STARS, zerohour_stars_device)
#endif // MAME_VIDEO_LADYBUG_H
diff --git a/src/mame/universal/redclash.h b/src/mame/universal/redclash.h
deleted file mode 100644
index f35f08c7cba..00000000000
--- a/src/mame/universal/redclash.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Nicola Salmoria
-/*************************************************************************
-
- Zero Hour / Red Clash
-
-*************************************************************************/
-#ifndef MAME_INCLUDES_REDCLASH_H
-#define MAME_INCLUDES_REDCLASH_H
-
-#pragma once
-
-#include "ladybug_v.h"
-#include "emupal.h"
-#include "tilemap.h"
-
-
-// redclash/zerohour
-class redclash_state : public driver_device
-{
-public:
- redclash_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag)
- , m_videoram(*this, "videoram")
- , m_spriteram(*this, "spriteram")
- , m_maincpu(*this, "maincpu")
- , m_palette(*this, "palette")
- , m_gfxdecode(*this, "gfxdecode")
- , m_stars(*this, "stars")
- { }
-
- void redclash(machine_config &config);
- void zerohour(machine_config &config);
-
- void init_redclash();
-
- DECLARE_INPUT_CHANGED_MEMBER(left_coin_inserted);
- DECLARE_INPUT_CHANGED_MEMBER(right_coin_inserted);
-
-protected:
- virtual void machine_start() override;
- virtual void video_start() override;
-
-private:
- DECLARE_WRITE_LINE_MEMBER(screen_vblank);
- void videoram_w(offs_t offset, uint8_t data);
- DECLARE_WRITE_LINE_MEMBER(gfxbank_w);
- DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
- void irqack_w(uint8_t data);
- void star_reset_w(uint8_t data);
- template <unsigned B> DECLARE_WRITE_LINE_MEMBER(star_w);
- void palette(palette_device &palette) const;
- TILE_GET_INFO_MEMBER(get_fg_tile_info);
-
- uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
- void draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect);
-
- void redclash_map(address_map &map);
- void zerohour_map(address_map &map);
-
- required_shared_ptr<uint8_t> m_videoram;
- required_shared_ptr<uint8_t> m_spriteram;
- required_device<cpu_device> m_maincpu;
- required_device<palette_device> m_palette;
- required_device<gfxdecode_device> m_gfxdecode;
- required_device<zerohour_stars_device> m_stars;
-
- tilemap_t *m_fg_tilemap = nullptr;
- int m_gfxbank = 0; // redclash only
-};
-
-#endif // MAME_INCLUDES_REDCLASH_H
diff --git a/src/mame/universal/redclash_v.cpp b/src/mame/universal/redclash_v.cpp
deleted file mode 100644
index 15f286ea210..00000000000
--- a/src/mame/universal/redclash_v.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-/***************************************************************************
-
- redclash.cpp
-
- Functions to emulate the video hardware of the machine.
-
-***************************************************************************/
-
-#include "emu.h"
-#include "redclash.h"
-#include "video/resnet.h"
-
-/***************************************************************************
-
- Convert the color PROMs into a more useable format.
-
- I'm using the same palette conversion as Lady Bug, but the Zero Hour
- schematics show a different resistor network.
-
-***************************************************************************/
-
-void redclash_state::palette(palette_device &palette) const
-{
- const uint8_t *color_prom = memregion("proms")->base();
-
- // create a lookup table for the palette
- for (int i = 0; i < 0x20; i++)
- {
- int bit0, bit1;
-
- // red component
- bit0 = BIT(color_prom[i], 0);
- bit1 = BIT(color_prom[i], 5);
- int const r = 0x47 * bit0 + 0x97 * bit1;
-
- // green component
- bit0 = BIT(color_prom[i], 2);
- bit1 = BIT(color_prom[i], 6);
- int const g = 0x47 * bit0 + 0x97 * bit1;
-
- // blue component
- bit0 = BIT(color_prom[i], 4);
- bit1 = BIT(color_prom[i], 7);
- int const b = 0x47 * bit0 + 0x97 * bit1;
-
- palette.set_indirect_color(i, rgb_t(r, g, b));
- }
-
- // star colors
- for (int i = 0; i < 0x20; i++)
- {
- int bit0, bit1;
-
- // red component
- bit0 = BIT(i, 3);
- bit1 = BIT(i, 4);
- int const b = 0x47 * bit0 + 0x97 * bit1;
-
- // green component
- bit0 = BIT(i, 1);
- bit1 = BIT(i, 2);
- int const g = 0x47 * bit0 + 0x97 * bit1;
-
- // blue component
- bit0 = BIT(i, 0);
- int const r = 0x47 * bit0;
-
- palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
- }
-
- // color_prom now points to the beginning of the lookup table
- color_prom += 0x20;
-
- // characters
- for (int i = 0; i < 0x20; i++)
- {
- uint8_t const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
- palette.set_pen_indirect(i, ctabentry);
- }
-
- // sprites
- for (int i = 0; i < 0x20; i++)
- {
- uint8_t ctabentry;
-
- ctabentry = bitswap<4>(color_prom[i], 0,1,2,3);
- palette.set_pen_indirect(i + 0x20, ctabentry);
-
- ctabentry = bitswap<4>(color_prom[i], 4,5,6,7);
- palette.set_pen_indirect(i + 0x40, ctabentry);
- }
-
- // stars
- for (int i = 0; i < 0x20; i++)
- palette.set_pen_indirect(i + 0x60, i + 0x20);
-}
-
-
-void redclash_state::videoram_w(offs_t offset, uint8_t data)
-{
- m_videoram[offset] = data;
- m_fg_tilemap->mark_tile_dirty(offset);
-}
-
-WRITE_LINE_MEMBER(redclash_state::gfxbank_w)
-{
- if (m_gfxbank != state)
- {
- m_gfxbank = state;
- m_fg_tilemap->mark_all_dirty();
- }
-}
-
-WRITE_LINE_MEMBER(redclash_state::flipscreen_w)
-{
- flip_screen_set(state);
-}
-
-void redclash_state::star_reset_w(uint8_t data)
-{
- m_stars->set_enable(true);
-}
-
-TILE_GET_INFO_MEMBER(redclash_state::get_fg_tile_info)
-{
- int code = m_videoram[tile_index];
- int color = (m_videoram[tile_index] & 0x70) >> 4; // ??
-
- tileinfo.set(0, code, color, 0);
-}
-
-
-void redclash_state::video_start()
-{
- m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(redclash_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
- m_fg_tilemap->set_transparent_pen(0);
-}
-
-void redclash_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- for (int offs = m_spriteram.bytes() - 0x20; offs >= 0; offs -= 0x20)
- {
- // find last valid sprite of current block
- int i = 0;
- while (i < 0x20 && m_spriteram[offs + i] != 0)
- i += 4;
-
- while (i > 0)
- {
- i -= 4;
-
- if (m_spriteram[offs + i] & 0x80)
- {
- int color = bitswap<4>(m_spriteram[offs + i + 2], 5,2,1,0);
- int sx = m_spriteram[offs + i + 3];
- int sy = offs / 4 + (m_spriteram[offs + i] & 0x07) - 16;
-
- switch ((m_spriteram[offs + i] & 0x18) >> 3)
- {
- case 3: /* 24x24 */
- {
- int code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
-
- m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
- code,
- color,
- 0,0,
- sx,sy,0);
- /* wraparound */
- m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
- code,
- color,
- 0,0,
- sx - 256,sy,0);
- break;
- }
-
- case 2: /* 16x16 */
- if (m_spriteram[offs + i] & 0x20) /* zero hour spaceships */
- {
- int code = ((m_spriteram[offs + i + 1] & 0xf8) >> 3) + ((m_gfxbank & 1) << 5);
- int bank = (m_spriteram[offs + i + 1] & 0x02) >> 1;
-
- m_gfxdecode->gfx(4+bank)->transpen(bitmap,cliprect,
- code,
- color,
- 0,0,
- sx,sy,0);
- }
- else
- {
- int code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
-
- m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
- code,
- color,
- 0,0,
- sx,sy,0);
- }
- break;
-
- case 1: /* 8x8 */
- m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
- m_spriteram[offs + i + 1],// + 4 * (m_spriteram[offs + i + 2] & 0x10),
- color,
- 0,0,
- sx,sy,0);
- break;
-
- case 0:
- popmessage("unknown sprite size 0");
- break;
- }
- }
- }
- }
-}
-
-void redclash_state::draw_bullets( bitmap_ind16 &bitmap, const rectangle &cliprect )
-{
- for (int offs = 0; offs < 0x20; offs++)
- {
- int sx = 8 * offs + 8;
- int sy = 0xff - m_videoram[offs + 0x20];
-
- if (flip_screen())
- sx = 264 - sx;
-
- int fine_x = m_videoram[offs] >> 3 & 7;
- sx = sx - fine_x;
-
- for (int y = 0; y < 2; y++)
- for (int x = 0; x < 8; x++)
- {
- if (cliprect.contains(sx + x, sy - y))
- bitmap.pix(sy - y, sx + x) = 0x3f;
- }
-
- }
-}
-
-WRITE_LINE_MEMBER(redclash_state::screen_vblank)
-{
- // falling edge
- if (!state)
- m_stars->update_state();
-}
-
-uint32_t redclash_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- bitmap.fill(m_palette->black_pen(), cliprect);
- m_stars->draw(bitmap, cliprect, 0x60, true, 0x00, 0xff);
- draw_bullets(bitmap, cliprect);
- draw_sprites(bitmap, cliprect);
- m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- return 0;
-}
diff --git a/src/mame/universal/sraider.cpp b/src/mame/universal/sraider.cpp
new file mode 100644
index 00000000000..421d10b7736
--- /dev/null
+++ b/src/mame/universal/sraider.cpp
@@ -0,0 +1,756 @@
+// license:BSD-3-Clause
+// copyright-holders:Frank Palazzolo
+/***************************************************************************
+
+Universal 8203-A + 8203-B PCB set
+
+Space Raider
+Mrs. Dynamite
+
+Space Raider also uses the Starfield generator board from Zero Hour,
+ Connected via flywires to these boards
+
+TODO:
+- decode cpu#2 writes to port 0x30 and 0x38 - resistors for sound
+- decode cpu#2 writes to port 0x28-0x2f - ???
+- unknown dips
+
+***************************************************************************/
+
+#include "emu.h"
+#include "ladybug_video.h"
+#include "zerohour_stars.h"
+
+#include "cpu/z80/z80.h"
+#include "machine/74259.h"
+#include "machine/gen_latch.h"
+#include "sound/sn76496.h"
+#include "video/resnet.h"
+
+#include "emupal.h"
+#include "screen.h"
+#include "speaker.h"
+#include "tilemap.h"
+
+#include <algorithm>
+
+namespace {
+
+// stripped down hardware, mrsdyna runs on this
+class mrsdyna_state : public driver_device
+{
+public:
+ mrsdyna_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_subcpu(*this, "sub")
+ , m_palette(*this, "palette")
+ , m_gfxdecode(*this, "gfxdecode")
+ , m_video(*this, "video")
+ { }
+
+ void mrsdyna(machine_config &config);
+
+protected:
+ u8 protection_r();
+ void unk_0x28_w(u8 data);
+ void unk_0x30_w(u8 data);
+ void unk_0x38_w(u8 data);
+ u8 rnd_r();
+ virtual void io_w(u8 data);
+ void mrsdyna_palette(palette_device &palette) const;
+ DECLARE_WRITE_LINE_MEMBER(update_stars);
+
+ virtual void machine_start() override;
+ virtual u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void cpu1_map(address_map &map);
+ void cpu2_map(address_map &map);
+ void cpu2_io_map(address_map &map);
+
+ required_device<cpu_device> m_maincpu;
+ required_device<cpu_device> m_subcpu;
+ required_device<palette_device> m_palette;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<ladybug_video_device> m_video;
+
+ u8 m_grid_color = 0;
+ u8 m_0x28 = 0;
+ u8 m_0x30 = 0;
+ u8 m_0x38 = 0;
+};
+
+// add stars from zerohour, uses grid layer
+class sraider_state : public mrsdyna_state
+{
+public:
+ sraider_state(const machine_config &mconfig, device_type type, const char *tag)
+ : mrsdyna_state(mconfig, type, tag)
+ , m_grid_data(*this, "grid_data")
+ , m_stars(*this, "stars")
+ { }
+
+ void sraider(machine_config &config);
+
+protected:
+ virtual void io_w(u8 data) override;
+ void sraider_palette(palette_device &palette) const;
+ DECLARE_WRITE_LINE_MEMBER(update_stars);
+ TILE_GET_INFO_MEMBER(get_grid_tile_info);
+
+ tilemap_t *m_grid_tilemap = nullptr;
+
+ virtual void video_start() override;
+ virtual u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
+
+private:
+ required_shared_ptr<u8> m_grid_data;
+ required_device<zerohour_stars_device> m_stars;
+};
+
+void mrsdyna_state::machine_start()
+{
+ save_item(NAME(m_grid_color));
+ save_item(NAME(m_0x28));
+ save_item(NAME(m_0x30));
+ save_item(NAME(m_0x38));
+}
+
+
+
+/***************************************************************************
+ Video
+***************************************************************************/
+
+void mrsdyna_state::mrsdyna_palette(palette_device &palette) const
+{
+ // assumed to be the same as Lady Bug
+ static constexpr int resistances[2] = { 470, 220 };
+
+ // compute the color output resistor weights
+ double rweights[2], gweights[2], bweights[2];
+ compute_resistor_weights(0, 255, -1.0,
+ 2, resistances, rweights, 470, 0,
+ 2, resistances, gweights, 470, 0,
+ 2, resistances, bweights, 470, 0);
+
+ const u8 *color_prom = memregion("proms")->base();
+
+ // create a lookup table for the palette
+ for (int i = 0; i < 0x20; i++)
+ {
+ int bit0, bit1;
+
+ // red component
+ bit0 = BIT(~color_prom[i], 3);
+ bit1 = BIT(~color_prom[i], 0);
+ int const r = combine_weights(rweights, bit0, bit1);
+
+ // green component
+ bit0 = BIT(~color_prom[i], 5);
+ bit1 = BIT(~color_prom[i], 4);
+ int const g = combine_weights(gweights, bit0, bit1);
+
+ // blue component
+ bit0 = BIT(~color_prom[i], 7);
+ bit1 = BIT(~color_prom[i], 6);
+ int const b = combine_weights(bweights, bit0, bit1);
+
+ palette.set_indirect_color(i, rgb_t(r, g, b));
+ }
+
+ // color_prom now points to the beginning of the lookup table
+ color_prom += 0x20;
+
+ // characters
+ for (int i = 0; i < 0x20; i++)
+ {
+ u8 const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
+ palette.set_pen_indirect(i, ctabentry);
+ }
+
+ // sprites
+ for (int i = 0; i < 0x20; i++)
+ {
+ u8 ctabentry;
+
+ ctabentry = bitswap<4>((color_prom[i] >> 0) & 0x0f, 0,1,2,3);
+ palette.set_pen_indirect(i + 0x20, ctabentry);
+
+ ctabentry = bitswap<4>((color_prom[i] >> 4) & 0x0f, 0,1,2,3);
+ palette.set_pen_indirect(i + 0x40, ctabentry);
+ }
+}
+
+void sraider_state::sraider_palette(palette_device &palette) const
+{
+ mrsdyna_palette(palette);
+
+ // star colors
+ for (int i = 0; i < 0x20; i++)
+ {
+ int bit0, bit1;
+
+ // red component
+ bit0 = BIT(i, 0);
+ int const r = 0x97 * bit0;
+
+ // green component
+ bit0 = BIT(i, 2);
+ bit1 = BIT(i, 1);
+ int const g = 0x47 * bit0 + 0x97 * bit1;
+
+ // blue component
+ bit0 = BIT(i, 4);
+ bit1 = BIT(i, 3);
+ int const b = 0x47 * bit0 + 0x97 * bit1;
+
+ palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
+ palette.set_pen_indirect(i + 0x60, i + 0x20);
+ }
+
+ // stationary part of grid
+ palette.set_pen_indirect(0x80, 0x00);
+ palette.set_pen_indirect(0x81, 0x40);
+}
+
+
+TILE_GET_INFO_MEMBER(sraider_state::get_grid_tile_info)
+{
+ if (tile_index < 512)
+ {
+ tileinfo.set(3, tile_index, 0, 0);
+ }
+ else
+ {
+ int temp = tile_index / 32;
+ tile_index = (31 - temp) * 32 + (tile_index % 32);
+ tileinfo.set(4, tile_index, 0, 0);
+ }
+}
+
+void sraider_state::video_start()
+{
+ mrsdyna_state::video_start();
+
+ m_grid_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(sraider_state::get_grid_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+ m_grid_tilemap->set_scroll_rows(32);
+ m_grid_tilemap->set_transparent_pen(0);
+}
+
+WRITE_LINE_MEMBER(sraider_state::update_stars)
+{
+ if (!state)
+ m_stars->update_state();
+}
+
+u32 mrsdyna_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // clear the bg bitmap
+ bitmap.fill(0, cliprect);
+
+ // now the chars/sprites
+ m_video->draw(screen, bitmap, cliprect, flip_screen());
+
+ return 0;
+}
+
+u32 sraider_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ // clear the bg bitmap
+ bitmap.fill(0, cliprect);
+
+ // draw the stars
+ rectangle stars_clip = cliprect;
+ if (flip_screen())
+ {
+ stars_clip.min_x = 0x27;
+ stars_clip.max_x = 0xff;
+ }
+ else
+ {
+ stars_clip.min_x = 0x00;
+ stars_clip.max_x = 0xd8;
+ }
+ stars_clip &= cliprect;
+ m_stars->draw(bitmap, stars_clip);
+
+ // draw the gridlines
+ m_palette->set_indirect_color(0x40, rgb_t(
+ m_grid_color & 0x40 ? 0xff : 0,
+ m_grid_color & 0x20 ? 0xff : 0,
+ m_grid_color & 0x10 ? 0xff : 0));
+ m_grid_tilemap->draw(screen, bitmap, cliprect, 0, flip_screen());
+
+ for (unsigned i = 0; i < 0x100; i++)
+ {
+ if (m_grid_data[i] != 0)
+ {
+ u8 x = i;
+ int height = cliprect.max_y - cliprect.min_y + 1;
+
+ if (flip_screen())
+ x = ~x;
+
+ bitmap.plot_box(x, cliprect.min_y, 1, height, 0x81);
+ }
+ }
+
+ // now the chars/sprites
+ m_video->draw(screen, bitmap, cliprect, flip_screen());
+
+ return 0;
+}
+
+
+
+/***************************************************************************
+ I/O
+***************************************************************************/
+
+void mrsdyna_state::io_w(u8 data)
+{
+ // bit7 = flip
+ // bit6 = grid red
+ // bit5 = grid green
+ // bit4 = grid blue
+ // bit3 = enable stars (not used for mrsdyna)
+ // bit210 = stars speed/dir (not used for mrsdyna)
+
+ if (flip_screen() != (data & 0x80))
+ {
+ flip_screen_set(data & 0x80);
+ machine().tilemap().mark_all_dirty();
+ }
+
+ m_grid_color = data & 0x70;
+}
+
+void sraider_state::io_w(u8 data)
+{
+ mrsdyna_state::io_w(data);
+
+ m_stars->set_enable(BIT(data, 3));
+
+ // There must be a subtle clocking difference between
+ // Space Raider and the other games using this star generator,
+ // hence the -1 here
+ m_stars->set_speed((data & 0x07) - 1, 0x07);
+}
+
+// documentation TBD - 556 dual timer
+u8 mrsdyna_state::rnd_r()
+{
+ return machine().rand() & 3;
+}
+
+// Protection - documentation TBD
+u8 mrsdyna_state::protection_r()
+{
+ // This must return X011111X or cpu #1 will hang
+ // see code at rst $10
+ return 0x3e;
+}
+
+// Unknown IO - documentation TBD
+void mrsdyna_state::unk_0x28_w(u8 data)
+{
+ // These 8 bits are stored in the LS259 latch at A7,
+ // and connected to all the select lines on 2 4066s at B7/C7
+ m_0x28 = data;
+}
+
+// documentation TBD
+void mrsdyna_state::unk_0x30_w(u8 data)
+{
+ // bits 0-2 select 4051s at M7 and M8
+ // bits 3-5 select 4051s at K7 and K8
+ m_0x30 = data & 0x3f;
+}
+
+// documentation TBD
+void mrsdyna_state::unk_0x38_w(u8 data)
+{
+ // These 6 bits are stored in the LS174 latch at N8
+ // bits 0-2 select 4051s at H7 and H8
+ // bits 3-5 select 4051s at E7 and E8
+ m_0x38 = data & 0x3f;
+}
+
+
+
+/***************************************************************************
+ Address Maps
+***************************************************************************/
+
+void mrsdyna_state::cpu1_map(address_map &map)
+{
+ // LS138 @ J4
+ map(0x0000, 0x5fff).rom(); // 2764s at R4, N4, and M4
+ // LS138 @ J4 and LS139 @ H4
+ map(0x6000, 0x6fff).ram(); // 6116s @ K3 & M3, also connected to clk on PAL K2 (16R6, U001)
+ map(0x7000, 0x73ff).w("video", FUNC(ladybug_video_device::spr_w)); // pin 29 on ribbon
+ //map(0x77ff, 0x7fff); // LS139 @ H4 pin7 is NC
+
+ // LS138 @ J4, Pin11 (0x8000-0x9fff) and
+ // LS138 @ N3 (bottom 3 bits)
+ // (all of these are read/write)
+ map(0x8005, 0x8005).mirror(0x1ff8).r(FUNC(mrsdyna_state::protection_r)); // OE on PAL @ K2 (16R6, U001) (100x xxxx xxxx x101)
+ map(0x8006, 0x8006).mirror(0x1ff8).w("soundlatch_low", FUNC(generic_latch_8_device::write)); // LS374 @ P6
+ map(0x8007, 0x8007).mirror(0x1ff8).w("soundlatch_high", FUNC(generic_latch_8_device::write)); // LS374 @ R6
+ map(0x8000, 0x8000).mirror(0x1ff8).portr("IN0");
+ map(0x8001, 0x8001).mirror(0x1ff8).portr("IN1");
+ map(0x8002, 0x8002).mirror(0x1ff8).portr("DSW0");
+ map(0x8003, 0x8003).mirror(0x1ff8).portr("DSW1");
+ //map(0x8004, 0x8004).mirror(0x1ff8).portr("IN2"); // extra JAMMA pins
+ // LS138 @ J4, Pin10 (0xa000-0xbfff) // NC
+ // LS138 @ J4, Pin9 (0xc000-0xdfff)
+ map(0xd000, 0xd7ff).w("video", FUNC(ladybug_video_device::bg_w)); // pin 27 on ribbon
+ // LS138 @ J4, Pin7 (0xe000-0xffff)
+ map(0xe000, 0xe000).nopw(); //unknown 0x10 when in attract, 0x20 when coined/playing - disabled watchdog based on LS123 @ F4
+}
+
+void mrsdyna_state::cpu2_map(address_map &map)
+{
+ // LS138 @ P7
+ map(0x0000, 0x5fff).rom(); // 2764s at H6,J6, and L6
+ map(0x6000, 0x63ff).mirror(0x0400).ram(); // 2x2114 @ M6/N6
+ map(0x8000, 0x8000).mirror(0x1fff).r("soundlatch_low", FUNC(generic_latch_8_device::read)); // LS374 @ P6
+ map(0xa000, 0xa000).mirror(0x1fff).r("soundlatch_high", FUNC(generic_latch_8_device::read)); // LS374 @ R6
+ map(0xc000, 0xc000).mirror(0x1fff).r(FUNC(mrsdyna_state::rnd_r)); // LS125 @ P8 - reads 556 outputs to D1 and D0?
+ // LS138 @ P7 (nY7) and LS139 @ H4
+ map(0xe000, 0xe0ff).mirror(0x0300).writeonly().share("grid_data"); // HD6148P @ D6
+ map(0xe800, 0xefff).w(FUNC(mrsdyna_state::io_w)); // LS273 @ D4
+ //map(0xf000, 0xf7ff) // NC
+ //map(0xf800, 0xffff) // NC
+}
+
+void mrsdyna_state::cpu2_io_map(address_map &map)
+{
+ map.global_mask(0xff);
+ // LS138 @ A8
+ map(0x00, 0x07).w("sn1", FUNC(sn76489_device::write)); // J214X2 @ N9
+ map(0x08, 0x0f).w("sn2", FUNC(sn76489_device::write)); // J214X2 @ M9
+ map(0x10, 0x17).w("sn3", FUNC(sn76489_device::write)); // J214X2 @ L9
+ map(0x18, 0x1f).w("sn4", FUNC(sn76489_device::write)); // J214X2 @ K9
+ map(0x20, 0x27).w("sn5", FUNC(sn76489_device::write)); // J214X2 @ J9
+ map(0x28, 0x2f).w("unklatch", FUNC(ls259_device::write_d0)); // LS259 @ A7
+ map(0x30, 0x37).w(FUNC(mrsdyna_state::unk_0x30_w)); // LS174 @ N7
+ map(0x38, 0x3f).w(FUNC(mrsdyna_state::unk_0x38_w)); // LS174 @ N8
+}
+
+
+
+/***************************************************************************
+ Input Ports
+***************************************************************************/
+
+static INPUT_PORTS_START( sraider )
+ PORT_START("IN0")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START1 )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START2 )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // JAMMA PIN 12
+
+ PORT_START("IN1")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_COCKTAIL
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_COCKTAIL
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_COCKTAIL
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_COCKTAIL
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // VBLANK????
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
+
+ PORT_START("DSW0") // DSW0 @ R3 via '244 @ R2
+ PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW0:7,8")
+ PORT_DIPSETTING( 0x03, DEF_STR( Easy ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Medium ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( Hard ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) )
+ PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
+ PORT_DIPSETTING( 0x00, "3 Letters" )
+ PORT_DIPSETTING( 0x04, "10 Letters" )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW0:5")
+ PORT_DIPSETTING( 0x08, DEF_STR( No ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Yes ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
+ PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
+ PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
+ PORT_DIPSETTING( 0x00, "2" )
+ PORT_DIPSETTING( 0xc0, "3" )
+ PORT_DIPSETTING( 0x80, "4" )
+ PORT_DIPSETTING( 0x40, "5" )
+
+ // Free Play setting works when it's set for both
+ PORT_START("DSW1") // DSW1 @ P3 via '244 @ P2
+ PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:8,7,6,5")
+ // settings 0x00 through 0x05 all give 1 Coin/1 Credit
+ PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
+ PORT_DIPSETTING( 0x09, DEF_STR( 2C_2C ) )
+ PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
+ PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,3,2,1")
+ // settings 0x00 through 0x50 all give 1 Coin/1 Credit
+ PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
+ PORT_DIPSETTING( 0x90, DEF_STR( 2C_2C ) )
+ PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
+INPUT_PORTS_END
+
+static INPUT_PORTS_START( mrsdyna )
+ PORT_INCLUDE( sraider )
+
+ PORT_MODIFY("DSW0")
+ PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:8")
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:7")
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, "High Score Names" ) PORT_DIPLOCATION("SW0:6")
+ PORT_DIPSETTING( 0x00, "3 Letters" )
+ PORT_DIPSETTING( 0x04, "12 Letters" )
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:5")
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW0:4")
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW0:3")
+ PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) )
+ PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW0:1,2")
+ PORT_DIPSETTING( 0x00, "2" )
+ PORT_DIPSETTING( 0xc0, "3" )
+ PORT_DIPSETTING( 0x80, "4" )
+ PORT_DIPSETTING( 0x40, "5" )
+INPUT_PORTS_END
+
+
+
+/***************************************************************************
+ GFX Layouts
+***************************************************************************/
+
+static const gfx_layout charlayout =
+{
+ 8,8, /* 8*8 characters */
+ 512, /* 512 characters */
+ 2, /* 2 bits per pixel */
+ { 0, 512*8*8 }, /* the two bitplanes are separated */
+ { 7, 6, 5, 4, 3, 2, 1, 0 },
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
+ 8*8 /* every char takes 8 consecutive bytes */
+};
+
+static const gfx_layout spritelayout =
+{
+ 16,16, /* 16*16 sprites */
+ 128, /* 128 sprites */
+ 2, /* 2 bits per pixel */
+ { 1, 0 }, /* the two bitplanes are packed in two consecutive bits */
+ { 0, 2, 4, 6, 8, 10, 12, 14,
+ 8*16+0, 8*16+2, 8*16+4, 8*16+6, 8*16+8, 8*16+10, 8*16+12, 8*16+14 },
+ { 23*16, 22*16, 21*16, 20*16, 19*16, 18*16, 17*16, 16*16,
+ 7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 },
+ 64*8 /* every sprite takes 64 consecutive bytes */
+};
+static const gfx_layout spritelayout2 =
+{
+ 8,8, /* 8*8 sprites */
+ 512, /* 512 sprites */
+ 2, /* 2 bits per pixel */
+ { 1, 0 }, /* the two bitplanes are packed in two consecutive bits */
+ { 0, 2, 4, 6, 8, 10, 12, 14 },
+ { 7*16, 6*16, 5*16, 4*16, 3*16, 2*16, 1*16, 0*16 },
+ 16*8 /* every sprite takes 16 consecutive bytes */
+};
+
+static const gfx_layout gridlayout =
+{
+ 8,8, /* 8*8 characters */
+ 512, /* 512 characters */
+ 1, /* 1 bit per pixel */
+ { 0 },
+ { 7, 6, 5, 4, 3, 2, 1, 0 },
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8},
+ 8*8 /* every char takes 8 consecutive bytes */
+};
+static const gfx_layout gridlayout2 =
+{
+ 8,8, /* 8*8 characters */
+ 512, /* 512 characters */
+ 1, /* 1 bit per pixel */
+ { 0 },
+ { 7, 6, 5, 4, 3, 2, 1, 0 },
+ { 7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8 },
+ 8*8 /* every char takes 8 consecutive bytes */
+};
+
+static GFXDECODE_START( gfx_mrsdyna )
+ GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
+ GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
+ GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
+GFXDECODE_END
+
+static GFXDECODE_START( gfx_sraider )
+ GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 )
+ GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 4*8, 16 )
+ GFXDECODE_ENTRY( "gfx2", 0, spritelayout2, 4*8, 16 )
+ GFXDECODE_ENTRY( "gfx3", 0, gridlayout, 4*8+4*16+32, 1 )
+ GFXDECODE_ENTRY( "gfx3", 0, gridlayout2, 4*8+4*16+32, 1 )
+GFXDECODE_END
+
+
+
+/***************************************************************************
+ Machine Configs
+***************************************************************************/
+
+void mrsdyna_state::mrsdyna(machine_config &config)
+{
+ // basic machine hardware
+ Z80(config, m_maincpu, 4000000);
+ m_maincpu->set_addrmap(AS_PROGRAM, &mrsdyna_state::cpu1_map);
+ m_maincpu->set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
+
+ Z80(config, m_subcpu, 4000000);
+ m_subcpu->set_addrmap(AS_PROGRAM, &mrsdyna_state::cpu2_map);
+ m_subcpu->set_addrmap(AS_IO, &mrsdyna_state::cpu2_io_map);
+ m_subcpu->set_vblank_int("screen", FUNC(mrsdyna_state::irq0_line_hold));
+
+ GENERIC_LATCH_8(config, "soundlatch_low");
+ GENERIC_LATCH_8(config, "soundlatch_high");
+
+ ls259_device &unklatch(LS259(config, "unklatch"));
+ unklatch.parallel_out_cb().set(FUNC(mrsdyna_state::unk_0x28_w));
+
+ // video hardware
+ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
+ screen.set_raw(9'828'000 / 2, 312, 8, 248, 262, 32, 224);
+ screen.set_screen_update(FUNC(mrsdyna_state::screen_update));
+ screen.set_palette(m_palette);
+
+ GFXDECODE(config, m_gfxdecode, m_palette, gfx_mrsdyna);
+ PALETTE(config, m_palette, FUNC(mrsdyna_state::mrsdyna_palette), 4*8 + 4*16, 32);
+
+ LADYBUG_VIDEO(config, m_video, 4000000).set_gfxdecode_tag(m_gfxdecode);
+
+ // sound hardware
+ SPEAKER(config, "mono").front_center();
+
+ SN76489(config, "sn1", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
+ SN76489(config, "sn2", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
+ SN76489(config, "sn3", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
+ SN76489(config, "sn4", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
+ SN76489(config, "sn5", 4000000).add_route(ALL_OUTPUTS, "mono", 0.2);
+}
+
+void sraider_state::sraider(machine_config &config)
+{
+ mrsdyna(config);
+
+ // video hardware
+ GFXDECODE(config.replace(), m_gfxdecode, m_palette, gfx_sraider);
+ PALETTE(config.replace(), m_palette, FUNC(sraider_state::sraider_palette), 4*8 + 4*16 + 32 + 2, 32 + 32 + 1);
+
+ ZEROHOUR_STARS(config, m_stars).has_va_bit(false);
+ subdevice<screen_device>("screen")->screen_vblank().set(FUNC(sraider_state::update_stars));
+}
+
+
+
+/***************************************************************************
+ ROM Definitions
+***************************************************************************/
+
+ROM_START( sraider )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD( "sraid3.r4", 0x0000, 0x2000, CRC(0f389774) SHA1(c67596e6bf00175ff0a241506cd2f88114d05933) )
+ ROM_LOAD( "sraid2.n4", 0x2000, 0x2000, CRC(38a48db0) SHA1(6f4f384d702fb8ee4bb2ef579638239d57e32ddd) )
+ ROM_LOAD( "sraid1.m4", 0x4000, 0x2000, CRC(2f302a4e) SHA1(3a902ce6858f38df88b60830bef4b1d45b09b2df) )
+
+ ROM_REGION( 0x10000, "sub", 0 )
+ ROM_LOAD( "sraid-s4.h6", 0x0000, 0x2000, CRC(57173a12) SHA1(6cb8fd4826e499f9a4e63621d58bc4b596cc261e) )
+ ROM_LOAD( "sraid-s5.j6", 0x2000, 0x2000, CRC(5a459179) SHA1(a261c8f3c7c4cd4587c003bbbe815d2c4e01ffbc) )
+ ROM_LOAD( "sraid-s6.l6", 0x4000, 0x2000, CRC(ea3aa25d) SHA1(353c0d075d5e0a3bc25a65e2748f5eb5212a844d) )
+
+ ROM_REGION( 0x2000, "gfx1", 0 )
+ ROM_LOAD( "sraid-s0.k6", 0x0000, 0x1000, CRC(a0373909) SHA1(00e3bd5dd90769d670fc3c51edd1cd4b69e6132d) )
+ ROM_LOAD( "sraids11.l6", 0x1000, 0x1000, CRC(ba22d949) SHA1(83762ced1df92ff594887e44d5b783826bbfb0c9) )
+
+ ROM_REGION( 0x2000, "gfx2", 0 )
+ ROM_LOAD( "sraid-s7.m2", 0x0000, 0x1000, CRC(299f8e07) SHA1(1de71f251286088487da7285d6f8070147002af5) )
+ ROM_LOAD( "sraid-s8.n2", 0x1000, 0x1000, CRC(57ba8888) SHA1(2aa1a5f682d146a55a96e471bb78e5c60da02bf9) )
+
+ ROM_REGION( 0x1000, "gfx3", 0 ) /* fixed portion of the grid */
+ ROM_LOAD( "sraid-s9.f6", 0x0000, 0x1000, CRC(2380b90f) SHA1(0310554e3f2ec973c2bb6e816d04e5c0c1e0a0b9) )
+
+ ROM_REGION( 0x0060, "proms", 0 )
+ ROM_LOAD( "srpr10-1.a2", 0x0000, 0x0020, CRC(121fdb99) SHA1(3bc092da40beb129a4df3db2f55d22bbbcf7bad8) )
+ ROM_LOAD( "srpr10-2.l3", 0x0020, 0x0020, CRC(88b67e70) SHA1(e21ee2939e96dffee101bd92c62ed975b6b64001) )
+ ROM_LOAD( "srpr10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
+ROM_END
+
+ROM_START( mrsdyna )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ // NOTE: Mrs. Dynamite returns ROM ERROR in test mode. It does an 8-bit checksum on these 3
+ // ROMs and computes 0xFF. The answer to pass the test is 0x00.
+ // However, these images were dumped twice, and seem to work fine.
+ ROM_LOAD( "mrsd-8203a-r4.f3", 0x0000, 0x2000, CRC(c944062c) SHA1(c61fc327d67595e601f6a7e5e337646f5f9d351b) )
+ ROM_LOAD( "mrsd-8203a-n4.f2", 0x2000, 0x2000, CRC(d1b9c7bb) SHA1(c139c8ae5b14924eb04a265095a7ab95ac5370af) )
+ ROM_LOAD( "mrsd-8203a-m4.f1", 0x4000, 0x2000, CRC(d25b1dfe) SHA1(f68c6fb2cda37fcffbe7c3c2a3cc5cb372c4101b) )
+
+ ROM_REGION( 0x10000, "sub", 0 )
+ ROM_LOAD( "mrsd-8203a-h6.f4", 0x0000, 0x2000, CRC(04f8617b) SHA1(64deef2269790d8460d0ad510548e178f0f61607) )
+ ROM_LOAD( "mrsd-8203a-j6.f5", 0x2000, 0x2000, CRC(1ffb5fc3) SHA1(e8fc7b95663a396ef7d46ba6ce24973a3c343381) )
+ ROM_LOAD( "mrsd-8203a-l6.f6", 0x4000, 0x2000, CRC(5a0f5030) SHA1(d1530230fe6c666f7920cb82cb47f5fcc7e1ecc8) )
+
+ ROM_REGION( 0x2000, "gfx1", 0 )
+ ROM_LOAD( "mrsd-8203b-k6.f10", 0x0000, 0x1000, CRC(e33cb26e) SHA1(207fa986754f8d7cd0bb3e56fd271ee0c1990269) )
+ ROM_LOAD( "mrsd-8203b-l6.f11", 0x1000, 0x1000, CRC(a327ba05) SHA1(5eac27b48d14fec179919fe0902a6c7ada95f2b2) )
+
+ ROM_REGION( 0x2000, "gfx2", 0 )
+ ROM_LOAD( "mrsd-8203b-m2.f7", 0x0000, 0x1000, CRC(a00ae797) SHA1(adff7f38870b7e8fa114886792a3acbb7a5726ab) )
+ ROM_LOAD( "mrsd-8203b-n2.f8", 0x1000, 0x1000, CRC(81f2bdbd) SHA1(45ee1d62462cfadf7d2c46767f03ccfb3c876c08) )
+
+ ROM_REGION( 0x0060, "proms", 0 )
+ ROM_LOAD( "mrsd-10-1.a2", 0x0000, 0x0020, CRC(4a819ad4) SHA1(d9072af7e52b506c1bcf8a327242d470eb240857) )
+ ROM_LOAD( "mrsd-10-2.l3", 0x0020, 0x0020, CRC(2d926a3a) SHA1(129fb60ce3df67614e39dcaac9c93f0652addbbb) )
+ ROM_LOAD( "mrsd-10-3.c1", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
+ROM_END
+
+} // anonymous namespace
+
+
+
+/***************************************************************************
+ Drivers
+***************************************************************************/
+
+// YEAR NAME PARENT MACHINE INPUT STATE INIT SCREEN COMPANY FULLNAME FLAGS
+GAME( 1982, sraider, 0, sraider, sraider, sraider_state, empty_init, ROT270, "Universal", "Space Raider", MACHINE_SUPPORTS_SAVE )
+GAME( 1982, mrsdyna, 0, mrsdyna, mrsdyna, mrsdyna_state, empty_init, ROT270, "Universal", "Mrs. Dynamite", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/universal/redclash.cpp b/src/mame/universal/zerohour.cpp
index 71514a09e0d..51a553d40ab 100644
--- a/src/mame/universal/redclash.cpp
+++ b/src/mame/universal/zerohour.cpp
@@ -13,91 +13,545 @@ Notes:
Earlier version? Gameplay is different too.
TODO:
-- Colors are not right. In zerohour P1 score should be white, the top score green,
- and "TOP" should be magenta. How is this determined? It's as if only the top part
- of the screen has this exception. Maybe via the unknown PROM? Sprite colors look ok.
-- Some graphical problems in both games
-- redclash supports more background layer effects: white+mixed with other colors,
- used in canyon parts and during the big ufo explosion
-- According to video reference(could only find 1), redclash player bullets should be
- 4*2px red on the 1st half of the screen and 8*2px yellow on the 2nd half, zerohour
- bullets are correct though(always 8*2px magenta)
-- Sound (analog, schematics available for Zero Hour)
+- redclash supports more background layer effects: white+mixed with other colors
+ scrolling at the same speed as the stars, it's used in canyon parts and during the
+ big ufo explosion
+- redclash canyon level, a gap sometimes appears on the right side, maybe BTANB
+- replace zerohour samples with netlist audio (schematics available but bad quality)
+- add redclash samples or netlist audio (eg. player shot sound, explosions)
+- redclash beeper frequency range should be higher, but it can't be solved with a
+ simple multiply calculation. Besides, anything more than right now and ears will
+ be destroyed, so maybe the sound is softer(filtered)
+
+BTANB:
+- redclash gameplay tempo is erratic (many slowdowns)
+- redclash beeper sound stops abruptly at the canyon parts
+- other than the pitch being inaccurate (see TODO), redclash beeper really does
+ sound like garbage, the only time it sounds pleasing is during the boss fight
***************************************************************************/
#include "emu.h"
-#include "redclash.h"
+#include "zerohour_stars.h"
#include "cpu/z80/z80.h"
#include "machine/74259.h"
-#include "sound/sn76496.h"
+#include "machine/clock.h"
+#include "sound/spkrdev.h"
+#include "sound/samples.h"
+#include "video/resnet.h"
+
+#include "emupal.h"
#include "screen.h"
#include "speaker.h"
+#include "tilemap.h"
+
+namespace {
+
+// zerohour/common
+class zerohour_state : public driver_device
+{
+public:
+ zerohour_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_videoram(*this, "videoram")
+ , m_spriteram(*this, "spriteram")
+ , m_maincpu(*this, "maincpu")
+ , m_outlatch(*this, "outlatch%u", 0)
+ , m_palette(*this, "palette")
+ , m_gfxdecode(*this, "gfxdecode")
+ , m_stars(*this, "stars")
+ , m_samples(*this, "samples")
+ { }
+
+ void base(machine_config &config);
+ void zerohour(machine_config &config);
+
+ void init_zerohour();
+
+ DECLARE_INPUT_CHANGED_MEMBER(left_coin_inserted);
+ DECLARE_INPUT_CHANGED_MEMBER(right_coin_inserted);
+
+protected:
+ virtual void machine_start() override;
+ virtual void video_start() override;
+
+ DECLARE_WRITE_LINE_MEMBER(update_stars);
+ void videoram_w(offs_t offset, u8 data);
+ DECLARE_WRITE_LINE_MEMBER(flipscreen_w);
+ void irqack_w(u8 data) { m_maincpu->set_input_line(0, CLEAR_LINE); }
+ void star_reset_w(u8 data);
+ template <unsigned N> DECLARE_WRITE_LINE_MEMBER(star_w);
+ template <unsigned N> DECLARE_WRITE_LINE_MEMBER(sample_w);
+ virtual DECLARE_WRITE_LINE_MEMBER(sound_enable_w);
+
+ void palette(palette_device &palette) const;
+ TILE_GET_INFO_MEMBER(get_fg_tile_info);
+
+ virtual u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect);
+
+ void zerohour_map(address_map &map);
+
+ required_shared_ptr<u8> m_videoram;
+ required_shared_ptr<u8> m_spriteram;
+ required_device<cpu_device> m_maincpu;
+ required_device_array<ls259_device, 2> m_outlatch;
+ required_device<palette_device> m_palette;
+ required_device<gfxdecode_device> m_gfxdecode;
+ required_device<zerohour_stars_device> m_stars;
+ optional_device<samples_device> m_samples;
+
+ tilemap_t *m_fg_tilemap = nullptr;
+ int m_sound_on = 0;
+ int m_gfxbank = 0; // redclash only
+};
+
+// redclash, adds background layer, one extra sound channel
+class redclash_state : public zerohour_state
+{
+public:
+ redclash_state(const machine_config &mconfig, device_type type, const char *tag)
+ : zerohour_state(mconfig, type, tag)
+ , m_beep_clock(*this, "beep_clock")
+ , m_beep(*this, "beep")
+ { }
+
+ void redclash(machine_config &config);
+
+protected:
+ virtual void machine_start() override;
+ virtual u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
+ virtual DECLARE_WRITE_LINE_MEMBER(sound_enable_w) override;
+
+private:
+ DECLARE_WRITE_LINE_MEMBER(gfxbank_w);
+ void background_w(u8 data);
+ void beeper_w(u8 data);
+
+ void redclash_map(address_map &map);
+
+ required_device<clock_device> m_beep_clock;
+ required_device<speaker_sound_device> m_beep;
+
+ u8 m_background = 0;
+};
+
+void zerohour_state::init_zerohour()
+{
+ u8 const *const src = memregion("gfx2")->base();
+ u8 *const dst = memregion("gfx3")->base();
+ int const len = memregion("gfx3")->bytes();
+
+ /* rearrange the sprite graphics */
+ for (int i = 0; i < len; i++)
+ {
+ int const j = (i & ~0x003e) | ((i & 0x0e) << 2) | ((i & 0x30) >> 3);
+ dst[i] = src[j];
+ }
+}
+
+void zerohour_state::machine_start()
+{
+ save_item(NAME(m_sound_on));
+}
+
+void redclash_state::machine_start()
+{
+ zerohour_state::machine_start();
+ save_item(NAME(m_gfxbank));
+ save_item(NAME(m_background));
+}
+
-void redclash_state::irqack_w(uint8_t data)
+/***************************************************************************
+ Video
+***************************************************************************/
+
+/***************************************************************************
+
+ Convert the color PROMs into a more useable format.
+
+ I'm using the same palette conversion as Lady Bug, but the Zero Hour
+ schematics show a different resistor network.
+
+***************************************************************************/
+
+void zerohour_state::palette(palette_device &palette) const
{
- m_maincpu->set_input_line(0, CLEAR_LINE);
+ const u8 *color_prom = memregion("proms")->base();
+
+ // create a lookup table for the palette
+ for (int i = 0; i < 0x20; i++)
+ {
+ int bit0, bit1;
+
+ // red component
+ bit0 = BIT(color_prom[i], 0);
+ bit1 = BIT(color_prom[i], 5);
+ int const r = 0x47 * bit0 + 0x97 * bit1;
+
+ // green component
+ bit0 = BIT(color_prom[i], 2);
+ bit1 = BIT(color_prom[i], 6);
+ int const g = 0x47 * bit0 + 0x97 * bit1;
+
+ // blue component
+ bit0 = BIT(color_prom[i], 4);
+ bit1 = BIT(color_prom[i], 7);
+ int const b = 0x47 * bit0 + 0x97 * bit1;
+
+ palette.set_indirect_color(i, rgb_t(r, g, b));
+ }
+
+ // star colors
+ for (int i = 0; i < 0x20; i++)
+ {
+ int bit0, bit1;
+
+ // red component
+ bit0 = BIT(i, 0);
+ int const r = 0x97 * bit0;
+
+ // green component
+ bit0 = BIT(i, 2);
+ bit1 = BIT(i, 1);
+ int const g = 0x47 * bit0 + 0x97 * bit1;
+
+ // blue component
+ bit0 = BIT(i, 4);
+ bit1 = BIT(i, 3);
+ int const b = 0x47 * bit0 + 0x97 * bit1;
+
+ palette.set_indirect_color(i + 0x20, rgb_t(r, g, b));
+ }
+
+ // color_prom now points to the beginning of the lookup table
+ color_prom += 0x20;
+
+ // characters
+ for (int i = 0; i < 0x20; i++)
+ {
+ u8 const ctabentry = ((i << 3) & 0x18) | ((i >> 2) & 0x07);
+ palette.set_pen_indirect(i, ctabentry);
+ }
+
+ // sprites
+ for (int i = 0; i < 0x20; i++)
+ {
+ u8 ctabentry;
+
+ ctabentry = bitswap<4>(color_prom[i], 0,1,2,3);
+ palette.set_pen_indirect(i + 0x20, ctabentry);
+
+ ctabentry = bitswap<4>(color_prom[i], 4,5,6,7);
+ palette.set_pen_indirect(i + 0x40, ctabentry);
+ }
+
+ // stars
+ for (int i = 0; i < 0x20; i++)
+ palette.set_pen_indirect(i + 0x60, i + 0x20);
}
-template <unsigned B> WRITE_LINE_MEMBER(redclash_state::star_w)
+
+void zerohour_state::videoram_w(offs_t offset, u8 data)
{
- m_stars->set_speed(state ? 1 << B : 0, 1U << B);
+ m_videoram[offset] = data;
+ m_fg_tilemap->mark_tile_dirty(offset);
}
-void redclash_state::zerohour_map(address_map &map)
+WRITE_LINE_MEMBER(redclash_state::gfxbank_w)
+{
+ m_gfxbank = state;
+}
+
+void redclash_state::background_w(u8 data)
+{
+ // redclash background layer
+ // 0x70: normal, 0xc3: white, 0x92: white+green, 0xf4: white+red/black
+ m_background = data;
+}
+
+WRITE_LINE_MEMBER(zerohour_state::flipscreen_w)
+{
+ flip_screen_set(state);
+}
+
+template <unsigned N> WRITE_LINE_MEMBER(zerohour_state::star_w)
+{
+ m_stars->set_speed(state ? 1 << N : 0, 1U << N);
+}
+
+void zerohour_state::star_reset_w(u8 data)
+{
+ m_stars->set_enable(true);
+}
+
+WRITE_LINE_MEMBER(zerohour_state::update_stars)
+{
+ if (!state)
+ m_stars->update_state();
+}
+
+
+TILE_GET_INFO_MEMBER(zerohour_state::get_fg_tile_info)
+{
+ int code = m_videoram[tile_index];
+ int color = (m_videoram[tile_index] & 0x70) >> 4;
+
+ // score panel colors are determined differently: P1=5, TOP=4, P2=7
+ if ((tile_index & 0x1f) > 0x1b)
+ color = (((tile_index >> 5) + 12) & 0x1f) >> 3 ^ 7;
+
+ tileinfo.set(0, code, color, 0);
+}
+
+void zerohour_state::video_start()
+{
+ m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(zerohour_state::get_fg_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
+ m_fg_tilemap->set_transparent_pen(0);
+}
+
+void zerohour_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ for (int offs = m_spriteram.bytes() - 0x20; offs >= 0; offs -= 0x20)
+ {
+ // find last valid sprite of current block
+ int i = 0;
+ while (i < 0x20 && m_spriteram[offs + i] != 0)
+ i += 4;
+
+ while (i > 0)
+ {
+ i -= 4;
+
+ /*
+ e-sssyyy iiiiiiii --c--ccc xxxxxxxx
+
+ e: enable?
+ i: code (some bits unused for large sprites)
+ s: size (0x20 only applies to size 16x16)
+ c: color
+ x: x position
+ y: fine-y (coarse-y is from offset)
+ */
+
+ if (m_spriteram[offs + i] & 0x80)
+ {
+ int sx = m_spriteram[offs + i + 3];
+ int sy = offs / 4 + (m_spriteram[offs + i] & 0x07) - 16;
+ int color = bitswap<4>(m_spriteram[offs + i + 2], 5,2,1,0);
+ int bank = 0, code = 0;
+
+ switch ((m_spriteram[offs + i] & 0x18) >> 3)
+ {
+ case 1: // 8x8
+ bank = 1;
+ code = m_spriteram[offs + i + 1] + ((m_gfxbank & 1) << 8);
+ break;
+
+ case 2: // 16x16
+ if (m_spriteram[offs + i] & 0x20) // zero hour spaceships
+ {
+ bank = 4 + ((m_spriteram[offs + i + 1] & 0x02) >> 1);
+ code = ((m_spriteram[offs + i + 1] & 0xf8) >> 3) + ((m_gfxbank & 1) << 5);
+ }
+ else
+ {
+ bank = 2;
+ code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
+ }
+ break;
+
+ case 3: // 24x24
+ {
+ bank = 3;
+ code = ((m_spriteram[offs + i + 1] & 0xf0) >> 4) + ((m_gfxbank & 1) << 4);
+ break;
+ }
+
+ default: // invalid
+ break;
+ }
+
+ if (bank > 0)
+ {
+ m_gfxdecode->gfx(bank)->transpen(bitmap, cliprect, code, color, 0, 0, sx, sy, 0);
+ m_gfxdecode->gfx(bank)->transpen(bitmap, cliprect, code, color, 0, 0, sx - 256, sy, 0); // wraparound
+ }
+ }
+ }
+ }
+}
+
+void zerohour_state::draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ for (int offs = 0; offs < 0x20; offs++)
+ {
+ int sx = 8 * offs + 8;
+ int sy = 0xff - m_videoram[offs + 0x20];
+
+ // width and color are from the same bitfield
+ int width = 8 - (m_videoram[offs] >> 5 & 6);
+ int color = (m_videoram[offs] >> 3 & 0x10) | 5;
+
+ if (flip_screen())
+ sx = 264 - sx;
+
+ int fine_x = m_videoram[offs] >> 3 & 7;
+ sx -= fine_x;
+
+ for (int y = 0; y < 2; y++)
+ for (int x = 0; x < width; x++)
+ {
+ if (cliprect.contains(sx + x, sy - y))
+ bitmap.pix(sy - y, sx + x) = color;
+ }
+
+ }
+}
+
+u32 zerohour_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ bitmap.fill(m_palette->black_pen(), cliprect);
+ m_stars->draw(bitmap, cliprect);
+ draw_bullets(bitmap, cliprect);
+ draw_sprites(bitmap, cliprect);
+ m_fg_tilemap->draw(screen, bitmap, cliprect);
+
+ return 0;
+}
+
+u32 redclash_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ bitmap.fill(m_palette->black_pen(), cliprect);
+ m_stars->draw(bitmap, cliprect);
+
+ // background effect, preliminary
+ if (m_background & 0xf)
+ bitmap.fill(m_palette->white_pen(), cliprect);
+
+ draw_bullets(bitmap, cliprect);
+ draw_sprites(bitmap, cliprect);
+ m_fg_tilemap->draw(screen, bitmap, cliprect);
+
+ return 0;
+}
+
+
+
+/***************************************************************************
+ Sound
+***************************************************************************/
+
+static const char *const zerohour_sample_names[] =
+{
+ "*zerohour",
+ "zh0",
+ "zh1",
+ "zh2",
+ "zh3",
+ "zh4",
+ "zh5",
+ "zh6",
+ "zh7",
+ "zh8",
+ "zh9",
+ "zh10",
+ nullptr
+};
+
+WRITE_LINE_MEMBER(zerohour_state::sound_enable_w)
+{
+ if (!state && m_samples)
+ m_samples->stop_all();
+ m_sound_on = state;
+}
+
+WRITE_LINE_MEMBER(redclash_state::sound_enable_w)
+{
+ zerohour_state::sound_enable_w(state);
+ if (!state)
+ beeper_w(0);
+}
+
+template <unsigned N> WRITE_LINE_MEMBER(zerohour_state::sample_w)
+{
+ if (m_sound_on && state)
+ m_samples->start(N, N);
+ else if (N == 8)
+ m_samples->stop(N);
+}
+
+void redclash_state::beeper_w(u8 data)
+{
+ // beeper frequency (0xff is off), preliminary
+ bool on = m_sound_on && (data != 0xff);
+ m_beep_clock->set_period(attotime::from_hz(on ? data * 8 : 0));
+}
+
+
+
+/***************************************************************************
+ Address Maps
+***************************************************************************/
+
+void zerohour_state::zerohour_map(address_map &map)
{
map(0x0000, 0x2fff).rom();
map(0x3000, 0x37ff).ram();
map(0x3800, 0x3bff).ram().share(m_spriteram);
- map(0x4000, 0x43ff).ram().w(FUNC(redclash_state::videoram_w)).share(m_videoram);
- map(0x4800, 0x4800).portr("IN0"); /* IN0 */
- map(0x4801, 0x4801).portr("IN1"); /* IN1 */
- map(0x4802, 0x4802).portr("DSW1"); /* DSW0 */
- map(0x4803, 0x4803).portr("DSW2"); /* DSW1 */
- map(0x5000, 0x5007).w("outlatch1", FUNC(ls259_device::write_d0)); /* to sound board */
- map(0x5800, 0x5807).w("outlatch2", FUNC(ls259_device::write_d0)); /* to sound board */
- map(0x7000, 0x7000).w(FUNC(redclash_state::star_reset_w));
- map(0x7800, 0x7800).w(FUNC(redclash_state::irqack_w));
+ map(0x4000, 0x43ff).ram().w(FUNC(zerohour_state::videoram_w)).share(m_videoram);
+ map(0x4800, 0x4800).portr("IN0");
+ map(0x4801, 0x4801).portr("IN1");
+ map(0x4802, 0x4802).portr("DSW1");
+ map(0x4803, 0x4803).portr("DSW2");
+ map(0x5000, 0x5007).w(m_outlatch[0], FUNC(ls259_device::write_d0)); // to sound board
+ map(0x5800, 0x5807).w(m_outlatch[1], FUNC(ls259_device::write_d0)); // to sound board
+ map(0x7000, 0x7000).w(FUNC(zerohour_state::star_reset_w));
+ map(0x7800, 0x7800).w(FUNC(zerohour_state::irqack_w));
}
void redclash_state::redclash_map(address_map &map)
{
map(0x0000, 0x2fff).rom();
-// map(0x3000, 0x3000).set_nopw();
-// map(0x3800, 0x3800).set_nopw();
+ map(0x3000, 0x3000).w(FUNC(redclash_state::background_w));
+ map(0x3800, 0x3800).w(FUNC(redclash_state::beeper_w));
map(0x4000, 0x43ff).ram().w(FUNC(redclash_state::videoram_w)).share(m_videoram);
- map(0x4800, 0x4800).portr("IN0"); /* IN0 */
- map(0x4801, 0x4801).portr("IN1"); /* IN1 */
- map(0x4802, 0x4802).portr("DSW1"); /* DSW0 */
- map(0x4803, 0x4803).portr("DSW2"); /* DSW1 */
- map(0x5000, 0x5007).w("outlatch1", FUNC(ls259_device::write_d0)); /* to sound board */
- map(0x5800, 0x5807).w("outlatch2", FUNC(ls259_device::write_d0)); /* to sound board */
+ map(0x4800, 0x4800).portr("IN0");
+ map(0x4801, 0x4801).portr("IN1");
+ map(0x4802, 0x4802).portr("DSW1");
+ map(0x4803, 0x4803).portr("DSW2");
+ map(0x5000, 0x5007).w(m_outlatch[0], FUNC(ls259_device::write_d0)); // to sound board
+ map(0x5800, 0x5807).w(m_outlatch[1], FUNC(ls259_device::write_d0)); // to sound board
map(0x6000, 0x67ff).ram();
map(0x6800, 0x6bff).ram().share(m_spriteram);
map(0x7000, 0x7000).w(FUNC(redclash_state::star_reset_w));
map(0x7800, 0x7800).w(FUNC(redclash_state::irqack_w));
}
-/*
- This game doesn't have VBlank interrupts.
- Interrupts are still used, but they are related to coin
- slots. Left slot generates an IRQ, Right slot a NMI.
-*/
-INPUT_CHANGED_MEMBER( redclash_state::left_coin_inserted )
+
+
+/***************************************************************************
+ Input Ports
+***************************************************************************/
+
+INPUT_CHANGED_MEMBER( zerohour_state::left_coin_inserted )
{
- if(newval)
+ if (newval)
m_maincpu->set_input_line(0, ASSERT_LINE);
}
-INPUT_CHANGED_MEMBER( redclash_state::right_coin_inserted )
+INPUT_CHANGED_MEMBER( zerohour_state::right_coin_inserted )
{
- if(newval)
+ if (newval)
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
-static INPUT_PORTS_START( redclash )
+
+static INPUT_PORTS_START( zerohour )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
@@ -115,13 +569,66 @@ static INPUT_PORTS_START( redclash )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- /* Note that there are TWO VBlank inputs, one is active low, the other active */
- /* high. There are probably other differences in the hardware, but emulating */
- /* them this way is enough to get the game running. */
+ // Note that there are TWO VBlank inputs, one is active low, the other active
+ // high. There are probably other differences in the hardware, but emulating
+ // them this way is enough to get the game running.
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW1")
+ PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "SW1:8" ) // Switches 6-8 are not used
+ PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "SW1:7" )
+ PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW1:6" )
+ PORT_DIPNAME( 0x08, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:5")
+ PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Cocktail ) )
+ PORT_DIPNAME( 0x30, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4,3") // Also determines the default topscore, 0 for "No Bonus"
+ PORT_DIPSETTING( 0x00, "No Bonus" )
+ PORT_DIPSETTING( 0x30, "5000" )
+ PORT_DIPSETTING( 0x20, "8000" )
+ PORT_DIPSETTING( 0x10, "10000" )
+ PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:2,1")
+ PORT_DIPSETTING( 0x00, "2" )
+ PORT_DIPSETTING( 0xc0, "3" )
+ PORT_DIPSETTING( 0x80, "4" )
+ PORT_DIPSETTING( 0x40, "5" )
+
+ PORT_START("DSW2")
+ PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW2:4,3,2,1")
+ PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
+ PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) ) // all other combinations give 1C_1C
+ PORT_DIPSETTING( 0x09, DEF_STR( 2C_3C ) )
+ PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
+ PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW2:8,7,6,5")
+ PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
+ PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) ) // all other combinations give 1C_1C
+ PORT_DIPSETTING( 0x90, DEF_STR( 2C_3C ) )
+ PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
+
+ PORT_START("FAKE")
+ // The coin slots are not memory mapped. Coin Left causes a NMI,
+ // Coin Right an IRQ. This fake input port is used by the interrupt
+ // handler to be notified of coin insertions.
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, zerohour_state, left_coin_inserted, 0)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, zerohour_state, right_coin_inserted, 0)
+INPUT_PORTS_END
+
+static INPUT_PORTS_START( redclash )
+ PORT_INCLUDE( zerohour )
+
+ PORT_MODIFY("DSW1")
PORT_DIPNAME( 0x03, 0x03, "Difficulty?" )
PORT_DIPSETTING( 0x03, "Easy?" )
PORT_DIPSETTING( 0x02, "Medium?" )
@@ -145,7 +652,7 @@ static INPUT_PORTS_START( redclash )
PORT_DIPSETTING( 0x80, "5" )
PORT_DIPSETTING( 0x40, "7" )
- PORT_START("DSW2")
+ PORT_MODIFY("DSW2")
PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) )
PORT_DIPSETTING( 0x04, DEF_STR( 6C_1C ) )
PORT_DIPSETTING( 0x05, DEF_STR( 5C_1C ) )
@@ -180,62 +687,13 @@ static INPUT_PORTS_START( redclash )
PORT_DIPSETTING( 0x20, DEF_STR( 1C_7C ) )
PORT_DIPSETTING( 0x10, DEF_STR( 1C_8C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_9C ) )
-
- PORT_START("FAKE")
- /* The coin slots are not memory mapped. Coin Left causes a NMI, */
- /* Coin Right an IRQ. This fake input port is used by the interrupt */
- /* handler to be notified of coin insertions. We use IMPULSE to */
- /* trigger exactly one interrupt, without having to check when the */
- /* user releases the key. */
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_IMPULSE(1) PORT_CHANGED_MEMBER(DEVICE_SELF, redclash_state, left_coin_inserted, 0)
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_IMPULSE(1) PORT_CHANGED_MEMBER(DEVICE_SELF, redclash_state, right_coin_inserted, 0)
INPUT_PORTS_END
-static INPUT_PORTS_START( zerohour )
- PORT_INCLUDE( redclash )
- PORT_MODIFY("DSW1")
- PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "SW1:8" ) /* Switches 6-8 are not used */
- PORT_DIPUNUSED_DIPLOC( 0x02, 0x02, "SW1:7" )
- PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW1:6" )
- PORT_DIPNAME( 0x08, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:5")
- PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Cocktail ) )
- PORT_DIPNAME( 0x30, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW1:4,3") /* Also determines the default topscore, 0 for "No Bonus" */
- PORT_DIPSETTING( 0x00, "No Bonus" )
- PORT_DIPSETTING( 0x30, "5000" )
- PORT_DIPSETTING( 0x20, "8000" )
- PORT_DIPSETTING( 0x10, "10000" )
- PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW1:2,1")
- PORT_DIPSETTING( 0x00, "2" )
- PORT_DIPSETTING( 0xc0, "3" )
- PORT_DIPSETTING( 0x80, "4" )
- PORT_DIPSETTING( 0x40, "5" )
- PORT_MODIFY("DSW2")
- PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW2:4,3,2,1")
- PORT_DIPSETTING( 0x06, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0x0a, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x07, DEF_STR( 3C_2C ) )
- PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) ) /* all other combinations give 1C_1C */
- PORT_DIPSETTING( 0x09, DEF_STR( 2C_3C ) )
- PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) )
- PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) )
- PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) )
- PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) )
- PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW2:8,7,6,5")
- PORT_DIPSETTING( 0x60, DEF_STR( 4C_1C ) )
- PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) )
- PORT_DIPSETTING( 0xa0, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x70, DEF_STR( 3C_2C ) )
- PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) ) /* all other combinations give 1C_1C */
- PORT_DIPSETTING( 0x90, DEF_STR( 2C_3C ) )
- PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) )
- PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) )
- PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) )
- PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) )
-INPUT_PORTS_END
+/***************************************************************************
+ GFX Layouts
+***************************************************************************/
static const gfx_layout charlayout =
{
@@ -292,7 +750,7 @@ static const gfx_layout spritelayout16x16bis =
32*32
};
-static GFXDECODE_START( gfx_redclash )
+static GFXDECODE_START( gfx_zerohour )
GFXDECODE_ENTRY( "gfx1", 0x0000, charlayout, 0, 8 )
GFXDECODE_ENTRY( "gfx3", 0x0000, spritelayout8x8, 4*8, 16 )
GFXDECODE_ENTRY( "gfx2", 0x0000, spritelayout16x16, 4*8, 16 )
@@ -302,58 +760,89 @@ static GFXDECODE_START( gfx_redclash )
GFXDECODE_END
-void redclash_state::machine_start()
-{
- save_item(NAME(m_gfxbank));
- m_gfxbank = 0;
-}
+/***************************************************************************
+ Machine Configs
+***************************************************************************/
-void redclash_state::zerohour(machine_config &config)
+void zerohour_state::base(machine_config &config)
{
- /* basic machine hardware */
- Z80(config, m_maincpu, 4_MHz_XTAL); /* 4 MHz */
- m_maincpu->set_addrmap(AS_PROGRAM, &redclash_state::zerohour_map);
+ // basic machine hardware
+ Z80(config, m_maincpu, 4_MHz_XTAL);
+ m_maincpu->set_addrmap(AS_PROGRAM, &zerohour_state::zerohour_map);
- LS259(config, "outlatch1"); // C1 (CS10 decode)
+ LS259(config, m_outlatch[0]); // C1 (CS10 decode)
- ls259_device &outlatch2(LS259(config, "outlatch2")); // C2 (CS11 decode)
- outlatch2.q_out_cb<0>().set(FUNC(redclash_state::star_w<0>));
- outlatch2.q_out_cb<5>().set(FUNC(redclash_state::star_w<1>));
- outlatch2.q_out_cb<6>().set(FUNC(redclash_state::star_w<2>));
- outlatch2.q_out_cb<7>().set(FUNC(redclash_state::flipscreen_w));
+ LS259(config, m_outlatch[1]); // C2 (CS11 decode)
+ m_outlatch[1]->q_out_cb<0>().set(FUNC(zerohour_state::star_w<0>));
+ m_outlatch[1]->q_out_cb<5>().set(FUNC(zerohour_state::star_w<1>));
+ m_outlatch[1]->q_out_cb<6>().set(FUNC(zerohour_state::star_w<2>));
+ m_outlatch[1]->q_out_cb<7>().set(FUNC(zerohour_state::flipscreen_w));
- /* video hardware */
+ // video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(9.828_MHz_XTAL / 2, 312, 8, 248, 262, 32, 224);
- screen.set_screen_update(FUNC(redclash_state::screen_update));
- screen.screen_vblank().set(FUNC(redclash_state::screen_vblank));
+ screen.set_screen_update(FUNC(zerohour_state::screen_update));
+ screen.screen_vblank().set(FUNC(zerohour_state::update_stars));
screen.set_palette(m_palette);
- GFXDECODE(config, m_gfxdecode, m_palette, gfx_redclash);
- PALETTE(config, m_palette, FUNC(redclash_state::palette), 4*8 + 4*16 + 32, 32 + 32);
+ GFXDECODE(config, m_gfxdecode, m_palette, gfx_zerohour);
+ PALETTE(config, m_palette, FUNC(zerohour_state::palette), 4*8 + 4*16 + 32, 32 + 32);
- ZEROHOUR_STARS(config, m_stars, 0);
-
- /* sound hardware */
+ ZEROHOUR_STARS(config, m_stars);
}
+void zerohour_state::zerohour(machine_config &config)
+{
+ base(config);
+
+ // sound hardware
+ m_outlatch[0]->q_out_cb<0>().set(FUNC(zerohour_state::sample_w<0>));
+ m_outlatch[0]->q_out_cb<1>().set(FUNC(zerohour_state::sample_w<1>));
+ m_outlatch[0]->q_out_cb<2>().set(FUNC(zerohour_state::sample_w<2>));
+ m_outlatch[0]->q_out_cb<3>().set(FUNC(zerohour_state::sample_w<3>));
+ m_outlatch[0]->q_out_cb<4>().set(FUNC(zerohour_state::sample_w<4>));
+ m_outlatch[0]->q_out_cb<5>().set(FUNC(zerohour_state::sample_w<5>));
+ m_outlatch[0]->q_out_cb<6>().set(FUNC(zerohour_state::sample_w<6>));
+ m_outlatch[0]->q_out_cb<7>().set(FUNC(zerohour_state::sample_w<7>));
+
+ m_outlatch[1]->q_out_cb<1>().set(FUNC(zerohour_state::sample_w<8>));
+ m_outlatch[1]->q_out_cb<2>().set(FUNC(zerohour_state::sound_enable_w));
+ m_outlatch[1]->q_out_cb<3>().set(FUNC(zerohour_state::sample_w<9>));
+ m_outlatch[1]->q_out_cb<4>().set(FUNC(zerohour_state::sample_w<10>));
+
+ SPEAKER(config, "mono").front_center();
+
+ SAMPLES(config, m_samples);
+ m_samples->set_channels(11);
+ m_samples->set_samples_names(zerohour_sample_names);
+ m_samples->add_route(ALL_OUTPUTS, "mono", 0.5);
+}
void redclash_state::redclash(machine_config &config)
{
- zerohour(config);
+ base(config);
m_maincpu->set_addrmap(AS_PROGRAM, &redclash_state::redclash_map);
+ m_outlatch[1]->q_out_cb<1>().set(FUNC(redclash_state::gfxbank_w));
- subdevice<addressable_latch_device>("outlatch2")->q_out_cb<1>().set(FUNC(redclash_state::gfxbank_w));
-}
+ m_stars->has_va_bit(false);
+ // sound hardware
+ m_outlatch[1]->q_out_cb<2>().set(FUNC(redclash_state::sound_enable_w));
+ SPEAKER(config, "mono").front_center();
+ SPEAKER_SOUND(config, m_beep).add_route(ALL_OUTPUTS, "mono", 0.25);
-/***************************************************************************
+ CLOCK(config, m_beep_clock, 0);
+ m_beep_clock->signal_handler().set(m_beep, FUNC(speaker_sound_device::level_w));
+ m_beep_clock->set_duty_cycle(0.25);
+}
- Game driver(s)
+
+/***************************************************************************
+ ROM Definitions
***************************************************************************/
ROM_START( zerohour )
@@ -538,26 +1027,20 @@ ROM_START( redclashs )
ROM_LOAD( "3.11e", 0x0040, 0x0020, CRC(27fa3a50) SHA1(7cf59b7a37c156640d6ea91554d1c4276c1780e0) ) /* ?? */
ROM_END
-void redclash_state::init_redclash()
-{
- uint8_t const *const src = memregion("gfx2")->base();
- uint8_t *const dst = memregion("gfx3")->base();
- int const len = memregion("gfx3")->bytes();
+} // anonymous namespace
+
- /* rearrange the sprite graphics */
- for (int i = 0; i < len; i++)
- {
- int const j = (i & ~0x003e) | ((i & 0x0e) << 2) | ((i & 0x30) >> 3);
- dst[i] = src[j];
- }
-}
+/***************************************************************************
+ Drivers
+***************************************************************************/
-GAME( 1980, zerohour, 0, zerohour, zerohour, redclash_state, init_redclash, ROT270, "Universal", "Zero Hour (set 1)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
-GAME( 1980, zerohoura, zerohour, zerohour, zerohour, redclash_state, init_redclash, ROT270, "Universal", "Zero Hour (set 2)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
-GAME( 1980, zerohouri, zerohour, zerohour, zerohour, redclash_state, init_redclash, ROT270, "bootleg (Inder SA)", "Zero Hour (Inder)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
+// YEAR NAME PARENT MACHINE INPUT STATE INIT SCREEN COMPANY FULLNAME FLAGS
+GAME( 1980, zerohour, 0, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
+GAME( 1980, zerohoura, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "Universal", "Zero Hour (set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
+GAME( 1980, zerohouri, zerohour, zerohour, zerohour, zerohour_state, init_zerohour, ROT270, "bootleg (Inder SA)", "Zero Hour (bootleg)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
-GAME( 1981, redclash, 0, redclash, redclash, redclash_state, init_redclash, ROT270, "Kaneko", "Red Clash", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
-GAME( 1981, redclasht, redclash, redclash, redclash, redclash_state, init_redclash, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 1)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
-GAME( 1981, redclashta, redclash, redclash, redclash, redclash_state, init_redclash, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 2)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
-GAME( 1982, redclashs, redclash, redclash, redclash, redclash_state, init_redclash, ROT270, "Kaneko (Suntronics license)", "Red Clash (Suntronics)", MACHINE_NO_SOUND | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
+GAME( 1981, redclash, 0, redclash, redclash, redclash_state, init_zerohour, ROT270, "Kaneko", "Red Clash", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
+GAME( 1981, redclasht, redclash, redclash, redclash, redclash_state, init_zerohour, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
+GAME( 1981, redclashta, redclash, redclash, redclash, redclash_state, init_zerohour, ROT270, "Kaneko (Tehkan license)", "Red Clash (Tehkan, set 2)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
+GAME( 1982, redclashs, redclash, redclash, redclash, redclash_state, init_zerohour, ROT270, "Kaneko (Suntronics license)", "Red Clash (Suntronics)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/universal/zerohour_stars.cpp b/src/mame/universal/zerohour_stars.cpp
new file mode 100644
index 00000000000..ec541de5104
--- /dev/null
+++ b/src/mame/universal/zerohour_stars.cpp
@@ -0,0 +1,127 @@
+// license:BSD-3-Clause
+// copyright-holders:Frank Palazzolo
+/***************************************************************************
+
+ zerohour/redclash/sraider stars
+
+ These functions emulate the star generator board
+ All this comes from the schematics for Zero Hour
+
+ It has a 17-bit LFSR which has a period of 2^17-1 clocks
+ (This is one pixel shy of "two screens" worth.)
+ So, there are two starfields drawn on alternate frames
+ These will scroll at a rate controlled by the speed register
+
+ I'm basically doing the same thing by drawing each
+ starfield on alternate frames, and then offsetting them
+
+***************************************************************************/
+
+#include "emu.h"
+#include "zerohour_stars.h"
+
+
+DEFINE_DEVICE_TYPE(ZEROHOUR_STARS, zerohour_stars_device, "zerohour_stars", "Zero Hour/Red Clash/Space Raider starfield")
+
+
+zerohour_stars_device::zerohour_stars_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, ZEROHOUR_STARS, tag, owner, clock)
+ , m_enable(0)
+ , m_speed(0)
+ , m_state(0)
+ , m_offset(0)
+ , m_count(0)
+{
+ // set default configuration
+ m_pal_offset = 0x60;
+ m_has_va_bit = true;
+}
+
+void zerohour_stars_device::device_start()
+{
+ save_item(NAME(m_enable));
+ save_item(NAME(m_speed));
+ save_item(NAME(m_state));
+ save_item(NAME(m_offset));
+ save_item(NAME(m_count));
+}
+
+void zerohour_stars_device::device_reset()
+{
+ m_enable = 0;
+ m_speed = 0;
+ m_state = 0;
+ m_offset = 0;
+ m_count = 0;
+}
+
+// This line can reset the LFSR to zero and disables the star generator
+void zerohour_stars_device::set_enable(bool on)
+{
+ if (!m_enable && on)
+ m_offset = 0;
+
+ m_enable = on ? 1 : 0;
+}
+
+// This sets up which starfield to draw and the offset, to be called from screen_vblank_*()
+void zerohour_stars_device::update_state()
+{
+ if (m_enable)
+ {
+ m_count = m_count ? 0 : 1;
+ if (!m_count)
+ {
+ m_offset += ((m_speed * 2) - 0x09);
+ m_offset %= 256 * 256;
+ m_state = 0;
+ }
+ else
+ {
+ m_state = 0x1fc71;
+ }
+ }
+}
+
+// Set the speed register (3 bits)
+void zerohour_stars_device::set_speed(u8 speed, u8 mask)
+{
+ // 0 left/down fastest (-9/2 pix per frame)
+ // 1 left/down faster (-7/2 pix per frame)
+ // 2 left/down fast (-5/2 pix per frame)
+ // 3 left/down medium (-3/2 pix per frame)
+ // 4 left/down slow (-1/2 pix per frame)
+ // 5 right/up slow (+1/2 pix per frame)
+ // 6 right/up medium (+3/2 pix per frame)
+ // 7 right/up fast (+5/2 pix per frame)
+ m_speed = (m_speed & ~mask) | (speed & mask);
+}
+
+// Draw the stars
+void zerohour_stars_device::draw(bitmap_ind16 &bitmap, rectangle const &cliprect)
+{
+ if (m_enable)
+ {
+ u32 state(m_state);
+ for (int i = 0; (256 * 256) > i; ++i)
+ {
+ u8 const xloc((m_offset + i) & 0x00ff);
+ u8 const yloc(((m_offset + i) >> 8) & 0x00ff);
+
+ bool const tempbit(!(state & 0x10000));
+ bool const feedback((state & 0x00020) ? !tempbit : tempbit);
+
+ bool const hcond(BIT(xloc + 8, 4));
+ bool const vcond(m_has_va_bit || BIT(yloc, 0));
+
+ if (cliprect.contains(xloc, yloc) && (hcond == vcond))
+ {
+ if (((state & 0x000ff) == 0x000ff) && !feedback)
+ bitmap.pix(yloc, xloc) = m_pal_offset + (state >> 9 & 0x1f);
+ }
+
+ // update LFSR state
+ state = ((state << 1) & 0x1fffe) | (feedback ? 1 : 0);
+ }
+ }
+}
diff --git a/src/mame/universal/zerohour_stars.h b/src/mame/universal/zerohour_stars.h
new file mode 100644
index 00000000000..c5d00454bc5
--- /dev/null
+++ b/src/mame/universal/zerohour_stars.h
@@ -0,0 +1,42 @@
+// license:BSD-3-Clause
+// copyright-holders:Frank Palazzolo
+#ifndef MAME_VIDEO_ZEROHOUR_STARS_H
+#define MAME_VIDEO_ZEROHOUR_STARS_H
+
+#pragma once
+
+
+// used by zerohour, redclash and sraider
+class zerohour_stars_device : public device_t
+{
+public:
+ zerohour_stars_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
+
+ // configuration helpers
+ zerohour_stars_device &has_va_bit(bool va) { m_has_va_bit = va; return *this; } // default yes (sraider does not)
+
+ // public interface
+ void set_enable(bool on);
+ void update_state();
+ void set_speed(u8 speed, u8 mask);
+ void draw(bitmap_ind16 &bitmap, rectangle const &cliprect);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ u8 m_enable;
+ u8 m_speed;
+ u32 m_state;
+ u16 m_offset;
+ u8 m_count;
+
+ u16 m_pal_offset;
+ bool m_has_va_bit;
+};
+
+
+DECLARE_DEVICE_TYPE(ZEROHOUR_STARS, zerohour_stars_device)
+
+#endif // MAME_VIDEO_ZEROHOUR_STARS_H
diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp
index 485322ecc27..2b060670cb7 100644
--- a/src/osd/modules/debugger/debuggdbstub.cpp
+++ b/src/osd/modules/debugger/debuggdbstub.cpp
@@ -1211,15 +1211,15 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
return REPLY_OK;
case 2:
// write watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind);
return REPLY_OK;
case 3:
// read watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind);
return REPLY_OK;
case 4:
// access watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind);
return REPLY_OK;
}
diff --git a/src/osd/modules/debugger/osx/disassemblyviewer.mm b/src/osd/modules/debugger/osx/disassemblyviewer.mm
index 1f286a6bfc4..64d665a31cb 100644
--- a/src/osd/modules/debugger/osx/disassemblyviewer.mm
+++ b/src/osd/modules/debugger/osx/disassemblyviewer.mm
@@ -182,7 +182,7 @@
// if it doesn't exist, add a new one
if (bp == nullptr)
{
- uint32_t const bpnum = device.debug()->breakpoint_set(address, nullptr, nullptr);
+ uint32_t const bpnum = device.debug()->breakpoint_set(address);
machine->debugger().console().printf("Breakpoint %X set\n", bpnum);
}
else
diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp
index 44ce8bac988..21e2520d712 100644
--- a/src/osd/modules/debugger/qt/dasmwindow.cpp
+++ b/src/osd/modules/debugger/qt/dasmwindow.cpp
@@ -149,7 +149,7 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
// If none exists, add a new one
if (!bp)
{
- int32_t bpindex = cpuinfo->breakpoint_set(address, nullptr, nullptr);
+ int32_t bpindex = cpuinfo->breakpoint_set(address);
m_machine.debugger().console().printf("Breakpoint %X set\n", bpindex);
}
else
diff --git a/src/osd/modules/debugger/win/disasmbasewininfo.cpp b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
index f68a7652c77..4f8a58ad0d1 100644
--- a/src/osd/modules/debugger/win/disasmbasewininfo.cpp
+++ b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
@@ -174,7 +174,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
if (bp == nullptr)
{
- int32_t bpindex = debug->breakpoint_set(address, nullptr, nullptr);
+ int32_t bpindex = debug->breakpoint_set(address);
machine().debugger().console().printf("Breakpoint %X set\n", bpindex);
}
else
diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp
index 9adf9f2e604..1019bc4f766 100644
--- a/src/osd/modules/lib/osdobj_common.cpp
+++ b/src/osd/modules/lib/osdobj_common.cpp
@@ -17,6 +17,7 @@
#include "modules/netdev/netdev_module.h"
#include "modules/midi/midi_module.h"
#include "modules/monitor/monitor_module.h"
+#include "osdnet.h"
#include "watchdog.h"
#include "emu.h"
diff --git a/src/osd/modules/midi/portmidi.cpp b/src/osd/modules/midi/portmidi.cpp
index 9cb5ddac39b..73d965d854a 100644
--- a/src/osd/modules/midi/portmidi.cpp
+++ b/src/osd/modules/midi/portmidi.cpp
@@ -2,7 +2,7 @@
// copyright-holders:R. Belmont
/***************************************************************************
- portmap.c
+ portmidi.cpp
Midi implementation based on portmidi library
@@ -11,9 +11,10 @@
#ifndef NO_USE_MIDI
#include <portmidi.h>
-#include "osdcore.h"
#include "modules/osdmodule.h"
#include "midi_module.h"
+#include <cstdio>
+#include <cstring>
class pm_module : public osd_module, public midi_module
{
diff --git a/src/osd/modules/netdev/pcap.cpp b/src/osd/modules/netdev/pcap.cpp
index 2ae32df0f3b..3ff82484b28 100644
--- a/src/osd/modules/netdev/pcap.cpp
+++ b/src/osd/modules/netdev/pcap.cpp
@@ -4,6 +4,7 @@
#if defined(OSD_NET_USE_PCAP)
#include "emu.h"
+#include "dinetwork.h"
#include "osdnet.h"
#include "netdev_module.h"
#include "modules/osdmodule.h"
diff --git a/src/osd/modules/netdev/taptun.cpp b/src/osd/modules/netdev/taptun.cpp
index c0d99ec750c..10ca76fb2d0 100644
--- a/src/osd/modules/netdev/taptun.cpp
+++ b/src/osd/modules/netdev/taptun.cpp
@@ -14,6 +14,7 @@
#endif
#include "emu.h"
+#include "dinetwork.h"
#include "osdnet.h"
#include "modules/osdmodule.h"
#include "netdev_module.h"
diff --git a/src/osd/modules/render/bgfx/statereader.cpp b/src/osd/modules/render/bgfx/statereader.cpp
index acaeddd35b5..bd7923f1c5e 100644
--- a/src/osd/modules/render/bgfx/statereader.cpp
+++ b/src/osd/modules/render/bgfx/statereader.cpp
@@ -11,6 +11,7 @@
#include "osdcore.h"
+#include <cstdarg>
#include <cmath>
bool state_reader::READER_CHECK(bool condition, const char* format, ...)
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index ff97f10c7d5..d9f61c22a5a 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -16,7 +16,6 @@
#include "strformat.h"
-#include <cstdarg>
#include <cstdint>
#include <iosfwd>
#include <string>
@@ -360,28 +359,6 @@ std::string osd_get_clipboard_text();
/***************************************************************************
- MIDI I/O INTERFACES
-***************************************************************************/
-
-class osd_midi_device
-{
-public:
- virtual ~osd_midi_device() { }
- // free result with osd_close_midi_channel()
- virtual bool open_input(const char *devname) = 0;
- // free result with osd_close_midi_channel()
- virtual bool open_output(const char *devname) = 0;
- virtual void close() = 0;
- virtual bool poll() = 0;
- virtual int read(uint8_t *pOut) = 0;
- virtual void write(uint8_t data) = 0;
-};
-
-//FIXME: really needed here?
-void osd_list_network_adapters();
-
-
-/***************************************************************************
UNCATEGORIZED INTERFACES
***************************************************************************/
diff --git a/src/osd/osdepend.h b/src/osd/osdepend.h
index 89665eb1a80..78f485d1759 100644
--- a/src/osd/osdepend.h
+++ b/src/osd/osdepend.h
@@ -24,7 +24,7 @@
// forward references
-class input_type_entry; // FIXME: including emu.h does not work because emu.h includes osdepend.h
+class input_type_entry;
class osd_midi_device;
namespace ui { class menu_item; }
@@ -99,4 +99,21 @@ protected:
virtual ~osd_interface() { }
};
+
+/***************************************************************************
+ MIDI I/O INTERFACES
+***************************************************************************/
+
+class osd_midi_device
+{
+public:
+ virtual ~osd_midi_device() { }
+ virtual bool open_input(const char *devname) = 0;
+ virtual bool open_output(const char *devname) = 0;
+ virtual void close() = 0;
+ virtual bool poll() = 0;
+ virtual int read(uint8_t *pOut) = 0;
+ virtual void write(uint8_t data) = 0;
+};
+
#endif // MAME_OSD_OSDEPEND_H
diff --git a/src/osd/osdnet.cpp b/src/osd/osdnet.cpp
index 39f0da3b343..0281bed9c1c 100644
--- a/src/osd/osdnet.cpp
+++ b/src/osd/osdnet.cpp
@@ -1,8 +1,11 @@
// license:BSD-3-Clause
// copyright-holders:Carl
+
#include "emu.h"
#include "osdnet.h"
+#include "dinetwork.h"
+
static class std::vector<std::unique_ptr<osd_netdev::entry_t>> netdev_list;
void add_netdev(const char *name, const char *description, create_netdev func)
diff --git a/src/osd/osdnet.h b/src/osd/osdnet.h
index f18d7c5fea7..0c78f0a1fad 100644
--- a/src/osd/osdnet.h
+++ b/src/osd/osdnet.h
@@ -55,5 +55,6 @@ void add_netdev(const char *name, const char *description, create_netdev func);
void clear_netdev();
const std::vector<std::unique_ptr<osd_netdev::entry_t>>& get_netdev_list();
int netdev_count();
+void osd_list_network_adapters();
#endif // MAME_OSD_OSDNET_H
diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp
index ff14b2509cc..7bb230d1e38 100644
--- a/src/tools/imgtool/imgtool.cpp
+++ b/src/tools/imgtool/imgtool.cpp
@@ -20,6 +20,7 @@
#include "corestr.h"
#include "opresolv.h"
+#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <cctype>
diff --git a/src/tools/imgtool/stream.cpp b/src/tools/imgtool/stream.cpp
index 014d5735514..5bd654af3d7 100644
--- a/src/tools/imgtool/stream.cpp
+++ b/src/tools/imgtool/stream.cpp
@@ -17,6 +17,7 @@
#include "unzip.h"
#include <cassert>
+#include <cstdarg>
#include <cstdio>
#include <cstring>