diff --git a/docs/source/techspecs/cpu_device.rst b/docs/source/techspecs/cpu_device.rst index 971641fa1d3..a3ca460796e 100644 --- a/docs/source/techspecs/cpu_device.rst +++ b/docs/source/techspecs/cpu_device.rst @@ -30,9 +30,9 @@ TODO. ~~~~~~~~~~~~~~ An interruptible CPU is defined as a core which is able to suspend the -execution of a instruction at any time, exit execute_run, then at the -next call of ``execute_run`` keep going from where it was. This -includes begin able to abort an issued memory access, quit +execution of one instruction at any time, exit execute_run, then at +the next call of ``execute_run`` keep going from where it was. This +includes being able to abort an issued memory access, quit execute_run, then upon the next call of execute_run reissue the exact same access. diff --git a/docs/source/techspecs/memory.rst b/docs/source/techspecs/memory.rst index 783771fbea5..9f0a31758c7 100644 --- a/docs/source/techspecs/memory.rst +++ b/docs/source/techspecs/memory.rst @@ -281,7 +281,7 @@ view can be re-enabled at any time. 3.5 Bus contention handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Some specific CPUs have be upgraded to be interruptible which allows +Some specific CPUs have been upgraded to be interruptible which allows to add bus contention and wait states capabitilites. Being interruptible means, in practice, that an instruction can be interrupted at any time and the execute_run method of the core exited. @@ -328,7 +328,7 @@ cycle will be aborted for lack of remaining time, and the method will eventually be called again. It will then give the time of when the second dma will finish, and all will be well. -It can also allow to reduce said earlier time when circonstances +It can also allow to reduce said earlier time when circumstances require it. For instance a PIO latch that waits up to 64 cycles that data arrives can indicate that current time + 64 as a target (which will trigger a bus error for instance) but if a timer elapses and diff --git a/hash/bkrankp_cart.xml b/hash/bkrankp_cart.xml index 9c83969a014..a9d29a56db3 100644 --- a/hash/bkrankp_cart.xml +++ b/hash/bkrankp_cart.xml @@ -37,6 +37,7 @@ Known carts: J-Pop Blue 2015 Bandai + @@ -46,9 +47,10 @@ Known carts: - Aikatsu Ver. Best + Aikatsu! Idol Katsudō! 2015 Bandai + @@ -61,6 +63,7 @@ Known carts: J-Pop - Strawberry 2015 Bandai + @@ -73,6 +76,7 @@ Known carts: J-Pop - Green 2015 Bandai + @@ -85,6 +89,7 @@ Known carts: J-Pop - Pink 2015 Bandai + @@ -97,6 +102,7 @@ Known carts: Kid's Pop - Lemon Yellow 2015 Bandai + @@ -160,6 +166,7 @@ Known carts: Kid's Pop - Red 2015 Bandai + @@ -184,6 +191,7 @@ Known carts: Kid's Pop - Apple Green 2015 Bandai + @@ -196,6 +204,7 @@ Known carts: J-Pop - Grapefruit 2015 Bandai + @@ -209,6 +218,7 @@ Known carts: 2015 Bandai + @@ -220,6 +230,7 @@ Known carts: J-Pop - Mint 2015 Bandai + @@ -232,6 +243,7 @@ Known carts: Best Hit Song 2015 Bandai + diff --git a/hash/ekara_cart.xml b/hash/ekara_cart.xml index 956f14031ce..6db750e0b76 100644 --- a/hash/ekara_cart.xml +++ b/hash/ekara_cart.xml @@ -315,7 +315,7 @@ license:CC0-1.0 Japanese cart listing (by M code) (M-x on cartridge / box, MC in cart identifier code) M-1 *MC0001-ATM Artist Mini Volume 1 (Aya Matsuura) - M-2 *MC0002-ATM Artist Mini Volume 2 (PIKA☆NCHI, A・RA・SHI/他) + M-2 *MC0002-ATM Artist Mini Volume 2 (PIKA☆NCHI, A·RA·SHI, etc.) M-3 *MC0003-ATM Artist Mini Volume 3 (Morning Musume) M-4 *MC0004-ATM Artist Mini Volume 4 (w-inds) M-5 *MC0005-KSM Kids Song Mini Volume 1 (TV Song) @@ -324,7 +324,7 @@ license:CC0-1.0 M-8 *MC0008-KSM Kids Song Mini Volume 3 M-9 *MC0009-JPM J-Pop Mix Mini Volume 1 M-10 *MC0010-ATM Artist Mini Volume 6 (Utada Hikaru) - M-11 *MC0011-KSM Kids Song Mini Volume 4 (Fantastic) + M-11 *MC0011-KSM Kids Song Mini Volume 4 (Micky Mouse March, Hoshi ni Negai O, etc.) M-12 *MC0012-ATM Artist Mini Volume 7 (Ayumi Hamasaki) M-13 *MC0013-KSM Kids Song Mini Volume 5 M-14 *MC0014-ATM Artist Mini Volume 8 (BoA) @@ -371,7 +371,7 @@ license:CC0-1.0 S-14 *SC0014-SAI Saiten Cartridge Challenge Idol vol.4 S-15 *SC0015-DCS Saiten Cartridge Detective Conan Vol.2 S-16 *SC0016-SAI Saiten Cartridge Nesshō vol. 5 - S-17 *SC0017-SAI Kids' Challenge Vol.2 + S-17 *SC0017-SAI Kids' Challenge Vol.2 (Te o Tsunagō, Anpanman no March, etc.) S-18 *SC0018-SAI Saiten Cartridge Challenge Artist Vol.1 (Morning Musume, Tanpopo, Petit Moni, Gotō Maki) S-19 *SC0019-SAI Saiten Cartridge Nesshō vol. 6 S-20 *SC0020-SAI Saiten Cartridge Challenge Idol vol.5 @@ -419,7 +419,7 @@ license:CC0-1.0 *KR-1 Kirarin Revolution (comes in kira kara Starter Set bundled with Kirarin Revolution microphone) (inside cart is marked AC0009-KIR) *BX01-MOR Morning Musume Special (sticker inside cart is marked CS019-004A) - *PR-01 MNG (c)2002 Morning Musume - I'm Here! (single song 'not for sale' cartridge) + *PR-01 MNG (c)2002 Premium Cartridge Koko ni Iru Zee! Morning Musume (single song 'not for sale' cartridge) PR-02 AYY (c)2003 Aya Matsuura - Prairies Man (single song 'not for sale' cartridge) *PR-06 Misora Hibari (inside cart is marked AC0009) @@ -1791,9 +1791,10 @@ license:CC0-1.0 - Dream Cartridge: TV Pop Junior Vol.8 (Japan) (DC0004-TPJ) + Dream Cartridge: TV Pop Junior Vol.8 (Happy Lucky - Onegai Mirmo, mini-moni - Telephone! Ring Ring Ring, etc.) (Japan) (DC0004-TPJ) 2004 Takara + @@ -1849,10 +1850,10 @@ license:CC0-1.0 - Dream Cartridge: TV Pop Junior Vol.10 (Japan) (DC0009-TPJ) + Dream Cartridge: TV Pop Junior Vol.10 (Bon Voyage!, Kimi to Yakusoku Shita Yasashī Ano Basho Made, etc.) (Japan) (DC0009-TPJ) 2004 Takara - + @@ -2297,9 +2298,10 @@ license:CC0-1.0 - Artist Mini Volume 2 (PIKA☆NCHI, A・RA・SHI/他) (Japan) (MC0002-ATM) + Artist Mini Volume 2 (PIKA☆NCHI, A·RA·SHI, etc.) (Japan) (MC0002-ATM) 2003 Takara + @@ -2413,9 +2415,10 @@ license:CC0-1.0 - Kids Song Mini Volume 4 (Fantastic) (Japan) (MC0011-KSM) + Kids Song Mini Volume 4 (Micky Mouse March, Hoshi ni Negai O, etc.) (Japan) (MC0011-KSM) 2003 Takara + @@ -2722,9 +2725,10 @@ license:CC0-1.0 - Saiten Cartridge Nesshō vol. 4 (Japan) (SC0013-SAI) + Saiten Cartridge Nesshō vol. 4 (Naminori Johnny, Kanashimi wa Yuki no Yō Ni, etc.) (Japan) (SC0013-SAI) 2001 Takara + @@ -2773,9 +2777,10 @@ license:CC0-1.0 - Kids' Challenge Vol.2 (Japan) (SC0017-SAI) + Kids' Challenge Vol.2 (Te o Tsunagō, Anpanman no March, etc.) (Japan) (SC0017-SAI) 2001 Takara + @@ -2952,9 +2957,10 @@ license:CC0-1.0 - PR-01 Morning Musume - I'm Here! (Not for Sale, Japan) + PR-01 Premium Cartridge Koko ni Iru Zee! Morning Musume (Not for Sale, Japan) 2002 Takara + @@ -2993,10 +2999,10 @@ license:CC0-1.0 - Natsukashi no Meikyoku-shū (Japan) + Natsukashi no Meikyoku-shū (Akatonbo, Haru ga Kita, etc.) (Japan) 2002 Takara - + diff --git a/hash/hikara.xml b/hash/hikara.xml index 1c3e155a25b..2f898f2374b 100644 --- a/hash/hikara.xml +++ b/hash/hikara.xml @@ -64,11 +64,11 @@ license:CC0-1.0 --> + キューティーハニー 倖田來未 Cutie Honey Kōda Kumi + KissHug aiko KissHug aiko + さくらんぼ 大塚愛 Sakuranbo Ōtsuka Ai + Dream Fighter Perfume Dream Fighter Perfume + ポリリズム Perfume Polyrhythm Perfume --> Hi-kara 5-song capacity user cartridge (used, with 5 songs) (Japan) 2008 @@ -80,6 +80,11 @@ license:CC0-1.0 + Hi-kara 5-song capacity user cartridge (used, with 4 songs) (Japan) 2008 @@ -232,9 +237,10 @@ license:CC0-1.0 - Pocket Monsters Special + Utatte Asonde! Best Hit Pokémon 2008 Takara Tomy + @@ -243,9 +249,10 @@ license:CC0-1.0 - Ciao Special + Ciao Best Hit Cartridge 2009 Takara Tomy + diff --git a/hash/neogeo.xml b/hash/neogeo.xml index 2903622b20c..c1156186a36 100644 --- a/hash/neogeo.xml +++ b/hash/neogeo.xml @@ -11815,8 +11815,8 @@ Four player adapter not supported - - + + diff --git a/hash/saitek_egr.xml b/hash/saitek_egr.xml index 0eb761b8a94..8dae2912cff 100644 --- a/hash/saitek_egr.xml +++ b/hash/saitek_egr.xml @@ -34,7 +34,7 @@ license:CC0-1.0 - Endgame ROM (ver. 2) + Endgame ROM (ver. 2, set 1) 1988 Saitek @@ -45,4 +45,16 @@ license:CC0-1.0 + + Endgame ROM (ver. 2, set 2) + 1988 + Saitek + + + + + + + + diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 3953786b204..ace32673389 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -1560,6 +1560,17 @@ if (MACHINES["1MB5"]~=null) then } end +--------------------------------------------------- +--@src/devices/machine/i2cmem.h,MACHINES["I2CHLE"] = true +--------------------------------------------------- + +if (MACHINES["I2CHLE"]~=null) then + files { + MAME_DIR .. "src/devices/machine/i2chle.cpp", + MAME_DIR .. "src/devices/machine/i2chle.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/i2cmem.h,MACHINES["I2CMEM"] = true diff --git a/src/devices/bus/kim1/kim1bus.h b/src/devices/bus/kim1/kim1bus.h index 2512654c196..7465a2e7441 100644 --- a/src/devices/bus/kim1/kim1bus.h +++ b/src/devices/bus/kim1/kim1bus.h @@ -4,6 +4,83 @@ kim1bus.h - KIM-1 expansion bus + Basically 6502 bus brought out to a connector. + + 44-pin edge connector, 1-22 on top, A-Z on bottom + + SYNC 1 A AB0 + /RDY 2 B AB1 + clock phase 1 3 C AB2 + /IRQ 4 D AB3 + RO 5 E AB4 + /NMI 6 F AB5 + /RES 7 H AB6 + DB7 8 J AB7 + DB6 9 K AB8 + DB5 10 L AB9 + DB4 11 M AB10 + DB3 12 N AB11 + DB2 13 P AB12 + DB1 14 R AB13 + DB0 15 S AB14 + K6 16 T AB15 + SST out 17 U clock phase 2 + N/C 18 V R/W + N/C 19 W inverted R/W + N/C 20 X PLL test + VCC 21 Y inverted clock phase 2 + GND 22 Z RAM R/W + + * RO is connected to 6502 SO pin + * K6 is asserted (low) when accessing 0x1800-0x1bff (mirror 0xe000) + + Rockwell AIM65 expansion only differs in five pins: + + -12V 16 + +12V 17 + /CS8 18 + /CS9 19 + /CSA 20 + + Comelta DRAC-1 expansion modules use a 96-pin Eurocard connector with row + b unused. Has an external manual reset input and more power rails, but + omits some control signals: + + +25V a 1 c +25V + external manual reset a 2 c reserved + reserved a 3 c +5V battery + +12V a 4 c +15V + -5V a 5 c -15V/-12V + +5V a 6 c +5V + GND a 7 c GND + GND a 8 c GND + N/C a 9 c N/C + N/C a 10 c N/C + N/C a 11 c N/C + N/C a 12 c N/C + reserved a 13 c SYNC + reserved a 14 c reserved + R/W a 15 c /RDY + clock phase 2 a 16 c clock phase 1 + /IRQ a 17 c reserved + /NMI a 18 c /RES + reserved a 19 c reserved + DB7 a 20 c DB6 + DB5 a 21 c DB4 + DB3 a 22 c DB2 + DB1 a 23 c DB0 + reserved a 24 c reserved + AB15 a 25 c AB14 + AB13 a 26 c AB12 + AB11 a 27 c AB10 + AB9 a 28 c AB8 + AB7 a 29 c AB6 + AB5 a 30 c AB4 + AB3 a 31 c AB2 + AB1 a 32 c AB0 + + * No RO, RAM R/W, inverted clock phase 2 and R/W, K6 or SST out + ***************************************************************************/ #ifndef MAME_BUS_KIM1_KIM1BUS_H diff --git a/src/devices/bus/qbus/qbus.cpp b/src/devices/bus/qbus/qbus.cpp index 565bab97e92..01229c459bd 100644 --- a/src/devices/bus/qbus/qbus.cpp +++ b/src/devices/bus/qbus/qbus.cpp @@ -131,6 +131,14 @@ void qbus_device::device_reset() { } +void qbus_device::init_w() +{ + for (device_qbus_card_interface &entry : m_device_list) + { + entry.init_w(); + } +} + //------------------------------------------------- // add_card - add card diff --git a/src/devices/bus/qbus/qbus.h b/src/devices/bus/qbus/qbus.h index ae6248c6a40..7e647eb40da 100644 --- a/src/devices/bus/qbus/qbus.h +++ b/src/devices/bus/qbus/qbus.h @@ -33,11 +33,14 @@ class device_qbus_card_interface : public device_interface // Q-Bus interface virtual void biaki_w(int state) { } virtual void bdmgi_w(int state) { } + virtual void init_w() { device_reset(); } protected: // construction/destruction device_qbus_card_interface(const machine_config &mconfig, device_t &device); + virtual void device_reset() { } + virtual int z80daisy_irq_state() { return 0; } virtual int z80daisy_irq_ack() { return -1; } virtual void z80daisy_irq_reti() { } @@ -79,6 +82,8 @@ class qbus_device : public device_t, void add_card(device_qbus_card_interface &card); void install_device(offs_t start, offs_t end, read16sm_delegate rhandler, write16sm_delegate whandler, uint32_t mask=0xffffffff); + void init_w(); + void birq4_w(int state) { m_out_birq4_cb(state); } void birq5_w(int state) { m_out_birq5_cb(state); } void birq6_w(int state) { m_out_birq6_cb(state); } @@ -138,7 +143,6 @@ class qbus_slot_device : public device_t, public device_slot_interface protected: // device_t implementation virtual void device_start() override; - virtual void device_reset() override { if (m_card) get_card_device()->reset(); } devcb_write_line m_write_birq4; devcb_write_line m_write_birq5; diff --git a/src/devices/cpu/t11/t11.cpp b/src/devices/cpu/t11/t11.cpp index 487a7a57003..5e785e6d11a 100644 --- a/src/devices/cpu/t11/t11.cpp +++ b/src/devices/cpu/t11/t11.cpp @@ -42,12 +42,14 @@ DEFINE_DEVICE_TYPE(K1801VM2, k1801vm2_device, "k1801vm2", "K1801VM2") k1801vm1_device::k1801vm1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : t11_device(mconfig, K1801VM1, tag, owner, clock) + , z80_daisy_chain_interface(mconfig, *this) { c_insn_set = IS_LEIS | IS_MXPS | IS_VM1; } k1801vm2_device::k1801vm2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : t11_device(mconfig, K1801VM2, tag, owner, clock) + , z80_daisy_chain_interface(mconfig, *this) { c_insn_set = IS_LEIS | IS_EIS | IS_MXPS | IS_VM2; } @@ -258,6 +260,7 @@ void k1801vm1_device::t11_check_irqs() // 8. external HALT (nIRQ1 pin); PSW11, PSW10 else if (m_hlt_active) { + m_hlt_active = 0; m_mcir = MCIR_HALT; m_vsel = VM1_HALT; } @@ -277,7 +280,8 @@ void k1801vm1_device::t11_check_irqs() // 12. nVIRQ pin; PSW7, PSW10 else if (m_vec_active && !GET_I) { - int vec = m_in_iack_func(0); + device_z80daisy_interface *intf = daisy_get_irq_device(); + int vec = (intf != nullptr) ? intf->z80daisy_irq_ack() : m_in_iack_func(0); if (vec == -1 || vec == 0) { m_vec_active = 0; diff --git a/src/devices/cpu/t11/t11.h b/src/devices/cpu/t11/t11.h index cb4c2d477c8..2cfc843d01a 100644 --- a/src/devices/cpu/t11/t11.h +++ b/src/devices/cpu/t11/t11.h @@ -7,6 +7,8 @@ #pragma once +#include "machine/z80daisy.h" + enum { @@ -1194,7 +1196,7 @@ class t11_device : public cpu_device void sub_ixd_ixd(uint16_t op); }; -class k1801vm1_device : public t11_device +class k1801vm1_device : public t11_device, public z80_daisy_chain_interface { public: // construction/destruction @@ -1212,7 +1214,7 @@ class k1801vm1_device : public t11_device }; -class k1801vm2_device : public t11_device +class k1801vm2_device : public t11_device, public z80_daisy_chain_interface { public: // construction/destruction diff --git a/src/devices/machine/dimm_spd.cpp b/src/devices/machine/dimm_spd.cpp index b6736e71ade..54788c3d977 100644 --- a/src/devices/machine/dimm_spd.cpp +++ b/src/devices/machine/dimm_spd.cpp @@ -6,8 +6,6 @@ Each DIMM contains a small EEPROM with information about the capacity and timings of the module. The EEPROM speaks a version of I2C called SMBus. - - This does not attempt to be a generalized I2C/SMBus solution. */ @@ -19,35 +17,12 @@ #define VERBOSE (0) #include "logmacro.h" -//************************************************************************** -// DEVICE DEFINITIONS -//************************************************************************** - DEFINE_DEVICE_TYPE(DIMM_SPD, dimm_spd_device, "dimm_spd", "DIMM Serial Presence Detect") -constexpr int STATE_IDLE = 0; -constexpr int STATE_GET_ADDRESS = 1; -constexpr int STATE_GET_SUBADDRESS = 2; -constexpr int STATE_READ_DATA = 3; -constexpr int STATE_WAIT_ACK = 4; - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// dimm_spd_device - constructor -//------------------------------------------------- - dimm_spd_device::dimm_spd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, DIMM_SPD, tag, owner, clock), - write_sda(*this) + i2c_hle_interface(mconfig, *this, 0) // address will be overridden by set_address as before { - m_data_offset = 0; - m_sda = m_scl = 1; - m_state = m_state_next = STATE_IDLE; - m_last_address = 0; - m_just_acked = false; } //------------------------------------------------- @@ -68,21 +43,6 @@ void dimm_spd_device::device_start() m_data[7] = 0; // data bus width high byte m_data[11] = 0; // non-ECC (1=parity, 2=ECC) m_data[62] = 0x12; // SPD version 1.2 - - m_latch = m_bit = 0; - m_state = STATE_IDLE; - m_sda = m_scl = 1; - m_last_address = 0; - m_data_offset = 0; - - save_item(NAME(m_latch)); - save_item(NAME(m_bit)); - save_item(NAME(m_state)); - save_item(NAME(m_state_next)); - save_item(NAME(m_data_offset)); - save_item(NAME(m_just_acked)); - - write_sda(1); } void dimm_spd_device::set_dimm_size(dimm_size_t size) @@ -138,191 +98,13 @@ void dimm_spd_device::set_dimm_size(dimm_size_t size) } } -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void dimm_spd_device::device_reset() -{ -} - -void dimm_spd_device::sda_write(int state) +u8 dimm_spd_device::read_data(u16 offset) { - if (m_size == SIZE_SLOT_EMPTY) + // i2c_hle_interface auto-increments the address but doesn't wrap it around + if (offset >= m_size) { - return; + m_data_offset = 0; } - if (m_sda != state) - { - m_sda = state & 1; - - if (m_scl) - { - if (m_sda) - { - LOG("%s: stop\n", tag()); - m_state = STATE_IDLE; - m_last_address = 0; - m_just_acked = false; - m_data_offset = 0; - } - else - { - LOG("%s: start\n", tag()); - m_state = STATE_GET_ADDRESS; - m_bit = 0; - m_latch = 0; - m_just_acked = false; - } - } - } -} - -void dimm_spd_device::scl_write(int state) -{ - if (m_size == SIZE_SLOT_EMPTY) - { - return; - } - - if (m_scl != state) - { - m_scl = state & 1; - - switch (m_state) - { - case STATE_IDLE: - // just ignore everything until a START - break; - - case STATE_GET_ADDRESS: - case STATE_GET_SUBADDRESS: - if (m_bit < 8) - { - if (m_scl) - { - m_latch <<= 1; - m_latch |= m_sda; - m_bit++; - } - } - else - { - if (m_scl) - { - m_bit++; - } - else - { - if (m_bit == 8) - { - if (m_state == STATE_GET_ADDRESS) - { - LOG("%s: Got address %02x (ours is %02x r/w %d)\n", tag(), m_latch >> 1, m_address, m_latch & 1); - // check if reading - if (m_latch & 1) - { - if ((m_latch >> 1) == m_address) - { - LOG("%s: address matches, ACKing\n", tag()); - write_sda(0); - m_bit = 0; - m_latch = 0; - m_state_next = STATE_READ_DATA; - m_state = STATE_WAIT_ACK; - } - else - { - LOG("%s: address doesn't match, ignoring\n", tag()); - m_state = STATE_IDLE; - write_sda(1); - } - } - else - { - LOGMASKED(LOG_DATAOUT, "%s: write: getting subaddress\n", tag()); - m_last_address = m_latch >> 1; - write_sda(0); - m_bit = 0; - m_latch = 0; - m_state_next = STATE_GET_SUBADDRESS; - m_state = STATE_WAIT_ACK; - } - } - else if (m_state == STATE_GET_SUBADDRESS) - { - LOGMASKED(LOG_DATAOUT, "%s: subaddress is %02x\n", tag(), m_latch); - m_data_offset = m_latch; - write_sda(0); - m_bit = 0; - m_latch = 0; - m_state_next = STATE_IDLE; // is this correct? - m_state = STATE_WAIT_ACK; - } - } - } - } - break; - - case STATE_WAIT_ACK: - if (!m_scl) - { - m_state = m_state_next; - write_sda(1); - } - break; - - case STATE_READ_DATA: - if (m_bit < 8) - { - if (!m_scl) - { - m_bit++; - write_sda(1); - } - else - { - if (m_bit == 0) - { - m_latch = m_data[m_data_offset++]; - m_data_offset &= 0xff; - LOGMASKED(LOG_DATAOUT, "%s: outputting byte %02x\n", tag(), m_latch); - } - - write_sda(BIT(m_latch, 7)); - m_latch <<= 1; - } - } - else - { - if (m_scl) - { - // did the master ACK or NACK? - if (m_sda) - { - LOGMASKED(LOG_DATAOUT, "%s: master NACK\n", tag()); - m_state = STATE_IDLE; - write_sda(1); - } - else - { - LOGMASKED(LOG_DATAOUT, "%s: master ACK\n", tag()); - m_just_acked = true; - } - } - else - { - write_sda(1); - if (m_just_acked) - { - m_bit = 0; - m_just_acked = false; - } - } - } - break; - } - - } + return m_data[offset]; } diff --git a/src/devices/machine/dimm_spd.h b/src/devices/machine/dimm_spd.h index 7fc42844bd5..0160e392e28 100644 --- a/src/devices/machine/dimm_spd.h +++ b/src/devices/machine/dimm_spd.h @@ -5,13 +5,8 @@ #pragma once -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** - -// ======================> dimm_spd_device - -class dimm_spd_device : public device_t +#include "machine/i2chle.h" +class dimm_spd_device : public device_t, public i2c_hle_interface { public: // construction/destruction @@ -22,16 +17,6 @@ class dimm_spd_device : public device_t dimm_spd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // inline configuration helpers - void set_address(u16 address) { m_address = address; } - - auto sda_callback() { return write_sda.bind(); } - - void sda_write(int state); - void scl_write(int state); - - devcb_write_line write_sda; - typedef enum { SIZE_SLOT_EMPTY = 0, @@ -47,20 +32,14 @@ class dimm_spd_device : public device_t void set_dimm_size(dimm_size_t size); protected: - // device-level overrides + // device_t overrides virtual void device_start() override; - virtual void device_reset() override; + // i2c_hle_interface overrides + virtual u8 read_data(u16 offset) override; + virtual const char *get_tag() override { return tag(); } private: u8 m_data[256]; - u8 m_latch; - u8 m_bit; - u16 m_address; - u16 m_last_address; - int m_sda, m_scl; - u32 m_state, m_state_next; - u16 m_data_offset; - bool m_just_acked; dimm_size_t m_size; }; diff --git a/src/devices/machine/i2chle.cpp b/src/devices/machine/i2chle.cpp new file mode 100644 index 00000000000..1e9f6cc0f59 --- /dev/null +++ b/src/devices/machine/i2chle.cpp @@ -0,0 +1,276 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/* + I2C HLE mix-in + by R. Belmont + + A mix-in to allow devices to speak I2C without reimplementing + the protocol themselves. + + If the device returns data over I2C, override read_data. + If the device is written data over I2C, override write_data. + If you want the mix-in's logging to show your device name, override + get_tag() with something that just returns your tag(). + + This mix-in will auto-increment the address on repeated reads/writes, + it's up to your class that consumes this mix-in +*/ + +#include "emu.h" +#include "i2chle.h" + +#define LOG_DATAOUT (1U << 1) + +#define VERBOSE (0) + +#define LOG_OUTPUT_FUNC osd_printf_info + +#include "logmacro.h" + +constexpr int STATE_IDLE = 0; +constexpr int STATE_GET_ADDRESS = 1; +constexpr int STATE_GET_SUBADDRESS = 2; +constexpr int STATE_READ_DATA = 3; +constexpr int STATE_WAIT_ACK = 4; +constexpr int STATE_GET_WRITE_DATA = 5; + +i2c_hle_interface::i2c_hle_interface(const machine_config &mconfig, device_t &device, u16 address) : + device_interface(device, "i2chle"), + write_sda(*this), + m_address(address) +{ + m_data_offset = 0; + m_sda = m_scl = 1; + m_state = m_state_next = STATE_IDLE; + m_last_address = 0; + m_just_acked = false; +} + +i2c_hle_interface::~i2c_hle_interface() +{ +} + +void i2c_hle_interface::interface_post_start() +{ + m_latch = m_bit = 0; + m_state = STATE_IDLE; + m_sda = m_scl = 1; + m_last_address = 0; + m_data_offset = 0; + + device().save_item(NAME(m_latch)); + device().save_item(NAME(m_bit)); + device().save_item(NAME(m_state)); + device().save_item(NAME(m_state_next)); + device().save_item(NAME(m_data_offset)); + device().save_item(NAME(m_just_acked)); + + write_sda(1); +} + +void i2c_hle_interface::sda_write(int state) +{ + if (m_sda != state) + { + m_sda = state & 1; + + if (m_scl) + { + if (m_sda) + { + LOG("%s: stop\n", get_tag()); + m_state = STATE_IDLE; + m_last_address = 0; + m_just_acked = false; + m_data_offset = 0; + } + else + { + LOG("%s: start\n", get_tag()); + m_state = STATE_GET_ADDRESS; + m_bit = 0; + m_latch = 0; + m_just_acked = false; + } + } + } +} + +void i2c_hle_interface::scl_write(int state) +{ + if (m_scl != state) + { + m_scl = state & 1; + + switch (m_state) + { + case STATE_IDLE: + // just ignore everything until a START + break; + + case STATE_GET_ADDRESS: + case STATE_GET_SUBADDRESS: + case STATE_GET_WRITE_DATA: + if (m_bit < 8) + { + if (m_scl) + { + m_latch <<= 1; + m_latch |= m_sda; + m_bit++; + } + } + else + { + if (m_scl) + { + m_bit++; + } + else + { + if (m_bit == 8) + { + if (m_state == STATE_GET_ADDRESS) + { + LOG("%s: Got address %02x (ours is %02x r/w %d)\n", get_tag(), m_latch >> 1, m_address, m_latch & 1); + // check if reading + if (m_latch & 1) + { + if ((m_latch >> 1) == m_address) + { + LOG("%s: address matches, ACKing\n", get_tag()); + write_sda(0); + m_bit = 0; + m_latch = 0; + m_state_next = STATE_READ_DATA; + m_state = STATE_WAIT_ACK; + } + else + { + LOG("%s: address doesn't match, ignoring\n", get_tag()); + m_state = STATE_IDLE; + write_sda(1); + } + } + else + { + if ((m_latch >> 1) == m_address) + { + LOGMASKED(LOG_DATAOUT, "%s: write: getting subaddress\n", get_tag()); + m_last_address = m_latch >> 1; + write_sda(0); + m_bit = 0; + m_latch = 0; + m_state_next = STATE_GET_SUBADDRESS; + m_state = STATE_WAIT_ACK; + } + else + { + LOG("%s: address doesn't match, ignoring\n", get_tag()); + m_state = STATE_IDLE; + write_sda(1); + } + } + } + else if (m_state == STATE_GET_SUBADDRESS) + { + LOGMASKED(LOG_DATAOUT, "%s: subaddress is %02x\n", get_tag(), m_latch); + m_data_offset = m_latch; + write_sda(0); + m_bit = 0; + m_latch = 0; + m_state_next = STATE_GET_WRITE_DATA; + m_state = STATE_WAIT_ACK; + } + else if (m_state == STATE_GET_WRITE_DATA) + { + LOGMASKED(LOG_DATAOUT, "%s: got write data %02x for address %02x\n", get_tag(), m_latch, m_data_offset); + write_data(m_data_offset, m_latch); + m_data_offset++; + write_sda(0); + m_bit = 0; + m_latch = 0; + m_state_next = STATE_GET_WRITE_DATA; + m_state = STATE_WAIT_ACK; + } + } + } + } + break; + + case STATE_WAIT_ACK: + if (!m_scl) + { + m_state = m_state_next; + write_sda(1); + } + break; + + case STATE_READ_DATA: + if (m_bit < 8) + { + if (!m_scl) + { + m_bit++; + write_sda(1); + } + else + { + if (m_bit == 0) + { + m_latch = read_data(m_data_offset); + m_data_offset++; + m_data_offset &= 0xff; + LOGMASKED(LOG_DATAOUT, "%s: outputting byte %02x\n", get_tag(), m_latch); + } + + write_sda(BIT(m_latch, 7)); + m_latch <<= 1; + } + } + else + { + if (m_scl) + { + // did the master ACK or NACK? + if (m_sda) + { + LOGMASKED(LOG_DATAOUT, "%s: master NACK\n", get_tag()); + m_state = STATE_IDLE; + write_sda(1); + } + else + { + LOGMASKED(LOG_DATAOUT, "%s: master ACK\n", get_tag()); + m_just_acked = true; + } + } + else + { + write_sda(1); + if (m_just_acked) + { + m_bit = 0; + m_just_acked = false; + } + } + } + break; + } + } +} + +u8 i2c_hle_interface::read_data(u16 offset) +{ + return 0xff; +} + +void i2c_hle_interface::write_data(u16 offset, u8 data) +{ +} + +static const char i2chle_name[] = "i2chle"; +const char *i2c_hle_interface::get_tag() +{ + return i2chle_name; +} diff --git a/src/devices/machine/i2chle.h b/src/devices/machine/i2chle.h new file mode 100644 index 00000000000..0e6d8b859ef --- /dev/null +++ b/src/devices/machine/i2chle.h @@ -0,0 +1,46 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +#ifndef MAME_MACHINE_I2CHLE_H +#define MAME_MACHINE_I2CHLE_H + +#pragma once + +class i2c_hle_interface : public device_interface +{ +public: + // construction/destruction + i2c_hle_interface(const machine_config &mconfig, device_t &device, u16 address); + virtual ~i2c_hle_interface(); + + void set_address(u16 address) { m_address = address; } + + auto sda_callback() { return write_sda.bind(); } + + void sda_write(int state); + void scl_write(int state); + + devcb_write_line write_sda; + +protected: + void interface_post_start() override ATTR_COLD; + + // override this to read out data + virtual u8 read_data(u16 offset); + virtual void write_data(u16 offset, u8 data); + + // override this to properly identify your device in logging + virtual const char *get_tag(); + + u16 m_data_offset; + +private: + u8 m_latch; + u8 m_bit; + u16 m_address; + u16 m_last_address; + int m_sda, m_scl; + u32 m_state, m_state_next; + bool m_just_acked; +}; + +#endif // MAME_MACHINE_I2CHLE_H diff --git a/src/devices/sound/gb.cpp b/src/devices/sound/gb.cpp index 643ecf9ec68..ea537870907 100644 --- a/src/devices/sound/gb.cpp +++ b/src/devices/sound/gb.cpp @@ -44,6 +44,7 @@ TODO: - Implement different behavior of CGB-02. - Implement different behavior of CGB-05. +- Implement different behavior of AGB-*. - Perform more tests on real hardware to figure out when the frequency counters are reloaded. - Perform more tests on real hardware to understand when changes to the noise divisor @@ -75,6 +76,7 @@ DEFINE_DEVICE_TYPE(DMG_APU, dmg_apu_device, "dmg_apu", "LR35902 APU") //DEFINE_DEVICE_TYPE(CGB02_APU, cgb02_apu_device, "cgb02_apu", fullname) DEFINE_DEVICE_TYPE(CGB04_APU, cgb04_apu_device, "cgb04_apu", "CGB04 APU") //DEFINE_DEVICE_TYPE(CGB05_APU, cgb05_apu_device, "cgb05_apu", fullname) +DEFINE_DEVICE_TYPE(AGB_APU, agb_apu_device, "agb_apu", "AGB APU") //************************************************************************** // LIVE DEVICE @@ -96,12 +98,20 @@ dmg_apu_device::dmg_apu_device(const machine_config &mconfig, const char *tag, d { } +cgb04_apu_device::cgb04_apu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : gameboy_sound_device(mconfig, type, tag, owner, clock) +{ +} cgb04_apu_device::cgb04_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : gameboy_sound_device(mconfig, CGB04_APU, tag, owner, clock) + : cgb04_apu_device(mconfig, CGB04_APU, tag, owner, clock) { } +agb_apu_device::agb_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : cgb04_apu_device(mconfig, AGB_APU, tag, owner, clock) +{ +} //------------------------------------------------- // device_start - device-specific startup @@ -131,6 +141,8 @@ cgb04_apu_device::cgb04_apu_device(const machine_config &mconfig, const char *ta save_item(NAME(snd.sweep_direction)); \ save_item(NAME(snd.sweep_time)); \ save_item(NAME(snd.sweep_count)); \ + save_item(NAME(snd.size)); \ + save_item(NAME(snd.bank)); \ save_item(NAME(snd.level)); \ save_item(NAME(snd.offset)); \ save_item(NAME(snd.duty_count)); \ @@ -148,6 +160,7 @@ void gameboy_sound_device::device_start() save_item(NAME(m_last_updated)); save_item(NAME(m_snd_regs)); + save_item(NAME(m_wave_ram)); // sound control save_item(NAME(m_snd_control.on)); save_item(NAME(m_snd_control.vol_left)); @@ -200,22 +213,22 @@ void gameboy_sound_device::device_reset() m_snd_4.length_mask = 0x3f; sound_w_internal(NR52, 0x00); - m_snd_regs[AUD3W0] = 0xac; - m_snd_regs[AUD3W1] = 0xdd; - m_snd_regs[AUD3W2] = 0xda; - m_snd_regs[AUD3W3] = 0x48; - m_snd_regs[AUD3W4] = 0x36; - m_snd_regs[AUD3W5] = 0x02; - m_snd_regs[AUD3W6] = 0xcf; - m_snd_regs[AUD3W7] = 0x16; - m_snd_regs[AUD3W8] = 0x2c; - m_snd_regs[AUD3W9] = 0x04; - m_snd_regs[AUD3WA] = 0xe5; - m_snd_regs[AUD3WB] = 0x2c; - m_snd_regs[AUD3WC] = 0xac; - m_snd_regs[AUD3WD] = 0xdd; - m_snd_regs[AUD3WE] = 0xda; - m_snd_regs[AUD3WF] = 0x48; + m_wave_ram[0][0x0] = 0xac; + m_wave_ram[0][0x1] = 0xdd; + m_wave_ram[0][0x2] = 0xda; + m_wave_ram[0][0x3] = 0x48; + m_wave_ram[0][0x4] = 0x36; + m_wave_ram[0][0x5] = 0x02; + m_wave_ram[0][0x6] = 0xcf; + m_wave_ram[0][0x7] = 0x16; + m_wave_ram[0][0x8] = 0x2c; + m_wave_ram[0][0x9] = 0x04; + m_wave_ram[0][0xa] = 0xe5; + m_wave_ram[0][0xb] = 0x2c; + m_wave_ram[0][0xc] = 0xac; + m_wave_ram[0][0xd] = 0xdd; + m_wave_ram[0][0xe] = 0xda; + m_wave_ram[0][0xf] = 0x48; } @@ -223,24 +236,63 @@ void cgb04_apu_device::device_reset() { gameboy_sound_device::device_reset(); - m_snd_regs[AUD3W0] = 0x00; - m_snd_regs[AUD3W1] = 0xff; - m_snd_regs[AUD3W2] = 0x00; - m_snd_regs[AUD3W3] = 0xff; - m_snd_regs[AUD3W4] = 0x00; - m_snd_regs[AUD3W5] = 0xff; - m_snd_regs[AUD3W6] = 0x00; - m_snd_regs[AUD3W7] = 0xff; - m_snd_regs[AUD3W8] = 0x00; - m_snd_regs[AUD3W9] = 0xff; - m_snd_regs[AUD3WA] = 0x00; - m_snd_regs[AUD3WB] = 0xff; - m_snd_regs[AUD3WC] = 0x00; - m_snd_regs[AUD3WD] = 0xff; - m_snd_regs[AUD3WE] = 0x00; - m_snd_regs[AUD3WF] = 0xff; + m_wave_ram[0][0x0] = 0x00; + m_wave_ram[0][0x1] = 0xff; + m_wave_ram[0][0x2] = 0x00; + m_wave_ram[0][0x3] = 0xff; + m_wave_ram[0][0x4] = 0x00; + m_wave_ram[0][0x5] = 0xff; + m_wave_ram[0][0x6] = 0x00; + m_wave_ram[0][0x7] = 0xff; + m_wave_ram[0][0x8] = 0x00; + m_wave_ram[0][0x9] = 0xff; + m_wave_ram[0][0xa] = 0x00; + m_wave_ram[0][0xb] = 0xff; + m_wave_ram[0][0xc] = 0x00; + m_wave_ram[0][0xd] = 0xff; + m_wave_ram[0][0xe] = 0x00; + m_wave_ram[0][0xf] = 0xff; } +void agb_apu_device::device_reset() +{ + gameboy_sound_device::device_reset(); + + // TODO: needs verification + m_wave_ram[0][0x0] = 0x00; + m_wave_ram[0][0x1] = 0xff; + m_wave_ram[0][0x2] = 0x00; + m_wave_ram[0][0x3] = 0xff; + m_wave_ram[0][0x4] = 0x00; + m_wave_ram[0][0x5] = 0xff; + m_wave_ram[0][0x6] = 0x00; + m_wave_ram[0][0x7] = 0xff; + m_wave_ram[0][0x8] = 0x00; + m_wave_ram[0][0x9] = 0xff; + m_wave_ram[0][0xa] = 0x00; + m_wave_ram[0][0xb] = 0xff; + m_wave_ram[0][0xc] = 0x00; + m_wave_ram[0][0xd] = 0xff; + m_wave_ram[0][0xe] = 0x00; + m_wave_ram[0][0xf] = 0xff; + + m_wave_ram[1][0x0] = 0x00; + m_wave_ram[1][0x1] = 0xff; + m_wave_ram[1][0x2] = 0x00; + m_wave_ram[1][0x3] = 0xff; + m_wave_ram[1][0x4] = 0x00; + m_wave_ram[1][0x5] = 0xff; + m_wave_ram[1][0x6] = 0x00; + m_wave_ram[1][0x7] = 0xff; + m_wave_ram[1][0x8] = 0x00; + m_wave_ram[1][0x9] = 0xff; + m_wave_ram[1][0xa] = 0x00; + m_wave_ram[1][0xb] = 0xff; + m_wave_ram[1][0xc] = 0x00; + m_wave_ram[1][0xd] = 0xff; + m_wave_ram[1][0xe] = 0x00; + m_wave_ram[1][0xf] = 0xff; +} /*************************************************************************** IMPLEMENTATION @@ -381,6 +433,7 @@ void dmg_apu_device::update_wave_channel(struct SOUND &snd, uint64_t cycles) // compensate for leftover cycles snd.cycles_left += cycles; + const uint8_t level = snd.level & 3; while (snd.cycles_left >= 2) { snd.cycles_left -= 2; @@ -396,14 +449,14 @@ void dmg_apu_device::update_wave_channel(struct SOUND &snd, uint64_t cycles) { // Read next sample snd.sample_reading = true; - snd.current_sample = m_snd_regs[AUD3W0 + (snd.offset/2)]; + snd.current_sample = m_wave_ram[0][(snd.offset / 2)]; if (!(snd.offset & 0x01)) { snd.current_sample >>= 4; } snd.current_sample = (snd.current_sample & 0x0f) - 8; - snd.signal = snd.level ? snd.current_sample / (1 << (snd.level - 1)) : 0; + snd.signal = level ? snd.current_sample / (1 << (level - 1)) : 0; // Reload frequency counter snd.frequency_counter = snd.frequency; @@ -423,23 +476,23 @@ void cgb04_apu_device::update_wave_channel(struct SOUND &snd, uint64_t cycles) return; cycles = (snd.cycles_left >> 1); - snd.cycles_left &= 1; - uint16_t distance = 0x800 - snd.frequency_counter; + uint16_t distance = 0x800 - snd.frequency_counter; + const uint8_t level = snd.level & 3; if (cycles >= distance) { cycles -= distance; distance = 0x800 - snd.frequency; // How many times the condition snd.frequency_counter == 0 is true - uint64_t counter = 1 + cycles / distance; + uint64_t counter = 1 + cycles / distance; snd.offset = (snd.offset + counter) & 0x1f; - snd.current_sample = m_snd_regs[AUD3W0 + snd.offset / 2]; + snd.current_sample = m_wave_ram[0][snd.offset / 2]; if (!(snd.offset & 1)) { snd.current_sample >>= 4; } snd.current_sample = (snd.current_sample & 0x0f) - 8; - snd.signal = snd.level ? snd.current_sample / (1 << (snd.level - 1)) : 0; + snd.signal = level ? snd.current_sample / (1 << (level - 1)) : 0; cycles %= distance; snd.sample_reading = cycles ? false : true; @@ -453,6 +506,66 @@ void cgb04_apu_device::update_wave_channel(struct SOUND &snd, uint64_t cycles) } } +void agb_apu_device::update_wave_channel(struct SOUND &snd, uint64_t cycles) +{ + if (snd.on) + { + const uint8_t level_table[8] = {0, 4, 2, 1, 3, 3, 3, 3}; + // compensate for left over cycles + if (snd.cycles_left > 0) + { + if (cycles <= snd.cycles_left) + { + // Emit samples + snd.cycles_left -= cycles; + cycles = 0; + } + else + { + // Emit samples + + cycles -= snd.cycles_left; + snd.cycles_left = 0; + } + } + + if (cycles & 1) + { + snd.cycles_left = 1; + } + cycles >>= 1; + uint16_t distance = 0x800 - snd.frequency_counter; + const uint8_t level = level_table[snd.level]; + snd.cycles_left &= 1; + + if (cycles >= distance) + { + cycles -= distance; + distance = 0x800 - snd.frequency; + // How many times the condition snd.frequency_counter == 0 is true + uint64_t counter = 1 + cycles / distance; + + snd.offset = (snd.offset + counter) & 0x3f; + const uint8_t bank = snd.size ? BIT(snd.offset, 5) : snd.bank; + snd.current_sample = m_wave_ram[bank][(snd.offset / 2) & 0xf]; + if (!(snd.offset & 1)) + { + snd.current_sample >>= 4; + } + snd.current_sample = (snd.current_sample & 0x0f) - 8; + snd.signal = level ? (snd.current_sample * level) / 4 : 0; + + cycles %= distance; + snd.sample_reading = cycles ? false : true; + + snd.frequency_counter = snd.frequency + cycles; + } + else + { + snd.frequency_counter += cycles; + } + } +} void gameboy_sound_device::update_noise_channel(struct SOUND &snd, uint64_t cycles) { @@ -572,13 +685,12 @@ u8 dmg_apu_device::wave_r(offs_t offset) if (m_snd_3.on) { - return m_snd_3.sample_reading ? m_snd_regs[AUD3W0 + (m_snd_3.offset/2)] : 0xff; + return m_snd_3.sample_reading ? m_wave_ram[0][(m_snd_3.offset / 2)] : 0xff; } - return m_snd_regs[AUD3W0 + offset]; + return m_wave_ram[0][offset]; } - u8 cgb04_apu_device::wave_r(offs_t offset) { m_channel->update(); @@ -586,12 +698,24 @@ u8 cgb04_apu_device::wave_r(offs_t offset) if (m_snd_3.on) { - return m_snd_regs[AUD3W0 + (m_snd_3.offset/2)]; + return m_wave_ram[0][(m_snd_3.offset / 2)]; } - return m_snd_regs[AUD3W0 + offset]; + return m_wave_ram[0][offset]; } +u8 agb_apu_device::wave_r(offs_t offset) +{ + m_channel->update(); + update_state(); + + if (m_snd_3.on) + { + return m_wave_ram[m_snd_3.bank ^ 1][(m_snd_3.offset / 2) & 0xf]; + } + + return m_wave_ram[m_snd_3.bank ^ 1][offset & 0xf]; +} u8 gameboy_sound_device::sound_r(offs_t offset) { @@ -621,6 +745,35 @@ u8 gameboy_sound_device::sound_r(offs_t offset) } } +u8 agb_apu_device::sound_r(offs_t offset) +{ + if ((offset >= AUD3W0) && (offset <= AUD3WF)) + return wave_r(offset - AUD3W0); + + static const uint8_t read_mask[0x40] = + { + 0x80, 0x3f, 0x00, 0xff, 0xbf, 0xff, 0x3f, 0x00, 0xff, 0xbf, 0x1f, 0xff, 0x1f, 0xff, 0xbf, 0xff, + 0xff, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // Make sure we are up to date. + m_channel->update(); + update_state(); + + if (m_snd_control.on) + { + if (offset == NR52) + { + return (m_snd_regs[NR52] & 0xf0) | (m_snd_1.on ? 1 : 0) | (m_snd_2.on ? 2 : 0) | (m_snd_3.on ? 4 : 0) | (m_snd_4.on ? 8 : 0) | 0x70; + } + return m_snd_regs[offset] | read_mask[offset & 0x3f]; + } + else + { + return read_mask[offset & 0x3f]; + } +} void dmg_apu_device::wave_w(offs_t offset, u8 data) { @@ -631,12 +784,12 @@ void dmg_apu_device::wave_w(offs_t offset, u8 data) { if (m_snd_3.sample_reading) { - m_snd_regs[AUD3W0 + (m_snd_3.offset/2)] = data; + m_wave_ram[0][(m_snd_3.offset / 2)] = data; } } else { - m_snd_regs[AUD3W0 + offset] = data; + m_wave_ram[0][offset] = data; } } @@ -648,14 +801,28 @@ void cgb04_apu_device::wave_w(offs_t offset, u8 data) if (m_snd_3.on) { - m_snd_regs[AUD3W0 + (m_snd_3.offset/2)] = data; + m_wave_ram[0][(m_snd_3.offset / 2)] = data; } else { - m_snd_regs[AUD3W0 + offset] = data; + m_wave_ram[0][offset] = data; } } +void agb_apu_device::wave_w(offs_t offset, u8 data) +{ + m_channel->update(); + update_state(); + + if (m_snd_3.on) + { + m_wave_ram[m_snd_3.bank ^ 1][(m_snd_3.offset / 2) & 0xf] = data; + } + else + { + m_wave_ram[m_snd_3.bank ^ 1][offset & 0xf] = data; + } +} void dmg_apu_device::sound_w(offs_t offset, u8 data) { @@ -689,13 +856,13 @@ void dmg_apu_device::corrupt_wave_ram() { if (m_snd_3.offset < 8) { - m_snd_regs[AUD3W0] = m_snd_regs[AUD3W0 + (m_snd_3.offset/2)]; + m_wave_ram[0][0x0] = m_wave_ram[0][(m_snd_3.offset / 2)]; } else { for (int i = 0; i < 4; i++) { - m_snd_regs[AUD3W0 + i] = m_snd_regs[AUD3W0 + ((m_snd_3.offset / 2) & ~0x03) + i]; + m_wave_ram[0][i] = m_wave_ram[0][((m_snd_3.offset / 2) & ~0x03) + i]; } } } @@ -880,6 +1047,8 @@ void gameboy_sound_device::sound_w_internal( int offset, uint8_t data ) /*MODE 3 */ case NR30: /* Sound On/Off (R/W) */ m_snd_3.reg[0] = data; + m_snd_3.size = BIT(data, 5); + m_snd_3.bank = BIT(data, 6); if (!dac_enabled(m_snd_3)) { m_snd_3.on = false; @@ -892,7 +1061,7 @@ void gameboy_sound_device::sound_w_internal( int offset, uint8_t data ) break; case NR32: /* Select Output Level */ m_snd_3.reg[2] = data; - m_snd_3.level = (data & 0x60) >> 5; + m_snd_3.level = (data & 0xe0) >> 5; break; case NR33: /* Frequency lo (W) */ m_snd_3.reg[3] = data; @@ -1041,6 +1210,24 @@ void gameboy_sound_device::sound_w_internal( int offset, uint8_t data ) m_snd_control.on = (data & 0x80) ? true : false; m_snd_regs[NR52] = data & 0x80; break; + case AUD3W0: // Wavetable (R/W) + case AUD3W1: + case AUD3W2: + case AUD3W3: + case AUD3W4: + case AUD3W5: + case AUD3W6: + case AUD3W7: + case AUD3W8: + case AUD3W9: + case AUD3WA: + case AUD3WB: + case AUD3WC: + case AUD3WD: + case AUD3WE: + case AUD3WF: + wave_w(offset - AUD3W0, data); + break; } } diff --git a/src/devices/sound/gb.h b/src/devices/sound/gb.h index 162672f0287..dd5204dee6b 100644 --- a/src/devices/sound/gb.h +++ b/src/devices/sound/gb.h @@ -9,9 +9,11 @@ class gameboy_sound_device : public device_t, public device_sound_interface { public: + static constexpr feature_type imperfect_features() { return feature::SOUND; } // incorrect sound pitch + gameboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - u8 sound_r(offs_t offset); + virtual u8 sound_r(offs_t offset); virtual u8 wave_r(offs_t offset) = 0; virtual void sound_w(offs_t offset, u8 data) = 0; virtual void wave_w(offs_t offset, u8 data) = 0; @@ -107,6 +109,8 @@ class gameboy_sound_device : public device_t, uint8_t sweep_time; uint8_t sweep_count; /* Mode 3 */ + uint8_t size; // AGB specific + uint8_t bank; // AGB specific uint8_t level; uint8_t offset; uint32_t duty_count; @@ -140,6 +144,7 @@ class gameboy_sound_device : public device_t, } m_snd_control; uint8_t m_snd_regs[0x30]; + uint8_t m_wave_ram[2][0x10]; // 16 bytes, 2 banks for AGB attotime m_last_updated; emu_timer *m_timer; @@ -187,15 +192,33 @@ class cgb04_apu_device : public gameboy_sound_device virtual void sound_w(offs_t offset, u8 data) override; protected: + cgb04_apu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + virtual void device_reset() override; virtual void apu_power_off() override; virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override; }; +class agb_apu_device : public cgb04_apu_device +{ +public: + agb_apu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual u8 sound_r(offs_t offset) override; + virtual u8 wave_r(offs_t offset) override; + virtual void wave_w(offs_t offset, u8 data) override; + +protected: + agb_apu_device(const machine_config &mconfig, device_type &type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_reset() override; + virtual void update_wave_channel(struct SOUND &snd, uint64_t cycles) override; +}; DECLARE_DEVICE_TYPE(DMG_APU, dmg_apu_device) //DECLARE_DEVICE_TYPE(CGB02_APU, cgb02_apu_device) DECLARE_DEVICE_TYPE(CGB04_APU, cgb04_apu_device) //DECLARE_DEVICE_TYPE(CGB05_APU, cgb05_apu_device) +DECLARE_DEVICE_TYPE(AGB_APU, agb_apu_device) #endif // MAME_SOUND_GB_H diff --git a/src/lib/formats/fs_cbmdos.cpp b/src/lib/formats/fs_cbmdos.cpp index cbf8ebed553..0654f740685 100644 --- a/src/lib/formats/fs_cbmdos.cpp +++ b/src/lib/formats/fs_cbmdos.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Nathan Woods +// copyright-holders:Nathan Woods, Wilbert Pol /*************************************************************************** fs_cbmdos.cpp @@ -8,21 +8,30 @@ http://fileformats.archiveteam.org/wiki/CBMFS +Current limitations: +- Writing is limited to the first 35 tracks. +- Determine or select the file type. Currently defaulting to PRG; 0 byte files + will be assigned file type DEL. + ***************************************************************************/ #include "fs_cbmdos.h" + #include "d64_dsk.h" #include "fsblk.h" #include "corestr.h" +#include "multibyte.h" #include "strformat.h" #include #include +#include #include #include #include + namespace fs { const cbmdos_image CBMDOS; }; @@ -59,6 +68,8 @@ class impl : public filesystem_t { const void *data() const; const std::array &dirent_data() const; u8 size() const; + u8 track() const { return m_track; } + u8 sector() const { return m_sector; } private: const impl & m_fs; @@ -66,6 +77,8 @@ class impl : public filesystem_t { std::set> m_visited_set; u8 m_track; u8 m_sector; + u8 m_next_track; + u8 m_next_sector; }; impl(fsblk_t &blockdev); @@ -75,12 +88,52 @@ class impl : public filesystem_t { virtual std::pair metadata(const std::vector &path) override; virtual std::pair> directory_contents(const std::vector &path) override; virtual std::pair> file_read(const std::vector &path) override; + virtual err_t file_create(const std::vector &path, const meta_data &meta) override; + virtual err_t file_write(const std::vector &path, const std::vector &data) override; private: + static constexpr u32 BLOCK_SIZE = 256; + static constexpr u8 DIRECTORY_ENTRY_SIZE = 0x20; + static constexpr u8 FILE_TYPE_DEL = 0x80; + static constexpr u8 FILE_TYPE_SEQ = 0x81; + static constexpr u8 FILE_TYPE_PRG = 0x82; + static constexpr u8 FILE_TYPE_USR = 0x83; + static constexpr u8 FILE_TYPE_REL = 0x84; + static constexpr u8 TRACK_VARIANTS = 5; + static constexpr u8 MAX_SECTORS = 21; + static constexpr u8 MAX_TRACKS = 40; + static constexpr u8 DIRECTORY_TRACK = 18; + static constexpr u8 BAM_SECTOR = 0; + static constexpr u8 FIRST_DIRECTORY_SECTOR = 1; + static constexpr u8 SECTOR_DATA_BYTES = 254; + static constexpr u8 OFFSET_FILE_TYPE = 0x02; + static constexpr u8 OFFSET_FILE_FIRST_TRACK = 0x03; + static constexpr u8 OFFSET_FILE_FIRST_SECTOR = 0x04; + static constexpr u8 OFFSET_FILE_NAME = 0x05; + static constexpr u8 OFFSET_SECTOR_COUNT = 0x1e; + static constexpr u8 OFFSET_CHAIN_TRACK = 0x00; + static constexpr u8 OFFSET_CHAIN_SECTOR = 0x01; + static constexpr u8 CHAIN_END = 0x00; + + static const struct smap + { + u8 first_track; + u8 last_track; + int sector[MAX_SECTORS]; + } s_track_sector_map[TRACK_VARIANTS]; + static const u8 s_data_track_order[MAX_TRACKS - 1]; + u8 m_max_track; + fsblk_t::block_t read_sector(int track, int sector) const; std::optional dirent_from_path(const std::vector &path) const; - void iterate_directory_entries(const std::function &callback) const; + void iterate_directory_entries(const std::function &callback) const; + void iterate_all_directory_entries(const std::function &callback) const; meta_data metadata_from_dirent(const cbmdos_dirent &dirent) const; + bool is_valid_filename(const std::string &filename) const; + std::pair claim_track_sector(u8 track) const; + std::tuple claim_sector() const; + err_t free_sector(u8 track, u8 sector) const; + u8 determine_file_type(const std::vector &data) const; }; // methods @@ -147,7 +200,7 @@ bool fs::cbmdos_image::can_read() const bool fs::cbmdos_image::can_write() const { - return false; + return true; } @@ -225,8 +278,22 @@ std::string_view strtrimright_cbm(const char (&str)[N]) // impl ctor //------------------------------------------------- +const u8 impl::s_data_track_order[MAX_TRACKS - 1] = { + 17, 19, 16, 20, 15, 21, 14, 22, 13, 23, 12, 24, 11, 25, 10, 26, 9, 27, 8, 28, 7, 29, 6, 30, 5, 31, 4, 32, 3, 33, 2, 34, 1, 35, 36, 37, 38, 39, 40 +}; + +const impl::smap impl::s_track_sector_map[TRACK_VARIANTS] = { + { 1, 17, { 0, 11, 1, 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10 } }, + { 18, 18, { 0, 1, 4, 7, 10, 13, 16, 2, 5, 8, 11, 14, 17, 3, 6, 9, 12, 15, 18, -1, -1 } }, + { 19, 24, { 0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, -1, -1 } }, + { 25, 30, { 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8, 17, -1, -1, -1 } }, + { 31, 40, { 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8, -1, -1, -1, -1 } } +}; + + impl::impl(fsblk_t &blockdev) - : filesystem_t(blockdev, 256) + : filesystem_t(blockdev, BLOCK_SIZE) + , m_max_track(35) { } @@ -237,7 +304,7 @@ impl::impl(fsblk_t &blockdev) meta_data impl::volume_metadata() { - auto bam_block = read_sector(18, 0); + auto bam_block = read_sector(DIRECTORY_TRACK, BAM_SECTOR); std::string_view disk_name = std::string_view((const char *) bam_block.rodata() + 0x90, 16); meta_data results; @@ -267,7 +334,7 @@ std::pair impl::metadata(const std::vector &path) std::pair> impl::directory_contents(const std::vector &path) { std::vector results; - auto callback = [this, &results](const cbmdos_dirent &ent) + auto callback = [this, &results](u8 track, u8 sector, u8 file_index, const cbmdos_dirent &ent) { results.emplace_back(dir_entry_type::file, metadata_from_dirent(ent)); return false; @@ -298,6 +365,262 @@ std::pair> impl::file_read(const std::vector } +err_t impl::file_create(const std::vector &path, const meta_data &meta) +{ + std::string filename = meta.get_string(meta_name::name, ""); + if (!is_valid_filename(filename)) + return ERR_INVALID; + + std::optional result; + u8 track = 0; + u8 sector = 0; + u8 file_index = 0; + auto callback = [&result, &track, §or, &file_index](u8 t, u8 s, u8 i, const cbmdos_dirent &dirent) + { + bool found = dirent.m_file_type == 0x00; + if (found) + { + result = dirent; + track = t; + sector = s; + file_index = i; + } + return found; + }; + iterate_all_directory_entries(callback); + + if (!result) + { + // Claim a next directory sector + auto const [err, new_sector] = claim_track_sector(DIRECTORY_TRACK); + if (err != ERR_OK) + return err; + auto new_block = read_sector(DIRECTORY_TRACK, new_sector); + for (int i = 2; i < BLOCK_SIZE; i++) + new_block.w8(i, 0); + // Find last directory sector + u8 last_sector = 0; + block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR); + while (iter.next()) + last_sector = iter.sector(); + // Update chain on last directory sector + auto last_dir_block = read_sector(DIRECTORY_TRACK, last_sector); + last_dir_block.w8(OFFSET_CHAIN_TRACK, DIRECTORY_TRACK); + last_dir_block.w8(OFFSET_CHAIN_SECTOR, new_sector); + track = DIRECTORY_TRACK; + sector = new_sector; + } + + auto const [err, file_track, file_sector] = claim_sector(); + if (err != ERR_OK) + return err; + + // Create the file + auto dirblk = read_sector(track, sector); + u32 offset = file_index * DIRECTORY_ENTRY_SIZE; + for (int i = 0; i < DIRECTORY_ENTRY_SIZE; i++) + dirblk.w8(offset + i, (i >= 5 && i < 5 + 16) ? 0xa0 : 0x00); + dirblk.w8(offset + OFFSET_FILE_TYPE, FILE_TYPE_PRG); + dirblk.w8(offset + OFFSET_FILE_FIRST_TRACK, file_track); + dirblk.w8(offset + OFFSET_FILE_FIRST_SECTOR, file_sector); + dirblk.wstr(offset + OFFSET_FILE_NAME, filename); + // TODO set first side sector block track (rel file) + // TODO set first side sector block sector (rel file) + // TODO set rel file record length + // sector count will be set while writing the data + + return ERR_OK; +} + + +err_t impl::file_write(const std::vector &path, const std::vector &data) +{ + if (path.size() != 1) + return ERR_NOT_FOUND; + std::string_view path_part = path[0]; + + std::optional result; + u8 dir_track = 0; + u8 dir_sector = 0; + u8 dir_file_index = 0; + auto const callback = [&result, &dir_track, &dir_sector, &dir_file_index, path_part] (u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent) + { + bool found = strtrimright_cbm(dirent.m_file_name) == path_part; + if (found) + { + dir_track = track; + dir_sector = sector; + dir_file_index = file_index; + result = dirent; + } + return found; + }; + iterate_directory_entries(callback); + + if (!result) + return ERR_NOT_FOUND; + + u8 data_track = result->m_file_first_track; + u8 data_sector = result->m_file_first_sector; + + const size_t data_length = data.size(); + size_t offset = 0; + u32 sector_count = 0; + while (offset < data_length) + { + auto datablk = read_sector(data_track, data_sector); + u8 bytes = (data_length - offset) > SECTOR_DATA_BYTES ? SECTOR_DATA_BYTES : data_length - offset; + memcpy(datablk.data() + 2, data.data() + offset, bytes); + offset += SECTOR_DATA_BYTES; + sector_count++; + if (datablk.r8(OFFSET_CHAIN_TRACK) == CHAIN_END) + { + if (offset < data_length) + { + auto [err, next_track, next_sector] = claim_sector(); + if (err != ERR_OK) + return err; + datablk.w8(OFFSET_CHAIN_TRACK, next_track); + datablk.w8(OFFSET_CHAIN_SECTOR, next_sector); + data_track = next_track; + data_sector = next_sector; + } + } + else + { + if (offset < data_length) + { + data_track = datablk.r8(OFFSET_CHAIN_TRACK); + data_sector = datablk.r8(OFFSET_CHAIN_SECTOR); + } + else + { + // Free the rest of the chain + u8 track_to_free = datablk.r8(OFFSET_CHAIN_TRACK); + u8 sector_to_free = datablk.r8(OFFSET_CHAIN_SECTOR); + + while (track_to_free != CHAIN_END) + { + err_t const err = free_sector(track_to_free, sector_to_free); + if (err != ERR_OK) + return err; + datablk = read_sector(track_to_free, sector_to_free); + track_to_free = datablk.r8(OFFSET_CHAIN_TRACK); + sector_to_free = datablk.r8(OFFSET_CHAIN_SECTOR); + } + } + } + if (offset >= data_length) + { + datablk.w8(OFFSET_CHAIN_TRACK, CHAIN_END); + datablk.w8(OFFSET_CHAIN_SECTOR, bytes + 1); + } + } + + // Write sector count and file type to directory entry + auto dirblk = read_sector(dir_track, dir_sector); + u8 file_type = determine_file_type(data); + if (file_type == FILE_TYPE_DEL) + { + // Free sector, update first file sector to 00 + u8 file_track = dirblk.r8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_TRACK); + u8 file_sector = dirblk.r8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_SECTOR); + err_t err = free_sector(file_track, file_sector); + if (err != ERR_OK) + return err; + dirblk.w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_TRACK, 0); + dirblk.w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_SECTOR, 0); + sector_count = 0; + } + dirblk.w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_TYPE, file_type); + dirblk.w16l(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_SECTOR_COUNT, sector_count); + + return ERR_OK; +} + + +u8 impl::determine_file_type(const std::vector &data) const +{ + // TODO: Determine/set the actual file type, defaulting to PRG for now. + const size_t data_length = data.size(); + if (data_length == 0) + return FILE_TYPE_DEL; + return FILE_TYPE_PRG; +} + + +bool impl::is_valid_filename(const std::string &filename) const +{ + // We only support a subset of the character set supported by Commodore for filenames. + std::regex filename_regex("[A-Z0-9!\"#\\$%&'\\(\\)*+,-./:;<=>?]{1,16}"); + return std::regex_match(filename, filename_regex); +} + + +std::pair impl::claim_track_sector(u8 track) const +{ + if (track == 0 || track > m_max_track) + return std::make_pair(ERR_INVALID, 0); + + u8 map_index; + for (map_index = 0; map_index < TRACK_VARIANTS && !(s_track_sector_map[map_index].first_track <= track && track <= s_track_sector_map[map_index].last_track) ; map_index++); + if (map_index >= TRACK_VARIANTS) + return std::make_pair(ERR_INVALID, 0); + + auto bamblk = read_sector(DIRECTORY_TRACK, BAM_SECTOR); + u8 free_count = bamblk.r8(4 * track); + u32 free_bitmap = bamblk.r24l(4 * track + 1); + + for (int s = 0; s < MAX_SECTORS; s++) + { + int sector = s_track_sector_map[map_index].sector[s]; + if (sector >= 0 && free_count > 0 && util::BIT(free_bitmap, sector)) + { + free_bitmap &= ~(1 << sector); + free_count--; + bamblk.w8(4 * track, free_count); + bamblk.w24l(4 * track + 1, free_bitmap); + // Write chain end marker in new sector + auto claimedlk = read_sector(track, sector); + claimedlk.w8(OFFSET_CHAIN_TRACK, CHAIN_END); + claimedlk.w8(OFFSET_CHAIN_SECTOR, 0xff); + return std::make_pair(ERR_OK, sector); + } + } + return std::make_pair(ERR_NO_SPACE, 0); +} + + +std::tuple impl::claim_sector() const +{ + for (int track = 0; track < m_max_track - 1; track++) + { + auto const [err, sector] = claim_track_sector(s_data_track_order[track]); + if (err == ERR_OK) + return std::make_tuple(ERR_OK, s_data_track_order[track], sector); + if (err != ERR_NO_SPACE) + return std::make_tuple(err, 0, 0); + } + return std::make_tuple(ERR_NO_SPACE, 0, 0); +} + + +err_t impl::free_sector(u8 track, u8 sector) const +{ + if (track == 0 || track > m_max_track) + return ERR_INVALID; + + auto bamblk = read_sector(DIRECTORY_TRACK, BAM_SECTOR); + u8 free_count = bamblk.r8(4 * track); + u32 free_bitmap = bamblk.r24l(4 * track + 1); + free_bitmap |= (1 << sector); + free_count++; + bamblk.w8(4 * track, free_count); + bamblk.w24l(4 * track + 1, free_bitmap); + return ERR_OK; +} + + //------------------------------------------------- // impl::read_sector //------------------------------------------------- @@ -322,13 +645,13 @@ fsblk_t::block_t impl::read_sector(int track, int sector) const std::optional impl::dirent_from_path(const std::vector &path) const { if (path.size() != 1) - return { }; + return std::nullopt; std::string_view path_part = path[0]; std::optional result; - auto callback = [&result, path_part](const cbmdos_dirent &dirent) + auto const callback = [&result, path_part] (u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent) { - bool found = strtrimright_cbm(dirent.m_file_name) == path_part; + bool const found = strtrimright_cbm(dirent.m_file_name) == path_part; if (found) result = dirent; return found; @@ -342,22 +665,38 @@ std::optional impl::dirent_from_path(const std::vector &callback) const +void impl::iterate_directory_entries(const std::function &callback) const { - block_iterator iter(*this, 18, 1); + block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR); while (iter.next()) { - for (const cbmdos_dirent &ent : iter.dirent_data()) + auto entries = iter.dirent_data(); + + for (int file_index = 0; file_index < SECTOR_DIRECTORY_COUNT; file_index++) { - if (ent.m_file_type != 0x00) + if (entries[file_index].m_file_type != 0x00) { - if (callback(ent)) + if (callback(iter.track(), iter.sector(), file_index, entries[file_index])) return; } } } } +void impl::iterate_all_directory_entries(const std::function &callback) const +{ + block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR); + while (iter.next()) + { + auto entries = iter.dirent_data(); + + for (int file_index = 0; file_index < SECTOR_DIRECTORY_COUNT; file_index++) + { + if (callback(iter.track(), iter.sector(), file_index, entries[file_index])) + return; + } + } +} //------------------------------------------------- // impl::metadata_from_dirent @@ -368,19 +707,19 @@ meta_data impl::metadata_from_dirent(const cbmdos_dirent &dirent) const std::string file_type; switch (dirent.m_file_type) { - case 0x80: + case FILE_TYPE_DEL: file_type = "DEL"; break; - case 0x81: + case FILE_TYPE_SEQ: file_type = "SEQ"; break; - case 0x82: + case FILE_TYPE_PRG: file_type = "PRG"; break; - case 0x83: + case FILE_TYPE_USR: file_type = "USR"; break; - case 0x84: + case FILE_TYPE_REL: file_type = "REL"; break; default: @@ -411,6 +750,8 @@ impl::block_iterator::block_iterator(const impl &fs, u8 first_track, u8 first_se : m_fs(fs) , m_track(first_track) , m_sector(first_sector) + , m_next_track(first_track) + , m_next_sector(first_sector) { } @@ -422,19 +763,21 @@ impl::block_iterator::block_iterator(const impl &fs, u8 first_track, u8 first_se bool impl::block_iterator::next() { bool result; - if (m_track != 0x00) + m_track = m_next_track; + m_sector = m_next_sector; + if (m_track != CHAIN_END) { // check for the degenerate scenario where we have a cycle (this should not happen // on a non-corrupt disk) - auto visited_tuple = std::make_tuple(m_track, m_sector); + auto visited_tuple = std::make_tuple(m_next_track, m_next_sector); if (m_visited_set.find(visited_tuple) != m_visited_set.end()) return false; m_visited_set.insert(visited_tuple); // with that out of the way, proceed - m_block = m_fs.read_sector(m_track, m_sector); - m_track = m_block.r8(0); - m_sector = m_block.r8(1); + m_block = m_fs.read_sector(m_next_track, m_next_sector); + m_next_track = m_block.r8(OFFSET_CHAIN_TRACK); + m_next_sector = m_block.r8(OFFSET_CHAIN_SECTOR); result = true; } else @@ -472,7 +815,7 @@ const std::array &impl::block u8 impl::block_iterator::size() const { - return m_track != 0x00 ? 254 : m_sector - 1; + return (m_track != CHAIN_END) ? SECTOR_DATA_BYTES : (m_sector - 1); } } // anonymous namespace diff --git a/src/mame/apple/macquadra630.cpp b/src/mame/apple/macquadra630.cpp index 472fdead1b1..9d030c8566b 100644 --- a/src/mame/apple/macquadra630.cpp +++ b/src/mame/apple/macquadra630.cpp @@ -43,6 +43,7 @@ #include "bus/nubus/cards.h" #include "bus/nubus/nubus.h" #include "cpu/m68000/m68040.h" +#include "machine/input_merger.h" #include "machine/ram.h" #include "machine/timer.h" @@ -177,6 +178,15 @@ void quadra630_state::macqd630(machine_config &config) m_macadb->adb_data_callback().set(m_cuda, FUNC(cuda_device::set_adb_line)); config.set_perfect_quantum(m_maincpu); + input_merger_device &sda_merger(INPUT_MERGER_ALL_HIGH(config, "sda")); + sda_merger.output_handler().append(m_cuda, FUNC(cuda_device::set_iic_sda)); + + m_cuda->iic_sda_callback().set(sda_merger, FUNC(input_merger_device::in_w<0>)); + m_cuda->iic_sda_callback().append(m_video, FUNC(valkyrie_device::sda_write)); + m_cuda->iic_scl_callback().set(m_video, FUNC(valkyrie_device::scl_write)); + + m_video->sda_callback().set(sda_merger, FUNC(input_merger_device::in_w<1>)); + m_primetimeii->pb3_callback().set(m_cuda, FUNC(cuda_device::get_treq)); m_primetimeii->pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack)); m_primetimeii->pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip)); diff --git a/src/mame/apple/valkyrie.cpp b/src/mame/apple/valkyrie.cpp index b91c53224f4..2fab3518d37 100644 --- a/src/mame/apple/valkyrie.cpp +++ b/src/mame/apple/valkyrie.cpp @@ -1,12 +1,26 @@ // license:BSD-3-Clause // copyright-holders:R. Belmont /* - Apple "Valkyrie" - very low-cost video framebuffer - Emulation by R. Belmont + Apple "Valkyrie" - very low-cost video framebuffer + Emulation by R. Belmont + + This was the bonus awfulness in the Quadra 630/LC 580 machines. While the + ROM software and MacOS don't support many monitor types, the Linux driver indicates + that's more of a software problem. + + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/video/fbdev/valkyriefb.c?h=v6.2.10 + + Also valkyrie.c in the Marathon Infinity open source release from Bungie. (They use Valkyrie's video upscaler + to only have to render 320x240!) + + TODO: + - YUV video-in support + - Determine if the I2C clock is internal or external + + Video in buffer 0 is at 0xf9300000 + Video in buffer 1 is at 0xf9340000 + Both buffers are 320x240 with a stride of 1024 bytes, data is 16 bits per pixel (YUV?) - This was the bonus awfulness in the infamous Quadra 630/LC 580 machines. Only - a few monitor types are supported and the video mode timings appear to be hardcoded - into the chip. */ #include "emu.h" @@ -15,6 +29,7 @@ #define LOG_MODE (1U << 1) #define LOG_MONSENSE (1U << 2) #define LOG_RAMDAC (1U << 3) +#define LOG_CLOCKGEN (1U << 4) #define VERBOSE (0) #include "logmacro.h" @@ -35,6 +50,7 @@ void valkyrie_device::map(address_map &map) valkyrie_device::valkyrie_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, VALKYRIE, tag, owner, clock), + i2c_hle_interface(mconfig, *this, 0x28), m_vram_size(0x100000), m_pixel_clock(31334400), m_pal_address(0), m_pal_idx(0), m_mode(0), @@ -43,8 +59,9 @@ valkyrie_device::valkyrie_device(const machine_config &mconfig, const char *tag, m_monitor_config(*this, "monitor"), m_irq(*this), m_vram_offset(0), m_monitor_id(0), - m_base(0), m_stride(1024), m_int_status(0), m_hres(0), m_vres(0), m_htotal(0), m_vtotal(0), - m_config(0) + m_base(0), m_stride(1024), m_video_timing(0x80), m_int_status(0), m_hres(0), m_vres(0), m_htotal(0), m_vtotal(0), + m_config(0), + m_M(1), m_N(1), m_P(1) { } @@ -55,6 +72,7 @@ void valkyrie_device::device_start() m_vbl_timer = timer_alloc(FUNC(valkyrie_device::vbl_tick), this); m_vbl_timer->adjust(attotime::never); + save_item(NAME(m_video_timing)); save_item(NAME(m_vram_offset)); save_item(NAME(m_mode)); save_item(NAME(m_monitor_id)); @@ -69,6 +87,9 @@ void valkyrie_device::device_start() save_item(NAME(m_pixel_clock)); save_item(NAME(m_config)); save_item(NAME(m_int_status)); + save_item(NAME(m_M)); + save_item(NAME(m_N)); + save_item(NAME(m_P)); save_pointer(NAME(m_vram), m_vram_size); machine().save().register_postload(save_prepost_delegate(FUNC(valkyrie_device::recalc_mode), this)); @@ -76,7 +97,15 @@ void valkyrie_device::device_start() void valkyrie_device::device_reset() { - m_enable = false; + m_video_timing = 0x80; + + // clear the MAME default palette so we don't get a weird red screen on initial startup + for (int i = 0; i < 256; i++) + { + m_palette->set_pen_red_level(i, 0); + m_palette->set_pen_green_level(i, 0); + m_palette->set_pen_blue_level(i, 0); + } } void valkyrie_device::device_add_mconfig(machine_config &config) @@ -98,9 +127,10 @@ static INPUT_PORTS_START(monitor_config) PORT_START("monitor") PORT_CONFNAME(0x7f, 6, "Monitor type") PORT_CONFSETTING(0x02, u8"Mac RGB Display (12\" 512\u00d7384)") // "Rubik" (modified IIgs AppleColor RGB) - PORT_CONFSETTING(0x06, u8"Mac Hi-Res Display (12-14\" 640\u00d7480)") // "High Res" - PORT_CONFSETTING(ext(1, 1, 3), "640x480 VGA") + PORT_CONFSETTING(0x06, u8"Mac Hi-Res Display (12-14\" 640\u00d7480)") // "High Res" 640x480 @ 67 Hz + PORT_CONFSETTING(ext(1, 1, 3), "640x480 VGA") // VGA 640x480 @ 60 Hz PORT_CONFSETTING(ext(2, 3, 1), "832x624 16\" RGB") // "Goldfish" or "16 inch RGB" + INPUT_PORTS_END ioport_constructor valkyrie_device::device_input_ports() const @@ -113,7 +143,7 @@ u32 valkyrie_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, auto const vram8 = util::big_endian_cast(&m_vram[0]) + 0x1000; const pen_t *pens = m_palette->pens(); - if (!m_enable) + if (m_video_timing & 0x80) { return 0; } @@ -209,7 +239,6 @@ u32 valkyrie_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, u8 valkyrie_device::regs_r(offs_t offset) { -// printf("Read regs @ %x\n", offset); switch (offset) { case 0: @@ -263,8 +292,12 @@ void valkyrie_device::regs_w(offs_t offset, u8 data) { switch (offset) { - case 0: // video timing select (apparently from hardcoded values!) - m_video_timing = data; + case 0: // video mode. hardcoded! + m_video_timing = data & 0xff; + if (!(data & 0x80)) + { + recalc_mode(); + } break; case 4: // video depth: 0=1bpp, 1=2bpp, 2=4bpp, 3=8bpp, 4=16bpp @@ -272,7 +305,7 @@ void valkyrie_device::regs_w(offs_t offset, u8 data) m_mode = data & 7; break; - case 0xc: // written to lock in the video timing from register 0 + case 0xc: // subsystem configuration register if (data == 0x1) { recalc_mode(); @@ -292,15 +325,6 @@ void valkyrie_device::regs_w(offs_t offset, u8 data) // at startup, the screen isn't wanted on until 0x81 is written. // if the Video Startup extension is installed, it later sets this to 0x02. if ((data & 0x80) || (data == 0x02)) - { - m_enable = true; - } - else - { - m_enable = false; - } - // start VBL interrupts when the screen is enabled - if (m_enable) { m_vbl_timer->adjust(m_screen->time_until_pos(m_vres, 0), 0); } @@ -315,6 +339,33 @@ void valkyrie_device::regs_w(offs_t offset, u8 data) LOGMASKED(LOG_MONSENSE, "%x to sense drive\n", data & 0xf); break; + case 0x20: // video in control + break; + + case 0x60: // video window X position + case 0x61: + break; + + case 0x64: // video window Y position + case 0x65: + break; + + case 0x70: // video window width + case 0x71: + break; + + case 0x74: // video window height + case 0x75: + break; + + case 0x80: // video field starting X pixel + case 0x81: + break; + + case 0x84: // video field starting Y pixel + case 0x85: + break; + default: LOG("Valkyrie: Unk write %08x @ %x\n", data, offset<<2); break; @@ -396,48 +447,59 @@ void valkyrie_device::ramdac_w(offs_t offset, u32 data) void valkyrie_device::recalc_mode() { // mode parameters taken from the Quadra 630 Developer Note - switch (m_video_timing) + // m_video_timing numbers: + // 2 = 512x384, 60 Hz ("Rubik") + // 6 = 640x480, 72 Hz (Mac 13") + // 9 = 832x624, 75 Hz (Mac 16") + // 11 = 640x480, 60 Hz (VGA) + // 12 = 800x600, 60 Hz (SVGA) + // 13 = 800x600, 72 Hz (SVGA) + // 14 = 1024x768, 60 Hz (SVGA) + // 15 = 1024x768, 72 Hz (SVGA) + + if (m_video_timing & 0x80) { - case 0x01: // default - case 0x86: // 13" 640x480 - m_hres = 640; - m_vres = 480; - m_htotal = 864; - m_vtotal = 525; - m_pixel_clock = 30240000; - m_stride = 80; - break; + return; + } - case 0x82: // Rubik 512x384 + switch (m_video_timing & 0x7f) + { + case 2: // Rubik 512x384 m_hres = 512; m_vres = 384; m_htotal = 640; m_vtotal = 407; - m_pixel_clock = 15670000; m_stride = 64; break; - case 0x8b: // VGA 640x480 + case 6: // 13" 640x480 m_hres = 640; m_vres = 480; - m_htotal = 800; + m_htotal = 864; m_vtotal = 525; - m_pixel_clock = 25180000; m_stride = 80; break; - case 0x89: // 16" RGB 832x624? + case 9: // 16" RGB 832x624? m_hres = 832; m_vres = 624; m_htotal = 1072; m_vtotal = 690; - m_pixel_clock = 50000000; m_stride = 104; break; + + case 11: // VGA 640x480 + m_hres = 640; + m_vres = 480; + m_htotal = 800; + m_vtotal = 525; + m_stride = 80; + break; } const double refresh = (double)m_pixel_clock / (double)(m_htotal * m_vtotal); LOGMASKED(LOG_MODE, "hres %d vres %d htotal %d vtotal %d refresh %f stride %d mode %d\n", m_hres, m_vres, m_htotal, m_vtotal, refresh, m_stride, m_mode); + if ((m_hres != 0) && (m_vres != 0)) { rectangle visarea(0, m_hres - 1, 0, m_vres - 1); @@ -474,3 +536,38 @@ TIMER_CALLBACK_MEMBER(valkyrie_device::vbl_tick) m_vbl_timer->adjust(m_screen->time_until_pos(480, 0), 0); } + +void valkyrie_device::write_data(u16 offset, u8 data) +{ + switch (offset) + { + case 0: + return; + + case 1: + m_M = data; + break; + + case 2: + m_N = data; + break; + + case 3: + m_P = data; + break; + } + + const double clock = (3986400.0f * (double)(1 << m_P) * (double)m_N) / (double)m_M; + m_pixel_clock = (u32)clock; + + // TODO: Apple documents these machines as supporting the 512x384 monitor, but selecting it + // programs garbage to the clock generator. Allow that configuration to work until we determine + // if the Apple developer note is lying. + if ((m_M == 0) && (m_N == 0) && (m_P = 98)) + { + m_pixel_clock = 15670000; + } + + LOGMASKED(LOG_CLOCKGEN, "Valkyrie: M = %d %02x, N = %d %02x P = %d, pixel clock %d\n", m_M, m_M, m_N, m_N, m_P, m_pixel_clock); + recalc_mode(); +} diff --git a/src/mame/apple/valkyrie.h b/src/mame/apple/valkyrie.h index cd815c2265e..77cf17b3b7e 100644 --- a/src/mame/apple/valkyrie.h +++ b/src/mame/apple/valkyrie.h @@ -7,11 +7,12 @@ #pragma once #include "cpu/m68000/m68040.h" +#include "machine/i2chle.h" #include "emupal.h" #include "screen.h" -class valkyrie_device : public device_t +class valkyrie_device : public device_t, public i2c_hle_interface { public: valkyrie_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); @@ -22,10 +23,14 @@ class valkyrie_device : public device_t auto write_irq() { return m_irq.bind(); } protected: + // device_t overrides virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; + // i2c_hle_interface overrides virtual ioport_constructor device_input_ports() const override; + virtual void write_data(u16 offset, u8 data) override; + virtual const char *get_tag() override { return tag(); } void recalc_ints(); void recalc_mode(); @@ -48,7 +53,7 @@ class valkyrie_device : public device_t u32 m_base, m_stride, m_video_timing; s32 m_int_status; u32 m_hres, m_vres, m_htotal, m_vtotal, m_config; - bool m_enable; + u8 m_M, m_N, m_P; u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); diff --git a/src/mame/dataeast/simpl156.h b/src/mame/dataeast/simpl156.h index 422c196c151..a3f8dd09b54 100644 --- a/src/mame/dataeast/simpl156.h +++ b/src/mame/dataeast/simpl156.h @@ -23,7 +23,7 @@ class simpl156_state : public driver_device m_okimusic(*this, "okimusic"), m_sprgen(*this, "spritegen"), m_palette(*this, "palette"), - m_rowscroll(*this, "rowscroll_%u", 1U, 0x800U, ENDIANNESS_LITTLE), + m_rowscroll(*this, "rowscroll_%u", 1U, 0x1000U, ENDIANNESS_LITTLE), m_mainram(*this, "mainram", 0x4000U, ENDIANNESS_LITTLE), m_systemram(*this, "systemram"), m_spriteram(*this, "spriteram", 0x1000U, ENDIANNESS_LITTLE) diff --git a/src/mame/konami/konamigq.cpp b/src/mame/konami/konamigq.cpp index 004f6a105cb..aa617c2d4e9 100644 --- a/src/mame/konami/konamigq.cpp +++ b/src/mame/konami/konamigq.cpp @@ -287,7 +287,7 @@ void konamigq_state::scsi_dma_read( uint32_t *p_n_psxram, uint32_t n_address, in m_dma_offset = n_address; m_dma_size = n_size * 4; m_dma_is_write = false; - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); } void konamigq_state::scsi_dma_write( uint32_t *p_n_psxram, uint32_t n_address, int32_t n_size ) @@ -296,12 +296,13 @@ void konamigq_state::scsi_dma_write( uint32_t *p_n_psxram, uint32_t n_address, i m_dma_offset = n_address; m_dma_size = n_size * 4; m_dma_is_write = true; - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); } TIMER_CALLBACK_MEMBER(konamigq_state::scsi_dma_transfer) { - if (m_dma_requested && m_dma_data_ptr != nullptr && m_dma_size > 0) + // TODO: Figure out proper DMA timings + while (m_dma_requested && m_dma_data_ptr != nullptr && m_dma_size > 0) { if (m_dma_is_write) m_ncr53cf96->dma_w(util::little_endian_cast(m_dma_data_ptr)[m_dma_offset]); @@ -311,15 +312,12 @@ TIMER_CALLBACK_MEMBER(konamigq_state::scsi_dma_transfer) m_dma_offset++; m_dma_size--; } - - if (m_dma_requested && m_dma_size > 0) - m_dma_timer->adjust(attotime::from_usec(10)); } void konamigq_state::scsi_drq(int state) { if (!m_dma_requested && state) - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); m_dma_requested = state; } diff --git a/src/mame/konami/konamigv.cpp b/src/mame/konami/konamigv.cpp index 0935ce6c773..0c45f806844 100644 --- a/src/mame/konami/konamigv.cpp +++ b/src/mame/konami/konamigv.cpp @@ -455,7 +455,7 @@ void konamigv_state::scsi_dma_read(uint32_t *p_n_psxram, uint32_t n_address, int m_dma_offset = n_address; m_dma_size = n_size * 4; m_dma_is_write = false; - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); } void konamigv_state::scsi_dma_write(uint32_t *p_n_psxram, uint32_t n_address, int32_t n_size) @@ -464,12 +464,13 @@ void konamigv_state::scsi_dma_write(uint32_t *p_n_psxram, uint32_t n_address, in m_dma_offset = n_address; m_dma_size = n_size * 4; m_dma_is_write = true; - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); } TIMER_CALLBACK_MEMBER(konamigv_state::scsi_dma_transfer) { - if (m_dma_requested && m_dma_data_ptr != nullptr && m_dma_size > 0) + // TODO: Figure out proper DMA timings + while (m_dma_requested && m_dma_data_ptr != nullptr && m_dma_size > 0) { if (m_dma_is_write) m_ncr53cf96->dma_w(util::little_endian_cast(m_dma_data_ptr)[m_dma_offset]); @@ -479,15 +480,12 @@ TIMER_CALLBACK_MEMBER(konamigv_state::scsi_dma_transfer) m_dma_offset++; m_dma_size--; } - - if (m_dma_requested && m_dma_size > 0) - m_dma_timer->adjust(attotime::from_usec(10)); } void konamigv_state::scsi_drq(int state) { if (!m_dma_requested && state) - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); m_dma_requested = state; } diff --git a/src/mame/konami/twinkle.cpp b/src/mame/konami/twinkle.cpp index cf91266a77f..b273c58292d 100644 --- a/src/mame/konami/twinkle.cpp +++ b/src/mame/konami/twinkle.cpp @@ -1088,7 +1088,7 @@ void twinkle_state::scsi_dma_read(uint32_t *p_n_psxram, uint32_t n_address, int3 m_dma_offset = n_address; m_dma_size = n_size * 4; m_dma_is_write = false; - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); } void twinkle_state::scsi_dma_write(uint32_t *p_n_psxram, uint32_t n_address, int32_t n_size) @@ -1097,12 +1097,13 @@ void twinkle_state::scsi_dma_write(uint32_t *p_n_psxram, uint32_t n_address, int m_dma_offset = n_address; m_dma_size = n_size * 4; m_dma_is_write = true; - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); } TIMER_CALLBACK_MEMBER(twinkle_state::scsi_dma_transfer) { - if (m_dma_requested && m_dma_data_ptr != nullptr && m_dma_size > 0) + // TODO: Figure out proper DMA timings + while (m_dma_requested && m_dma_data_ptr != nullptr && m_dma_size > 0) { if (m_dma_is_write) m_ncr53cf96->dma_w(util::little_endian_cast(m_dma_data_ptr)[m_dma_offset]); @@ -1112,15 +1113,12 @@ TIMER_CALLBACK_MEMBER(twinkle_state::scsi_dma_transfer) m_dma_offset++; m_dma_size--; } - - if (m_dma_requested && m_dma_size > 0) - m_dma_timer->adjust(attotime::from_usec(10)); } void twinkle_state::scsi_drq(int state) { if (!m_dma_requested && state) - m_dma_timer->adjust(attotime::from_usec(10)); + m_dma_timer->adjust(attotime::zero); m_dma_requested = state; } diff --git a/src/mame/nintendo/gba.cpp b/src/mame/nintendo/gba.cpp index 265c2972bfe..7730b2a699a 100644 --- a/src/mame/nintendo/gba.cpp +++ b/src/mame/nintendo/gba.cpp @@ -1241,8 +1241,8 @@ void gba_state::dma_vblank_callback(int state) void gba_state::gba_map(address_map &map) { map.unmap_value_high(); // for "Fruit Mura no Doubutsu Tachi" and "Classic NES Series" - map(0x02000000, 0x0203ffff).ram().mirror(0xfc0000); - map(0x03000000, 0x03007fff).ram().mirror(0xff8000); + map(0x02000000, 0x0203ffff).ram().mirror(0xfc0000); // External RAM (16 bit) + map(0x03000000, 0x03007fff).ram().mirror(0xff8000); // Internal RAM (32 bit) map(0x04000000, 0x0400005f).rw("lcd", FUNC(gba_lcd_device::video_r), FUNC(gba_lcd_device::video_w)); map(0x04000060, 0x040003ff).rw(FUNC(gba_state::gba_io_r), FUNC(gba_state::gba_io_w)); map(0x04000400, 0x04ffffff).noprw(); // Not used @@ -1453,7 +1453,7 @@ static void gba_cart(device_slot_interface &device) void gba_state::gbadv(machine_config &config) { - ARM7(config, m_maincpu, XTAL(16'777'216)); + ARM7(config, m_maincpu, XTAL(4'194'304) * 4); // 4.194304MHz * 4 m_maincpu->set_addrmap(AS_PROGRAM, &gba_state::gba_map); gba_lcd_device &lcd(GBA_LCD(config, "lcd", 0)); @@ -1465,7 +1465,7 @@ void gba_state::gbadv(machine_config &config) SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - CGB04_APU(config, m_gbsound, XTAL(16'777'216)/4); + AGB_APU(config, m_gbsound, XTAL(4'194'304)); m_gbsound->add_route(0, "lspeaker", 0.5); m_gbsound->add_route(1, "rspeaker", 0.5); diff --git a/src/mame/sega/segaybd.cpp b/src/mame/sega/segaybd.cpp index 776f211a8a9..53e3981b655 100644 --- a/src/mame/sega/segaybd.cpp +++ b/src/mame/sega/segaybd.cpp @@ -3031,12 +3031,12 @@ GAME( 1990, glocu, gloc, yboard, gloc, segaybd_state, init_gl GAME( 1990, glocr360, gloc, yboard, glocr360, segaybd_state, init_r360, ROT0, "Sega", "G-LOC R360 (World)", MACHINE_SUPPORTS_SAVE ) GAME( 1990, glocr360j, gloc, yboard, glocr360, segaybd_state, init_r360, ROT0, "Sega", "G-LOC R360 (Japan)", MACHINE_SUPPORTS_SAVE ) -GAMEL(1988, pdrift, 0, yboard, pdrift, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (World, Rev A)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE, layout_pdrift ) -GAMEL(1988, pdrifta, pdrift, yboard, pdrift, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (World)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE, layout_pdrift ) -GAMEL(1988, pdrifte, pdrift, yboard, pdrifte, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (World, Earlier)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE, layout_pdrift ) -GAMEL(1988, pdriftj, pdrift, yboard, pdriftj, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (Japan)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE, layout_pdrift ) +GAMEL(1988, pdrift, 0, yboard, pdrift, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (World, Rev A)", MACHINE_SUPPORTS_SAVE, layout_pdrift ) +GAMEL(1988, pdrifta, pdrift, yboard, pdrift, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (World)", MACHINE_SUPPORTS_SAVE, layout_pdrift ) +GAMEL(1988, pdrifte, pdrift, yboard, pdrifte, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (World, Earlier)", MACHINE_SUPPORTS_SAVE, layout_pdrift ) +GAMEL(1988, pdriftj, pdrift, yboard, pdriftj, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift (Japan)", MACHINE_SUPPORTS_SAVE, layout_pdrift ) -GAMEL(1988, pdriftl, 0, yboard_link, pdriftl, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift - Link Version (Japan, Rev A)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN, layout_pdrift ) +GAMEL(1988, pdriftl, 0, yboard_link, pdriftl, segaybd_state, init_pdrift, ROT0, "Sega", "Power Drift - Link Version (Japan, Rev A)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN, layout_pdrift ) GAME( 1991, rchase, 0, yboard, rchase, segaybd_state, init_rchase, ROT0, "Sega", "Rail Chase (World)", MACHINE_SUPPORTS_SAVE ) GAME( 1991, rchasej, rchase, yboard, rchase, segaybd_state, init_rchase, ROT0, "Sega", "Rail Chase (Japan)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/seta/st0016.cpp b/src/mame/seta/st0016.cpp index 425263fe8d1..dd3f1e61894 100644 --- a/src/mame/seta/st0016.cpp +++ b/src/mame/seta/st0016.cpp @@ -260,7 +260,7 @@ u8 st0016_cpu_device::vregs_r(offs_t offset) /* $0, $1 = max scanline(including vblank)/timer? ($3e7) - $8-$40 = bg tilemaps (8 bytes each) : + $8-$3F = bg tilemaps (8 bytes each) : 0 - ? = usually 0/20/ba* 1 - 0 = disabled , !zero = address of tilemap in spriteram /$1000 (for example: 3 -> tilemap at $3000 ) 2 - ? = usually ff/1f/af* @@ -270,7 +270,7 @@ u8 st0016_cpu_device::vregs_r(offs_t offset) 6 - ? = 0 7 - ? =$20/$10/$12* - $40-$60 = scroll registers , X.w, Y.w + $40-$5F = scroll registers , X.w, Y.w */ switch (offset) @@ -299,27 +299,44 @@ void st0016_cpu_device::vregs_w(offs_t offset, u8 data) I/O ports: - $74 x--- ---- global flip screen - -xx- ---- individual flip screen x/y - i.e. Mayjinsen sets 0x80, other ST0016 games 0x60. - TODO: Might also be paired with $70 & $75 (setted up by Mayjinsen). - - $a0 \ - $a1 - source address >> 1 - $a2 / - - $a3 \ - $a4 - destination address >> 1 (inside character ram) - $a5 / - - $a6 \ - &a7 - (length inbytes - 1 ) >> 1 - - $a8 - 76543210 - ??faaaaa - - a - most sign. bits of length - f - DMA start latch + $60 \ + $61 - H sync start? + $62 \ + $63 - H visible start? + $64 \ + $65 - H visible end >> 1? + $66 \ + $67 - H total + $68 \ + $69 - V sync start? + $6a \ + $6b - V visible start? + $6c \ + $6d - V visible end? + $6e \ + $6f - V total + + $74 x--- ---- global flip screen + -xx- ---- individual flip screen x/y + i.e. Mayjinsen sets 0x80, other ST0016 games 0x60. + TODO: Might also be paired with $70 & $75 (setted up by Mayjinsen). + + $a0 \ + $a1 - source address >> 1 + $a2 / + + $a3 \ + $a4 - destination address >> 1 (inside character ram) + $a5 / + + $a6 \ + &a7 - (length inbytes - 1 ) >> 1 + + $a8 - 76543210 + ??faaaaa + + a - most sign. bits of length + f - DMA start latch */ diff --git a/src/mame/subsino/subsino2.cpp b/src/mame/subsino/subsino2.cpp index 44eeba32108..de8ddbc1083 100644 --- a/src/mame/subsino/subsino2.cpp +++ b/src/mame/subsino/subsino2.cpp @@ -2711,7 +2711,7 @@ static INPUT_PORTS_START( wtrnymph ) PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:4") PORT_DIPSETTING( 0x00, "5k" ) PORT_DIPSETTING( 0x08, "10k" ) - PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:6") + PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:5") PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW4:6") diff --git a/src/mame/tvgames/xavix.cpp b/src/mame/tvgames/xavix.cpp index bfdb4499314..44c075381a1 100644 --- a/src/mame/tvgames/xavix.cpp +++ b/src/mame/tvgames/xavix.cpp @@ -1636,7 +1636,7 @@ void xavix_hikara_state::machine_reset() for (int j = 0; j < 5; j++) { - u8 searchfor[5] = { 0x29, 0x80, 0xd0, 0x14, 0xad }; + constexpr u8 searchfor[5] = { 0x29, 0x80, 0xd0, 0x14, 0xad }; if (ROM[i + j] == searchfor[j]) matchcount++; diff --git a/src/mame/upl/ninjakd2.cpp b/src/mame/upl/ninjakd2.cpp index 597f31b84a6..c5608082571 100644 --- a/src/mame/upl/ninjakd2.cpp +++ b/src/mame/upl/ninjakd2.cpp @@ -161,9 +161,6 @@ Omega Fighter: #include "speaker.h" -#define MAIN_CLOCK_12 XTAL(12'000'000) -#define MAIN_CLOCK_5 XTAL(5'000'000) - /************************************* * @@ -261,7 +258,9 @@ uint8_t omegaf_state::io_protection_r(offs_t offset) switch (m_io_protection[0] & 0xe0) { case 0x00: - if (++m_io_protection_tick & 1) + if (!machine().side_effects_disabled()) + ++m_io_protection_tick; + if (m_io_protection_tick & 1) { result = 0x00; } @@ -347,12 +346,12 @@ void omegaf_state::io_protection_w(offs_t offset, uint8_t data) /*****************************************************************************/ -void ninjakd2_state::ninjakd2_bankselect_w(uint8_t data) +void ninjakd2_state::bankselect_w(uint8_t data) { m_mainbank->set_entry(data & m_rom_bank_mask); } -void ninjakd2_state::ninjakd2_soundreset_w(uint8_t data) +void ninjakd2_state::soundreset_w(uint8_t data) { // bit 4 resets sound CPU m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 0x10) ? ASSERT_LINE : CLEAR_LINE); @@ -409,32 +408,32 @@ uint8_t omegaf_state::unk_r() void ninjakd2_state::ninjakd2_main_cpu(address_map &map) { map(0x0000, 0x7fff).rom(); - map(0x8000, 0xbfff).bankr("mainbank"); + map(0x8000, 0xbfff).bankr(m_mainbank); map(0xc000, 0xc000).portr("KEYCOIN"); map(0xc001, 0xc001).portr("PAD1"); map(0xc002, 0xc002).portr("PAD2"); map(0xc003, 0xc003).portr("DIPSW1"); map(0xc004, 0xc004).portr("DIPSW2"); map(0xc200, 0xc200).w("soundlatch", FUNC(generic_latch_8_device::write)); - map(0xc201, 0xc201).w(FUNC(ninjakd2_state::ninjakd2_soundreset_w)); - map(0xc202, 0xc202).w(FUNC(ninjakd2_state::ninjakd2_bankselect_w)); - map(0xc203, 0xc203).w(FUNC(ninjakd2_state::ninjakd2_sprite_overdraw_w)); + map(0xc201, 0xc201).w(FUNC(ninjakd2_state::soundreset_w)); + map(0xc202, 0xc202).w(FUNC(ninjakd2_state::bankselect_w)); + map(0xc203, 0xc203).w(FUNC(ninjakd2_state::sprite_overdraw_w)); map(0xc208, 0xc20c).w(FUNC(ninjakd2_state::ninjakd2_bg_ctrl_w)); map(0xc800, 0xcdff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette"); - map(0xd000, 0xd7ff).ram().w(FUNC(ninjakd2_state::ninjakd2_fgvideoram_w)).share("fg_videoram"); + map(0xd000, 0xd7ff).ram().w(FUNC(ninjakd2_state::fgvideoram_w)).share("fg_videoram"); map(0xd800, 0xdfff).ram().w(FUNC(ninjakd2_state::ninjakd2_bgvideoram_w)).share("bg_videoram"); map(0xe000, 0xf9ff).ram(); - map(0xfa00, 0xffff).ram().share("spriteram"); + map(0xfa00, 0xffff).ram().share(m_spriteram); } void mnight_state::mnight_main_cpu(address_map &map) { map(0x0000, 0x7fff).rom(); - map(0x8000, 0xbfff).bankr("mainbank"); + map(0x8000, 0xbfff).bankr(m_mainbank); map(0xc000, 0xd9ff).ram(); - map(0xda00, 0xdfff).ram().share("spriteram"); + map(0xda00, 0xdfff).ram().share(m_spriteram); map(0xe000, 0xe7ff).ram().w(FUNC(mnight_state::ninjakd2_bgvideoram_w)).share("bg_videoram"); - map(0xe800, 0xefff).ram().w(FUNC(mnight_state::ninjakd2_fgvideoram_w)).share("fg_videoram"); + map(0xe800, 0xefff).ram().w(FUNC(mnight_state::fgvideoram_w)).share("fg_videoram"); map(0xf000, 0xf5ff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette"); map(0xf800, 0xf800).portr("KEYCOIN"); map(0xf801, 0xf801).portr("PAD1"); @@ -442,9 +441,9 @@ void mnight_state::mnight_main_cpu(address_map &map) map(0xf803, 0xf803).portr("DIPSW1"); map(0xf804, 0xf804).portr("DIPSW2"); map(0xfa00, 0xfa00).w("soundlatch", FUNC(generic_latch_8_device::write)); - map(0xfa01, 0xfa01).w(FUNC(mnight_state::ninjakd2_soundreset_w)); - map(0xfa02, 0xfa02).w(FUNC(mnight_state::ninjakd2_bankselect_w)); - map(0xfa03, 0xfa03).w(FUNC(mnight_state::ninjakd2_sprite_overdraw_w)); + map(0xfa01, 0xfa01).w(FUNC(mnight_state::soundreset_w)); + map(0xfa02, 0xfa02).w(FUNC(mnight_state::bankselect_w)); + map(0xfa03, 0xfa03).w(FUNC(mnight_state::sprite_overdraw_w)); map(0xfa08, 0xfa0c).w(FUNC(mnight_state::ninjakd2_bg_ctrl_w)); } @@ -452,16 +451,16 @@ void mnight_state::mnight_main_cpu(address_map &map) void robokid_state::robokid_main_cpu(address_map &map) { map(0x0000, 0x7fff).rom(); - map(0x8000, 0xbfff).bankr("mainbank"); + map(0x8000, 0xbfff).bankr(m_mainbank); map(0xc000, 0xc7ff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette"); - map(0xc800, 0xcfff).ram().w(FUNC(robokid_state::ninjakd2_fgvideoram_w)).share("fg_videoram"); + map(0xc800, 0xcfff).ram().w(FUNC(robokid_state::fgvideoram_w)).share("fg_videoram"); map(0xd000, 0xd3ff).rw(FUNC(robokid_state::robokid_bg_videoram_r<2>), FUNC(robokid_state::robokid_bg_videoram_w<2>)); // banked map(0xd400, 0xd7ff).rw(FUNC(robokid_state::robokid_bg_videoram_r<1>), FUNC(robokid_state::robokid_bg_videoram_w<1>)); // banked map(0xd800, 0xdbff).rw(FUNC(robokid_state::robokid_bg_videoram_r<0>), FUNC(robokid_state::robokid_bg_videoram_w<0>)); // banked map(0xdc00, 0xdc00).portr("KEYCOIN").w("soundlatch", FUNC(generic_latch_8_device::write)); - map(0xdc01, 0xdc01).portr("PAD1").w(FUNC(robokid_state::ninjakd2_soundreset_w)); - map(0xdc02, 0xdc02).portr("PAD2").w(FUNC(robokid_state::ninjakd2_bankselect_w)); - map(0xdc03, 0xdc03).portr("DIPSW1").w(FUNC(robokid_state::ninjakd2_sprite_overdraw_w)); + map(0xdc01, 0xdc01).portr("PAD1").w(FUNC(robokid_state::soundreset_w)); + map(0xdc02, 0xdc02).portr("PAD2").w(FUNC(robokid_state::bankselect_w)); + map(0xdc03, 0xdc03).portr("DIPSW1").w(FUNC(robokid_state::sprite_overdraw_w)); map(0xdc04, 0xdc04).portr("DIPSW2"); map(0xdd00, 0xdd04).w(FUNC(robokid_state::robokid_bg_ctrl_w<0>)); map(0xdd05, 0xdd05).w(FUNC(robokid_state::robokid_bg_bank_w<0>)); @@ -470,19 +469,19 @@ void robokid_state::robokid_main_cpu(address_map &map) map(0xdf00, 0xdf04).w(FUNC(robokid_state::robokid_bg_ctrl_w<2>)); map(0xdf05, 0xdf05).w(FUNC(robokid_state::robokid_bg_bank_w<2>)); map(0xe000, 0xf9ff).ram(); - map(0xfa00, 0xffff).ram().share("spriteram"); + map(0xfa00, 0xffff).ram().share(m_spriteram); } void omegaf_state::omegaf_main_cpu(address_map &map) { map(0x0000, 0x7fff).rom(); - map(0x8000, 0xbfff).bankr("mainbank"); + map(0x8000, 0xbfff).bankr(m_mainbank); map(0xc000, 0xc000).portr("KEYCOIN").w("soundlatch", FUNC(generic_latch_8_device::write)); map(0xc001, 0xc003).r(FUNC(omegaf_state::io_protection_r)); - map(0xc001, 0xc001).w(FUNC(omegaf_state::ninjakd2_soundreset_w)); - map(0xc002, 0xc002).w(FUNC(omegaf_state::ninjakd2_bankselect_w)); - map(0xc003, 0xc003).w(FUNC(omegaf_state::ninjakd2_sprite_overdraw_w)); + map(0xc001, 0xc001).w(FUNC(omegaf_state::soundreset_w)); + map(0xc002, 0xc002).w(FUNC(omegaf_state::bankselect_w)); + map(0xc003, 0xc003).w(FUNC(omegaf_state::sprite_overdraw_w)); map(0xc004, 0xc006).w(FUNC(omegaf_state::io_protection_w)); map(0xc100, 0xc104).w(FUNC(omegaf_state::robokid_bg_ctrl_w<0>)); map(0xc105, 0xc105).w(FUNC(omegaf_state::robokid_bg_bank_w<0>)); @@ -494,10 +493,10 @@ void omegaf_state::omegaf_main_cpu(address_map &map) map(0xc400, 0xc7ff).rw(FUNC(omegaf_state::robokid_bg_videoram_r<0>), FUNC(omegaf_state::robokid_bg_videoram_w<0>)); // banked map(0xc800, 0xcbff).rw(FUNC(omegaf_state::robokid_bg_videoram_r<1>), FUNC(omegaf_state::robokid_bg_videoram_w<1>)); // banked map(0xcc00, 0xcfff).rw(FUNC(omegaf_state::robokid_bg_videoram_r<2>), FUNC(omegaf_state::robokid_bg_videoram_w<2>)); // banked - map(0xd000, 0xd7ff).ram().w(FUNC(omegaf_state::ninjakd2_fgvideoram_w)).share("fg_videoram"); + map(0xd000, 0xd7ff).ram().w(FUNC(omegaf_state::fgvideoram_w)).share("fg_videoram"); map(0xd800, 0xdfff).ram().w(m_palette, FUNC(palette_device::write8)).share("palette"); map(0xe000, 0xf9ff).ram(); - map(0xfa00, 0xffff).ram().share("spriteram"); + map(0xfa00, 0xffff).ram().share(m_spriteram); } @@ -521,7 +520,7 @@ void ninjakd2_state::ninjakid_nopcm_sound_cpu(address_map &map) void ninjakd2_state::decrypted_opcodes_map(address_map &map) { - map(0x0000, 0x7fff).rom().share("decrypted_opcodes"); + map(0x0000, 0x7fff).rom().share(m_decrypted_opcodes); map(0x8000, 0xbfff).rom().region("soundcpu", 0x8000); } @@ -546,7 +545,7 @@ static INPUT_PORTS_START( common ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) /* keep pressed during boot to enter service mode */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) // keep pressed during boot to enter service mode PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 ) @@ -578,7 +577,7 @@ static INPUT_PORTS_START( common_2p ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) /* keep pressed during boot to enter service mode */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SERVICE ) // keep pressed during boot to enter service mode PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 ) @@ -881,17 +880,17 @@ INPUT_PORTS_END *************************************/ static GFXDECODE_START( gfx_ninjakd2 ) - GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_packed_msb, 0x200, 16) // fg - GFXDECODE_ENTRY( "gfx2", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0x100, 16) // sprites - GFXDECODE_ENTRY( "gfx3", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0x000, 16) // bg + GFXDECODE_ENTRY( "chars", 0, gfx_8x8x4_packed_msb, 0x200, 16) // fg + GFXDECODE_ENTRY( "sprites", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0x100, 16) // sprites + GFXDECODE_ENTRY( "tiles1", 0, gfx_8x8x4_row_2x2_group_packed_msb, 0x000, 16) // bg GFXDECODE_END static GFXDECODE_START( gfx_robokid ) - GFXDECODE_ENTRY( "gfx1", 0, gfx_8x8x4_packed_msb, 0x300, 16) // fg - GFXDECODE_ENTRY( "gfx2", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x200, 16) // sprites - GFXDECODE_ENTRY( "gfx3", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x000, 16) // bg0 - GFXDECODE_ENTRY( "gfx4", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x000, 16) // bg1 - GFXDECODE_ENTRY( "gfx5", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x000, 16) // bg2 + GFXDECODE_ENTRY( "chars", 0, gfx_8x8x4_packed_msb, 0x300, 16) // fg + GFXDECODE_ENTRY( "sprites", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x200, 16) // sprites + GFXDECODE_ENTRY( "tiles1", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x000, 16) // bg0 + GFXDECODE_ENTRY( "tiles2", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x000, 16) // bg1 + GFXDECODE_ENTRY( "tiles3", 0, gfx_8x8x4_col_2x2_group_packed_msb, 0x000, 16) // bg2 GFXDECODE_END @@ -903,8 +902,8 @@ GFXDECODE_END void ninjakd2_state::machine_start() { - /* initialize main Z80 bank */ - int num_banks = (memregion("maincpu")->bytes() - 0x10000) / 0x4000; + // initialize main Z80 bank + int const num_banks = (memregion("maincpu")->bytes() - 0x10000) / 0x4000; m_mainbank->configure_entries(0, num_banks, memregion("maincpu")->base() + 0x10000, 0x4000); // ... @@ -932,42 +931,45 @@ void omegaf_state::machine_reset() /*****************************************************************************/ +static constexpr XTAL MAIN_CLOCK_12 = XTAL(12'000'000); +static constexpr XTAL MAIN_CLOCK_5 = XTAL(5'000'000); + void ninjakd2_state::ninjakd2_core(machine_config &config) { - /* basic machine hardware */ - Z80(config, m_maincpu, MAIN_CLOCK_12/2); /* verified */ + // basic machine hardware + Z80(config, m_maincpu, MAIN_CLOCK_12/2); // verified m_maincpu->set_addrmap(AS_PROGRAM, &ninjakd2_state::ninjakd2_main_cpu); - Z80(config, m_soundcpu, MAIN_CLOCK_5); /* verified */ + Z80(config, m_soundcpu, MAIN_CLOCK_5); // verified m_soundcpu->set_addrmap(AS_PROGRAM, &ninjakd2_state::ninjakd2_sound_cpu); m_soundcpu->set_addrmap(AS_IO, &ninjakd2_state::ninjakd2_sound_io); - /* video hardware */ + // video hardware SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(59.61); /* verified on pcb */ + m_screen->set_refresh_hz(59.61); // verified on pcb m_screen->set_size(32*8, 32*8); m_screen->set_visarea(0*8, 32*8-1, 4*8, 28*8-1); m_screen->set_screen_update(FUNC(ninjakd2_state::screen_update_ninjakd2)); - m_screen->screen_vblank().set(FUNC(ninjakd2_state::screen_vblank_ninjakd2)); + m_screen->screen_vblank().set(FUNC(ninjakd2_state::screen_vblank)); m_screen->set_palette(m_palette); GFXDECODE(config, m_gfxdecode, m_palette, gfx_ninjakd2); PALETTE(config, m_palette).set_format(palette_device::RGBx_444, 0x300); m_palette->set_endianness(ENDIANNESS_BIG); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); GENERIC_LATCH_8(config, "soundlatch"); - ym2203_device &ym2203_1(YM2203(config, "2203.1", MAIN_CLOCK_12/8)); /* verified */ + ym2203_device &ym2203_1(YM2203(config, "2203.1", MAIN_CLOCK_12/8)); // verified ym2203_1.irq_handler().set_inputline("soundcpu", 0); ym2203_1.add_route(0, "mono", 0.10); ym2203_1.add_route(1, "mono", 0.10); ym2203_1.add_route(2, "mono", 0.10); ym2203_1.add_route(3, "mono", 0.50); - ym2203_device &ym2203_2(YM2203(config, "2203.2", MAIN_CLOCK_12/8)); /* verified */ + ym2203_device &ym2203_2(YM2203(config, "2203.2", MAIN_CLOCK_12/8)); // verified ym2203_2.add_route(0, "mono", 0.10); ym2203_2.add_route(1, "mono", 0.10); ym2203_2.add_route(2, "mono", 0.10); @@ -982,7 +984,7 @@ void ninjakd2_state::ninjakd2_core(machine_config &config) void ninjakd2_state::ninjakd2(machine_config &config) { ninjakd2_core(config); - MC8123(config.replace(), m_soundcpu, MAIN_CLOCK_5); /* verified */ + MC8123(config.replace(), m_soundcpu, MAIN_CLOCK_5); // verified m_soundcpu->set_addrmap(AS_PROGRAM, &ninjakd2_state::ninjakd2_sound_cpu); m_soundcpu->set_addrmap(AS_IO, &ninjakd2_state::ninjakd2_sound_io); m_soundcpu->set_addrmap(AS_OPCODES, &ninjakd2_state::decrypted_opcodes_map); @@ -999,14 +1001,14 @@ void mnight_state::mnight(machine_config &config) { ninjakd2_core(config); - /* basic machine hardware */ + // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &mnight_state::mnight_main_cpu); m_soundcpu->set_addrmap(AS_PROGRAM, &mnight_state::ninjakid_nopcm_sound_cpu); - /* video hardware */ + // video hardware MCFG_VIDEO_START_OVERRIDE(mnight_state,mnight) - /* sound hardware */ + // sound hardware config.device_remove("pcm"); } @@ -1014,7 +1016,7 @@ void mnight_state::arkarea(machine_config &config) { mnight(config); - /* video hardware */ + // video hardware MCFG_VIDEO_START_OVERRIDE(mnight_state,arkarea) } @@ -1022,13 +1024,13 @@ void robokid_state::robokid(machine_config &config) { mnight(config); - /* basic machine hardware */ + // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &robokid_state::robokid_main_cpu); m_soundcpu->set_addrmap(AS_PROGRAM, &robokid_state::ninjakid_nopcm_sound_cpu); - /* video hardware */ + // video hardware m_gfxdecode->set_info(gfx_robokid); - m_palette->set_format(palette_device::RGBx_444, 0x400); // RAM is this large, but still only 0x300 colors used + m_palette->set_format(palette_device::RRRRGGGGBBBBRGBx, 0x400); // RAM is this large, but still only 0x300 colors used m_palette->set_endianness(ENDIANNESS_BIG); MCFG_VIDEO_START_OVERRIDE(robokid_state,robokid) @@ -1040,12 +1042,12 @@ void omegaf_state::omegaf(machine_config &config) { robokid(config); - /* basic machine hardware */ + // basic machine hardware m_maincpu->set_addrmap(AS_PROGRAM, &omegaf_state::omegaf_main_cpu); m_soundcpu->set_addrmap(AS_PROGRAM, &omegaf_state::ninjakid_nopcm_sound_cpu); - /* video hardware */ + // video hardware MCFG_VIDEO_START_OVERRIDE(omegaf_state,omegaf) m_screen->set_screen_update(FUNC(omegaf_state::screen_update_omegaf)); @@ -1070,17 +1072,17 @@ ROM_START( ninjakd2 ) ROM_REGION( 0x10000, "soundcpu", 0 ) // NEC MC-8123 custom CPU block ROM_LOAD( "6.3h", 0x0000, 0x10000, CRC(d3a18a79) SHA1(e4df713f89d8a8b43ef831b14864c50ec9b53f0b) ) // encrypted - ROM_REGION( 0x2000, "soundcpu:key", 0 ) /* MC8123 key */ + ROM_REGION( 0x2000, "soundcpu:key", 0 ) // MC8123 key ROM_LOAD( "ninjakd2.key", 0x0000, 0x2000, CRC(ec25318f) SHA1(619da3f69f9919e1457f79ee1d38e7ec80c4ebb0) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "12.5n", 0x00000, 0x08000, CRC(db5657a9) SHA1(abbb033edb9a5a0c66ee5981d1e4df1ab334a82d) ) - ROM_REGION( 0x20000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x20000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "8.6l", 0x00000, 0x10000, CRC(1b79c50a) SHA1(8954bc51cb9fbbe16b09381f35c84ccc56a803f3) ) ROM_LOAD( "7.6n", 0x10000, 0x10000, CRC(0be5cd13) SHA1(8f94a8fef6668aaf13329715fee81302dbd6c685) ) - ROM_REGION( 0x20000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x20000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "11.2n", 0x00000, 0x10000, CRC(41a714b3) SHA1(b05f48d71a9837914c12c13e0b479c8a6dc8c25e) ) ROM_LOAD( "10.2r", 0x10000, 0x10000, CRC(c913c4ab) SHA1(f822c5621b3e32c1a284f6367bdcace81c1c74b3) ) @@ -1100,14 +1102,14 @@ ROM_START( ninjakd2a ) ROM_LOAD( "nk2_06.bin", 0x10000, 0x8000, CRC(7bfe6c9e) SHA1(aef8cbeb0024939bf65f77113a5cf777f6613722) ) // decrypted opcodes ROM_CONTINUE( 0x00000, 0x8000 ) // decrypted data - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "12.5n", 0x00000, 0x08000, CRC(db5657a9) SHA1(abbb033edb9a5a0c66ee5981d1e4df1ab334a82d) ) - ROM_REGION( 0x20000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x20000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "8.6l", 0x00000, 0x10000, CRC(1b79c50a) SHA1(8954bc51cb9fbbe16b09381f35c84ccc56a803f3) ) ROM_LOAD( "7.6n", 0x10000, 0x10000, CRC(0be5cd13) SHA1(8f94a8fef6668aaf13329715fee81302dbd6c685) ) - ROM_REGION( 0x20000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x20000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "11.2n", 0x00000, 0x10000, CRC(41a714b3) SHA1(b05f48d71a9837914c12c13e0b479c8a6dc8c25e) ) ROM_LOAD( "10.2r", 0x10000, 0x10000, CRC(c913c4ab) SHA1(f822c5621b3e32c1a284f6367bdcace81c1c74b3) ) @@ -1127,14 +1129,14 @@ ROM_START( ninjakd2b ) ROM_LOAD( "nk2_06.bin", 0x10000, 0x8000, CRC(7bfe6c9e) SHA1(aef8cbeb0024939bf65f77113a5cf777f6613722) ) // 6.3g decrypted opcodes ROM_CONTINUE( 0x00000, 0x8000 ) // decrypted data - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "12.5n", 0x00000, 0x08000, CRC(db5657a9) SHA1(abbb033edb9a5a0c66ee5981d1e4df1ab334a82d) ) - ROM_REGION( 0x20000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x20000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "8.6l", 0x00000, 0x10000, CRC(1b79c50a) SHA1(8954bc51cb9fbbe16b09381f35c84ccc56a803f3) ) ROM_LOAD( "7.6n", 0x10000, 0x10000, CRC(0be5cd13) SHA1(8f94a8fef6668aaf13329715fee81302dbd6c685) ) - ROM_REGION( 0x20000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x20000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "11.2n", 0x00000, 0x10000, CRC(41a714b3) SHA1(b05f48d71a9837914c12c13e0b479c8a6dc8c25e) ) ROM_LOAD( "10.2r", 0x10000, 0x10000, CRC(c913c4ab) SHA1(f822c5621b3e32c1a284f6367bdcace81c1c74b3) ) @@ -1153,17 +1155,17 @@ ROM_START( ninjakd2c ) ROM_REGION( 0x10000, "soundcpu", 0 ) // NEC MC-8123 custom CPU block ROM_LOAD( "6.3h", 0x0000, 0x10000, CRC(d3a18a79) SHA1(e4df713f89d8a8b43ef831b14864c50ec9b53f0b) ) // encrypted - ROM_REGION( 0x2000, "soundcpu:key", 0 ) /* MC8123 key */ + ROM_REGION( 0x2000, "soundcpu:key", 0 ) // MC8123 key ROM_LOAD( "ninjakd2.key", 0x0000, 0x2000, CRC(ec25318f) SHA1(619da3f69f9919e1457f79ee1d38e7ec80c4ebb0) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "12.5n", 0x00000, 0x08000, CRC(db5657a9) SHA1(abbb033edb9a5a0c66ee5981d1e4df1ab334a82d) ) - ROM_REGION( 0x20000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x20000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "8.6l", 0x00000, 0x10000, CRC(1b79c50a) SHA1(8954bc51cb9fbbe16b09381f35c84ccc56a803f3) ) ROM_LOAD( "7.6n", 0x10000, 0x10000, CRC(0be5cd13) SHA1(8f94a8fef6668aaf13329715fee81302dbd6c685) ) - ROM_REGION( 0x20000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x20000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "11.2n", 0x00000, 0x10000, CRC(41a714b3) SHA1(b05f48d71a9837914c12c13e0b479c8a6dc8c25e) ) ROM_LOAD( "10.2r", 0x10000, 0x10000, CRC(c913c4ab) SHA1(f822c5621b3e32c1a284f6367bdcace81c1c74b3) ) @@ -1182,17 +1184,17 @@ ROM_START( rdaction ) ROM_REGION( 0x10000, "soundcpu", 0 ) // NEC MC-8123 custom CPU block ROM_LOAD( "6.3h", 0x0000, 0x10000, CRC(d3a18a79) SHA1(e4df713f89d8a8b43ef831b14864c50ec9b53f0b) ) // encrypted - ROM_REGION( 0x2000, "soundcpu:key", 0 ) /* MC8123 key */ + ROM_REGION( 0x2000, "soundcpu:key", 0 ) // MC8123 key ROM_LOAD( "ninjakd2.key", 0x0000, 0x2000, CRC(ec25318f) SHA1(619da3f69f9919e1457f79ee1d38e7ec80c4ebb0) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "12.5n", 0x00000, 0x08000, CRC(0936b365) SHA1(3705f42b76ab474357e77c1a9b8e3755c7ab2c0c) ) // sldh - this rom contains the new title / license - ROM_REGION( 0x20000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x20000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "8.6l", 0x00000, 0x10000, CRC(1b79c50a) SHA1(8954bc51cb9fbbe16b09381f35c84ccc56a803f3) ) ROM_LOAD( "7.6n", 0x10000, 0x10000, CRC(0be5cd13) SHA1(8f94a8fef6668aaf13329715fee81302dbd6c685) ) - ROM_REGION( 0x20000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x20000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "11.2n", 0x00000, 0x10000, CRC(41a714b3) SHA1(b05f48d71a9837914c12c13e0b479c8a6dc8c25e) ) ROM_LOAD( "10.2r", 0x10000, 0x10000, CRC(c913c4ab) SHA1(f822c5621b3e32c1a284f6367bdcace81c1c74b3) ) @@ -1213,17 +1215,17 @@ ROM_START( jt104 ) ROM_REGION( 0x10000, "soundcpu", 0 ) // NEC MC-8123 custom CPU block ROM_LOAD( "6.3h", 0x0000, 0x10000, CRC(d3a18a79) SHA1(e4df713f89d8a8b43ef831b14864c50ec9b53f0b) ) // encrypted - ROM_REGION( 0x2000, "soundcpu:key", 0 ) /* MC8123 key */ + ROM_REGION( 0x2000, "soundcpu:key", 0 ) // MC8123 key ROM_LOAD( "ninjakd2.key", 0x0000, 0x2000, CRC(ec25318f) SHA1(619da3f69f9919e1457f79ee1d38e7ec80c4ebb0) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "12.5n", 0x00000, 0x08000, CRC(c038fadb) SHA1(59e9b125ead3e9bdc9d66de75dffd58956eb922e) ) // sldh - this rom contains the new title / license - ROM_REGION( 0x20000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x20000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "8.6l", 0x00000, 0x10000, CRC(1b79c50a) SHA1(8954bc51cb9fbbe16b09381f35c84ccc56a803f3) ) ROM_LOAD( "7.6n", 0x10000, 0x10000, CRC(0be5cd13) SHA1(8f94a8fef6668aaf13329715fee81302dbd6c685) ) - ROM_REGION( 0x20000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x20000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "11.2n", 0x00000, 0x10000, CRC(41a714b3) SHA1(b05f48d71a9837914c12c13e0b479c8a6dc8c25e) ) ROM_LOAD( "10.2r", 0x10000, 0x10000, CRC(c913c4ab) SHA1(f822c5621b3e32c1a284f6367bdcace81c1c74b3) ) @@ -1243,15 +1245,15 @@ ROM_START( mnight ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "6.j7", 0x00000, 0x10000, CRC(a0782a31) SHA1(8abd2f0b0c2c2eb876f324f7a095a5cdc773c187) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "13.b10", 0x00000, 0x08000, CRC(8c177a19) SHA1(328df41b5bacd1999f97d99781c6ef8afc9989a3) ) - ROM_REGION( 0x30000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x30000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "9.e11", 0x00000, 0x10000, CRC(4883059c) SHA1(53d4b9b0f0725c25e302ee1549a306778ec74d85) ) ROM_LOAD( "8.e12", 0x10000, 0x10000, CRC(02b91445) SHA1(f0cf85f9e17c40248de16bca8df6d745e359b92d) ) ROM_LOAD( "7.e14", 0x20000, 0x10000, CRC(9f08d160) SHA1(1a0041ad138e7e6598d4d03d7cbd52a7244557ac) ) - ROM_REGION( 0x30000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x30000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "12.b20", 0x00000, 0x10000, CRC(4d37e0f4) SHA1(a6d9aaccd97769197622cda45474e223c2ee1d98) ) ROM_LOAD( "11.b22", 0x10000, 0x10000, CRC(b22cbbd3) SHA1(70984f1051fd236730d97011bc87dacb3ca38594) ) ROM_LOAD( "10.b23", 0x20000, 0x10000, CRC(65714070) SHA1(48f3c130c97d00e8f0535904dc2237277067c475) ) @@ -1268,15 +1270,15 @@ ROM_START( mnightj ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "6.j7", 0x00000, 0x10000, CRC(a0782a31) SHA1(8abd2f0b0c2c2eb876f324f7a095a5cdc773c187) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "13.b10", 0x00000, 0x08000, CRC(37b8221f) SHA1(ac86e0ae8039fd30a028a893d08ce099f7765615) ) - ROM_REGION( 0x30000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x30000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "9.e11", 0x00000, 0x10000, CRC(4883059c) SHA1(53d4b9b0f0725c25e302ee1549a306778ec74d85) ) ROM_LOAD( "8.e12", 0x10000, 0x10000, CRC(02b91445) SHA1(f0cf85f9e17c40248de16bca8df6d745e359b92d) ) ROM_LOAD( "7.e14", 0x20000, 0x10000, CRC(9f08d160) SHA1(1a0041ad138e7e6598d4d03d7cbd52a7244557ac) ) - ROM_REGION( 0x30000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x30000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "12.b20", 0x00000, 0x10000, CRC(4d37e0f4) SHA1(a6d9aaccd97769197622cda45474e223c2ee1d98) ) ROM_LOAD( "11.b22", 0x10000, 0x10000, CRC(b22cbbd3) SHA1(70984f1051fd236730d97011bc87dacb3ca38594) ) ROM_LOAD( "10.b23", 0x20000, 0x10000, CRC(65714070) SHA1(48f3c130c97d00e8f0535904dc2237277067c475) ) @@ -1293,15 +1295,15 @@ ROM_START( arkarea ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "arkarea.013", 0x00000, 0x8000, CRC(2d409d58) SHA1(6344b43db5459691728c3f843b643c84ea71dd8e) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles (need lineswapping) + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles (need lineswapping) ROM_LOAD( "arkarea.004", 0x00000, 0x08000, CRC(69e36af2) SHA1(2bccef8f396dcb5261af0140af04c95ee8ecae11) ) - ROM_REGION( 0x30000, "gfx2", 0 ) // sprites (need lineswapping) + ROM_REGION( 0x30000, "sprites", 0 ) // sprites (need lineswapping) ROM_LOAD( "arkarea.007", 0x00000, 0x10000, CRC(d5684a27) SHA1(4961e8a5df2510afb1ef3e937d0a5d52e91893a3) ) ROM_LOAD( "arkarea.006", 0x10000, 0x10000, CRC(2c0567d6) SHA1(f36a2a3ff487660f89470516617482331f008da0) ) ROM_LOAD( "arkarea.005", 0x20000, 0x10000, CRC(9886004d) SHA1(4050756af5c00ab1a368780fe091460fd9e2cb05) ) - ROM_REGION( 0x30000, "gfx3", 0 ) // bg tiles (need lineswapping) + ROM_REGION( 0x30000, "tiles1", 0 ) // bg tiles (need lineswapping) ROM_LOAD( "arkarea.003", 0x00000, 0x10000, CRC(6f45a308) SHA1(b6994fe1f50d5e9cf38d3efbd69a2c5f76f33c56) ) ROM_LOAD( "arkarea.002", 0x10000, 0x10000, CRC(051d3482) SHA1(3ebef1a7280f52df6d5ee34e3d4e7567aac0c165) ) ROM_LOAD( "arkarea.001", 0x20000, 0x10000, CRC(09d11ab7) SHA1(14f68e93e7173069f790493eafe9e1adc1a074cc) ) @@ -1325,16 +1327,16 @@ ROM_START( robokid ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "robokid.k7", 0x00000, 0x10000, CRC(f490a2e9) SHA1(861d1256c090ce3d1f45f95cc894affbbc3f1466) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles ROM_LOAD( "robokid.b9", 0x00000, 0x08000, CRC(fac59c3f) SHA1(1b202ad5c12982512129d9e097267dd31b984ae8) ) - ROM_REGION( 0x40000, "gfx2", 0 ) // sprite tiles + ROM_REGION( 0x40000, "sprites", 0 ) // sprite tiles ROM_LOAD( "robokid.15f", 0x00000, 0x10000, CRC(ba61f5ab) SHA1(8433ddd55f0184cd5e8bb4a94a1c2336b2f8ff05) ) ROM_LOAD( "robokid.16f", 0x10000, 0x10000, CRC(d9b399ce) SHA1(70755c9cae27187f183ae6d61bedb95c420756f4) ) ROM_LOAD( "robokid.17f", 0x20000, 0x10000, CRC(afe432b9) SHA1(1ec7954ccf112eddf0ffcb8b5aec6cbc5cba7a7a) ) ROM_LOAD( "robokid.18f", 0x30000, 0x10000, CRC(a0aa2a84) SHA1(4d46c169429cd285644336c7d47e393b33bd8770) ) - ROM_REGION( 0x80000, "gfx3", 0 ) // bg0 tiles + ROM_REGION( 0x80000, "tiles1", 0 ) // bg0 tiles ROM_LOAD( "robokid.19c", 0x00000, 0x10000, CRC(02220421) SHA1(f533e9c6cea1dccbb60e0528c470f3cb5e8fc44e) ) ROM_LOAD( "robokid.20c", 0x10000, 0x10000, CRC(02d59bc2) SHA1(031acbb14145f9f4623de8868c6207fb9f8e8207) ) ROM_LOAD( "robokid.17d", 0x20000, 0x10000, CRC(2fa29b99) SHA1(13dce7932e2e9c03a139a4293584838aa3d9f1c3) ) @@ -1343,7 +1345,7 @@ ROM_START( robokid ) ROM_LOAD( "robokid.20d", 0x50000, 0x10000, CRC(b0b395ed) SHA1(31ec07634053793a701bbfd601b029f7da66e9d7) ) ROM_LOAD( "robokid.19f", 0x60000, 0x10000, CRC(0f9071c6) SHA1(8bf0c35189eda98a9bc150788890e136870cb5b2) ) - ROM_REGION( 0x80000, "gfx4", 0 ) // bg1 tiles + ROM_REGION( 0x80000, "tiles2", 0 ) // bg1 tiles ROM_LOAD( "robokid.12c", 0x00000, 0x10000, CRC(0ab45f94) SHA1(d8274263068d998c89a1b247dde7f814037cc15b) ) ROM_LOAD( "robokid.14c", 0x10000, 0x10000, CRC(029bbd4a) SHA1(8e078cdafe608fc6cde827be85c5267ade4ecca6) ) ROM_LOAD( "robokid.15c", 0x20000, 0x10000, CRC(7de67ebb) SHA1(2fe92e50e2894dd363e69b053db96bdb66a273eb) ) @@ -1353,7 +1355,7 @@ ROM_START( robokid ) ROM_LOAD( "robokid.15d", 0x60000, 0x10000, CRC(cd632a4d) SHA1(a537d9ced45fdac490097e9162ac4d09a470be79) ) ROM_LOAD( "robokid.16d", 0x70000, 0x10000, CRC(18d92b2b) SHA1(e6d20ea8f0fac8bd4824a3b279a0fd8a1d6c26f5) ) - ROM_REGION( 0x80000, "gfx5", 0 ) // bg2 tiles + ROM_REGION( 0x80000, "tiles3", 0 ) // bg2 tiles ROM_LOAD( "robokid.12a", 0x00000, 0x10000, CRC(e64d1c10) SHA1(d1073c80c9788aba65410f88691747a37b2a9d4a) ) ROM_LOAD( "robokid.14a", 0x10000, 0x10000, CRC(8f9371e4) SHA1(0ea06d62bf4673ebda49a849cead832a24e5b886) ) ROM_LOAD( "robokid.15a", 0x20000, 0x10000, CRC(469204e7) SHA1(8c2e94635b2b304e7dfa2e6ad58ba526dcf02453) ) @@ -1379,16 +1381,16 @@ ROM_START( robokidj3 ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "robokid.k7", 0x00000, 0x10000, CRC(f490a2e9) SHA1(861d1256c090ce3d1f45f95cc894affbbc3f1466) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles ROM_LOAD( "robokid.b9", 0x00000, 0x08000, CRC(fac59c3f) SHA1(1b202ad5c12982512129d9e097267dd31b984ae8) ) - ROM_REGION( 0x40000, "gfx2", 0 ) // sprite tiles + ROM_REGION( 0x40000, "sprites", 0 ) // sprite tiles ROM_LOAD( "robokid.15f", 0x00000, 0x10000, CRC(ba61f5ab) SHA1(8433ddd55f0184cd5e8bb4a94a1c2336b2f8ff05) ) ROM_LOAD( "robokid.16f", 0x10000, 0x10000, CRC(d9b399ce) SHA1(70755c9cae27187f183ae6d61bedb95c420756f4) ) ROM_LOAD( "robokid.17f", 0x20000, 0x10000, CRC(afe432b9) SHA1(1ec7954ccf112eddf0ffcb8b5aec6cbc5cba7a7a) ) ROM_LOAD( "robokid.18f", 0x30000, 0x10000, CRC(a0aa2a84) SHA1(4d46c169429cd285644336c7d47e393b33bd8770) ) - ROM_REGION( 0x80000, "gfx3", 0 ) // bg0 tiles + ROM_REGION( 0x80000, "tiles1", 0 ) // bg0 tiles ROM_LOAD( "robokid.19c", 0x00000, 0x10000, CRC(02220421) SHA1(f533e9c6cea1dccbb60e0528c470f3cb5e8fc44e) ) ROM_LOAD( "robokid.20c", 0x10000, 0x10000, CRC(02d59bc2) SHA1(031acbb14145f9f4623de8868c6207fb9f8e8207) ) ROM_LOAD( "robokid.17d", 0x20000, 0x10000, CRC(2fa29b99) SHA1(13dce7932e2e9c03a139a4293584838aa3d9f1c3) ) @@ -1397,7 +1399,7 @@ ROM_START( robokidj3 ) ROM_LOAD( "robokid.20d", 0x50000, 0x10000, CRC(b0b395ed) SHA1(31ec07634053793a701bbfd601b029f7da66e9d7) ) ROM_LOAD( "robokid.19f", 0x60000, 0x10000, CRC(0f9071c6) SHA1(8bf0c35189eda98a9bc150788890e136870cb5b2) ) - ROM_REGION( 0x80000, "gfx4", 0 ) // bg1 tiles + ROM_REGION( 0x80000, "tiles2", 0 ) // bg1 tiles ROM_LOAD( "robokid.12c", 0x00000, 0x10000, CRC(0ab45f94) SHA1(d8274263068d998c89a1b247dde7f814037cc15b) ) ROM_LOAD( "robokid.14c", 0x10000, 0x10000, CRC(029bbd4a) SHA1(8e078cdafe608fc6cde827be85c5267ade4ecca6) ) ROM_LOAD( "robokid.15c", 0x20000, 0x10000, CRC(7de67ebb) SHA1(2fe92e50e2894dd363e69b053db96bdb66a273eb) ) @@ -1407,7 +1409,7 @@ ROM_START( robokidj3 ) ROM_LOAD( "robokid.15d", 0x60000, 0x10000, CRC(cd632a4d) SHA1(a537d9ced45fdac490097e9162ac4d09a470be79) ) ROM_LOAD( "robokid.16d", 0x70000, 0x10000, CRC(18d92b2b) SHA1(e6d20ea8f0fac8bd4824a3b279a0fd8a1d6c26f5) ) - ROM_REGION( 0x80000, "gfx5", 0 ) // bg2 tiles + ROM_REGION( 0x80000, "tiles3", 0 ) // bg2 tiles ROM_LOAD( "robokid.12a", 0x00000, 0x10000, CRC(e64d1c10) SHA1(d1073c80c9788aba65410f88691747a37b2a9d4a) ) ROM_LOAD( "robokid.14a", 0x10000, 0x10000, CRC(8f9371e4) SHA1(0ea06d62bf4673ebda49a849cead832a24e5b886) ) ROM_LOAD( "robokid.15a", 0x20000, 0x10000, CRC(469204e7) SHA1(8c2e94635b2b304e7dfa2e6ad58ba526dcf02453) ) @@ -1433,16 +1435,16 @@ ROM_START( robokidj ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "robokid.k7", 0x00000, 0x10000, CRC(f490a2e9) SHA1(861d1256c090ce3d1f45f95cc894affbbc3f1466) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles ROM_LOAD( "robokid.b9", 0x00000, 0x08000, CRC(fac59c3f) SHA1(1b202ad5c12982512129d9e097267dd31b984ae8) ) - ROM_REGION( 0x40000, "gfx2", 0 ) // sprite tiles + ROM_REGION( 0x40000, "sprites", 0 ) // sprite tiles ROM_LOAD( "robokid.15f", 0x00000, 0x10000, CRC(ba61f5ab) SHA1(8433ddd55f0184cd5e8bb4a94a1c2336b2f8ff05) ) ROM_LOAD( "robokid.16f", 0x10000, 0x10000, CRC(d9b399ce) SHA1(70755c9cae27187f183ae6d61bedb95c420756f4) ) ROM_LOAD( "robokid.17f", 0x20000, 0x10000, CRC(afe432b9) SHA1(1ec7954ccf112eddf0ffcb8b5aec6cbc5cba7a7a) ) ROM_LOAD( "robokid.18f", 0x30000, 0x10000, CRC(a0aa2a84) SHA1(4d46c169429cd285644336c7d47e393b33bd8770) ) - ROM_REGION( 0x80000, "gfx3", 0 ) // bg0 tiles + ROM_REGION( 0x80000, "tiles1", 0 ) // bg0 tiles ROM_LOAD( "robokid.19c", 0x00000, 0x10000, CRC(02220421) SHA1(f533e9c6cea1dccbb60e0528c470f3cb5e8fc44e) ) ROM_LOAD( "robokid.20c", 0x10000, 0x10000, CRC(02d59bc2) SHA1(031acbb14145f9f4623de8868c6207fb9f8e8207) ) ROM_LOAD( "robokid.17d", 0x20000, 0x10000, CRC(2fa29b99) SHA1(13dce7932e2e9c03a139a4293584838aa3d9f1c3) ) @@ -1451,7 +1453,7 @@ ROM_START( robokidj ) ROM_LOAD( "robokid.20d", 0x50000, 0x10000, CRC(b0b395ed) SHA1(31ec07634053793a701bbfd601b029f7da66e9d7) ) ROM_LOAD( "robokid.19f", 0x60000, 0x10000, CRC(0f9071c6) SHA1(8bf0c35189eda98a9bc150788890e136870cb5b2) ) - ROM_REGION( 0x80000, "gfx4", 0 ) // bg1 tiles + ROM_REGION( 0x80000, "tiles2", 0 ) // bg1 tiles ROM_LOAD( "robokid.12c", 0x00000, 0x10000, CRC(0ab45f94) SHA1(d8274263068d998c89a1b247dde7f814037cc15b) ) ROM_LOAD( "robokid.14c", 0x10000, 0x10000, CRC(029bbd4a) SHA1(8e078cdafe608fc6cde827be85c5267ade4ecca6) ) ROM_LOAD( "robokid.15c", 0x20000, 0x10000, CRC(7de67ebb) SHA1(2fe92e50e2894dd363e69b053db96bdb66a273eb) ) @@ -1461,7 +1463,7 @@ ROM_START( robokidj ) ROM_LOAD( "robokid.15d", 0x60000, 0x10000, CRC(cd632a4d) SHA1(a537d9ced45fdac490097e9162ac4d09a470be79) ) ROM_LOAD( "robokid.16d", 0x70000, 0x10000, CRC(18d92b2b) SHA1(e6d20ea8f0fac8bd4824a3b279a0fd8a1d6c26f5) ) - ROM_REGION( 0x80000, "gfx5", 0 ) // bg2 tiles + ROM_REGION( 0x80000, "tiles3", 0 ) // bg2 tiles ROM_LOAD( "robokid.12a", 0x00000, 0x10000, CRC(e64d1c10) SHA1(d1073c80c9788aba65410f88691747a37b2a9d4a) ) ROM_LOAD( "robokid.14a", 0x10000, 0x10000, CRC(8f9371e4) SHA1(0ea06d62bf4673ebda49a849cead832a24e5b886) ) ROM_LOAD( "robokid.15a", 0x20000, 0x10000, CRC(469204e7) SHA1(8c2e94635b2b304e7dfa2e6ad58ba526dcf02453) ) @@ -1486,16 +1488,16 @@ ROM_START( robokidj2 ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "robokid.k7", 0x00000, 0x10000, CRC(f490a2e9) SHA1(861d1256c090ce3d1f45f95cc894affbbc3f1466) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles ROM_LOAD( "robokid.b9", 0x00000, 0x08000, CRC(fac59c3f) SHA1(1b202ad5c12982512129d9e097267dd31b984ae8) ) - ROM_REGION( 0x40000, "gfx2", 0 ) // sprite tiles + ROM_REGION( 0x40000, "sprites", 0 ) // sprite tiles ROM_LOAD( "robokid.15f", 0x00000, 0x10000, CRC(ba61f5ab) SHA1(8433ddd55f0184cd5e8bb4a94a1c2336b2f8ff05) ) ROM_LOAD( "robokid.16f", 0x10000, 0x10000, CRC(d9b399ce) SHA1(70755c9cae27187f183ae6d61bedb95c420756f4) ) ROM_LOAD( "robokid.17f", 0x20000, 0x10000, CRC(afe432b9) SHA1(1ec7954ccf112eddf0ffcb8b5aec6cbc5cba7a7a) ) ROM_LOAD( "robokid.18f", 0x30000, 0x10000, CRC(a0aa2a84) SHA1(4d46c169429cd285644336c7d47e393b33bd8770) ) - ROM_REGION( 0x80000, "gfx3", 0 ) // bg0 tiles + ROM_REGION( 0x80000, "tiles1", 0 ) // bg0 tiles ROM_LOAD( "robokid.19c", 0x00000, 0x10000, CRC(02220421) SHA1(f533e9c6cea1dccbb60e0528c470f3cb5e8fc44e) ) ROM_LOAD( "robokid.20c", 0x10000, 0x10000, CRC(02d59bc2) SHA1(031acbb14145f9f4623de8868c6207fb9f8e8207) ) ROM_LOAD( "robokid.17d", 0x20000, 0x10000, CRC(2fa29b99) SHA1(13dce7932e2e9c03a139a4293584838aa3d9f1c3) ) @@ -1504,7 +1506,7 @@ ROM_START( robokidj2 ) ROM_LOAD( "robokid.20d", 0x50000, 0x10000, CRC(b0b395ed) SHA1(31ec07634053793a701bbfd601b029f7da66e9d7) ) ROM_LOAD( "robokid.19f", 0x60000, 0x10000, CRC(0f9071c6) SHA1(8bf0c35189eda98a9bc150788890e136870cb5b2) ) - ROM_REGION( 0x80000, "gfx4", 0 ) // bg1 tiles + ROM_REGION( 0x80000, "tiles2", 0 ) // bg1 tiles ROM_LOAD( "robokid.12c", 0x00000, 0x10000, CRC(0ab45f94) SHA1(d8274263068d998c89a1b247dde7f814037cc15b) ) ROM_LOAD( "robokid.14c", 0x10000, 0x10000, CRC(029bbd4a) SHA1(8e078cdafe608fc6cde827be85c5267ade4ecca6) ) ROM_LOAD( "robokid.15c", 0x20000, 0x10000, CRC(7de67ebb) SHA1(2fe92e50e2894dd363e69b053db96bdb66a273eb) ) @@ -1514,7 +1516,7 @@ ROM_START( robokidj2 ) ROM_LOAD( "robokid.15d", 0x60000, 0x10000, CRC(cd632a4d) SHA1(a537d9ced45fdac490097e9162ac4d09a470be79) ) ROM_LOAD( "robokid.16d", 0x70000, 0x10000, CRC(18d92b2b) SHA1(e6d20ea8f0fac8bd4824a3b279a0fd8a1d6c26f5) ) - ROM_REGION( 0x80000, "gfx5", 0 ) // bg2 tiles + ROM_REGION( 0x80000, "tiles3", 0 ) // bg2 tiles ROM_LOAD( "robokid.12a", 0x00000, 0x10000, CRC(e64d1c10) SHA1(d1073c80c9788aba65410f88691747a37b2a9d4a) ) ROM_LOAD( "robokid.14a", 0x10000, 0x10000, CRC(8f9371e4) SHA1(0ea06d62bf4673ebda49a849cead832a24e5b886) ) ROM_LOAD( "robokid.15a", 0x20000, 0x10000, CRC(469204e7) SHA1(8c2e94635b2b304e7dfa2e6ad58ba526dcf02453) ) @@ -1533,19 +1535,19 @@ ROM_START( omegaf ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "7.7m", 0x00000, 0x10000, CRC(d40fc8d5) SHA1(4f615a0fb786cafc20f82f0b5fa112a9c356378f) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles ROM_LOAD( "4.18h", 0x00000, 0x08000, CRC(9e2d8152) SHA1(4b50557d171d1b03a870db5891ae67d70858ad37) ) - ROM_REGION( 0x20000, "gfx2", 0 ) // sprite tiles + ROM_REGION( 0x20000, "sprites", 0 ) // sprite tiles ROM_LOAD( "8.23m", 0x00000, 0x20000, CRC(0bd2a5d1) SHA1(ef84f1a5554e891fc38d17314e3952ea5c9d2731) ) - ROM_REGION( 0x80000, "gfx3", 0 ) // bg0 tiles + ROM_REGION( 0x80000, "tiles1", 0 ) // bg0 tiles ROM_LOAD( "2back1.27b", 0x00000, 0x80000, CRC(21f8a32e) SHA1(26582e06e7381e09443fa99f24ca9edd0b4a2937) ) - ROM_REGION( 0x80000, "gfx4", 0 ) // bg1 tiles + ROM_REGION( 0x80000, "tiles2", 0 ) // bg1 tiles ROM_LOAD( "1back2.15b", 0x00000, 0x80000, CRC(6210ddcc) SHA1(89c091eeafcc92750d0ea303fcde8a8dc3eeba89) ) - ROM_REGION( 0x80000, "gfx5", 0 ) // bg2 tiles + ROM_REGION( 0x80000, "tiles3", 0 ) // bg2 tiles ROM_LOAD( "3back3.5f", 0x00000, 0x80000, CRC(c31cae56) SHA1(4cc2d0d70990ca04b0e3abd15e5afe183e98e4ab) ) ROM_END @@ -1559,19 +1561,19 @@ ROM_START( omegafs ) ROM_REGION( 0x10000, "soundcpu", 0 ) ROM_LOAD( "7.7m", 0x00000, 0x10000, CRC(d40fc8d5) SHA1(4f615a0fb786cafc20f82f0b5fa112a9c356378f) ) - ROM_REGION( 0x08000, "gfx1", 0 ) // fg tiles + ROM_REGION( 0x08000, "chars", 0 ) // fg tiles ROM_LOAD( "4.18h", 0x00000, 0x08000, CRC(9e2d8152) SHA1(4b50557d171d1b03a870db5891ae67d70858ad37) ) - ROM_REGION( 0x20000, "gfx2", 0 ) // sprite tiles + ROM_REGION( 0x20000, "sprites", 0 ) // sprite tiles ROM_LOAD( "8.23m", 0x00000, 0x20000, CRC(0bd2a5d1) SHA1(ef84f1a5554e891fc38d17314e3952ea5c9d2731) ) - ROM_REGION( 0x80000, "gfx3", 0 ) // bg0 tiles + ROM_REGION( 0x80000, "tiles1", 0 ) // bg0 tiles ROM_LOAD( "2back1.27b", 0x00000, 0x80000, CRC(21f8a32e) SHA1(26582e06e7381e09443fa99f24ca9edd0b4a2937) ) - ROM_REGION( 0x80000, "gfx4", 0 ) // bg1 tiles + ROM_REGION( 0x80000, "tiles2", 0 ) // bg1 tiles ROM_LOAD( "1back2.15b", 0x00000, 0x80000, CRC(6210ddcc) SHA1(89c091eeafcc92750d0ea303fcde8a8dc3eeba89) ) - ROM_REGION( 0x80000, "gfx5", 0 ) // bg2 tiles + ROM_REGION( 0x80000, "tiles3", 0 ) // bg2 tiles ROM_LOAD( "3back3.5f", 0x00000, 0x80000, CRC(c31cae56) SHA1(4cc2d0d70990ca04b0e3abd15e5afe183e98e4ab) ) ROM_END @@ -1596,7 +1598,7 @@ by one place all the intervening bits. void ninjakd2_state::lineswap_gfx_roms(const char *region, const int bit) { const int length = memregion(region)->bytes(); - uint8_t* const src = memregion(region)->base(); + uint8_t *const src = memregion(region)->base(); std::vector temp(length); const int mask = (1 << (bit + 1)) - 1; @@ -1611,9 +1613,9 @@ void ninjakd2_state::lineswap_gfx_roms(const char *region, const int bit) void ninjakd2_state::gfx_unscramble() { - lineswap_gfx_roms("gfx1", 13); // fg tiles - lineswap_gfx_roms("gfx2", 14); // sprites - lineswap_gfx_roms("gfx3", 14); // bg tiles + lineswap_gfx_roms("chars", 13); // fg tiles + lineswap_gfx_roms("sprites", 14); // sprites + lineswap_gfx_roms("tiles1", 14); // bg tiles } @@ -1640,8 +1642,11 @@ void mnight_state::init_mnight() uint8_t robokid_state::motion_error_verbose_r() { - popmessage("%s MOTION ERROR, contact MAMEdev", machine().system().name); - logerror("maincpu %04x MOTION ERROR\n", m_maincpu->pc()); + if (!machine().side_effects_disabled()) + { + popmessage("%s MOTION ERROR, contact MAMEdev", machine().system().name); + logerror("maincpu %04x MOTION ERROR\n", m_maincpu->pc()); + } return 0xe6; } @@ -1681,22 +1686,22 @@ void robokid_state::init_robokidj() *************************************/ // YEAR, NAME, PARENT, MACHINE, INPUT, STATE, INIT, MONITOR,COMPANY,FULLNAME,FLAGS -GAME( 1987, ninjakd2, 0, ninjakd2, ninjakd2, ninjakd2_state, init_ninjakd2, ROT0, "UPL", "Ninja-Kid II / NinjaKun Ashura no Shou (set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, ninjakd2, 0, ninjakd2, ninjakd2, ninjakd2_state, init_ninjakd2, ROT0, "UPL", "Ninja-Kid II / NinjaKun Ashura no Shou (set 1)", MACHINE_SUPPORTS_SAVE ) GAME( 1987, ninjakd2a, ninjakd2, ninjakd2b, ninjakd2, ninjakd2_state, init_bootleg, ROT0, "UPL", "Ninja-Kid II / NinjaKun Ashura no Shou (set 2, bootleg?)", MACHINE_SUPPORTS_SAVE ) GAME( 1987, ninjakd2b, ninjakd2, ninjakd2b, rdaction, ninjakd2_state, init_bootleg, ROT0, "UPL", "Ninja-Kid II / NinjaKun Ashura no Shou (set 3, bootleg?)", MACHINE_SUPPORTS_SAVE ) -GAME( 1987, ninjakd2c, ninjakd2, ninjakd2, rdaction, ninjakd2_state, init_ninjakd2, ROT0, "UPL", "Ninja-Kid II / NinjaKun Ashura no Shou (set 4)", MACHINE_SUPPORTS_SAVE ) // close to set 3 -GAME( 1987, rdaction, ninjakd2, ninjakd2, rdaction, ninjakd2_state, init_ninjakd2, ROT0, "UPL (World Games license)", "Rad Action / NinjaKun Ashura no Shou", MACHINE_SUPPORTS_SAVE ) -GAME( 1987, jt104, ninjakd2, ninjakd2, rdaction, ninjakd2_state, init_ninjakd2, ROT0, "UPL (United Amusements license)", "JT 104 / NinjaKun Ashura no Shou", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, ninjakd2c, ninjakd2, ninjakd2, rdaction, ninjakd2_state, init_ninjakd2, ROT0, "UPL", "Ninja-Kid II / NinjaKun Ashura no Shou (set 4)", MACHINE_SUPPORTS_SAVE ) // close to set 3 +GAME( 1987, rdaction, ninjakd2, ninjakd2, rdaction, ninjakd2_state, init_ninjakd2, ROT0, "UPL (World Games license)", "Rad Action / NinjaKun Ashura no Shou", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, jt104, ninjakd2, ninjakd2, rdaction, ninjakd2_state, init_ninjakd2, ROT0, "UPL (United Amusements license)", "JT 104 / NinjaKun Ashura no Shou", MACHINE_SUPPORTS_SAVE ) -GAME( 1987, mnight, 0, mnight, mnight, mnight_state, init_mnight, ROT0, "UPL", "Mutant Night", MACHINE_SUPPORTS_SAVE ) -GAME( 1987, mnightj, mnight, mnight, mnight, mnight_state, init_mnight, ROT0, "UPL (Kawakus license)", "Mutant Night (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, mnight, 0, mnight, mnight, mnight_state, init_mnight, ROT0, "UPL", "Mutant Night", MACHINE_SUPPORTS_SAVE ) +GAME( 1987, mnightj, mnight, mnight, mnight, mnight_state, init_mnight, ROT0, "UPL (Kawakus license)", "Mutant Night (Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 1988, arkarea, 0, arkarea, arkarea, mnight_state, init_mnight, ROT0, "UPL", "Ark Area", MACHINE_SUPPORTS_SAVE ) +GAME( 1988, arkarea, 0, arkarea, arkarea, mnight_state, init_mnight, ROT0, "UPL", "Ark Area", MACHINE_SUPPORTS_SAVE ) -GAME( 1988, robokid, 0, robokid, robokid, robokid_state, init_robokid, ROT0, "UPL", "Atomic Robo-kid (World, Type-2)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) // 3-digit highscore names -GAME( 1988, robokidj, robokid, robokid, robokidj, robokid_state, init_robokidj, ROT0, "UPL", "Atomic Robo-kid (Japan, Type-2, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) -GAME( 1988, robokidj2, robokid, robokid, robokidj, robokid_state, init_robokidj, ROT0, "UPL", "Atomic Robo-kid (Japan, Type-2, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) -GAME( 1988, robokidj3, robokid, robokid, robokidj, robokid_state, empty_init, ROT0, "UPL", "Atomic Robo-kid (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) +GAME( 1988, robokid, 0, robokid, robokid, robokid_state, init_robokid, ROT0, "UPL", "Atomic Robo-kid (World, Type-2)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) // 3-digit highscore names +GAME( 1988, robokidj, robokid, robokid, robokidj, robokid_state, init_robokidj, ROT0, "UPL", "Atomic Robo-kid (Japan, Type-2, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) +GAME( 1988, robokidj2, robokid, robokid, robokidj, robokid_state, init_robokidj, ROT0, "UPL", "Atomic Robo-kid (Japan, Type-2, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) +GAME( 1988, robokidj3, robokid, robokid, robokidj, robokid_state, empty_init, ROT0, "UPL", "Atomic Robo-kid (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) -GAME( 1989, omegaf, 0, omegaf, omegaf, omegaf_state, empty_init, ROT270, "UPL", "Omega Fighter", MACHINE_SUPPORTS_SAVE ) -GAME( 1989, omegafs, omegaf, omegaf, omegaf, omegaf_state, empty_init, ROT270, "UPL", "Omega Fighter Special", MACHINE_SUPPORTS_SAVE ) +GAME( 1989, omegaf, 0, omegaf, omegaf, omegaf_state, empty_init, ROT270, "UPL", "Omega Fighter", MACHINE_SUPPORTS_SAVE ) +GAME( 1989, omegafs, omegaf, omegaf, omegaf, omegaf_state, empty_init, ROT270, "UPL", "Omega Fighter Special", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/upl/ninjakd2.h b/src/mame/upl/ninjakd2.h index bebc26d5c97..341316eca62 100644 --- a/src/mame/upl/ninjakd2.h +++ b/src/mame/upl/ninjakd2.h @@ -26,12 +26,12 @@ class ninjakd2_state : public driver_device m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_soundcpu(*this, "soundcpu"), + m_spriteram(*this, "spriteram"), + m_mainbank(*this, "mainbank"), m_pcm(*this, "pcm"), m_pcm_region(*this, "pcm"), m_fg_videoram(*this, "fg_videoram"), - m_spriteram(*this, "spriteram"), - m_decrypted_opcodes(*this, "decrypted_opcodes"), - m_mainbank(*this, "mainbank") + m_decrypted_opcodes(*this, "decrypted_opcodes") { } void ninjakd2b(machine_config &config); @@ -41,28 +41,17 @@ class ninjakd2_state : public driver_device void init_bootleg(); protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + void ninjakd2_bgvideoram_w(offs_t offset, uint8_t data); - void ninjakd2_fgvideoram_w(offs_t offset, uint8_t data); + void fgvideoram_w(offs_t offset, uint8_t data); void ninjakd2_bg_ctrl_w(offs_t offset, uint8_t data); - void ninjakd2_sprite_overdraw_w(uint8_t data); - - void ninjakd2_bankselect_w(uint8_t data); - void ninjakd2_soundreset_w(uint8_t data); - - required_device m_maincpu; - required_device m_palette; - optional_shared_ptr m_bg_videoram; - required_device m_gfxdecode; - required_device m_screen; - required_device m_soundcpu; + void sprite_overdraw_w(uint8_t data); - uint8_t m_vram_bank_mask = 0; - int m_robokid_sprites = 0; - bool (*m_stencil_compare_function) (uint16_t pal); - int m_sprites_updated = 0; - tilemap_t* m_fg_tilemap; - tilemap_t* m_bg_tilemap; - bitmap_ind16 m_sprites_bitmap; + void bankselect_w(uint8_t data); + void soundreset_w(uint8_t data); void video_init_common(); @@ -72,7 +61,7 @@ class ninjakd2_state : public driver_device TILE_GET_INFO_MEMBER(get_fg_tile_info); TILE_GET_INFO_MEMBER(ninjakd2_get_bg_tile_info); uint32_t screen_update_ninjakd2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void screen_vblank_ninjakd2(int state); + void screen_vblank(int state); void bg_ctrl(int offset, int data, tilemap_t* tilemap); void gfx_unscramble(); @@ -80,32 +69,43 @@ class ninjakd2_state : public driver_device void ninjakid_nopcm_sound_cpu(address_map &map); - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - void ninjakd2_core(machine_config &config); -private: - optional_device m_pcm; - optional_memory_region m_pcm_region; - required_shared_ptr m_fg_videoram; - required_shared_ptr m_spriteram; - optional_shared_ptr m_decrypted_opcodes; + required_device m_maincpu; + required_device m_palette; + optional_shared_ptr m_bg_videoram; + required_device m_gfxdecode; + required_device m_screen; + required_device m_soundcpu; + required_shared_ptr m_spriteram; required_memory_bank m_mainbank; - std::unique_ptr m_sampledata; - int m_next_sprite_overdraw_enabled = 0; - uint8_t m_rom_bank_mask = 0; + uint8_t m_vram_bank_mask = 0; + bool m_robokid_sprites = false; + bool (*m_stencil_compare_function)(uint16_t pal) = nullptr; + bool m_sprites_updated = false; + tilemap_t *m_fg_tilemap = nullptr; + tilemap_t *m_bg_tilemap = nullptr; + bitmap_ind16 m_sprites_bitmap; - void draw_sprites( bitmap_ind16 &bitmap); - void erase_sprites( bitmap_ind16 &bitmap); +private: + void draw_sprites(bitmap_ind16 &bitmap); + void erase_sprites(bitmap_ind16 &bitmap); void lineswap_gfx_roms(const char *region, const int bit); void decrypted_opcodes_map(address_map &map); void ninjakd2_main_cpu(address_map &map); void ninjakd2_sound_cpu(address_map &map); void ninjakd2_sound_io(address_map &map); + + optional_device m_pcm; + optional_memory_region m_pcm_region; + required_shared_ptr m_fg_videoram; + optional_shared_ptr m_decrypted_opcodes; + + std::unique_ptr m_sampledata; + bool m_next_sprite_overdraw_enabled = false; + uint8_t m_rom_bank_mask = 0; }; class mnight_state : public ninjakd2_state @@ -141,18 +141,19 @@ class robokid_state : public mnight_state void init_robokidj(); protected: - template uint8_t robokid_bg_videoram_r(offs_t offset); - template void robokid_bg_videoram_w(offs_t offset, uint8_t data); - template void robokid_bg_ctrl_w(offs_t offset, uint8_t data); - template void robokid_bg_bank_w(uint8_t data); - tilemap_t* m_robokid_tilemap[3]; + template uint8_t robokid_bg_videoram_r(offs_t offset); + template void robokid_bg_videoram_w(offs_t offset, uint8_t data); + template void robokid_bg_ctrl_w(offs_t offset, uint8_t data); + template void robokid_bg_bank_w(uint8_t data); void video_init_banked(uint32_t vram_alloc_size); TILEMAP_MAPPER_MEMBER(robokid_bg_scan); - template TILE_GET_INFO_MEMBER(robokid_get_bg_tile_info); + template TILE_GET_INFO_MEMBER(robokid_get_bg_tile_info); void robokid_main_cpu(address_map &map); + tilemap_t *m_robokid_tilemap[3] = { nullptr, nullptr, nullptr }; + private: uint8_t motion_error_verbose_r(); @@ -160,8 +161,9 @@ class robokid_state : public mnight_state uint32_t screen_update_robokid(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); void motion_error_kludge(uint16_t offset); + uint8_t m_robokid_bg_bank[3] = { }; - std::unique_ptr m_robokid_bg_videoram[3]; + std::unique_ptr m_robokid_bg_videoram[3]; }; class omegaf_state : public robokid_state @@ -190,15 +192,15 @@ class omegaf_state : public robokid_state TILEMAP_MAPPER_MEMBER(omegaf_bg_scan); uint32_t screen_update_omegaf(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - required_ioport_array<2> m_dsw_io; - required_ioport_array<2> m_pad_io; - void io_protection_start(); void io_protection_reset(); + required_ioport_array<2> m_dsw_io; + required_ioport_array<2> m_pad_io; + uint8_t m_io_protection[3] = { }; uint8_t m_io_protection_input = 0; - int m_io_protection_tick = 0; + uint32_t m_io_protection_tick = 0; }; #endif // MAME_UPL_NINJAKD2_H diff --git a/src/mame/upl/ninjakd2_v.cpp b/src/mame/upl/ninjakd2_v.cpp index 2811c971df3..2e4d4a195fc 100644 --- a/src/mame/upl/ninjakd2_v.cpp +++ b/src/mame/upl/ninjakd2_v.cpp @@ -61,13 +61,13 @@ TILE_GET_INFO_MEMBER(mnight_state::mnight_get_bg_tile_info) TILEMAP_MAPPER_MEMBER(robokid_state::robokid_bg_scan) { - /* logical (col,row) -> memory offset */ + // logical (col,row) -> memory offset return (col & 0x0f) | ((row & 0x1f) << 4) | ((col & 0x10) << 5); } TILEMAP_MAPPER_MEMBER(omegaf_state::omegaf_bg_scan) { - /* logical (col,row) -> memory offset */ + // logical (col,row) -> memory offset return (col & 0x0f) | ((row & 0x1f) << 4) | ((col & 0x70) << 5); } @@ -99,8 +99,8 @@ void ninjakd2_state::video_init_common() m_screen->register_screen_bitmap(m_sprites_bitmap); - m_sprites_updated = 0; - m_robokid_sprites = 0; + m_sprites_updated = false; + m_robokid_sprites = false; m_vram_bank_mask = 0; // register for save states @@ -162,7 +162,7 @@ VIDEO_START_MEMBER(robokid_state,robokid) { video_init_common(); video_init_banked(0x0800); - m_robokid_sprites = 1; + m_robokid_sprites = true; m_robokid_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(robokid_state::robokid_get_bg_tile_info<0>)), tilemap_mapper_delegate(*this, FUNC(robokid_state::robokid_bg_scan)), 16, 16, 32, 32); m_robokid_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(robokid_state::robokid_get_bg_tile_info<1>)), tilemap_mapper_delegate(*this, FUNC(robokid_state::robokid_bg_scan)), 16, 16, 32, 32); @@ -178,7 +178,7 @@ VIDEO_START_MEMBER(omegaf_state,omegaf) { video_init_common(); video_init_banked(0x2000); - m_robokid_sprites = 1; + m_robokid_sprites = true; m_robokid_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(omegaf_state::robokid_get_bg_tile_info<0>)), tilemap_mapper_delegate(*this, FUNC(omegaf_state::omegaf_bg_scan)), 16, 16, 128, 32); m_robokid_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(omegaf_state::robokid_get_bg_tile_info<1>)), tilemap_mapper_delegate(*this, FUNC(omegaf_state::omegaf_bg_scan)), 16, 16, 128, 32); @@ -205,7 +205,7 @@ void ninjakd2_state::ninjakd2_bgvideoram_w(offs_t offset, uint8_t data) m_bg_tilemap->mark_tile_dirty(offset >> 1); } -void ninjakd2_state::ninjakd2_fgvideoram_w(offs_t offset, uint8_t data) +void ninjakd2_state::fgvideoram_w(offs_t offset, uint8_t data) { m_fg_videoram[offset] = data; m_fg_tilemap->mark_tile_dirty(offset >> 1); @@ -222,7 +222,7 @@ void ninjakd2_state::bg_ctrl(int offset, int data, tilemap_t* tilemap) case 1: scrollx = ((scrollx & 0xff) | (data << 8)); break; case 2: scrolly = ((scrolly & ~0xff) | data); break; case 3: scrolly = ((scrolly & 0xff) | (data << 8)); break; - case 4: tilemap->enable(data & 1); break; + case 4: tilemap->enable(BIT(data, 0)); break; } tilemap->set_scrollx(0, scrollx); @@ -234,9 +234,9 @@ void ninjakd2_state::ninjakd2_bg_ctrl_w(offs_t offset, uint8_t data) bg_ctrl(offset, data, m_bg_tilemap); } -void ninjakd2_state::ninjakd2_sprite_overdraw_w(uint8_t data) +void ninjakd2_state::sprite_overdraw_w(uint8_t data) { - m_next_sprite_overdraw_enabled = data & 1; + m_next_sprite_overdraw_enabled = BIT(data, 0); } @@ -247,13 +247,13 @@ void ninjakd2_state::ninjakd2_sprite_overdraw_w(uint8_t data) * *************************************/ -void ninjakd2_state::draw_sprites( bitmap_ind16 &bitmap) +void ninjakd2_state::draw_sprites(bitmap_ind16 &bitmap) { - gfx_element* const gfx = m_gfxdecode->gfx(1); + gfx_element *const gfx = m_gfxdecode->gfx(1); int const big_xshift = m_robokid_sprites ? 1 : 0; int const big_yshift = m_robokid_sprites ? 0 : 1; - uint8_t* sprptr = &m_spriteram[11]; + uint8_t const *sprptr = &m_spriteram[11]; int sprites_drawn = 0; /* The sprite generator draws exactly 96 16x16 sprites per frame. When big @@ -267,22 +267,22 @@ void ninjakd2_state::draw_sprites( bitmap_ind16 &bitmap) for (;;) { - if (sprptr[2] & 0x02) + if (BIT(sprptr[2], 1)) { int sx = sprptr[1] - ((sprptr[2] & 0x01) << 8); int sy = sprptr[0]; // Ninja Kid II doesn't use the topmost bit (it has smaller ROMs) so it might not be connected on the board - int code = sprptr[3] + ((sprptr[2] & 0xc0) << 2) + ((sprptr[2] & 0x08) << 7); - int flipx = (sprptr[2] & 0x10) >> 4; - int flipy = (sprptr[2] & 0x20) >> 5; + int code = sprptr[3] | (bitswap<3>(sprptr[2], 3, 7, 6) << 8); + int flipx = BIT(sprptr[2], 4); + int flipy = BIT(sprptr[2], 5); int const color = sprptr[4] & 0x0f; // Ninja Kid II doesn't use the 'big' feature so it might not be available on the board - int const big = (sprptr[2] & 0x04) >> 2; + int const big = BIT(sprptr[2], 2); if (flip_screen()) { - sx = 240 - 16*big - sx; - sy = 240 - 16*big - sy; + sx = 240 - 16 * big - sx; + sy = 240 - 16 * big - sy; flipx ^= 1; flipy ^= 1; } @@ -298,13 +298,13 @@ void ninjakd2_state::draw_sprites( bitmap_ind16 &bitmap) { for (int x = 0; x <= big; ++x) { - int const tile = code ^ (x << big_xshift) ^ (y << big_yshift); + uint32_t const tile = code ^ (x << big_xshift) ^ (y << big_yshift); gfx->transpen(bitmap,bitmap.cliprect(), - tile, - color, - flipx,flipy, - sx + 16*x, sy + 16*y, 0xf); + tile, + color, + flipx, flipy, + sx + 16*x, sy + 16*y, 0xf); ++sprites_drawn; if (sprites_drawn >= 96) @@ -323,11 +323,11 @@ void ninjakd2_state::draw_sprites( bitmap_ind16 &bitmap) } } -static bool stencil_ninjakd2( uint16_t pal ) { return( (pal & 0xf0) == 0xf0 ); } -static bool stencil_mnight( uint16_t pal ) { return( (pal & 0xf0) == 0xf0 ); } -static bool stencil_arkarea( uint16_t pal ) { return( (pal & 0xf0) == 0xf0 ); } -static bool stencil_robokid( uint16_t pal ) { return( (pal & 0xf0) < 0xe0 ); } -static bool stencil_omegaf( uint16_t pal ) { return( true ); } +static bool stencil_ninjakd2( uint16_t pal ) { return (pal & 0xf0) == 0xf0; } +static bool stencil_mnight( uint16_t pal ) { return (pal & 0xf0) == 0xf0; } +static bool stencil_arkarea( uint16_t pal ) { return (pal & 0xf0) == 0xf0; } +static bool stencil_robokid( uint16_t pal ) { return (pal & 0xf0) < 0xe0; } +static bool stencil_omegaf( uint16_t pal ) { return true; } ////// OVERDRAW STENCIL UNKNOWN ////// NINJAKD2 023459ABCDE F 1678 ////// MNIGHT 0134568ABCDE F 279 @@ -339,7 +339,7 @@ static bool stencil_omegaf( uint16_t pal ) { return( true ); } // This is very hackish. // (Is there a possibility that software can't select it but hardware can?) -void ninjakd2_state::erase_sprites( bitmap_ind16 &bitmap) +void ninjakd2_state::erase_sprites(bitmap_ind16 &bitmap) { // if sprite overdraw is disabled, clear the sprite framebuffer if (!m_next_sprite_overdraw_enabled) @@ -353,7 +353,8 @@ void ninjakd2_state::erase_sprites( bitmap_ind16 &bitmap) for (int x = 0; x < m_sprites_bitmap.width(); ++x) { uint16_t *const ptr = &m_sprites_bitmap.pix(y, x); - if ( (*m_stencil_compare_function)(*ptr) ) *ptr = 0xf; + if ((*m_stencil_compare_function)(*ptr)) + *ptr = 0xf; } } } @@ -377,7 +378,7 @@ uint32_t ninjakd2_state::screen_update_ninjakd2(screen_device &screen, bitmap_in // updating sprites here instead than in screen_vblank avoids a palette glitch // at the end of the "rainbow sky" screens. update_sprites(); - m_sprites_updated = 1; + m_sprites_updated = true; bitmap.fill(0, cliprect); @@ -391,7 +392,7 @@ uint32_t ninjakd2_state::screen_update_ninjakd2(screen_device &screen, bitmap_in uint32_t robokid_state::screen_update_robokid(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { update_sprites(); - m_sprites_updated = 1; + m_sprites_updated = true; bitmap.fill(0, cliprect); @@ -407,7 +408,7 @@ uint32_t robokid_state::screen_update_robokid(screen_device &screen, bitmap_ind1 uint32_t omegaf_state::screen_update_omegaf(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { update_sprites(); - m_sprites_updated = 1; + m_sprites_updated = true; bitmap.fill(0, cliprect); @@ -421,7 +422,7 @@ uint32_t omegaf_state::screen_update_omegaf(screen_device &screen, bitmap_ind16 } -void ninjakd2_state::screen_vblank_ninjakd2(int state) +void ninjakd2_state::screen_vblank(int state) { // rising edge if (state) @@ -429,8 +430,8 @@ void ninjakd2_state::screen_vblank_ninjakd2(int state) if (!m_sprites_updated) update_sprites(); - m_sprites_updated = 0; + m_sprites_updated = false; - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xd7); /* Z80 - RST 10h */ + m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xd7); // Z80 - RST 10h } }