diff --git a/hash/nes.xml b/hash/nes.xml index da222b15c20..56794f211c1 100644 --- a/hash/nes.xml +++ b/hash/nes.xml @@ -8906,6 +8906,31 @@ + + Dooly Bravo Land + 1992 + Daou Infosys + + + + + + + + + + + + + + + + + + + + + Door Door (Jpn) 1985 @@ -22341,14 +22366,14 @@ - - - - - - + + + - + + + + @@ -47070,11 +47095,18 @@ preliminary proto for the PAL version, still running on NTSC systems) or the gfx + + + + + + + - + - + @@ -62144,30 +62176,6 @@ preliminary proto for the PAL version, still running on NTSC systems) or the gfx - - Subor Kara OK - 19?? - Subor - - - - - - - - - - - - - - - - - - - - Karaoke (Asia, Chinese) 19?? @@ -69277,24 +69285,23 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - + + GSD Super Student Computer Cartridge (Chi) 19?? - <unknown> + Gao Sheng Da + + - - - - @@ -69503,7 +69510,7 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t ABM Study Card V5.0 (Chi) - 19?? + 1995? <unknown> @@ -69525,8 +69532,8 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t ASDER PC-95 (Asia?) - 19?? - <unknown> + 1995? + Asder @@ -69703,8 +69710,8 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t Hong Da Study Cartridge (Chi) - 19?? - <unknown> + 1995? + Hong Da @@ -69830,27 +69837,6 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t - - Xiao Ba Wang Zhong Ying Wen Dian Nao Xue Xi Ji III (Chi) - 19?? - Subor - - - - - - - - - - - - - - - - - Cang Ku Shi Jia Dong Nao Jin (Chi) 19?? @@ -69917,25 +69903,80 @@ Also notice that VRAM & WRAM are probably incorrect for some of these sets, at t + + Subor v13.0 (Chi) + 2000? + Subor + + + + + + + + + + + + + + + + Subor v11.0 (Chi) + 2000? + Subor + + + + + + + + + + + + + + + + + + Subor v10.0 (Chi) + 199? + Subor + + + + + + + + + + + + Subor v8.0 (Chi) @@ -69951,16 +69992,51 @@ Subor v15.0 (this shows Windows 2002 on the title screen) - - - + + + + + Subor v6.0 (Chi) + 199? + Subor + + + + + + + + + + + + + + + + + + + Subor v5.0 (Chi) + 1996 + Subor + + + + + + + + + + Subor v4.0 (Chi) - 19?? + 1995 Subor @@ -69970,7 +70046,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) - + @@ -69980,19 +70056,39 @@ Subor v15.0 (this shows Windows 2002 on the title screen) + + Subor v3.0 (Chi, with Dr. Mario) + 1994 + Subor + + + + + + + + + + + + + + + - Subor v3.0 (Chi) - 19?? + Subor v3.0 (Chi, with Chinese Chess) + 1994 Subor + - + @@ -70000,7 +70096,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) Subor v1.1 (Chi) - 19?? + 1993? Subor @@ -70023,7 +70119,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) Subor v1.0 (Rus) - 19?? + 1994 Subor @@ -70033,7 +70129,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) - + @@ -70045,7 +70141,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) Subor v1.0 (Rus, Alt) - 19?? + 1994 Subor @@ -70055,7 +70151,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) - + @@ -70063,7 +70159,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) Magistr v1.0 (Rus) - 19?? + 199? <unknown> @@ -70084,7 +70180,7 @@ Subor v15.0 (this shows Windows 2002 on the title screen) Simba's v1.0 (Rus) - 19?? + 199? <unknown> @@ -70145,6 +70241,28 @@ Subor v15.0 (this shows Windows 2002 on the title screen) + + Subor Karaoke + 19?? + Subor + + + + + + + + + + + + + + + + + + Ren Shi Ma Xue Xi v1.0 (Chi) 19?? diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index db9f5dffb92..1523768b95b 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1932,6 +1932,8 @@ if (BUSES["NES"]~=null) then MAME_DIR .. "src/devices/bus/nes/sachen.h", MAME_DIR .. "src/devices/bus/nes/somari.cpp", MAME_DIR .. "src/devices/bus/nes/somari.h", + MAME_DIR .. "src/devices/bus/nes/subor.cpp", + MAME_DIR .. "src/devices/bus/nes/subor.h", MAME_DIR .. "src/devices/bus/nes/sunsoft.cpp", MAME_DIR .. "src/devices/bus/nes/sunsoft.h", MAME_DIR .. "src/devices/bus/nes/sunsoft_dcs.cpp", diff --git a/src/devices/bus/nes/konami.cpp b/src/devices/bus/nes/konami.cpp index e807b813091..fd6de204003 100644 --- a/src/devices/bus/nes/konami.cpp +++ b/src/devices/bus/nes/konami.cpp @@ -39,8 +39,6 @@ #define LOG_MMC(x) do { if (VERBOSE) logerror x; } while (0) -#define N2A03_DEFAULTCLOCK (21477272.724 / 12) - //------------------------------------------------- // constructor //------------------------------------------------- @@ -642,7 +640,9 @@ static MACHINE_CONFIG_FRAGMENT( vrc6 ) // additional sound hardware MCFG_SPEAKER_STANDARD_MONO("addon") - MCFG_SOUND_ADD("vrc6snd", VRC6, N2A03_DEFAULTCLOCK) + // TODO: this is not how VRC6 clock signaling works! + // The board uses the CLK pin in reality, not hardcoded NTSC values! + MCFG_SOUND_ADD("vrc6snd", VRC6, XTAL_21_4772MHz/12) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "addon", 0.5) MACHINE_CONFIG_END @@ -774,7 +774,9 @@ static MACHINE_CONFIG_FRAGMENT( vrc7 ) // additional sound hardware MCFG_SPEAKER_STANDARD_MONO("addon") - MCFG_SOUND_ADD("ym", YM2413, N2A03_DEFAULTCLOCK) + // TODO: this is not how VRC7 clock signaling works! + // The board uses the CLK pin in reality, not hardcoded NTSC values! + MCFG_SOUND_ADD("ym", YM2413, XTAL_21_4772MHz/12) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "addon", 0.5) MACHINE_CONFIG_END diff --git a/src/devices/bus/nes/nes_carts.cpp b/src/devices/bus/nes/nes_carts.cpp index cc692ee9f0d..5d04a57b77d 100644 --- a/src/devices/bus/nes/nes_carts.cpp +++ b/src/devices/bus/nes/nes_carts.cpp @@ -216,6 +216,7 @@ SLOT_INTERFACE_START(nes_cart) SLOT_INTERFACE_INTERNAL("daou_306", NES_DAOU306) SLOT_INTERFACE_INTERNAL("subor0", NES_SUBOR0) SLOT_INTERFACE_INTERNAL("subor1", NES_SUBOR1) + SLOT_INTERFACE_INTERNAL("subor2", NES_SUBOR2) SLOT_INTERFACE_INTERNAL("cc21", NES_CC21) SLOT_INTERFACE_INTERNAL("xiaozy", NES_XIAOZY) SLOT_INTERFACE_INTERNAL("edu2k", NES_EDU2K) diff --git a/src/devices/bus/nes/nes_carts.h b/src/devices/bus/nes/nes_carts.h index 13fa3f20037..85bc4b429fb 100644 --- a/src/devices/bus/nes/nes_carts.h +++ b/src/devices/bus/nes/nes_carts.h @@ -55,6 +55,7 @@ #include "rexsoft.h" #include "sachen.h" #include "somari.h" +#include "subor.h" #include "tengen.h" #include "txc.h" #include "waixing.h" diff --git a/src/devices/bus/nes/nes_ines.hxx b/src/devices/bus/nes/nes_ines.hxx index 760fa9b130e..a515afe7dec 100644 --- a/src/devices/bus/nes/nes_ines.hxx +++ b/src/devices/bus/nes/nes_ines.hxx @@ -691,7 +691,7 @@ void nes_cart_slot_device::call_load_ines() if (!ines20) { logerror("Loaded game in iNES format:\n"); - logerror("-- Mapper %d\n", mapper); + logerror("-- Mapper %u\n", mapper); logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000); logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000); logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000); @@ -707,8 +707,8 @@ void nes_cart_slot_device::call_load_ines() else { logerror("Loaded game in Extended iNES format:\n"); - logerror("-- Mapper: %d\n", mapper); - logerror("-- Submapper: %d\n", (header[8] & 0xf0) >> 4); + logerror("-- Mapper: %u\n", mapper); + logerror("-- Submapper: %u\n", (header[8] & 0xf0) >> 4); logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000); logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000); logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000); diff --git a/src/devices/bus/nes/nes_pcb.hxx b/src/devices/bus/nes/nes_pcb.hxx index 5496c7e2e0f..8d91645f300 100644 --- a/src/devices/bus/nes/nes_pcb.hxx +++ b/src/devices/bus/nes/nes_pcb.hxx @@ -185,6 +185,7 @@ static const nes_pcb pcb_list[] = { "daou_306", OPENCORP_DAOU306 }, { "subor0", SUBOR_TYPE0 }, { "subor1", SUBOR_TYPE1 }, + { "subor2", SUBOR_TYPE2 }, { "cc21", UNL_CC21 }, { "xiaozy", UNL_XIAOZY }, { "edu2k", UNL_EDU2K }, diff --git a/src/devices/bus/nes/nes_slot.h b/src/devices/bus/nes/nes_slot.h index 2cdb784e78a..04c79c3c831 100644 --- a/src/devices/bus/nes/nes_slot.h +++ b/src/devices/bus/nes/nes_slot.h @@ -113,7 +113,7 @@ enum /* Misc: these are needed to convert mappers to boards, I will sort them later */ OPENCORP_DAOU306, HES_BOARD, SVISION16_BOARD, RUMBLESTATION_BOARD, JYCOMPANY_A, JYCOMPANY_B, JYCOMPANY_C, MAGICSERIES_MD, KASING_BOARD, FUTUREMEDIA_BOARD, FUKUTAKE_BOARD, SOMARI_SL12, - HENGG_SRICH, HENGG_XHZS, HENGG_SHJY3, SUBOR_TYPE0, SUBOR_TYPE1, + HENGG_SRICH, HENGG_XHZS, HENGG_SHJY3, SUBOR_TYPE0, SUBOR_TYPE1, SUBOR_TYPE2, KAISER_KS7058, KAISER_KS7032, KAISER_KS7022, KAISER_KS7017, KAISER_KS7012, KAISER_KS7013B, KAISER_KS202, KAISER_KS7031, KAISER_KS7016, KAISER_KS7037, diff --git a/src/devices/bus/nes/pirate.cpp b/src/devices/bus/nes/pirate.cpp index 059293ede9d..cded3deb09d 100644 --- a/src/devices/bus/nes/pirate.cpp +++ b/src/devices/bus/nes/pirate.cpp @@ -41,8 +41,6 @@ const device_type NES_FUKUTAKE = device_creator; const device_type NES_FUTUREMEDIA = device_creator; const device_type NES_MAGSERIES = device_creator; const device_type NES_DAOU306 = device_creator; -const device_type NES_SUBOR0 = device_creator; -const device_type NES_SUBOR1 = device_creator; const device_type NES_CC21 = device_creator; const device_type NES_XIAOZY = device_creator; const device_type NES_EDU2K = device_creator; @@ -84,16 +82,6 @@ nes_daou306_device::nes_daou306_device(const machine_config &mconfig, const char { } -nes_subor0_device::nes_subor0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : nes_nrom_device(mconfig, NES_SUBOR0, "NES Cart Subor Type 0 PCB", tag, owner, clock, "nes_subor0", __FILE__) -{ -} - -nes_subor1_device::nes_subor1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : nes_nrom_device(mconfig, NES_SUBOR1, "NES Cart Subor Type 1 PCB", tag, owner, clock, "nes_subor1", __FILE__) -{ -} - nes_cc21_device::nes_cc21_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : nes_nrom_device(mconfig, NES_CC21, "NES Cart CC-21 PCB", tag, owner, clock, "nes_cc21", __FILE__) { @@ -236,38 +224,6 @@ void nes_daou306_device::pcb_reset() memset(m_reg, 0, sizeof(m_reg)); } -void nes_subor0_device::device_start() -{ - common_start(); - save_item(NAME(m_reg)); -} - -void nes_subor0_device::pcb_reset() -{ - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg16_89ab(0); - prg16_cdef(0x20); - chr8(0, m_chr_source); - - memset(m_reg, 0, sizeof(m_reg)); -} - -void nes_subor1_device::device_start() -{ - common_start(); - save_item(NAME(m_reg)); -} - -void nes_subor1_device::pcb_reset() -{ - m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; - prg16_89ab(0); - prg16_cdef(0x07); - chr8(0, m_chr_source); - - memset(m_reg, 0, sizeof(m_reg)); -} - void nes_cc21_device::device_start() { common_start(); @@ -730,82 +686,6 @@ WRITE8_MEMBER(nes_daou306_device::write_h) } } -/*------------------------------------------------- - - Subor bootleg board Type 0 - - iNES: mapper 167 - - -------------------------------------------------*/ - -WRITE8_MEMBER(nes_subor0_device::write_h) -{ - uint8_t subor_helper1, subor_helper2; - LOG_MMC(("subor0 write_h, offset: %04x, data: %02x\n", offset, data)); - - m_reg[(offset >> 13) & 0x03] = data; - subor_helper1 = ((m_reg[0] ^ m_reg[1]) << 1) & 0x20; - subor_helper2 = ((m_reg[2] ^ m_reg[3]) << 0) & 0x1f; - - if (m_reg[1] & 0x08) - { - subor_helper1 += subor_helper2 & 0xfe; - subor_helper2 = subor_helper1; - subor_helper1 += 1; - } - else if (m_reg[1] & 0x04) - { - subor_helper2 += subor_helper1; - subor_helper1 = 0x1f; - } - else - { - subor_helper1 += subor_helper2; - subor_helper2 = 0x20; - } - - prg16_89ab(subor_helper1); - prg16_cdef(subor_helper2); -} - -/*------------------------------------------------- - - Subor bootleg board Type 1 - - iNES: mapper 166 - - -------------------------------------------------*/ - -WRITE8_MEMBER(nes_subor1_device::write_h) -{ - uint8_t subor_helper1, subor_helper2; - LOG_MMC(("subor1 write_h, offset: %04x, data: %02x\n", offset, data)); - - m_reg[(offset >> 13) & 0x03] = data; - subor_helper1 = ((m_reg[0] ^ m_reg[1]) << 1) & 0x20; - subor_helper2 = ((m_reg[2] ^ m_reg[3]) << 0) & 0x1f; - - if (m_reg[1] & 0x08) - { - subor_helper1 += subor_helper2 & 0xfe; - subor_helper2 = subor_helper1; - subor_helper2 += 1; - } - else if (m_reg[1] & 0x04) - { - subor_helper2 += subor_helper1; - subor_helper1 = 0x1f; - } - else - { - subor_helper1 += subor_helper2; - subor_helper2 = 0x07; - } - - prg16_89ab(subor_helper1); - prg16_cdef(subor_helper2); -} - /*------------------------------------------------- Board UNL-CC-21 diff --git a/src/devices/bus/nes/pirate.h b/src/devices/bus/nes/pirate.h index 3a8bd1c09ea..b17ce1ada9d 100644 --- a/src/devices/bus/nes/pirate.h +++ b/src/devices/bus/nes/pirate.h @@ -118,44 +118,6 @@ private: }; -// ======================> nes_subor0_device - -class nes_subor0_device : public nes_nrom_device -{ -public: - // construction/destruction - nes_subor0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // device-level overrides - virtual void device_start() override; - virtual DECLARE_WRITE8_MEMBER(write_h) override; - - virtual void pcb_reset() override; - -private: - uint8_t m_reg[4]; -}; - - -// ======================> nes_subor1_device - -class nes_subor1_device : public nes_nrom_device -{ -public: - // construction/destruction - nes_subor1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // device-level overrides - virtual void device_start() override; - virtual DECLARE_WRITE8_MEMBER(write_h) override; - - virtual void pcb_reset() override; - -private: - uint8_t m_reg[4]; -}; - - // ======================> nes_cc21_device class nes_cc21_device : public nes_nrom_device diff --git a/src/devices/bus/nes/subor.cpp b/src/devices/bus/nes/subor.cpp new file mode 100644 index 00000000000..65bf2e18e7e --- /dev/null +++ b/src/devices/bus/nes/subor.cpp @@ -0,0 +1,325 @@ +// license:BSD-3-Clause +// copyright-holders:Kaz +/*********************************************************************************************************** + + NES/Famicom cartridge emulation for Subor PCBs + + TODO: + - Implement Type 2 variant for Subor Karaoke. + (Subor Karaoke updates banks differently.) + - Check and verify CHR banking in Type 2 boards + - Investigate connection with DANCE 2000 board; likely made by ex-Subor staff! + + ***********************************************************************************************************/ + +#include "emu.h" +#include "subor.h" + +#ifdef NES_PCB_DEBUG +#define VERBOSE 1 +#else +#define VERBOSE 0 +#endif + +#define LOG_MMC(...) do { if (VERBOSE) logerror(__VA_ARGS__); } while (0) + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type NES_SUBOR0 = device_creator; +const device_type NES_SUBOR1 = device_creator; +const device_type NES_SUBOR2 = device_creator; + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// nes_subor0_device - constructor +//------------------------------------------------- + +nes_subor0_device::nes_subor0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : nes_nrom_device(mconfig, NES_SUBOR0, "NES Cart Subor Type 0 PCB", tag, owner, clock, "nes_subor0", __FILE__) +{ +} + +//------------------------------------------------- +// nes_subor1_device - constructor +//------------------------------------------------- + +nes_subor1_device::nes_subor1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : nes_nrom_device(mconfig, NES_SUBOR1, "NES Cart Subor Type 1 PCB", tag, owner, clock, "nes_subor1", __FILE__) +{ +} + +//------------------------------------------------- +// nes_subor2_device - constructor +//------------------------------------------------- + +nes_subor2_device::nes_subor2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : nes_nrom_device(mconfig, NES_SUBOR2, "NES Cart Subor Type 2 PCB", tag, owner, clock, "nes_subor2", __FILE__), + m_switch_reg(0), + m_bank_reg(0), + m_chr_banking(0), + m_page(0) +{ +} + +/*------------------------------------------------- + device_start +-------------------------------------------------*/ + +void nes_subor0_device::device_start() +{ + common_start(); + save_item(NAME(m_reg)); +} + +void nes_subor1_device::device_start() +{ + common_start(); + save_item(NAME(m_reg)); +} + +void nes_subor2_device::device_start() +{ + common_start(); + + save_item(NAME(m_switch_reg)); + save_item(NAME(m_bank_reg)); + save_item(NAME(m_chr_banking)); +} + +/*------------------------------------------------- + pcb_reset +-------------------------------------------------*/ + +void nes_subor0_device::pcb_reset() +{ + m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; + prg16_89ab(0); + prg16_cdef(0x20); + chr8(0, m_chr_source); + + memset(m_reg, 0, sizeof(m_reg)); +} + +void nes_subor1_device::pcb_reset() +{ + m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM; + prg16_89ab(0); + prg16_cdef(0x07); + chr8(0, m_chr_source); + + memset(m_reg, 0, sizeof(m_reg)); +} + +void nes_subor2_device::pcb_reset() +{ + m_switch_reg = 0; + m_bank_reg = 0; + m_chr_banking = true; + m_page = 0; + + prg16_89ab(0); + prg16_cdef(0); +} + +/*------------------------------------------------- + mapper specific handlers +-------------------------------------------------*/ + +/*------------------------------------------------- + + Subor educational cartridge board Type 0: + iNES Mapper 167 + + Subor educational cartridge board Type 1: + iNES Mapper 166 + + Subor educational cartridge board Type 2: + No iNES mapper as of yet. + + Notes on Type 2 variants: + Implementation based upon VirtuaNESUp source code + and studying VirtuaNESEx. The latter makes the + read at 0x5300 return 0x8F, perhaps as a form + of copy protection? + + There are two revisions of Type 2 that are + currently known; + + Subor v5.0- 16k/32k PRG banking combo + + Subor Karaoke- 32k PRG banking + +-------------------------------------------------*/ + +/*------------------------------------------------- + ppu_latch +-------------------------------------------------*/ + +void nes_subor2_device::ppu_latch(offs_t offset) +{ + /* CHR banks are conditionally changed midframe */ + /* If this is split off onto the external PPU latch, every edge case works */ + if (m_chr_banking) + { + if ( (m_page == 2) || (m_page == 1 && m_switch_reg == 2) ) + { + chr4_0(1, CHRRAM); + } + else + { + chr4_0(0, CHRRAM); + } + } +} + +/*------------------------------------------------- + nt +-------------------------------------------------*/ + +READ8_MEMBER(nes_subor2_device::nt_r) +{ + int page = ((offset & 0xc00) >> 10); + + /* Nametable reads report the current page; this seems to work without issues */ + m_page = page; + + return m_nt_access[page][offset & 0x3ff]; +} + +/*------------------------------------------------- + update_banks +-------------------------------------------------*/ + +void nes_subor2_device::update_banks() +{ + switch (m_switch_reg) + { + case 0x00: + case 0x02: + m_chr_banking = true; + set_nt_mirroring(PPU_MIRROR_VERT); + break; + case 0x01: + case 0x03: + m_chr_banking = true; + set_nt_mirroring(PPU_MIRROR_HORZ); + break; + case 0x05: + /* Subor v11.0 needs this, and VirtuaNESEx keeps it specific to this cart */ + /* But leaving it as it is doesn't seem to be an issue for now */ + m_chr_banking = false; + set_nt_mirroring(PPU_MIRROR_HORZ); + break; + } + + if (m_switch_reg >= 0x04) + { + prg32(m_bank_reg); + } + else + { + prg16_89ab(m_bank_reg); + prg16_cdef(0); + } +} + +/*------------------------------------------------- + read +-------------------------------------------------*/ + +READ8_MEMBER(nes_subor2_device::read_l) +{ + LOG_MMC("subor2 read_l, offset: %04x\n", offset); + + if (offset == 0x1200) + { + return 0x8F; + } + return m_open_bus; +} + +/*------------------------------------------------- + write +-------------------------------------------------*/ + +WRITE8_MEMBER(nes_subor0_device::write_h) +{ + uint8_t subor_helper1, subor_helper2; + LOG_MMC("subor0 write_h, offset: %04x, data: %02x\n", offset, data); + + m_reg[(offset >> 13) & 0x03] = data; + subor_helper1 = ((m_reg[0] ^ m_reg[1]) << 1) & 0x20; + subor_helper2 = ((m_reg[2] ^ m_reg[3]) << 0) & 0x1f; + + if (m_reg[1] & 0x08) + { + subor_helper1 += subor_helper2 & 0xfe; + subor_helper2 = subor_helper1; + subor_helper1 += 1; + } + else if (m_reg[1] & 0x04) + { + subor_helper2 += subor_helper1; + subor_helper1 = 0x1f; + } + else + { + subor_helper1 += subor_helper2; + subor_helper2 = 0x20; + } + + prg16_89ab(subor_helper1); + prg16_cdef(subor_helper2); +} + +WRITE8_MEMBER(nes_subor1_device::write_h) +{ + uint8_t subor_helper1, subor_helper2; + LOG_MMC("subor1 write_h, offset: %04x, data: %02x\n", offset, data); + + m_reg[(offset >> 13) & 0x03] = data; + subor_helper1 = ((m_reg[0] ^ m_reg[1]) << 1) & 0x20; + subor_helper2 = ((m_reg[2] ^ m_reg[3]) << 0) & 0x1f; + + if (m_reg[1] & 0x08) + { + subor_helper1 += subor_helper2 & 0xfe; + subor_helper2 = subor_helper1; + subor_helper2 += 1; + } + else if (m_reg[1] & 0x04) + { + subor_helper2 += subor_helper1; + subor_helper1 = 0x1f; + } + else + { + subor_helper1 += subor_helper2; + subor_helper2 = 0x07; + } + + prg16_89ab(subor_helper1); + prg16_cdef(subor_helper2); +} + +WRITE8_MEMBER(nes_subor2_device::write_l) +{ + LOG_MMC("subor2 write_l, offset: %04x, data: %02x\n", offset, data); + + switch (offset) + { + case 0x0F00: + m_bank_reg = data; + update_banks(); + break; + case 0x1100: + m_switch_reg = data & 7; + update_banks(); + break; + } +} \ No newline at end of file diff --git a/src/devices/bus/nes/subor.h b/src/devices/bus/nes/subor.h new file mode 100644 index 00000000000..167561f3b36 --- /dev/null +++ b/src/devices/bus/nes/subor.h @@ -0,0 +1,78 @@ +// license:BSD-3-Clause +// copyright-holders:Kaz +#ifndef MAME_BUS_NES_SUBOR_H +#define MAME_BUS_NES_SUBOR_H + +#include "nxrom.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> nes_subor0_device + +class nes_subor0_device : + public nes_nrom_device +{ +public: + // construction/destruction + nes_subor0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + virtual DECLARE_WRITE8_MEMBER(write_h) override; + + virtual void pcb_reset() override; + +private: + uint8_t m_reg[4]; +}; + +// ======================> nes_subor1_device + +class nes_subor1_device : + public nes_nrom_device +{ +public: + // construction/destruction + nes_subor1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + virtual DECLARE_WRITE8_MEMBER(write_h) override; + + virtual void pcb_reset() override; + +private: + uint8_t m_reg[4]; +}; + +// ======================> nes_subor2_device + +class nes_subor2_device : + public nes_nrom_device +{ +public: + // construction/destruction + nes_subor2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + virtual DECLARE_READ8_MEMBER(nt_r) override; + virtual DECLARE_WRITE8_MEMBER(write_l) override; + virtual DECLARE_READ8_MEMBER(read_l) override; + + virtual void ppu_latch(offs_t offset) override; + virtual void pcb_reset() override; + +private: + void update_banks(); + uint8_t m_switch_reg, m_bank_reg, m_chr_banking, m_page; +}; + +// device type definition +extern const device_type NES_SUBOR0; +extern const device_type NES_SUBOR1; +extern const device_type NES_SUBOR2; + +#endif /* MAME_BUS_NES_SUBOR_H */ \ No newline at end of file diff --git a/src/devices/bus/nes/sunsoft.cpp b/src/devices/bus/nes/sunsoft.cpp index 82bb39ed1eb..2394d67dad8 100644 --- a/src/devices/bus/nes/sunsoft.cpp +++ b/src/devices/bus/nes/sunsoft.cpp @@ -608,14 +608,14 @@ WRITE8_MEMBER(nes_sunsoft_5_device::write_h) // YM2149F operating in this mode. To use an AY-3-8910 as a substitute, // you would need an external divider to reduce the clock speed by half. -#define SUN5_NTSC_CLOCK (21477272.724 / 12) - static MACHINE_CONFIG_FRAGMENT( sun_5b ) // additional sound hardware MCFG_SPEAKER_STANDARD_MONO("addon") - MCFG_SOUND_ADD("ay", YM2149, SUN5_NTSC_CLOCK/2) // divide by 2 for the internal divider + // TODO: this is not how Sunsoft 5B clock signaling works! + // The board uses the CLK pin in reality, not hardcoded NTSC values! + MCFG_SOUND_ADD("ay", YM2149, (XTAL_21_4772MHz/12)/2) // divide by 2 for the internal divider MCFG_SOUND_ROUTE(ALL_OUTPUTS, "addon", 0.50) MACHINE_CONFIG_END diff --git a/src/devices/cpu/m6502/n2a03.h b/src/devices/cpu/m6502/n2a03.h index 9a236839c59..3faff1fb202 100644 --- a/src/devices/cpu/m6502/n2a03.h +++ b/src/devices/cpu/m6502/n2a03.h @@ -72,7 +72,15 @@ private: }; -#define N2A03_DEFAULTCLOCK (21477272.724 / 12) +/* These are the official XTAL values and clock rates used by Nintendo for + manufacturing throughout the production of the 2A03. PALC_APU_CLOCK is + the clock rate devised by UMC(?) for PAL Famicom clone hardware. */ + +#define N2A03_NTSC_XTAL XTAL_21_4772MHz +#define N2A03_PAL_XTAL XTAL_26_601712MHz +#define NTSC_APU_CLOCK (N2A03_NTSC_XTAL/12) /* 1.7897726666... MHz */ +#define PAL_APU_CLOCK (N2A03_PAL_XTAL/16) /* 1.662607 MHz */ +#define PALC_APU_CLOCK (N2A03_PAL_XTAL/15) /* 1.77344746666... MHz */ enum { N2A03_IRQ_LINE = m6502_device::IRQ_LINE, diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp index 670e504b351..0d787209d15 100644 --- a/src/devices/video/ppu2c0x.cpp +++ b/src/devices/video/ppu2c0x.cpp @@ -79,6 +79,7 @@ const device_type PPU_2C02 = device_creator; const device_type PPU_2C03B = device_creator; const device_type PPU_2C04 = device_creator; const device_type PPU_2C07 = device_creator; +const device_type PPU_PALC = device_creator; const device_type PPU_2C05_01 = device_creator; const device_type PPU_2C05_02 = device_creator; const device_type PPU_2C05_03 = device_creator; @@ -152,6 +153,7 @@ ppu2c0x_device::ppu2c0x_device(const machine_config &mconfig, device_type type, memset(m_palette_ram, 0, ARRAY_LENGTH(m_palette_ram)); m_scanlines_per_frame = PPU_NTSC_SCANLINES_PER_FRAME; + m_vblank_first_scanline = PPU_VBLANK_FIRST_SCANLINE; /* usually, no security value... */ m_security_value = 0; @@ -181,6 +183,13 @@ ppu2c07_device::ppu2c07_device(const machine_config &mconfig, const char *tag, d m_scanlines_per_frame = PPU_PAL_SCANLINES_PER_FRAME; } +// PAL clones +ppupalc_device::ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : ppu2c0x_device(mconfig, PPU_PALC, "Generic PAL Clone PPU", tag, owner, clock, "ppupalc", __FILE__) +{ + m_scanlines_per_frame = PPU_PAL_SCANLINES_PER_FRAME; + m_vblank_first_scanline = PPU_VBLANK_FIRST_SCANLINE_PALC; +} + // The PPU_2C05 variants have different protection value, set at device start, but otherwise are all the same... // Vs. Unisystem (Ninja Jajamaru Kun) ppu2c05_01_device::ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : ppu2c0x_device(mconfig, PPU_2C05_01, "2C05_01 PPU", tag, owner, clock, "ppu2c05_01", __FILE__) @@ -254,6 +263,7 @@ void ppu2c0x_device::device_start() save_item(NAME(m_back_color)); save_item(NAME(m_scan_scale)); save_item(NAME(m_scanlines_per_frame)); + save_item(NAME(m_vblank_first_scanline)); save_item(NAME(m_regs)); save_item(NAME(m_palette_ram)); save_item(NAME(m_draw_phase)); @@ -469,7 +479,7 @@ void ppu2c0x_device::device_timer(emu_timer &timer, device_timer_id id, int para { case TIMER_HBLANK: blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0; - vblank = ((m_scanline >= PPU_VBLANK_FIRST_SCANLINE - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0; + vblank = ((m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0; //update_scanline(); @@ -489,7 +499,7 @@ void ppu2c0x_device::device_timer(emu_timer &timer, device_timer_id id, int para case TIMER_SCANLINE: blanked = (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES)) == 0; - vblank = ((m_scanline >= PPU_VBLANK_FIRST_SCANLINE - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0; + vblank = ((m_scanline >= m_vblank_first_scanline - 1) && (m_scanline < m_scanlines_per_frame - 1)) ? 1 : 0; int next_scanline; /* if a callback is available, call it */ @@ -505,7 +515,7 @@ void ppu2c0x_device::device_timer(emu_timer &timer, device_timer_id id, int para // logerror("starting scanline %d (MAME %d, beam %d)\n", m_scanline, device->m_screen->vpos(), device->m_screen->hpos()); /* Note: this is called at the _end_ of each scanline */ - if (m_scanline == PPU_VBLANK_FIRST_SCANLINE) + if (m_scanline == m_vblank_first_scanline) { // logerror("vblank starting\n"); /* We just entered VBLANK */ diff --git a/src/devices/video/ppu2c0x.h b/src/devices/video/ppu2c0x.h index d426630eb64..ec050df8d8c 100644 --- a/src/devices/video/ppu2c0x.h +++ b/src/devices/video/ppu2c0x.h @@ -47,33 +47,34 @@ enum // bit definitions for (some of) the registers enum { - PPU_CONTROL0_INC = 0x04, - PPU_CONTROL0_SPR_SELECT = 0x08, - PPU_CONTROL0_CHR_SELECT = 0x10, - PPU_CONTROL0_SPRITE_SIZE = 0x20, - PPU_CONTROL0_NMI = 0x80, + PPU_CONTROL0_INC = 0x04, + PPU_CONTROL0_SPR_SELECT = 0x08, + PPU_CONTROL0_CHR_SELECT = 0x10, + PPU_CONTROL0_SPRITE_SIZE = 0x20, + PPU_CONTROL0_NMI = 0x80, - PPU_CONTROL1_DISPLAY_MONO = 0x01, - PPU_CONTROL1_BACKGROUND_L8 = 0x02, - PPU_CONTROL1_SPRITES_L8 = 0x04, - PPU_CONTROL1_BACKGROUND = 0x08, - PPU_CONTROL1_SPRITES = 0x10, - PPU_CONTROL1_COLOR_EMPHASIS = 0xe0, + PPU_CONTROL1_DISPLAY_MONO = 0x01, + PPU_CONTROL1_BACKGROUND_L8 = 0x02, + PPU_CONTROL1_SPRITES_L8 = 0x04, + PPU_CONTROL1_BACKGROUND = 0x08, + PPU_CONTROL1_SPRITES = 0x10, + PPU_CONTROL1_COLOR_EMPHASIS = 0xe0, - PPU_STATUS_8SPRITES = 0x20, - PPU_STATUS_SPRITE0_HIT = 0x40, - PPU_STATUS_VBLANK = 0x80 + PPU_STATUS_8SPRITES = 0x20, + PPU_STATUS_SPRITE0_HIT = 0x40, + PPU_STATUS_VBLANK = 0x80 }; enum { - PPU_NTSC_SCANLINES_PER_FRAME = 262, - PPU_PAL_SCANLINES_PER_FRAME = 312, + PPU_NTSC_SCANLINES_PER_FRAME = 262, + PPU_PAL_SCANLINES_PER_FRAME = 312, - PPU_BOTTOM_VISIBLE_SCANLINE = 239, - PPU_VBLANK_FIRST_SCANLINE = 241, - PPU_VBLANK_LAST_SCANLINE_NTSC = 260, - PPU_VBLANK_LAST_SCANLINE_PAL = 310 + PPU_BOTTOM_VISIBLE_SCANLINE = 239, + PPU_VBLANK_FIRST_SCANLINE = 241, + PPU_VBLANK_FIRST_SCANLINE_PALC = 291, + PPU_VBLANK_LAST_SCANLINE_NTSC = 260, + PPU_VBLANK_LAST_SCANLINE_PAL = 310 // Both the scanline immediately before and immediately after VBLANK // are non-rendering and non-vblank. @@ -96,6 +97,8 @@ enum MCFG_PPU2C0X_ADD(_tag, PPU_2C04) #define MCFG_PPU2C07_ADD(_tag) \ MCFG_PPU2C0X_ADD(_tag, PPU_2C07) +#define MCFG_PPUPALC_ADD(_tag) \ + MCFG_PPU2C0X_ADD(_tag, PPU_PALC) #define MCFG_PPU2C05_01_ADD(_tag) \ MCFG_PPU2C0X_ADD(_tag, PPU_2C05_01) #define MCFG_PPU2C05_02_ADD(_tag) \ @@ -189,7 +192,7 @@ public: required_device m_cpu; std::unique_ptr m_bitmap; /* target bitmap */ - std::unique_ptr m_spriteram; /* sprite ram */ + std::unique_ptr m_spriteram; /* sprite ram */ std::unique_ptr m_colortable; /* color table modified at run time */ std::unique_ptr m_colortable_mono; /* monochromatic color table modified at run time */ int m_scanline; /* scanline count */ @@ -210,9 +213,10 @@ public: int m_sprite_page; /* current sprite page */ int m_back_color; /* background color */ int m_color_base; - uint8_t m_palette_ram[0x20]; /* shouldn't be in main memory! */ + uint8_t m_palette_ram[0x20]; /* shouldn't be in main memory! */ int m_scan_scale; /* scan scale */ int m_scanlines_per_frame; /* number of scanlines per frame */ + int m_vblank_first_scanline; /* the very first scanline where VBLANK occurs */ int m_security_value; /* 2C05 protection */ int m_tilecount; /* MMC5 can change attributes to subsets of the 34 visible tiles */ int m_draw_phase; /* MMC5 uses different regs for BG and OAM */ @@ -261,6 +265,11 @@ public: ppu2c07_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +class ppupalc_device : public ppu2c0x_device { +public: + ppupalc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); +}; + class ppu2c05_01_device : public ppu2c0x_device { public: ppu2c05_01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -288,6 +297,7 @@ extern const device_type PPU_2C02; // NTSC NES extern const device_type PPU_2C03B; // Playchoice 10 extern const device_type PPU_2C04; // Vs. Unisystem extern const device_type PPU_2C07; // PAL NES +extern const device_type PPU_PALC; // PAL Clones extern const device_type PPU_2C05_01; // Vs. Unisystem (Ninja Jajamaru Kun) extern const device_type PPU_2C05_02; // Vs. Unisystem (Mighty Bomb Jack) extern const device_type PPU_2C05_03; // Vs. Unisystem (Gumshoe) diff --git a/src/mame/audio/dkong.cpp b/src/mame/audio/dkong.cpp index 28d6d366719..196e9a040fd 100644 --- a/src/mame/audio/dkong.cpp +++ b/src/mame/audio/dkong.cpp @@ -1429,11 +1429,11 @@ MACHINE_CONFIG_END MACHINE_CONFIG_FRAGMENT( dkong3_audio ) - MCFG_CPU_ADD("n2a03a", N2A03,N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("n2a03a", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(dkong3_sound1_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", dkong_state, nmi_line_pulse) - MCFG_CPU_ADD("n2a03b", N2A03,N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("n2a03b", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(dkong3_sound2_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", dkong_state, nmi_line_pulse) diff --git a/src/mame/drivers/cham24.cpp b/src/mame/drivers/cham24.cpp index a6ad7a89a63..09e79421f4c 100644 --- a/src/mame/drivers/cham24.cpp +++ b/src/mame/drivers/cham24.cpp @@ -311,10 +311,9 @@ GFXDECODE_END static MACHINE_CONFIG_START( cham24, cham24_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", N2A03, N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("maincpu", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(cham24_map) - /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) diff --git a/src/mame/drivers/famibox.cpp b/src/mame/drivers/famibox.cpp index 31ba4eca55d..d9576552172 100644 --- a/src/mame/drivers/famibox.cpp +++ b/src/mame/drivers/famibox.cpp @@ -546,7 +546,7 @@ void famibox_state::machine_start() static MACHINE_CONFIG_START( famibox, famibox_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", N2A03, N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("maincpu", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(famibox_map) /* video hardware */ diff --git a/src/mame/drivers/multigam.cpp b/src/mame/drivers/multigam.cpp index dee9c71d0fb..103e8b87b3a 100644 --- a/src/mame/drivers/multigam.cpp +++ b/src/mame/drivers/multigam.cpp @@ -1214,7 +1214,7 @@ MACHINE_START_MEMBER(multigam_state,supergm3) static MACHINE_CONFIG_START( multigam, multigam_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", N2A03, N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("maincpu", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(multigam_map) diff --git a/src/mame/drivers/nes.cpp b/src/mame/drivers/nes.cpp index 2e22e40df43..c14797a03c1 100644 --- a/src/mame/drivers/nes.cpp +++ b/src/mame/drivers/nes.cpp @@ -56,16 +56,16 @@ void nes_state::ppu_nmi(int *ppu_regs) static MACHINE_CONFIG_START( nes, nes_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", N2A03, NTSC_CLOCK) + MCFG_CPU_ADD("maincpu", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(nes_map) MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60.098) + MCFG_SCREEN_REFRESH_RATE(60.0988) // This isn't used so much to calulate the vblank duration (the PPU code tracks that manually) but to determine // the number of cycles in each scanline for the PPU scanline timer. Since the PPU has 20 vblank scanlines + 2 // non-rendering scanlines, we compensate. This ends up being 2500 cycles for the non-rendering portion, 2273 // cycles for the actual vblank period. - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((113.66/(NTSC_CLOCK/1000000)) * (PPU_VBLANK_LAST_SCANLINE_NTSC-PPU_VBLANK_FIRST_SCANLINE+1+2))) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((113.66/(NTSC_APU_CLOCK/1000000)) * (PPU_VBLANK_LAST_SCANLINE_NTSC-PPU_VBLANK_FIRST_SCANLINE+1+2))) MCFG_SCREEN_SIZE(32*8, 262) MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 30*8-1) MCFG_SCREEN_UPDATE_DRIVER(nes_state, screen_update_nes) @@ -97,15 +97,13 @@ static MACHINE_CONFIG_START( nes, nes_state ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( nespal, nes ) - /* basic machine hardware */ // MCFG_CPU_MODIFY("maincpu") -// MCFG_CPU_CLOCK(PAL_CLOCK) // this doesn't get inherited by the APU with DERIVED_CLOCK! +// MCFG_CPU_CLOCK(PAL_APU_CLOCK) // this doesn't get inherited by the APU with DERIVED_CLOCK! - MCFG_CPU_REPLACE("maincpu", N2A03, PAL_CLOCK) + MCFG_CPU_REPLACE("maincpu", N2A03, PAL_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(nes_map) - MCFG_DEVICE_REMOVE("ppu") MCFG_PPU2C07_ADD("ppu") MCFG_PPU2C0X_CPU("maincpu") @@ -113,33 +111,10 @@ static MACHINE_CONFIG_DERIVED( nespal, nes ) /* video hardware */ MCFG_SCREEN_MODIFY("screen") - MCFG_SCREEN_REFRESH_RATE(53.355) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((106.53/(PAL_CLOCK/1000000)) * (PPU_VBLANK_LAST_SCANLINE_PAL-PPU_VBLANK_FIRST_SCANLINE+1+2))) + MCFG_SCREEN_REFRESH_RATE(50.0070) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((106.53/(PAL_APU_CLOCK/1000000)) * (PPU_VBLANK_LAST_SCANLINE_PAL-PPU_VBLANK_FIRST_SCANLINE+1+2))) MCFG_SCREEN_SIZE(32*8, 312) MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 30*8-1) - - -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( dendy, nes ) - - /* basic machine hardware */ -// MCFG_CPU_MODIFY( "maincpu" ) -// MCFG_CPU_CLOCK( 26601712/15 ) // this doesn't get inherited by the APU with DERIVED_CLOCK! - - MCFG_CPU_REPLACE("maincpu", N2A03, 26601712/15 )/* 26.601712MHz / 15 == 1.77344746666... MHz */ - MCFG_CPU_PROGRAM_MAP(nes_map) - - MCFG_DEVICE_REMOVE("ppu") - MCFG_PPU2C07_ADD("ppu") - MCFG_PPU2C0X_CPU("maincpu") - MCFG_PPU2C0X_SET_NMI(nes_state, ppu_nmi) - - /* video hardware */ - MCFG_SCREEN_MODIFY("screen") - MCFG_SCREEN_REFRESH_RATE(50.00697796827) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((106.53/(PAL_CLOCK/1000000)) * (PPU_VBLANK_LAST_SCANLINE_PAL-PPU_VBLANK_FIRST_SCANLINE+1+2))) - MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( famicom, nes ) @@ -154,6 +129,43 @@ static MACHINE_CONFIG_DERIVED( famicom, nes ) MCFG_SOFTWARE_LIST_ADD("cass_list", "famicom_cass") MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( nespalc, nespal ) +// MCFG_CPU_MODIFY( "maincpu" ) +// MCFG_CPU_CLOCK(PALC_APU_CLOCK) // this doesn't get inherited by the APU with DERIVED_CLOCK! + + MCFG_CPU_REPLACE("maincpu", N2A03, PALC_APU_CLOCK) + MCFG_CPU_PROGRAM_MAP(nes_map) + + /* UMC 6538 and friends -- extends time for rendering dummy scanlines */ + MCFG_DEVICE_REMOVE("ppu") + MCFG_PPUPALC_ADD("ppu") + MCFG_PPU2C0X_CPU("maincpu") + MCFG_PPU2C0X_SET_NMI(nes_state, ppu_nmi) + + /* video hardware */ + MCFG_SCREEN_MODIFY("screen") + MCFG_SCREEN_REFRESH_RATE(50.0070) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC((113.66/(PALC_APU_CLOCK/1000000)) * (PPU_VBLANK_LAST_SCANLINE_PAL-PPU_VBLANK_FIRST_SCANLINE_PALC+1+2))) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( famipalc, nespalc ) + MCFG_DEVICE_REMOVE("ctrl1") + MCFG_DEVICE_REMOVE("ctrl2") + MCFG_NES_CONTROL_PORT_ADD("ctrl1", fc_control_port1_devices, "joypad") + MCFG_NES_CONTROL_PORT_ADD("ctrl2", fc_control_port2_devices, "joypad") + MCFG_FC_EXPANSION_PORT_ADD("exp", fc_expansion_devices, nullptr) + MCFG_NESCTRL_BRIGHTPIXEL_CB(nes_state, bright_pixel) + + MCFG_SOFTWARE_LIST_ADD("cass_list", "famicom_cass") +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( suborkbd, famipalc ) + /* TODO: emulate the parallel port bus! */ + MCFG_DEVICE_MODIFY("exp") + MCFG_SLOT_DEFAULT_OPTION("subor_keyboard") + MCFG_SLOT_FIXED(true) +MACHINE_CONFIG_END + void nes_state::setup_disk(nes_disksys_device *slot) { if (slot) @@ -285,6 +297,13 @@ ROM_START( m82 ) ROM_LOAD( "m82_v1_0.bin", 0x10000, 0x4000, CRC(7d56840a) SHA1(cbd2d14fa073273ba58367758f40d67fd8a9106d) ) ROM_END +ROM_START( m82p ) + /* same as m82 */ + ROM_REGION( 0x14000, "maincpu", 0 ) /* Main RAM + program banks */ + /* Banks to be mapped at 0xe000? More investigations needed... */ + ROM_LOAD( "m82_v1_0.bin", 0x10000, 0x4000, CRC(7d56840a) SHA1(cbd2d14fa073273ba58367758f40d67fd8a9106d) ) +ROM_END + // see http://www.disgruntleddesigner.com/chrisc/drpcjr/index.html // and http://www.disgruntleddesigner.com/chrisc/drpcjr/DrPCJrMemMap.txt ROM_START( drpcjr ) @@ -296,14 +315,30 @@ ROM_START( drpcjr ) // ROM_LOAD("drpcjr_v1_5_gg.bin", 0x10000, 0x8000, CRC(98f2033b) SHA1(93c114da787a19279d1a46667c2f69b49e25d4f1) ) ROM_END +ROM_START( iq501 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */ +ROM_END + +ROM_START( iq502 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */ +ROM_END + ROM_START( dendy ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */ ROM_END +ROM_START( dendy2 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */ +ROM_END + ROM_START( gchinatv ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */ ROM_END +ROM_START( sb486 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */ +ROM_END + /*************************************************************************** Game driver(s) @@ -311,12 +346,37 @@ ROM_END ***************************************************************************/ /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ -CONS( 1985, nes, 0, 0, nes, nes, driver_device, 0, "Nintendo", "Nintendo Entertainment System / Famicom (NTSC)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -CONS( 1987, nespal, nes, 0, nespal, nes, driver_device, 0, "Nintendo", "Nintendo Entertainment System (PAL)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -CONS( 1983, famicom, nes, 0, famicom, famicom, nes_state, famicom, "Nintendo", "Famicom (NTSC)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -CONS( 1983, fds, nes, 0, fds, famicom, nes_state, famicom, "Nintendo", "Famicom (w/ Disk System add-on)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -CONS( 1986, famitwin, nes, 0, famitwin, famicom, nes_state, famicom, "Sharp", "Famicom Twin", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -CONS( 198?, m82, nes, 0, nes, nes, driver_device, 0, "Nintendo", "M82 Display Unit", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) -CONS( 1996, drpcjr, nes, 0, famicom, famicom, nes_state, famicom, "Bung", "Doctor PC Jr", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -CONS( 1992, dendy, nes, 0, dendy, nes, driver_device, 0, "Steepler", "Dendy Classic", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -CONS( 198?, gchinatv, nes, 0, nespal, nes, driver_device, 0, "Golden China", "Golden China TV Game", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) + +/* Nintendo Entertainment System hardware */ +CONS( 1985, nes, 0, 0, nes, nes, driver_device, 0, "Nintendo", "Nintendo Entertainment System / Famicom (NTSC)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +CONS( 1987, nespal, nes, 0, nespal, nes, driver_device, 0, "Nintendo", "Nintendo Entertainment System (PAL)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +// M82 Display Unit +// supports up to twelve cartridge slots +CONS( 198?, m82, nes, 0, nes, nes, driver_device, 0, "Nintendo", "M82 Display Unit (NTSC)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +CONS( 198?, m82p, nes, 0, nespal, nes, driver_device, 0, "Nintendo", "M82 Display Unit (PAL)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) + +/* Famicom hardware */ +CONS( 1983, famicom, 0, 0, famicom, famicom, nes_state, famicom, "Nintendo", "Famicom", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +CONS( 1983, fds, famicom, 0, fds, famicom, nes_state, famicom, "Nintendo", "Famicom (w/ Disk System add-on)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +CONS( 1986, famitwin, famicom, 0, famitwin, famicom, nes_state, famicom, "Sharp", "Famicom Twin", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) + +/* Clone hardware */ +/* Many knockoffs using derivatives of the UMC board design, later incorporated into single CMOS chips, were manufactured before and past the end of the Famicom's timeline. */ + +/* !! PAL clones documented here !! */ +// Famicom-based +CONS( 1992, iq501, 0, 0, famipalc, nes, nes_state, famicom, "Micro Genius", "IQ-501", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +CONS( 1992, iq502, 0, 0, famipalc, nes, nes_state, famicom, "Micro Genius", "IQ-502", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +CONS( 1992, dendy, iq501, 0, famipalc, nes, nes_state, famicom, "Steepler", "Dendy Classic 1", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +CONS( 1992, dendy2, iq502, 0, famipalc, nes, nes_state, famicom, "Steepler", "Dendy Classic 2", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +CONS( 198?, gchinatv, 0, 0, famipalc, nes, nes_state, famicom, "Golden China", "Golden China TV Game", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) + +// Subor/Xiao Ba Wang hardware and derivatives +// These clones implement a keyboard and a parallel port for printing from a word processor. Later models have mice, PS/2 ports, serial ports and a floppy drive. +CONS( 1993, sb486, 0, 0, suborkbd, nes, nes_state, famicom, "Subor", "SB-486", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) + +/* !! NTSC clones documented here !! */ +// Famicom-based +// Bung hardware +// Mice, keyboard, etc, including a floppy drive that allows you to run games with a selection of 4 internal "mappers" available on the system. +CONS( 1996, drpcjr, 0, 0, famicom, famicom, nes_state, famicom, "Bung", "Doctor PC Jr", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) \ No newline at end of file diff --git a/src/mame/drivers/playch10.cpp b/src/mame/drivers/playch10.cpp index f3a5a5f8722..0e42d8bb727 100644 --- a/src/mame/drivers/playch10.cpp +++ b/src/mame/drivers/playch10.cpp @@ -303,8 +303,6 @@ Notes & Todo: #include "screen.h" #include "speaker.h" -/* clock frequency */ -#define N2A03_DEFAULTCLOCK (21477272.724 / 12) /******************************************************************************/ @@ -654,7 +652,7 @@ static MACHINE_CONFIG_START( playch10, playch10_state ) MCFG_CPU_IO_MAP(bios_io_map) MCFG_CPU_VBLANK_INT_DRIVER("top", playch10_state, playch10_interrupt) - MCFG_CPU_ADD("cart", N2A03, N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("cart", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(cart_map) diff --git a/src/mame/drivers/punchout.cpp b/src/mame/drivers/punchout.cpp index 0003da071d5..d3bc387214c 100644 --- a/src/mame/drivers/punchout.cpp +++ b/src/mame/drivers/punchout.cpp @@ -648,7 +648,7 @@ static MACHINE_CONFIG_START( punchout, punchout_state ) MCFG_CPU_IO_MAP(punchout_io_map) MCFG_CPU_VBLANK_INT_DRIVER("top", punchout_state, vblank_irq) - MCFG_CPU_ADD("audiocpu", N2A03, XTAL_21_4772MHz/12) + MCFG_CPU_ADD("audiocpu", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(punchout_sound_map) MCFG_CPU_VBLANK_INT_DRIVER("top", punchout_state, nmi_line_pulse) @@ -681,7 +681,7 @@ static MACHINE_CONFIG_START( punchout, punchout_state ) MCFG_GENERIC_LATCH_8_ADD("soundlatch") MCFG_GENERIC_LATCH_8_ADD("soundlatch2") - MCFG_SOUND_ADD("vlm", VLM5030, XTAL_21_4772MHz/6) + MCFG_SOUND_ADD("vlm", VLM5030, N2A03_NTSC_XTAL/6) MCFG_DEVICE_ADDRESS_MAP(AS_0, punchout_vlm_map) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.50) MACHINE_CONFIG_END diff --git a/src/mame/drivers/vsnes.cpp b/src/mame/drivers/vsnes.cpp index 0b27c15c664..8895a0710cf 100644 --- a/src/mame/drivers/vsnes.cpp +++ b/src/mame/drivers/vsnes.cpp @@ -1702,7 +1702,7 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( vsnes, vsnes_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", N2A03,N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("maincpu", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(vsnes_cpu1_map) /* some carts also trigger IRQs */ MCFG_MACHINE_RESET_OVERRIDE(vsnes_state,vsnes) @@ -1769,10 +1769,10 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_START( vsdual, vsnes_state ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", N2A03,N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("maincpu", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(vsnes_cpu1_map) /* some carts also trigger IRQs */ - MCFG_CPU_ADD("sub", N2A03,N2A03_DEFAULTCLOCK) + MCFG_CPU_ADD("sub", N2A03, NTSC_APU_CLOCK) MCFG_CPU_PROGRAM_MAP(vsnes_cpu2_map) /* some carts also trigger IRQs */ MCFG_MACHINE_RESET_OVERRIDE(vsnes_state,vsdual) diff --git a/src/mame/includes/nes.h b/src/mame/includes/nes.h index d6ce3d7761f..c9d5ec6470f 100644 --- a/src/mame/includes/nes.h +++ b/src/mame/includes/nes.h @@ -21,12 +21,8 @@ CONSTANTS ***************************************************************************/ -#define NTSC_CLOCK N2A03_DEFAULTCLOCK /* 1.789772 MHz */ -#define PAL_CLOCK (26601712.0/16) /* 1.662607 MHz */ - #define NES_BATTERY_SIZE 0x2000 - /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 7ee8a0b667b..6978bbbbd1c 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -29157,13 +29157,18 @@ nprsp // neptunp2 // @source:nes.cpp -dendy // Dendy (Classic russian famiclone) +iq501 // Micro Genius IQ-501 +iq502 // Micro Genius IQ-502 +dendy // Dendy Classic (Russian import of IQ-501 famiclone) +dendy2 // Dendy Classic 2 (Russian import of IQ-502 famiclone) +sb486 // Subor/Xiao Ba Wang SB-486 drpcjr // Bung Doctor PC Jr famicom // Nintendo Family Computer (a.k.a. Famicom) famitwin // Sharp Famicom Twin System fds // Nintendo Family Computer (a.k.a. Famicom) + Disk System add-on gchinatv // Golden China TV Game Centre (Chinese famiclone) m82 // Nintendo M82 Display Unit +m82p // Nintendo M82 Display Unit PAL nes // Nintendo Entertainment System nespal // Nintendo Entertainment System PAL