From 1e4ac0fcf27e6e4770c819a1fef9546543e5894d Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Mon, 29 Apr 2019 17:05:37 +1000 Subject: Added Star Rider skeleton based on schematics. Thanks to TrevEB for pointing me in the right direction. Added IBGR444 format to palette_device. Minor consistency fix to laserbat.cpp. (nw). New machines marked NOT_WORKING ------------------------------- Star Rider --- scripts/target/mame/arcade.lua | 1 + src/emu/emupal.cpp | 6 + src/emu/emupal.h | 2 + src/mame/drivers/laserbat.cpp | 4 +- src/mame/drivers/starrider.cpp | 866 +++++++++++++++++++++++++++++++++++++++++ src/mame/mame.lst | 3 + 6 files changed, 880 insertions(+), 2 deletions(-) create mode 100644 src/mame/drivers/starrider.cpp diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 4dde461c1ed..306ae73c33a 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -2715,6 +2715,7 @@ files { MAME_DIR .. "src/mame/drivers/sspeedr.cpp", MAME_DIR .. "src/mame/includes/sspeedr.h", MAME_DIR .. "src/mame/video/sspeedr.cpp", + MAME_DIR .. "src/mame/drivers/starrider.cpp", MAME_DIR .. "src/mame/drivers/tmaster.cpp", MAME_DIR .. "src/mame/drivers/vegas.cpp", MAME_DIR .. "src/mame/drivers/wmg.cpp", diff --git a/src/emu/emupal.cpp b/src/emu/emupal.cpp index 96fe75638e1..f401a4b8cb4 100644 --- a/src/emu/emupal.cpp +++ b/src/emu/emupal.cpp @@ -217,6 +217,12 @@ palette_device &palette_device::set_format(rgbi_4444_t, u32 entries) return *this; } +palette_device &palette_device::set_format(ibgr_4444_t, u32 entries) +{ + set_format(2, &raw_to_rgb_converter::standard_irgb_decoder<4,4,4,4, 12,0,4,8>, entries); + return *this; +} + palette_device &palette_device::set_format(xrgb_555_t, u32 entries) { set_format(2, &raw_to_rgb_converter::standard_rgb_decoder<5,5,5, 10,5,0>, entries); diff --git a/src/emu/emupal.h b/src/emu/emupal.h index 00b3d0863f2..acc528110f1 100644 --- a/src/emu/emupal.h +++ b/src/emu/emupal.h @@ -218,6 +218,7 @@ public: enum gbrx_444_t { GBRx_444, GGGGBBBBRRRRxxxx }; enum irgb_4444_t { IRGB_4444, IIIIRRRRGGGGBBBB }; enum rgbi_4444_t { RGBI_4444, RRRRGGGGBBBBIIII }; + enum ibgr_4444_t { IBGR_4444, IIIIBBBBGGGGRRRR }; enum xrgb_555_t { xRGB_555, xRRRRRGGGGGBBBBB }; enum xgrb_555_t { xGRB_555, xGGGGGRRRRRBBBBB }; enum xgbr_555_t { xGBR_555, xGGGGGBBBBBRRRRR }; @@ -312,6 +313,7 @@ public: palette_device &set_format(gbrx_444_t, u32 entries); palette_device &set_format(irgb_4444_t, u32 entries); palette_device &set_format(rgbi_4444_t, u32 entries); + palette_device &set_format(ibgr_4444_t, u32 entries); palette_device &set_format(xrgb_555_t, u32 entries); palette_device &set_format(xgrb_555_t, u32 entries); palette_device &set_format(xgbr_555_t, u32 entries); diff --git a/src/mame/drivers/laserbat.cpp b/src/mame/drivers/laserbat.cpp index 8ccaa320059..e0ae530cfe0 100644 --- a/src/mame/drivers/laserbat.cpp +++ b/src/mame/drivers/laserbat.cpp @@ -213,8 +213,8 @@ static INPUT_PORTS_START( laserbat_base ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_CONFNAME( 0x10, 0x10, DEF_STR(Cabinet) ) // sense line on wiring harness - PORT_DIPSETTING( 0x10, DEF_STR(Upright) ) - PORT_DIPSETTING( 0x00, DEF_STR(Cocktail) ) + PORT_CONFSETTING( 0x10, DEF_STR(Upright) ) + PORT_CONFSETTING( 0x00, DEF_STR(Cocktail) ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_TILT ) diff --git a/src/mame/drivers/starrider.cpp b/src/mame/drivers/starrider.cpp new file mode 100644 index 00000000000..bd5fe16ba6e --- /dev/null +++ b/src/mame/drivers/starrider.cpp @@ -0,0 +1,866 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/* + Williams Start Rider + + One of the more sophisticated LaserDisc games. The "video expander" + allows part of the LaserDisc backdrop to be enlarged and panned + horizontally. Overlay graphics are also supported. + + Major components: + ----------------- + * Modified Pioneer PR8210 LaserDisc player + * C-9928 Processor Interface board (PIF) + * C-9994 throttle opto board + * C-9995 steering opto board + * C-9996 brake opto board + * D-9837 NTSC to RGB board (NTSC) + * D-9922 CPU board (CPU) + * D-9924 Video Graphics Generator board (VGG) + * D-9926 Image ROM board (ROM) + * D-9930 Video Expander board (EXP) + * D-9941 Sound System board (Sound) + + C-9928 PIF: + ----------- + Handles communication with the LaserDisc player. Uses a 68029E CPU + with 4KiB of ROM and 8KiB of RAM. + + * CR1 4MHz crystal oscillator + * J1 4-pin SIL connector + * J2 15-pin SIL connector (host interface) + - pin 1 connected to ground + - pin 2 connected to MPU and PIA reset (active low) + - pins 3-10 connected to PIA PA0-7 + - pins 11-12 connected to PIA CA1-2 + - pin 13 input is used to generate IRQ interrupts + - pin 14 is composite sync, connected directly to J3 pin 7 + - pin 15 is even/odd field signal, inverted and connected to PIA PB6 + * J3 26-pin DIL connector + * U1 6821 PIA + - IRQA connects to FIRQ + - IRQB connects to NMI + - PA/CA are used for host communication + - PB/CB are used for LaserDisc player control + * U2 2k*8 RAM + * U3 2732 4k*8 PROM + * U4 6809E microprocessor + * U5 unpopulated (74LS245 - would be used for a different player type) + * U6 74LS74 dual D-type flip-flop + - used to generate IRQ interrupts + * U7 74LS04 hex inverter + * U8 74LS74 dual D-type flip-flop + - generates 1MHz 2-phase Q and E clocks for CPU and PIA + * U9 74LS138 1-of-8 decoder/demultiplexer + - decodes A15/A14/A13 + * U10 74LS10 triple 3-input NAND gate + * U11 74LS244 octal tri-state line driver/buffer + - used to buffer signals to/from LaserDisc player + + D-9837 NTSC: + ------------ + NTSC to analog RGB and composite sync, based around RCA CA3143E + luminance processor (U1) and RCA CA3151G chroma processor/demodulator + (U2). + + D-9922 CPU: + ---------- + Clocks are generated by the VGG board. The CPU address and data buses + are exposed to the VGG board. There are separate address/data buffers + for peripherals on the CPU board and VGG board. + + * J2 9-pin SIL connector + * J3 12-pin SIL connector + * J4 10-pin SIL connector + * J5 12-pin SIL connector + * J6 7-pin SIL connector + * J7 10-pin SIL connector (power) + - pin 1-4 connected to ground + - pin 5 is not present (key) + - pin 6-9 supply +5V + - pin 10 supplies +12V unregulated (used by reset circuit) + + W1 (27128) populated + W2 (2764) unpopulated + W3 (ROM) unpopulated - would map U7 at 0xd000-0xdff for 2732 2k*8 ROM + W4 (RAM) populated - maps U7 at 0xd800-dfff for 6116 2k*8 RAM + W5 populated - connects /WRX to U7 for 6116 2k*8 RAM + W6 unpopulated - would connect A11 to U7 for 2732 4k*8 ROM + W7 (UPRIGHT) populated + + /FXXX+EXXX (active low) 111xxxxx xxxxxxxx 0xe000-0xefff + + U23.11 (active low) 101xxxxx xxxxxxxx 0xa000-0xbfff + 110xxxxx xxxxxxxx 0xc000-0xdfff + + U24.15 /C0 11000xxx xxxxxxxx 0xc000-0xc7ff + U24.14 /C8 11001xxx xxxxxxxx 0xc800-0xcfff + U24.13 /D0 11010xxx xxxxxxxx 0xd000-0xd7ff + U24.12 /D8 11011xxx xxxxxxxx 0xd800-0xffff + U24.11 /A0 10100xxx xxxxxxxx 0xa000-0xa7ff + U24.10 /A8 10101xxx xxxxxxxx 0xa800-0xafff + U24.9 /B0 10110xxx xxxxxxxx 0xb000-0xb7ff + U24.7 /B8 10111xxx xxxxxxxx 0xb800-0xbfff + + U19.8 (active low) 110011xx xxxxxxxx 0xcc00-0xcfff + U19.11 (active low) 1100100x xxxxxxxx 0xc800-0xc9ff + + U19.4 11001000 0xxxxxxx 0xc800-0xc87f + U19.5 11001000 1xxxxxxx 0xc880-0xc8ff + U19.6 11001001 0xxxxxxx 0xc900-0xc97f + U19.7 11001001 1xxxxxxx 0xc980-0xc9ff + + D-9924 VGG: + ----------- + + * U96 2148 Palette blue (low nybble of odd bytes) + * U97 2148 Palette luminance (high nybble of odd bytes) + * U98 2148 Palette red (low nybble of even bytes) + * U99 2148 Palette green (high nybble of even bytes) + + U33.8 (active low) 11001011 xxxxxxxx 0xcb00-0xcbff + + U35.15 /CB80 11001011 1000xxxx 0xcb80-0xcb8f + U35.14 /CB90 11001011 1001xxxx 0xcb90-0xcb9f + U35.13 /CBA0 11001011 1010xxxx 0xcba0-0xcbaf + U35.12 /DMA 11001011 1011xxxx 0xcbb0-0xcbbf + U35.11 11001011 1100xxxx 0xcbc0-0xcbcf (W) + U35.10 /CBD0 11001011 1101xxxx 0xcbd0-0xcbdf (W) + U35.9 /CBE0 11001011 1110xxxx 0xcbe0-0xcbef (W) + + U36.1 (active high) 110010xx xxxxxxxx 0xc800-0xcbff + + D-9926 ROM: + ----------- + Wired for 48 27128 16k*8 PROMs for the main layer and a single 27128 + 16k*8 PROM for the high-priority text layer. The board is laid out to + allow for a second bank of 48 16k*8 PROMs (possibly intented to be + selected with A15). There are provisions for in-circuit programming, + but the lines are disabled using jumpers during nromal operation. + + +------+-----+-----+-----+-----+ + | PP4 | 0 | 0 | 1 | 1 | + | A15 | 0 | 0 | 0 | 0 | + | A14 | 0 | 1 | 0 | 1 | + +------+-----+-----+-----+-----+ + | 0000 | U4 | U19 | U37 | U51 | + | 0001 | U5 | U20 | U38 | U52 | + | 0010 | U6 | U21 | U39 | U53 | + | 0011 | U7 | U22 | U40 | U54 | + | 0100 | U8 | U23 | U41 | U55 | + | 0101 | U9 | U24 | U42 | U56 | + | 0110 | U10 | U25 | U43 | U57 | + | 0111 | U11 | U26 | U44 | U58 | + | 1000 | U12 | U27 | | | + | 1001 | U13 | U28 | | | + | 1010 | U14 | U29 | | | + | 1011 | U15 | U30 | | | + | 1100 | U33 | U47 | | | + | 1101 | U34 | U48 | | | + | 1110 | U35 | U49 | | U46 | + | 1111 | U36 | U50 | | | + +------+-----+-----+-----+-----+ + * U46 will only be selected using A and PP if B/G 9 is asserted + * U46 will also be selected if CS TOP is asserted + + D-9941 Sound: + ------------- + Supports up to 56KiB of ROM (48KiB low and 8KiB high), but only 8KiB is + populated. Supports up to 4KiB of RAM, but only 2KiB is populated. + The main sound generation uses 1408 8-bit R2R DACs driven through 2812 + 32*8 FIFOs. The board is wired for three, but only two are populated. + The FIFOs can be stepped under CPU control or using the outputs of a + 6840 PTM. There's also provision for a 5220 speech chip, but it's + unpopulated. + + There's space for a 64-pin DIL connector exposing the CPU address, data + and control signals, and providing in-circut ROM programming capability, + but it isn't populated. + + */ + +#include "emu.h" + +#include "cpu/m6809/m6809.h" +#include "machine/2812fifo.h" +#include "machine/6821pia.h" +#include "machine/6840ptm.h" +#include "machine/input_merger.h" +#include "machine/nvram.h" + +#include "emupal.h" + + +namespace { + +class sr_state : public driver_device +{ +public: + sr_state(machine_config const &mconfig, device_type type, char const *tag) + : driver_device(mconfig, type, tag) + , m_main_cpu(*this, "cpu.u46") + , m_main_pia1(*this, "cpu.u10") + , m_main_pia2(*this, "cpu.u20") + , m_main_nvram(*this, "cpu.u9") + , m_main_mem_prot(*this, "MEMPROT") + , m_main_led(*this, "cpu.u3") + , m_vgg_pia(*this, "vgg.u7") + , m_vgg_palette(*this, "vgg.color") + , m_pif_cpu(*this, "pif.u4") + , m_pif_pia(*this, "pif.u1") + , m_sound_cpu(*this, "sound.u5") + , m_sound_ptm(*this, "sound.u14") + , m_sound_pia1(*this, "sound.u34") + , m_sound_pia2(*this, "sound.u15") + , m_sound_fifos(*this, { "sound.u23", "sound.u22" }) + { + } + + void starrider(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(sound_sw1_changed); + +protected: + void driver_start() override; + +private: + u8 cpu_page_r(address_space &space); + void cpu_page_w(u8 data); + u8 cpu_led_r(address_space &space); + void cpu_led_w(u8 data); + u8 cpu_wd_r(address_space &space); + void cpu_wd_w(u8 data); + u8 cpu_nvram_r(address_space &space, offs_t offset); + void cpu_nvram_w(offs_t offset, u8 data); + DECLARE_WRITE_LINE_MEMBER(cpu_pia2_ca2_w); + + void vgg_impg_w(u8 data); + void vgg_xlate_w(u8 data); + void vgg_disable_w(u8 data); + void vgg_color_palet_w(u8 data); + + u8 pif_irq_enable_r(address_space &space); + void pif_irq_enable_w(u8 data); + u8 pif_irq_ack_r(address_space &space) { m_pif_cpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); return space.unmap(); } + void pif_irq_ack_w(u8 data) { m_pif_cpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE); } + + template u8 sound_fifo_pl_r(address_space &space); + template void sound_fifo_pl_w(u8 data); + template u8 sound_fifo_pd_r(address_space &space); + template void sound_fifo_pd_w(u8 data); + u8 sound_ef1_r(address_space &space); + void sound_ef1_w(u8 data); + u8 sound_er1_r(address_space &space); + void sound_er1_w(u8 data); + u8 sound_ef2_r(address_space &space); + void sound_ef2_w(u8 data); + u8 sound_er2_r(address_space &space); + void sound_er2_w(u8 data); + + void sound_pia2_pa(u8 data); + DECLARE_WRITE_LINE_MEMBER(sound_fifo0_ir); + DECLARE_WRITE_LINE_MEMBER(sound_fifo1_ir); + template DECLARE_WRITE_LINE_MEMBER(sound_fifo_or); + template DECLARE_WRITE_LINE_MEMBER(sound_fifo_flag); + + void main_memory(address_map &map); + void pif_memory(address_map &map); + void sound_memory(address_map &map); + + required_device m_main_cpu; + required_device m_main_pia1; + required_device m_main_pia2; + required_shared_ptr m_main_nvram; + required_ioport m_main_mem_prot; + output_finder<> m_main_led; + + required_device m_vgg_pia; + required_device m_vgg_palette; + + required_device m_pif_cpu; + required_device m_pif_pia; + + required_device m_sound_cpu; + required_device m_sound_ptm; + required_device m_sound_pia1; + required_device m_sound_pia2; + required_device_array m_sound_fifos; + + u8 m_main_page = 0U; + + u8 m_vgg_image_page = 0U; + u8 m_vgg_xlate = 0U; + u8 m_vgg_expand_disable = 0U; + u8 m_vgg_background_disable = 0U; + u8 m_vgg_color_palet = 0U; + + u8 m_pif_irq_enable = 0U; + + u8 m_sound_ptm_o[2] = { 0U, 0U }; + u8 m_sound_pia2_pa_out = 0xffU; + u8 m_sound_pia2_pb_in = 0xffU; +}; + + +void sr_state::starrider(machine_config &config) +{ + // CPU + MC6809E(config, m_main_cpu, 24_MHz_XTAL / 2 / 12 /* ? */); // 6809E - clock patterns generated using 82S123 at VGG U114 + m_main_cpu->set_addrmap(AS_PROGRAM, &sr_state::main_memory); + + PIA6821(config, m_main_pia1, 24_MHz_XTAL / 2 / 12 /* ? */); // 6820/21 + m_main_pia1->readpa_handler().set_ioport("IN2"); + // CA1 is the /END SCREEN signal + // CA2 is the 4MS signal + m_main_pia1->writepb_handler().set(m_sound_pia1, FUNC(pia6821_device::write_portb)); + m_main_pia1->cb2_handler().set(m_sound_pia1, FUNC(pia6821_device::ca1_w)); + m_main_pia1->irqa_handler().set("main.irq", FUNC(input_merger_device::in_w<0>)); + m_main_pia1->irqb_handler().set("main.irq", FUNC(input_merger_device::in_w<1>)); + + PIA6821(config, m_main_pia2, 24_MHz_XTAL / 2 / 12 /* ? */); // 6820/21 + m_main_pia2->readpa_handler().set_ioport("IN0"); + m_main_pia2->readca1_handler().set_constant(0); // grounded + m_main_pia2->ca2_handler().set(FUNC(sr_state::cpu_pia2_ca2_w)); + m_main_pia2->readpb_handler().set_ioport("IN1"); + m_main_pia2->readcb1_handler().set_constant(0); // grounded + // CB2 is unused + // IRQA and IRQB are unused + + NVRAM(config, "cpu.u9", nvram_device::DEFAULT_ALL_0); + + INPUT_MERGER_ANY_HIGH(config, "main.irq").output_handler().set_inputline(m_main_cpu, M6809_IRQ_LINE); + + // VGG + PIA6821(config, m_vgg_pia, 24_MHz_XTAL / 2 / 12 /* ? */); // 6821 + // PA0-8 and CA2 are outputs to the expander board + // CA1 is the /HALT signal + // PB0-7 and CB1-2 are the interface to the PIF board (bidirectional) + m_vgg_pia->irqa_handler().set_inputline(m_main_cpu, M6809_FIRQ_LINE); + m_vgg_pia->irqb_handler().set("main.irq", FUNC(input_merger_device::in_w<2>)); + + PALETTE(config, m_vgg_palette).set_format(palette_device::IBGR_4444, 1024).set_endianness(ENDIANNESS_LITTLE); + + // PIF + MC6809E(config, m_pif_cpu, 4_MHz_XTAL / 4); // 6809E + m_pif_cpu->set_addrmap(AS_PROGRAM, &sr_state::pif_memory); + + PIA6821(config, m_pif_pia, 4_MHz_XTAL / 4); // 6821 + m_pif_pia->irqa_handler().set_inputline(m_pif_cpu, M6809_FIRQ_LINE); + m_pif_pia->irqb_handler().set_inputline(m_pif_cpu, INPUT_LINE_NMI); + + // Sound + MC6809E(config, m_sound_cpu, 8_MHz_XTAL / 4); // 68B09E + m_sound_cpu->set_addrmap(AS_PROGRAM, &sr_state::sound_memory); + + PTM6840(config, m_sound_ptm, 8_MHz_XTAL / 4); // 68B40 + m_sound_ptm->o1_callback().set(m_sound_ptm, FUNC(ptm6840_device::set_c1)); + m_sound_ptm->o1_callback().append([this] (int state) { m_sound_fifos[0]->pd_w(m_sound_ptm_o[0] = state); }); + m_sound_ptm->o2_callback().set(m_sound_ptm, FUNC(ptm6840_device::set_c2)); + m_sound_ptm->o2_callback().append([this] (int state) { m_sound_fifos[1]->pd_w(m_sound_ptm_o[1] = state); }); + m_sound_ptm->o3_callback().set(m_sound_ptm, FUNC(ptm6840_device::set_c3)); + m_sound_ptm->irq_callback().set("sound.irq", FUNC(input_merger_device::in_w<0>)); + + PIA6821(config, m_sound_pia1, 8_MHz_XTAL / 4); // 68B21 + m_sound_pia1->ca2_handler().set(m_main_pia1, FUNC(pia6821_device::cb1_w)); + // PB0-7 are for unpopulated 5220 at U55 + // CB1-2 are unused + m_sound_pia1->irqa_handler().set_inputline(m_sound_cpu, M6809_FIRQ_LINE); + m_sound_pia1->irqb_handler().set("sound.irq", FUNC(input_merger_device::in_w<1>)); + + PIA6821(config, m_sound_pia2, 8_MHz_XTAL / 4); // 68B21 + m_sound_pia2->writepa_handler().set(FUNC(sr_state::sound_pia2_pa)); + // PA3 is the IR output from the unpopulated third FIFO (active low) + // PA7 is the RDY output from the unpopulated 5220 (active low) + // CB1-2 are unused + m_sound_pia1->irqb_handler().set("sound.irq", FUNC(input_merger_device::in_w<2>)); + m_sound_pia1->irqb_handler().set("sound.irq", FUNC(input_merger_device::in_w<3>)); + + FIFO2812(config, m_sound_fifos[0]); + m_sound_fifos[0]->ir_cb().set(FUNC(sr_state::sound_fifo0_ir)); + //m_sound_fifos[0]->ir_cb().append(...) IR is input to a clock-stretching circuit + m_sound_fifos[0]->or_cb().set(FUNC(sr_state::sound_fifo_or<0>)); + m_sound_fifos[0]->flag_cb().set(FUNC(sr_state::sound_fifo_flag<0>)); + + FIFO2812(config, m_sound_fifos[1]); + m_sound_fifos[1]->ir_cb().set(FUNC(sr_state::sound_fifo1_ir)); + //m_sound_fifos[1]->ir_cb().append(...) IR is input to a clock-stretching circuit + m_sound_fifos[1]->or_cb().set(FUNC(sr_state::sound_fifo_or<1>)); + m_sound_fifos[1]->flag_cb().set(FUNC(sr_state::sound_fifo_flag<1>)); + + INPUT_MERGER_ANY_HIGH(config, "sound.irq").output_handler().set_inputline(m_sound_cpu, M6809_IRQ_LINE); +} + + +INPUT_CHANGED_MEMBER(sr_state::sound_sw1_changed) +{ + // TODO: 4.7kΩ/0.01µF RC time constant to stretch/debounce this + m_sound_cpu->set_input_line(INPUT_LINE_NMI, newval ? ASSERT_LINE : CLEAR_LINE); +} + + +void sr_state::driver_start() +{ + m_main_led.resolve(); + + save_item(NAME(m_main_page)); + save_item(NAME(m_vgg_image_page)); + save_item(NAME(m_vgg_xlate)); + save_item(NAME(m_vgg_expand_disable)); + save_item(NAME(m_vgg_background_disable)); + save_item(NAME(m_vgg_color_palet)); + save_item(NAME(m_pif_irq_enable)); + save_item(NAME(m_sound_ptm_o)); + save_item(NAME(m_sound_pia2_pa_out)); + save_item(NAME(m_sound_pia2_pb_in)); + + m_main_page = 0U; + m_vgg_image_page = 0U; + m_vgg_xlate = 0U; + m_vgg_expand_disable = 0U; + m_vgg_background_disable = 0U; + m_vgg_color_palet = 0U; + m_pif_irq_enable = 0U; + std::fill(std::begin(m_sound_ptm_o), std::end(m_sound_ptm_o), 0U); + m_sound_pia2_pa_out = 0xffU; + m_sound_pia2_pb_in = 0xffU; + + for (unsigned i = 0U; 3U > i; ++i) + { + m_sound_ptm->set_gate(i, 0); + m_sound_ptm->set_clock(i, 0); + } +} + + +u8 sr_state::cpu_page_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + cpu_page_w(data); + return data; +} + +void sr_state::cpu_page_w(u8 data) +{ + // 4 bits latched by U43 (74LS173) + m_main_page = data & 0x0f; +} + +u8 sr_state::cpu_led_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + cpu_led_w(data); + return data; +} + +void sr_state::cpu_led_w(u8 data) +{ + // latched by U16 (74LS374) + m_main_led = bitswap<8>(~data, 0, 1, 2, 3, 4, 5, 6, 7); +} + +u8 sr_state::cpu_wd_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + cpu_wd_w(data); + return data; +} + +void sr_state::cpu_wd_w(u8 data) +{ + // U22 (74LS161) parallel load zero + if ((data & 0x3e) == 0x2a) + /* TODO: watchdog reset */; +} + +u8 sr_state::cpu_nvram_r(address_space &space, offs_t offset) +{ + // U9 (5514) is 4 bits wide + return (m_main_nvram[offset] & 0x0f) | (space.unmap() & 0xf0); +} + +void sr_state::cpu_nvram_w(offs_t offset, u8 data) +{ + // memory protect switch prevents writes to the first quarter of NVRAM + if ((offset & 0x300) || !BIT(m_main_mem_prot->read(), 0)) + m_main_nvram[offset] = data & 0x0f; +} + +WRITE_LINE_MEMBER(sr_state::cpu_pia2_ca2_w) +{ + m_sound_cpu->set_input_line(INPUT_LINE_RESET, state ? ASSERT_LINE : CLEAR_LINE); + for (auto const &fifo : m_sound_fifos) + fifo->mr_w(state ? 0 : 1); + + // TODO: these devices don't have reset line inputs exposed + if (state) + { + m_sound_ptm->reset(); + m_sound_pia1->reset(); + m_sound_pia2->reset(); + } +} + + +void sr_state::vgg_impg_w(u8 data) +{ + // 6 bits latched by U13 (74LS173) but only 5 bits used + m_vgg_image_page = data & 0x1f; +} + +void sr_state::vgg_xlate_w(u8 data) +{ + // 6 bits latched by U12 (74LS173) + m_vgg_xlate = data & 0x3f; +} + +void sr_state::vgg_disable_w(u8 data) +{ + // latched by U111 (74LS74) + m_vgg_background_disable = BIT(data, 0); // actual signal is active low + m_vgg_expand_disable = BIT(data, 1); +} + +void sr_state::vgg_color_palet_w(u8 data) +{ + // all 8 bits latched by U94 (74LS374) but only 6 bits used + m_vgg_color_palet = data & 0x3f; +} + + +u8 sr_state::pif_irq_enable_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + pif_irq_enable_w(data); + return data; +} + +void sr_state::pif_irq_enable_w(u8 data) +{ + m_pif_irq_enable = BIT(data, 0); +} + + +template u8 sr_state::sound_fifo_pl_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + sound_fifo_pl_w(data); + return data; +} + +template void sr_state::sound_fifo_pl_w(u8 data) +{ + // TODO: input to a clock-stretching circuit + m_sound_fifos[N]->write(data); +} + +template u8 sr_state::sound_fifo_pd_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + sound_fifo_pd_w(data); + return data; +} + +template void sr_state::sound_fifo_pd_w(u8 data) +{ + m_sound_fifos[N]->pd_w(m_sound_ptm_o[N] ? 0 : 1); + m_sound_fifos[N]->pd_w(m_sound_ptm_o[N] ? 1 : 0); +} + +u8 sr_state::sound_ef1_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + sound_ef1_w(data); + return data; +} + +void sr_state::sound_ef1_w(u8 data) +{ + data &= 0x3f; // DAC 1 -> front mix level (6 bits latched by U19) +} + +u8 sr_state::sound_er1_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + sound_er1_w(data); + return data; +} + +void sr_state::sound_er1_w(u8 data) +{ + data &= 0x3f; // DAC 1 -> rear mix level (6 bits latched by U2) +} + +u8 sr_state::sound_ef2_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + sound_ef2_w(data); + return data; +} + +void sr_state::sound_ef2_w(u8 data) +{ + data &= 0x3f; // DAC 2 -> front mix level (6 bits latched by U17) +} + +u8 sr_state::sound_er2_r(address_space &space) +{ + u8 const data(space.unmap()); + if (!machine().side_effects_disabled()) + sound_er2_w(data); + return data; +} + +void sr_state::sound_er2_w(u8 data) +{ + data &= 0x3f; // DAC 2 -> rear mix level (6 bits latched by U36) +} + + +void sr_state::sound_pia2_pa(u8 data) +{ + u8 const diff(data ^ m_sound_pia2_pa_out); + m_sound_pia2_pa_out = data; + if (diff & ~m_sound_pia2_pb_in & 0x77U) + { + m_sound_pia2->write_portb(m_sound_pia2_pb_in | (m_sound_pia2_pa_out & 0x77U)); + m_sound_pia2->ca1_w((0x07U == ((m_sound_pia2_pb_in | m_sound_pia2_pa_out) & 0x07U)) ? 1 : 0); + m_sound_pia2->ca2_w((0x70U == ((m_sound_pia2_pb_in | m_sound_pia2_pa_out) & 0x70U)) ? 1 : 0); + } +} + +DECLARE_WRITE_LINE_MEMBER(sr_state::sound_fifo0_ir) +{ + if (state) + m_sound_pia2_pb_in |= 0x08U; + else + m_sound_pia2_pb_in &= 0xf7U; + m_sound_pia2->write_portb(m_sound_pia2_pb_in | (m_sound_pia2_pa_out & 0x77U)); +} + +DECLARE_WRITE_LINE_MEMBER(sr_state::sound_fifo1_ir) +{ + if (state) + m_sound_pia2_pb_in |= 0x80U; + else + m_sound_pia2_pb_in &= 0x7fU; + m_sound_pia2->write_portb(m_sound_pia2_pb_in | (m_sound_pia2_pa_out & 0x77U)); +} + +template WRITE_LINE_MEMBER(sr_state::sound_fifo_or) +{ + if (state) + m_sound_pia2_pb_in |= u8(1) << (N + 4); + else + m_sound_pia2_pb_in &= ~(u8(1) << (N + 4)); + if (!BIT(m_sound_pia2_pa_out, N + 4)) + { + m_sound_pia2->write_portb(m_sound_pia2_pb_in | (m_sound_pia2_pa_out & 0x77U)); + m_sound_pia2->ca2_w((0x70U == ((m_sound_pia2_pb_in | m_sound_pia2_pa_out) & 0x70U)) ? 1 : 0); + } +} + +template WRITE_LINE_MEMBER(sr_state::sound_fifo_flag) +{ + if (state) + m_sound_pia2_pb_in |= u8(1) << N; + else + m_sound_pia2_pb_in &= ~(u8(1) << N); + if (!BIT(m_sound_pia2_pa_out, N)) + { + m_sound_pia2->write_portb(m_sound_pia2_pb_in | (m_sound_pia2_pa_out & 0x77U)); + m_sound_pia2->ca1_w((0x07U == ((m_sound_pia2_pb_in | m_sound_pia2_pa_out) & 0x07U)) ? 1 : 0); + } +} + + +void sr_state::main_memory(address_map &map) +{ + map(0xa000, 0xbfff).ram(); // U51/U44/U36/U25 (6116) + map(0xc000, 0xc7ff).ram().w(m_vgg_palette, FUNC(palette_device::write8)).share("vgg.color"); // U96/U97/U98/U99 (2148) + + map(0xc800, 0xc800).mirror(0x007f).rw(FUNC(sr_state::cpu_page_r), FUNC(sr_state::cpu_page_w)); + map(0xc880, 0xc880).mirror(0x007f).rw(FUNC(sr_state::cpu_led_r), FUNC(sr_state::cpu_led_w)); + map(0xc900, 0xc900).mirror(0x007f).rw(FUNC(sr_state::cpu_wd_r), FUNC(sr_state::cpu_wd_w)); + map(0xc980, 0xc983).mirror(0x0070).rw(m_main_pia1, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + map(0xc984, 0xc987).mirror(0x0070).rw(m_main_pia2, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + + map(0xcb80, 0xcb83).mirror(0x000c).rw(m_vgg_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + //map(0xcb90, 0xcb90).mirror(0x000f).r(FUNC(sr_state::...)); inverted FIELD signal on D7 + //map(0xcba0, 0xcba0).mirror(0x000f).r(FUNC(sr_state::...)); vertical counters (video address A13..A6) + //map(0xcbb0, 0xcbbf) DMA + map(0xcbc0, 0xcbc0).mirror(0x000e).w(FUNC(sr_state::vgg_impg_w)); + map(0xcbc1, 0xcbc1).mirror(0x000e).w(FUNC(sr_state::vgg_xlate_w)); + map(0xcbd0, 0xcbd0).mirror(0x000f).w(FUNC(sr_state::vgg_disable_w)); + map(0xcbe0, 0xcbe0).mirror(0x000f).w(FUNC(sr_state::vgg_color_palet_w)); + + map(0xcc00, 0xcfff).rw(FUNC(sr_state::cpu_nvram_r), FUNC(sr_state::cpu_nvram_w)).share(m_main_nvram); + map(0xd000, 0xd7ff).ram(); // U14 (6116) + //map(0xd800, 0xdfff).ram() U7 (6116) unpopulated + map(0xe000, 0xffff).rom().region("fixed", 0x0000); +} + +void sr_state::pif_memory(address_map &map) +{ + map(0x0000, 0x1fff).ram(); + map(0x2000, 0x2000).mirror(0x1fff).rw(FUNC(sr_state::pif_irq_enable_r), FUNC(sr_state::pif_irq_enable_w)); + map(0x4000, 0x4000).mirror(0x1fff).rw(FUNC(sr_state::pif_irq_ack_r), FUNC(sr_state::pif_irq_ack_w)); + //map(0x6000, 0x6000).mirror(0x1fff) LD player via U5 if it was populated + map(0x8000, 0x8003).mirror(0x1ffc).rw(m_pif_pia, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + // nothing in 0xa000-0xdfff + map(0xe000, 0xefff).mirror(0x1000).rom().region("pif", 0x0000); +} + +void sr_state::sound_memory(address_map &map) +{ + map(0x0000, 0xbfff).rom().region("snd", 0x0000); + map(0xc000, 0xc007).mirror(0x0078).rw(m_sound_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)); + map(0xc080, 0xc083).mirror(0x007c).rw(m_sound_pia1, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + //map(0xc100, 0xc17f) U55 (5220) unpopulated + // nothing in 0xc180-0xc1ff + map(0xc200, 0xc200).mirror(0x007f).rw(FUNC(sr_state::sound_fifo_pd_r<0>), FUNC(sr_state::sound_fifo_pd_w<0>)); + map(0xc280, 0xc280).mirror(0x007f).rw(FUNC(sr_state::sound_fifo_pd_r<1>), FUNC(sr_state::sound_fifo_pd_w<1>)); + //map(0xc300, 0xc37f) U21 (2821) unpopulated + map(0xc380, 0xc380).mirror(0x007f).rw(FUNC(sr_state::sound_ef1_r), FUNC(sr_state::sound_ef1_w)); + map(0xc400, 0xc400).mirror(0x007f).rw(FUNC(sr_state::sound_er1_r), FUNC(sr_state::sound_er1_w)); + map(0xc480, 0xc480).mirror(0x007f).rw(FUNC(sr_state::sound_ef2_r), FUNC(sr_state::sound_ef2_w)); + map(0xc500, 0xc500).mirror(0x007f).rw(FUNC(sr_state::sound_er2_r), FUNC(sr_state::sound_er2_w)); + map(0xc580, 0xc583).mirror(0x007c).rw(m_sound_pia2, FUNC(pia6821_device::read), FUNC(pia6821_device::write)); + // nothing in 0xc600-0xc67f + //map(0xc680, 0xc6ff) U21 (2812) unpopulated + map(0xc700, 0xc700).mirror(0x007f).rw(FUNC(sr_state::sound_fifo_pl_r<1>), FUNC(sr_state::sound_fifo_pl_w<1>)); + map(0xc780, 0xc780).mirror(0x007f).rw(FUNC(sr_state::sound_fifo_pl_r<0>), FUNC(sr_state::sound_fifo_pl_w<0>)); + // nothing in 0xc800-0xcfff + map(0xd000, 0xd7ff).ram(); // U13 (6116) + //map(0xd800, 0xdfff) U12 (6116) unpopulated + map(0xe000, 0xffff).rom().region("snd", 0xe000); +} + + +INPUT_PORTS_START(starrider) + PORT_START("IN0") + PORT_BIT(0x3f, IP_ACTIVE_LOW, IPT_UNKNOWN) // TODO: steering Gray code + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_START2) + + PORT_START("IN1") + PORT_BIT(0x0f, IP_ACTIVE_LOW, IPT_UNKNOWN) // TODO: accelerator + PORT_BIT(0x30, IP_ACTIVE_LOW, IPT_UNKNOWN) // TODO: brake + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Turbo") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_TOGGLE PORT_NAME("Hi/Lo") + + PORT_START("IN2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_SERVICE1) PORT_TOGGLE PORT_NAME("Auto Up / Manual Down") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_SERVICE) PORT_NAME("Advance") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_MEMORY_RESET) PORT_NAME("High Score Reset") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_COIN1) + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_COIN2) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_COIN3) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_TILT) + PORT_CONFNAME(0x80, 0x00, DEF_STR(Upright)) PORT_DIPLOCATION("CPU W7:1") + PORT_CONFSETTING(0x80, DEF_STR(Off)) + PORT_CONFSETTING(0x00, DEF_STR(On)) + + PORT_START("MEMPROT") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_SERVICE2) PORT_TOGGLE PORT_NAME("Memory Protect") + + PORT_START("SW1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_SERVICE3) PORT_NAME("Sound Test") + PORT_CHANGED_MEMBER(DEVICE_SELF, sr_state, sound_sw1_changed, 0) +INPUT_PORTS_END + + +ROM_START(starridr) + // TODO: ROM labels are illegible in photos + ROM_REGION(0x2000, "fixed", 0) + ROM_LOAD("rom_35.u52", 0x0000, 0x2000, CRC(9c9a50bb) SHA1(99f6cfff19c41251645259f5268af6d29d28e48b)) + + ROM_REGION(0x1'2000, "banked", 0) + ROM_LOAD("rom_30.u8", 0x0'0000, 0x4000, CRC(934d98c0) SHA1(8e53b0b024623d88bbaf7a3061925b5d8de37fb3)) + ROM_LOAD("rom_31.u15", 0x0'4000, 0x4000, CRC(69dcb5af) SHA1(a3a6cefa1b8029ba1ca2ab14898f2949a7e13a4b)) + ROM_LOAD("rom_32.u26", 0x0'8000, 0x4000, CRC(b0ed1ed4) SHA1(32f2f06c3359079628e8ec83c8bdb85e170031ea)) + // 0xc000 U37 unpopulated + ROM_LOAD("rom_34.u45", 0x1'0000, 0x2000, CRC(5b0b9a26) SHA1(3e2f8efa805a797546f984c6538fd353f3f7470b)) + + ROM_REGION(0x1000, "pif", 0) + ROM_LOAD("rom_26.u3", 0x0000, 0x1000, CRC(04e9d9fc) SHA1(c5531f6acf929bc243b5313bee6627d93dac90b9) BAD_DUMP) // reset vector points to RAM - can't be right + + ROM_REGION(0x1'0000, "snd", 0) + // 0x0000 U8 unpopulated + // 0x4000 U9 unpopulated + // 0x8000 U10 unpopulated + // 0xc000 space for RAM and I/O + ROM_LOAD("rom_27.u11", 0xe000, 0x2000, CRC(ffacb56d) SHA1(e6f7984e014a5ace50b0b1428a386ae645b972f5)) + + ROM_REGION(0x10'0000, "gfx", 0) + ROM_LOAD("rom_1.u4", 0x0'0000, 0x4000, CRC(9655db83) SHA1(50406ea8a4e20dbc7d4ff3ca60d41d142e3d593e)) + ROM_LOAD("rom_2.u19", 0x0'4000, 0x4000, CRC(8903afe2) SHA1(dce09ab66ad96422e426b8f0eb7bedaad1596be2)) + ROM_LOAD("rom_3.u5", 0x0'8000, 0x4000, CRC(ac1bdd83) SHA1(a635714d814fea7728e3d62003069873d00536b2)) + ROM_LOAD("rom_4.u20", 0x0'c000, 0x4000, CRC(3bef2dc3) SHA1(60e8c794d706ea6ef7b4c25f11fd9850f992bafd)) + ROM_LOAD("rom_5.u6", 0x1'0000, 0x4000, CRC(18470b9c) SHA1(5cf7bbf8c1dfeff9ee570b86d7d02bf7126ad01f)) + ROM_LOAD("rom_6.u21", 0x1'4000, 0x4000, CRC(3d345e8b) SHA1(77a1faa1b2e48bc51b20b3015007d399f72c5fc9)) + ROM_LOAD("rom_7.u7", 0x1'8000, 0x4000, CRC(c2f624db) SHA1(f57c6c16a7cf5a03cb1bee7fba841d70fe6a25d9)) + ROM_LOAD("rom_8.u22", 0x1'c000, 0x4000, CRC(089cc4dd) SHA1(ef15cf517da6ffae9e1063f3fda854ad2ef16e66)) + ROM_LOAD("rom_9.u8", 0x2'0000, 0x4000, CRC(360938be) SHA1(632194a3d398a7f670bfb05f58c1afd8c17ec288)) + ROM_LOAD("rom_10.u23", 0x2'4000, 0x4000, CRC(2fc10697) SHA1(205476c13348140a92254d0998d740f18bff7187)) + ROM_LOAD("rom_11.u9", 0x2'8000, 0x4000, CRC(665a4b07) SHA1(3c57839f65070e2b63b33eaa833370203993dc51)) + ROM_LOAD("rom_12.u24", 0x2'c000, 0x4000, CRC(e117c9b3) SHA1(0500e6723b973ab672f4479bf1ce45579ef9a9f2)) + ROM_LOAD("rom_13.u10", 0x3'0000, 0x4000, CRC(3e8cdea4) SHA1(554ddd87d5a5de1b04b81ca6a730682d90f334a1)) + ROM_LOAD("rom_14.u25", 0x3'4000, 0x4000, CRC(d8260022) SHA1(6eb60d512f6bee3a74950145ab52a6c8bb7054c4)) + ROM_LOAD("rom_15.u11", 0x3'8000, 0x4000, CRC(bac9b2b4) SHA1(0700debb88f7e001c78407f69d804c4340d602e2)) + ROM_LOAD("rom_16.u26", 0x3'c000, 0x4000, CRC(111e2f28) SHA1(96904f08d66fed87fcfc0c59be50546f42e27687)) + ROM_LOAD("rom_17.u12", 0x4'0000, 0x4000, CRC(eb5f96dd) SHA1(2ccd3b1ea12e201306707d8ed95c000c06766b48)) + ROM_LOAD("rom_18.u27", 0x4'4000, 0x4000, CRC(b87eeeee) SHA1(37d6c360c7557d28bb7cc109ac6617569d7afb18)) + ROM_LOAD("rom_19.u13", 0x4'8000, 0x4000, CRC(67ffe21b) SHA1(ebfc8f963e852cf5adb14f7f76f60fd738ddbc18)) + // 0x4'c000 U28 unpopulated + // 0x5'0000 U14 unpopulated + // 0x5'4000 U29 unpopulated + // 0x5'8000 U15 unpopulated + // 0x5'c000 U30 unpopulated + // 0x6'0000 U33 unpopulated + // 0x6'4000 U47 unpopulated + // 0x6'8000 U34 unpopulated + // 0x6'c000 U48 unpopulated + // 0x7'0000 U35 unpopulated + // 0x7'4000 U49 unpopulated + // 0x7'8000 U36 unpopulated + // 0x7'c000 U50 unpopulated + // 0x8'0000 U37 unpopulated + // 0x8'4000 U51 unpopulated + // 0x8'8000 U38 unpopulated + // 0x8'c000 U52 unpopulated + // 0x9'0000 U39 unpopulated + // 0x9'4000 U53 unpopulated + // 0x9'8000 U40 unpopulated + // 0x9'c000 U54 unpopulated + // 0xa'0000 U41 unpopulated + // 0xa'4000 U55 unpopulated + // 0xa'8000 U42 unpopulated + // 0xa'c000 U56 unpopulated + // 0xb'0000 U43 unpopulated + // 0xb'4000 U57 unpopulated + // 0xb'8000 U44 unpopulated + // 0xb'c000 U58 unpopulated + ROM_LOAD("rom_25.u46", 0xe'4000, 0x2000, CRC(2812097e) SHA1(793ed5ec8b1d1689e856fc2008f46faf963f5045)) + ROM_RELOAD(0xe'6000, 0x2000) + + ROM_REGION(0x4000, "text", 0) + ROM_LOAD("rom_25.u46", 0x0000, 0x2000, CRC(2812097e) SHA1(793ed5ec8b1d1689e856fc2008f46faf963f5045)) + ROM_RELOAD(0x2000, 0x2000) +ROM_END + +} // anonymous namespace + + +/*********************************************************************** + Machine definitions +***********************************************************************/ +GAME( 1984, starridr, 0, starrider, starrider, sr_state, empty_init, ROT0, "Williams", "Star Rider", MACHINE_IS_SKELETON ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 2e92c99379b..0e6095fad24 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -36243,6 +36243,9 @@ starfirea // Exidy [1979?] spcship // whtforce // +@source:starrider.cpp // +starridr + @source:starshp1.cpp starshp1 // 007513-007531 1977/07 [6502] starshpp // 007513-007531 1977/07 [6502] -- cgit v1.2.3