From 5d183b86fe6d63ab86e7fbd5677cd4b01b3da782 Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 11 Jun 2018 19:46:46 -0400 Subject: balsente.cpp: Split NVRAM between two X2212 devices --- src/mame/drivers/balsente.cpp | 7 ++++--- src/mame/includes/balsente.h | 3 +++ src/mame/machine/balsente.cpp | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/mame/drivers/balsente.cpp b/src/mame/drivers/balsente.cpp index e81882b5159..bb2a511ce09 100644 --- a/src/mame/drivers/balsente.cpp +++ b/src/mame/drivers/balsente.cpp @@ -231,7 +231,6 @@ DIP locations verified for: #include "cpu/z80/z80.h" #include "cpu/m6809/m6809.h" #include "cpu/m68000/m68000.h" -#include "machine/nvram.h" #include "machine/watchdog.h" #include "sound/cem3394.h" #include "speaker.h" @@ -267,7 +266,8 @@ void balsente_state::cpu1_map(address_map &map) map(0x9903, 0x9903).portr("IN1").nopw(); map(0x9a00, 0x9a03).r(FUNC(balsente_state::random_num_r)); map(0x9a04, 0x9a05).rw(FUNC(balsente_state::m6850_r), FUNC(balsente_state::m6850_w)); - map(0x9b00, 0x9cff).ram().share("nvram"); /* system+cart NOVRAM */ + map(0x9b00, 0x9bff).rw("nov0", FUNC(x2212_device::read), FUNC(x2212_device::write)); + map(0x9c00, 0x9cff).rw("nov1", FUNC(x2212_device::read), FUNC(x2212_device::write)); map(0xa000, 0xbfff).bankr("bank1"); map(0xc000, 0xffff).bankr("bank2"); } @@ -1305,7 +1305,8 @@ MACHINE_CONFIG_START(balsente_state::balsente) MCFG_QUANTUM_TIME(attotime::from_hz(600)) - MCFG_NVRAM_ADD_0FILL("nvram") + MCFG_X2212_ADD_AUTOSAVE("nov0") // system NOVRAM + MCFG_X2212_ADD_AUTOSAVE("nov1") // cart NOVRAM MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/includes/balsente.h b/src/mame/includes/balsente.h index b5fa0467412..14f8385e972 100644 --- a/src/mame/includes/balsente.h +++ b/src/mame/includes/balsente.h @@ -10,6 +10,7 @@ #include "machine/pit8253.h" #include "machine/timer.h" +#include "machine/x2212.h" #include "machine/74259.h" #include "sound/cem3394.h" #include "screen.h" @@ -51,6 +52,7 @@ public: , m_screen(*this, "screen") , m_palette(*this, "palette") , m_outlatch(*this, "outlatch") + , m_novram(*this, "nov%u", 0U) , m_generic_paletteram_8(*this, "paletteram") { } @@ -227,6 +229,7 @@ private: required_device m_screen; required_device m_palette; required_device m_outlatch; + required_device_array m_novram; required_shared_ptr m_generic_paletteram_8; }; diff --git a/src/mame/machine/balsente.cpp b/src/mame/machine/balsente.cpp index ff2f54b27d0..d1d2740071f 100644 --- a/src/mame/machine/balsente.cpp +++ b/src/mame/machine/balsente.cpp @@ -312,7 +312,8 @@ WRITE_LINE_MEMBER(balsente_state::out6_w) WRITE_LINE_MEMBER(balsente_state::nvrecall_w) { - logerror("nvrecall_w=%d\n", state); + m_novram[0]->recall(!state); + m_novram[1]->recall(!state); } -- cgit v1.2.3 From 3a46a189a38eab99463fcdfbf10d87984c7e5d61 Mon Sep 17 00:00:00 2001 From: Lord-Nightmare Date: Mon, 11 Jun 2018 19:54:33 -0400 Subject: fix build (nw) --- scripts/target/mame/arcade.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index ad079a568a4..59470e46c0c 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -354,6 +354,7 @@ VIDEOS["PPU2C0X"] = true -------------------------------------------------- MACHINES["AKIKO"] = true +MACHINES["BUSMOUSE"] = true MACHINES["NCR53C7XX"] = true MACHINES["LSI53C810"] = true MACHINES["6522VIA"] = true -- cgit v1.2.3 From 07b70fec341453e8ee6d65c1fe19592853654981 Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 11 Jun 2018 20:35:05 -0400 Subject: d461: NOVRAM stuff (nw) --- src/mame/drivers/d400.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/mame/drivers/d400.cpp b/src/mame/drivers/d400.cpp index 0983c9d3227..be5aed24c18 100644 --- a/src/mame/drivers/d400.cpp +++ b/src/mame/drivers/d400.cpp @@ -19,14 +19,19 @@ public: d400_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_novram(*this, "novram") { } + void d461(machine_config &config); +private: u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void d461(machine_config &config); + DECLARE_READ8_MEMBER(novram_recall_r); + DECLARE_READ8_MEMBER(novram_store_r); void mem_map(address_map &map); -private: + required_device m_maincpu; + required_device m_novram; }; u32 d400_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -34,6 +39,26 @@ u32 d400_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const return 0; } +READ8_MEMBER(d400_state::novram_recall_r) +{ + if (!machine().side_effects_disabled()) + { + m_novram->recall(1); + m_novram->recall(0); + } + return 0xff; +} + +READ8_MEMBER(d400_state::novram_store_r) +{ + if (!machine().side_effects_disabled()) + { + m_novram->store(1); + m_novram->store(0); + } + return 0xff; +} + void d400_state::mem_map(address_map &map) { map(0x0000, 0x3fff).ram(); @@ -43,6 +68,8 @@ void d400_state::mem_map(address_map &map) map(0x6000, 0x6fff).ram(); map(0x7800, 0x780f).rw("duart", FUNC(scn2681_device::read), FUNC(scn2681_device::write)); map(0x7880, 0x78bf).rw("novram", FUNC(x2210_device::read), FUNC(x2210_device::write)); + map(0x7900, 0x7900).r(FUNC(d400_state::novram_recall_r)); + map(0x7980, 0x7980).r(FUNC(d400_state::novram_store_r)); map(0x7c00, 0x7c00).nopw(); map(0x8000, 0xffff).rom().region("maincpu", 0); } @@ -62,6 +89,7 @@ MACHINE_CONFIG_START(d400_state::d461) MCFG_DEVICE_ADD("novram", X2210, 0) MCFG_DEVICE_ADD("duart", SCN2681, XTAL(3'686'400)) + MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", M6809_FIRQ_LINE)) MACHINE_CONFIG_END -- cgit v1.2.3 From 7f06e4f6c26c513c6f5e0e0556879d261fb306da Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 11 Jun 2018 21:47:34 -0400 Subject: irobot.cpp: Eliminate machine().device; use X2212 device for NVRAM (nw) --- src/mame/drivers/irobot.cpp | 17 ++--------------- src/mame/includes/irobot.h | 20 ++++++++++++-------- src/mame/machine/irobot.cpp | 34 +++++++++++++++++++++------------- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/mame/drivers/irobot.cpp b/src/mame/drivers/irobot.cpp index 4eb863ee031..056bd73b299 100644 --- a/src/mame/drivers/irobot.cpp +++ b/src/mame/drivers/irobot.cpp @@ -89,19 +89,6 @@ #define MAIN_CLOCK 12.096_MHz_XTAL #define VIDEO_CLOCK 20_MHz_XTAL -/************************************* - * - * NVRAM handler - * - *************************************/ - -WRITE8_MEMBER(irobot_state::irobot_nvram_w) -{ - m_nvram[offset] = data & 0x0f; -} - - - /************************************* * * IRQ acknowledgement @@ -157,7 +144,7 @@ void irobot_state::irobot_map(address_map &map) map(0x1140, 0x1140).w(FUNC(irobot_state::irobot_statwr_w)); map(0x1180, 0x1180).w(FUNC(irobot_state::irobot_out0_w)); map(0x11c0, 0x11c0).w(FUNC(irobot_state::irobot_rom_banksel_w)); - map(0x1200, 0x12ff).ram().w(FUNC(irobot_state::irobot_nvram_w)).share("nvram"); + map(0x1200, 0x12ff).rw("nvram", FUNC(x2212_device::read), FUNC(x2212_device::write)); map(0x1300, 0x1300).mirror(0xff).r("adc", FUNC(adc0809_device::data_r)); map(0x1400, 0x143f).rw(FUNC(irobot_state::quad_pokeyn_r), FUNC(irobot_state::quad_pokeyn_w)); map(0x1800, 0x18ff).w(FUNC(irobot_state::irobot_paletteram_w)); @@ -305,7 +292,7 @@ MACHINE_CONFIG_START(irobot_state::irobot) MCFG_ADC0808_IN0_CB(IOPORT("AN0")) MCFG_ADC0808_IN1_CB(IOPORT("AN1")) - MCFG_NVRAM_ADD_0FILL("nvram") + MCFG_X2212_ADD_AUTOSAVE("nvram") /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/includes/irobot.h b/src/mame/includes/irobot.h index 9a3d72f529f..d068ab5f1aa 100644 --- a/src/mame/includes/irobot.h +++ b/src/mame/includes/irobot.h @@ -11,6 +11,7 @@ #pragma once #include "machine/timer.h" +#include "machine/x2212.h" #include "sound/pokey.h" #include "screen.h" @@ -35,12 +36,16 @@ public: irobot_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_nvram(*this, "nvram") , m_videoram(*this, "videoram"), m_maincpu(*this, "maincpu"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_palette(*this, "palette"), +#if IR_TIMING + m_irvg_timer(*this, "irvg_timer"), + m_irmb_timer(*this, "irmb_timer"), +#endif + m_novram(*this, "nvram"), m_pokey(*this, "pokey%u", 1U), m_leds(*this, "led%u", 0U) { } @@ -50,12 +55,11 @@ public: void irobot(machine_config &config); protected: - virtual void machine_start() override { m_leds.resolve(); } + virtual void machine_start() override; virtual void machine_reset() override; virtual void video_start() override; void irobot_map(address_map &map); - DECLARE_WRITE8_MEMBER(irobot_nvram_w); DECLARE_WRITE8_MEMBER(irobot_clearirq_w); DECLARE_WRITE8_MEMBER(irobot_clearfirq_w); DECLARE_READ8_MEMBER(irobot_sharedmem_r); @@ -82,7 +86,6 @@ protected: void irmb_run(); private: - required_shared_ptr m_nvram; required_shared_ptr m_videoram; uint8_t m_vg_clear; uint8_t m_bufsel; @@ -91,10 +94,6 @@ private: uint8_t m_irvg_vblank; uint8_t m_irvg_running; uint8_t m_irmb_running; -#if IR_TIMING - timer_device *m_irvg_timer; - timer_device *m_irmb_timer; -#endif uint8_t *m_comRAM[2]; uint8_t *m_mbRAM; uint8_t *m_mbROM; @@ -118,6 +117,11 @@ private: required_device m_gfxdecode; required_device m_screen; required_device m_palette; +#if IR_TIMING + required_device m_irvg_timer; + required_device m_irmb_timer; +#endif + required_device m_novram; required_device_array m_pokey; output_finder<2> m_leds; }; diff --git a/src/mame/machine/irobot.cpp b/src/mame/machine/irobot.cpp index 3bfb2152b4b..cf0881456b2 100644 --- a/src/mame/machine/irobot.cpp +++ b/src/mame/machine/irobot.cpp @@ -67,15 +67,15 @@ WRITE8_MEMBER(irobot_state::irobot_statwr_w) logerror("write %2x ", data); IR_CPU_STATE(); - m_combase = m_comRAM[data >> 7]; - m_combase_mb = m_comRAM[(data >> 7) ^ 1]; - m_bufsel = data & 0x02; - if (((data & 0x01) == 0x01) && (m_vg_clear == 0)) + m_combase = m_comRAM[BIT(data, 7)]; + m_combase_mb = m_comRAM[BIT(data, 7) ^ 1]; + m_bufsel = BIT(data, 1); + if (BIT(data, 0) && (m_vg_clear == 0)) irobot_poly_clear(); - m_vg_clear = data & 0x01; + m_vg_clear = BIT(data, 0); - if ((data & 0x04) && !(m_statwr & 0x04)) + if (BIT(data, 2) && !BIT(m_statwr, 2)) { irobot_run_video(); #if IR_TIMING @@ -88,8 +88,11 @@ WRITE8_MEMBER(irobot_state::irobot_statwr_w) #endif m_irvg_running=1; } - if ((data & 0x10) && !(m_statwr & 0x10)) + if (BIT(data, 4) && !BIT(m_statwr, 4)) irmb_run(); + + m_novram->recall(!BIT(data, 6)); + m_statwr = data; } @@ -160,6 +163,13 @@ TIMER_CALLBACK_MEMBER(irobot_state::scanline_callback) machine().scheduler().timer_set(m_screen->time_until_pos(scanline), timer_expired_delegate(FUNC(irobot_state::scanline_callback),this), scanline); } +void irobot_state::machine_start() +{ + m_leds.resolve(); + m_vg_clear = 0; + m_statwr = 0; +} + void irobot_state::machine_reset() { uint8_t *MB = memregion("mathbox")->base(); @@ -172,17 +182,15 @@ void irobot_state::machine_reset() m_irvg_vblank=0; m_irvg_running = 0; - m_irvg_timer = machine().device("irvg_timer"); m_irmb_running = 0; - m_irmb_timer = machine().device("irmb_timer"); /* set an initial timer to go off on scanline 0 */ machine().scheduler().timer_set(m_screen->time_until_pos(0), timer_expired_delegate(FUNC(irobot_state::scanline_callback),this)); - irobot_rom_banksel_w(m_maincpu->space(AS_PROGRAM),0,0); - irobot_out0_w(m_maincpu->space(AS_PROGRAM),0,0); - m_combase = m_comRAM[0]; - m_combase_mb = m_comRAM[1]; + address_space &space = machine().dummy_space(); + irobot_rom_banksel_w(space, 0, 0); + irobot_out0_w(space, 0, 0); + irobot_statwr_w(space, 0, 0); m_outx = 0; } -- cgit v1.2.3 From 200d03c46a05bf83f2f770974b24c76cd88274f3 Mon Sep 17 00:00:00 2001 From: Lord-Nightmare Date: Tue, 12 Jun 2018 00:36:57 -0400 Subject: a2echoii: replaced read flag, write flag and write latch implementation with one which matches actual hardware tracing [Lord Nightmare, Tony Diaz] --- src/devices/bus/a2bus/a2echoii.cpp | 132 ++++++++++++++++++++++++------------- src/devices/bus/a2bus/a2echoii.h | 12 ++-- 2 files changed, 93 insertions(+), 51 deletions(-) diff --git a/src/devices/bus/a2bus/a2echoii.cpp b/src/devices/bus/a2bus/a2echoii.cpp index 89ef73ac00e..6e300c39c55 100644 --- a/src/devices/bus/a2bus/a2echoii.cpp +++ b/src/devices/bus/a2bus/a2echoii.cpp @@ -4,9 +4,21 @@ a2echoii.c - Implementation of the Street Electronics Echo II speech card - Ready logic traced by Jonathan Gevaryahu + Implementation of the Street Electronics Echo II and EchoIIb speech card + Ready logic traced by Lord Nightmare and Tony Diaz + Notes from Tony Diaz: + Capacitor values: + C1,C2 - .47nF C3,C4 - 16v 10uF C5 - 16v 100uF C7,C7,C8 .1uF + + Pictures: + Original EchoII card, S/N 789 with ?original? TMS5200: http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Speech/Street%20Echo%20II/Photos/SEC%20-%20Echo%20II%20rev.A%20-%20Front.jpg + Original EchoII card, S/N 103, with a much later 1987 non-original TSP5220C installed: https://upload.wikimedia.org/wikipedia/en/e/ee/Echo2Card.jpg + Later EchoII without the VSM socket footprints, and with the 'FREQ' potentiometer: http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Speech/Street%20Echo%20II/Photos/Echo%20II%20-%20Front.jpg + EchoIIb, similar to later EchoII but without the 'FREQ' potentiometer and with the 74LS92 clock divider: http://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Interface%20Cards/Speech/Street%20Echo%20II/Photos/Echo%20IIb%20-%20Front.jpg + + TODO: separate cards for the EchoII(both the freq adjustable and the older non-adjustable version, and maybe a tms5200 version?), EchoIIb (tms5220c) + TODO: echo+ is in a2mockinboard.cpp and really should be a sub-device inherited from here, to reduce duplicated code. *********************************************************************/ #include "emu.h" @@ -14,6 +26,11 @@ #include "sound/tms5220.h" #include "speaker.h" +#undef DEBUG_ECHOII_READYQ +#undef DEBUG_ECHOII_READ +#undef DEBUG_ECHOII_WRITE + + /*************************************************************************** PARAMETERS ***************************************************************************/ @@ -36,8 +53,13 @@ DEFINE_DEVICE_TYPE(A2BUS_ECHOII, a2bus_echoii_device, "a2echoii", "Street Electr MACHINE_CONFIG_START(a2bus_echoii_device::device_add_mconfig) SPEAKER(config, "echoii").front_center(); - MCFG_DEVICE_ADD(TMS_TAG, TMS5220, 640000) // Note the Echo II card has a "FREQ" potentiometer which can be used to adjust the tms5220's clock frequency; 640khz is the '8khz' value according to the tms5220 datasheet - MCFG_TMS52XX_READYQ_HANDLER(WRITELINE(*this, a2bus_echoii_device, ready_w)) + MCFG_DEVICE_ADD(TMS_TAG, TMS5220, 640000) // Note the Echo II card has an R/C circuit (and sometimes a 'FREQ' potentiometer) to control the tms5220[c]'s clock frequency; 640khz is the nominal '8khz' value according to the TMS5220 datasheet. + // The EchoIIb card however has a 74LS92 which divides the apple2's Q3 ((14.318/7)MHz asymmetrical) clock by 6 to produce a 681.809khz/2 clock, which doesn't actually make sense, since the tms5220, unless it has a mask option (mentioned on the datasheet) to use a ceramic resonator instead of an r/c circuit, needs a clock at twice that speed. Could it be that the EchoIIb uses tsp5220C chips with a special mask option? + // Some Old EchoII cards shipped with TMS5200(really?), some with TMS5220. Many (most?) were retrofitted with a TMS5220 or TMS5220C later. + // The later VSM-socket-less EchoII shipped with a TMS5220. + // The EchoIIb and later cards shipped with a TMS5220C + //MCFG_TMS52XX_IRQ_HANDLER(WRITELINE(*this, a2bus_echoii_device, tms_irq_callback)) + MCFG_TMS52XX_READYQ_HANDLER(WRITELINE(*this, a2bus_echoii_device, tms_readyq_callback)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "echoii", 1.0) MACHINE_CONFIG_END @@ -63,65 +85,87 @@ a2bus_echoii_device::a2bus_echoii_device(const machine_config &mconfig, const ch void a2bus_echoii_device::device_start() { - m_timer = timer_alloc(0); - m_timer->adjust(attotime::never); - - save_item(NAME(m_latch)); - save_item(NAME(m_ready)); - save_item(NAME(m_byte_in_latch)); + m_writelatch_data = 0xff; + m_readlatch_flag = true; // /RESET presets this latch + m_writelatch_flag = true; // not initialized but we need to set it somewhere. + save_item(NAME(m_writelatch_data)); + save_item(NAME(m_readlatch_flag)); + save_item(NAME(m_writelatch_flag)); } void a2bus_echoii_device::device_reset() { - m_byte_in_latch = false; - m_ready = 0; - m_latch = 0; + m_readlatch_flag = true; // /RESET presets this latch + m_tms->rsq_w(m_readlatch_flag); // update the rsq pin } -uint8_t a2bus_echoii_device::read_c0nx(uint8_t offset) +/* +WRITE_LINE_MEMBER(a2bus_echoii_device::tms_irq_callback) { - switch (offset) - { - case 0: - return 0x1f | m_tms->read_status(); - } - - return 0; + update_irq_to_maincpu(); } +*/ -void a2bus_echoii_device::write_c0nx(uint8_t offset, uint8_t data) +WRITE_LINE_MEMBER(a2bus_echoii_device::tms_readyq_callback) { - switch (offset) + if (state == ASSERT_LINE) { - case 0: - m_latch = data; - if (!m_ready) - m_tms->write_data(m_latch); - else - m_byte_in_latch = true; - break; +#ifdef DEBUG_ECHOII_READYQ + logerror("ReadyQ callback called with state of %d! NOT READY\n", state); +#endif + // the rising edge of /READY doesn't really do anything. + } + else + { +#ifdef DEBUG_ECHOII_READYQ + logerror("ReadyQ callback called with state of %d! READY\n", state); +#endif + m_writelatch_flag = true; + m_tms->wsq_w(m_writelatch_flag); } } -bool a2bus_echoii_device::take_c800() +uint8_t a2bus_echoii_device::read_c0nx(uint8_t offset) { - return false; + // offset is completely ignored, the same register maps to the entire space. + uint8_t retval = 0xff; // pull-up resistor pack on the tms5220 bus + + // upon the falling edge of /DEVREAD, the active part of the read... + if (m_readlatch_flag == false) // /RS was low, so we need to return a value from the tms5220 + { + retval = 0x1f | m_tms->status_r(machine().dummy_space(), 0, 0xff); +#ifdef DEBUG_ECHOII_READ + logerror("Returning status of speech chip, which is %02x\n", retval); + } + else + { + logerror("chip status read on odd cycle, returning pull-up value of %02x\n", retval); +#endif + } + + // upon the rising edge of /DEVREAD, i.e. after the read has finished (so no updating retval after this) + m_readlatch_flag = (!m_readlatch_flag); // latch inverts itself upon each read... + m_tms->rsq_w(m_readlatch_flag); // update the /RS pin + return retval; } -void a2bus_echoii_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +void a2bus_echoii_device::write_c0nx(uint8_t offset, uint8_t data) { - m_tms->write_data(m_latch); - m_byte_in_latch = false; - m_timer->adjust(attotime::never); + // offset is completely ignored, the same register maps to the entire space. + if (m_writelatch_flag == false) + logerror("Data in echoii latch (%02x) was clobbered with new write (%02x) before being read by speech chip!\n", m_writelatch_data, data); +#ifdef DEBUG_ECHOII_WRITE + else + logerror("Data written to latch of %02x\n", data); +#endif + m_writelatch_data = data; + + m_writelatch_flag = false; // /DEVWRITE clears the latch on its falling edge + m_tms->wsq_w(m_writelatch_flag); + m_tms->data_w(machine().dummy_space(), 0, m_writelatch_data); } -WRITE_LINE_MEMBER( a2bus_echoii_device::ready_w ) +bool a2bus_echoii_device::take_c800() { - // if /Ready falls, write the byte in the latch if there is one - if ((m_ready) && (!state) && (m_byte_in_latch)) - { - m_timer->adjust(attotime::zero); - } - - m_ready = state; + return false; } diff --git a/src/devices/bus/a2bus/a2echoii.h b/src/devices/bus/a2bus/a2echoii.h index 7e304e5b5b9..7cb1c401550 100644 --- a/src/devices/bus/a2bus/a2echoii.h +++ b/src/devices/bus/a2bus/a2echoii.h @@ -36,20 +36,18 @@ protected: virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; // overrides of standard a2bus slot functions virtual uint8_t read_c0nx(uint8_t offset) override; virtual void write_c0nx(uint8_t offset, uint8_t data) override; virtual bool take_c800() override; - DECLARE_WRITE_LINE_MEMBER( ready_w ); - private: - uint8_t m_latch; - int m_ready; - emu_timer *m_timer; - bool m_byte_in_latch; + //DECLARE_WRITE_LINE_MEMBER(tms_irq_callback); + DECLARE_WRITE_LINE_MEMBER(tms_readyq_callback); + uint8_t m_writelatch_data; // 74ls373 latch + bool m_readlatch_flag; // 74c74 1st half + bool m_writelatch_flag; // 74c74 2nd half }; // device type definition -- cgit v1.2.3 From f3e3e2e5e5534a53aab85e82c5487edceb6069f4 Mon Sep 17 00:00:00 2001 From: braintro Date: Mon, 11 Jun 2018 23:40:21 -0500 Subject: asteroid.cpp: Document Asteroid Deluxe Revision 3 change and correct Difficulty dipswitch. [Brian Troha] --- src/mame/drivers/asteroid.cpp | 66 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/src/mame/drivers/asteroid.cpp b/src/mame/drivers/asteroid.cpp index 8b1c287eb04..9593a878aa4 100644 --- a/src/mame/drivers/asteroid.cpp +++ b/src/mame/drivers/asteroid.cpp @@ -50,9 +50,69 @@ For kit 08-0303008 (from rev 02) swap the following: There is not a rev 03 known or dumped. An Asteroids rev 03 is not mentioned in any known Atari docs found to date. + +**************************************************************************** + +For revision 3 of Asteroids Deluxe: + +U.S Update +New Program with Easier Game Play for Asteroids Deluxe + +The read-only memories (ROMs) in this kit contain a new program that changes the Asteroids Deluxe +game play. To attract new players, the game play is now operator-adjustable to be either easy for +approximately the first 30,000 points or hard through-out the game. + +The technical manual describes the game play correctly if the game PCB option switch at R5 is set +to "hard". If you set the switch to "easy", then the following game-play changes happen: + +* FOUR large asteroids begin the game. The second wave of asteroids begins with FIVE, and the + susbequent waves start with SIX through NINE large asteroids. In addition, the asteriods move + much more slowly across the screen. (If the option switch is set to hard, the waves begin with + SIX to NINE large asteriods.) +* The large ships ("death stars") when shot will break up into three slowly-moving diamonds. (If + the option switch is set to hard, diamonds would immediatly begin chasing the player's + spaceship at high speed.) + +After installing these five ROMs, we recommend you set your game to easy game play. To do so, refer +to the figure that follows. You should note also that the self-test now deisplays and addition 0 or 1 +to represnt your game difficulty selection. + + +ROM kit for Asteroids Deluxe Game PCB Assembly A036471-03 and -04 F + +Part Number PCB Location +-------------------------------- +036430-02 D1 +036431-02 E/F1 +036432-02 H1 +036433-03 J1 +036800-02 R2 + +*********************** + +Self-Test screen shows: + + 0000 (left to right: Coin Bonus Adder, Left Mech Mutiplier, Right Mech Multiplier & Game Price) + + 01000 (left to right: Game Language, Ships at Game Start, Minimum Plays, Difficulty, Bonus Ship) + + ^^ (Graphic display of the number of ships per game [up to 7]) + + 10000 (Point score at which a bonus ship is granted, blank is no bonus ship) + + +NOTE: Previous program versions, for the second line would only show 4 digits. The 6th switch has + a currently unknown effect in the game. However, on the Minimum Number of Plays display (on the + Self-Test screen) changes the values shown from 0 for a 1-Play Minimum to show a 2 and from + 1 for a 2-Play Minimum to show a 3. Known documentation for ealier game versions state the 6th + switch is "Unused" + +**************************************************************************** + Asteroids-deluxe state-prom added by HIGHWAYMAN. The prom pcb location is:C8 and is 256x4 (i need to update the dump, this one is read in 8bit-mode) + **************************************************************************** Asteroids Memory Map (preliminary) @@ -486,9 +546,9 @@ static INPUT_PORTS_START( astdelux ) PORT_DIPNAME( 0x10, 0x00, "Minimum Plays" ) PORT_DIPLOCATION("R5:5") PORT_DIPSETTING ( 0x00, "1" ) PORT_DIPSETTING ( 0x10, "2" ) - PORT_DIPNAME( 0x20, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("R5:6") /* Listed as "Unused" */ - PORT_DIPSETTING ( 0x00, DEF_STR( Hard ) ) - PORT_DIPSETTING ( 0x20, DEF_STR( Easy ) ) + PORT_DIPNAME( 0x20, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("R5:6") /* Listed as "Unused" for pre Revision 03 versions */ + PORT_DIPSETTING ( 0x20, DEF_STR( Hard ) ) + PORT_DIPSETTING ( 0x00, DEF_STR( Easy ) ) PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("R5:7,8") PORT_DIPSETTING ( 0x00, "10000" ) PORT_DIPSETTING ( 0x40, "12000" ) -- cgit v1.2.3 From f79dfb796af3d97e8595af196feb3fe03ec82fd2 Mon Sep 17 00:00:00 2001 From: braintro Date: Mon, 11 Jun 2018 23:49:18 -0500 Subject: asteroid.cpp: Spelling (nw) --- src/mame/drivers/asteroid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mame/drivers/asteroid.cpp b/src/mame/drivers/asteroid.cpp index 9593a878aa4..520ffa71847 100644 --- a/src/mame/drivers/asteroid.cpp +++ b/src/mame/drivers/asteroid.cpp @@ -75,7 +75,7 @@ to "hard". If you set the switch to "easy", then the following game-play changes After installing these five ROMs, we recommend you set your game to easy game play. To do so, refer to the figure that follows. You should note also that the self-test now deisplays and addition 0 or 1 -to represnt your game difficulty selection. +to represent your game difficulty selection. ROM kit for Asteroids Deluxe Game PCB Assembly A036471-03 and -04 F -- cgit v1.2.3 From 62fc2e8f068a67b84b324b1c2e9b55791850247e Mon Sep 17 00:00:00 2001 From: Lord-Nightmare Date: Tue, 12 Jun 2018 00:42:59 -0400 Subject: tms5220: fix the READYQ callback to poll the fifo state with a timer loop instead of always asserting the /ready via callback even if there is no more room in the FIFO, to match hardware. Fix the speak vsm mode to assume that the ADDR/DATA pin floats high if no VSM is attached, so that the speech chip doesn't get permanently stuck speaking silence if a spurious SPEAK VSM command is sent to it. Fix some race conditions with the INTQ callback and status flags not being updated before the callback is called. General cleanup and bool-ification of boolean variables. [Lord Nightmare] --- src/devices/sound/tms5220.cpp | 485 +++++++++++++++++++++--------------------- src/devices/sound/tms5220.h | 78 +++---- 2 files changed, 288 insertions(+), 275 deletions(-) diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index b0cf48a271a..d80d4a88f20 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -198,6 +198,10 @@ Interpolation is inhibited (i.e. interpolation at IP frames will not happen ****Documentation of chip commands:*** + 76543210 (these are in logical 7 thru 0 order with MSB (7) first; TI calls + these bits by the opposite order, D0 thru D7, on the datasheet, + with D0 being the MSB) + x0x0xbcc: on 5200/5220: NOP (does nothing) on 5220C and CD2501ECD: Select frame length by cc, and b selects whether every frame is preceded by 2 bits to select the frame @@ -321,9 +325,10 @@ this), mostly on later pinballs with LPC speech) module (6511 based), IBM PS/2 Speech adapter (parallel port connection device), PES Speech adapter (serial port connection) -Street electronics had a later 1989-era ECHO appleII card which is TSP50c0x/1x -MCU based speech and not tms5xxx based (though it is likely emulating the tms5220 -in MCU code). Look for a 16-pin chip at U6 labeled "ECHO-3 SN". +Street electronics had two later 1988-1990-era ECHO appleII cards which are +TSP50c0x/1x MCU based speech and not tms52xx based (though it is likely +emulating the tms5220 in MCU code). Look for a 16-pin chip at U6 labeled +"ECHO-2 SN" or "ECHO-3 SN". ***********************************************************************************************/ @@ -382,6 +387,8 @@ static int16_t clip_analog(int16_t cliptemp); // above dumps info if a frame ran out of data #undef DEBUG_COMMAND_DUMP // above dumps all non-speech-data command writes +#undef DEBUG_COMMAND_VERBOSE +// above dumps decoded info about command writes #undef DEBUG_PIN_READS // above spams the errorlog with i/o ready messages whenever the ready or irq pin is read #undef DEBUG_GENERATION @@ -393,9 +400,10 @@ static int16_t clip_analog(int16_t cliptemp); #undef DEBUG_CLIP // above dumps info to stderr whenever the analog clip hardware is (or would be) clipping the signal. #undef DEBUG_IO_READY -// above debugs the io ready callback +// above debugs the io ready callback timer #undef DEBUG_RS_WS // above debugs the tms5220_data_r and data_w access methods which actually respect rs and ws +// TODO: switch the comments to be above the defines instead of below them #define MAX_SAMPLE_CHUNK 512 @@ -440,12 +448,32 @@ static const uint8_t reload_table[4] = { 0, 2, 4, 6 }; //sample count reload for void tms5220_device::register_for_save_states() { + // for sanity purposes these variables should be in the same order as in tms5220.h! + + // 5110 specific stuff + save_item(NAME(m_PDC)); + save_item(NAME(m_CTL_pins)); + save_item(NAME(m_state)); + + // new VSM stuff + save_item(NAME(m_address)); + save_item(NAME(m_next_is_address)); + save_item(NAME(m_schedule_dummy_read)); + save_item(NAME(m_addr_bit)); + save_item(NAME(m_CTL_buffer)); + + // old VSM stuff + save_item(NAME(m_read_byte_register)); + save_item(NAME(m_RDB_flag)); + + // FIFO save_item(NAME(m_fifo)); save_item(NAME(m_fifo_head)); save_item(NAME(m_fifo_tail)); save_item(NAME(m_fifo_count)); save_item(NAME(m_fifo_bits_taken)); + // global status bits (booleans) save_item(NAME(m_previous_TALK_STATUS)); save_item(NAME(m_SPEN)); save_item(NAME(m_DDIS)); @@ -456,6 +484,7 @@ void tms5220_device::register_for_save_states() save_item(NAME(m_irq_pin)); save_item(NAME(m_ready_pin)); + // current and previous frames save_item(NAME(m_OLDE)); save_item(NAME(m_OLDP)); @@ -492,65 +521,59 @@ void tms5220_device::register_for_save_states() save_item(NAME(m_RNG)); save_item(NAME(m_excitation_data)); - save_item(NAME(m_schedule_dummy_read)); - save_item(NAME(m_data_register)); - save_item(NAME(m_RDB_flag)); save_item(NAME(m_digital_select)); save_item(NAME(m_io_ready)); + // "proper" rs+ws emulation save_item(NAME(m_true_timing)); save_item(NAME(m_rs_ws)); save_item(NAME(m_read_latch)); save_item(NAME(m_write_latch)); - - // 5110 specific stuff - save_item(NAME(m_PDC)); - save_item(NAME(m_CTL_pins)); - save_item(NAME(m_state)); - save_item(NAME(m_address)); - save_item(NAME(m_next_is_address)); - save_item(NAME(m_addr_bit)); - save_item(NAME(m_CTL_buffer)); } /********************************************************************************************** - printbits helper function: takes a long int input and prints the resulting bits to stderr + printbits helper function: takes an input and prints the resulting bits to a string buffer, passed to it using snprintf. ***********************************************************************************************/ #ifdef DEBUG_PARSE_FRAME_DUMP_BIN -static void printbits(long data, int num) +int tms5220_device::printbits(char *buffer, int count, unsigned int data, int num) { + int retval = 0; int i; for (i=(num-1); i>=0; i--) - logerror("%0ld", (data>>i)&1); + { + retval += snprintf(buffer+retval, count-retval, "%0d", (data>>i)&1); + } + retval += snprintf(buffer+retval, count-retval, " "); + return retval; } #endif #ifdef DEBUG_PARSE_FRAME_DUMP_HEX -static void printbits(long data, int num) +int tms5220_device::printbits(char *buffer, int count, unsigned int data, int num) { + int retval = 0; switch((num-1)&0xFC) { case 0: - logerror("%0lx", data); + retval = snprintf(buffer, count, "%01x ", data); break; case 4: - logerror("%02lx", data); + retval = snprintf(buffer, count, "%02x ", data); break; case 8: - logerror("%03lx", data); + retval = snprintf(buffer, count, "%03x ", data); break; case 12: - logerror("%04lx", data); - break; default: - logerror("%04lx", data); + retval = snprintf(buffer, count, "%04x ", data); break; } + return retval; } #endif @@ -611,10 +634,9 @@ uint8_t tms5220_device::new_int_read() tms5220_device::data_write -- handle a write to the TMS5220 ***********************************************************************************************/ - void tms5220_device::data_write(int data) { - int old_buffer_low = m_buffer_low; + bool old_buffer_low = m_buffer_low; #ifdef DEBUG_DUMP_INPUT_DATA fprintf(stdout, "%c",data); #endif @@ -631,24 +653,24 @@ void tms5220_device::data_write(int data) #endif update_fifo_status_and_ints(); // if we just unset buffer low with that last write, and SPEN *was* zero (see circuit 251, sheet 12) - if ((m_SPEN == 0) && ((old_buffer_low == 1) && (m_buffer_low == 0))) // MUST HAVE EDGE DETECT + if ((!m_SPEN) && ((old_buffer_low) && (!m_buffer_low))) // MUST HAVE EDGE DETECT { int i; #ifdef DEBUG_FIFO logerror("data_write triggered SPEN to go active!\n"); #endif // ...then we now have enough bytes to start talking; set zpar and clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) - m_zpar = 1; - m_uv_zpar = 1; // zero k4-k10 as well - m_OLDE = 1; // 'silence/zpar' frames are zero energy - m_OLDP = 1; // 'silence/zpar' frames are zero pitch + m_zpar = true; + m_uv_zpar = true; // zero k4-k10 as well + m_OLDE = true; // 'silence/zpar' frames are zero energy + m_OLDP = true; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = 1; // zero all the old parameters - m_old_uv_zpar = 1; // zero old k4-k10 as well + m_old_zpar = true; // zero all the old parameters + m_old_uv_zpar = true; // zero old k4-k10 as well #endif - m_SPEN = 1; + m_SPEN = true; #ifdef FAST_START_HACK - m_TALK = 1; + m_TALK = true; #endif m_new_frame_energy_idx = 0; m_new_frame_pitch_idx = 0; @@ -698,7 +720,6 @@ void tms5220_device::data_write(int data) Speak External command execution is terminated. ***********************************************************************************************/ - void tms5220_device::update_fifo_status_and_ints() { /* update 52xx fifo flags and set ints if needed */ @@ -712,11 +733,13 @@ void tms5220_device::update_fifo_status_and_ints() { // generate an interrupt if necessary; if /BL was inactive and is now active, set int. if (!m_buffer_low) + { + m_buffer_low = true; set_interrupt_state(1); - m_buffer_low = 1; + } } else - m_buffer_low = 0; + m_buffer_low = false; /* BE is set if neither byte 15 nor 14 of the fifo are in use; this translates to having fifo_count equal to exactly 0 @@ -725,23 +748,25 @@ void tms5220_device::update_fifo_status_and_ints() { // generate an interrupt if necessary; if /BE was inactive and is now active, set int. if (!m_buffer_empty) + { + m_buffer_empty = true; set_interrupt_state(1); - m_buffer_empty = 1; + } if (m_DDIS) - m_TALK = m_SPEN = 0; // /BE being active clears the TALK status via TCON, which in turn clears SPEN, but ONLY if m_DDIS is set! See patent page 16, gate 232b + m_TALK = m_SPEN = false; // /BE being active clears the TALK status via TCON, which in turn clears SPEN, but ONLY if m_DDIS is set! See patent page 16, gate 232b } else - m_buffer_empty = 0; + m_buffer_empty = false; // generate an interrupt if /TS was active, and is now inactive. // also, in this case, regardless if DDIS was set, unset it. - if ((m_previous_TALK_STATUS == 1) && (TALK_STATUS() == 0)) + if (m_previous_TALK_STATUS && (!TALK_STATUS())) { #ifdef VERBOSE logerror("Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); #endif set_interrupt_state(1); - m_DDIS = 0; + m_DDIS = false; } m_previous_TALK_STATUS = TALK_STATUS(); @@ -752,7 +777,6 @@ void tms5220_device::update_fifo_status_and_ints() extract_bits -- extract a specific number of bits from the current input stream (FIFO or VSM) ***********************************************************************************************/ - int tms5220_device::extract_bits(int count) { int val = 0; @@ -781,6 +805,8 @@ int tms5220_device::extract_bits(int count) // extract from VSM (speech ROM) if (m_speechrom) val = m_speechrom->read(count); + else + val = (1<> m_fifo_bits_taken) & 0xf; - if (val == 0) - /* 0 -> silence frame: we will only read 4 bits, and we will - * therefore need to read another frame before the FIFO is not - * full any more */ - answer += m_subc_reload?200:304; - /* 15 -> stop frame, we will only read 4 bits, but the FIFO will - * we cleared; otherwise, we need to parse the repeat flag (1 bit) - * and the pitch (6 bits), so everything will be OK. */ - } - } - - return answer; + return m_io_ready; } - /********************************************************************************************** tms5220_int_read -- returns the interrupt state of the TMS5220 ***********************************************************************************************/ - -int tms5220_device::int_read() +bool tms5220_device::int_read() { #ifdef DEBUG_PIN_READS logerror("int_read: irq pin read, state is %d\n", m_irq_pin); @@ -906,16 +889,14 @@ int tms5220_device::int_read() return m_irq_pin; } - /********************************************************************************************** tms5220_process -- fill the buffer with a specific number of samples ***********************************************************************************************/ - void tms5220_device::process(int16_t *buffer, unsigned int size) { - int buf_count=0; + int buf_count = 0; int i, bitout; int32_t this_sample; @@ -955,7 +936,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */ if (NEW_FRAME_STOP_FLAG()) { - m_TALK = m_SPEN = 0; + m_TALK = m_SPEN = false; update_fifo_status_and_ints(); // probably not necessary... } @@ -966,20 +947,20 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) * Old frame was unvoiced, new is voiced * Old frame was unvoiced, new frame is silence/zero energy (non-existent on tms51xx rev D and F (present and working on tms52xx, present but buggy on tms51xx rev A and B)) */ - if ( ((OLD_FRAME_UNVOICED_FLAG() == 0) && NEW_FRAME_UNVOICED_FLAG()) - || ((OLD_FRAME_UNVOICED_FLAG() == 1) && !NEW_FRAME_UNVOICED_FLAG()) - || ((OLD_FRAME_SILENCE_FLAG() == 1) && !NEW_FRAME_SILENCE_FLAG()) - //|| ((m_inhibit == 1) && (OLD_FRAME_UNVOICED_FLAG() == 1) && NEW_FRAME_SILENCE_FLAG()) ) //TMS51xx INTERP BUG1 - || ((OLD_FRAME_UNVOICED_FLAG() == 1) && NEW_FRAME_SILENCE_FLAG()) ) - m_inhibit = 1; + if ( (!OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_UNVOICED_FLAG()) + || (OLD_FRAME_UNVOICED_FLAG() && !NEW_FRAME_UNVOICED_FLAG()) + || (OLD_FRAME_SILENCE_FLAG() && !NEW_FRAME_SILENCE_FLAG()) + //|| ((m_inhibit == true) && OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_SILENCE_FLAG()) ) //TMS51xx INTERP BUG1 + || (OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_SILENCE_FLAG()) ) + m_inhibit = true; else // normal frame, normal interpolation - m_inhibit = 0; + m_inhibit = false; #ifdef DEBUG_GENERATION /* Debug info for current parsed frame */ logerror( "OLDE: %d; NEWE: %d; OLDP: %d; NEWP: %d ", OLD_FRAME_SILENCE_FLAG(), NEW_FRAME_SILENCE_FLAG(), OLD_FRAME_UNVOICED_FLAG(), NEW_FRAME_UNVOICED_FLAG()); logerror("Processing new frame: "); - if (m_inhibit == 0) + if (m_inhibit == false) logerror( "Normal Frame\n"); else logerror("Interpolation Inhibited\n"); @@ -1003,7 +984,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } else // Not a new frame, just interpolate the existing frame. { - int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value + bool inhibit_state = ((m_inhibit == true) && (m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value #ifdef TMS5220_PERFECT_INTERPOLATION_HACK int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW @@ -1024,7 +1005,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } else // we're done, play this frame for 1/8 frame. { - if (m_subcycle == 2) m_pitch_zero = 0; // this reset happens around the second subcycle during IP=0 + if (m_subcycle == 2) m_pitch_zero = false; // this reset happens around the second subcycle during IP=0 m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)); m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)); for (i = 0; i < m_coeff->num_k; i++) @@ -1056,7 +1037,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } // calculate the output - if (OLD_FRAME_UNVOICED_FLAG() == 1) + if (OLD_FRAME_UNVOICED_FLAG() == true) { // generate unvoiced samples here if (m_RNG & 1) @@ -1138,13 +1119,13 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) * According to testing the pitch zeroing lasts approximately 2 samples. * We set the zeroing latch here, and unset it on PC=1 in the generator. */ - if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1; + if ((m_IP == 7)&&(m_inhibit == true)) m_pitch_zero = true; if (m_IP == 7) // RESETL4 { // Latch OLDE and OLDP - //if (OLD_FRAME_SILENCE_FLAG()) m_uv_zpar = 0; // TMS51xx INTERP BUG2 - OLD_FRAME_SILENCE_FLAG() = NEW_FRAME_SILENCE_FLAG() ? 1 : 0; // m_OLDE - OLD_FRAME_UNVOICED_FLAG() = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; // m_OLDP + //if (OLD_FRAME_SILENCE_FLAG()) m_uv_zpar = false; // TMS51xx INTERP BUG2 + OLD_FRAME_SILENCE_FLAG() = NEW_FRAME_SILENCE_FLAG() ? true : false; // m_OLDE + OLD_FRAME_UNVOICED_FLAG() = NEW_FRAME_UNVOICED_FLAG() ? true : false; // m_OLDP /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */ #ifdef DEBUG_GENERATION logerror("RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); @@ -1155,7 +1136,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) #endif m_TALKD = m_TALK; // TALKD is latched from TALK update_fifo_status_and_ints(); // to trigger an interrupt if TALK_STATUS has changed - if ((!m_TALK) && m_SPEN) m_TALK = 1; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). + if ((!m_TALK) && m_SPEN) m_TALK = true; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). #ifdef DEBUG_GENERATION logerror("RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); #endif @@ -1171,7 +1152,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) m_PC++; } m_pitch_count++; - if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0; + if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == true)) m_pitch_count = 0; m_pitch_count &= 0x1FF; } else // m_TALKD == 0 @@ -1183,7 +1164,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) { m_TALKD = m_TALK; // TALKD is latched from TALK update_fifo_status_and_ints(); // probably not necessary - if ((!m_TALK) && m_SPEN) m_TALK = 1; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). + if ((!m_TALK) && m_SPEN) m_TALK = true; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). } m_subcycle = m_subc_reload; m_PC = 0; @@ -1207,7 +1188,6 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) clip_analog -- clips the 14 bit return value from the lattice filter to its final 10 bit value (-512 to 511), and upshifts/range extends this to 16 bits ***********************************************************************************************/ - static int16_t clip_analog(int16_t cliptemp) { /* clipping, just like the patent shows: @@ -1239,7 +1219,6 @@ static int16_t clip_analog(int16_t cliptemp) #endif } - /********************************************************************************************** matrix_multiply -- does the proper multiply and shift @@ -1272,7 +1251,6 @@ static int32_t matrix_multiply(int32_t a, int32_t b) resulting sample. ***********************************************************************************************/ - int32_t tms5220_device::lattice_filter() { // Lattice filter here @@ -1339,13 +1317,11 @@ int32_t tms5220_device::lattice_filter() return m_u[0]; } - /********************************************************************************************** process_command -- extract a byte from the FIFO and interpret it as a command ***********************************************************************************************/ - void tms5220_device::process_command(unsigned char cmd) { int i; @@ -1356,6 +1332,9 @@ void tms5220_device::process_command(unsigned char cmd) switch (cmd & 0x70) { case 0x10 : /* read byte */ +#ifdef DEBUG_COMMAND_VERBOSE + logerror("Read Byte command received\n"); +#endif if (TALK_STATUS() == 0) /* TALKST must be clear for RDBY */ { if (m_schedule_dummy_read) @@ -1365,23 +1344,34 @@ void tms5220_device::process_command(unsigned char cmd) m_speechrom->read(1); } if (m_speechrom) - m_data_register = m_speechrom->read(8); /* read one byte from speech ROM... */ + m_read_byte_register = m_speechrom->read(8); /* read one byte from speech ROM... */ m_RDB_flag = true; } +#ifdef DEBUG_COMMAND_VERBOSE + else + logerror("Read Byte command received during TALK state, ignoring!\n"); +#endif break; case 0x00: case 0x20: /* set rate (tms5220c and cd2501ecd only), otherwise NOP */ if (TMS5220_HAS_RATE_CONTROL) +#ifdef DEBUG_COMMAND_VERBOSE { + logerror("Set Rate (or NOP) command received\n"); +#endif m_c_variant_rate = cmd&0x0F; +#ifdef DEBUG_COMMAND_VERBOSE } + else + logerror("NOP command received\n"); +#endif break; case 0x30 : /* read and branch */ if (TALK_STATUS() == 0) /* TALKST must be clear for RB */ { -#ifdef VERBOSE - logerror("read and branch command received\n"); +#ifdef DEBUG_COMMAND_VERBOSE + logerror("Read and Branch command received\n"); #endif m_RDB_flag = false; if (m_speechrom) @@ -1390,6 +1380,9 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x40 : /* load address */ +#ifdef DEBUG_COMMAND_VERBOSE + logerror("Load Address command received\n"); +#endif if (TALK_STATUS() == 0) /* TALKST must be clear for LA */ { /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. @@ -1398,9 +1391,16 @@ void tms5220_device::process_command(unsigned char cmd) m_speechrom->load_address(cmd & 0x0f); m_schedule_dummy_read = true; } +#ifdef DEBUG_COMMAND_VERBOSE + else + logerror("Load Address command received during TALK state, ignoring!\n"); +#endif break; case 0x50 : /* speak */ +#ifdef DEBUG_COMMAND_VERBOSE + logerror("Speak (VSM) command received\n"); +#endif if (m_schedule_dummy_read) { m_schedule_dummy_read = false; @@ -1411,14 +1411,14 @@ void tms5220_device::process_command(unsigned char cmd) #ifdef FAST_START_HACK m_TALK = 1; #endif - m_DDIS = 0; - m_zpar = 1; // zero all the parameters - m_uv_zpar = 1; // zero k4-k10 as well - m_OLDE = 1; // 'silence/zpar' frames are zero energy - m_OLDP = 1; // 'silence/zpar' frames are zero pitch + m_DDIS = false; // speak using VSM + m_zpar = true; // zero all the parameters + m_uv_zpar = true; // zero k4-k10 as well + m_OLDE = true; // 'silence/zpar' frames are zero energy + m_OLDP = true; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = 1; // zero all the old parameters - m_old_uv_zpar = 1; // zero old k4-k10 as well + m_old_zpar = true; // zero all the old parameters + m_old_uv_zpar = true; // zero old k4-k10 as well #endif // following is semi-hack but matches idle state observed on chip m_new_frame_energy_idx = 0; @@ -1432,17 +1432,21 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x60 : /* speak external */ - // SPKEXT going active activates SPKEE which clears the fifo +#ifdef DEBUG_COMMAND_VERBOSE + logerror("Speak External command received\n"); +#endif + // SPKEXT going active asserts /SPKEE for 2 clocks, which clears the FIFO and its counters + memset(m_fifo, 0, sizeof(m_fifo[0])*FIFO_SIZE); m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; - // SPEN is enabled when the fifo passes half full (falling edge of BL signal) - m_DDIS = 1; - m_zpar = 1; // zero all the parameters - m_uv_zpar = 1; // zero k4-k10 as well - m_OLDE = 1; // 'silence/zpar' frames are zero energy - m_OLDP = 1; // 'silence/zpar' frames are zero pitch + // SPEN is enabled when the FIFO passes half full (falling edge of BL signal) + m_DDIS = true; // speak using FIFO + m_zpar = true; // zero all the parameters + m_uv_zpar = true; // zero k4-k10 as well + m_OLDE = true; // 'silence/zpar' frames are zero energy + m_OLDP = true; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = 1; // zero all the old parameters - m_old_uv_zpar = 1; // zero old k4-k10 as well + m_old_zpar = true; // zero all the old parameters + m_old_uv_zpar = true; // zero old k4-k10 as well #endif // following is semi-hack but matches idle state observed on chip m_new_frame_energy_idx = 0; @@ -1457,6 +1461,9 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x70 : /* reset */ +#ifdef DEBUG_COMMAND_VERBOSE + logerror("Reset command received\n"); +#endif if (m_schedule_dummy_read) { m_schedule_dummy_read = false; @@ -1476,9 +1483,17 @@ void tms5220_device::process_command(unsigned char cmd) parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer ******************************************************************************************/ - void tms5220_device::parse_frame() { +#ifdef DEBUG_PARSE_FRAME_DUMP + char p_buffer[64] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + uint8_t p_buffer_count = 0; +#endif int i, rep_flag; #ifdef TMS5220_PERFECT_INTERPOLATION_HACK m_old_uv_zpar = m_uv_zpar; @@ -1496,8 +1511,7 @@ void tms5220_device::parse_frame() { i = extract_bits(2); #ifdef DEBUG_PARSE_FRAME_DUMP - printbits(i,2); - logerror(" "); + p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, i, 2); #endif m_IP = reload_table[i]; } @@ -1510,8 +1524,7 @@ void tms5220_device::parse_frame() // attempt to extract the energy index m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits); #ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_energy_idx,m_coeff->energy_bits); - logerror(" "); + p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_energy_idx, m_coeff->energy_bits); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1519,19 +1532,16 @@ void tms5220_device::parse_frame() if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15)) return; - // attempt to extract the repeat flag rep_flag = extract_bits(1); #ifdef DEBUG_PARSE_FRAME_DUMP - printbits(rep_flag, 1); - logerror(" "); + p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, rep_flag, 1); #endif // attempt to extract the pitch m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits); #ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits); - logerror(" "); + p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_pitch_idx,m_coeff->pitch_bits); #endif // if the new frame is unvoiced, be sure to zero out the k5-k10 parameters m_uv_zpar = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; @@ -1546,8 +1556,7 @@ void tms5220_device::parse_frame() { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); - logerror(" "); + p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_k_idx[i],m_coeff->kbits[i]); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1565,14 +1574,13 @@ void tms5220_device::parse_frame() { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); - logerror(" "); + p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_k_idx[i],m_coeff->kbits[i]); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; } #ifdef DEBUG_PARSE_FRAME_DUMP - logerror("\n"); + logerror("%s\n", p_buffer); #endif #ifdef VERBOSE if (m_DDIS) @@ -1594,7 +1602,6 @@ void tms5220_device::parse_frame() set_interrupt_state -- generate an interrupt ***********************************************************************************************/ - void tms5220_device::set_interrupt_state(int state) { if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin @@ -1611,16 +1618,18 @@ void tms5220_device::set_interrupt_state(int state) update_ready_state -- update the ready line ***********************************************************************************************/ - void tms5220_device::update_ready_state() { - int state = ready_read(); + bool state = ready_read(); + if (m_ready_pin != state) + { #ifdef DEBUG_PIN_READS - logerror("ready pin set to state %d\n", state); + logerror("ready pin set to state %d\n", state); #endif - if (!m_readyq_handler.isnull() && state != m_ready_pin) - m_readyq_handler(!state); - m_ready_pin = state; + if (!m_readyq_handler.isnull()) + m_readyq_handler(!state); + m_ready_pin = state; + } } @@ -1688,11 +1697,13 @@ void tms5220_device::device_start() m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80); m_timer_io_ready = timer_alloc(0); + //m_timer_rsq_wsq_check = timer_alloc(1); /* not during reset which is called from within a write! */ - m_io_ready = 1; - m_true_timing = 0; + m_io_ready = true; + m_true_timing = false; m_rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup + m_write_latch = 0; // assume on start that nothing is driving the data bus register_for_save_states(); } @@ -1705,15 +1716,15 @@ void tms5220_device::device_reset() { m_digital_select = FORCE_DIGITAL; // assume analog output /* initialize the FIFO */ - /*memset(m_fifo, 0, sizeof(m_fifo));*/ + memset(m_fifo, 0, sizeof(m_fifo[0])*FIFO_SIZE); m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; /* initialize the chip state */ /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if m_buffer_empty or m_buffer_low are 0 */ - m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = 0; + m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = false; set_interrupt_state(0); update_ready_state(); - m_buffer_empty = m_buffer_low = 1; + m_buffer_empty = m_buffer_low = true; m_RDB_flag = false; @@ -1721,24 +1732,24 @@ void tms5220_device::device_reset() #ifdef TMS5220_PERFECT_INTERPOLATION_HACK m_old_frame_energy_idx = m_old_frame_pitch_idx = 0; memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx)); - m_old_zpar = 0; + m_old_zpar = false; #endif m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0; m_new_frame_pitch_idx = m_current_pitch = 0; - m_zpar = m_uv_zpar = 0; + m_zpar = m_uv_zpar = false; memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx)); memset(m_current_k, 0, sizeof(m_current_k)); /* initialize the sample generators */ - m_inhibit = 1; + m_inhibit = true; m_subcycle = m_c_variant_rate = m_pitch_count = m_PC = 0; m_subc_reload = FORCE_SUBC_RELOAD; - m_OLDE = m_OLDP = 1; + m_OLDE = m_OLDP = true; m_IP = reload_table[m_c_variant_rate&0x3]; m_RNG = 0x1FFF; memset(m_u, 0, sizeof(m_u)); memset(m_x, 0, sizeof(m_x)); - m_schedule_dummy_read = 0; + m_schedule_dummy_read = false; if (m_speechrom) { @@ -1746,7 +1757,7 @@ void tms5220_device::device_reset() // MZ: Do the dummy read immediately. The previous line will cause a // shift in the address pointer in the VSM. When the next command is a // load_address, no dummy read will occur, hence the address will be - // falsely shifted. + // incorrectly shifted. m_speechrom->read(1); m_schedule_dummy_read = false; } @@ -1772,41 +1783,61 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para { switch(id) { - case 0: - if (param) + case 0: // m_timer_io_ready + /* bring up to date first */ + m_stream->update(); +#ifdef DEBUG_IO_READY + logerror("m_timer_io_ready timer fired, param = %02x, m_rs_ws = %02x\n", param, m_rs_ws); +#endif + if (param) // low->high ready state { switch (m_rs_ws) { case 0x02: /* Write */ - /* bring up to date first */ #ifdef DEBUG_IO_READY - logerror("Serviced write: %02x\n", m_write_latch); - //logerror( "Processed write data: %02X\n", m_write_latch); + logerror("m_timer_io_ready: Attempting to service write...\n"); #endif - m_stream->update(); - data_write(m_write_latch); - break; + if ((m_fifo_count >= FIFO_SIZE) && m_DDIS) // if fifo is full and we're in speak external mode + { +#ifdef DEBUG_IO_READY + logerror("m_timer_io_ready: in SPKEXT and FIFO was full! cannot service write now, delaying 16 cycles...\n"); +#endif + m_timer_io_ready->adjust(clocks_to_attotime(16), 1); + break; + } + else + { +#ifdef DEBUG_IO_READY + logerror("m_timer_io_ready: Serviced write: %02x\n", m_write_latch); +#endif + data_write(m_write_latch); + m_io_ready = param; + break; + } case 0x01: /* Read */ - /* bring up to date first */ - m_stream->update(); - m_read_latch = status_read(); + m_read_latch = status_read(true); #ifdef DEBUG_IO_READY - logerror("Serviced read, returning %02x\n", m_read_latch); + logerror("m_timer_io_ready: Serviced read, returning %02x\n", m_read_latch); #endif + m_io_ready = param; break; case 0x03: /* High Impedance */ + m_io_ready = param; case 0x00: /* illegal */ + m_io_ready = param; break; } } - m_io_ready = param; update_ready_state(); break; + /*case 1: // m_timer_rsq_wsq_check + // TODO: write me, and get rid of the garbage in wsq_w, rsq_w, etc! + break; */ } } @@ -1817,7 +1848,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) { uint8_t new_val; - m_true_timing = 1; + m_true_timing = true; state &= 0x01; #ifdef DEBUG_RS_WS logerror("/RS written with data: %d\n", state); @@ -1828,7 +1859,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) m_rs_ws = new_val; if (new_val == 0) { - if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, ? for cd2501ecd + if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, probably also correct for cd2501ecd reset(); #ifdef DEBUG_RS_WS else @@ -1854,10 +1885,11 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) logerror("Scheduling ready cycle for /RS...\n"); #endif /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = 0; + m_io_ready = false; update_ready_state(); - /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */ - m_timer_io_ready->adjust(clocks_to_attotime(16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete + /* How long does /READY stay inactive, when /RS is pulled low? It might be always ~16 clocks (25 usec at 800khz as shown on the datasheet) + but the patent schematic implies it might be as short as 4 clock cycles. */ + m_timer_io_ready->adjust(clocks_to_attotime(16), 1); } } } @@ -1869,7 +1901,7 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) { uint8_t new_val; - m_true_timing = 1; + m_true_timing = true; state &= 0x01; #ifdef DEBUG_RS_WS logerror("/WS written with data: %d\n", state); @@ -1906,7 +1938,7 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) logerror("Scheduling ready cycle for /WS...\n"); #endif /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = 0; + m_io_ready = false; update_ready_state(); /* Now comes the complicated part: how long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not... Speak external mode: ~16 cycles @@ -1933,7 +1965,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) { uint8_t new_val; uint8_t falling_edges; - m_true_timing = 1; + m_true_timing = true; #ifdef DEBUG_RS_WS logerror("/RS and /WS written with %d and %d respectively\n", (data&2)>>1, data&1); #endif @@ -1965,7 +1997,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) logerror("Scheduling ready cycle for /WS...\n"); #endif /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = 0; + m_io_ready = false; update_ready_state(); /* Now comes the complicated part: how long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not... Speak external mode: ~16 cycles @@ -1988,7 +2020,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) logerror("Scheduling ready cycle for /RS...\n"); #endif /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = 0; + m_io_ready = false; update_ready_state(); /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */ m_timer_io_ready->adjust(clocks_to_attotime(16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete @@ -2006,18 +2038,14 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) void tms5220_device::write_data(uint8_t data) { - // prevent debugger from changing the internal state - if (machine().side_effects_disabled()) return; - #ifdef DEBUG_RS_WS logerror("tms5220_data_w: data %02x\n", data); #endif - if (!m_true_timing) - { - /* bring up to date first */ - m_stream->update(); - data_write(data); - } + /* bring up to date first */ + m_stream->update(); + m_write_latch = data; + if (!m_true_timing) // if we're in the default hacky mode where we don't bother with rsq_w and wsq_w... + data_write(m_write_latch); // ...force the write through instantly. else { /* actually in a write ? */ @@ -2025,12 +2053,9 @@ void tms5220_device::write_data(uint8_t data) if (!(m_rs_ws == 0x02)) logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); #endif - m_write_latch = data; } } - - /********************************************************************************************** tms5220_status_r -- read status or data from the sound chip @@ -2039,14 +2064,15 @@ void tms5220_device::write_data(uint8_t data) uint8_t tms5220_device::read_status() { - // prevent debugger from changing the internal state - if (machine().side_effects_disabled()) return 0; + /* bring up to date first */ + m_stream->update(); if (!m_true_timing) { - /* bring up to date first */ - m_stream->update(); - return status_read(); + // prevent debugger from changing the internal state + if (machine().side_effects_disabled()) + return status_read(false); + return status_read(true); } else { @@ -2057,7 +2083,7 @@ uint8_t tms5220_device::read_status() else logerror("tms5220_status_r: data read outside rs!\n"); #endif - return 0xff; + return 0xff; // m_write_latch; // return open bus } } @@ -2078,21 +2104,6 @@ READ_LINE_MEMBER( tms5220_device::readyq_r ) -/********************************************************************************************** - - tms5220_time_to_ready -- return the time until the ready line is asserted - -***********************************************************************************************/ - -attotime tms5220_device::time_to_ready() -{ - /* bring up to date first */ - m_stream->update(); - return clocks_to_attotime(cycles_to_ready() * 80); -} - - - /********************************************************************************************** tms5220_int_r -- return the int status from the sound chip diff --git a/src/devices/sound/tms5220.h b/src/devices/sound/tms5220.h index 4cfab5491ef..0b7617be505 100644 --- a/src/devices/sound/tms5220.h +++ b/src/devices/sound/tms5220.h @@ -90,8 +90,6 @@ public: READ_LINE_MEMBER( readyq_r ); READ_LINE_MEMBER( intq_r ); - attotime time_to_ready(); - protected: tms5220_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int variant); @@ -118,20 +116,23 @@ private: void data_write(int data); void update_fifo_status_and_ints(); int extract_bits(int count); - int status_read(); - int ready_read(); - int cycles_to_ready(); - int int_read(); + uint8_t status_read(bool clear_int); + bool ready_read(); + bool int_read(); void process(int16_t *buffer, unsigned int size); int32_t lattice_filter(); void process_command(unsigned char cmd); void parse_frame(); void set_interrupt_state(int state); void update_ready_state(); + //debug +#ifdef DEBUG_PARSE_FRAME_DUMP + printbits(char *buffer, int count, unsigned int data, int num); +#endif - uint8_t TALK_STATUS() const { return m_SPEN | m_TALKD; } - uint8_t &OLD_FRAME_SILENCE_FLAG() { return m_OLDE; } // 1 if E=0, 0 otherwise. - uint8_t &OLD_FRAME_UNVOICED_FLAG() { return m_OLDP; } // 1 if P=0 (unvoiced), 0 if voiced + bool TALK_STATUS() const { return m_SPEN || m_TALKD; } + bool &OLD_FRAME_SILENCE_FLAG() { return m_OLDE; } // 1 if E=0, 0 otherwise. + bool &OLD_FRAME_UNVOICED_FLAG() { return m_OLDP; } // 1 if P=0 (unvoiced), 0 if voiced bool NEW_FRAME_STOP_FLAG() const { return m_new_frame_energy_idx == 0x0F; } // 1 if this is a stop (Energy = 0xF) frame bool NEW_FRAME_SILENCE_FLAG() const { return m_new_frame_energy_idx == 0; } // ditto as above bool NEW_FRAME_UNVOICED_FLAG() const { return m_new_frame_pitch_idx == 0; } // ditto as above @@ -144,23 +145,23 @@ private: /* coefficient tables */ const struct tms5100_coeffs *m_coeff; - /* these contain global status bits */ + /* these contain global status bits for the 5100 */ uint8_t m_PDC; uint8_t m_CTL_pins; uint8_t m_state; /* New VSM interface */ uint32_t m_address; - uint8_t m_next_is_address; - uint8_t m_schedule_dummy_read; + bool m_next_is_address; + bool m_schedule_dummy_read; uint8_t m_addr_bit; /* read byte */ uint8_t m_CTL_buffer; /* Old VSM interface; R Nabet : These have been added to emulate speech Roms */ - //uint8_t m_schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */ - uint8_t m_data_register; /* data register, used by read command */ - uint8_t m_RDB_flag; /* whether we should read data register or status register */ + //bool m_schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */ + uint8_t m_read_byte_register; /* a serial->parallel shifter, used by "read byte" command to store 8 bits from the VSM */ + bool m_RDB_flag; /* whether we should read data register or status register */ /* these contain data that describes the 128-bit data FIFO */ uint8_t m_fifo[FIFO_SIZE]; @@ -170,20 +171,20 @@ private: uint8_t m_fifo_bits_taken; - /* these contain global status bits */ - uint8_t m_previous_TALK_STATUS; /* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */ - uint8_t m_SPEN; /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */ - uint8_t m_DDIS; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */ - uint8_t m_TALK; /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */ - uint8_t m_TALKD; /* TALK(TCON) value, latched every RESETL4 */ - uint8_t m_buffer_low; /* If 1, FIFO has less than 8 bytes in it */ - uint8_t m_buffer_empty; /* If 1, FIFO is empty */ - uint8_t m_irq_pin; /* state of the IRQ pin (output) */ - uint8_t m_ready_pin; /* state of the READY pin (output) */ + /* these contain global status bits (booleans) */ + bool m_previous_TALK_STATUS;/* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */ + bool m_SPEN; /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */ + bool m_DDIS; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */ + bool m_TALK; /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */ + bool m_TALKD; /* TALK(TCON) value, latched every RESETL4 */ + bool m_buffer_low; /* If 1, FIFO has less than 8 bytes in it */ + bool m_buffer_empty; /* If 1, FIFO is empty */ + bool m_irq_pin; /* state of the IRQ pin (output) */ + bool m_ready_pin; /* state of the READY pin (output) */ /* these contain data describing the current and previous voice frames */ - uint8_t m_OLDE; - uint8_t m_OLDP; + bool m_OLDE; + bool m_OLDP; uint8_t m_new_frame_energy_idx; uint8_t m_new_frame_pitch_idx; @@ -199,8 +200,8 @@ private: uint8_t m_old_frame_energy_idx; uint8_t m_old_frame_pitch_idx; uint8_t m_old_frame_k_idx[10]; - uint8_t m_old_zpar; - uint8_t m_old_uv_zpar; + bool m_old_zpar; + bool m_old_uv_zpar; int32_t m_current_energy; int32_t m_current_pitch; @@ -214,11 +215,11 @@ private: uint8_t m_PC; /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */ /* NOTE: the interpolation period counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */ uint8_t m_IP; /* the current interpolation period */ - uint8_t m_inhibit; /* If 1, interpolation is inhibited until the DIV1 period */ - uint8_t m_uv_zpar; /* If 1, zero k5 thru k10 coefficients */ - uint8_t m_zpar; /* If 1, zero ALL parameters. */ - uint8_t m_pitch_zero; /* circuit 412; pitch is forced to zero under certain circumstances */ - uint8_t m_c_variant_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */ + bool m_inhibit; /* If 1, interpolation is inhibited until the DIV1 period */ + bool m_uv_zpar; /* If 1, zero k5 thru k10 coefficients */ + bool m_zpar; /* If 1, zero ALL parameters. */ + bool m_pitch_zero; /* circuit 412; pitch is forced to zero under certain circumstances */ + uint8_t m_c_variant_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */ uint16_t m_pitch_count; /* pitch counter; provides chirp rom address */ int32_t m_u[11]; @@ -232,17 +233,17 @@ private: The internal DAC used to feed the analog pin is only 8 bits, and has the funny clipping/clamping logic, while the digital pin gives full 10 bit resolution of the output data. - TODO: add a way to set/reset this other than the FORCE_DIGITAL define + TODO: add an MCFG macro to set this other than the FORCE_DIGITAL define */ - uint8_t m_digital_select; + bool m_digital_select; /* io_ready: page 3 of the datasheet specifies that READY will be asserted until * data is available or processed by the system. */ - uint8_t m_io_ready; + bool m_io_ready; /* flag for "true" timing involving rs/ws */ - uint8_t m_true_timing; + bool m_true_timing; /* rsws - state, rs bit 1, ws bit 0 */ uint8_t m_rs_ws; @@ -251,6 +252,7 @@ private: sound_stream *m_stream; emu_timer *m_timer_io_ready; + //emu_timer *m_timer_rsq_wsq_check; /* callbacks */ devcb_write_line m_irq_handler; -- cgit v1.2.3 From 108c36547ccd890828a173752aa4f20bb456208c Mon Sep 17 00:00:00 2001 From: mooglyguy Date: Tue, 12 Jun 2018 07:04:57 +0200 Subject: lviv, gaplus: machine().device cleanup, other cleanup, nw --- src/mame/drivers/gaplus.cpp | 232 ++++++++++++++++++++------------------------ src/mame/drivers/lviv.cpp | 36 +++---- src/mame/includes/gaplus.h | 88 ++++++++++++----- src/mame/includes/lviv.h | 103 +++++++++++--------- src/mame/machine/gaplus.cpp | 4 +- src/mame/machine/lviv.cpp | 60 ++++++------ src/mame/video/gaplus.cpp | 182 ++++++++++++++++------------------ src/mame/video/lviv.cpp | 55 +++++------ 8 files changed, 379 insertions(+), 381 deletions(-) diff --git a/src/mame/drivers/gaplus.cpp b/src/mame/drivers/gaplus.cpp index 1af2b4392a9..998f806706d 100644 --- a/src/mame/drivers/gaplus.cpp +++ b/src/mame/drivers/gaplus.cpp @@ -161,7 +161,7 @@ TODO: #include "speaker.h" -WRITE8_MEMBER(gaplus_state::irq_1_ctrl_w) +WRITE8_MEMBER(gaplus_base_state::irq_1_ctrl_w) { int bit = !BIT(offset, 11); m_main_irq_mask = bit & 1; @@ -169,7 +169,7 @@ WRITE8_MEMBER(gaplus_state::irq_1_ctrl_w) m_maincpu->set_input_line(0, CLEAR_LINE); } -WRITE8_MEMBER(gaplus_state::irq_2_ctrl_w) +WRITE8_MEMBER(gaplus_base_state::irq_2_ctrl_w) { int bit = offset & 1; m_sub_irq_mask = bit & 1; @@ -177,7 +177,7 @@ WRITE8_MEMBER(gaplus_state::irq_2_ctrl_w) m_subcpu->set_input_line(0, CLEAR_LINE); } -WRITE8_MEMBER(gaplus_state::irq_3_ctrl_w) +WRITE8_MEMBER(gaplus_base_state::irq_3_ctrl_w) { int bit = !BIT(offset, 13); m_sub2_irq_mask = bit & 1; @@ -185,7 +185,7 @@ WRITE8_MEMBER(gaplus_state::irq_3_ctrl_w) m_subcpu2->set_input_line(0, CLEAR_LINE); } -WRITE8_MEMBER(gaplus_state::sreset_w) +WRITE8_MEMBER(gaplus_base_state::sreset_w) { int bit = !BIT(offset, 11); m_subcpu->set_input_line(INPUT_LINE_RESET, bit ? CLEAR_LINE : ASSERT_LINE); @@ -193,7 +193,7 @@ WRITE8_MEMBER(gaplus_state::sreset_w) m_namco_15xx->sound_enable_w(bit); } -WRITE8_MEMBER(gaplus_state::freset_w) +WRITE8_MEMBER(gaplus_base_state::freset_w) { int bit = !BIT(offset, 11); @@ -203,14 +203,14 @@ WRITE8_MEMBER(gaplus_state::freset_w) m_namco56xx->set_reset_line(bit ? CLEAR_LINE : ASSERT_LINE); } -void gaplus_state::machine_reset() +void gaplus_base_state::machine_reset() { /* on reset, VINTON is reset, while the other flags don't seem to be affected */ m_sub_irq_mask = 0; m_subcpu->set_input_line(0, CLEAR_LINE); } -void gaplus_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +void gaplus_base_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { switch (id) { @@ -221,21 +221,21 @@ void gaplus_state::device_timer(emu_timer &timer, device_timer_id id, int param, namcoio1_run(ptr, param); break; default: - assert_always(false, "Unknown id in gaplus_state::device_timer"); + assert_always(false, "Unknown id in gaplus_base_state::device_timer"); } } -TIMER_CALLBACK_MEMBER(gaplus_state::namcoio0_run) +TIMER_CALLBACK_MEMBER(gaplus_base_state::namcoio0_run) { m_namco58xx->customio_run(); } -TIMER_CALLBACK_MEMBER(gaplus_state::namcoio1_run) +TIMER_CALLBACK_MEMBER(gaplus_base_state::namcoio1_run) { m_namco56xx->customio_run(); } -WRITE_LINE_MEMBER(gaplus_state::vblank_irq) +WRITE_LINE_MEMBER(gaplus_base_state::vblank_irq) { if (!state) return; @@ -256,7 +256,7 @@ WRITE_LINE_MEMBER(gaplus_state::vblank_irq) m_subcpu2->set_input_line(0, ASSERT_LINE); } -WRITE_LINE_MEMBER(gaplus_state::gapluso_vblank_irq) +WRITE_LINE_MEMBER(gapluso_state::vblank_irq) { if (!state) return; @@ -278,36 +278,36 @@ WRITE_LINE_MEMBER(gaplus_state::gapluso_vblank_irq) } -void gaplus_state::cpu1_map(address_map &map) +void gaplus_base_state::cpu1_map(address_map &map) { - map(0x0000, 0x07ff).ram().w(FUNC(gaplus_state::videoram_w)).share("videoram"); /* tilemap RAM (shared with CPU #2) */ + map(0x0000, 0x07ff).ram().w(FUNC(gaplus_base_state::videoram_w)).share("videoram"); /* tilemap RAM (shared with CPU #2) */ map(0x0800, 0x1fff).ram().share("spriteram"); /* shared RAM with CPU #2 (includes sprite RAM) */ map(0x6000, 0x63ff).rw(m_namco_15xx, FUNC(namco_15xx_device::sharedram_r), FUNC(namco_15xx_device::sharedram_w)); /* shared RAM with CPU #3 */ map(0x6800, 0x680f).rw("namcoio_1", FUNC(namcoio_device::read), FUNC(namcoio_device::write)); /* custom I/O chips interface */ map(0x6810, 0x681f).rw("namcoio_2", FUNC(namcoio_device::read), FUNC(namcoio_device::write)); /* custom I/O chips interface */ - map(0x6820, 0x682f).rw(FUNC(gaplus_state::customio_3_r), FUNC(gaplus_state::customio_3_w)).share("customio_3"); /* custom I/O chip #3 interface */ - map(0x7000, 0x7fff).w(FUNC(gaplus_state::irq_1_ctrl_w)); /* main CPU irq control */ + map(0x6820, 0x682f).rw(FUNC(gaplus_base_state::customio_3_r), FUNC(gaplus_base_state::customio_3_w)).share("customio_3"); /* custom I/O chip #3 interface */ + map(0x7000, 0x7fff).w(FUNC(gaplus_base_state::irq_1_ctrl_w)); /* main CPU irq control */ map(0x7800, 0x7fff).r("watchdog", FUNC(watchdog_timer_device::reset_r)); - map(0x8000, 0x8fff).w(FUNC(gaplus_state::sreset_w)); /* reset CPU #2 & #3, enable sound */ - map(0x9000, 0x9fff).w(FUNC(gaplus_state::freset_w)); /* reset I/O chips */ - map(0xa000, 0xa7ff).w(FUNC(gaplus_state::starfield_control_w)); /* starfield control */ + map(0x8000, 0x8fff).w(FUNC(gaplus_base_state::sreset_w)); /* reset CPU #2 & #3, enable sound */ + map(0x9000, 0x9fff).w(FUNC(gaplus_base_state::freset_w)); /* reset I/O chips */ + map(0xa000, 0xa7ff).w(FUNC(gaplus_base_state::starfield_control_w)); /* starfield control */ map(0xa000, 0xffff).rom(); /* ROM */ } -void gaplus_state::cpu2_map(address_map &map) +void gaplus_base_state::cpu2_map(address_map &map) { - map(0x0000, 0x07ff).ram().w(FUNC(gaplus_state::videoram_w)).share("videoram"); /* tilemap RAM (shared with CPU #1) */ + map(0x0000, 0x07ff).ram().w(FUNC(gaplus_base_state::videoram_w)).share("videoram"); /* tilemap RAM (shared with CPU #1) */ map(0x0800, 0x1fff).ram().share("spriteram"); /* shared RAM with CPU #1 */ // AM_RANGE(0x500f, 0x500f) AM_WRITENOP /* ??? written 256 times on startup */ - map(0x6000, 0x6fff).w(FUNC(gaplus_state::irq_2_ctrl_w)); /* IRQ 2 control */ + map(0x6000, 0x6fff).w(FUNC(gaplus_base_state::irq_2_ctrl_w)); /* IRQ 2 control */ map(0xa000, 0xffff).rom(); /* ROM */ } -void gaplus_state::cpu3_map(address_map &map) +void gaplus_base_state::cpu3_map(address_map &map) { map(0x0000, 0x03ff).rw(m_namco_15xx, FUNC(namco_15xx_device::sharedram_r), FUNC(namco_15xx_device::sharedram_w)); /* shared RAM with the main CPU + sound registers */ map(0x2000, 0x3fff).rw("watchdog", FUNC(watchdog_timer_device::reset_r), FUNC(watchdog_timer_device::reset_w)); /* watchdog? */ - map(0x4000, 0x7fff).w(FUNC(gaplus_state::irq_3_ctrl_w)); /* interrupt enable/disable */ + map(0x4000, 0x7fff).w(FUNC(gaplus_base_state::irq_3_ctrl_w)); /* interrupt enable/disable */ map(0xe000, 0xffff).rom(); /* ROM */ } @@ -497,46 +497,77 @@ WRITE8_MEMBER(gaplus_state::out_lamps1) machine().bookkeeping().coin_counter_w(1, ~data & 1); } -void gaplus_state::machine_start() +void gaplus_base_state::machine_start() { - m_lamps.resolve(); m_namcoio0_run_timer = timer_alloc(TIMER_NAMCOIO0_RUN); m_namcoio1_run_timer = timer_alloc(TIMER_NAMCOIO1_RUN); - switch (m_type) - { - case GAME_GALAGA3: - case GAME_GAPLUS: - m_namco56xx = machine().device("namcoio_1"); - m_namco58xx = machine().device("namcoio_2"); - break; - case GAME_GAPLUSD: - m_namco58xx = machine().device("namcoio_1"); - m_namco56xx = machine().device("namcoio_2"); - break; - } - save_item(NAME(m_main_irq_mask)); save_item(NAME(m_sub_irq_mask)); save_item(NAME(m_sub2_irq_mask)); } +void gaplus_state::machine_start() +{ + gaplus_base_state::machine_start(); -MACHINE_CONFIG_START(gaplus_state::gaplus) - - /* basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", MC6809E, XTAL(24'576'000)/16) /* 1.536 MHz */ - MCFG_DEVICE_PROGRAM_MAP(cpu1_map) - - MCFG_DEVICE_ADD("sub", MC6809E, XTAL(24'576'000)/16) /* 1.536 MHz */ - MCFG_DEVICE_PROGRAM_MAP(cpu2_map) - - MCFG_DEVICE_ADD("sub2", MC6809E, XTAL(24'576'000)/16) /* 1.536 MHz */ - MCFG_DEVICE_PROGRAM_MAP(cpu3_map) + m_lamps.resolve(); +} - MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* a high value to ensure proper synchronization of the CPUs */ +MACHINE_CONFIG_START(gaplus_base_state::gaplus_base) + /* basic machine hardware */ + MCFG_DEVICE_ADD(m_maincpu, MC6809E, XTAL(24'576'000) / 16) /* 1.536 MHz */ + MCFG_DEVICE_PROGRAM_MAP(cpu1_map) + + MCFG_DEVICE_ADD("sub", MC6809E, XTAL(24'576'000) / 16) /* 1.536 MHz */ + MCFG_DEVICE_PROGRAM_MAP(cpu2_map) + + MCFG_DEVICE_ADD("sub2", MC6809E, XTAL(24'576'000) / 16) /* 1.536 MHz */ + MCFG_DEVICE_PROGRAM_MAP(cpu3_map) + + MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* a high value to ensure proper synchronization of the CPUs */ + + MCFG_WATCHDOG_ADD("watchdog") + + MCFG_NAMCO_62XX_ADD("62xx", 24576000 / 6 / 2) /* totally made up - TODO: fix */ + //MCFG_NAMCO_62XX_INPUT_0_CB(IOPORT("IN0L")) + //MCFG_NAMCO_62XX_INPUT_1_CB(IOPORT("IN0H")) + //MCFG_NAMCO_62XX_INPUT_2_CB(IOPORT("IN1L")) + //MCFG_NAMCO_62XX_INPUT_3_CB(IOPORT("IN1H")) + //MCFG_NAMCO_62XX_OUTPUT_0_CB(WRITE8(*this, gaplus_base_state,out_0)) + //MCFG_NAMCO_62XX_OUTPUT_1_CB(WRITE8(*this, gaplus_base_state,out_1)) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60.606060) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_SIZE(36 * 8, 28 * 8) + MCFG_SCREEN_VISIBLE_AREA(0 * 8, 36 * 8 - 1, 0 * 8, 28 * 8 - 1) + MCFG_SCREEN_UPDATE_DRIVER(gaplus_base_state, screen_update) + MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, gaplus_base_state, screen_vblank)) + MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE(*this, gaplus_base_state, vblank_irq)) + MCFG_SCREEN_PALETTE("palette") + + MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_gaplus) + MCFG_PALETTE_ADD("palette", 64 * 4 + 64 * 8) + MCFG_PALETTE_INDIRECT_ENTRIES(256) + MCFG_PALETTE_INIT_OWNER(gaplus_base_state, gaplus) + + /* sound hardware */ + SPEAKER(config, "mono").front_center(); + + MCFG_DEVICE_ADD("namco", NAMCO_15XX, XTAL(24'576'000) / 1024) + MCFG_NAMCO_AUDIO_VOICES(8) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) + + MCFG_DEVICE_ADD("samples", SAMPLES) + MCFG_SAMPLES_CHANNELS(1) + MCFG_SAMPLES_NAMES(gaplus_sample_names) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) +MACHINE_CONFIG_END - MCFG_WATCHDOG_ADD("watchdog") +MACHINE_CONFIG_START(gaplus_state::gaplus) + gaplus_base(config); MCFG_DEVICE_ADD("namcoio_1", NAMCO_56XX, 0) MCFG_NAMCO56XX_IN_0_CB(IOPORT("COINS")) @@ -551,75 +582,39 @@ MACHINE_CONFIG_START(gaplus_state::gaplus) MCFG_NAMCO58XX_IN_1_CB(IOPORT("DSWB_LOW")) MCFG_NAMCO58XX_IN_2_CB(IOPORT("DSWB_HIGH")) MCFG_NAMCO58XX_IN_3_CB(IOPORT("DSWA_LOW")) - - MCFG_NAMCO_62XX_ADD("62xx", 24576000/6/2) /* totally made up - TODO: fix */ - //MCFG_NAMCO_62XX_INPUT_0_CB(IOPORT("IN0L")) - //MCFG_NAMCO_62XX_INPUT_1_CB(IOPORT("IN0H")) - //MCFG_NAMCO_62XX_INPUT_2_CB(IOPORT("IN1L")) - //MCFG_NAMCO_62XX_INPUT_3_CB(IOPORT("IN1H")) - //MCFG_NAMCO_62XX_OUTPUT_0_CB(WRITE8(*this, gaplus_state,out_0)) - //MCFG_NAMCO_62XX_OUTPUT_1_CB(WRITE8(*this, gaplus_state,out_1)) - - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60.606060) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(36*8, 28*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 36*8-1, 0*8, 28*8-1) - MCFG_SCREEN_UPDATE_DRIVER(gaplus_state, screen_update) - MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, gaplus_state, screen_vblank)) - MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE(*this, gaplus_state, vblank_irq)) - MCFG_SCREEN_PALETTE("palette") - - MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_gaplus) - MCFG_PALETTE_ADD("palette", 64*4+64*8) - MCFG_PALETTE_INDIRECT_ENTRIES(256) - MCFG_PALETTE_INIT_OWNER(gaplus_state, gaplus) - - /* sound hardware */ - SPEAKER(config, "mono").front_center(); - - MCFG_DEVICE_ADD("namco", NAMCO_15XX, XTAL(24'576'000)/1024) - MCFG_NAMCO_AUDIO_VOICES(8) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) - - MCFG_DEVICE_ADD("samples", SAMPLES) - MCFG_SAMPLES_CHANNELS(1) - MCFG_SAMPLES_NAMES(gaplus_sample_names) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.80) MACHINE_CONFIG_END -MACHINE_CONFIG_START(gaplus_state::gaplusd) - gaplus(config); +MACHINE_CONFIG_START(gaplusd_state::gaplusd) + gaplus_base(config); - MCFG_DEVICE_REPLACE("namcoio_1", NAMCO_58XX, 0) + MCFG_DEVICE_ADD("namcoio_1", NAMCO_58XX, 0) MCFG_NAMCO58XX_IN_0_CB(IOPORT("COINS")) MCFG_NAMCO58XX_IN_1_CB(IOPORT("P1")) MCFG_NAMCO58XX_IN_2_CB(IOPORT("P2")) MCFG_NAMCO58XX_IN_3_CB(IOPORT("BUTTONS")) - MCFG_DEVICE_REPLACE("namcoio_2", NAMCO_56XX, 0) + MCFG_DEVICE_ADD("namcoio_2", NAMCO_56XX, 0) MCFG_NAMCO56XX_IN_0_CB(IOPORT("DSWA_HIGH")) MCFG_NAMCO56XX_IN_1_CB(IOPORT("DSWB_LOW")) MCFG_NAMCO56XX_IN_2_CB(IOPORT("DSWB_HIGH")) MCFG_NAMCO56XX_IN_3_CB(IOPORT("DSWA_LOW")) MACHINE_CONFIG_END -MACHINE_CONFIG_START(gaplus_state::gapluso) - gaplusd(config); +MACHINE_CONFIG_START(gapluso_state::gapluso) + gaplus_base(config); /* basic machine hardware */ MCFG_DEVICE_MODIFY("screen") - MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, gaplus_state, screen_vblank)) - MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE(*this, gaplus_state, gapluso_vblank_irq)) + MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, gaplus_base_state, screen_vblank)) + MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE(*this, gapluso_state, vblank_irq)) - MCFG_DEVICE_REPLACE("namcoio_1", NAMCO_56XX, 0) + MCFG_DEVICE_ADD("namcoio_1", NAMCO_56XX, 0) MCFG_NAMCO56XX_IN_0_CB(IOPORT("COINS")) MCFG_NAMCO56XX_IN_1_CB(IOPORT("P1")) MCFG_NAMCO56XX_IN_2_CB(IOPORT("P2")) MCFG_NAMCO56XX_IN_3_CB(IOPORT("BUTTONS")) - - MCFG_DEVICE_REPLACE("namcoio_2", NAMCO_58XX, 0) + + MCFG_DEVICE_ADD("namcoio_2", NAMCO_58XX, 0) MCFG_NAMCO58XX_IN_0_CB(IOPORT("DSWA_HIGH")) MCFG_NAMCO58XX_IN_1_CB(IOPORT("DSWB_LOW")) MCFG_NAMCO58XX_IN_2_CB(IOPORT("DSWB_HIGH")) @@ -993,44 +988,29 @@ ROM_START( galaga3m ) /* Version (AKA Midway) 1 PCB */ ROM_END -void gaplus_state::init_gaplus() +void gaplus_base_state::driver_init() { - uint8_t *rom = memregion("gfx1")->base(); + uint8_t *rom = m_gfx1_region->base(); for (int i = 0;i < 0x2000;i++) rom[i + 0x2000] = rom[i] >> 4; - rom = memregion("gfx2")->base() + 0x6000; + rom = m_gfx2_region->base() + 0x6000; for (int i = 0;i < 0x2000;i++) rom[i + 0x2000] = rom[i] << 4; - - m_type = GAME_GAPLUS; -} - - -void gaplus_state::init_gaplusd() -{ - init_gaplus(); - m_type = GAME_GAPLUSD; -} - -void gaplus_state::init_galaga3() -{ - init_gaplus(); - m_type = GAME_GALAGA3; } /* These sets are on revision 2 or 3 PCBs AKA "Namco" PCBs */ -GAME( 1984, gaplus, 0, gapluso, gapluso, gaplus_state, init_gaplus, ROT90, "Namco", "Gaplus (GP2 rev. B)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, gaplusa, gaplus, gapluso, gapluso, gaplus_state, init_gaplus, ROT90, "Namco", "Gaplus (GP2)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, gaplusd, gaplus, gaplusd, gapluso, gaplus_state, init_gaplusd, ROT90, "Namco", "Gaplus (GP2 rev D, alternate hardware)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, galaga3, gaplus, gaplus, gaplus, gaplus_state, init_galaga3, ROT90, "Namco", "Galaga 3 (GP3 rev. D)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, galaga3a, gaplus, gaplus, gaplus, gaplus_state, init_galaga3, ROT90, "Namco", "Galaga 3 (GP3 rev. C)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, galaga3b, gaplus, gaplus, gaplus, gaplus_state, init_galaga3, ROT90, "Namco", "Galaga 3 (GP3)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gaplus, 0, gapluso, gapluso, gapluso_state, driver_init, ROT90, "Namco", "Gaplus (GP2 rev. B)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gaplusa, gaplus, gapluso, gapluso, gapluso_state, driver_init, ROT90, "Namco", "Gaplus (GP2)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gaplusd, gaplus, gaplusd, gapluso, gaplusd_state, driver_init, ROT90, "Namco", "Gaplus (GP2 rev D, alternate hardware)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, galaga3, gaplus, gaplus, gaplus, gaplus_state, driver_init, ROT90, "Namco", "Galaga 3 (GP3 rev. D)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, galaga3a, gaplus, gaplus, gaplus, gaplus_state, driver_init, ROT90, "Namco", "Galaga 3 (GP3 rev. C)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, galaga3b, gaplus, gaplus, gaplus, gaplus_state, driver_init, ROT90, "Namco", "Galaga 3 (GP3)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) /* These sets are on older revision (AKA Midway) 1 PCBs */ -GAME( 1984, galaga3c, gaplus, gaplus, galaga3a, gaplus_state, init_galaga3, ROT90, "Namco", "Galaga 3 (set 4)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, galaga3m, gaplus, gaplus, galaga3m, gaplus_state, init_galaga3, ROT90, "Namco", "Galaga 3 (set 5)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, galaga3c, gaplus, gaplus, galaga3a, gaplus_state, driver_init, ROT90, "Namco", "Galaga 3 (set 4)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, galaga3m, gaplus, gaplus, galaga3m, gaplus_state, driver_init, ROT90, "Namco", "Galaga 3 (set 5)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) /* This is an odd mix of Galaga3 and Gaplus, main code seems closest to galaga3m but still has significant changes, copyright is modified to 1992, has Galaga 3 style high scores, PARSEF spelling error on high score table */ -GAME( 1992, gaplust, gaplus, gaplus, galaga3m, gaplus_state, init_galaga3, ROT90, "bootleg (Tecfri)", "Gaplus (Tecfri PCB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, gaplust, gaplus, gaplus, galaga3m, gaplus_state, driver_init, ROT90, "bootleg (Tecfri)", "Gaplus (Tecfri PCB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/lviv.cpp b/src/mame/drivers/lviv.cpp index 86c89ce2c0e..7fe75206ebe 100644 --- a/src/mame/drivers/lviv.cpp +++ b/src/mame/drivers/lviv.cpp @@ -298,12 +298,12 @@ Timings: void lviv_state::io_map(address_map &map) { - map(0x00, 0xff).rw(FUNC(lviv_state::lviv_io_r), FUNC(lviv_state::lviv_io_w)); + map(0x00, 0xff).rw(FUNC(lviv_state::io_r), FUNC(lviv_state::io_w)); } /* memory w/r functions */ -void lviv_state::lviv_mem(address_map &map) +void lviv_state::mem_map(address_map &map) { map(0x0000, 0x3fff).bankrw(m_bank[0]); map(0x4000, 0x7fff).bankrw(m_bank[1]); @@ -407,7 +407,7 @@ static INPUT_PORTS_START (lviv) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_START("RESET") /* CPU */ - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Reset") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN)) PORT_CHANGED_MEMBER(DEVICE_SELF, lviv_state, lviv_reset, 0) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Reset") PORT_CODE(KEYCODE_PGDN) PORT_CHAR(UCHAR_MAMEKEY(PGDN)) PORT_CHANGED_MEMBER(DEVICE_SELF, lviv_state, reset_button, 0) PORT_START("JOY") /* Joystick */ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN) @@ -424,25 +424,25 @@ INPUT_PORTS_END MACHINE_CONFIG_START(lviv_state::lviv) /* basic machine hardware */ MCFG_DEVICE_ADD(m_maincpu, I8080, 2500000) - MCFG_DEVICE_PROGRAM_MAP(lviv_mem) + MCFG_DEVICE_PROGRAM_MAP(mem_map) MCFG_DEVICE_IO_MAP(io_map) MCFG_QUANTUM_TIME(attotime::from_hz(60)) MCFG_DEVICE_ADD(m_ppi[0], I8255, 0) - MCFG_I8255_IN_PORTA_CB(READ8(*this, lviv_state, lviv_ppi_0_porta_r)) - MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, lviv_state, lviv_ppi_0_porta_w)) - MCFG_I8255_IN_PORTB_CB(READ8(*this, lviv_state, lviv_ppi_0_portb_r)) - MCFG_I8255_OUT_PORTB_CB(WRITE8(*this, lviv_state, lviv_ppi_0_portb_w)) - MCFG_I8255_IN_PORTC_CB(READ8(*this, lviv_state, lviv_ppi_0_portc_r)) - MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, lviv_state, lviv_ppi_0_portc_w)) + MCFG_I8255_IN_PORTA_CB(READ8(*this, lviv_state, ppi_0_porta_r)) + MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, lviv_state, ppi_0_porta_w)) + MCFG_I8255_IN_PORTB_CB(READ8(*this, lviv_state, ppi_0_portb_r)) + MCFG_I8255_OUT_PORTB_CB(WRITE8(*this, lviv_state, ppi_0_portb_w)) + MCFG_I8255_IN_PORTC_CB(READ8(*this, lviv_state, ppi_0_portc_r)) + MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, lviv_state, ppi_0_portc_w)) MCFG_DEVICE_ADD(m_ppi[1], I8255, 0) - MCFG_I8255_IN_PORTA_CB(READ8(*this, lviv_state, lviv_ppi_1_porta_r)) - MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, lviv_state, lviv_ppi_1_porta_w)) - MCFG_I8255_IN_PORTB_CB(READ8(*this, lviv_state, lviv_ppi_1_portb_r)) - MCFG_I8255_OUT_PORTB_CB(WRITE8(*this, lviv_state, lviv_ppi_1_portb_w)) - MCFG_I8255_IN_PORTC_CB(READ8(*this, lviv_state, lviv_ppi_1_portc_r)) - MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, lviv_state, lviv_ppi_1_portc_w)) + MCFG_I8255_IN_PORTA_CB(READ8(*this, lviv_state, ppi_1_porta_r)) + MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, lviv_state, ppi_1_porta_w)) + MCFG_I8255_IN_PORTB_CB(READ8(*this, lviv_state, ppi_1_portb_r)) + MCFG_I8255_OUT_PORTB_CB(WRITE8(*this, lviv_state, ppi_1_portb_w)) + MCFG_I8255_IN_PORTC_CB(READ8(*this, lviv_state, ppi_1_portc_r)) + MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, lviv_state, ppi_1_portc_w)) MCFG_SCREEN_ADD(m_screen, RASTER) MCFG_SCREEN_REFRESH_RATE(50) @@ -451,10 +451,10 @@ MACHINE_CONFIG_START(lviv_state::lviv) /* video hardware */ MCFG_SCREEN_SIZE(256, 256) MCFG_SCREEN_VISIBLE_AREA(0, 256-1, 0, 256-1) - MCFG_SCREEN_UPDATE_DRIVER(lviv_state, screen_update_lviv) + MCFG_SCREEN_UPDATE_DRIVER(lviv_state, screen_update) MCFG_SCREEN_PALETTE(m_palette) - MCFG_PALETTE_ADD(m_palette, sizeof (lviv_palette) / 3) + MCFG_PALETTE_ADD(m_palette, sizeof (s_palette) / 3) MCFG_PALETTE_INIT_OWNER(lviv_state, lviv) /* sound hardware */ diff --git a/src/mame/includes/gaplus.h b/src/mame/includes/gaplus.h index c1c275a9608..db7e4541f86 100644 --- a/src/mame/includes/gaplus.h +++ b/src/mame/includes/gaplus.h @@ -13,7 +13,7 @@ struct star { }; -class gaplus_state : public driver_device +class gaplus_base_state : public driver_device { public: enum @@ -22,27 +22,24 @@ public: TIMER_NAMCOIO1_RUN }; - enum - { - GAME_GAPLUS = 0, - GAME_GAPLUSD, - GAME_GALAGA3 - }; - - gaplus_state(const machine_config &mconfig, device_type type, const char *tag) + gaplus_base_state(const machine_config &mconfig, device_type type, const char *tag, const char *namco56xx_tag, const char *namco58xx_tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_subcpu(*this, "sub") , m_subcpu2(*this, "sub2") + , m_namco56xx(*this, namco56xx_tag) + , m_namco58xx(*this, namco58xx_tag) , m_namco_15xx(*this, "namco") , m_samples(*this, "samples") , m_gfxdecode(*this, "gfxdecode") , m_screen(*this, "screen") , m_palette(*this, "palette") - , m_customio_3(*this,"customio_3") - , m_videoram(*this,"videoram") - , m_spriteram(*this,"spriteram") - , m_lamps(*this, "lamp%u", 0U) + , m_proms_region(*this, "proms") + , m_customio_3(*this, "customio_3") + , m_videoram(*this, "videoram") + , m_spriteram(*this, "spriteram") + , m_gfx1_region(*this, "gfx1") + , m_gfx2_region(*this, "gfx2") { } DECLARE_WRITE8_MEMBER(irq_1_ctrl_w); @@ -54,19 +51,13 @@ public: DECLARE_READ8_MEMBER(customio_3_r); DECLARE_WRITE8_MEMBER(videoram_w); DECLARE_WRITE8_MEMBER(starfield_control_w); - DECLARE_WRITE8_MEMBER(out_lamps0); - DECLARE_WRITE8_MEMBER(out_lamps1); - void init_gaplus(); - void init_gaplusd(); - void init_galaga3(); DECLARE_PALETTE_INIT(gaplus); TILEMAP_MAPPER_MEMBER(tilemap_scan); TILE_GET_INFO_MEMBER(get_tile_info); DECLARE_WRITE_LINE_MEMBER(vblank_irq); - DECLARE_WRITE_LINE_MEMBER(gapluso_vblank_irq); TIMER_CALLBACK_MEMBER(namcoio0_run); TIMER_CALLBACK_MEMBER(namcoio1_run); @@ -74,14 +65,15 @@ public: DECLARE_WRITE_LINE_MEMBER(screen_vblank); void starfield_init(); void starfield_render(bitmap_ind16 &bitmap); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ) const; - void gapluso(machine_config &config); - void gaplusd(machine_config &config); - void gaplus(machine_config &config); + void gaplus_base(machine_config &config); void cpu1_map(address_map &map); void cpu2_map(address_map &map); void cpu3_map(address_map &map); + + virtual void driver_init() override; + protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void machine_start() override; @@ -91,18 +83,20 @@ protected: required_device m_maincpu; required_device m_subcpu; required_device m_subcpu2; + required_device m_namco56xx; + required_device m_namco58xx; required_device m_namco_15xx; required_device m_samples; required_device m_gfxdecode; required_device m_screen; required_device m_palette; - namco58xx_device *m_namco58xx; - namco56xx_device *m_namco56xx; + required_memory_region m_proms_region; required_shared_ptr m_customio_3; required_shared_ptr m_videoram; required_shared_ptr m_spriteram; - output_finder<2> m_lamps; + required_memory_region m_gfx1_region; + required_memory_region m_gfx2_region; int m_type; @@ -116,3 +110,45 @@ protected: emu_timer *m_namcoio0_run_timer; emu_timer *m_namcoio1_run_timer; }; + +class gaplusd_state : public gaplus_base_state +{ +public: + gaplusd_state(const machine_config &mconfig, device_type type, const char *tag) + : gaplus_base_state(mconfig, type, tag, "namcoio_2", "namcoio_1") + { + } + + void gaplusd(machine_config &config); +}; + +class gapluso_state : public gaplus_base_state { +public: + gapluso_state(const machine_config &mconfig, device_type type, const char *tag) + : gaplus_base_state(mconfig, type, tag, "namcoio_1", "namcoio_2") { + } + + void gapluso(machine_config &config); + +protected: + DECLARE_WRITE_LINE_MEMBER(vblank_irq); +}; + +class gaplus_state : public gaplus_base_state { +public: + gaplus_state(const machine_config &mconfig, device_type type, const char *tag) + : gaplus_base_state(mconfig, type, tag, "namcoio_1", "namcoio_2") + , m_lamps(*this, "lamp%u", 0U) + { + } + + void gaplus(machine_config &config); + +protected: + virtual void machine_start() override; + + DECLARE_WRITE8_MEMBER(out_lamps0); + DECLARE_WRITE8_MEMBER(out_lamps1); + + output_finder<2> m_lamps; +}; diff --git a/src/mame/includes/lviv.h b/src/mame/includes/lviv.h index dc98fb4570b..12df36c4c19 100644 --- a/src/mame/includes/lviv.h +++ b/src/mame/includes/lviv.h @@ -20,42 +20,59 @@ class lviv_state : public driver_device { public: lviv_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_ram(*this, RAM_TAG), - m_ppi(*this, "ppi8255_%u", 0U), - m_speaker(*this, "speaker"), - m_cassette(*this, "cassette"), - m_screen(*this, "screen"), - m_palette(*this, "palette"), - m_maincpu_region(*this, "maincpu"), - m_bank(*this, "bank%u", 1U), - m_key(*this, "KEY%u", 0U), - m_joy_port(*this, "JOY") + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_ram(*this, RAM_TAG) + , m_ppi(*this, "ppi8255_%u", 0U) + , m_speaker(*this, "speaker") + , m_cassette(*this, "cassette") + , m_screen(*this, "screen") + , m_palette(*this, "palette") + , m_maincpu_region(*this, "maincpu") + , m_bank(*this, "bank%u", 1U) + , m_key(*this, "KEY%u", 0U) + , m_joy_port(*this, "JOY") { } - unsigned char * m_video_ram; - unsigned short m_colortable[1][4]; - uint8_t m_ppi_port_outputs[2][3]; - uint8_t m_startup_mem_map; - DECLARE_READ8_MEMBER(lviv_io_r); - DECLARE_WRITE8_MEMBER(lviv_io_w); + void lviv(machine_config &config); + + DECLARE_INPUT_CHANGED_MEMBER(reset_button); + +protected: virtual void machine_reset() override; - virtual void video_start() override; + DECLARE_PALETTE_INIT(lviv); - uint32_t screen_update_lviv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - DECLARE_READ8_MEMBER(lviv_ppi_0_porta_r); - DECLARE_READ8_MEMBER(lviv_ppi_0_portb_r); - DECLARE_READ8_MEMBER(lviv_ppi_0_portc_r); - DECLARE_WRITE8_MEMBER(lviv_ppi_0_porta_w); - DECLARE_WRITE8_MEMBER(lviv_ppi_0_portb_w); - DECLARE_WRITE8_MEMBER(lviv_ppi_0_portc_w); - DECLARE_READ8_MEMBER(lviv_ppi_1_porta_r); - DECLARE_READ8_MEMBER(lviv_ppi_1_portb_r); - DECLARE_READ8_MEMBER(lviv_ppi_1_portc_r); - DECLARE_WRITE8_MEMBER(lviv_ppi_1_porta_w); - DECLARE_WRITE8_MEMBER(lviv_ppi_1_portb_w); - DECLARE_WRITE8_MEMBER(lviv_ppi_1_portc_w); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + DECLARE_READ8_MEMBER(io_r); + DECLARE_WRITE8_MEMBER(io_w); + + DECLARE_READ8_MEMBER(ppi_0_porta_r); + DECLARE_READ8_MEMBER(ppi_0_portb_r); + DECLARE_READ8_MEMBER(ppi_0_portc_r); + DECLARE_READ8_MEMBER(ppi_1_porta_r); + DECLARE_READ8_MEMBER(ppi_1_portb_r); + DECLARE_READ8_MEMBER(ppi_1_portc_r); + + DECLARE_WRITE8_MEMBER(ppi_0_porta_w); + DECLARE_WRITE8_MEMBER(ppi_0_portb_w); + DECLARE_WRITE8_MEMBER(ppi_0_portc_w); + DECLARE_WRITE8_MEMBER(ppi_1_porta_w); + DECLARE_WRITE8_MEMBER(ppi_1_portb_w); + DECLARE_WRITE8_MEMBER(ppi_1_portc_w); + + DECLARE_SNAPSHOT_LOAD_MEMBER(lviv); + + void update_palette(uint8_t pal); + + void update_memory(); + void setup_snapshot(uint8_t * data); + void dump_registers(); + image_verify_result verify_snapshot(uint8_t * data, uint32_t size); + + void io_map(address_map &map); + void mem_map(address_map &map); + required_device m_maincpu; required_device m_ram; required_device_array m_ppi; @@ -68,21 +85,13 @@ public: required_ioport_array<12> m_key; required_ioport m_joy_port; - void lviv_update_palette(uint8_t pal); - void lviv_update_memory (); - void lviv_setup_snapshot (uint8_t * data); - void dump_registers(); - image_verify_result lviv_verify_snapshot(uint8_t * data, uint32_t size); - DECLARE_SNAPSHOT_LOAD_MEMBER( lviv ); - DECLARE_INPUT_CHANGED_MEMBER(lviv_reset); - void lviv(machine_config &config); - void io_map(address_map &map); - void lviv_mem(address_map &map); -}; - -/*----------- defined in video/lviv.c -----------*/ - -extern const unsigned char lviv_palette[8*3]; + uint8_t* m_video_ram; + uint16_t m_colortable[1][4]; + uint8_t m_ppi_port_outputs[2][3]; + uint8_t m_startup_mem_map; + /*----------- defined in video/lviv.c -----------*/ + static const uint8_t s_palette[8*3]; +}; #endif // MAME_INCLUDES_LVIV_H diff --git a/src/mame/machine/gaplus.cpp b/src/mame/machine/gaplus.cpp index 377ea6f6233..c496e69fabd 100644 --- a/src/mame/machine/gaplus.cpp +++ b/src/mame/machine/gaplus.cpp @@ -20,7 +20,7 @@ * * ************************************************************************************/ -WRITE8_MEMBER(gaplus_state::customio_3_w) +WRITE8_MEMBER(gaplus_base_state::customio_3_w) { if ((offset == 0x09) && (data >= 0x0f)) m_samples->start(0,0); @@ -29,7 +29,7 @@ WRITE8_MEMBER(gaplus_state::customio_3_w) } -READ8_MEMBER(gaplus_state::customio_3_r) +READ8_MEMBER(gaplus_base_state::customio_3_r) { int mode = m_customio_3[8]; diff --git a/src/mame/machine/lviv.cpp b/src/mame/machine/lviv.cpp index 4c6fc34332d..afc15380bf2 100644 --- a/src/mame/machine/lviv.cpp +++ b/src/mame/machine/lviv.cpp @@ -20,7 +20,7 @@ #define LVIV_SNAPSHOT_SIZE 82219 -void lviv_state::lviv_update_memory() +void lviv_state::update_memory() { uint8_t *ram = m_ram->pointer(); @@ -36,22 +36,22 @@ void lviv_state::lviv_update_memory() } } -INPUT_CHANGED_MEMBER(lviv_state::lviv_reset) +INPUT_CHANGED_MEMBER(lviv_state::reset_button) { machine().schedule_soft_reset(); } -READ8_MEMBER(lviv_state::lviv_ppi_0_porta_r) +READ8_MEMBER(lviv_state::ppi_0_porta_r) { return 0xff; } -READ8_MEMBER(lviv_state::lviv_ppi_0_portb_r) +READ8_MEMBER(lviv_state::ppi_0_portb_r) { return 0xff; } -READ8_MEMBER(lviv_state::lviv_ppi_0_portc_r) +READ8_MEMBER(lviv_state::ppi_0_portc_r) { uint8_t data = m_ppi_port_outputs[0][2] & 0x0f; if (m_cassette->input() > 0.038) @@ -61,32 +61,32 @@ READ8_MEMBER(lviv_state::lviv_ppi_0_portc_r) return data; } -WRITE8_MEMBER(lviv_state::lviv_ppi_0_porta_w) +WRITE8_MEMBER(lviv_state::ppi_0_porta_w) { m_ppi_port_outputs[0][0] = data; } -WRITE8_MEMBER(lviv_state::lviv_ppi_0_portb_w) +WRITE8_MEMBER(lviv_state::ppi_0_portb_w) { m_ppi_port_outputs[0][1] = data; - lviv_update_palette(data&0x7f); + update_palette(data&0x7f); } -WRITE8_MEMBER(lviv_state::lviv_ppi_0_portc_w)/* tape in/out, video memory on/off */ +WRITE8_MEMBER(lviv_state::ppi_0_portc_w)/* tape in/out, video memory on/off */ { m_ppi_port_outputs[0][2] = data; if (m_ppi_port_outputs[0][1]&0x80) m_speaker->level_w(data & 0x01); m_cassette->output((data & 0x01) ? -1.0 : 1.0); - lviv_update_memory(); + update_memory(); } -READ8_MEMBER(lviv_state::lviv_ppi_1_porta_r) +READ8_MEMBER(lviv_state::ppi_1_porta_r) { return 0xff; } -READ8_MEMBER(lviv_state::lviv_ppi_1_portb_r)/* keyboard reading */ +READ8_MEMBER(lviv_state::ppi_1_portb_r)/* keyboard reading */ { return ((m_ppi_port_outputs[1][0] & 0x01) ? 0xff : m_key[0]->read()) & ((m_ppi_port_outputs[1][0] & 0x02) ? 0xff : m_key[1]->read()) & @@ -98,7 +98,7 @@ READ8_MEMBER(lviv_state::lviv_ppi_1_portb_r)/* keyboard reading */ ((m_ppi_port_outputs[1][0] & 0x80) ? 0xff : m_key[7]->read()); } -READ8_MEMBER(lviv_state::lviv_ppi_1_portc_r)/* keyboard reading */ +READ8_MEMBER(lviv_state::ppi_1_portc_r)/* keyboard reading */ { return ((m_ppi_port_outputs[1][2] & 0x01) ? 0xff : m_key[ 8]->read()) & ((m_ppi_port_outputs[1][2] & 0x02) ? 0xff : m_key[ 9]->read()) & @@ -106,24 +106,24 @@ READ8_MEMBER(lviv_state::lviv_ppi_1_portc_r)/* keyboard reading */ ((m_ppi_port_outputs[1][2] & 0x08) ? 0xff : m_key[11]->read()); } -WRITE8_MEMBER(lviv_state::lviv_ppi_1_porta_w)/* kayboard scaning */ +WRITE8_MEMBER(lviv_state::ppi_1_porta_w)/* kayboard scaning */ { m_ppi_port_outputs[1][0] = data; } -WRITE8_MEMBER(lviv_state::lviv_ppi_1_portb_w) +WRITE8_MEMBER(lviv_state::ppi_1_portb_w) { m_ppi_port_outputs[1][1] = data; } -WRITE8_MEMBER(lviv_state::lviv_ppi_1_portc_w)/* kayboard scaning */ +WRITE8_MEMBER(lviv_state::ppi_1_portc_w)/* kayboard scaning */ { m_ppi_port_outputs[1][2] = data; } /* I/O */ -READ8_MEMBER(lviv_state::lviv_io_r) +READ8_MEMBER(lviv_state::io_r) { if (m_startup_mem_map) { @@ -147,7 +147,7 @@ READ8_MEMBER(lviv_state::lviv_io_r) } } -WRITE8_MEMBER(lviv_state::lviv_io_w) +WRITE8_MEMBER(lviv_state::io_w) { address_space &cpuspace = m_maincpu->space(AS_PROGRAM); if (m_startup_mem_map) @@ -223,13 +223,11 @@ Lviv snapshot files (SAV) 1411D - 1412A: ??? (something additional) *******************************************************************************/ -void lviv_state::lviv_setup_snapshot(uint8_t * data) +void lviv_state::setup_snapshot(uint8_t * data) { - unsigned char lo,hi; - /* Set registers */ - lo = data[0x14112] & 0x0ff; - hi = data[0x14111] & 0x0ff; + uint8_t lo = data[0x14112] & 0x0ff; + uint8_t hi = data[0x14111] & 0x0ff; m_maincpu->set_state_int(i8080_cpu_device::I8085_BC, (hi << 8) | lo); lo = data[0x14114] & 0x0ff; hi = data[0x14113] & 0x0ff; @@ -254,9 +252,9 @@ void lviv_state::lviv_setup_snapshot(uint8_t * data) /* Ports */ m_ppi_port_outputs[0][0] = data[0x14011+0xc0]; m_ppi_port_outputs[0][1] = data[0x14011+0xc1]; - lviv_update_palette(m_ppi_port_outputs[0][1]&0x7f); + update_palette(m_ppi_port_outputs[0][1]&0x7f); m_ppi_port_outputs[0][2] = data[0x14011+0xc2]; - lviv_update_memory(); + update_memory(); } void lviv_state::dump_registers() @@ -269,7 +267,7 @@ void lviv_state::dump_registers() logerror("HL = %04x\n", (unsigned) m_maincpu->state_int(i8080_cpu_device::I8085_HL)); } -image_verify_result lviv_state::lviv_verify_snapshot(uint8_t * data, uint32_t size) +image_verify_result lviv_state::verify_snapshot(uint8_t * data, uint32_t size) { const char* tag = "LVOV/DUMP/2.0/"; @@ -289,18 +287,18 @@ image_verify_result lviv_state::lviv_verify_snapshot(uint8_t * data, uint32_t si return image_verify_result::PASS; } -SNAPSHOT_LOAD_MEMBER( lviv_state, lviv ) +SNAPSHOT_LOAD_MEMBER(lviv_state, lviv) { - std::vector lviv_snapshot_data(LVIV_SNAPSHOT_SIZE); + std::vector snapshot_data(LVIV_SNAPSHOT_SIZE); - image.fread( &lviv_snapshot_data[0], LVIV_SNAPSHOT_SIZE); + image.fread(&snapshot_data[0], LVIV_SNAPSHOT_SIZE); - if (lviv_verify_snapshot(&lviv_snapshot_data[0], snapshot_size) != image_verify_result::PASS) + if (verify_snapshot(&snapshot_data[0], snapshot_size) != image_verify_result::PASS) { return image_init_result::FAIL; } - lviv_setup_snapshot (&lviv_snapshot_data[0]); + setup_snapshot(&snapshot_data[0]); dump_registers(); diff --git a/src/mame/video/gaplus.cpp b/src/mame/video/gaplus.cpp index a7a492bc588..3ef083b6f79 100644 --- a/src/mame/video/gaplus.cpp +++ b/src/mame/video/gaplus.cpp @@ -25,46 +25,43 @@ ***************************************************************************/ -PALETTE_INIT_MEMBER(gaplus_state, gaplus) +PALETTE_INIT_MEMBER(gaplus_base_state, gaplus) { - const uint8_t *color_prom = memregion("proms")->base(); - int i; - - for (i = 0;i < 256;i++) + const uint8_t *color_prom = m_proms_region->base(); + for (int i = 0; i < 256; i++) { - int bit0,bit1,bit2,bit3,r,g,b; - /* red component */ - bit0 = (color_prom[i] >> 0) & 0x01; - bit1 = (color_prom[i] >> 1) & 0x01; - bit2 = (color_prom[i] >> 2) & 0x01; - bit3 = (color_prom[i] >> 3) & 0x01; - r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; - /* green component */ - bit0 = (color_prom[i + 0x100] >> 0) & 0x01; - bit1 = (color_prom[i + 0x100] >> 1) & 0x01; - bit2 = (color_prom[i + 0x100] >> 2) & 0x01; - bit3 = (color_prom[i + 0x100] >> 3) & 0x01; - g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + int bit0 = BIT(color_prom[i], 0); + int bit1 = BIT(color_prom[i], 1); + int bit2 = BIT(color_prom[i], 2); + int bit3 = BIT(color_prom[i], 3); + int r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + + /* green component */ + bit0 = BIT(color_prom[i + 0x100], 0); + bit1 = BIT(color_prom[i + 0x100], 1); + bit2 = BIT(color_prom[i + 0x100], 2); + bit3 = BIT(color_prom[i + 0x100], 3); + int g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; /* blue component */ - bit0 = (color_prom[i + 0x200] >> 0) & 0x01; - bit1 = (color_prom[i + 0x200] >> 1) & 0x01; - bit2 = (color_prom[i + 0x200] >> 2) & 0x01; - bit3 = (color_prom[i + 0x200] >> 3) & 0x01; - b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + bit0 = BIT(color_prom[i + 0x200], 0); + bit1 = BIT(color_prom[i + 0x200], 1); + bit2 = BIT(color_prom[i + 0x200], 2); + bit3 = BIT(color_prom[i + 0x200], 3); + int b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; - palette.set_indirect_color(i,rgb_t(r,g,b)); + palette.set_indirect_color(i, rgb_t(r, g, b)); } color_prom += 0x300; /* color_prom now points to the beginning of the lookup table */ /* characters use colors 0xf0-0xff */ - for (i = 0;i < m_gfxdecode->gfx(0)->colors() * m_gfxdecode->gfx(0)->granularity();i++) + for (int i = 0; i < m_gfxdecode->gfx(0)->colors() * m_gfxdecode->gfx(0)->granularity(); i++) palette.set_pen_indirect(m_gfxdecode->gfx(0)->colorbase() + i, 0xf0 + (*color_prom++ & 0x0f)); /* sprites */ - for (i = 0;i < m_gfxdecode->gfx(1)->colors() * m_gfxdecode->gfx(1)->granularity();i++) + for (int i = 0; i < m_gfxdecode->gfx(1)->colors() * m_gfxdecode->gfx(1)->granularity(); i++) { palette.set_pen_indirect(m_gfxdecode->gfx(1)->colorbase() + i, (color_prom[0] & 0x0f) + ((color_prom[0x200] & 0x0f) << 4)); color_prom++; @@ -80,23 +77,18 @@ PALETTE_INIT_MEMBER(gaplus_state, gaplus) ***************************************************************************/ /* convert from 32x32 to 36x28 */ -TILEMAP_MAPPER_MEMBER(gaplus_state::tilemap_scan) +TILEMAP_MAPPER_MEMBER(gaplus_base_state::tilemap_scan) { - int offs; - row += 2; col -= 2; if (col & 0x20) - offs = row + ((col & 0x1f) << 5); - else - offs = col + (row << 5); - - return offs; + return row + ((col & 0x1f) << 5); + return col + (row << 5); } -TILE_GET_INFO_MEMBER(gaplus_state::get_tile_info) +TILE_GET_INFO_MEMBER(gaplus_base_state::get_tile_info) { - uint8_t attr = m_videoram[tile_index + 0x400]; + const uint8_t attr = m_videoram[tile_index + 0x400]; tileinfo.category = (attr & 0x40) >> 6; tileinfo.group = attr & 0x3f; SET_TILE_INFO_MEMBER(0, @@ -123,42 +115,40 @@ TILE_GET_INFO_MEMBER(gaplus_state::get_tile_info) #define SPEED_2 1.0f #define SPEED_3 2.0f -void gaplus_state::starfield_init() +void gaplus_base_state::starfield_init() { - struct star *stars = m_stars; int generator = 0; - int x,y; int set = 0; - int width = m_screen->width(); - int height = m_screen->height(); + const int width = m_screen->width(); + const int height = m_screen->height(); m_total_stars = 0; /* precalculate the star background */ /* this comes from the Galaxian hardware, Gaplus is probably different */ - for ( y = 0;y < height; y++ ) { - for ( x = width*2 - 1; x >= 0; x--) { - int bit1,bit2; - + for (int y = 0; y < height; y++) + { + for (int x = width * 2 - 1; x >= 0; x--) + { generator <<= 1; - bit1 = (~generator >> 17) & 1; - bit2 = (generator >> 5) & 1; + const int bit1 = (~generator >> 17) & 1; + const int bit2 = (generator >> 5) & 1; if (bit1 ^ bit2) generator |= 1; - if ( ((~generator >> 16) & 1) && (generator & 0xff) == 0xff) { - int color; - - color = (~(generator >> 8)) & 0x3f; - if ( color && m_total_stars < MAX_STARS ) { - stars[m_total_stars].x = x; - stars[m_total_stars].y = y; - stars[m_total_stars].col = color; - stars[m_total_stars].set = set++; - - if ( set == 3 ) + if (BIT(~generator, 16) && (generator & 0xff) == 0xff) + { + const int color = ~(generator >> 8) & 0x3f; + if (color && m_total_stars < MAX_STARS) + { + m_stars[m_total_stars].x = x; + m_stars[m_total_stars].y = y; + m_stars[m_total_stars].col = color; + m_stars[m_total_stars].set = set++; + + if (set == 3) set = 0; m_total_stars++; @@ -176,7 +166,7 @@ void gaplus_state::starfield_init() ***************************************************************************/ -void gaplus_state::video_start() +void gaplus_base_state::video_start() { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(gaplus_state::get_tile_info),this),tilemap_mapper_delegate(FUNC(gaplus_state::tilemap_scan),this),8,8,36,28); @@ -202,16 +192,15 @@ void gaplus_state::video_start() ***************************************************************************/ -WRITE8_MEMBER(gaplus_state::videoram_w) +WRITE8_MEMBER(gaplus_base_state::videoram_w) { m_videoram[offset] = data; m_bg_tilemap->mark_tile_dirty(offset & 0x3ff); } -WRITE8_MEMBER(gaplus_state::starfield_control_w) +WRITE8_MEMBER(gaplus_base_state::starfield_control_w) { - offset &= 3; - m_starfield_control[offset] = data; + m_starfield_control[offset & 3] = data; } @@ -222,41 +211,35 @@ WRITE8_MEMBER(gaplus_state::starfield_control_w) ***************************************************************************/ -void gaplus_state::starfield_render(bitmap_ind16 &bitmap) +void gaplus_base_state::starfield_render(bitmap_ind16 &bitmap) { - struct star *stars = m_stars; - int i; - - int width = m_screen->width(); - int height = m_screen->height(); - /* check if we're running */ - if ( ( m_starfield_control[0] & 1 ) == 0 ) + if ((m_starfield_control[0] & 1) == 0) return; - /* draw the starfields */ - for ( i = 0; i < m_total_stars; i++ ) - { - int x, y; + const int width = m_screen->width(); + const int height = m_screen->height(); - x = stars[i].x; - y = stars[i].y; + /* draw the starfields */ + for (int i = 0; i < m_total_stars; i++) + { + int x = m_stars[i].x; + int y = m_stars[i].y; - if ( x >=0 && x < width && y >= 0 && y < height ) + if (x >= 0 && x < width && y >= 0 && y < height) { - bitmap.pix16(y, x) = stars[i].col; + bitmap.pix16(y, x) = m_stars[i].col; } } } -void gaplus_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ) +void gaplus_base_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ) const { uint8_t *spriteram = m_spriteram + 0x780; uint8_t *spriteram_2 = spriteram + 0x800; uint8_t *spriteram_3 = spriteram_2 + 0x800; - int offs; - for (offs = 0;offs < 0x80;offs += 2) + for (int offs = 0;offs < 0x80;offs += 2) { /* is it on? */ if ((spriteram_3[offs+1] & 2) == 0) @@ -266,16 +249,15 @@ void gaplus_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect { 0, 1 }, { 2, 3 } }; - int sprite = spriteram[offs] | ((spriteram_3[offs] & 0x40) << 2); - int color = spriteram[offs+1] & 0x3f; - int sx = spriteram_2[offs+1] + 0x100 * (spriteram_3[offs+1] & 1) - 71; + const int sprite = spriteram[offs] | ((spriteram_3[offs] & 0x40) << 2); + const int color = spriteram[offs+1] & 0x3f; + const int sx = spriteram_2[offs+1] + 0x100 * (spriteram_3[offs+1] & 1) - 71; int sy = 256 - spriteram_2[offs] - 8; - int flipx = (spriteram_3[offs] & 0x01); - int flipy = (spriteram_3[offs] & 0x02) >> 1; - int sizex = (spriteram_3[offs] & 0x08) >> 3; - int sizey = (spriteram_3[offs] & 0x20) >> 5; - int duplicate = spriteram_3[offs] & 0x80; - int x,y; + int flipx = BIT(spriteram_3[offs], 0); + int flipy = BIT(spriteram_3[offs], 1); + const int sizex = BIT(spriteram_3[offs], 3); + const int sizey = BIT(spriteram_3[offs], 5); + const int duplicate = spriteram_3[offs] & 0x80; if (flip_screen()) { @@ -286,15 +268,15 @@ void gaplus_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect sy -= 16 * sizey; sy = (sy & 0xff) - 32; // fix wraparound - for (y = 0;y <= sizey;y++) + for (int y = 0;y <= sizey; y++) { - for (x = 0;x <= sizex;x++) + for (int x = 0; x <= sizex; x++) { - m_gfxdecode->gfx(1)->transmask(bitmap,cliprect, + m_gfxdecode->gfx(1)->transmask(bitmap, cliprect, sprite + (duplicate ? 0 : (gfx_offs[y ^ (sizey * flipy)][x ^ (sizex * flipx)])), color, flipx,flipy, - sx + 16*x,sy + 16*y, + sx + 16 * x, sy + 16 * y, m_palette->transpen_mask(*m_gfxdecode->gfx(1), color, 0xff)); } } @@ -302,28 +284,28 @@ void gaplus_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect } } -uint32_t gaplus_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t gaplus_base_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { /* flip screen control is embedded in RAM */ - flip_screen_set(m_spriteram[0x1f7f-0x800] & 1); + flip_screen_set(m_spriteram[0x1f7f - 0x800] & 1); bitmap.fill(0, cliprect); starfield_render(bitmap); /* draw the low priority characters */ - m_bg_tilemap->draw(screen, bitmap, cliprect, 0,0); + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); draw_sprites(bitmap, cliprect); /* draw the high priority characters */ /* (I don't know if this feature is used by Gaplus, but it's shown in the schematics) */ - m_bg_tilemap->draw(screen, bitmap, cliprect, 1,0); + m_bg_tilemap->draw(screen, bitmap, cliprect, 1, 0); return 0; } -WRITE_LINE_MEMBER(gaplus_state::screen_vblank)/* update starfields */ +WRITE_LINE_MEMBER(gaplus_base_state::screen_vblank)/* update starfields */ { // falling edge if (!state) diff --git a/src/mame/video/lviv.cpp b/src/mame/video/lviv.cpp index db8577c316d..4fa8e63bf05 100644 --- a/src/mame/video/lviv.cpp +++ b/src/mame/video/lviv.cpp @@ -13,7 +13,7 @@ #include "emu.h" #include "includes/lviv.h" -const unsigned char lviv_palette[8*3] = +const uint8_t lviv_state::s_palette[8*3] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, @@ -28,54 +28,46 @@ const unsigned char lviv_palette[8*3] = PALETTE_INIT_MEMBER(lviv_state, lviv) { - int i; - - for ( i = 0; i < sizeof(lviv_palette) / 3; i++ ) { - m_palette->set_pen_color(i, lviv_palette[i*3], lviv_palette[i*3+1], lviv_palette[i*3+2]); + for (int i = 0; i < sizeof(s_palette) / 3; i++) + { + m_palette->set_pen_color(i, s_palette[i*3], s_palette[i*3+1], s_palette[i*3+2]); } } -void lviv_state::lviv_update_palette(uint8_t pal) +void lviv_state::update_palette(uint8_t pal) { m_colortable[0][0] = 0; m_colortable[0][1] = 0; m_colortable[0][2] = 0; m_colortable[0][3] = 0; - m_colortable[0][0] |= (((pal>>3)&0x01) == ((pal>>4)&0x01)) ? 0x04 : 0x00; - m_colortable[0][0] |= ((pal>>5)&0x01) ? 0x02 : 0x00; - m_colortable[0][0] |= (((pal>>2)&0x01) == ((pal>>6)&0x01)) ? 0x01 : 0x00; - - m_colortable[0][1] |= ((pal&0x01) == ((pal>>4)&0x01)) ? 0x04 : 0x00; - m_colortable[0][1] |= ((pal>>5)&0x01) ? 0x02 : 0x00; - m_colortable[0][1] |= ((pal>>6)&0x01) ? 0x00 : 0x01; + m_colortable[0][0] |= (BIT(pal, 3) == BIT(pal, 4)) ? 0x04 : 0x00; + m_colortable[0][0] |= BIT(pal, 5) ? 0x02 : 0x00; + m_colortable[0][0] |= (BIT(pal, 2) == BIT(pal, 6)) ? 0x01 : 0x00; - m_colortable[0][2] |= ((pal>>4)&0x01) ? 0x04 : 0x00; - m_colortable[0][2] |= ((pal>>5)&0x01) ? 0x00 : 0x02; - m_colortable[0][2] |= ((pal>>6)&0x01) ? 0x01 : 0x00; + m_colortable[0][1] |= (BIT(pal, 0) == BIT(pal, 4)) ? 0x04 : 0x00; + m_colortable[0][1] |= BIT(pal, 5) ? 0x02 : 0x00; + m_colortable[0][1] |= BIT(pal, 6) ? 0x00 : 0x01; - m_colortable[0][3] |= ((pal>>4)&0x01) ? 0x00 : 0x04; - m_colortable[0][3] |= (((pal>>1)&0x01) == ((pal>>5)&0x01)) ? 0x02 : 0x00; - m_colortable[0][3] |= ((pal>>6)&0x01) ? 0x01 : 0x00; -} + m_colortable[0][2] |= BIT(pal, 4) ? 0x04 : 0x00; + m_colortable[0][2] |= BIT(pal, 5) ? 0x00 : 0x02; + m_colortable[0][2] |= BIT(pal, 6) ? 0x01 : 0x00; -void lviv_state::video_start() -{ + m_colortable[0][3] |= BIT(pal, 4) ? 0x00 : 0x04; + m_colortable[0][3] |= (BIT(pal, 1) == BIT(pal, 5)) ? 0x02 : 0x00; + m_colortable[0][3] |= BIT(pal, 6) ? 0x01 : 0x00; } -uint32_t lviv_state::screen_update_lviv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t lviv_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - int x,y; - int pen; - uint8_t data; - - for (y=0; y<256; y++) - for (x=0; x<256; x+=4) + for (int y = 0; y < 256; y++) + { + for (int x = 0; x < 256; x += 4) { - data = m_video_ram[y*64+x/4]; + const uint8_t data = m_video_ram[(y << 6) | (x >> 2)]; - pen = m_colortable[0][((data & 0x08) >> 3) | ((data & 0x80) >> (3+3))]; + int pen = m_colortable[0][((data & 0x08) >> 3) | ((data & 0x80) >> (3+3))]; bitmap.pix16(y, x + 0) = pen; pen = m_colortable[0][((data & 0x04) >> 2) | ((data & 0x40) >> (2+3))]; @@ -87,5 +79,6 @@ uint32_t lviv_state::screen_update_lviv(screen_device &screen, bitmap_ind16 &bit pen = m_colortable[0][((data & 0x01) >> 0) | ((data & 0x10) >> (0+3))]; bitmap.pix16(y, x + 3) = pen; } + } return 0; } -- cgit v1.2.3 From d94e8b266445313038be2a86b3ae671dae30e529 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Tue, 12 Jun 2018 16:07:05 +1000 Subject: Revert "tms5220: fix the READYQ callback to poll the fifo state with a timer loop instead of always asserting the /ready via callback even if there is no more room in the FIFO, to match hardware. Fix the speak vsm mode to assume that the ADDR/DATA pin floats high if no VSM is attached, so that the speech chip doesn't get permanently stuck speaking silence if a spurious SPEAK VSM command is sent to it. Fix some race conditions with the INTQ callback and status flags not being updated before the callback is called. General cleanup and bool-ification of boolean variables. [Lord Nightmare]" This reverts commit 62fc2e8f068a67b84b324b1c2e9b55791850247e. See coments on https://github.com/mamedev/mame/commit/62fc2e8f068a67b84b324b1c2e9b55791850247e --- src/devices/sound/tms5220.cpp | 485 +++++++++++++++++++++--------------------- src/devices/sound/tms5220.h | 78 ++++--- 2 files changed, 275 insertions(+), 288 deletions(-) diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index d80d4a88f20..b0cf48a271a 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -198,10 +198,6 @@ Interpolation is inhibited (i.e. interpolation at IP frames will not happen ****Documentation of chip commands:*** - 76543210 (these are in logical 7 thru 0 order with MSB (7) first; TI calls - these bits by the opposite order, D0 thru D7, on the datasheet, - with D0 being the MSB) - x0x0xbcc: on 5200/5220: NOP (does nothing) on 5220C and CD2501ECD: Select frame length by cc, and b selects whether every frame is preceded by 2 bits to select the frame @@ -325,10 +321,9 @@ this), mostly on later pinballs with LPC speech) module (6511 based), IBM PS/2 Speech adapter (parallel port connection device), PES Speech adapter (serial port connection) -Street electronics had two later 1988-1990-era ECHO appleII cards which are -TSP50c0x/1x MCU based speech and not tms52xx based (though it is likely -emulating the tms5220 in MCU code). Look for a 16-pin chip at U6 labeled -"ECHO-2 SN" or "ECHO-3 SN". +Street electronics had a later 1989-era ECHO appleII card which is TSP50c0x/1x +MCU based speech and not tms5xxx based (though it is likely emulating the tms5220 +in MCU code). Look for a 16-pin chip at U6 labeled "ECHO-3 SN". ***********************************************************************************************/ @@ -387,8 +382,6 @@ static int16_t clip_analog(int16_t cliptemp); // above dumps info if a frame ran out of data #undef DEBUG_COMMAND_DUMP // above dumps all non-speech-data command writes -#undef DEBUG_COMMAND_VERBOSE -// above dumps decoded info about command writes #undef DEBUG_PIN_READS // above spams the errorlog with i/o ready messages whenever the ready or irq pin is read #undef DEBUG_GENERATION @@ -400,10 +393,9 @@ static int16_t clip_analog(int16_t cliptemp); #undef DEBUG_CLIP // above dumps info to stderr whenever the analog clip hardware is (or would be) clipping the signal. #undef DEBUG_IO_READY -// above debugs the io ready callback timer +// above debugs the io ready callback #undef DEBUG_RS_WS // above debugs the tms5220_data_r and data_w access methods which actually respect rs and ws -// TODO: switch the comments to be above the defines instead of below them #define MAX_SAMPLE_CHUNK 512 @@ -448,32 +440,12 @@ static const uint8_t reload_table[4] = { 0, 2, 4, 6 }; //sample count reload for void tms5220_device::register_for_save_states() { - // for sanity purposes these variables should be in the same order as in tms5220.h! - - // 5110 specific stuff - save_item(NAME(m_PDC)); - save_item(NAME(m_CTL_pins)); - save_item(NAME(m_state)); - - // new VSM stuff - save_item(NAME(m_address)); - save_item(NAME(m_next_is_address)); - save_item(NAME(m_schedule_dummy_read)); - save_item(NAME(m_addr_bit)); - save_item(NAME(m_CTL_buffer)); - - // old VSM stuff - save_item(NAME(m_read_byte_register)); - save_item(NAME(m_RDB_flag)); - - // FIFO save_item(NAME(m_fifo)); save_item(NAME(m_fifo_head)); save_item(NAME(m_fifo_tail)); save_item(NAME(m_fifo_count)); save_item(NAME(m_fifo_bits_taken)); - // global status bits (booleans) save_item(NAME(m_previous_TALK_STATUS)); save_item(NAME(m_SPEN)); save_item(NAME(m_DDIS)); @@ -484,7 +456,6 @@ void tms5220_device::register_for_save_states() save_item(NAME(m_irq_pin)); save_item(NAME(m_ready_pin)); - // current and previous frames save_item(NAME(m_OLDE)); save_item(NAME(m_OLDP)); @@ -521,59 +492,65 @@ void tms5220_device::register_for_save_states() save_item(NAME(m_RNG)); save_item(NAME(m_excitation_data)); + save_item(NAME(m_schedule_dummy_read)); + save_item(NAME(m_data_register)); + save_item(NAME(m_RDB_flag)); save_item(NAME(m_digital_select)); save_item(NAME(m_io_ready)); - // "proper" rs+ws emulation save_item(NAME(m_true_timing)); save_item(NAME(m_rs_ws)); save_item(NAME(m_read_latch)); save_item(NAME(m_write_latch)); + + // 5110 specific stuff + save_item(NAME(m_PDC)); + save_item(NAME(m_CTL_pins)); + save_item(NAME(m_state)); + save_item(NAME(m_address)); + save_item(NAME(m_next_is_address)); + save_item(NAME(m_addr_bit)); + save_item(NAME(m_CTL_buffer)); } /********************************************************************************************** - printbits helper function: takes an input and prints the resulting bits to a string buffer, passed to it using snprintf. + printbits helper function: takes a long int input and prints the resulting bits to stderr ***********************************************************************************************/ #ifdef DEBUG_PARSE_FRAME_DUMP_BIN -int tms5220_device::printbits(char *buffer, int count, unsigned int data, int num) +static void printbits(long data, int num) { - int retval = 0; int i; for (i=(num-1); i>=0; i--) - { - retval += snprintf(buffer+retval, count-retval, "%0d", (data>>i)&1); - } - retval += snprintf(buffer+retval, count-retval, " "); - return retval; + logerror("%0ld", (data>>i)&1); } #endif #ifdef DEBUG_PARSE_FRAME_DUMP_HEX -int tms5220_device::printbits(char *buffer, int count, unsigned int data, int num) +static void printbits(long data, int num) { - int retval = 0; switch((num-1)&0xFC) { case 0: - retval = snprintf(buffer, count, "%01x ", data); + logerror("%0lx", data); break; case 4: - retval = snprintf(buffer, count, "%02x ", data); + logerror("%02lx", data); break; case 8: - retval = snprintf(buffer, count, "%03x ", data); + logerror("%03lx", data); break; case 12: + logerror("%04lx", data); + break; default: - retval = snprintf(buffer, count, "%04x ", data); + logerror("%04lx", data); break; } - return retval; } #endif @@ -634,9 +611,10 @@ uint8_t tms5220_device::new_int_read() tms5220_device::data_write -- handle a write to the TMS5220 ***********************************************************************************************/ + void tms5220_device::data_write(int data) { - bool old_buffer_low = m_buffer_low; + int old_buffer_low = m_buffer_low; #ifdef DEBUG_DUMP_INPUT_DATA fprintf(stdout, "%c",data); #endif @@ -653,24 +631,24 @@ void tms5220_device::data_write(int data) #endif update_fifo_status_and_ints(); // if we just unset buffer low with that last write, and SPEN *was* zero (see circuit 251, sheet 12) - if ((!m_SPEN) && ((old_buffer_low) && (!m_buffer_low))) // MUST HAVE EDGE DETECT + if ((m_SPEN == 0) && ((old_buffer_low == 1) && (m_buffer_low == 0))) // MUST HAVE EDGE DETECT { int i; #ifdef DEBUG_FIFO logerror("data_write triggered SPEN to go active!\n"); #endif // ...then we now have enough bytes to start talking; set zpar and clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) - m_zpar = true; - m_uv_zpar = true; // zero k4-k10 as well - m_OLDE = true; // 'silence/zpar' frames are zero energy - m_OLDP = true; // 'silence/zpar' frames are zero pitch + m_zpar = 1; + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = true; // zero all the old parameters - m_old_uv_zpar = true; // zero old k4-k10 as well + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well #endif - m_SPEN = true; + m_SPEN = 1; #ifdef FAST_START_HACK - m_TALK = true; + m_TALK = 1; #endif m_new_frame_energy_idx = 0; m_new_frame_pitch_idx = 0; @@ -720,6 +698,7 @@ void tms5220_device::data_write(int data) Speak External command execution is terminated. ***********************************************************************************************/ + void tms5220_device::update_fifo_status_and_ints() { /* update 52xx fifo flags and set ints if needed */ @@ -733,13 +712,11 @@ void tms5220_device::update_fifo_status_and_ints() { // generate an interrupt if necessary; if /BL was inactive and is now active, set int. if (!m_buffer_low) - { - m_buffer_low = true; set_interrupt_state(1); - } + m_buffer_low = 1; } else - m_buffer_low = false; + m_buffer_low = 0; /* BE is set if neither byte 15 nor 14 of the fifo are in use; this translates to having fifo_count equal to exactly 0 @@ -748,25 +725,23 @@ void tms5220_device::update_fifo_status_and_ints() { // generate an interrupt if necessary; if /BE was inactive and is now active, set int. if (!m_buffer_empty) - { - m_buffer_empty = true; set_interrupt_state(1); - } + m_buffer_empty = 1; if (m_DDIS) - m_TALK = m_SPEN = false; // /BE being active clears the TALK status via TCON, which in turn clears SPEN, but ONLY if m_DDIS is set! See patent page 16, gate 232b + m_TALK = m_SPEN = 0; // /BE being active clears the TALK status via TCON, which in turn clears SPEN, but ONLY if m_DDIS is set! See patent page 16, gate 232b } else - m_buffer_empty = false; + m_buffer_empty = 0; // generate an interrupt if /TS was active, and is now inactive. // also, in this case, regardless if DDIS was set, unset it. - if (m_previous_TALK_STATUS && (!TALK_STATUS())) + if ((m_previous_TALK_STATUS == 1) && (TALK_STATUS() == 0)) { #ifdef VERBOSE logerror("Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); #endif set_interrupt_state(1); - m_DDIS = false; + m_DDIS = 0; } m_previous_TALK_STATUS = TALK_STATUS(); @@ -777,6 +752,7 @@ void tms5220_device::update_fifo_status_and_ints() extract_bits -- extract a specific number of bits from the current input stream (FIFO or VSM) ***********************************************************************************************/ + int tms5220_device::extract_bits(int count) { int val = 0; @@ -805,8 +781,6 @@ int tms5220_device::extract_bits(int count) // extract from VSM (speech ROM) if (m_speechrom) val = m_speechrom->read(count); - else - val = (1<> m_fifo_bits_taken) & 0xf; + if (val == 0) + /* 0 -> silence frame: we will only read 4 bits, and we will + * therefore need to read another frame before the FIFO is not + * full any more */ + answer += m_subc_reload?200:304; + /* 15 -> stop frame, we will only read 4 bits, but the FIFO will + * we cleared; otherwise, we need to parse the repeat flag (1 bit) + * and the pitch (6 bits), so everything will be OK. */ + } + } + + return answer; } + /********************************************************************************************** tms5220_int_read -- returns the interrupt state of the TMS5220 ***********************************************************************************************/ -bool tms5220_device::int_read() + +int tms5220_device::int_read() { #ifdef DEBUG_PIN_READS logerror("int_read: irq pin read, state is %d\n", m_irq_pin); @@ -889,14 +906,16 @@ bool tms5220_device::int_read() return m_irq_pin; } + /********************************************************************************************** tms5220_process -- fill the buffer with a specific number of samples ***********************************************************************************************/ + void tms5220_device::process(int16_t *buffer, unsigned int size) { - int buf_count = 0; + int buf_count=0; int i, bitout; int32_t this_sample; @@ -936,7 +955,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) /* if the new frame is a stop frame, unset both TALK and SPEN (via TCON). TALKD remains active while the energy is ramping to 0. */ if (NEW_FRAME_STOP_FLAG()) { - m_TALK = m_SPEN = false; + m_TALK = m_SPEN = 0; update_fifo_status_and_ints(); // probably not necessary... } @@ -947,20 +966,20 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) * Old frame was unvoiced, new is voiced * Old frame was unvoiced, new frame is silence/zero energy (non-existent on tms51xx rev D and F (present and working on tms52xx, present but buggy on tms51xx rev A and B)) */ - if ( (!OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_UNVOICED_FLAG()) - || (OLD_FRAME_UNVOICED_FLAG() && !NEW_FRAME_UNVOICED_FLAG()) - || (OLD_FRAME_SILENCE_FLAG() && !NEW_FRAME_SILENCE_FLAG()) - //|| ((m_inhibit == true) && OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_SILENCE_FLAG()) ) //TMS51xx INTERP BUG1 - || (OLD_FRAME_UNVOICED_FLAG() && NEW_FRAME_SILENCE_FLAG()) ) - m_inhibit = true; + if ( ((OLD_FRAME_UNVOICED_FLAG() == 0) && NEW_FRAME_UNVOICED_FLAG()) + || ((OLD_FRAME_UNVOICED_FLAG() == 1) && !NEW_FRAME_UNVOICED_FLAG()) + || ((OLD_FRAME_SILENCE_FLAG() == 1) && !NEW_FRAME_SILENCE_FLAG()) + //|| ((m_inhibit == 1) && (OLD_FRAME_UNVOICED_FLAG() == 1) && NEW_FRAME_SILENCE_FLAG()) ) //TMS51xx INTERP BUG1 + || ((OLD_FRAME_UNVOICED_FLAG() == 1) && NEW_FRAME_SILENCE_FLAG()) ) + m_inhibit = 1; else // normal frame, normal interpolation - m_inhibit = false; + m_inhibit = 0; #ifdef DEBUG_GENERATION /* Debug info for current parsed frame */ logerror( "OLDE: %d; NEWE: %d; OLDP: %d; NEWP: %d ", OLD_FRAME_SILENCE_FLAG(), NEW_FRAME_SILENCE_FLAG(), OLD_FRAME_UNVOICED_FLAG(), NEW_FRAME_UNVOICED_FLAG()); logerror("Processing new frame: "); - if (m_inhibit == false) + if (m_inhibit == 0) logerror( "Normal Frame\n"); else logerror("Interpolation Inhibited\n"); @@ -984,7 +1003,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } else // Not a new frame, just interpolate the existing frame. { - bool inhibit_state = ((m_inhibit == true) && (m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value + int inhibit_state = ((m_inhibit==1)&&(m_IP != 0)); // disable inhibit when reaching the last interp period, but don't overwrite the m_inhibit value #ifdef TMS5220_PERFECT_INTERPOLATION_HACK int samples_per_frame = m_subc_reload?175:266; // either (13 A cycles + 12 B cycles) * 7 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 7 interps for SPKSLOW //int samples_per_frame = m_subc_reload?200:304; // either (13 A cycles + 12 B cycles) * 8 interps for normal SPEAK/SPKEXT, or (13*2 A cycles + 12 B cycles) * 8 interps for SPKSLOW @@ -1005,7 +1024,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } else // we're done, play this frame for 1/8 frame. { - if (m_subcycle == 2) m_pitch_zero = false; // this reset happens around the second subcycle during IP=0 + if (m_subcycle == 2) m_pitch_zero = 0; // this reset happens around the second subcycle during IP=0 m_current_energy = (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)); m_current_pitch = (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)); for (i = 0; i < m_coeff->num_k; i++) @@ -1037,7 +1056,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) } // calculate the output - if (OLD_FRAME_UNVOICED_FLAG() == true) + if (OLD_FRAME_UNVOICED_FLAG() == 1) { // generate unvoiced samples here if (m_RNG & 1) @@ -1119,13 +1138,13 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) * According to testing the pitch zeroing lasts approximately 2 samples. * We set the zeroing latch here, and unset it on PC=1 in the generator. */ - if ((m_IP == 7)&&(m_inhibit == true)) m_pitch_zero = true; + if ((m_IP == 7)&&(m_inhibit==1)) m_pitch_zero = 1; if (m_IP == 7) // RESETL4 { // Latch OLDE and OLDP - //if (OLD_FRAME_SILENCE_FLAG()) m_uv_zpar = false; // TMS51xx INTERP BUG2 - OLD_FRAME_SILENCE_FLAG() = NEW_FRAME_SILENCE_FLAG() ? true : false; // m_OLDE - OLD_FRAME_UNVOICED_FLAG() = NEW_FRAME_UNVOICED_FLAG() ? true : false; // m_OLDP + //if (OLD_FRAME_SILENCE_FLAG()) m_uv_zpar = 0; // TMS51xx INTERP BUG2 + OLD_FRAME_SILENCE_FLAG() = NEW_FRAME_SILENCE_FLAG() ? 1 : 0; // m_OLDE + OLD_FRAME_UNVOICED_FLAG() = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; // m_OLDP /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */ #ifdef DEBUG_GENERATION logerror("RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); @@ -1136,7 +1155,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) #endif m_TALKD = m_TALK; // TALKD is latched from TALK update_fifo_status_and_ints(); // to trigger an interrupt if TALK_STATUS has changed - if ((!m_TALK) && m_SPEN) m_TALK = true; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). + if ((!m_TALK) && m_SPEN) m_TALK = 1; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). #ifdef DEBUG_GENERATION logerror("RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); #endif @@ -1152,7 +1171,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) m_PC++; } m_pitch_count++; - if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == true)) m_pitch_count = 0; + if ((m_pitch_count >= m_current_pitch)||(m_pitch_zero == 1)) m_pitch_count = 0; m_pitch_count &= 0x1FF; } else // m_TALKD == 0 @@ -1164,7 +1183,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) { m_TALKD = m_TALK; // TALKD is latched from TALK update_fifo_status_and_ints(); // probably not necessary - if ((!m_TALK) && m_SPEN) m_TALK = true; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). + if ((!m_TALK) && m_SPEN) m_TALK = 1; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). } m_subcycle = m_subc_reload; m_PC = 0; @@ -1188,6 +1207,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) clip_analog -- clips the 14 bit return value from the lattice filter to its final 10 bit value (-512 to 511), and upshifts/range extends this to 16 bits ***********************************************************************************************/ + static int16_t clip_analog(int16_t cliptemp) { /* clipping, just like the patent shows: @@ -1219,6 +1239,7 @@ static int16_t clip_analog(int16_t cliptemp) #endif } + /********************************************************************************************** matrix_multiply -- does the proper multiply and shift @@ -1251,6 +1272,7 @@ static int32_t matrix_multiply(int32_t a, int32_t b) resulting sample. ***********************************************************************************************/ + int32_t tms5220_device::lattice_filter() { // Lattice filter here @@ -1317,11 +1339,13 @@ int32_t tms5220_device::lattice_filter() return m_u[0]; } + /********************************************************************************************** process_command -- extract a byte from the FIFO and interpret it as a command ***********************************************************************************************/ + void tms5220_device::process_command(unsigned char cmd) { int i; @@ -1332,9 +1356,6 @@ void tms5220_device::process_command(unsigned char cmd) switch (cmd & 0x70) { case 0x10 : /* read byte */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Read Byte command received\n"); -#endif if (TALK_STATUS() == 0) /* TALKST must be clear for RDBY */ { if (m_schedule_dummy_read) @@ -1344,34 +1365,23 @@ void tms5220_device::process_command(unsigned char cmd) m_speechrom->read(1); } if (m_speechrom) - m_read_byte_register = m_speechrom->read(8); /* read one byte from speech ROM... */ + m_data_register = m_speechrom->read(8); /* read one byte from speech ROM... */ m_RDB_flag = true; } -#ifdef DEBUG_COMMAND_VERBOSE - else - logerror("Read Byte command received during TALK state, ignoring!\n"); -#endif break; case 0x00: case 0x20: /* set rate (tms5220c and cd2501ecd only), otherwise NOP */ if (TMS5220_HAS_RATE_CONTROL) -#ifdef DEBUG_COMMAND_VERBOSE { - logerror("Set Rate (or NOP) command received\n"); -#endif m_c_variant_rate = cmd&0x0F; -#ifdef DEBUG_COMMAND_VERBOSE } - else - logerror("NOP command received\n"); -#endif break; case 0x30 : /* read and branch */ if (TALK_STATUS() == 0) /* TALKST must be clear for RB */ { -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Read and Branch command received\n"); +#ifdef VERBOSE + logerror("read and branch command received\n"); #endif m_RDB_flag = false; if (m_speechrom) @@ -1380,9 +1390,6 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x40 : /* load address */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Load Address command received\n"); -#endif if (TALK_STATUS() == 0) /* TALKST must be clear for LA */ { /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. @@ -1391,16 +1398,9 @@ void tms5220_device::process_command(unsigned char cmd) m_speechrom->load_address(cmd & 0x0f); m_schedule_dummy_read = true; } -#ifdef DEBUG_COMMAND_VERBOSE - else - logerror("Load Address command received during TALK state, ignoring!\n"); -#endif break; case 0x50 : /* speak */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Speak (VSM) command received\n"); -#endif if (m_schedule_dummy_read) { m_schedule_dummy_read = false; @@ -1411,14 +1411,14 @@ void tms5220_device::process_command(unsigned char cmd) #ifdef FAST_START_HACK m_TALK = 1; #endif - m_DDIS = false; // speak using VSM - m_zpar = true; // zero all the parameters - m_uv_zpar = true; // zero k4-k10 as well - m_OLDE = true; // 'silence/zpar' frames are zero energy - m_OLDP = true; // 'silence/zpar' frames are zero pitch + m_DDIS = 0; + m_zpar = 1; // zero all the parameters + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = true; // zero all the old parameters - m_old_uv_zpar = true; // zero old k4-k10 as well + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well #endif // following is semi-hack but matches idle state observed on chip m_new_frame_energy_idx = 0; @@ -1432,21 +1432,17 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x60 : /* speak external */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Speak External command received\n"); -#endif - // SPKEXT going active asserts /SPKEE for 2 clocks, which clears the FIFO and its counters - memset(m_fifo, 0, sizeof(m_fifo[0])*FIFO_SIZE); + // SPKEXT going active activates SPKEE which clears the fifo m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; - // SPEN is enabled when the FIFO passes half full (falling edge of BL signal) - m_DDIS = true; // speak using FIFO - m_zpar = true; // zero all the parameters - m_uv_zpar = true; // zero k4-k10 as well - m_OLDE = true; // 'silence/zpar' frames are zero energy - m_OLDP = true; // 'silence/zpar' frames are zero pitch + // SPEN is enabled when the fifo passes half full (falling edge of BL signal) + m_DDIS = 1; + m_zpar = 1; // zero all the parameters + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = true; // zero all the old parameters - m_old_uv_zpar = true; // zero old k4-k10 as well + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well #endif // following is semi-hack but matches idle state observed on chip m_new_frame_energy_idx = 0; @@ -1461,9 +1457,6 @@ void tms5220_device::process_command(unsigned char cmd) break; case 0x70 : /* reset */ -#ifdef DEBUG_COMMAND_VERBOSE - logerror("Reset command received\n"); -#endif if (m_schedule_dummy_read) { m_schedule_dummy_read = false; @@ -1483,17 +1476,9 @@ void tms5220_device::process_command(unsigned char cmd) parse_frame -- parse a new frame's worth of data; returns 0 if not enough bits in buffer ******************************************************************************************/ + void tms5220_device::parse_frame() { -#ifdef DEBUG_PARSE_FRAME_DUMP - char p_buffer[64] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - }; - uint8_t p_buffer_count = 0; -#endif int i, rep_flag; #ifdef TMS5220_PERFECT_INTERPOLATION_HACK m_old_uv_zpar = m_uv_zpar; @@ -1511,7 +1496,8 @@ void tms5220_device::parse_frame() { i = extract_bits(2); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, i, 2); + printbits(i,2); + logerror(" "); #endif m_IP = reload_table[i]; } @@ -1524,7 +1510,8 @@ void tms5220_device::parse_frame() // attempt to extract the energy index m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_energy_idx, m_coeff->energy_bits); + printbits(m_new_frame_energy_idx,m_coeff->energy_bits); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1532,16 +1519,19 @@ void tms5220_device::parse_frame() if ((m_new_frame_energy_idx == 0) || (m_new_frame_energy_idx == 15)) return; + // attempt to extract the repeat flag rep_flag = extract_bits(1); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, rep_flag, 1); + printbits(rep_flag, 1); + logerror(" "); #endif // attempt to extract the pitch m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_pitch_idx,m_coeff->pitch_bits); + printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits); + logerror(" "); #endif // if the new frame is unvoiced, be sure to zero out the k5-k10 parameters m_uv_zpar = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; @@ -1556,7 +1546,8 @@ void tms5220_device::parse_frame() { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_k_idx[i],m_coeff->kbits[i]); + printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; @@ -1574,13 +1565,14 @@ void tms5220_device::parse_frame() { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); #ifdef DEBUG_PARSE_FRAME_DUMP - p_buffer_count += printbits(p_buffer+p_buffer_count, 64-p_buffer_count, m_new_frame_k_idx[i],m_coeff->kbits[i]); + printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); + logerror(" "); #endif update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; } #ifdef DEBUG_PARSE_FRAME_DUMP - logerror("%s\n", p_buffer); + logerror("\n"); #endif #ifdef VERBOSE if (m_DDIS) @@ -1602,6 +1594,7 @@ void tms5220_device::parse_frame() set_interrupt_state -- generate an interrupt ***********************************************************************************************/ + void tms5220_device::set_interrupt_state(int state) { if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin @@ -1618,18 +1611,16 @@ void tms5220_device::set_interrupt_state(int state) update_ready_state -- update the ready line ***********************************************************************************************/ + void tms5220_device::update_ready_state() { - bool state = ready_read(); - if (m_ready_pin != state) - { + int state = ready_read(); #ifdef DEBUG_PIN_READS - logerror("ready pin set to state %d\n", state); + logerror("ready pin set to state %d\n", state); #endif - if (!m_readyq_handler.isnull()) - m_readyq_handler(!state); - m_ready_pin = state; - } + if (!m_readyq_handler.isnull() && state != m_ready_pin) + m_readyq_handler(!state); + m_ready_pin = state; } @@ -1697,13 +1688,11 @@ void tms5220_device::device_start() m_stream = machine().sound().stream_alloc(*this, 0, 1, clock() / 80); m_timer_io_ready = timer_alloc(0); - //m_timer_rsq_wsq_check = timer_alloc(1); /* not during reset which is called from within a write! */ - m_io_ready = true; - m_true_timing = false; + m_io_ready = 1; + m_true_timing = 0; m_rs_ws = 0x03; // rs and ws are assumed to be inactive on device startup - m_write_latch = 0; // assume on start that nothing is driving the data bus register_for_save_states(); } @@ -1716,15 +1705,15 @@ void tms5220_device::device_reset() { m_digital_select = FORCE_DIGITAL; // assume analog output /* initialize the FIFO */ - memset(m_fifo, 0, sizeof(m_fifo[0])*FIFO_SIZE); + /*memset(m_fifo, 0, sizeof(m_fifo));*/ m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; /* initialize the chip state */ /* Note that we do not actually clear IRQ on start-up : IRQ is even raised if m_buffer_empty or m_buffer_low are 0 */ - m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = false; + m_SPEN = m_DDIS = m_TALK = m_TALKD = m_previous_TALK_STATUS = m_irq_pin = m_ready_pin = 0; set_interrupt_state(0); update_ready_state(); - m_buffer_empty = m_buffer_low = true; + m_buffer_empty = m_buffer_low = 1; m_RDB_flag = false; @@ -1732,24 +1721,24 @@ void tms5220_device::device_reset() #ifdef TMS5220_PERFECT_INTERPOLATION_HACK m_old_frame_energy_idx = m_old_frame_pitch_idx = 0; memset(m_old_frame_k_idx, 0, sizeof(m_old_frame_k_idx)); - m_old_zpar = false; + m_old_zpar = 0; #endif m_new_frame_energy_idx = m_current_energy = m_previous_energy = 0; m_new_frame_pitch_idx = m_current_pitch = 0; - m_zpar = m_uv_zpar = false; + m_zpar = m_uv_zpar = 0; memset(m_new_frame_k_idx, 0, sizeof(m_new_frame_k_idx)); memset(m_current_k, 0, sizeof(m_current_k)); /* initialize the sample generators */ - m_inhibit = true; + m_inhibit = 1; m_subcycle = m_c_variant_rate = m_pitch_count = m_PC = 0; m_subc_reload = FORCE_SUBC_RELOAD; - m_OLDE = m_OLDP = true; + m_OLDE = m_OLDP = 1; m_IP = reload_table[m_c_variant_rate&0x3]; m_RNG = 0x1FFF; memset(m_u, 0, sizeof(m_u)); memset(m_x, 0, sizeof(m_x)); - m_schedule_dummy_read = false; + m_schedule_dummy_read = 0; if (m_speechrom) { @@ -1757,7 +1746,7 @@ void tms5220_device::device_reset() // MZ: Do the dummy read immediately. The previous line will cause a // shift in the address pointer in the VSM. When the next command is a // load_address, no dummy read will occur, hence the address will be - // incorrectly shifted. + // falsely shifted. m_speechrom->read(1); m_schedule_dummy_read = false; } @@ -1783,61 +1772,41 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para { switch(id) { - case 0: // m_timer_io_ready - /* bring up to date first */ - m_stream->update(); -#ifdef DEBUG_IO_READY - logerror("m_timer_io_ready timer fired, param = %02x, m_rs_ws = %02x\n", param, m_rs_ws); -#endif - if (param) // low->high ready state + case 0: + if (param) { switch (m_rs_ws) { case 0x02: /* Write */ + /* bring up to date first */ #ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: Attempting to service write...\n"); -#endif - if ((m_fifo_count >= FIFO_SIZE) && m_DDIS) // if fifo is full and we're in speak external mode - { -#ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: in SPKEXT and FIFO was full! cannot service write now, delaying 16 cycles...\n"); -#endif - m_timer_io_ready->adjust(clocks_to_attotime(16), 1); - break; - } - else - { -#ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: Serviced write: %02x\n", m_write_latch); + logerror("Serviced write: %02x\n", m_write_latch); + //logerror( "Processed write data: %02X\n", m_write_latch); #endif - data_write(m_write_latch); - m_io_ready = param; - break; - } + m_stream->update(); + data_write(m_write_latch); + break; case 0x01: /* Read */ - m_read_latch = status_read(true); + /* bring up to date first */ + m_stream->update(); + m_read_latch = status_read(); #ifdef DEBUG_IO_READY - logerror("m_timer_io_ready: Serviced read, returning %02x\n", m_read_latch); + logerror("Serviced read, returning %02x\n", m_read_latch); #endif - m_io_ready = param; break; case 0x03: /* High Impedance */ - m_io_ready = param; case 0x00: /* illegal */ - m_io_ready = param; break; } } + m_io_ready = param; update_ready_state(); break; - /*case 1: // m_timer_rsq_wsq_check - // TODO: write me, and get rid of the garbage in wsq_w, rsq_w, etc! - break; */ } } @@ -1848,7 +1817,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) { uint8_t new_val; - m_true_timing = true; + m_true_timing = 1; state &= 0x01; #ifdef DEBUG_RS_WS logerror("/RS written with data: %d\n", state); @@ -1859,7 +1828,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) m_rs_ws = new_val; if (new_val == 0) { - if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, probably also correct for cd2501ecd + if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, ? for cd2501ecd reset(); #ifdef DEBUG_RS_WS else @@ -1885,11 +1854,10 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) logerror("Scheduling ready cycle for /RS...\n"); #endif /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); - /* How long does /READY stay inactive, when /RS is pulled low? It might be always ~16 clocks (25 usec at 800khz as shown on the datasheet) - but the patent schematic implies it might be as short as 4 clock cycles. */ - m_timer_io_ready->adjust(clocks_to_attotime(16), 1); + /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */ + m_timer_io_ready->adjust(clocks_to_attotime(16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete } } } @@ -1901,7 +1869,7 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) { uint8_t new_val; - m_true_timing = true; + m_true_timing = 1; state &= 0x01; #ifdef DEBUG_RS_WS logerror("/WS written with data: %d\n", state); @@ -1938,7 +1906,7 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) logerror("Scheduling ready cycle for /WS...\n"); #endif /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); /* Now comes the complicated part: how long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not... Speak external mode: ~16 cycles @@ -1965,7 +1933,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) { uint8_t new_val; uint8_t falling_edges; - m_true_timing = true; + m_true_timing = 1; #ifdef DEBUG_RS_WS logerror("/RS and /WS written with %d and %d respectively\n", (data&2)>>1, data&1); #endif @@ -1997,7 +1965,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) logerror("Scheduling ready cycle for /WS...\n"); #endif /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); /* Now comes the complicated part: how long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not... Speak external mode: ~16 cycles @@ -2020,7 +1988,7 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) logerror("Scheduling ready cycle for /RS...\n"); #endif /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ - m_io_ready = false; + m_io_ready = 0; update_ready_state(); /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */ m_timer_io_ready->adjust(clocks_to_attotime(16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete @@ -2038,14 +2006,18 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) void tms5220_device::write_data(uint8_t data) { + // prevent debugger from changing the internal state + if (machine().side_effects_disabled()) return; + #ifdef DEBUG_RS_WS logerror("tms5220_data_w: data %02x\n", data); #endif - /* bring up to date first */ - m_stream->update(); - m_write_latch = data; - if (!m_true_timing) // if we're in the default hacky mode where we don't bother with rsq_w and wsq_w... - data_write(m_write_latch); // ...force the write through instantly. + if (!m_true_timing) + { + /* bring up to date first */ + m_stream->update(); + data_write(data); + } else { /* actually in a write ? */ @@ -2053,9 +2025,12 @@ void tms5220_device::write_data(uint8_t data) if (!(m_rs_ws == 0x02)) logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); #endif + m_write_latch = data; } } + + /********************************************************************************************** tms5220_status_r -- read status or data from the sound chip @@ -2064,15 +2039,14 @@ void tms5220_device::write_data(uint8_t data) uint8_t tms5220_device::read_status() { - /* bring up to date first */ - m_stream->update(); + // prevent debugger from changing the internal state + if (machine().side_effects_disabled()) return 0; if (!m_true_timing) { - // prevent debugger from changing the internal state - if (machine().side_effects_disabled()) - return status_read(false); - return status_read(true); + /* bring up to date first */ + m_stream->update(); + return status_read(); } else { @@ -2083,7 +2057,7 @@ uint8_t tms5220_device::read_status() else logerror("tms5220_status_r: data read outside rs!\n"); #endif - return 0xff; // m_write_latch; // return open bus + return 0xff; } } @@ -2104,6 +2078,21 @@ READ_LINE_MEMBER( tms5220_device::readyq_r ) +/********************************************************************************************** + + tms5220_time_to_ready -- return the time until the ready line is asserted + +***********************************************************************************************/ + +attotime tms5220_device::time_to_ready() +{ + /* bring up to date first */ + m_stream->update(); + return clocks_to_attotime(cycles_to_ready() * 80); +} + + + /********************************************************************************************** tms5220_int_r -- return the int status from the sound chip diff --git a/src/devices/sound/tms5220.h b/src/devices/sound/tms5220.h index 0b7617be505..4cfab5491ef 100644 --- a/src/devices/sound/tms5220.h +++ b/src/devices/sound/tms5220.h @@ -90,6 +90,8 @@ public: READ_LINE_MEMBER( readyq_r ); READ_LINE_MEMBER( intq_r ); + attotime time_to_ready(); + protected: tms5220_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int variant); @@ -116,23 +118,20 @@ private: void data_write(int data); void update_fifo_status_and_ints(); int extract_bits(int count); - uint8_t status_read(bool clear_int); - bool ready_read(); - bool int_read(); + int status_read(); + int ready_read(); + int cycles_to_ready(); + int int_read(); void process(int16_t *buffer, unsigned int size); int32_t lattice_filter(); void process_command(unsigned char cmd); void parse_frame(); void set_interrupt_state(int state); void update_ready_state(); - //debug -#ifdef DEBUG_PARSE_FRAME_DUMP - printbits(char *buffer, int count, unsigned int data, int num); -#endif - bool TALK_STATUS() const { return m_SPEN || m_TALKD; } - bool &OLD_FRAME_SILENCE_FLAG() { return m_OLDE; } // 1 if E=0, 0 otherwise. - bool &OLD_FRAME_UNVOICED_FLAG() { return m_OLDP; } // 1 if P=0 (unvoiced), 0 if voiced + uint8_t TALK_STATUS() const { return m_SPEN | m_TALKD; } + uint8_t &OLD_FRAME_SILENCE_FLAG() { return m_OLDE; } // 1 if E=0, 0 otherwise. + uint8_t &OLD_FRAME_UNVOICED_FLAG() { return m_OLDP; } // 1 if P=0 (unvoiced), 0 if voiced bool NEW_FRAME_STOP_FLAG() const { return m_new_frame_energy_idx == 0x0F; } // 1 if this is a stop (Energy = 0xF) frame bool NEW_FRAME_SILENCE_FLAG() const { return m_new_frame_energy_idx == 0; } // ditto as above bool NEW_FRAME_UNVOICED_FLAG() const { return m_new_frame_pitch_idx == 0; } // ditto as above @@ -145,23 +144,23 @@ private: /* coefficient tables */ const struct tms5100_coeffs *m_coeff; - /* these contain global status bits for the 5100 */ + /* these contain global status bits */ uint8_t m_PDC; uint8_t m_CTL_pins; uint8_t m_state; /* New VSM interface */ uint32_t m_address; - bool m_next_is_address; - bool m_schedule_dummy_read; + uint8_t m_next_is_address; + uint8_t m_schedule_dummy_read; uint8_t m_addr_bit; /* read byte */ uint8_t m_CTL_buffer; /* Old VSM interface; R Nabet : These have been added to emulate speech Roms */ - //bool m_schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */ - uint8_t m_read_byte_register; /* a serial->parallel shifter, used by "read byte" command to store 8 bits from the VSM */ - bool m_RDB_flag; /* whether we should read data register or status register */ + //uint8_t m_schedule_dummy_read; /* set after each load address, so that next read operation is preceded by a dummy read */ + uint8_t m_data_register; /* data register, used by read command */ + uint8_t m_RDB_flag; /* whether we should read data register or status register */ /* these contain data that describes the 128-bit data FIFO */ uint8_t m_fifo[FIFO_SIZE]; @@ -171,20 +170,20 @@ private: uint8_t m_fifo_bits_taken; - /* these contain global status bits (booleans) */ - bool m_previous_TALK_STATUS;/* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */ - bool m_SPEN; /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */ - bool m_DDIS; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */ - bool m_TALK; /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */ - bool m_TALKD; /* TALK(TCON) value, latched every RESETL4 */ - bool m_buffer_low; /* If 1, FIFO has less than 8 bytes in it */ - bool m_buffer_empty; /* If 1, FIFO is empty */ - bool m_irq_pin; /* state of the IRQ pin (output) */ - bool m_ready_pin; /* state of the READY pin (output) */ + /* these contain global status bits */ + uint8_t m_previous_TALK_STATUS; /* this is the OLD value of TALK_STATUS (i.e. previous value of m_SPEN|m_TALKD), needed for generating interrupts on a falling TALK_STATUS edge */ + uint8_t m_SPEN; /* set on speak(or speak external and BL falling edge) command, cleared on stop command, reset command, or buffer out */ + uint8_t m_DDIS; /* If 1, DDIS is 1, i.e. Speak External command in progress, writes go to FIFO. */ + uint8_t m_TALK; /* set on SPEN & RESETL4(pc12->pc0 transition), cleared on stop command or reset command */ + uint8_t m_TALKD; /* TALK(TCON) value, latched every RESETL4 */ + uint8_t m_buffer_low; /* If 1, FIFO has less than 8 bytes in it */ + uint8_t m_buffer_empty; /* If 1, FIFO is empty */ + uint8_t m_irq_pin; /* state of the IRQ pin (output) */ + uint8_t m_ready_pin; /* state of the READY pin (output) */ /* these contain data describing the current and previous voice frames */ - bool m_OLDE; - bool m_OLDP; + uint8_t m_OLDE; + uint8_t m_OLDP; uint8_t m_new_frame_energy_idx; uint8_t m_new_frame_pitch_idx; @@ -200,8 +199,8 @@ private: uint8_t m_old_frame_energy_idx; uint8_t m_old_frame_pitch_idx; uint8_t m_old_frame_k_idx[10]; - bool m_old_zpar; - bool m_old_uv_zpar; + uint8_t m_old_zpar; + uint8_t m_old_uv_zpar; int32_t m_current_energy; int32_t m_current_pitch; @@ -215,11 +214,11 @@ private: uint8_t m_PC; /* current parameter counter (what param is being interpolated), ranges from 0 to 12 */ /* NOTE: the interpolation period counts 1,2,3,4,5,6,7,0 for divide by 8,8,8,4,4,2,2,1 */ uint8_t m_IP; /* the current interpolation period */ - bool m_inhibit; /* If 1, interpolation is inhibited until the DIV1 period */ - bool m_uv_zpar; /* If 1, zero k5 thru k10 coefficients */ - bool m_zpar; /* If 1, zero ALL parameters. */ - bool m_pitch_zero; /* circuit 412; pitch is forced to zero under certain circumstances */ - uint8_t m_c_variant_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */ + uint8_t m_inhibit; /* If 1, interpolation is inhibited until the DIV1 period */ + uint8_t m_uv_zpar; /* If 1, zero k5 thru k10 coefficients */ + uint8_t m_zpar; /* If 1, zero ALL parameters. */ + uint8_t m_pitch_zero; /* circuit 412; pitch is forced to zero under certain circumstances */ + uint8_t m_c_variant_rate; /* only relevant for tms5220C's multi frame rate feature; is the actual 4 bit value written on a 0x2* or 0x0* command */ uint16_t m_pitch_count; /* pitch counter; provides chirp rom address */ int32_t m_u[11]; @@ -233,17 +232,17 @@ private: The internal DAC used to feed the analog pin is only 8 bits, and has the funny clipping/clamping logic, while the digital pin gives full 10 bit resolution of the output data. - TODO: add an MCFG macro to set this other than the FORCE_DIGITAL define + TODO: add a way to set/reset this other than the FORCE_DIGITAL define */ - bool m_digital_select; + uint8_t m_digital_select; /* io_ready: page 3 of the datasheet specifies that READY will be asserted until * data is available or processed by the system. */ - bool m_io_ready; + uint8_t m_io_ready; /* flag for "true" timing involving rs/ws */ - bool m_true_timing; + uint8_t m_true_timing; /* rsws - state, rs bit 1, ws bit 0 */ uint8_t m_rs_ws; @@ -252,7 +251,6 @@ private: sound_stream *m_stream; emu_timer *m_timer_io_ready; - //emu_timer *m_timer_rsq_wsq_check; /* callbacks */ devcb_write_line m_irq_handler; -- cgit v1.2.3 From 4c62c8a48f56402f1683a04e9510529899175a9e Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 12 Jun 2018 10:20:47 -0400 Subject: tms5220: Convert logging calls to logmacro.h standard (nw) This also reinstates the command logging improvements from 62fc2e8f068a67b84b324b1c2e9b55791850247e. --- src/devices/sound/tms5220.cpp | 596 +++++++++++++++++++----------------------- src/devices/sound/tms5220.h | 5 + 2 files changed, 268 insertions(+), 333 deletions(-) diff --git a/src/devices/sound/tms5220.cpp b/src/devices/sound/tms5220.cpp index b0cf48a271a..7d6ac1abc93 100644 --- a/src/devices/sound/tms5220.cpp +++ b/src/devices/sound/tms5220.cpp @@ -330,8 +330,6 @@ in MCU code). Look for a 16-pin chip at U6 labeled "ECHO-3 SN". #include "emu.h" #include "tms5220.h" -static int16_t clip_analog(int16_t cliptemp); - /* *****optional defines***** */ /* Hacky improvements which don't match patent: */ @@ -365,38 +363,41 @@ static int16_t clip_analog(int16_t cliptemp); /* *****debugging defines***** */ -#undef VERBOSE +#define LOG_GENERAL (1 << 0) // above is general, somewhat obsolete, catch all for debugs which don't fit elsewhere -#undef DEBUG_DUMP_INPUT_DATA +#define LOG_DUMP_INPUT_DATA (1 << 1) /* 5220 only; above dumps the data written to the tms52xx to stdout, useful for making logged data dumps for real hardware tests */ -#undef DEBUG_FIFO +#define LOG_FIFO (1 << 2) // 5220 only; above debugs fifo stuff: writes, reads and flag updates -#undef DEBUG_PARSE_FRAME_DUMP -// above dumps each frame to stderr: be sure to select one of the options below if you define it! -#undef DEBUG_PARSE_FRAME_DUMP_BIN +#define LOG_PARSE_FRAME_DUMP_BIN (1 << 3) // dumps each speech frame as binary -#undef DEBUG_PARSE_FRAME_DUMP_HEX +#define LOG_PARSE_FRAME_DUMP_HEX (1 << 4) // dumps each speech frame as hex -#undef DEBUG_FRAME_ERRORS +#define LOG_FRAME_ERRORS (1 << 6) // above dumps info if a frame ran out of data -#undef DEBUG_COMMAND_DUMP +#define LOG_COMMAND_DUMP (1 << 7) // above dumps all non-speech-data command writes -#undef DEBUG_PIN_READS +#define LOG_COMMAND_VERBOSE (1 << 8) +// above dumps decoded info about command writes +#define LOG_PIN_READS (1 << 9) // above spams the errorlog with i/o ready messages whenever the ready or irq pin is read -#undef DEBUG_GENERATION +#define LOG_GENERATION (1 << 10) // above dumps debug information related to the sample generation loop, i.e. whether interpolation is inhibited or not, and what the current and target values for each frame are. -#undef DEBUG_GENERATION_VERBOSE +#define LOG_GENERATION_VERBOSE (1 << 11) // above dumps MUCH MORE debug information related to the sample generation loop, namely the excitation, energy, pitch, k*, and output values for EVERY SINGLE SAMPLE during a frame. -#undef DEBUG_LATTICE +#define LOG_LATTICE (1 << 12) // above dumps the lattice filter state data each sample. -#undef DEBUG_CLIP +#define LOG_CLIP (1 << 13) // above dumps info to stderr whenever the analog clip hardware is (or would be) clipping the signal. -#undef DEBUG_IO_READY -// above debugs the io ready callback -#undef DEBUG_RS_WS +#define LOG_IO_READY (1 << 14) +// above debugs the io ready callback timer +#define LOG_RS_WS (1 << 15) // above debugs the tms5220_data_r and data_w access methods which actually respect rs and ws +//#define VERBOSE (LOG_GENERAL | LOG_DUMP_INPUT_DATA | LOG_FIFO | LOG_PARSE_FRAME_DUMP_HEX | LOG_FRAME_ERRORS | LOG_COMMAND_DUMP | LOG_COMMAND_VERBOSE | LOG_PIN_READS | LOG_GENERATION | LOG_GENERATION_VERBOSE | LOG_LATTICE | LOG_CLIP | LOG_IO_READY | LOG_RS_WS) +#include "logmacro.h" + #define MAX_SAMPLE_CHUNK 512 /* 6+4 Variants, from tms5110r.inc */ @@ -522,37 +523,30 @@ void tms5220_device::register_for_save_states() ***********************************************************************************************/ -#ifdef DEBUG_PARSE_FRAME_DUMP_BIN -static void printbits(long data, int num) -{ - int i; - for (i=(num-1); i>=0; i--) - logerror("%0ld", (data>>i)&1); -} -#endif -#ifdef DEBUG_PARSE_FRAME_DUMP_HEX -static void printbits(long data, int num) +void tms5220_device::printbits(long data, int num) { - switch((num-1)&0xFC) + for (int i = num - 1; i >= 0; i--) + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN, "%0ld", (data>>i)&1); + + switch ((num - 1) & 0xfc) { - case 0: - logerror("%0lx", data); - break; - case 4: - logerror("%02lx", data); - break; - case 8: - logerror("%03lx", data); - break; - case 12: - logerror("%04lx", data); - break; - default: - logerror("%04lx", data); - break; + case 0: + LOGMASKED(LOG_PARSE_FRAME_DUMP_HEX, "%0lx", data); + break; + case 4: + LOGMASKED(LOG_PARSE_FRAME_DUMP_HEX, "%02lx", data); + break; + case 8: + LOGMASKED(LOG_PARSE_FRAME_DUMP_HEX, "%03lx", data); + break; + case 12: + LOGMASKED(LOG_PARSE_FRAME_DUMP_HEX, "%04lx", data); + break; + default: + LOGMASKED(LOG_PARSE_FRAME_DUMP_HEX, "%04lx", data); + break; } } -#endif /********************************************************************************************** @@ -600,9 +594,7 @@ uint8_t tms5220_device::new_int_read() new_int_write(0, 0, 0, 0); // romclk 0, m0 0, m1 0, addr bus nybble = 0/open bus if (!m_data_cb.isnull()) return m_data_cb(); -#ifdef VERBOSE - logerror("WARNING: CALLBACK MISSING, RETURNING 0!\n"); -#endif + LOGMASKED(LOG_GENERAL, "WARNING: CALLBACK MISSING, RETURNING 0!\n"); return 0; } @@ -615,9 +607,8 @@ uint8_t tms5220_device::new_int_read() void tms5220_device::data_write(int data) { int old_buffer_low = m_buffer_low; -#ifdef DEBUG_DUMP_INPUT_DATA - fprintf(stdout, "%c",data); -#endif + LOGMASKED(LOG_DUMP_INPUT_DATA, "%c", data); + if (m_DDIS) // If we're in speak external mode { // add this byte to the FIFO @@ -626,17 +617,13 @@ void tms5220_device::data_write(int data) m_fifo[m_fifo_tail] = data; m_fifo_tail = (m_fifo_tail + 1) % FIFO_SIZE; m_fifo_count++; -#ifdef DEBUG_FIFO - logerror("data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count); -#endif + LOGMASKED(LOG_FIFO, "data_write: Added byte to FIFO (current count=%2d)\n", m_fifo_count); update_fifo_status_and_ints(); + // if we just unset buffer low with that last write, and SPEN *was* zero (see circuit 251, sheet 12) if ((m_SPEN == 0) && ((old_buffer_low == 1) && (m_buffer_low == 0))) // MUST HAVE EDGE DETECT { - int i; -#ifdef DEBUG_FIFO - logerror("data_write triggered SPEN to go active!\n"); -#endif + LOGMASKED(LOG_FIFO, "data_write triggered SPEN to go active!\n"); // ...then we now have enough bytes to start talking; set zpar and clear out the new frame parameters (it will become old frame just before the first call to parse_frame() ) m_zpar = 1; m_uv_zpar = 1; // zero k4-k10 as well @@ -652,21 +639,19 @@ void tms5220_device::data_write(int data) #endif m_new_frame_energy_idx = 0; m_new_frame_pitch_idx = 0; - for (i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) m_new_frame_k_idx[i] = 0; - for (i = 4; i < 7; i++) + for (int i = 4; i < 7; i++) m_new_frame_k_idx[i] = 0xF; - for (i = 7; i < m_coeff->num_k; i++) + for (int i = 7; i < m_coeff->num_k; i++) m_new_frame_k_idx[i] = 0x7; } } else { -#ifdef DEBUG_FIFO - logerror("data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n"); + LOGMASKED(LOG_FIFO, "data_write: Ran out of room in the tms52xx FIFO! this should never happen!\n"); // at this point, /READY should remain HIGH/inactive until the fifo has at least one byte open in it. -#endif } @@ -737,9 +722,7 @@ void tms5220_device::update_fifo_status_and_ints() // also, in this case, regardless if DDIS was set, unset it. if ((m_previous_TALK_STATUS == 1) && (TALK_STATUS() == 0)) { -#ifdef VERBOSE - logerror("Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); -#endif + LOGMASKED(LOG_GENERAL, "Talk status WAS 1, is now 0, unsetting DDIS and firing an interrupt!\n"); set_interrupt_state(1); m_DDIS = 0; } @@ -785,9 +768,7 @@ int tms5220_device::extract_bits(int count) while (count--) { val = (val << 1) | new_int_read(); -#ifdef VERBOSE - logerror("bit read: %d\n", val&1); -#endif + LOGMASKED(LOG_GENERAL, "bit read: %d\n", val&1); } #endif } @@ -799,12 +780,8 @@ void tms5220_device::perform_dummy_read() { if (m_schedule_dummy_read) { -#ifdef VERBOSE int data = new_int_read(); - logerror("TMS5110 performing dummy read; value read = %1i\n", data & 1); -#else - new_int_read(); -#endif + LOGMASKED(LOG_GENERAL, "TMS5110 performing dummy read; value read = %1i\n", data & 1); m_schedule_dummy_read = false; } } @@ -826,9 +803,7 @@ int tms5220_device::status_read() { /* read status */ /* clear the interrupt pin on status read */ set_interrupt_state(0); -#ifdef DEBUG_PIN_READS - logerror("Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS(), m_buffer_low, m_buffer_empty); -#endif + LOGMASKED(LOG_PIN_READS, "Status read: TS=%d BL=%d BE=%d\n", TALK_STATUS(), m_buffer_low, m_buffer_empty); return (TALK_STATUS() << 7) | (m_buffer_low << 6) | (m_buffer_empty << 5); } } @@ -842,9 +817,8 @@ int tms5220_device::status_read() int tms5220_device::ready_read() { -#ifdef DEBUG_PIN_READS - logerror("ready_read: ready pin read, io_ready is %d, fifo count is %d, DDIS(speak external) is %d\n", m_io_ready, m_fifo_count, m_DDIS); -#endif + LOGMASKED(LOG_PIN_READS, "ready_read: ready pin read, io_ready is %d, fifo count is %d, DDIS(speak external) is %d\n", m_io_ready, m_fifo_count, m_DDIS); + return ((m_fifo_count < FIFO_SIZE)||(!m_DDIS)) && m_io_ready; } @@ -900,9 +874,8 @@ int tms5220_device::cycles_to_ready() int tms5220_device::int_read() { -#ifdef DEBUG_PIN_READS - logerror("int_read: irq pin read, state is %d\n", m_irq_pin); -#endif + LOGMASKED(LOG_PIN_READS, "int_read: irq pin read, state is %d\n", m_irq_pin); + return m_irq_pin; } @@ -919,9 +892,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) int i, bitout; int32_t this_sample; -#ifdef VERBOSE - logerror("process called with size of %d; IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", size, m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); -#endif + LOGMASKED(LOG_GENERAL, "process called with size of %d; IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", size, m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); /* loop until the buffer is full or we've stopped speaking */ while (size > 0) @@ -975,16 +946,15 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) else // normal frame, normal interpolation m_inhibit = 0; -#ifdef DEBUG_GENERATION /* Debug info for current parsed frame */ - logerror( "OLDE: %d; NEWE: %d; OLDP: %d; NEWP: %d ", OLD_FRAME_SILENCE_FLAG(), NEW_FRAME_SILENCE_FLAG(), OLD_FRAME_UNVOICED_FLAG(), NEW_FRAME_UNVOICED_FLAG()); - logerror("Processing new frame: "); + LOGMASKED(LOG_GENERATION, "OLDE: %d; NEWE: %d; OLDP: %d; NEWP: %d ", OLD_FRAME_SILENCE_FLAG(), NEW_FRAME_SILENCE_FLAG(), OLD_FRAME_UNVOICED_FLAG(), NEW_FRAME_UNVOICED_FLAG()); + LOGMASKED(LOG_GENERATION, "Processing new frame: "); if (m_inhibit == 0) - logerror( "Normal Frame\n"); + LOGMASKED(LOG_GENERATION, "Normal Frame\n"); else - logerror("Interpolation Inhibited\n"); - logerror("*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); - logerror("*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n", + LOGMASKED(LOG_GENERATION, "Interpolation Inhibited\n"); + LOGMASKED(LOG_GENERATION, "*** current Energy, Pitch and Ks = %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n",m_current_energy, m_current_pitch, m_current_k[0], m_current_k[1], m_current_k[2], m_current_k[3], m_current_k[4], m_current_k[5], m_current_k[6], m_current_k[7], m_current_k[8], m_current_k[9]); + LOGMASKED(LOG_GENERATION, "*** target Energy(idx), Pitch, and Ks = %04d(%x),%04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d, %04d\n", (m_coeff->energytable[m_new_frame_energy_idx] * (1-m_zpar)), m_new_frame_energy_idx, (m_coeff->pitchtable[m_new_frame_pitch_idx] * (1-m_zpar)), @@ -998,8 +968,6 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) (m_coeff->ktable[7][m_new_frame_k_idx[7]] * (1-m_uv_zpar)), (m_coeff->ktable[8][m_new_frame_k_idx[8]] * (1-m_uv_zpar)), (m_coeff->ktable[9][m_new_frame_k_idx[9]] * (1-m_uv_zpar)) ); -#endif - } else // Not a new frame, just interpolate the existing frame. { @@ -1090,20 +1058,20 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) m_RNG |= bitout; } this_sample = lattice_filter(); /* execute lattice filter */ -#ifdef DEBUG_GENERATION_VERBOSE - //logerror("C:%01d; ",m_subcycle); - logerror("IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); - //logerror("X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); + + //LOGMASKED(LOG_GENERATION_VERBOSE, "C:%01d; ",m_subcycle); + LOGMASKED(LOG_GENERATION_VERBOSE, "IP:%01d PC:%02d X:%04d E:%03d P:%03d Pc:%03d ",m_IP, m_PC, m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); + //LOGMASKED(LOG_GENERATION_VERBOSE, "X:%04d E:%03d P:%03d Pc:%03d ", m_excitation_data, m_current_energy, m_current_pitch, m_pitch_count); for (i=0; i<10; i++) - logerror("K%d:%04d ", i+1, m_current_k[i]); - logerror("Out:%06d ", this_sample); + LOGMASKED(LOG_GENERATION_VERBOSE, "K%d:%04d ", i+1, m_current_k[i]); + LOGMASKED(LOG_GENERATION_VERBOSE, "Out:%06d ", this_sample); //#ifdef TMS5220_PERFECT_INTERPOLATION_HACK -// logerror("%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar); +// LOGMASKED(LOG_GENERATION_VERBOSE, "%d%d%d%d",m_old_zpar,m_zpar,m_old_uv_zpar,m_uv_zpar); //#else -// logerror("x%dx%d",m_zpar,m_uv_zpar); +// LOGMASKED(LOG_GENERATION_VERBOSE, "x%dx%d",m_zpar,m_uv_zpar); //#endif - logerror("\n"); -#endif + LOGMASKED(LOG_GENERATION_VERBOSE, "\n"); + /* next, force result to 14 bits (since its possible that the addition at the final (k1) stage of the lattice overflowed) */ while (this_sample > 16383) this_sample -= 32768; while (this_sample < -16384) this_sample += 32768; @@ -1146,19 +1114,16 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) OLD_FRAME_SILENCE_FLAG() = NEW_FRAME_SILENCE_FLAG() ? 1 : 0; // m_OLDE OLD_FRAME_UNVOICED_FLAG() = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; // m_OLDP /* if TALK was clear last frame, halt speech now, since TALKD (latched from TALK on new frame) just went inactive. */ -#ifdef DEBUG_GENERATION - logerror("RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); -#endif -#ifdef DEBUG_GENERATION + + LOGMASKED(LOG_GENERATION, "RESETL4, about to update status: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); if ((!m_TALK) && (!m_SPEN)) - logerror("tms5220_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n"); -#endif + LOGMASKED(LOG_GENERATION, "tms5220_process: processing frame: TALKD = 0 caused by stop frame or buffer empty, halting speech.\n"); + m_TALKD = m_TALK; // TALKD is latched from TALK update_fifo_status_and_ints(); // to trigger an interrupt if TALK_STATUS has changed if ((!m_TALK) && m_SPEN) m_TALK = 1; // TALK is only activated if it wasn't already active, if m_SPEN is active, and if we're in RESETL4 (which we are). -#ifdef DEBUG_GENERATION - logerror("RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); -#endif + + LOGMASKED(LOG_GENERATION, "RESETL4, status updated: IP=%d, PC=%d, subcycle=%d, m_SPEN=%d, m_TALK=%d, m_TALKD=%d\n", m_IP, m_PC, m_subcycle, m_SPEN, m_TALK, m_TALKD); } m_subcycle = m_subc_reload; m_PC = 0; @@ -1208,7 +1173,7 @@ void tms5220_device::process(int16_t *buffer, unsigned int size) ***********************************************************************************************/ -static int16_t clip_analog(int16_t cliptemp) +int16_t tms5220_device::clip_analog(int16_t cliptemp) const { /* clipping, just like the patent shows: * the top 10 bits of this result are visible on the digital output IO pin. @@ -1218,9 +1183,8 @@ static int16_t clip_analog(int16_t cliptemp) * 00 0bcd efgh xxxx -> 0b0bcdefgh * 0x xxxx xxxx xxxx -> 0b01111111 */ -#ifdef DEBUG_CLIP - if ((cliptemp > 2047) || (cliptemp < -2048)) logerror("clipping cliptemp to range; was %d\n", cliptemp); -#endif + if ((cliptemp > 2047) || (cliptemp < -2048)) + LOGMASKED(LOG_CLIP, "clipping cliptemp to range; was %d\n", cliptemp); if (cliptemp > 2047) cliptemp = 2047; else if (cliptemp < -2048) cliptemp = -2048; /* at this point the analog output is tapped */ @@ -1250,7 +1214,7 @@ static int16_t clip_analog(int16_t cliptemp) output, this makes almost no difference in the computation. **********************************************************************************************/ -static int32_t matrix_multiply(int32_t a, int32_t b) +int32_t tms5220_device::matrix_multiply(int32_t a, int32_t b) const { int32_t result; while (a>511) { a-=1024; } @@ -1258,10 +1222,8 @@ static int32_t matrix_multiply(int32_t a, int32_t b) while (b>16383) { b-=32768; } while (b<-16384) { b+=32768; } result = ((a*b)>>9); /** TODO: this isn't technically right to the chip, which truncates the lowest result bit, but it causes glitches otherwise. **/ -#ifdef VERBOSE - if (result>16383) logerror("matrix multiplier overflowed! a: %x, b: %x, result: %x", a, b, result); - if (result<-16384) logerror("matrix multiplier underflowed! a: %x, b: %x, result: %x", a, b, result); -#endif + if (result>16383) LOGMASKED(LOG_GENERAL, "matrix multiplier overflowed! a: %x, b: %x, result: %x", a, b, result); + if (result<-16384) LOGMASKED(LOG_GENERAL, "matrix multiplier underflowed! a: %x, b: %x, result: %x", a, b, result); return result; } @@ -1307,9 +1269,7 @@ int32_t tms5220_device::lattice_filter() m_u[2] = m_u[3] - matrix_multiply(m_current_k[2], m_x[2]); m_u[1] = m_u[2] - matrix_multiply(m_current_k[1], m_x[1]); m_u[0] = m_u[1] - matrix_multiply(m_current_k[0], m_x[0]); -#ifdef DEBUG_LATTICE int32_t err = m_x[9] + matrix_multiply(m_current_k[9], m_u[9]); //x_10, real chip doesn't use or calculate this -#endif m_x[9] = m_x[8] + matrix_multiply(m_current_k[8], m_u[8]); m_x[8] = m_x[7] + matrix_multiply(m_current_k[7], m_u[7]); m_x[7] = m_x[6] + matrix_multiply(m_current_k[6], m_u[6]); @@ -1321,21 +1281,20 @@ int32_t tms5220_device::lattice_filter() m_x[1] = m_x[0] + matrix_multiply(m_current_k[0], m_u[0]); m_x[0] = m_u[0]; m_previous_energy = m_current_energy; -#ifdef DEBUG_LATTICE - int i; - logerror("V:%04d ", m_u[10]); - for (i = 9; i >= 0; i--) + + LOGMASKED(LOG_LATTICE, "V:%04d ", m_u[10]); + for (int i = 9; i >= 0; i--) { - logerror("Y%d:%04d ", i+1, m_u[i]); + LOGMASKED(LOG_LATTICE, "Y%d:%04d ", i+1, m_u[i]); } - logerror("\n"); - logerror("E:%04d ", err); - for (i = 9; i >= 0; i--) + LOGMASKED(LOG_LATTICE, "\n"); + LOGMASKED(LOG_LATTICE, "E:%04d ", err); + for (int i = 9; i >= 0; i--) { - logerror("b%d:%04d ", i+1, m_x[i]); + LOGMASKED(LOG_LATTICE, "b%d:%04d ", i+1, m_x[i]); } - logerror("\n"); -#endif + LOGMASKED(LOG_LATTICE, "\n"); + return m_u[0]; } @@ -1348,123 +1307,135 @@ int32_t tms5220_device::lattice_filter() void tms5220_device::process_command(unsigned char cmd) { - int i; -#ifdef DEBUG_COMMAND_DUMP - logerror("process_command called with parameter %02X\n",cmd); -#endif - /* parse the command */ - switch (cmd & 0x70) + LOGMASKED(LOG_COMMAND_DUMP, "process_command called with parameter %02X\n", cmd); + + /* parse the command */ + switch (cmd & 0x70) + { + case 0x10 : /* read byte */ + if (TALK_STATUS() == 0) /* TALKST must be clear for RDBY */ { - case 0x10 : /* read byte */ - if (TALK_STATUS() == 0) /* TALKST must be clear for RDBY */ + LOGMASKED(LOG_COMMAND_VERBOSE, "Read Byte command received\n"); + if (m_schedule_dummy_read) { - if (m_schedule_dummy_read) - { - m_schedule_dummy_read = false; - if (m_speechrom) - m_speechrom->read(1); - } + m_schedule_dummy_read = false; if (m_speechrom) - m_data_register = m_speechrom->read(8); /* read one byte from speech ROM... */ - m_RDB_flag = true; + m_speechrom->read(1); } + if (m_speechrom) + m_data_register = m_speechrom->read(8); /* read one byte from speech ROM... */ + m_RDB_flag = true; + } + else + LOGMASKED(LOG_COMMAND_VERBOSE, "Read Byte command received during TALK state, ignoring!\n"); break; - case 0x00: case 0x20: /* set rate (tms5220c and cd2501ecd only), otherwise NOP */ - if (TMS5220_HAS_RATE_CONTROL) - { - m_c_variant_rate = cmd&0x0F; - } + case 0x00: case 0x20: /* set rate (tms5220c and cd2501ecd only), otherwise NOP */ + if (TMS5220_HAS_RATE_CONTROL) + { + LOGMASKED(LOG_COMMAND_VERBOSE, "Set Rate command received\n"); + m_c_variant_rate = cmd&0x0F; + } + else + LOGMASKED(LOG_COMMAND_VERBOSE, "NOP command received\n"); break; - case 0x30 : /* read and branch */ - if (TALK_STATUS() == 0) /* TALKST must be clear for RB */ - { -#ifdef VERBOSE - logerror("read and branch command received\n"); -#endif - m_RDB_flag = false; - if (m_speechrom) - m_speechrom->read_and_branch(); - } - break; + case 0x30 : /* read and branch */ + if (TALK_STATUS() == 0) /* TALKST must be clear for RB */ + { + LOGMASKED(LOG_COMMAND_VERBOSE, "Read and Branch command received\n"); + m_RDB_flag = false; + if (m_speechrom) + m_speechrom->read_and_branch(); + } + else + LOGMASKED(LOG_COMMAND_VERBOSE, "Read and Branch command received during TALK state, ignoring!\n"); + break; - case 0x40 : /* load address */ - if (TALK_STATUS() == 0) /* TALKST must be clear for LA */ - { - /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. - This code does not care about this. */ - if (m_speechrom) - m_speechrom->load_address(cmd & 0x0f); - m_schedule_dummy_read = true; - } - break; + case 0x40 : /* load address */ + if (TALK_STATUS() == 0) /* TALKST must be clear for LA */ + { + LOGMASKED(LOG_COMMAND_VERBOSE, "Load Address command received\n"); - case 0x50 : /* speak */ - if (m_schedule_dummy_read) - { - m_schedule_dummy_read = false; - if (m_speechrom) - m_speechrom->read(1); - } - m_SPEN = 1; + /* tms5220 data sheet says that if we load only one 4-bit nibble, it won't work. + This code does not care about this. */ + if (m_speechrom) + m_speechrom->load_address(cmd & 0x0f); + m_schedule_dummy_read = true; + } + else + LOGMASKED(LOG_COMMAND_VERBOSE, "Load Address command received during TALK state, ignoring!\n"); + break; + + case 0x50 : /* speak */ + LOGMASKED(LOG_COMMAND_VERBOSE, "Speak (VSM) command received\n"); + if (m_schedule_dummy_read) + { + m_schedule_dummy_read = false; + if (m_speechrom) + m_speechrom->read(1); + } + m_SPEN = 1; #ifdef FAST_START_HACK - m_TALK = 1; + m_TALK = 1; #endif - m_DDIS = 0; - m_zpar = 1; // zero all the parameters - m_uv_zpar = 1; // zero k4-k10 as well - m_OLDE = 1; // 'silence/zpar' frames are zero energy - m_OLDP = 1; // 'silence/zpar' frames are zero pitch + m_DDIS = 0; + m_zpar = 1; // zero all the parameters + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = 1; // zero all the old parameters - m_old_uv_zpar = 1; // zero old k4-k10 as well -#endif - // following is semi-hack but matches idle state observed on chip - m_new_frame_energy_idx = 0; - m_new_frame_pitch_idx = 0; - for (i = 0; i < 4; i++) - m_new_frame_k_idx[i] = 0; - for (i = 4; i < 7; i++) - m_new_frame_k_idx[i] = 0xF; - for (i = 7; i < m_coeff->num_k; i++) - m_new_frame_k_idx[i] = 0x7; - break; - - case 0x60 : /* speak external */ - // SPKEXT going active activates SPKEE which clears the fifo - m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; - // SPEN is enabled when the fifo passes half full (falling edge of BL signal) - m_DDIS = 1; - m_zpar = 1; // zero all the parameters - m_uv_zpar = 1; // zero k4-k10 as well - m_OLDE = 1; // 'silence/zpar' frames are zero energy - m_OLDP = 1; // 'silence/zpar' frames are zero pitch + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well +#endif + // following is semi-hack but matches idle state observed on chip + m_new_frame_energy_idx = 0; + m_new_frame_pitch_idx = 0; + for (int i = 0; i < 4; i++) + m_new_frame_k_idx[i] = 0; + for (int i = 4; i < 7; i++) + m_new_frame_k_idx[i] = 0xF; + for (int i = 7; i < m_coeff->num_k; i++) + m_new_frame_k_idx[i] = 0x7; + break; + + case 0x60 : /* speak external */ + LOGMASKED(LOG_COMMAND_VERBOSE, "Speak External command received\n"); + + // SPKEXT going active activates SPKEE which clears the fifo + m_fifo_head = m_fifo_tail = m_fifo_count = m_fifo_bits_taken = 0; + // SPEN is enabled when the fifo passes half full (falling edge of BL signal) + m_DDIS = 1; + m_zpar = 1; // zero all the parameters + m_uv_zpar = 1; // zero k4-k10 as well + m_OLDE = 1; // 'silence/zpar' frames are zero energy + m_OLDP = 1; // 'silence/zpar' frames are zero pitch #ifdef TMS5220_PERFECT_INTERPOLATION_HACK - m_old_zpar = 1; // zero all the old parameters - m_old_uv_zpar = 1; // zero old k4-k10 as well -#endif - // following is semi-hack but matches idle state observed on chip - m_new_frame_energy_idx = 0; - m_new_frame_pitch_idx = 0; - for (i = 0; i < 4; i++) - m_new_frame_k_idx[i] = 0; - for (i = 4; i < 7; i++) - m_new_frame_k_idx[i] = 0xF; - for (i = 7; i < m_coeff->num_k; i++) - m_new_frame_k_idx[i] = 0x7; - m_RDB_flag = false; - break; + m_old_zpar = 1; // zero all the old parameters + m_old_uv_zpar = 1; // zero old k4-k10 as well +#endif + // following is semi-hack but matches idle state observed on chip + m_new_frame_energy_idx = 0; + m_new_frame_pitch_idx = 0; + for (int i = 0; i < 4; i++) + m_new_frame_k_idx[i] = 0; + for (int i = 4; i < 7; i++) + m_new_frame_k_idx[i] = 0xF; + for (int i = 7; i < m_coeff->num_k; i++) + m_new_frame_k_idx[i] = 0x7; + m_RDB_flag = false; + break; - case 0x70 : /* reset */ - if (m_schedule_dummy_read) - { - m_schedule_dummy_read = false; - if (m_speechrom) - m_speechrom->read(1); - } - reset(); - break; + case 0x70 : /* reset */ + LOGMASKED(LOG_COMMAND_VERBOSE, "Reset command received\n"); + if (m_schedule_dummy_read) + { + m_schedule_dummy_read = false; + if (m_speechrom) + m_speechrom->read(1); + } + reset(); + break; } /* update the buffer low state */ @@ -1495,10 +1466,8 @@ void tms5220_device::parse_frame() if ((TMS5220_HAS_RATE_CONTROL) && (m_c_variant_rate & 0x04)) { i = extract_bits(2); -#ifdef DEBUG_PARSE_FRAME_DUMP - printbits(i,2); - logerror(" "); -#endif + printbits(i, 2); + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, " "); m_IP = reload_table[i]; } else // non-5220C and 5220C in fixed rate mode @@ -1509,10 +1478,8 @@ void tms5220_device::parse_frame() // attempt to extract the energy index m_new_frame_energy_idx = extract_bits(m_coeff->energy_bits); -#ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_energy_idx,m_coeff->energy_bits); - logerror(" "); -#endif + printbits(m_new_frame_energy_idx, m_coeff->energy_bits); + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, " "); update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; // if the energy index is 0 or 15, we're done @@ -1522,17 +1489,13 @@ void tms5220_device::parse_frame() // attempt to extract the repeat flag rep_flag = extract_bits(1); -#ifdef DEBUG_PARSE_FRAME_DUMP printbits(rep_flag, 1); - logerror(" "); -#endif + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, " "); // attempt to extract the pitch m_new_frame_pitch_idx = extract_bits(m_coeff->pitch_bits); -#ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_pitch_idx,m_coeff->pitch_bits); - logerror(" "); -#endif + printbits(m_new_frame_pitch_idx, m_coeff->pitch_bits); + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, " "); // if the new frame is unvoiced, be sure to zero out the k5-k10 parameters m_uv_zpar = NEW_FRAME_UNVOICED_FLAG() ? 1 : 0; update_fifo_status_and_ints(); @@ -1545,10 +1508,8 @@ void tms5220_device::parse_frame() for (i = 0; i < 4; i++) { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); -#ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); - logerror(" "); -#endif + printbits(m_new_frame_k_idx[i], m_coeff->kbits[i]); + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, " "); update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; } @@ -1564,28 +1525,21 @@ void tms5220_device::parse_frame() for (i = 4; i < m_coeff->num_k; i++) { m_new_frame_k_idx[i] = extract_bits(m_coeff->kbits[i]); -#ifdef DEBUG_PARSE_FRAME_DUMP - printbits(m_new_frame_k_idx[i],m_coeff->kbits[i]); - logerror(" "); -#endif + printbits(m_new_frame_k_idx[i], m_coeff->kbits[i]); + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, " "); update_fifo_status_and_ints(); if (m_DDIS && m_buffer_empty) goto ranout; } -#ifdef DEBUG_PARSE_FRAME_DUMP - logerror("\n"); -#endif -#ifdef VERBOSE + LOGMASKED(LOG_PARSE_FRAME_DUMP_BIN | LOG_PARSE_FRAME_DUMP_HEX, "\n"); + if (m_DDIS) - logerror("Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); + LOGMASKED(LOG_GENERAL, "Parsed a frame successfully in FIFO - %d bits remaining\n", (m_fifo_count*8)-(m_fifo_bits_taken)); else - logerror("Parsed a frame successfully in ROM\n"); -#endif + LOGMASKED(LOG_GENERAL, "Parsed a frame successfully in ROM\n"); return; ranout: -#ifdef DEBUG_FRAME_ERRORS - logerror("Ran out of bits on a parse!\n"); -#endif + LOGMASKED(LOG_FRAME_ERRORS, "Ran out of bits on a parse!\n"); return; } @@ -1598,9 +1552,9 @@ void tms5220_device::parse_frame() void tms5220_device::set_interrupt_state(int state) { if (!TMS5220_IS_52xx) return; // bail out if not a 52xx chip, since there's no int pin -#ifdef DEBUG_PIN_READS - logerror("irq pin set to state %d\n", state); -#endif + + LOGMASKED(LOG_PIN_READS, "irq pin set to state %d\n", state); + if (!m_irq_handler.isnull() && state != m_irq_pin) m_irq_handler(!state); m_irq_pin = state; @@ -1615,9 +1569,9 @@ void tms5220_device::set_interrupt_state(int state) void tms5220_device::update_ready_state() { int state = ready_read(); -#ifdef DEBUG_PIN_READS - logerror("ready pin set to state %d\n", state); -#endif + + LOGMASKED(LOG_PIN_READS, "ready pin set to state %d\n", state); + if (!m_readyq_handler.isnull() && state != m_ready_pin) m_readyq_handler(!state); m_ready_pin = state; @@ -1780,10 +1734,8 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para case 0x02: /* Write */ /* bring up to date first */ -#ifdef DEBUG_IO_READY - logerror("Serviced write: %02x\n", m_write_latch); - //logerror( "Processed write data: %02X\n", m_write_latch); -#endif + LOGMASKED(LOG_IO_READY, "Serviced write: %02x\n", m_write_latch); + //LOGMASKED(LOG_IO_READY, "Processed write data: %02X\n", m_write_latch); m_stream->update(); data_write(m_write_latch); break; @@ -1792,9 +1744,7 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para /* bring up to date first */ m_stream->update(); m_read_latch = status_read(); -#ifdef DEBUG_IO_READY - logerror("Serviced read, returning %02x\n", m_read_latch); -#endif + LOGMASKED(LOG_IO_READY, "Serviced read, returning %02x\n", m_read_latch); break; case 0x03: /* High Impedance */ @@ -1815,14 +1765,11 @@ void tms5220_device::device_timer(emu_timer &timer, device_timer_id id, int para */ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) { - uint8_t new_val; - m_true_timing = 1; state &= 0x01; -#ifdef DEBUG_RS_WS - logerror("/RS written with data: %d\n", state); -#endif - new_val = (m_rs_ws & 0x01) | (state<<1); + LOGMASKED(LOG_RS_WS, "/RS written with data: %d\n", state); + + uint8_t new_val = (m_rs_ws & 0x01) | (state<<1); if (new_val != m_rs_ws) { m_rs_ws = new_val; @@ -1830,11 +1777,9 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) { if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, ? for cd2501ecd reset(); -#ifdef DEBUG_RS_WS else /* illegal */ - logerror("tms5220_rsq_w: illegal\n"); -#endif + LOGMASKED(LOG_RS_WS, "tms5220_rsq_w: illegal\n"); return; } else if ( new_val == 3) @@ -1850,9 +1795,7 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) else { /* high to low - schedule ready cycle */ -#ifdef DEBUG_RS_WS - logerror("Scheduling ready cycle for /RS...\n"); -#endif + LOGMASKED(LOG_RS_WS, "Scheduling ready cycle for /RS...\n"); /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ m_io_ready = 0; update_ready_state(); @@ -1867,14 +1810,11 @@ WRITE_LINE_MEMBER( tms5220_device::rsq_w ) */ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) { - uint8_t new_val; - m_true_timing = 1; state &= 0x01; -#ifdef DEBUG_RS_WS - logerror("/WS written with data: %d\n", state); -#endif - new_val = (m_rs_ws & 0x02) | (state<<0); + LOGMASKED(LOG_RS_WS, "/WS written with data: %d\n", state); + + uint8_t new_val = (m_rs_ws & 0x02) | (state<<0); if (new_val != m_rs_ws) { m_rs_ws = new_val; @@ -1882,11 +1822,9 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) { if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, probably also correct for cd2501ecd reset(); -#ifdef DEBUG_RS_WS else /* illegal */ - logerror("tms5220_wsq_w: illegal\n"); -#endif + LOGMASKED(LOG_RS_WS, "tms5220_wsq_w: illegal\n"); return; } else if ( new_val == 3) @@ -1902,9 +1840,8 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) else { /* high to low - schedule ready cycle */ -#ifdef DEBUG_RS_WS - logerror("Scheduling ready cycle for /WS...\n"); -#endif + LOGMASKED(LOG_RS_WS, "Scheduling ready cycle for /WS...\n"); + /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ m_io_ready = 0; update_ready_state(); @@ -1931,13 +1868,11 @@ WRITE_LINE_MEMBER( tms5220_device::wsq_w ) */ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) { - uint8_t new_val; uint8_t falling_edges; m_true_timing = 1; -#ifdef DEBUG_RS_WS - logerror("/RS and /WS written with %d and %d respectively\n", (data&2)>>1, data&1); -#endif - new_val = data&0x03; + LOGMASKED(LOG_RS_WS, "/RS and /WS written with %d and %d respectively\n", (data&2)>>1, data&1); + + uint8_t new_val = data & 0x03; if (new_val != m_rs_ws) { falling_edges = ((m_rs_ws^new_val)&(~new_val)); @@ -1947,11 +1882,9 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) case 0: if (TMS5220_HAS_RATE_CONTROL) // correct for 5220c, probably also correct for cd2501ecd reset(); -#ifdef DEBUG_RS_WS else /* illegal */ - logerror("tms5220_combined_rsq_wsq_w: illegal\n"); -#endif + LOGMASKED(LOG_RS_WS, "tms5220_combined_rsq_wsq_w: illegal\n"); return; case 3: /* high impedance */ @@ -1960,13 +1893,14 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) case 2: // /WS active, /RS not /* check for falling or rising edge */ if (!(falling_edges&0x01)) return; /* low to high, do nothing */ + /* high to low - schedule ready cycle */ -#ifdef DEBUG_RS_WS - logerror("Scheduling ready cycle for /WS...\n"); -#endif + LOGMASKED(LOG_RS_WS, "Scheduling ready cycle for /WS...\n"); + /* upon /WS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ m_io_ready = 0; update_ready_state(); + /* Now comes the complicated part: how long does /READY stay inactive, when /WS is pulled low? This depends ENTIRELY on the command written, or whether the chip is in speak external mode or not... Speak external mode: ~16 cycles Command Mode: @@ -1983,13 +1917,14 @@ WRITE8_MEMBER( tms5220_device::combined_rsq_wsq_w ) case 1: // /RS active, /WS not /* check for falling or rising edge */ if (!(falling_edges&0x02)) return; /* low to high, do nothing */ + /* high to low - schedule ready cycle */ -#ifdef DEBUG_RS_WS - logerror("Scheduling ready cycle for /RS...\n"); -#endif + LOGMASKED(LOG_RS_WS, "Scheduling ready cycle for /RS...\n"); + /* upon /RS being activated, /READY goes inactive after 100 nsec from data sheet, through 3 asynchronous gates on patent. This is effectively within one clock, so we immediately set io_ready to 0 and activate the callback. */ m_io_ready = 0; update_ready_state(); + /* How long does /READY stay inactive, when /RS is pulled low? I believe its almost always ~16 clocks (25 usec at 800khz as shown on the datasheet) */ m_timer_io_ready->adjust(clocks_to_attotime(16), 1); // this should take around 10-16 (closer to ~11?) cycles to complete return; @@ -2009,9 +1944,8 @@ void tms5220_device::write_data(uint8_t data) // prevent debugger from changing the internal state if (machine().side_effects_disabled()) return; -#ifdef DEBUG_RS_WS - logerror("tms5220_data_w: data %02x\n", data); -#endif + LOGMASKED(LOG_RS_WS, "tms5220_data_w: data %02x\n", data); + if (!m_true_timing) { /* bring up to date first */ @@ -2021,10 +1955,8 @@ void tms5220_device::write_data(uint8_t data) else { /* actually in a write ? */ -#ifdef DEBUG_RS_WS if (!(m_rs_ws == 0x02)) - logerror("tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); -#endif + LOGMASKED(LOG_RS_WS, "tms5220_data_w: data written outside ws, status: %02x!\n", m_rs_ws); m_write_latch = data; } } @@ -2053,10 +1985,8 @@ uint8_t tms5220_device::read_status() /* actually in a read ? */ if (m_rs_ws == 0x01) return m_read_latch; -#ifdef DEBUG_RS_WS else - logerror("tms5220_status_r: data read outside rs!\n"); -#endif + LOGMASKED(LOG_RS_WS, "tms5220_status_r: data read outside rs!\n"); return 0xff; } } diff --git a/src/devices/sound/tms5220.h b/src/devices/sound/tms5220.h index 4cfab5491ef..b48ca8d9b9a 100644 --- a/src/devices/sound/tms5220.h +++ b/src/devices/sound/tms5220.h @@ -123,6 +123,8 @@ private: int cycles_to_ready(); int int_read(); void process(int16_t *buffer, unsigned int size); + int16_t clip_analog(int16_t cliptemp) const; + int32_t matrix_multiply(int32_t a, int32_t b) const; int32_t lattice_filter(); void process_command(unsigned char cmd); void parse_frame(); @@ -136,6 +138,9 @@ private: bool NEW_FRAME_SILENCE_FLAG() const { return m_new_frame_energy_idx == 0; } // ditto as above bool NEW_FRAME_UNVOICED_FLAG() const { return m_new_frame_pitch_idx == 0; } // ditto as above + // debugging helper + void printbits(long data, int num); + // internal state /* coefficient tables */ -- cgit v1.2.3 From 755f17458bfee4b9487fec2c57498d82c54663e0 Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 12 Jun 2018 10:35:16 -0400 Subject: jedi: Moderate driver overhaul - Split NVRAM between two 4-bit X2212 devices - Guarantee an invalid checksum when default NVRAM data is used (so that the manufacturer's high scores will be installed) - Soundlatch modernization - Use WSQ handler to drive TMS5220 --- src/mame/audio/jedi.cpp | 99 +++++++---------------------------------------- src/mame/drivers/jedi.cpp | 59 +++++++++++++++++++--------- src/mame/includes/jedi.h | 38 +++++++----------- 3 files changed, 68 insertions(+), 128 deletions(-) diff --git a/src/mame/audio/jedi.cpp b/src/mame/audio/jedi.cpp index f13e0e5ffc3..31d2d6dc4db 100644 --- a/src/mame/audio/jedi.cpp +++ b/src/mame/audio/jedi.cpp @@ -16,40 +16,6 @@ -/************************************* - * - * Start - * - *************************************/ - -void jedi_state::sound_start() -{ - /* set up save state */ - save_item(NAME(m_audio_latch)); - save_item(NAME(m_audio_ack_latch)); - save_item(NAME(m_speech_strobe_state)); -} - - - -/************************************* - * - * Reset - * - *************************************/ - -void jedi_state::sound_reset() -{ - /* init globals */ - m_audio_latch = 0; - m_audio_ack_latch = 0; - *m_audio_comm_stat = 0; - *m_speech_data = 0; - m_speech_strobe_state = 0; -} - - - /************************************* * * Interrupt handling @@ -72,53 +38,20 @@ WRITE8_MEMBER(jedi_state::irq_ack_w) WRITE_LINE_MEMBER(jedi_state::audio_reset_w) { m_audiocpu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE); + if (!state) + m_tms->set_output_gain(ALL_OUTPUTS, 0.0); } -TIMER_CALLBACK_MEMBER(jedi_state::delayed_audio_latch_w) -{ - m_audio_latch = param; - *m_audio_comm_stat |= 0x80; -} - - -WRITE8_MEMBER(jedi_state::jedi_audio_latch_w) -{ - machine().scheduler().synchronize(timer_expired_delegate(FUNC(jedi_state::delayed_audio_latch_w), this), data); -} - - -READ8_MEMBER(jedi_state::audio_latch_r) +READ8_MEMBER(jedi_state::audio_comm_stat_r) { - *m_audio_comm_stat &= ~0x80; - return m_audio_latch; + return (m_soundlatch->pending_r() << 7) | (m_sacklatch->pending_r() << 6); } CUSTOM_INPUT_MEMBER(jedi_state::jedi_audio_comm_stat_r) { - return *m_audio_comm_stat >> 6; -} - - - -/************************************* - * - * Sound CPU -> Main CPU communications - * - *************************************/ - -READ8_MEMBER(jedi_state::jedi_audio_ack_latch_r) -{ - *m_audio_comm_stat &= ~0x40; - return m_audio_ack_latch; -} - - -WRITE8_MEMBER(jedi_state::audio_ack_latch_w) -{ - m_audio_ack_latch = data; - *m_audio_comm_stat |= 0x40; + return (m_soundlatch->pending_r() << 1) | m_sacklatch->pending_r(); } @@ -131,13 +64,7 @@ WRITE8_MEMBER(jedi_state::audio_ack_latch_w) WRITE8_MEMBER(jedi_state::speech_strobe_w) { - int new_speech_strobe_state = (~offset >> 8) & 1; - - if ((new_speech_strobe_state != m_speech_strobe_state) && new_speech_strobe_state) - { - m_tms->data_w(space, 0, *m_speech_data); - } - m_speech_strobe_state = new_speech_strobe_state; + m_tms->wsq_w(BIT(offset, 8)); } @@ -149,7 +76,8 @@ READ8_MEMBER(jedi_state::speech_ready_r) WRITE8_MEMBER(jedi_state::speech_reset_w) { - /* not supported by the TMS5220 emulator */ + // Flip-flop at 8C controls the power supply to the TMS5220 (through transistors Q6 and Q7) + m_tms->set_output_gain(ALL_OUTPUTS, BIT(data, 0) ? 1.0 : 0.0); } @@ -168,14 +96,14 @@ void jedi_state::audio_map(address_map &map) map(0x0820, 0x082f).mirror(0x07c0).rw("pokey3", FUNC(pokey_device::read), FUNC(pokey_device::write)); map(0x0830, 0x083f).mirror(0x07c0).rw("pokey4", FUNC(pokey_device::read), FUNC(pokey_device::write)); map(0x1000, 0x1000).mirror(0x00ff).nopr().w(FUNC(jedi_state::irq_ack_w)); - map(0x1100, 0x1100).mirror(0x00ff).nopr().writeonly().share("speech_data"); + map(0x1100, 0x1100).mirror(0x00ff).nopr().w("tms", FUNC(tms5220_device::data_w)); map(0x1200, 0x13ff).nopr().w(FUNC(jedi_state::speech_strobe_w)); - map(0x1400, 0x1400).mirror(0x00ff).nopr().w(FUNC(jedi_state::audio_ack_latch_w)); + map(0x1400, 0x1400).mirror(0x00ff).nopr().w("sacklatch", FUNC(generic_latch_8_device::write)); map(0x1500, 0x1500).mirror(0x00ff).nopr().w(FUNC(jedi_state::speech_reset_w)); map(0x1600, 0x17ff).noprw(); - map(0x1800, 0x1800).mirror(0x03ff).r(FUNC(jedi_state::audio_latch_r)).nopw(); + map(0x1800, 0x1800).mirror(0x03ff).r("soundlatch", FUNC(generic_latch_8_device::read)).nopw(); map(0x1c00, 0x1c00).mirror(0x03fe).r(FUNC(jedi_state::speech_ready_r)).nopw(); - map(0x1c01, 0x1c01).mirror(0x03fe).readonly().nopw().share("audio_comm_stat"); + map(0x1c01, 0x1c01).mirror(0x03fe).r(FUNC(jedi_state::audio_comm_stat_r)).nopw(); map(0x2000, 0x7fff).noprw(); map(0x8000, 0xffff).rom(); } @@ -217,4 +145,7 @@ MACHINE_CONFIG_START(jedi_state::jedi_audio) MCFG_DEVICE_ADD("tms", TMS5220, JEDI_TMS5220_CLOCK) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0) + + MCFG_GENERIC_LATCH_8_ADD("soundlatch") // 5E (LS374) + 3E (LS279) pins 13-15 + MCFG_GENERIC_LATCH_8_ADD("sacklatch") // 4E (LS374) + 3E (LS279) pins 1-4 MACHINE_CONFIG_END diff --git a/src/mame/drivers/jedi.cpp b/src/mame/drivers/jedi.cpp index 7411bd5590f..a827529ddef 100644 --- a/src/mame/drivers/jedi.cpp +++ b/src/mame/drivers/jedi.cpp @@ -165,9 +165,6 @@ void jedi_state::machine_start() /* configure the banks */ membank("bank1")->configure_entries(0, 3, memregion("maincpu")->base() + 0x10000, 0x4000); - - /* set up save state */ - save_item(NAME(m_nvram_enabled)); } @@ -180,9 +177,8 @@ void jedi_state::machine_start() void jedi_state::machine_reset() { - /* init globals */ - m_a2d_select = 0; - m_nvram_enabled = 0; + m_novram[0]->recall(1); + m_novram[1]->recall(1); } @@ -223,20 +219,36 @@ WRITE_LINE_MEMBER(jedi_state::coin_counter_right_w) /************************************* * - * NVRAM + * X2212-30 NOVRAM * *************************************/ -WRITE8_MEMBER(jedi_state::nvram_data_w) +READ8_MEMBER(jedi_state::novram_data_r) +{ + return (m_novram[0]->read(space, offset) & 0x0f) | (m_novram[1]->read(space, offset) << 4); +} + + +WRITE8_MEMBER(jedi_state::novram_data_w) { - if (m_nvram_enabled) - m_nvram[offset] = data; + m_novram[0]->write(space, offset, data & 0x0f); + m_novram[1]->write(space, offset, data >> 4); } -WRITE8_MEMBER(jedi_state::nvram_enable_w) +WRITE8_MEMBER(jedi_state::novram_recall_w) { - m_nvram_enabled = ~offset & 1; + m_novram[0]->recall(BIT(offset, 0)); + m_novram[1]->recall(BIT(offset, 0)); +} + + +WRITE8_MEMBER(jedi_state::novram_store_w) +{ + m_novram[0]->store(1); + m_novram[1]->store(1); + m_novram[0]->store(0); + m_novram[1]->store(0); } @@ -250,19 +262,19 @@ WRITE8_MEMBER(jedi_state::nvram_enable_w) void jedi_state::main_map(address_map &map) { map(0x0000, 0x07ff).ram(); - map(0x0800, 0x08ff).mirror(0x0300).ram().w(FUNC(jedi_state::nvram_data_w)).share("nvram"); + map(0x0800, 0x08ff).mirror(0x0300).rw(FUNC(jedi_state::novram_data_r), FUNC(jedi_state::novram_data_w)); map(0x0c00, 0x0c00).mirror(0x03fe).portr("0c00").nopw(); map(0x0c01, 0x0c01).mirror(0x03fe).portr("0c01").nopw(); map(0x1000, 0x13ff).noprw(); - map(0x1400, 0x1400).mirror(0x03ff).r(FUNC(jedi_state::jedi_audio_ack_latch_r)).nopw(); + map(0x1400, 0x1400).mirror(0x03ff).r("sacklatch", FUNC(generic_latch_8_device::read)).nopw(); map(0x1800, 0x1800).mirror(0x03ff).r("adc", FUNC(adc0808_device::data_r)).nopw(); - map(0x1c00, 0x1c01).mirror(0x007e).nopr().w(FUNC(jedi_state::nvram_enable_w)); + map(0x1c00, 0x1c01).mirror(0x007e).nopr().w(FUNC(jedi_state::novram_recall_w)); map(0x1c80, 0x1c87).mirror(0x0078).nopr().w("adc", FUNC(adc0808_device::address_offset_start_w)); - map(0x1d00, 0x1d00).mirror(0x007f).noprw(); /* write: NVRAM store */ + map(0x1d00, 0x1d00).mirror(0x007f).nopr().w(FUNC(jedi_state::novram_store_w)); map(0x1d80, 0x1d80).mirror(0x007f).nopr().w("watchdog", FUNC(watchdog_timer_device::reset_w)); map(0x1e00, 0x1e00).mirror(0x007f).nopr().w(FUNC(jedi_state::main_irq_ack_w)); map(0x1e80, 0x1e87).mirror(0x0078).nopr().w("outlatch", FUNC(ls259_device::write_d7)); - map(0x1f00, 0x1f00).mirror(0x007f).nopr().w(FUNC(jedi_state::jedi_audio_latch_w)); + map(0x1f00, 0x1f00).mirror(0x007f).nopr().w("soundlatch", FUNC(generic_latch_8_device::write)); map(0x1f80, 0x1f80).mirror(0x007f).nopr().w(FUNC(jedi_state::rom_banksel_w)); map(0x2000, 0x27ff).ram().share("backgroundram"); map(0x2800, 0x2fff).ram().share("paletteram"); @@ -324,9 +336,10 @@ MACHINE_CONFIG_START(jedi_state::jedi) MCFG_QUANTUM_TIME(attotime::from_hz(240)) - MCFG_NVRAM_ADD_0FILL("nvram") + MCFG_X2212_ADD("novram12b") + MCFG_X2212_ADD("novram12c") - MCFG_DEVICE_ADD("adc", ADC0809, JEDI_AUDIO_CPU_OSC / 2 / 9) + MCFG_DEVICE_ADD("adc", ADC0809, JEDI_AUDIO_CPU_OSC / 2 / 9) // nominally 666 kHz MCFG_ADC0808_IN0_CB(IOPORT("STICKY")) MCFG_ADC0808_IN1_CB(NOOP) // SPARE MCFG_ADC0808_IN2_CB(IOPORT("STICKX")) @@ -386,6 +399,14 @@ ROM_START( jedi ) ROM_REGION( 0x1000, "proms", 0 ) /* background smoothing */ ROM_LOAD( "136030-117.bin", 0x0000, 0x0400, CRC(9831bd55) SHA1(12945ef2d1582914125b9ee591567034d71d6573) ) ROM_LOAD( "136030-118.bin", 0x0800, 0x0400, CRC(261fbfe7) SHA1(efc65a74a3718563a07b718e34d8a7aa23339a69) ) + + // NOVRAM default fills are specified to guarantee an invalid checksum + ROM_REGION( 0x100, "novram12b", 0 ) + ROM_FILL( 0x00, 0x100, 0x0f ) + ROM_FILL( 0x50, 0x010, 0x00 ) + ROM_REGION( 0x100, "novram12c", 0 ) + ROM_FILL( 0x00, 0x100, 0x0f ) + ROM_FILL( 0x50, 0x010, 0x00 ) ROM_END diff --git a/src/mame/includes/jedi.h b/src/mame/includes/jedi.h index 33ff8f86b3e..d0d0e3f4466 100644 --- a/src/mame/includes/jedi.h +++ b/src/mame/includes/jedi.h @@ -10,6 +10,8 @@ #pragma once +#include "machine/gen_latch.h" +#include "machine/x2212.h" #include "sound/tms5220.h" #include "screen.h" @@ -28,17 +30,17 @@ class jedi_state : public driver_device public: jedi_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_nvram(*this, "nvram") , m_backgroundram(*this, "backgroundram"), m_paletteram(*this, "paletteram"), m_foregroundram(*this, "foregroundram"), m_spriteram(*this, "spriteram"), m_smoothing_table(*this, "smoothing_table"), - m_audio_comm_stat(*this, "audio_comm_stat"), - m_speech_data(*this, "speech_data"), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), + m_soundlatch(*this, "soundlatch"), + m_sacklatch(*this, "sacklatch"), m_tms(*this, "tms"), + m_novram(*this, "novram12%c", 'b'), m_screen(*this, "screen") { } @@ -48,33 +50,27 @@ public: protected: DECLARE_WRITE8_MEMBER(main_irq_ack_w); DECLARE_WRITE8_MEMBER(rom_banksel_w); - DECLARE_READ8_MEMBER(a2d_data_r); - DECLARE_WRITE8_MEMBER(a2d_select_w); DECLARE_WRITE_LINE_MEMBER(coin_counter_left_w); DECLARE_WRITE_LINE_MEMBER(coin_counter_right_w); - DECLARE_WRITE8_MEMBER(nvram_data_w); - DECLARE_WRITE8_MEMBER(nvram_enable_w); + DECLARE_READ8_MEMBER(novram_data_r); + DECLARE_WRITE8_MEMBER(novram_data_w); + DECLARE_WRITE8_MEMBER(novram_recall_w); + DECLARE_WRITE8_MEMBER(novram_store_w); DECLARE_WRITE8_MEMBER(jedi_vscroll_w); DECLARE_WRITE8_MEMBER(jedi_hscroll_w); DECLARE_WRITE8_MEMBER(irq_ack_w); DECLARE_WRITE_LINE_MEMBER(audio_reset_w); - DECLARE_WRITE8_MEMBER(jedi_audio_latch_w); - DECLARE_READ8_MEMBER(audio_latch_r); - DECLARE_READ8_MEMBER(jedi_audio_ack_latch_r); - DECLARE_WRITE8_MEMBER(audio_ack_latch_w); + DECLARE_READ8_MEMBER(audio_comm_stat_r); DECLARE_WRITE8_MEMBER(speech_strobe_w); DECLARE_READ8_MEMBER(speech_ready_r); DECLARE_WRITE8_MEMBER(speech_reset_w); virtual void machine_start() override; virtual void machine_reset() override; - virtual void sound_start() override; - virtual void sound_reset() override; virtual void video_start() override; DECLARE_WRITE_LINE_MEMBER(foreground_bank_w); DECLARE_WRITE_LINE_MEMBER(video_off_w); uint32_t screen_update_jedi(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); TIMER_CALLBACK_MEMBER(generate_interrupt); - TIMER_CALLBACK_MEMBER(delayed_audio_latch_w); void get_pens(pen_t *pens); void do_pen_lookup(bitmap_rgb32 &bitmap, const rectangle &cliprect); void draw_background_and_text(bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -85,11 +81,7 @@ protected: void main_map(address_map &map); private: - required_shared_ptr m_nvram; - /* machine state */ - uint8_t m_a2d_select; - uint8_t m_nvram_enabled; emu_timer *m_interrupt_timer; /* video state */ @@ -103,16 +95,12 @@ private: bool m_foreground_bank; bool m_video_off; - /* audio state */ - uint8_t m_audio_latch; - uint8_t m_audio_ack_latch; - required_shared_ptr m_audio_comm_stat; - required_shared_ptr m_speech_data; - uint8_t m_speech_strobe_state; - required_device m_maincpu; required_device m_audiocpu; + required_device m_soundlatch; + required_device m_sacklatch; required_device m_tms; + required_device_array m_novram; required_device m_screen; }; -- cgit v1.2.3 From d1d76492925c05c0111301f97a69c48c753c92dc Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Tue, 12 Jun 2018 18:09:15 +0200 Subject: magmax.cpp: device_finder (nw) --- src/mame/drivers/magmax.cpp | 105 +++++++++++++++++++++----------------------- src/mame/includes/magmax.h | 44 ++++++++++++------- src/mame/video/magmax.cpp | 55 +++++++++-------------- 3 files changed, 100 insertions(+), 104 deletions(-) diff --git a/src/mame/drivers/magmax.cpp b/src/mame/drivers/magmax.cpp index 44af74b5432..65cb698f624 100644 --- a/src/mame/drivers/magmax.cpp +++ b/src/mame/drivers/magmax.cpp @@ -30,7 +30,6 @@ Stephh's notes (based on the game M68000 code and some tests) : #include "cpu/m68000/m68000.h" #include "cpu/z80/z80.h" -#include "sound/ay8910.h" #include "speaker.h" @@ -39,7 +38,7 @@ WRITE16_MEMBER(magmax_state::cpu_irq_ack_w) m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); } -READ8_MEMBER(magmax_state::magmax_sound_r) +READ8_MEMBER(magmax_state::sound_r) { return (m_soundlatch->read(space, 0) << 1) | m_LS74_q; } @@ -96,11 +95,6 @@ void magmax_state::machine_reset() WRITE8_MEMBER(magmax_state::ay8910_portA_0_w) { -ay8910_device *ay1 = machine().device("ay1"); -ay8910_device *ay2 = machine().device("ay2"); -ay8910_device *ay3 = machine().device("ay3"); -float percent; - /*There are three AY8910 chips and four(!) separate amplifiers on the board * Each of AY channels is hardware mapped in following way: * amplifier 0 gain x 1.00 <- AY0 CHA @@ -108,10 +102,10 @@ float percent; * amplifier 2 gain x 4.54 (150K/33K) <- AY1 CHC + AY2 CHA * amplifier 3 gain x 4.54 (150K/33K) <- AY2 CHB + AY2 CHC * -* Each of the amps has its own analog cuircit: +* Each of the amps has its own analog circuit: * amp0, amp1 and amp2 are different from each other; amp3 is the same as amp2 * -* Outputs of those amps are inputs to post amps, each having own cuircit +* Outputs of those amps are inputs to post amps, each having own circuit * that is partially controlled by AY #0 port A. * PORT A BIT 0 - control postamp 0 (gain x10.0 | gain x 5.00) * PORT A BIT 1 - control postamp 1 (gain x4.54 | gain x 2.27) @@ -120,7 +114,7 @@ float percent; * * The "control" means assert/clear input pins on chip called 4066 (it is analog switch) * which results in volume gain (exactly 2 times). -* I use mixer_set_volume() to emulate the effect. +* I use set_output_gain() to emulate the effect. gain summary: port A control ON OFF @@ -152,30 +146,30 @@ bit3 - SOUND Chan#8 name=AY-3-8910 #2 Ch C /*popmessage("gain_ctrl = %2x",data&0x0f);*/ - percent = (m_gain_control & 1) ? 1.0 : 0.50; - ay1->set_output_gain(0, percent); + float percent = (m_gain_control & 1) ? 1.0 : 0.50; + m_ay[0]->set_output_gain(0, percent); //fixme: set_RC_filter(0,10000,100000000,0,10000); /* 10K, 10000pF = 0.010uF */ percent = (m_gain_control & 2) ? 0.45 : 0.23; - ay1->set_output_gain(1, percent); - ay1->set_output_gain(2, percent); - ay2->set_output_gain(0, percent); - ay2->set_output_gain(1, percent); + m_ay[0]->set_output_gain(1, percent); + m_ay[0]->set_output_gain(2, percent); + m_ay[1]->set_output_gain(0, percent); + m_ay[1]->set_output_gain(1, percent); //fixme: set_RC_filter(1,4700,100000000,0,4700); /* 4.7K, 4700pF = 0.0047uF */ //fixme: set_RC_filter(2,4700,100000000,0,4700); /* 4.7K, 4700pF = 0.0047uF */ //fixme: set_RC_filter(3,4700,100000000,0,4700); /* 4.7K, 4700pF = 0.0047uF */ //fixme: set_RC_filter(4,4700,100000000,0,4700); /* 4.7K, 4700pF = 0.0047uF */ percent = (m_gain_control & 4) ? 0.45 : 0.23; - ay2->set_output_gain(2, percent); - ay3->set_output_gain(0, percent); + m_ay[1]->set_output_gain(2, percent); + m_ay[2]->set_output_gain(0, percent); percent = (m_gain_control & 8) ? 0.45 : 0.23; - ay3->set_output_gain(1, percent); - ay3->set_output_gain(2, percent); + m_ay[2]->set_output_gain(1, percent); + m_ay[2]->set_output_gain(2, percent); } -WRITE16_MEMBER(magmax_state::magmax_vreg_w) +WRITE16_MEMBER(magmax_state::vreg_w) { /* VRAM CONTROL REGISTER */ /* bit0 - coin counter 1 */ @@ -186,28 +180,31 @@ WRITE16_MEMBER(magmax_state::magmax_vreg_w) /* bit5 - sprite bank MSB (DP1) */ /* bit6 - BG display enable (BE)*/ COMBINE_DATA(m_vreg); + + machine().bookkeeping().coin_counter_w(0, BIT(data, 0)); + machine().bookkeeping().coin_counter_w(1, BIT(data, 1)); } -void magmax_state::magmax_map(address_map &map) +void magmax_state::main_map(address_map &map) { map(0x000000, 0x013fff).rom(); map(0x018000, 0x018fff).ram(); - map(0x020000, 0x0207ff).ram().share("videoram"); - map(0x028000, 0x0281ff).ram().share("spriteram"); + map(0x020000, 0x0207ff).ram().share(m_videoram); + map(0x028000, 0x0281ff).ram().share(m_spriteram); map(0x030000, 0x030001).portr("P1"); map(0x030002, 0x030003).portr("P2"); map(0x030004, 0x030005).portr("SYSTEM"); map(0x030006, 0x030007).portr("DSW"); - map(0x030010, 0x030011).w(FUNC(magmax_state::magmax_vreg_w)).share("vreg"); - map(0x030012, 0x030013).writeonly().share("scroll_x"); - map(0x030014, 0x030015).writeonly().share("scroll_y"); + map(0x030010, 0x030011).w(FUNC(magmax_state::vreg_w)).share(m_vreg); + map(0x030012, 0x030013).writeonly().share(m_scroll_x); + map(0x030014, 0x030015).writeonly().share(m_scroll_y); map(0x03001d, 0x03001d).w(m_soundlatch, FUNC(generic_latch_8_device::write)); map(0x03001e, 0x03001f).w(FUNC(magmax_state::cpu_irq_ack_w)); } -void magmax_state::magmax_sound_map(address_map &map) +void magmax_state::sound_map(address_map &map) { map.global_mask(0x7fff); // A15 not connected map(0x0000, 0x3fff).rom(); @@ -215,13 +212,13 @@ void magmax_state::magmax_sound_map(address_map &map) map(0x6000, 0x67ff).mirror(0x1800).ram(); } -void magmax_state::magmax_sound_io_map(address_map &map) +void magmax_state::sound_io_map(address_map &map) { map.global_mask(0xff); - map(0x00, 0x01).w("ay1", FUNC(ay8910_device::address_data_w)); - map(0x02, 0x03).w("ay2", FUNC(ay8910_device::address_data_w)); - map(0x04, 0x05).w("ay3", FUNC(ay8910_device::address_data_w)); - map(0x06, 0x06).r(FUNC(magmax_state::magmax_sound_r)); + map(0x00, 0x01).w(m_ay[0], FUNC(ay8910_device::address_data_w)); + map(0x02, 0x03).w(m_ay[1], FUNC(ay8910_device::address_data_w)); + map(0x04, 0x05).w(m_ay[2], FUNC(ay8910_device::address_data_w)); + map(0x06, 0x06).r(FUNC(magmax_state::sound_r)); } @@ -323,54 +320,54 @@ static const gfx_layout spritelayout = }; static GFXDECODE_START( gfx_magmax ) - GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 1 ) /*no color codes*/ - GFXDECODE_ENTRY( "gfx2", 0, spritelayout, 1*16, 16 ) /*16 color codes*/ + GFXDECODE_ENTRY( "chars", 0, charlayout, 0, 1 ) /*no color codes*/ + GFXDECODE_ENTRY( "sprites", 0, spritelayout, 1*16, 16 ) /*16 color codes*/ GFXDECODE_END MACHINE_CONFIG_START(magmax_state::magmax) /* basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", M68000, XTAL(16'000'000)/2) /* verified on pcb */ - MCFG_DEVICE_PROGRAM_MAP(magmax_map) + MCFG_DEVICE_ADD(m_maincpu, M68000, XTAL(16'000'000)/2) /* verified on pcb */ + MCFG_DEVICE_PROGRAM_MAP(main_map) MCFG_DEVICE_VBLANK_INT_DRIVER("screen", magmax_state, irq1_line_assert) - MCFG_DEVICE_ADD("audiocpu", Z80,XTAL(20'000'000)/8) /* verified on pcb */ - MCFG_DEVICE_PROGRAM_MAP(magmax_sound_map) - MCFG_DEVICE_IO_MAP(magmax_sound_io_map) + MCFG_DEVICE_ADD(m_audiocpu, Z80,XTAL(20'000'000)/8) /* verified on pcb */ + MCFG_DEVICE_PROGRAM_MAP(sound_map) + MCFG_DEVICE_IO_MAP(sound_io_map) MCFG_QUANTUM_TIME(attotime::from_hz(600)) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_ADD(m_screen, RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_SIZE(32*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) - MCFG_SCREEN_UPDATE_DRIVER(magmax_state, screen_update_magmax) - MCFG_SCREEN_PALETTE("palette") + MCFG_SCREEN_UPDATE_DRIVER(magmax_state, screen_update) + MCFG_SCREEN_PALETTE(m_palette) - MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_magmax) - MCFG_PALETTE_ADD("palette", 1*16 + 16*16 + 256) + MCFG_DEVICE_ADD(m_gfxdecode, GFXDECODE, m_palette, gfx_magmax) + MCFG_PALETTE_ADD(m_palette, 1*16 + 16*16 + 256) MCFG_PALETTE_INDIRECT_ENTRIES(256) MCFG_PALETTE_INIT_OWNER(magmax_state, magmax) /* sound hardware */ SPEAKER(config, "mono").front_center(); - MCFG_DEVICE_ADD("ay1", AY8910, XTAL(20'000'000)/16) /* verified on pcb */ - MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(*this, magmax_state, ay8910_portA_0_w)) /*write port A*/ - MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(*this, magmax_state, ay8910_portB_0_w)) /*write port B*/ + MCFG_DEVICE_ADD(m_ay[0], AY8910, XTAL(20'000'000)/16) /* verified on pcb */ + MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(*this, magmax_state, ay8910_portA_0_w)) + MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(*this, magmax_state, ay8910_portB_0_w)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40) - MCFG_DEVICE_ADD("ay2", AY8910, XTAL(20'000'000)/16) /* verified on pcb */ + MCFG_DEVICE_ADD(m_ay[1], AY8910, XTAL(20'000'000)/16) /* verified on pcb */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40) - MCFG_DEVICE_ADD("ay3", AY8910, XTAL(20'000'000)/16) /* verified on pcb */ + MCFG_DEVICE_ADD(m_ay[2], AY8910, XTAL(20'000'000)/16) /* verified on pcb */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40) - MCFG_GENERIC_LATCH_8_ADD("soundlatch") - MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0)) + MCFG_GENERIC_LATCH_8_ADD(m_soundlatch) + MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE(m_audiocpu, 0)) MCFG_GENERIC_LATCH_SEPARATE_ACKNOWLEDGE(true) MACHINE_CONFIG_END @@ -388,10 +385,10 @@ ROM_START( magmax ) ROM_LOAD( "15.17b", 0x00000, 0x2000, CRC(19e7b983) SHA1(b1cd0b728e7cce87d9b1039be179d0915d939a4f) ) ROM_LOAD( "16.18b", 0x02000, 0x2000, CRC(055e3126) SHA1(8c9b03eb7588512ef17f8c1b731a2fd7cf372bf8) ) - ROM_REGION( 0x02000, "gfx1", 0 ) /* chars */ + ROM_REGION( 0x02000, "chars", 0 ) ROM_LOAD( "23.15g", 0x00000, 0x2000, CRC(a7471da2) SHA1(ec2815a5801bc55955e612173a845399fd493eb7) ) - ROM_REGION( 0x10000, "gfx2", 0 ) /* sprites */ + ROM_REGION( 0x10000, "sprites", 0 ) ROM_LOAD( "17.3e", 0x00000, 0x2000, CRC(8e305b2e) SHA1(74c318089f6bebafbee31c22302e93a09d3ffa32) ) ROM_LOAD( "18.5e", 0x02000, 0x2000, CRC(14c55a60) SHA1(fd2a1b434bb65502f0f791995caf1cd869ccd254) ) ROM_LOAD( "19.6e", 0x04000, 0x2000, CRC(fa4141d8) SHA1(a5279d1ada5a13df14a8bbc18ceeea79f82a4c23) ) diff --git a/src/mame/includes/magmax.h b/src/mame/includes/magmax.h index 5ed8624ba17..1e0b3315729 100644 --- a/src/mame/includes/magmax.h +++ b/src/mame/includes/magmax.h @@ -2,6 +2,7 @@ // copyright-holders:Takahiro Nogi #include "screen.h" #include "machine/gen_latch.h" +#include "sound/ay8910.h" class magmax_state : public driver_device { @@ -13,18 +14,36 @@ public: m_vreg(*this, "vreg"), m_scroll_x(*this, "scroll_x"), m_scroll_y(*this, "scroll_y"), + m_rom18B(*this, "user1"), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), + m_ay(*this, "ay%u", 0U), m_soundlatch(*this, "soundlatch"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_palette(*this, "palette") { } + void magmax(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: required_shared_ptr m_videoram; required_shared_ptr m_spriteram; required_shared_ptr m_vreg; required_shared_ptr m_scroll_x; required_shared_ptr m_scroll_y; + required_region_ptr m_rom18B; + required_device m_maincpu; + required_device m_audiocpu; + required_device_array m_ay; + required_device m_soundlatch; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; uint8_t m_sound_latch; uint8_t m_LS74_clr; @@ -34,25 +53,18 @@ public: int m_flipscreen; std::unique_ptr m_prom_tab; bitmap_ind16 m_bitmap; + DECLARE_WRITE16_MEMBER(cpu_irq_ack_w); - DECLARE_READ8_MEMBER(magmax_sound_r); - DECLARE_WRITE16_MEMBER(magmax_vreg_w); + DECLARE_READ8_MEMBER(sound_r); + DECLARE_WRITE16_MEMBER(vreg_w); DECLARE_WRITE8_MEMBER(ay8910_portB_0_w); DECLARE_WRITE8_MEMBER(ay8910_portA_0_w); - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; + DECLARE_PALETTE_INIT(magmax); - uint32_t screen_update_magmax(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); TIMER_CALLBACK_MEMBER(scanline_callback); - required_device m_maincpu; - required_device m_audiocpu; - required_device m_soundlatch; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; - void magmax(machine_config &config); - void magmax_map(address_map &map); - void magmax_sound_io_map(address_map &map); - void magmax_sound_map(address_map &map); + + void main_map(address_map &map); + void sound_io_map(address_map &map); + void sound_map(address_map &map); }; diff --git a/src/mame/video/magmax.cpp b/src/mame/video/magmax.cpp index b7a9ec495c4..d3a04f03441 100644 --- a/src/mame/video/magmax.cpp +++ b/src/mame/video/magmax.cpp @@ -29,10 +29,9 @@ Additional tweaking by Jarek Burczynski PALETTE_INIT_MEMBER(magmax_state, magmax) { const uint8_t *color_prom = memregion("proms")->base(); - int i; /* create a lookup table for the palette */ - for (i = 0; i < 0x100; i++) + for (int i = 0; i < 0x100; i++) { int r = pal4bit(color_prom[i + 0x000]); int g = pal4bit(color_prom[i + 0x100]); @@ -45,25 +44,24 @@ PALETTE_INIT_MEMBER(magmax_state, magmax) color_prom += 0x300; /* characters use colors 0-0x0f */ - for (i = 0; i < 0x10; i++) + for (int i = 0; i < 0x10; i++) palette.set_pen_indirect(i, i); /*sprites use colors 0x10-0x1f, color 0x1f being transparent*/ - for (i = 0x10; i < 0x110; i++) + for (int i = 0x10; i < 0x110; i++) { uint8_t ctabentry = (color_prom[i - 0x10] & 0x0f) | 0x10; palette.set_pen_indirect(i, ctabentry); } /* background uses all colors (no lookup table) */ - for (i = 0x110; i < 0x210; i++) + for (int i = 0x110; i < 0x210; i++) palette.set_pen_indirect(i, i - 0x110); } void magmax_state::video_start() { - int i,v; uint8_t * prom14D = memregion("user2")->base(); /* Set up save state */ @@ -74,21 +72,17 @@ void magmax_state::video_start() m_screen->register_screen_bitmap(m_bitmap); /* Allocate temporary bitmap */ - for (i=0; i<256; i++) + for (int i = 0; i < 256; i++) { - v = (prom14D[i] << 4) + prom14D[i + 0x100]; + int v = (prom14D[i] << 4) + prom14D[i + 0x100]; m_prom_tab[i] = ((v&0x1f)<<8) | ((v&0x10)<<10) | ((v&0xe0)>>1); /*convert data into more useful format*/ } } -uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t magmax_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint16_t *videoram = m_videoram; - uint16_t *spriteram16 = m_spriteram; - int offs; - /* bit 2 flip screen */ m_flipscreen = *m_vreg & 0x04; @@ -97,17 +91,14 @@ uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 bitmap.fill(0, cliprect); else { - int v; - uint8_t * rom18B = memregion("user1")->base(); uint32_t scroll_h = (*m_scroll_x) & 0x3fff; uint32_t scroll_v = (*m_scroll_y) & 0xff; /*clear background-over-sprites bitmap*/ m_bitmap.fill(0); - for (v = 2*8; v < 30*8; v++) /*only for visible area*/ + for (int v = 2*8; v < 30*8; v++) /*only for visible area*/ { - int h; uint16_t line_data[256]; uint32_t map_v_scr_100 = (scroll_v + v) & 0x100; @@ -117,7 +108,7 @@ uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 pen_t pen_base = 0x110 + 0x20 + (map_v_scr_100>>1); - for (h = 0; h < 0x100; h++) + for (int h = 0; h < 0x100; h++) { uint32_t graph_data; uint32_t graph_color; @@ -129,9 +120,9 @@ uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 if (!map_v_scr_100) { if (h & 0x80) - LS283 = LS283 + (rom18B[ map_v_scr_1fe_6 + (h ^ 0xff) ] ^ 0xff); + LS283 = LS283 + (m_rom18B[ map_v_scr_1fe_6 + (h ^ 0xff) ] ^ 0xff); else - LS283 = LS283 + rom18B[ map_v_scr_1fe_6 + h ] + 0xff01; + LS283 = LS283 + m_rom18B[ map_v_scr_1fe_6 + h ] + 0xff01; } prom_data = m_prom_tab[ (LS283 >> 6) & 0xff ]; @@ -140,12 +131,12 @@ uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 rom18D_addr += (prom_data & 0x1f00) + ((LS283 & 0x38) >>3); rom15F_addr &= 0x201c; - rom15F_addr += (rom18B[0x4000 + rom18D_addr ]<<5) + ((LS283 & 0x6)>>1); + rom15F_addr += (m_rom18B[0x4000 + rom18D_addr ]<<5) + ((LS283 & 0x6)>>1); rom15F_addr += (prom_data & 0x4000); graph_color = (prom_data & 0x0070); - graph_data = rom18B[0x8000 + rom15F_addr]; + graph_data = m_rom18B[0x8000 + rom15F_addr]; if ((LS283 & 1)) graph_data >>= 4; graph_data &= 0x0f; @@ -159,9 +150,8 @@ uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 if (m_flipscreen) { - int i; uint16_t line_data_flip_x[256]; - for (i=0; i<256; i++) + for (int i = 0; i < 256; i++) line_data_flip_x[i] = line_data[255-i]; draw_scanline16(bitmap, 0, 255-v, 256, line_data_flip_x, nullptr); } @@ -171,21 +161,19 @@ uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 } /* draw the sprites */ - for (offs = 0; offs < m_spriteram.bytes()/2; offs += 4) + for (int offs = 0; offs < m_spriteram.bytes()/2; offs += 4) { - int sx, sy; - - sy = spriteram16[offs] & 0xff; + int sy = m_spriteram[offs] & 0xff; if (sy) { - int code = spriteram16[offs + 1] & 0xff; - int attr = spriteram16[offs + 2] & 0xff; + int code = m_spriteram[offs + 1] & 0xff; + int attr = m_spriteram[offs + 2] & 0xff; int color = (attr & 0xf0) >> 4; int flipx = attr & 0x04; int flipy = attr & 0x08; - sx = (spriteram16[offs + 3] & 0xff) - 0x80 + 0x100 * (attr & 0x01); + int sx = (m_spriteram[offs + 3] & 0xff) - 0x80 + 0x100 * (attr & 0x01); sy = 239 - sy; if (m_flipscreen) @@ -212,12 +200,11 @@ uint32_t magmax_state::screen_update_magmax(screen_device &screen, bitmap_ind16 copybitmap_trans(bitmap, m_bitmap, m_flipscreen,m_flipscreen,0,0, cliprect, 0); /* draw the foreground characters */ - for (offs = 32*32-1; offs >= 0; offs -= 1) + for (int offs = 32*32-1; offs >= 0; offs -= 1) { //int page = (*m_vreg>>3) & 0x1; - int code; + int code = m_videoram[offs /*+ page*/] & 0xff; - code = videoram[offs /*+ page*/] & 0xff; if (code) { int sx = (offs % 32); -- cgit v1.2.3 From 831222b40d3497b39055314668ad019585fd7ec0 Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Tue, 12 Jun 2018 18:14:13 +0200 Subject: new working clone --------------------------- Gran Rally (Spanish bootleg of Pole Position II) [Jordi Beltran Casany, Recreativas.org, The Dumping Union] --- src/mame/drivers/polepos.cpp | 206 ++++++++++++++++++++++++++++++------------- src/mame/includes/polepos.h | 77 ++++++++-------- src/mame/mame.lst | 1 + src/mame/video/polepos.cpp | 111 +++++++++-------------- 4 files changed, 226 insertions(+), 169 deletions(-) diff --git a/src/mame/drivers/polepos.cpp b/src/mame/drivers/polepos.cpp index 30a9a5c46cc..144d30f39b7 100644 --- a/src/mame/drivers/polepos.cpp +++ b/src/mame/drivers/polepos.cpp @@ -212,7 +212,7 @@ Notes: Todo: -- the bootlegs without Namco devices (topracern, polepos2bi) still require +- the bootlegs without Namco devices (i.e. topracern, polepos2bi) still require our 06xx and 51xx emulation to boot, this is incorrect. ***************************************************************************/ @@ -226,7 +226,6 @@ Todo: #include "cpu/z80/z80.h" #include "cpu/z8000/z8000.h" #include "cpu/mb88xx/mb88xx.h" -#include "machine/74259.h" #include "machine/namco06.h" #include "machine/namco51.h" #include "machine/namco53.h" @@ -273,12 +272,12 @@ READ16_MEMBER(polepos_state::polepos2_ic25_r) } -READ8_MEMBER(polepos_state::polepos_adc_r) +READ8_MEMBER(polepos_state::adc_r) { return ioport(m_adc_input ? "ACCEL" : "BRAKE")->read(); } -READ8_MEMBER(polepos_state::polepos_ready_r) +READ8_MEMBER(polepos_state::ready_r) { int ret = 0xff; @@ -306,7 +305,7 @@ WRITE_LINE_MEMBER(polepos_state::sb0_w) m_auto_start_mask = !state; } -template WRITE16_MEMBER(polepos_state::polepos_z8002_nvi_enable_w) +template WRITE16_MEMBER(polepos_state::z8002_nvi_enable_w) { data &= 1; @@ -380,7 +379,7 @@ READ8_MEMBER(polepos_state::steering_delta_r) return m_steer_delta; } -TIMER_DEVICE_CALLBACK_MEMBER(polepos_state::polepos_scanline) +TIMER_DEVICE_CALLBACK_MEMBER(polepos_state::scanline) { int scanline = param; @@ -394,8 +393,19 @@ TIMER_DEVICE_CALLBACK_MEMBER(polepos_state::polepos_scanline) } } +void polepos_state::machine_start() +{ + save_item(NAME(m_steer_last)); + save_item(NAME(m_steer_delta)); + save_item(NAME(m_steer_accum)); + save_item(NAME(m_last_result)); + save_item(NAME(m_last_signed)); + save_item(NAME(m_last_unsigned)); + save_item(NAME(m_adc_input)); + save_item(NAME(m_auto_start_mask)); +} -MACHINE_RESET_MEMBER(polepos_state,polepos) +void polepos_state::machine_reset() { /* set the interrupt vectors (this shouldn't be needed) */ m_subcpu->set_input_line_vector(0, Z8000_NVI); @@ -412,17 +422,17 @@ void polepos_state::z80_map(address_map &map) { map(0x0000, 0x2fff).rom(); map(0x3000, 0x37ff).mirror(0x0800).ram().share("nvram"); /* Battery Backup */ - map(0x4000, 0x47ff).rw(FUNC(polepos_state::polepos_sprite_r), FUNC(polepos_state::polepos_sprite_w)); /* Motion Object */ - map(0x4800, 0x4bff).rw(FUNC(polepos_state::polepos_road_r), FUNC(polepos_state::polepos_road_w)); /* Road Memory */ - map(0x4c00, 0x4fff).rw(FUNC(polepos_state::polepos_alpha_r), FUNC(polepos_state::polepos_alpha_w)); /* Alphanumeric (char ram) */ - map(0x5000, 0x57ff).rw(FUNC(polepos_state::polepos_view_r), FUNC(polepos_state::polepos_view_w)); /* Background Memory */ + map(0x4000, 0x47ff).rw(FUNC(polepos_state::sprite_r), FUNC(polepos_state::sprite_w)); /* Motion Object */ + map(0x4800, 0x4bff).rw(FUNC(polepos_state::road_r), FUNC(polepos_state::road_w)); /* Road Memory */ + map(0x4c00, 0x4fff).rw(FUNC(polepos_state::alpha_r), FUNC(polepos_state::alpha_w)); /* Alphanumeric (char ram) */ + map(0x5000, 0x57ff).rw(FUNC(polepos_state::view_r), FUNC(polepos_state::view_w)); /* Background Memory */ map(0x8000, 0x83bf).mirror(0x0c00).ram(); /* Sound Memory */ map(0x83c0, 0x83ff).mirror(0x0c00).rw(m_namco_sound, FUNC(namco_device::polepos_sound_r), FUNC(namco_device::polepos_sound_w)); /* Sound data */ map(0x9000, 0x9000).mirror(0x0eff).rw("06xx", FUNC(namco_06xx_device::data_r), FUNC(namco_06xx_device::data_w)); map(0x9100, 0x9100).mirror(0x0eff).rw("06xx", FUNC(namco_06xx_device::ctrl_r), FUNC(namco_06xx_device::ctrl_w)); - map(0xa000, 0xa000).mirror(0x0cff).r(FUNC(polepos_state::polepos_ready_r)); /* READY */ + map(0xa000, 0xa000).mirror(0x0cff).r(FUNC(polepos_state::ready_r)); /* READY */ map(0xa000, 0xa007).mirror(0x0cf8).w(m_latch, FUNC(ls259_device::write_d0)); map(0xa100, 0xa100).mirror(0x0cff).w("watchdog", FUNC(watchdog_timer_device::reset_w)); map(0xa200, 0xa200).mirror(0x0cff).w("polepos", FUNC(polepos_sound_device::polepos_engine_sound_lsb_w)); /* Car Sound ( Lower Nibble ) */ @@ -432,7 +442,7 @@ void polepos_state::z80_map(address_map &map) void polepos_state::z80_io(address_map &map) { map.global_mask(0xff); - map(0x00, 0x00).r(FUNC(polepos_state::polepos_adc_r)).nopw(); + map(0x00, 0x00).r(FUNC(polepos_state::adc_r)).nopw(); } @@ -440,24 +450,24 @@ void polepos_state::z80_io(address_map &map) void polepos_state::z8002_map(address_map &map) { map(0x0000, 0x7fff).rom(); - map(0x8000, 0x8fff).rw(FUNC(polepos_state::polepos_sprite16_r), FUNC(polepos_state::polepos_sprite16_w)).share("sprite16_memory"); /* Motion Object */ - map(0x9000, 0x97ff).rw(FUNC(polepos_state::polepos_road16_r), FUNC(polepos_state::polepos_road16_w)).share("road16_memory"); /* Road Memory */ - map(0x9800, 0x9fff).rw(FUNC(polepos_state::polepos_alpha16_r), FUNC(polepos_state::polepos_alpha16_w)).share("alpha16_memory"); /* Alphanumeric (char ram) */ - map(0xa000, 0xafff).rw(FUNC(polepos_state::polepos_view16_r), FUNC(polepos_state::polepos_view16_w)).share("view16_memory"); /* Background memory */ - map(0xc000, 0xc001).mirror(0x38fe).w(FUNC(polepos_state::polepos_view16_hscroll_w)); /* Background horz scroll position */ - map(0xc100, 0xc101).mirror(0x38fe).w(FUNC(polepos_state::polepos_road16_vscroll_w)); /* Road vertical position */ + map(0x8000, 0x8fff).ram().share(m_sprite16_memory); /* Motion Object */ + map(0x9000, 0x97ff).ram().share(m_road16_memory); /* Road Memory */ + map(0x9800, 0x9fff).ram().w(FUNC(polepos_state::alpha16_w)).share(m_alpha16_memory); /* Alphanumeric (char ram) */ + map(0xa000, 0xafff).ram().w(FUNC(polepos_state::view16_w)).share(m_view16_memory); /* Background memory */ + map(0xc000, 0xc001).mirror(0x38fe).w(FUNC(polepos_state::view16_hscroll_w)); /* Background horz scroll position */ + map(0xc100, 0xc101).mirror(0x38fe).w(FUNC(polepos_state::road16_vscroll_w)); /* Road vertical position */ } void polepos_state::z8002_map_1(address_map &map) { z8002_map(map); - map(0x6000, 0x6001).mirror(0x0ffe).w(FUNC(polepos_state::polepos_z8002_nvi_enable_w)); /* NVI enable - *NOT* shared by the two CPUs */ + map(0x6000, 0x6001).mirror(0x0ffe).w(FUNC(polepos_state::z8002_nvi_enable_w)); /* NVI enable - *NOT* shared by the two CPUs */ } void polepos_state::z8002_map_2(address_map &map) { z8002_map(map); - map(0x6000, 0x6001).mirror(0x0ffe).w(FUNC(polepos_state::polepos_z8002_nvi_enable_w)); /* NVI enable - *NOT* shared by the two CPUs */ + map(0x6000, 0x6001).mirror(0x0ffe).w(FUNC(polepos_state::z8002_nvi_enable_w)); /* NVI enable - *NOT* shared by the two CPUs */ } @@ -842,14 +852,14 @@ GFXDECODE_END MACHINE_CONFIG_START(polepos_state::polepos) /* basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", Z80, MASTER_CLOCK/8) /* 3.072 MHz */ + MCFG_DEVICE_ADD(m_maincpu, Z80, MASTER_CLOCK/8) /* 3.072 MHz */ MCFG_DEVICE_PROGRAM_MAP(z80_map) MCFG_DEVICE_IO_MAP(z80_io) - MCFG_DEVICE_ADD("sub", Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ + MCFG_DEVICE_ADD(m_subcpu, Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ MCFG_DEVICE_PROGRAM_MAP(z8002_map_1) - MCFG_DEVICE_ADD("sub2", Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ + MCFG_DEVICE_ADD(m_subcpu2, Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ MCFG_DEVICE_PROGRAM_MAP(z8002_map_2) MCFG_NAMCO_51XX_ADD("51xx", MASTER_CLOCK/8/2) /* 1.536 MHz */ @@ -892,41 +902,39 @@ MACHINE_CONFIG_START(polepos_state::polepos) MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* some interleaving */ - MCFG_MACHINE_RESET_OVERRIDE(polepos_state,polepos) MCFG_NVRAM_ADD_1FILL("nvram") - MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", polepos_state, polepos_scanline, "screen", 0, 1) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", polepos_state, scanline, "screen", 0, 1) - MCFG_DEVICE_ADD("latch", LS259, 0) // at 8E on polepos - MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(CLEARLINE("maincpu", 0)) MCFG_DEVCB_INVERT + MCFG_DEVICE_ADD(m_latch, LS259, 0) // at 8E on polepos + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(CLEARLINE(m_maincpu, 0)) MCFG_DEVCB_INVERT MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE(*this, polepos_state, iosel_w)) - MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE("namco", namco_device, sound_enable_w)) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE(m_namco_sound, namco_device, sound_enable_w)) MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("polepos", polepos_sound_device, clson_w)) MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(*this, polepos_state, gasel_w)) - MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(INPUTLINE("sub", INPUT_LINE_RESET)) MCFG_DEVCB_INVERT - MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(INPUTLINE("sub2", INPUT_LINE_RESET)) MCFG_DEVCB_INVERT + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(INPUTLINE(m_subcpu, INPUT_LINE_RESET)) MCFG_DEVCB_INVERT + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(INPUTLINE(m_subcpu2, INPUT_LINE_RESET)) MCFG_DEVCB_INVERT MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE(*this, polepos_state, sb0_w)) MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(*this, polepos_state, chacl_w)) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_ADD(m_screen, RASTER) MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK/4, 384, 0, 256, 264, 16, 224+16) - MCFG_SCREEN_UPDATE_DRIVER(polepos_state, screen_update_polepos) - MCFG_SCREEN_PALETTE("palette") + MCFG_SCREEN_UPDATE_DRIVER(polepos_state, screen_update) + MCFG_SCREEN_PALETTE(m_palette) - MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_polepos) - MCFG_PALETTE_ADD("palette", 0x0f00) + MCFG_DEVICE_ADD(m_gfxdecode, GFXDECODE, m_palette, gfx_polepos) + MCFG_PALETTE_ADD(m_palette, 0x0f00) MCFG_PALETTE_INDIRECT_ENTRIES(128) MCFG_DEFAULT_LAYOUT(layout_polepos) MCFG_PALETTE_INIT_OWNER(polepos_state,polepos) - MCFG_VIDEO_START_OVERRIDE(polepos_state,polepos) /* sound hardware */ SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - MCFG_DEVICE_ADD("namco", NAMCO, MASTER_CLOCK/512) + MCFG_DEVICE_ADD(m_namco_sound, NAMCO, MASTER_CLOCK/512) MCFG_NAMCO_AUDIO_VOICES(8) MCFG_NAMCO_AUDIO_STEREO(1) MCFG_SOUND_ROUTE(0, "lspeaker", 0.80) @@ -978,17 +986,17 @@ void polepos_state::sound_z80_bootleg_iomap(address_map &map) MACHINE_CONFIG_START(polepos_state::topracern) /* basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", Z80, MASTER_CLOCK/8) /* 3.072 MHz */ + MCFG_DEVICE_ADD(m_maincpu, Z80, MASTER_CLOCK/8) /* 3.072 MHz */ MCFG_DEVICE_PROGRAM_MAP(z80_map) MCFG_DEVICE_IO_MAP(topracern_io) - MCFG_DEVICE_ADD("sub", Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ + MCFG_DEVICE_ADD(m_subcpu, Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ MCFG_DEVICE_PROGRAM_MAP(z8002_map_1) - MCFG_DEVICE_ADD("sub2", Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ + MCFG_DEVICE_ADD(m_subcpu2, Z8002, MASTER_CLOCK/8) /* 3.072 MHz */ MCFG_DEVICE_PROGRAM_MAP(z8002_map_2) - /* todo, remove these devices too, this bootleg doesn't have them, but the emulation doesn't boot without them.. */ + /* TODO, remove these devices too, this bootleg doesn't have them, but the emulation doesn't boot without them.. */ /* doesn't exist on the bootleg, but required for now or the game only boots in test mode! they probably simulate some of the logic */ MCFG_NAMCO_51XX_ADD("51xx", MASTER_CLOCK/8/2) /* 1.536 MHz */ @@ -1005,41 +1013,39 @@ MACHINE_CONFIG_START(polepos_state::topracern) MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* some interleaving */ - MCFG_MACHINE_RESET_OVERRIDE(polepos_state,polepos) MCFG_NVRAM_ADD_1FILL("nvram") - MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", polepos_state, polepos_scanline, "screen", 0, 1) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", polepos_state, scanline, "screen", 0, 1) - MCFG_DEVICE_ADD("latch", LS259, 0) - MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(CLEARLINE("maincpu", 0)) MCFG_DEVCB_INVERT + MCFG_DEVICE_ADD(m_latch, LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(CLEARLINE(m_maincpu, 0)) MCFG_DEVCB_INVERT MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE(*this, polepos_state, iosel_w)) - MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE("namco", namco_device, sound_enable_w)) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE(m_namco_sound, namco_device, sound_enable_w)) MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("polepos", polepos_sound_device, clson_w)) MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(*this, polepos_state, gasel_w)) - MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(INPUTLINE("sub", INPUT_LINE_RESET)) MCFG_DEVCB_INVERT - MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(INPUTLINE("sub2", INPUT_LINE_RESET)) MCFG_DEVCB_INVERT + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(INPUTLINE(m_subcpu, INPUT_LINE_RESET)) MCFG_DEVCB_INVERT + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(INPUTLINE(m_subcpu2, INPUT_LINE_RESET)) MCFG_DEVCB_INVERT MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE(*this, polepos_state, sb0_w)) MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(*this, polepos_state, chacl_w)) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_ADD(m_screen, RASTER) MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK/4, 384, 0, 256, 264, 16, 224+16) - MCFG_SCREEN_UPDATE_DRIVER(polepos_state, screen_update_polepos) - MCFG_SCREEN_PALETTE("palette") + MCFG_SCREEN_UPDATE_DRIVER(polepos_state, screen_update) + MCFG_SCREEN_PALETTE(m_palette) - MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_polepos) - MCFG_PALETTE_ADD("palette", 0x0f00) + MCFG_DEVICE_ADD(m_gfxdecode, GFXDECODE, m_palette, gfx_polepos) + MCFG_PALETTE_ADD(m_palette, 0x0f00) MCFG_PALETTE_INDIRECT_ENTRIES(128) MCFG_DEFAULT_LAYOUT(layout_topracer) MCFG_PALETTE_INIT_OWNER(polepos_state,polepos) - MCFG_VIDEO_START_OVERRIDE(polepos_state,polepos) /* sound hardware */ SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - MCFG_DEVICE_ADD("namco", NAMCO, MASTER_CLOCK/512) + MCFG_DEVICE_ADD(m_namco_sound, NAMCO, MASTER_CLOCK/512) MCFG_NAMCO_AUDIO_VOICES(8) MCFG_NAMCO_AUDIO_STEREO(1) MCFG_SOUND_ROUTE(0, "lspeaker", 0.80) @@ -1060,12 +1066,12 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(polepos_state::polepos2bi) topracern(config); - MCFG_DEVICE_ADD("soundz80bl", Z80, MASTER_CLOCK/8) /*? MHz */ + MCFG_DEVICE_ADD(m_sound_z80, Z80, MASTER_CLOCK/8) /*? MHz */ MCFG_DEVICE_PROGRAM_MAP(sound_z80_bootleg_map) MCFG_DEVICE_IO_MAP(sound_z80_bootleg_iomap) - MCFG_GENERIC_LATCH_8_ADD("soundlatch") - MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("soundz80bl", INPUT_LINE_NMI)) + MCFG_GENERIC_LATCH_8_ADD(m_soundlatch) + MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE(m_sound_z80, INPUT_LINE_NMI)) MCFG_GENERIC_LATCH_SEPARATE_ACKNOWLEDGE(true) MCFG_DEVICE_ADD("tms", TMS5220, 600000) /* ? Mhz */ @@ -1926,8 +1932,7 @@ ROM_END CPU/Sound Board: A039185 Video Board: A039187 - Pole Position 2 uses the same hardware as Pole Position except there a - couple of extra roms. + Pole Position 2 uses the same hardware as Pole Position except there are a couple of extra roms. */ ROM_START( polepos2a ) @@ -2357,7 +2362,85 @@ ROM_START( polepos2bs ) // ...not dumped yet... ROM_END +ROM_START( grally ) + /* Z80 memory/ROM data */ + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "gr_niemer_bboard-5p-2764.17f", 0x0000, 0x2000, CRC(1a6412a1) SHA1(ccc41e60aad6ed332f8f2582860e11f10937dffa) ) + ROM_LOAD( "gr_niemer_bboard-6p-2732.16f", 0x2000, 0x1000, CRC(e7362148) SHA1(5a4ab037fa6a773b90c10ac4c4e9417183e0cfd8) ) + + /* Z8002 #1 memory/ROM data */ + ROM_REGION( 0x10000, "sub", 0 ) + ROM_LOAD16_BYTE( "gr_niemer_bboard-1p-2764.23f", 0x0001, 0x2000, CRC(41da3c28) SHA1(c9294d686282adfc72796511c3c9e186ad057374) ) + ROM_LOAD16_BYTE( "gr_niemer_bboard-2p-2764.21f", 0x0000, 0x2000, CRC(2856d5b1) SHA1(96f5c3d67901a1abceca12b3448f381cc4852a33) ) + + /* Z8002 #2 memory/ROM data */ + ROM_REGION( 0x10000, "sub2", 0 ) + ROM_LOAD16_BYTE( "gr_niemer_bboard-3p-27128.20f", 0x0001, 0x4000, CRC(6c823932) SHA1(68ef9f70c4305c3a3bacf83a64b727fd3711f34f) ) + ROM_LOAD16_BYTE( "gr_niemer_bboard-4p-27128.18f", 0x0000, 0x4000, CRC(fe9baeb6) SHA1(9a8ad2d8a69b4005f7abed278093fd57b9242bca) ) + + /* graphics data */ + ROM_REGION( 0x02000, "gfx1", 0 ) /* 2bpp alpha layer */ + ROM_LOAD( "gr_niemer_cboard-12f-2764.2j", 0x0000, 0x2000, CRC(4b0a3fe9) SHA1(b0c69df94ac41a2f0705db69500cd0a224b854ad) ) + + ROM_REGION( 0x02000, "gfx2", 0 ) /* 2bpp view layer */ + ROM_LOAD( "gr_niemer_cboard-15f-2764.2l", 0x0000, 0x2000, CRC(ec3ec6e6) SHA1(ae905d0ae802d1010b2c1f1a13e88a1f0dbe57da) ) + + ROM_REGION( 0x04000, "gfx3", 0 ) /* 4bpp 16x16 sprites */ + ROM_LOAD( "gr_niemer_cboard-6f-2764.5a", 0x0000, 0x2000, CRC(1c72041a) SHA1(b65b09c4251ee61d247f359615e7adc7c80bc8d5) ) /* 4bpp sm sprites, planes 0+1 */ + ROM_LOAD( "gr_niemer_cboard-5f-2764.6a", 0x2000, 0x2000, CRC(1b38b257) SHA1(c7eec0692a31e1c8285bd1cba3ebd17ab253d2c9) ) /* 4bpp sm sprites, planes 2+3 */ + + ROM_REGION( 0x10000, "gfx4", 0 ) /* 4bpp 32x32 sprites */ + ROM_LOAD( "gr_niemer_cboard-10f-2764.1a", 0x0000, 0x2000, CRC(613ab0df) SHA1(88aa4500275aae010fc9783c1d8d843feab89afa) ) /* 4bpp lg sprites, planes 0+1 */ + ROM_LOAD( "gr_niemer_cboard-9f-2764.2a", 0x2000, 0x2000, CRC(2d11fc01) SHA1(0515df62073db993899dde3f9ad84334c5a12fc5) ) + ROM_LOAD( "gr_niemer_cboard-8f-2764.3a", 0x4000, 0x2000, CRC(17c798b0) SHA1(ae2047bc0e4e8c85e1de09c39c200ea8f7c6a72e) ) + ROM_LOAD( "gr_niemer_cboard-7f-2764.4a", 0x6000, 0x2000, CRC(ed6a8052) SHA1(dedd6d63f9a06a1edd57cb134e86c048cff7a3c1) ) + ROM_LOAD( "gr_niemer_cboard-4f-2764.7a", 0x8000, 0x2000, CRC(5fd933e3) SHA1(5b27a8519234c935308f943cd58abc1efc463726) ) /* 4bpp lg sprites, planes 2+3 */ + ROM_LOAD( "gr_niemer_cboard-3f-2764.8a", 0xa000, 0x2000, CRC(94a7155d) SHA1(c162e2b0e93745614475326905a30d2095101913) ) + ROM_LOAD( "gr_niemer_cboard-2f-2764.9a", 0xc000, 0x2000, CRC(5fe9b365) SHA1(1a3ac099a6bb506a5f71c12c6fb14d014172371c) ) + ROM_LOAD( "gr_niemer_cboard-1fr-2764.10a", 0xe000, 0x2000, CRC(1f553db8) SHA1(897e8103e8023918dae8b45b19ad1ecb34a92b3f) ) + + ROM_REGION( 0x5000, "gfx5", 0 ) /* road generation ROMs needed at runtime */ + ROM_LOAD( "gr_niemer_cboard-14f-2764.8m", 0x0000, 0x2000, CRC(ee6b3315) SHA1(9cc26c6d3604c0f60d716f86e67e9d9c0487f87d) ) /* road control */ + ROM_LOAD( "gr_niemer_cboard-13f-2764.9m", 0x2000, 0x2000, CRC(6d1e7042) SHA1(90113ff0c93ed86d95067290088705bb5e6608d1) ) /* road bits 1 */ + ROM_LOAD( "gr_niemer_cboard-16f-2732.8r", 0x4000, 0x1000, CRC(4e97f101) SHA1(f377d053821c74aee93ebcd30a4d43e6156f3cfe) ) /* road bits 2 */ + + ROM_REGION( 0x1000, "gfx6", 0 ) /* sprite scaling */ + ROM_LOAD( "gr_niemer_cboard-11f-2732.9c", 0x0000, 0x1000, CRC(a61bff15) SHA1(f7a59970831cdaaa7bf59c2221a38e4746c54244) ) /* vertical scaling */ + + /* graphics (P)ROM data */ + ROM_REGION( 0x1040, "proms", 0 ) + ROM_LOAD( "gr-niemer-cboard-f1-82s129.2u", 0x0000, 0x0100, CRC(16d69c31) SHA1(f24b345448e4f4ef4e2f3b057b81d399cf427f88) ) /* red palette */ + ROM_LOAD( "gr-niemer-cboard-f2-82s129.2t", 0x0100, 0x0100, CRC(07340311) SHA1(3820d1fa99013ed18de5d9400ad376cc446d1217) ) /* green palette */ + ROM_LOAD( "gr-niemer-cboard-f3-82s129.2s", 0x0200, 0x0100, CRC(1efc84d7) SHA1(6946e1c209eec0a4b75778ae88111e6cb63c63fb) ) /* blue palette */ + ROM_LOAD( "gr-niemer-cboard-f4-82s129.2p", 0x0300, 0x0100, CRC(064d51a0) SHA1(d5baa29930530a8930b44a374e285de849c2a6ce) ) /* alpha color */ + ROM_LOAD( "gr-niemer-cboard-f5-82s129.2n", 0x0400, 0x0100, CRC(7880c5af) SHA1(e4388e354420be3f99594a10c091e3d2f745cc04) ) /* background color */ + ROM_LOAD( "gr-niemer-cboard-f8-82s129.13f", 0x0500, 0x0100, CRC(2d502464) SHA1(682b7dd22e51d5db52c0804b7e27e47641dfa6bd) ) /* vertical position low */ + ROM_LOAD( "gr-niemer-cboard-f9-82s129.13e", 0x0600, 0x0100, CRC(027aa62c) SHA1(c7030d8b64b80e107c446f6fbdd63f560c0a91c0) ) /* vertical position med */ + ROM_LOAD( "gr-niemer-cboard-f10-82s129.13d", 0x0700, 0x0100, CRC(1f8d0df3) SHA1(b8f17758f114f5e247b65b3f2922ca2660757e66) ) /* vertical position hi */ + ROM_LOAD( "gr-niemer-cboard-f6-82s137.5p", 0x0800, 0x0400, CRC(8b270902) SHA1(27b3ebc92d3a2a5c0432bde018a0e43669041d50) ) /* road color */ + ROM_LOAD( "gr-niemer-cboard-f7-82s137.7h", 0x0c00, 0x0400, CRC(a079ed19) SHA1(134b3d156a1ed0fa21cc5dc3cc84ea16ef7f84f7) ) /* sprite color */ + ROM_LOAD( "gr-niemer-cboard-82s123.15s", 0x1000, 0x0020, CRC(4330a51b) SHA1(9531d18ce2de4eda9913d47ef8c5cd8f05791716) ) /* video RAM address decoder (not used) */ + ROM_LOAD( "gr-niemer-cboard-82s123.15t", 0x1020, 0x0020, CRC(4330a51b) SHA1(9531d18ce2de4eda9913d47ef8c5cd8f05791716) ) /* video RAM address decoder (not used) */ + + /* sound (P)ROM data */ + ROM_REGION( 0x0100, "namco", 0 ) // not dumped for this board + ROM_LOAD( "bboard-2p.9e", 0x0000, 0x0100, CRC(8568decc) SHA1(0aac1fa082858d4d201e21511c609a989f9a1535) ) /* Namco sound */ + + ROM_REGION( 0x4000, "engine", 0 ) + ROM_LOAD( "gr_niemer_bboard-8p-2764.8a", 0x0000, 0x2000, CRC(b5ad4d5f) SHA1(c07e77a050200d6fe9952031f971ca35f4d15ff8) ) /* engine sound */ + ROM_LOAD( "gr_niemer_bboard-7p-2764.9a", 0x2000, 0x2000, CRC(8fdd2f6f) SHA1(3818dc94c60cd78c4212ab7a4367cf3d98166ee6) ) /* engine sound */ + + ROM_REGION( 0x6000, "52xx", ROMREGION_ERASEFF ) + /* the bootleg has a TMS5220, NOT the Namco 52xx */ + + /* unknown or unused (P)ROM data */ + ROM_REGION( 0x0100, "user1", 0 ) // not dumped for this board + ROM_LOAD( "bboard-1p.14c", 0x0000, 0x0100, CRC(0e742cb1) SHA1(3ae43270aab4848fdeece1648e7e040ab216b08e) ) /* sync chain */ + /* this is used for the Spanish speech with a TMS5220 */ + ROM_REGION( 0x2000, "soundz80bl", 0 ) + ROM_LOAD( "gr_niemer_aboard-sp1-2764.11", 0x0000, 0x2000, CRC(47226cda) SHA1(03115ead04b11e7ef3ef08d32d4d61a56dc35190) ) +ROM_END /********************************************************************* * Initialization routines @@ -2389,3 +2472,4 @@ GAME( 1983, polepos2a, polepos2, polepos, polepos2, polepos_state, init_pol GAME( 1983, polepos2b, polepos2, polepos, polepos2, polepos_state, empty_init, ROT0, "bootleg", "Pole Position II (bootleg)", 0 ) GAME( 1984, polepos2bi, polepos2, polepos2bi, polepos2bi,polepos_state, empty_init, ROT0, "bootleg", "Gran Premio F1 (Italian bootleg of Pole Position II)", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND ) GAME( 1984, polepos2bs, polepos2, polepos2bi, polepos2bi,polepos_state, empty_init, ROT0, "bootleg (BCN Internacional S.A.)", "Gran Premio F1 (Spanish bootleg of Pole Position II)", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND ) +GAME( 1984, grally, polepos2, polepos2bi, polepos2bi,polepos_state, empty_init, ROT0, "bootleg (Niemer)", "Gran Rally (Spanish bootleg of Pole Position II)", MACHINE_IMPERFECT_COLORS | MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/includes/polepos.h b/src/mame/includes/polepos.h index b7702b19237..5a3b553864e 100644 --- a/src/mame/includes/polepos.h +++ b/src/mame/includes/polepos.h @@ -37,6 +37,20 @@ public: m_screen(*this, "screen"), m_palette(*this, "palette") { } + DECLARE_CUSTOM_INPUT_MEMBER(auto_start_r); + + void init_polepos2(); + + void polepos2bi(machine_config &config); + void topracern(machine_config &config); + void polepos(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: required_device m_maincpu; required_device m_subcpu; required_device m_subcpu2; @@ -44,6 +58,14 @@ public: optional_device m_soundlatch; optional_device m_namco_sound; required_device m_latch; + required_shared_ptr m_sprite16_memory; + required_shared_ptr m_road16_memory; + required_shared_ptr m_alpha16_memory; + required_shared_ptr m_view16_memory; + required_device m_gfxdecode; + required_device m_screen; + required_device m_palette; + uint8_t m_steer_last; uint8_t m_steer_delta; int16_t m_steer_accum; @@ -52,13 +74,6 @@ public: uint8_t m_last_unsigned; int m_adc_input; int m_auto_start_mask; - required_shared_ptr m_sprite16_memory; - required_shared_ptr m_road16_memory; - required_shared_ptr m_alpha16_memory; - required_shared_ptr m_view16_memory; - required_device m_gfxdecode; - required_device m_screen; - required_device m_palette; uint16_t m_vertical_position_modifier[256]; uint16_t m_road16_vscroll; @@ -67,33 +82,27 @@ public: int m_chacl; uint16_t m_scroll; uint8_t m_sub_irq_mask; + DECLARE_READ16_MEMBER(polepos2_ic25_r); - DECLARE_READ8_MEMBER(polepos_adc_r); - DECLARE_READ8_MEMBER(polepos_ready_r); + DECLARE_READ8_MEMBER(adc_r); + DECLARE_READ8_MEMBER(ready_r); DECLARE_WRITE_LINE_MEMBER(iosel_w); DECLARE_WRITE_LINE_MEMBER(gasel_w); DECLARE_WRITE_LINE_MEMBER(sb0_w); DECLARE_WRITE_LINE_MEMBER(chacl_w); - template DECLARE_WRITE16_MEMBER(polepos_z8002_nvi_enable_w); - DECLARE_READ16_MEMBER(polepos_sprite16_r); - DECLARE_WRITE16_MEMBER(polepos_sprite16_w); - DECLARE_READ8_MEMBER(polepos_sprite_r); - DECLARE_WRITE8_MEMBER(polepos_sprite_w); - DECLARE_READ16_MEMBER(polepos_road16_r); - DECLARE_WRITE16_MEMBER(polepos_road16_w); - DECLARE_READ8_MEMBER(polepos_road_r); - DECLARE_WRITE8_MEMBER(polepos_road_w); - DECLARE_WRITE16_MEMBER(polepos_road16_vscroll_w); - DECLARE_READ16_MEMBER(polepos_view16_r); - DECLARE_WRITE16_MEMBER(polepos_view16_w); - DECLARE_READ8_MEMBER(polepos_view_r); - DECLARE_WRITE8_MEMBER(polepos_view_w); - DECLARE_WRITE16_MEMBER(polepos_view16_hscroll_w); - DECLARE_READ16_MEMBER(polepos_alpha16_r); - DECLARE_WRITE16_MEMBER(polepos_alpha16_w); - DECLARE_READ8_MEMBER(polepos_alpha_r); - DECLARE_WRITE8_MEMBER(polepos_alpha_w); - DECLARE_CUSTOM_INPUT_MEMBER(auto_start_r); + template DECLARE_WRITE16_MEMBER(z8002_nvi_enable_w); + DECLARE_READ8_MEMBER(sprite_r); + DECLARE_WRITE8_MEMBER(sprite_w); + DECLARE_READ8_MEMBER(road_r); + DECLARE_WRITE8_MEMBER(road_w); + DECLARE_WRITE16_MEMBER(road16_vscroll_w); + DECLARE_WRITE16_MEMBER(view16_w); + DECLARE_READ8_MEMBER(view_r); + DECLARE_WRITE8_MEMBER(view_w); + DECLARE_WRITE16_MEMBER(view16_hscroll_w); + DECLARE_WRITE16_MEMBER(alpha16_w); + DECLARE_READ8_MEMBER(alpha_r); + DECLARE_WRITE8_MEMBER(alpha_w); DECLARE_WRITE8_MEMBER(out_0); DECLARE_WRITE8_MEMBER(out_1); DECLARE_READ8_MEMBER(namco_52xx_rom_r); @@ -102,20 +111,14 @@ public: DECLARE_READ8_MEMBER(steering_changed_r); DECLARE_READ8_MEMBER(steering_delta_r); DECLARE_WRITE8_MEMBER(bootleg_soundlatch_w); - void init_polepos2(); TILE_GET_INFO_MEMBER(bg_get_tile_info); TILE_GET_INFO_MEMBER(tx_get_tile_info); - DECLARE_MACHINE_RESET(polepos); - DECLARE_VIDEO_START(polepos); DECLARE_PALETTE_INIT(polepos); - uint32_t screen_update_polepos(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_DEVICE_CALLBACK_MEMBER(polepos_scanline); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_DEVICE_CALLBACK_MEMBER(scanline); void draw_road(bitmap_ind16 &bitmap); void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ); void zoom_sprite(bitmap_ind16 &bitmap,int big,uint32_t code,uint32_t color,int flipx,int sx,int sy,int sizex,int sizey); - void polepos2bi(machine_config &config); - void topracern(machine_config &config); - void polepos(machine_config &config); void sound_z80_bootleg_iomap(address_map &map); void sound_z80_bootleg_map(address_map &map); void topracern_io(address_map &map); diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ddb5ae412fd..9657fe83ffc 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -32109,6 +32109,7 @@ pokemini // Nintendo Pokemon Mini poker72 // @source:polepos.cpp +grally // bootleg polepos // (c) 1982 polepos2 // (c) 1983 polepos2a // 136014 (c) 1983 + Atari license diff --git a/src/mame/video/polepos.cpp b/src/mame/video/polepos.cpp index 355af8b52dc..6856771ddd8 100644 --- a/src/mame/video/polepos.cpp +++ b/src/mame/video/polepos.cpp @@ -30,7 +30,6 @@ PALETTE_INIT_MEMBER(polepos_state,polepos) { const uint8_t *color_prom = memregion("proms")->base(); - int i, j; /******************************************************* * Color PROMs @@ -51,30 +50,28 @@ PALETTE_INIT_MEMBER(polepos_state,polepos) * below the pixel or not. That would be tricky to emulate, and it's * not needed because of course the two banks are the same. *******************************************************/ - for (i = 0; i < 128; i++) + for (int i = 0; i < 128; i++) { - int bit0,bit1,bit2,bit3,r,g,b; - /* Sheet 15B: 136014-0137 red component */ - bit0 = (color_prom[0x000 + i] >> 0) & 1; - bit1 = (color_prom[0x000 + i] >> 1) & 1; - bit2 = (color_prom[0x000 + i] >> 2) & 1; - bit3 = (color_prom[0x000 + i] >> 3) & 1; - r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + int bit0 = (color_prom[0x000 + i] >> 0) & 1; + int bit1 = (color_prom[0x000 + i] >> 1) & 1; + int bit2 = (color_prom[0x000 + i] >> 2) & 1; + int bit3 = (color_prom[0x000 + i] >> 3) & 1; + int r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; /* Sheet 15B: 136014-0138 green component */ bit0 = (color_prom[0x100 + i] >> 0) & 1; bit1 = (color_prom[0x100 + i] >> 1) & 1; bit2 = (color_prom[0x100 + i] >> 2) & 1; bit3 = (color_prom[0x100 + i] >> 3) & 1; - g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + int g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; /* Sheet 15B: 136014-0139 blue component */ bit0 = (color_prom[0x200 + i] >> 0) & 1; bit1 = (color_prom[0x200 + i] >> 1) & 1; bit2 = (color_prom[0x200 + i] >> 2) & 1; bit3 = (color_prom[0x200 + i] >> 3) & 1; - b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; + int b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3; palette.set_indirect_color(i,rgb_t(r,g,b)); } @@ -84,7 +81,7 @@ PALETTE_INIT_MEMBER(polepos_state,polepos) * Sheet 15B: top left, 136014-140 * Inputs: SHFT0, SHFT1 and CHA8* ... CHA13* *******************************************************/ - for (i = 0; i < 64*4; i++) + for (int i = 0; i < 64*4; i++) { int color = color_prom[0x300 + i]; palette.set_pen_indirect(0x0000 + i, (color != 15) ? (0x020 + color) : 0x2f); @@ -97,7 +94,7 @@ PALETTE_INIT_MEMBER(polepos_state,polepos) * Inputs: SHFT2, SHFT3 and CHA8 ... CHA13 * The background is only in the top half of the screen *******************************************************/ - for (i = 0; i < 64*4; i++) + for (int i = 0; i < 64*4; i++) { int color = color_prom[0x400 + i]; palette.set_pen_indirect(0x0200 + i, 0x000 + color); @@ -108,7 +105,7 @@ PALETTE_INIT_MEMBER(polepos_state,polepos) * Sheet 14B: right, 136014-146 * Inputs: CUSTOM0 ... CUSTOM3 and DATA0 ... DATA5 *******************************************************/ - for (i = 0; i < 64*16; i++) + for (int i = 0; i < 64*16; i++) { int color = color_prom[0xc00 + i]; palette.set_pen_indirect(0x0300 + i, (color != 15) ? (0x010 + color) : 0x1f); @@ -121,16 +118,16 @@ PALETTE_INIT_MEMBER(polepos_state,polepos) * Inputs: R1 ... R6 and CHA0 ... CHA3 * The road is only in the bottom half of the screen *******************************************************/ - for (i = 0; i < 64*16; i++) + for (int i = 0; i < 64*16; i++) { int color = color_prom[0x800 + i]; palette.set_pen_indirect(0x0b00 + i, 0x040 + color); } /* 136014-142, 136014-143, 136014-144 Vertical position modifiers */ - for (i = 0; i < 256; i++) + for (int i = 0; i < 256; i++) { - j = color_prom[0x500 + i] + (color_prom[0x600 + i] << 4) + (color_prom[0x700 + i] << 8); + int j = color_prom[0x500 + i] + (color_prom[0x600 + i] << 4) + (color_prom[0x700 + i] << 8); m_vertical_position_modifier[i] = j; } } @@ -187,12 +184,17 @@ TILE_GET_INFO_MEMBER(polepos_state::tx_get_tile_info) ***************************************************************************/ -VIDEO_START_MEMBER(polepos_state,polepos) +void polepos_state::video_start() { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(polepos_state::bg_get_tile_info),this),TILEMAP_SCAN_COLS,8,8,64,16); m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(polepos_state::tx_get_tile_info),this),TILEMAP_SCAN_ROWS,8,8,32,32); m_tx_tilemap->configure_groups(*m_gfxdecode->gfx(0), 0x2f); + + save_item(NAME(m_road16_vscroll)); + save_item(NAME(m_chacl)); + save_item(NAME(m_scroll)); + save_item(NAME(m_sub_irq_mask)); } @@ -202,22 +204,12 @@ VIDEO_START_MEMBER(polepos_state,polepos) ***************************************************************************/ -READ16_MEMBER(polepos_state::polepos_sprite16_r) -{ - return m_sprite16_memory[offset]; -} - -WRITE16_MEMBER(polepos_state::polepos_sprite16_w) -{ - COMBINE_DATA(&m_sprite16_memory[offset]); -} - -READ8_MEMBER(polepos_state::polepos_sprite_r) +READ8_MEMBER(polepos_state::sprite_r) { return m_sprite16_memory[offset] & 0xff; } -WRITE8_MEMBER(polepos_state::polepos_sprite_w) +WRITE8_MEMBER(polepos_state::sprite_w) { m_sprite16_memory[offset] = (m_sprite16_memory[offset] & 0xff00) | data; } @@ -229,27 +221,17 @@ WRITE8_MEMBER(polepos_state::polepos_sprite_w) ***************************************************************************/ -READ16_MEMBER(polepos_state::polepos_road16_r) -{ - return m_road16_memory[offset]; -} - -WRITE16_MEMBER(polepos_state::polepos_road16_w) -{ - COMBINE_DATA(&m_road16_memory[offset]); -} - -READ8_MEMBER(polepos_state::polepos_road_r) +READ8_MEMBER(polepos_state::road_r) { return m_road16_memory[offset] & 0xff; } -WRITE8_MEMBER(polepos_state::polepos_road_w) +WRITE8_MEMBER(polepos_state::road_w) { m_road16_memory[offset] = (m_road16_memory[offset] & 0xff00) | data; } -WRITE16_MEMBER(polepos_state::polepos_road16_vscroll_w) +WRITE16_MEMBER(polepos_state::road16_vscroll_w) { COMBINE_DATA(&m_road16_vscroll); } @@ -261,31 +243,26 @@ WRITE16_MEMBER(polepos_state::polepos_road16_vscroll_w) ***************************************************************************/ -READ16_MEMBER(polepos_state::polepos_view16_r) -{ - return m_view16_memory[offset]; -} - -WRITE16_MEMBER(polepos_state::polepos_view16_w) +WRITE16_MEMBER(polepos_state::view16_w) { COMBINE_DATA(&m_view16_memory[offset]); if (offset < 0x400) m_bg_tilemap->mark_tile_dirty(offset); } -READ8_MEMBER(polepos_state::polepos_view_r) +READ8_MEMBER(polepos_state::view_r) { return m_view16_memory[offset] & 0xff; } -WRITE8_MEMBER(polepos_state::polepos_view_w) +WRITE8_MEMBER(polepos_state::view_w) { m_view16_memory[offset] = (m_view16_memory[offset] & 0xff00) | data; if (offset < 0x400) m_bg_tilemap->mark_tile_dirty(offset); } -WRITE16_MEMBER(polepos_state::polepos_view16_hscroll_w) +WRITE16_MEMBER(polepos_state::view16_hscroll_w) { COMBINE_DATA(&m_scroll); m_bg_tilemap->set_scrollx(0,m_scroll); @@ -304,23 +281,18 @@ WRITE_LINE_MEMBER(polepos_state::chacl_w) ***************************************************************************/ -READ16_MEMBER(polepos_state::polepos_alpha16_r) -{ - return m_alpha16_memory[offset]; -} - -WRITE16_MEMBER(polepos_state::polepos_alpha16_w) +WRITE16_MEMBER(polepos_state::alpha16_w) { COMBINE_DATA(&m_alpha16_memory[offset]); m_tx_tilemap->mark_tile_dirty(offset); } -READ8_MEMBER(polepos_state::polepos_alpha_r) +READ8_MEMBER(polepos_state::alpha_r) { return m_alpha16_memory[offset] & 0xff; } -WRITE8_MEMBER(polepos_state::polepos_alpha_w) +WRITE8_MEMBER(polepos_state::alpha_w) { m_alpha16_memory[offset] = (m_alpha16_memory[offset] & 0xff00) | data; m_tx_tilemap->mark_tile_dirty(offset); @@ -339,10 +311,9 @@ void polepos_state::draw_road(bitmap_ind16 &bitmap) const uint8_t *road_control = memregion("gfx5")->base(); const uint8_t *road_bits1 = road_control + 0x2000; const uint8_t *road_bits2 = road_control + 0x4000; - int x, y, i; /* loop over the lower half of the screen */ - for (y = 128; y < 256; y++) + for (int y = 128; y < 256; y++) { int xoffs, yoffs, xscroll, roadpal; uint16_t scanline[256 + 8]; @@ -367,14 +338,14 @@ void polepos_state::draw_road(bitmap_ind16 &bitmap) xoffs &= ~7; /* loop over 8-pixel chunks */ - for (x = 0; x < 256 / 8 + 1; x++, xoffs += 8) + for (int x = 0; x < 256 / 8 + 1; x++, xoffs += 8) { /* if the 0x200 bit of the xoffset is set, a special pin on the custom */ /* chip is set and the /CE and /OE for the road chips is disabled */ if (xoffs & 0x200) { /* in this case, it looks like we just fill with 0 */ - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) *dest++ = pen_base | 0; } @@ -394,7 +365,7 @@ void polepos_state::draw_road(bitmap_ind16 &bitmap) int carin = control >> 7; /* draw this 8-pixel chunk */ - for (i = 8; i > 0; i--) + for (int i = 8; i > 0; i--) { int bits = BIT(bits1,i) + (BIT(bits2,i) << 1); if (!carin && bits) bits++; @@ -418,11 +389,10 @@ void polepos_state::zoom_sprite(bitmap_ind16 &bitmap,int big, uint8_t *scaling_rom = memregion("gfx6")->base(); uint32_t transmask = m_palette->transpen_mask(*gfx, color, 0x1f); int coloroffs = gfx->colorbase() + color * gfx->granularity(); - int x,y; if (flipx) flipx = big ? 0x1f : 0x0f; - for (y = 0;y <= sizey;y++) + for (int y = 0;y <= sizey;y++) { int yy = (sy + y) & 0x1ff; @@ -438,7 +408,7 @@ void polepos_state::zoom_sprite(bitmap_ind16 &bitmap,int big, if (!big) dy >>= 1; src = gfxdata + dy * gfx->rowbytes(); - for (x = (big ? 0x40 : 0x20);x > 0;x--) + for (int x = (big ? 0x40 : 0x20);x > 0;x--) { if (xx < 0x100) { @@ -464,9 +434,8 @@ void polepos_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect { uint16_t *posmem = &m_sprite16_memory[0x380]; uint16_t *sizmem = &m_sprite16_memory[0x780]; - int i; - for (i = 0; i < 64; i++, posmem += 2, sizmem += 2) + for (int i = 0; i < 64; i++, posmem += 2, sizmem += 2) { int sx = (posmem[1] & 0x3ff) - 0x40 + 4; int sy = 512 - (posmem[0] & 0x1ff) + 1; // sprites are buffered and delayed by one scanline @@ -489,7 +458,7 @@ void polepos_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect } -uint32_t polepos_state::screen_update_polepos(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t polepos_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { rectangle clip = cliprect; clip.max_y = 127; -- cgit v1.2.3 From 0cc9810bc4980ad5bcd047e30c5d416de5ac653b Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 12 Jun 2018 12:22:55 -0400 Subject: polepos.cpp: Pedantic Latin abbreviation usage (nw) --- src/mame/drivers/polepos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mame/drivers/polepos.cpp b/src/mame/drivers/polepos.cpp index 144d30f39b7..f333ec4c735 100644 --- a/src/mame/drivers/polepos.cpp +++ b/src/mame/drivers/polepos.cpp @@ -212,7 +212,7 @@ Notes: Todo: -- the bootlegs without Namco devices (i.e. topracern, polepos2bi) still require +- the bootlegs without Namco devices (e.g. topracern, polepos2bi) still require our 06xx and 51xx emulation to boot, this is incorrect. ***************************************************************************/ -- cgit v1.2.3 From 43d4b6ba361eef21f6cff1b583cd7c550a70c6e7 Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 12 Jun 2018 12:32:39 -0400 Subject: ad1848, cem3394: More descriptive device names (nw) --- src/devices/sound/ad1848.cpp | 2 +- src/devices/sound/cem3394.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devices/sound/ad1848.cpp b/src/devices/sound/ad1848.cpp index 66e6e958acb..27c4d87ce70 100644 --- a/src/devices/sound/ad1848.cpp +++ b/src/devices/sound/ad1848.cpp @@ -11,7 +11,7 @@ #include "speaker.h" -DEFINE_DEVICE_TYPE(AD1848, ad1848_device, "ad1848", "Analog Device AD1848") +DEFINE_DEVICE_TYPE(AD1848, ad1848_device, "ad1848", "AD1848 16-bit SoundPort Stereo Codec") ad1848_device::ad1848_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, AD1848, tag, owner, clock), diff --git a/src/devices/sound/cem3394.cpp b/src/devices/sound/cem3394.cpp index 08734c31023..22894cfcbfd 100644 --- a/src/devices/sound/cem3394.cpp +++ b/src/devices/sound/cem3394.cpp @@ -2,7 +2,7 @@ // copyright-holders:Aaron Giles /*************************************************************************** - CEM3394 sound driver. + Curtis Electromusic Specialties CEM3394 µP-Controllable Synthesizer Voice This driver handles CEM-3394 analog synth chip. Very crudely. @@ -105,7 +105,7 @@ // device type definition -DEFINE_DEVICE_TYPE(CEM3394, cem3394_device, "cem3394", "CEM3394") +DEFINE_DEVICE_TYPE(CEM3394, cem3394_device, "cem3394", "CEM3394 Synthesizer Voice") //************************************************************************** // LIVE DEVICE -- cgit v1.2.3 From e1cd7964656d1bfc8996c2129757b4e155c5eee5 Mon Sep 17 00:00:00 2001 From: Ivan Vangelista Date: Tue, 12 Jun 2018 19:22:30 +0200 Subject: Dumped bios for ALG 3DO based arcade games [Mr Invader] --- src/mame/drivers/3do.cpp | 63 +++++----- src/mame/includes/3do.h | 308 ++++++++++++++++++++++++----------------------- src/mame/machine/3do.cpp | 50 ++++---- src/mame/mame.lst | 1 + 4 files changed, 217 insertions(+), 205 deletions(-) diff --git a/src/mame/drivers/3do.cpp b/src/mame/drivers/3do.cpp index 88fbe234c6c..69f1214b526 100644 --- a/src/mame/drivers/3do.cpp +++ b/src/mame/drivers/3do.cpp @@ -2,7 +2,7 @@ // copyright-holders:Angelo Salese, Wilbert Pol /*************************************************************************** - 3do.c + 3do.cpp Driver file to handle emulation of the 3DO systems @@ -99,7 +99,6 @@ Part list of Goldstar 3DO Interactive Multiplayer #include "cpu/arm/arm.h" #include "cpu/arm7/arm7.h" #include "imagedev/chd_cd.h" -#include "screen.h" #define X2_CLOCK_PAL 59000000 @@ -107,17 +106,17 @@ Part list of Goldstar 3DO Interactive Multiplayer #define X601_CLOCK XTAL(16'934'400) -void _3do_state::_3do_mem(address_map &map) +void _3do_state::main_mem(address_map &map) { - map(0x00000000, 0x001FFFFF).bankrw("bank1").share("dram"); /* DRAM */ - map(0x00200000, 0x003FFFFF).ram().share("vram"); /* VRAM */ - map(0x03000000, 0x030FFFFF).bankr("bank2"); /* BIOS */ + map(0x00000000, 0x001FFFFF).bankrw(m_bank1).share(m_dram); /* DRAM */ + map(0x00200000, 0x003FFFFF).ram().share(m_vram); /* VRAM */ + map(0x03000000, 0x030FFFFF).bankr(m_bank2); /* BIOS */ map(0x03100000, 0x0313FFFF).ram(); /* Brooktree? */ - map(0x03140000, 0x0315FFFF).rw(FUNC(_3do_state::_3do_nvarea_r), FUNC(_3do_state::_3do_nvarea_w)).umask32(0x000000ff); /* NVRAM */ - map(0x03180000, 0x031BFFFF).rw(FUNC(_3do_state::_3do_slow2_r), FUNC(_3do_state::_3do_slow2_w)); /* Slow bus - additional expansion */ - map(0x03200000, 0x0320FFFF).rw(FUNC(_3do_state::_3do_svf_r), FUNC(_3do_state::_3do_svf_w)); /* special vram access1 */ - map(0x03300000, 0x033FFFFF).rw(FUNC(_3do_state::_3do_madam_r), FUNC(_3do_state::_3do_madam_w)); /* address decoder */ - map(0x03400000, 0x034FFFFF).rw(FUNC(_3do_state::_3do_clio_r), FUNC(_3do_state::_3do_clio_w)); /* io controller */ + map(0x03140000, 0x0315FFFF).rw(FUNC(_3do_state::nvarea_r), FUNC(_3do_state::nvarea_w)).umask32(0x000000ff); /* NVRAM */ + map(0x03180000, 0x031BFFFF).rw(FUNC(_3do_state::slow2_r), FUNC(_3do_state::slow2_w)); /* Slow bus - additional expansion */ + map(0x03200000, 0x0320FFFF).rw(FUNC(_3do_state::svf_r), FUNC(_3do_state::svf_w)); /* special vram access1 */ + map(0x03300000, 0x033FFFFF).rw(FUNC(_3do_state::madam_r), FUNC(_3do_state::madam_w)); /* address decoder */ + map(0x03400000, 0x034FFFFF).rw(FUNC(_3do_state::clio_r), FUNC(_3do_state::clio_w)); /* io controller */ } @@ -142,9 +141,9 @@ void _3do_state::machine_start() m_bank1->configure_entry(0, m_dram); m_bank1->configure_entry(1, memregion("user1")->base()); - m_3do_slow2_init(); - m_3do_madam_init(); - m_3do_clio_init( downcast(machine().device("screen"))); + m_slow2_init(); + m_madam_init(); + m_clio_init(); } void _3do_state::machine_reset() @@ -158,16 +157,16 @@ void _3do_state::machine_reset() MACHINE_CONFIG_START(_3do_state::_3do) /* Basic machine hardware */ - MCFG_DEVICE_ADD( "maincpu", ARM7_BE, XTAL(50'000'000)/4 ) - MCFG_DEVICE_PROGRAM_MAP( _3do_mem) + MCFG_DEVICE_ADD( m_maincpu, ARM7_BE, XTAL(50'000'000)/4 ) + MCFG_DEVICE_PROGRAM_MAP( main_mem) - MCFG_NVRAM_ADD_1FILL("nvram") + MCFG_NVRAM_ADD_1FILL(m_nvram) MCFG_TIMER_DRIVER_ADD_PERIODIC("timer_x16", _3do_state, timer_x16_cb, attotime::from_hz(12000)) // TODO: timing - MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_ADD(m_screen, RASTER) MCFG_SCREEN_RAW_PARAMS( X2_CLOCK_NTSC / 2, 1592, 254, 1534, 263, 22, 262 ) - MCFG_SCREEN_UPDATE_DRIVER(_3do_state, screen_update__3do) + MCFG_SCREEN_UPDATE_DRIVER(_3do_state, screen_update) MCFG_CDROM_ADD("cdrom") MACHINE_CONFIG_END @@ -176,16 +175,16 @@ MACHINE_CONFIG_END MACHINE_CONFIG_START(_3do_state::_3do_pal) /* Basic machine hardware */ - MCFG_DEVICE_ADD("maincpu", ARM7_BE, XTAL(50'000'000)/4 ) - MCFG_DEVICE_PROGRAM_MAP( _3do_mem) + MCFG_DEVICE_ADD(m_maincpu, ARM7_BE, XTAL(50'000'000)/4 ) + MCFG_DEVICE_PROGRAM_MAP( main_mem) - MCFG_NVRAM_ADD_1FILL("nvram") + MCFG_NVRAM_ADD_1FILL(m_nvram) MCFG_TIMER_DRIVER_ADD_PERIODIC("timer_x16", _3do_state, timer_x16_cb, attotime::from_hz(12000)) // TODO: timing - MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_ADD(m_screen, RASTER) MCFG_SCREEN_RAW_PARAMS( X2_CLOCK_PAL / 2, 1592, 254, 1534, 263, 22, 262 ) // TODO: proper params - MCFG_SCREEN_UPDATE_DRIVER(_3do_state, screen_update__3do) + MCFG_SCREEN_UPDATE_DRIVER(_3do_state, screen_update) MCFG_CDROM_ADD("cdrom") MACHINE_CONFIG_END @@ -241,6 +240,14 @@ ROM_START(orbatak) DISK_IMAGE_READONLY( "orbatak", 0, SHA1(25cb3b889cf09dbe5faf2b0ca4aae5e03453da00) ) ROM_END +ROM_START(md23do) + ROM_REGION32_BE( 0x200000, "user1", 0 ) + ROM_LOAD( "soat_rom2.bin", 0x000000, 0x80000, CRC(b832da9a) SHA1(520d3d1b5897800af47f92efd2444a26b7a7dead) ) // TC544000AF-150, 1xxxxxxxxxxxxxxxxxx = 0xFF + + DISK_REGION( "cdrom" ) + DISK_IMAGE_READONLY( "md23do", 0, NO_DUMP ) +ROM_END + /*************************************************************************** Game driver(s) @@ -251,6 +258,8 @@ ROM_END CONS( 1991, 3do, 0, 0, _3do, 3do, _3do_state, empty_init, "The 3DO Company", "3DO (NTSC)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) CONS( 1991, 3do_pal, 3do, 0, _3do_pal, 3do, _3do_state, empty_init, "The 3DO Company", "3DO (PAL)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -/* YEAR NAME PARENT MACHINE INPUT STATE INIT MONITOR COMPANY FULLNAME FLAGS */ -GAME( 1991, 3dobios, 0, _3do, 3do, _3do_state, empty_init, ROT0, "The 3DO Company", "3DO Bios", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IS_BIOS_ROOT ) -GAME( 199?, orbatak, 3dobios, _3do, 3do, _3do_state, empty_init, ROT0, "", "Orbatak (prototype)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +/* YEAR NAME PARENT MACHINE INPUT STATE INIT MONITOR COMPANY FULLNAME FLAGS */ +GAME( 1991, 3dobios, 0, _3do, 3do, _3do_state, empty_init, ROT0, "The 3DO Company", "3DO Bios", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IS_BIOS_ROOT ) +GAME( 199?, orbatak, 3dobios, _3do, 3do, _3do_state, empty_init, ROT0, "", "Orbatak (prototype)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +GAME( 199?, md23do, 0, _3do, 3do, _3do_state, empty_init, ROT0, "American Laser Games", "Mad Dog II: The Lost Gold (3DO hardware)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) + diff --git a/src/mame/includes/3do.h b/src/mame/includes/3do.h index 73e0901665c..90fbf3ccd05 100644 --- a/src/mame/includes/3do.h +++ b/src/mame/includes/3do.h @@ -11,132 +11,9 @@ #include "machine/nvram.h" #include "machine/timer.h" +#include "screen.h" -struct SLOW2 { - /* 03180000 - 0318003f - configuration group */ - /* 03180040 - 0318007f - diagnostic UART */ - - uint8_t cg_r_count; - uint8_t cg_w_count; - uint32_t cg_input; - uint32_t cg_output; -}; - - -struct MADAM { - uint32_t revision; /* 03300000 */ - uint32_t msysbits; /* 03300004 */ - uint32_t mctl; /* 03300008 */ - uint32_t sltime; /* 0330000c */ - uint32_t abortbits; /* 03300020 */ - uint32_t privbits; /* 03300024 */ - uint32_t statbits; /* 03300028 */ - uint32_t diag; /* 03300040 */ - - uint32_t ccobctl0; /* 03300110 */ - uint32_t ppmpc; /* 03300120 */ - - uint32_t regctl0; /* 03300130 */ - uint32_t regctl1; /* 03300134 */ - uint32_t regctl2; /* 03300138 */ - uint32_t regctl3; /* 0330013c */ - uint32_t xyposh; /* 03300140 */ - uint32_t xyposl; /* 03300144 */ - uint32_t linedxyh; /* 03300148 */ - uint32_t linedxyl; /* 0330014c */ - uint32_t dxyh; /* 03300150 */ - uint32_t dxyl; /* 03300154 */ - uint32_t ddxyh; /* 03300158 */ - uint32_t ddxyl; /* 0330015c */ - - uint32_t pip[16]; /* 03300180-033001bc (W); 03300180-033001fc (R) */ - uint32_t fence[16]; /* 03300200-0330023c (W); 03300200-0330027c (R) */ - uint32_t mmu[64]; /* 03300300-033003fc */ - uint32_t dma[32][4]; /* 03300400-033005fc */ - uint32_t mult[40]; /* 03300600-0330069c */ - uint32_t mult_control; /* 033007f0-033007f4 */ - uint32_t mult_status; /* 033007f8 */ -}; - - -struct CLIO { - screen_device *screen; - - uint32_t revision; /* 03400000 */ - uint32_t csysbits; /* 03400004 */ - uint32_t vint0; /* 03400008 */ - uint32_t vint1; /* 0340000c */ - uint32_t audin; /* 03400020 */ - uint32_t audout; /* 03400024 */ - uint32_t cstatbits; /* 03400028 */ - uint32_t wdog; /* 0340002c */ - uint32_t hcnt; /* 03400030 */ - uint32_t vcnt; /* 03400034 */ - uint32_t seed; /* 03400038 */ - uint32_t random; /* 0340004c */ - uint32_t irq0; /* 03400040 / 03400044 */ - uint32_t irq0_enable; /* 03400048 / 0340004c */ - uint32_t mode; /* 03400050 / 03400054 */ - uint32_t badbits; /* 03400058 */ - uint32_t spare; /* 0340005c */ - uint32_t irq1; /* 03400060 / 03400064 */ - uint32_t irq1_enable; /* 03400068 / 0340006c */ - uint32_t hdelay; /* 03400080 */ - uint32_t adbio; /* 03400084 */ - uint32_t adbctl; /* 03400088 */ - /* Timers */ - uint32_t timer_count[16];/* 034001** & 8 */ - uint32_t timer_backup[16]; /* 034001**+4 & 8 */ - uint64_t timer_ctrl; /* 03400200 */ - uint32_t slack; /* 03400220 */ - /* DMA */ - uint32_t dmareqdis; /* 03400308 */ - /* Expansion bus */ - uint32_t expctl; /* 03400400/03400404 */ - uint32_t type0_4; /* 03400408 */ - uint32_t dipir1; /* 03400410 */ - uint32_t dipir2; /* 03400414 */ - /* Bus signals */ - uint32_t sel; /* 03400500 - 0340053f */ - uint32_t poll; /* 03400540 - 0340057f */ - uint32_t cmdstat; /* 03400580 - 034005bf */ - uint32_t data; /* 034005c0 - 034005ff */ - /* DSPP */ - uint32_t semaphore; /* 034017d0 */ - uint32_t semaack; /* 034017d4 */ - uint32_t dsppdma; /* 034017e0 */ - uint32_t dspprst0; /* 034017e4 */ - uint32_t dspprst1; /* 034017e8 */ - uint32_t dspppc; /* 034017f4 */ - uint32_t dsppnr; /* 034017f8 */ - uint32_t dsppgw; /* 034017fc */ - uint32_t dsppn[0x400]; /* 03401800 - 03401bff DSPP N stack (32bit writes) */ - /* 03402000 - 034027ff DSPP N stack (16bit writes) */ - uint32_t dsppei[0x100]; /* 03403000 - 034030ff DSPP EI stack (32bit writes) */ - /* 03403400 - 034035ff DSPP EI stack (16bit writes) */ - uint32_t dsppeo[0x1f]; /* 03403800 - 0340381f DSPP EO stack (32bit reads) */ - /* 03403c00 - 03403c3f DSPP EO stack (32bit reads) */ - uint32_t dsppclkreload; /* 034039dc / 03403fbc */ - /* UNCLE */ - uint32_t unclerev; /* 0340c000 */ - uint32_t uncle_soft_rev; /* 0340c004 */ - uint32_t uncle_addr; /* 0340c008 */ - uint32_t uncle_rom; /* 0340c00c */ -}; - - -struct SVF { - uint32_t sport[512]; - uint32_t color; -}; - -struct DSPP { - std::unique_ptr N; - std::unique_ptr EI; - std::unique_ptr EO; -}; - class _3do_state : public driver_device { public: @@ -146,13 +23,151 @@ public: m_dram(*this, "dram"), m_vram(*this, "vram"), m_nvram(*this, "nvram"), + m_screen(*this, "screen"), m_bank1(*this, "bank1"), m_bank2(*this, "bank2") { } + void _3do(machine_config &config); + void _3do_pal(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: + struct SLOW2 { + /* 03180000 - 0318003f - configuration group */ + /* 03180040 - 0318007f - diagnostic UART */ + + uint8_t cg_r_count; + uint8_t cg_w_count; + uint32_t cg_input; + uint32_t cg_output; + }; + + + struct MADAM { + uint32_t revision; /* 03300000 */ + uint32_t msysbits; /* 03300004 */ + uint32_t mctl; /* 03300008 */ + uint32_t sltime; /* 0330000c */ + uint32_t abortbits; /* 03300020 */ + uint32_t privbits; /* 03300024 */ + uint32_t statbits; /* 03300028 */ + uint32_t diag; /* 03300040 */ + + uint32_t ccobctl0; /* 03300110 */ + uint32_t ppmpc; /* 03300120 */ + + uint32_t regctl0; /* 03300130 */ + uint32_t regctl1; /* 03300134 */ + uint32_t regctl2; /* 03300138 */ + uint32_t regctl3; /* 0330013c */ + uint32_t xyposh; /* 03300140 */ + uint32_t xyposl; /* 03300144 */ + uint32_t linedxyh; /* 03300148 */ + uint32_t linedxyl; /* 0330014c */ + uint32_t dxyh; /* 03300150 */ + uint32_t dxyl; /* 03300154 */ + uint32_t ddxyh; /* 03300158 */ + uint32_t ddxyl; /* 0330015c */ + + uint32_t pip[16]; /* 03300180-033001bc (W); 03300180-033001fc (R) */ + uint32_t fence[16]; /* 03300200-0330023c (W); 03300200-0330027c (R) */ + uint32_t mmu[64]; /* 03300300-033003fc */ + uint32_t dma[32][4]; /* 03300400-033005fc */ + uint32_t mult[40]; /* 03300600-0330069c */ + uint32_t mult_control; /* 033007f0-033007f4 */ + uint32_t mult_status; /* 033007f8 */ + }; + + + struct CLIO { + screen_device *screen; + + uint32_t revision; /* 03400000 */ + uint32_t csysbits; /* 03400004 */ + uint32_t vint0; /* 03400008 */ + uint32_t vint1; /* 0340000c */ + uint32_t audin; /* 03400020 */ + uint32_t audout; /* 03400024 */ + uint32_t cstatbits; /* 03400028 */ + uint32_t wdog; /* 0340002c */ + uint32_t hcnt; /* 03400030 */ + uint32_t vcnt; /* 03400034 */ + uint32_t seed; /* 03400038 */ + uint32_t random; /* 0340004c */ + uint32_t irq0; /* 03400040 / 03400044 */ + uint32_t irq0_enable; /* 03400048 / 0340004c */ + uint32_t mode; /* 03400050 / 03400054 */ + uint32_t badbits; /* 03400058 */ + uint32_t spare; /* 0340005c */ + uint32_t irq1; /* 03400060 / 03400064 */ + uint32_t irq1_enable; /* 03400068 / 0340006c */ + uint32_t hdelay; /* 03400080 */ + uint32_t adbio; /* 03400084 */ + uint32_t adbctl; /* 03400088 */ + /* Timers */ + uint32_t timer_count[16];/* 034001** & 8 */ + uint32_t timer_backup[16]; /* 034001**+4 & 8 */ + uint64_t timer_ctrl; /* 03400200 */ + uint32_t slack; /* 03400220 */ + /* DMA */ + uint32_t dmareqdis; /* 03400308 */ + /* Expansion bus */ + uint32_t expctl; /* 03400400/03400404 */ + uint32_t type0_4; /* 03400408 */ + uint32_t dipir1; /* 03400410 */ + uint32_t dipir2; /* 03400414 */ + /* Bus signals */ + uint32_t sel; /* 03400500 - 0340053f */ + uint32_t poll; /* 03400540 - 0340057f */ + uint32_t cmdstat; /* 03400580 - 034005bf */ + uint32_t data; /* 034005c0 - 034005ff */ + /* DSPP */ + uint32_t semaphore; /* 034017d0 */ + uint32_t semaack; /* 034017d4 */ + uint32_t dsppdma; /* 034017e0 */ + uint32_t dspprst0; /* 034017e4 */ + uint32_t dspprst1; /* 034017e8 */ + uint32_t dspppc; /* 034017f4 */ + uint32_t dsppnr; /* 034017f8 */ + uint32_t dsppgw; /* 034017fc */ + uint32_t dsppn[0x400]; /* 03401800 - 03401bff DSPP N stack (32bit writes) */ + /* 03402000 - 034027ff DSPP N stack (16bit writes) */ + uint32_t dsppei[0x100]; /* 03403000 - 034030ff DSPP EI stack (32bit writes) */ + /* 03403400 - 034035ff DSPP EI stack (16bit writes) */ + uint32_t dsppeo[0x1f]; /* 03403800 - 0340381f DSPP EO stack (32bit reads) */ + /* 03403c00 - 03403c3f DSPP EO stack (32bit reads) */ + uint32_t dsppclkreload; /* 034039dc / 03403fbc */ + /* UNCLE */ + uint32_t unclerev; /* 0340c000 */ + uint32_t uncle_soft_rev; /* 0340c004 */ + uint32_t uncle_addr; /* 0340c008 */ + uint32_t uncle_rom; /* 0340c00c */ + }; + + + struct SVF { + uint32_t sport[512]; + uint32_t color; + }; + + struct DSPP { + std::unique_ptr N; + std::unique_ptr EI; + std::unique_ptr EO; + }; + required_device m_maincpu; required_shared_ptr m_dram; required_shared_ptr m_vram; required_device m_nvram; + required_device m_screen; + required_memory_bank m_bank1; + required_memory_bank m_bank2; + SLOW2 m_slow2; MADAM m_madam; CLIO m_clio; @@ -161,41 +176,28 @@ public: uint8_t m_nvmem[0x8000]; // uint8_t m_video_bits[512]; - DECLARE_READ8_MEMBER(_3do_nvarea_r); - DECLARE_WRITE8_MEMBER(_3do_nvarea_w); - DECLARE_READ32_MEMBER(_3do_slow2_r); - DECLARE_WRITE32_MEMBER(_3do_slow2_w); - DECLARE_READ32_MEMBER(_3do_svf_r); - DECLARE_WRITE32_MEMBER(_3do_svf_w); - DECLARE_READ32_MEMBER(_3do_madam_r); - DECLARE_WRITE32_MEMBER(_3do_madam_w); - DECLARE_READ32_MEMBER(_3do_clio_r); - DECLARE_WRITE32_MEMBER(_3do_clio_w); - uint32_t screen_update__3do(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + DECLARE_READ8_MEMBER(nvarea_r); + DECLARE_WRITE8_MEMBER(nvarea_w); + DECLARE_READ32_MEMBER(slow2_r); + DECLARE_WRITE32_MEMBER(slow2_w); + DECLARE_READ32_MEMBER(svf_r); + DECLARE_WRITE32_MEMBER(svf_w); + DECLARE_READ32_MEMBER(madam_r); + DECLARE_WRITE32_MEMBER(madam_w); + DECLARE_READ32_MEMBER(clio_r); + DECLARE_WRITE32_MEMBER(clio_w); + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); TIMER_DEVICE_CALLBACK_MEMBER( timer_x16_cb ); - void _3do(machine_config &config); - void _3do_pal(machine_config &config); - void _3do_mem(address_map &map); + void main_mem(address_map &map); -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; + void m_slow2_init( void ); + void m_madam_init( void ); + void m_clio_init( void ); - required_memory_bank m_bank1; - required_memory_bank m_bank2; - -private: - void m_3do_slow2_init( void ); - void m_3do_madam_init( void ); - void m_3do_clio_init( screen_device *screen ); - - void m_3do_request_fiq(uint32_t irq_req, uint8_t type); + void m_request_fiq(uint32_t irq_req, uint8_t type); }; -/*----------- defined in machine/3do.c -----------*/ - #endif // MAME_INCLUDES_3DO_H diff --git a/src/mame/machine/3do.cpp b/src/mame/machine/3do.cpp index 7d3dfe633f5..42772a69940 100644 --- a/src/mame/machine/3do.cpp +++ b/src/mame/machine/3do.cpp @@ -106,7 +106,7 @@ IRQ1 0x00000001 DMA Player bus */ -void _3do_state::m_3do_request_fiq(uint32_t irq_req, uint8_t type) +void _3do_state::m_request_fiq(uint32_t irq_req, uint8_t type) { if(type) m_clio.irq1 |= irq_req; @@ -153,7 +153,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( _3do_state::timer_x16_cb ) if(m_clio.timer_count[i] == 0xffffffff) // timer hit { if(i & 1) // odd timer irq fires - m_3do_request_fiq(8 << (7-(i >> 1)),0); + m_request_fiq(8 << (7-(i >> 1)),0); carry_val = 1; @@ -170,8 +170,8 @@ TIMER_DEVICE_CALLBACK_MEMBER( _3do_state::timer_x16_cb ) } } -READ8_MEMBER(_3do_state::_3do_nvarea_r) { return m_nvmem[offset]; } -WRITE8_MEMBER(_3do_state::_3do_nvarea_w) { m_nvmem[offset] = data; } +READ8_MEMBER(_3do_state::nvarea_r) { return m_nvmem[offset]; } +WRITE8_MEMBER(_3do_state::nvarea_w) { m_nvmem[offset] = data; } @@ -200,7 +200,7 @@ WRITE8_MEMBER(_3do_state::_3do_nvarea_w) { m_nvmem[offset] = data; } 3022630 */ -READ32_MEMBER(_3do_state::_3do_slow2_r){ +READ32_MEMBER(_3do_state::slow2_r){ uint32_t data = 0; logerror( "%08X: UNK_318 read offset = %08X\n", m_maincpu->pc(), offset ); @@ -215,7 +215,7 @@ READ32_MEMBER(_3do_state::_3do_slow2_r){ } -WRITE32_MEMBER(_3do_state::_3do_slow2_w) +WRITE32_MEMBER(_3do_state::slow2_w) { logerror( "%08X: UNK_318 write offset = %08X, data = %08X, mask = %08X\n", m_maincpu->pc(), offset, data, mem_mask ); @@ -237,7 +237,7 @@ WRITE32_MEMBER(_3do_state::_3do_slow2_w) -READ32_MEMBER(_3do_state::_3do_svf_r) +READ32_MEMBER(_3do_state::svf_r) { uint32_t addr = ( offset & ( 0x07fc / 4 ) ) << 9; uint32_t *p = m_vram + addr; @@ -262,7 +262,7 @@ READ32_MEMBER(_3do_state::_3do_svf_r) return 0; } -WRITE32_MEMBER(_3do_state::_3do_svf_w) +WRITE32_MEMBER(_3do_state::svf_w) { uint32_t addr = ( offset & ( 0x07fc / 4 ) ) << 9; uint32_t *p = m_vram + addr; @@ -302,7 +302,7 @@ WRITE32_MEMBER(_3do_state::_3do_svf_w) -READ32_MEMBER(_3do_state::_3do_madam_r){ +READ32_MEMBER(_3do_state::madam_r){ logerror( "%08X: MADAM read offset = %08X\n", m_maincpu->pc(), offset*4 ); switch( offset ) { @@ -461,7 +461,7 @@ READ32_MEMBER(_3do_state::_3do_madam_r){ } -WRITE32_MEMBER(_3do_state::_3do_madam_w){ +WRITE32_MEMBER(_3do_state::madam_w){ if(offset == 0) { if(data == 0x0a) @@ -655,7 +655,7 @@ WRITE32_MEMBER(_3do_state::_3do_madam_w){ -READ32_MEMBER(_3do_state::_3do_clio_r) +READ32_MEMBER(_3do_state::clio_r) { if (!machine().side_effects_disabled()) { @@ -782,7 +782,7 @@ READ32_MEMBER(_3do_state::_3do_clio_r) return 0; } -WRITE32_MEMBER(_3do_state::_3do_clio_w) +WRITE32_MEMBER(_3do_state::clio_w) { if(offset != 0x200/4 && offset != 0x40/4 && offset != 0x44/4 && offset != 0x48/4 && offset != 0x4c/4 && offset != 0x118/4 && offset != 0x11c/4) @@ -856,22 +856,22 @@ WRITE32_MEMBER(_3do_state::_3do_clio_w) case 0x0040/4: LOG(("%08x PEND0\n",data)); m_clio.irq0 |= data; - m_3do_request_fiq(0,0); + m_request_fiq(0,0); break; case 0x0044/4: //LOG(("%08x PEND0 CLEAR\n",data)); m_clio.irq0 &= ~data; - m_3do_request_fiq(0,0); + m_request_fiq(0,0); break; case 0x0048/4: LOG(("%08x MASK0\n",data)); m_clio.irq0_enable |= data; - m_3do_request_fiq(0,0); + m_request_fiq(0,0); break; case 0x004c/4: LOG(("%08x MASK0 CLEAR\n",data)); m_clio.irq0_enable &= ~data; - m_3do_request_fiq(0,0); + m_request_fiq(0,0); break; case 0x0050/4: m_clio.mode |= data; @@ -888,22 +888,22 @@ WRITE32_MEMBER(_3do_state::_3do_clio_w) case 0x0060/4: LOG(("%08x PEND1\n",data)); m_clio.irq1 |= data; - m_3do_request_fiq(0,1); + m_request_fiq(0,1); break; case 0x0064/4: LOG(("%08x PEND1 CLEAR\n",data)); m_clio.irq1 &= ~data; - m_3do_request_fiq(0,1); + m_request_fiq(0,1); break; case 0x0068/4: LOG(("%08x MASK1\n",data)); m_clio.irq1_enable |= data; - m_3do_request_fiq(0,1); + m_request_fiq(0,1); break; case 0x006c/4: LOG(("%08x MASK1 CLEAR\n",data)); m_clio.irq1_enable &= ~data; - m_3do_request_fiq(0,1); + m_request_fiq(0,1); break; case 0x0080/4: m_clio.hdelay = data; @@ -1040,7 +1040,7 @@ void _3do_state::video_start() } -uint32_t _3do_state::screen_update__3do(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t _3do_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { uint32_t *source_p = m_vram + 0x1c0000 / 4; @@ -1096,23 +1096,23 @@ uint32_t _3do_state::screen_update__3do(screen_device &screen, bitmap_rgb32 &bit * */ -void _3do_state::m_3do_madam_init( void ) +void _3do_state::m_madam_init( void ) { memset( &m_madam, 0, sizeof(MADAM) ); m_madam.revision = 0x01020000; m_madam.msysbits = 0x51; } -void _3do_state::m_3do_slow2_init( void ) +void _3do_state::m_slow2_init( void ) { m_slow2.cg_input = 0; m_slow2.cg_output = 0x00000005 - 1; } -void _3do_state::m_3do_clio_init( screen_device *screen ) +void _3do_state::m_clio_init() { memset( &m_clio, 0, sizeof(CLIO) ); - m_clio.screen = screen; + m_clio.screen = m_screen; m_clio.revision = 0x02022000 /* 0x04000000 */; m_clio.unclerev = 0x03800000; m_clio.expctl = 0x80; /* ARM has the expansion bus */ diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 9657fe83ffc..74da396d5f0 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -70,6 +70,7 @@ flagrall // ? 3do // 3DO consoles 3do_pal // 3dobios // +md23do // orbatak // @source:3x3puzzl.cpp -- cgit v1.2.3 From 87181350318d9d2b7c3a086c5ff59f2e166f5e23 Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 12 Jun 2018 14:15:39 -0400 Subject: rescraid: Regression fix (nw) --- src/mame/drivers/balsente.cpp | 29 ++++++++++++++++++++++++----- src/mame/includes/balsente.h | 5 +++++ src/mame/machine/balsente.cpp | 11 +++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/mame/drivers/balsente.cpp b/src/mame/drivers/balsente.cpp index bb2a511ce09..396eabee072 100644 --- a/src/mame/drivers/balsente.cpp +++ b/src/mame/drivers/balsente.cpp @@ -245,7 +245,7 @@ DIP locations verified for: * *************************************/ -void balsente_state::cpu1_map(address_map &map) +void balsente_state::cpu1_base_map(address_map &map) { map(0x0000, 0x07ff).ram().share("spriteram"); map(0x0800, 0x7fff).ram().w(FUNC(balsente_state::videoram_w)).share("videoram"); @@ -266,12 +266,23 @@ void balsente_state::cpu1_map(address_map &map) map(0x9903, 0x9903).portr("IN1").nopw(); map(0x9a00, 0x9a03).r(FUNC(balsente_state::random_num_r)); map(0x9a04, 0x9a05).rw(FUNC(balsente_state::m6850_r), FUNC(balsente_state::m6850_w)); - map(0x9b00, 0x9bff).rw("nov0", FUNC(x2212_device::read), FUNC(x2212_device::write)); - map(0x9c00, 0x9cff).rw("nov1", FUNC(x2212_device::read), FUNC(x2212_device::write)); map(0xa000, 0xbfff).bankr("bank1"); map(0xc000, 0xffff).bankr("bank2"); } +void balsente_state::cpu1_map(address_map &map) +{ + cpu1_base_map(map); + map(0x9b00, 0x9bff).rw("nov0", FUNC(x2212_device::read), FUNC(x2212_device::write)); + map(0x9c00, 0x9cff).rw("nov1", FUNC(x2212_device::read), FUNC(x2212_device::write)); +} + +void balsente_state::cpu1_smudge_map(address_map &map) +{ + cpu1_base_map(map); + map(0x9b00, 0x9bff).rw(FUNC(balsente_state::novram_8bit_r), FUNC(balsente_state::novram_8bit_w)); +} + /************************************* @@ -1394,6 +1405,14 @@ MACHINE_CONFIG_START(balsente_state::shrike) MACHINE_CONFIG_END +MACHINE_CONFIG_START(balsente_state::rescraid) + balsente(config); + + MCFG_DEVICE_MODIFY("maincpu") + MCFG_DEVICE_PROGRAM_MAP(cpu1_smudge_map) +MACHINE_CONFIG_END + + /************************************* * @@ -2454,9 +2473,9 @@ GAME( 1986, spiker3, spiker, balsente, spiker, balsente_state, init_spiker GAME( 1986, stompin, 0, balsente, stompin, balsente_state, init_stompin, ROT0, "Bally/Sente", "Stompin' (4/4/86)", MACHINE_SUPPORTS_SAVE ) /* Board: A084-91889-A000 (Not a cartridge, but dedicated board) */ -GAME( 1987, rescraid, 0, balsente, rescraid, balsente_state, init_rescraid, ROT0, "Bally Midway", "Rescue Raider (5/11/87) (non-cartridge)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, rescraid, 0, rescraid, rescraid, balsente_state, init_rescraid, ROT0, "Bally Midway", "Rescue Raider (5/11/87) (non-cartridge)", MACHINE_SUPPORTS_SAVE ) /* Board: Unknown */ GAME( 1986, shrike, 0, shrike, shrike, balsente_state, init_shrike, ROT0, "Bally/Sente", "Shrike Avenger (prototype)", MACHINE_SUPPORTS_SAVE ) -GAME( 1987, rescraida, rescraid, balsente, rescraid, balsente_state, init_rescraid, ROT0, "Bally Midway", "Rescue Raider (stand-alone)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, rescraida, rescraid, rescraid, rescraid, balsente_state, init_rescraid, ROT0, "Bally Midway", "Rescue Raider (stand-alone)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, teamht, 0, balsente, teamht, balsente_state, init_teamht, ROT0, "Bally/Sente", "Team Hat Trick", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/balsente.h b/src/mame/includes/balsente.h index 14f8385e972..a467a2357ab 100644 --- a/src/mame/includes/balsente.h +++ b/src/mame/includes/balsente.h @@ -57,6 +57,7 @@ public: { } void shrike(machine_config &config); + void rescraid(machine_config &config); void balsente(machine_config &config); DECLARE_CUSTOM_INPUT_MEMBER(nstocker_bits_r); void init_otwalls(); @@ -97,6 +98,8 @@ private: DECLARE_WRITE_LINE_MEMBER(out5_w); DECLARE_WRITE_LINE_MEMBER(out6_w); DECLARE_WRITE_LINE_MEMBER(nvrecall_w); + DECLARE_READ8_MEMBER(novram_8bit_r); + DECLARE_WRITE8_MEMBER(novram_8bit_w); DECLARE_READ8_MEMBER(m6850_r); DECLARE_WRITE8_MEMBER(m6850_w); DECLARE_READ8_MEMBER(m6850_sound_r); @@ -151,7 +154,9 @@ private: CEM3394_EXT_INPUT(noise_gen_4); CEM3394_EXT_INPUT(noise_gen_5); + void cpu1_base_map(address_map &map); void cpu1_map(address_map &map); + void cpu1_smudge_map(address_map &map); void cpu2_io_map(address_map &map); void cpu2_map(address_map &map); void shrike68k_map(address_map &map); diff --git a/src/mame/machine/balsente.cpp b/src/mame/machine/balsente.cpp index d1d2740071f..2800bf4a941 100644 --- a/src/mame/machine/balsente.cpp +++ b/src/mame/machine/balsente.cpp @@ -316,6 +316,17 @@ WRITE_LINE_MEMBER(balsente_state::nvrecall_w) m_novram[1]->recall(!state); } +READ8_MEMBER(balsente_state::novram_8bit_r) +{ + return (m_novram[0]->read(space, offset) & 0x0f) | (m_novram[1]->read(space, offset) << 4); +} + +WRITE8_MEMBER(balsente_state::novram_8bit_w) +{ + m_novram[0]->write(space, offset, data & 0x0f); + m_novram[1]->write(space, offset, data >> 4); +} + /************************************* -- cgit v1.2.3 From 66b6b3e6f793407a5ebd7ce75bfb05b83684a5b5 Mon Sep 17 00:00:00 2001 From: MetalliC <0vetal0@gmail.com> Date: Tue, 12 Jun 2018 21:35:51 +0300 Subject: docs (nw) --- src/mame/drivers/namcos10.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mame/drivers/namcos10.cpp b/src/mame/drivers/namcos10.cpp index f239e359bd3..7ae7dbed730 100644 --- a/src/mame/drivers/namcos10.cpp +++ b/src/mame/drivers/namcos10.cpp @@ -40,6 +40,7 @@ Point Blank 3 (GNN2 Ver. A) (C) Namco, 2000 *Ren-ai Quiz High School Angel (C) Namco, 2002 Seishun Quiz Colorful High School (CHS1 Ver.A) (C) Namco, 2002 Sekai Kaseki Hakken (Japan, SKH1 Ver.A) (C) Namco, 2004 +Shamisen Brothers (C) Kato/Konami, 2003 Star Trigon (STT1 Ver.A) (C) Namco, 2002 *Taiko No Tatsujin (C) Namco, 2001 Taiko No Tatsujin 2 (TK21 Ver.C) (C) Namco, 2001 -- cgit v1.2.3