mirror of
https://github.com/holub/mame
synced 2025-04-16 21:44:32 +03:00
(MESS) famicom: converted the disk system add-on to be a cart
in the softlist. The official syntax to launch disk games is now mess famicom -cart disksys -flop gamename which corresponds to inserting the RAM expansion cart with connected the disk drive into the cartslot and the desired disk in the disk drive (exactly like you would have done with the real thing). In this way, you cannot mount anymore both a cart and a disk in the Family Computer (as in a real unit). Users that cannot cope with this limitation and/or with the new syntax can still use the famitwin driver (which offers both cart and disk options) or the newly added driver fds which emulates a famicom with the expansion always inserted: in both latter cases the old syntax mess famitwin -flop gamename will launch the game, as previously. [Fabio Priuli] (MESS) famicom: fixed disk system IRQ latch clear in Kaettekita Mario Bros. based on investigations by FHorse. [Fabio Priuli] Out of whatsnew: For the moment I gave up the original plan to also modernize the floppy drive and the disk format. If anyone wants to look into these, be my guest :-)
This commit is contained in:
parent
a7ca0bbba2
commit
af7242fcb4
21
hash/nes.xml
21
hash/nes.xml
@ -79008,4 +79008,25 @@ that the real dumps might surface -->
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- Romless cart for the RAM expansion + Disk System drive (drive ROM is included in the drive device) -->
|
||||
<software name="disksys">
|
||||
<description>Family Computer Disk System (Jpn)</description>
|
||||
<year>1986</year>
|
||||
<publisher>Nintendo</publisher>
|
||||
<info name="usage" value="This only is only supported by Famicom"/>
|
||||
<part name="cart" interface="nes_cart">
|
||||
<feature name="slot" value="disksys" />
|
||||
<!-- This is a fake and unused PRG dataarea to avoid changing the loading routines for the moment-->
|
||||
<dataarea name="prg" size="32768">
|
||||
<rom value="0xff" size="32768" offset="0" loadflag="fill" />
|
||||
</dataarea>
|
||||
<!-- 8k VRAM on cartridge -->
|
||||
<dataarea name="vram" size="8192">
|
||||
</dataarea>
|
||||
<!-- 32k WRAM on cartridge -->
|
||||
<dataarea name="wram" size="32768">
|
||||
</dataarea>
|
||||
</part>
|
||||
</software>
|
||||
|
||||
</softwarelist>
|
||||
|
@ -878,6 +878,7 @@ BUSOBJS += $(BUSOBJ)/nes/cne.o
|
||||
BUSOBJS += $(BUSOBJ)/nes/cony.o
|
||||
BUSOBJS += $(BUSOBJ)/nes/datach.o
|
||||
BUSOBJS += $(BUSOBJ)/nes/discrete.o
|
||||
BUSOBJS += $(BUSOBJ)/nes/disksys.o
|
||||
BUSOBJS += $(BUSOBJ)/nes/event.o
|
||||
BUSOBJS += $(BUSOBJ)/nes/ggenie.o
|
||||
BUSOBJS += $(BUSOBJ)/nes/henggedianzi.o
|
||||
|
@ -51,6 +51,8 @@ SLOT_INTERFACE_START(nes_cart)
|
||||
SLOT_INTERFACE_INTERNAL("txsrom", NES_TXSROM)
|
||||
// ExROM
|
||||
SLOT_INTERFACE_INTERNAL("exrom", NES_EXROM)
|
||||
// RAM expansion + Disk System add-on
|
||||
SLOT_INTERFACE_INTERNAL("disksys", NES_DISKSYS)
|
||||
// Nintendo Custom boards
|
||||
SLOT_INTERFACE_INTERNAL("pal_zz", NES_ZZ_PCB)
|
||||
SLOT_INTERFACE_INTERNAL("nes_qj", NES_QJ_PCB)
|
||||
@ -355,3 +357,8 @@ SLOT_INTERFACE_START(nes_cart)
|
||||
//
|
||||
SLOT_INTERFACE_INTERNAL("unknown", NES_NROM) // a few pirate dumps uses the wrong mapper...
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
SLOT_INTERFACE_START(disksys_only)
|
||||
// RAM expansion + Disk System add-on
|
||||
SLOT_INTERFACE("disksys", NES_DISKSYS)
|
||||
SLOT_INTERFACE_END
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "bandai.h"
|
||||
#include "datach.h"
|
||||
#include "discrete.h"
|
||||
#include "disksys.h"
|
||||
#include "event.h"
|
||||
#include "irem.h"
|
||||
#include "jaleco.h"
|
||||
@ -65,5 +66,6 @@
|
||||
|
||||
// supported devices
|
||||
SLOT_INTERFACE_EXTERN(nes_cart);
|
||||
SLOT_INTERFACE_EXTERN(disksys_only);
|
||||
|
||||
#endif // __NES_CARTS_H__
|
||||
|
@ -37,6 +37,7 @@ static const nes_pcb pcb_list[] =
|
||||
{ "tqrom", STD_TQROM },
|
||||
{ "txsrom", STD_TXSROM },
|
||||
{ "exrom", STD_EXROM },
|
||||
{ "disksys", STD_DISKSYS },
|
||||
{ "pal_zz", PAL_ZZ },
|
||||
{ "nes_qj", NES_QJ },
|
||||
{ "nes_event", STD_EVENT },
|
||||
|
@ -663,24 +663,30 @@ WRITE8_MEMBER(device_nes_cart_interface::write_h)
|
||||
}
|
||||
|
||||
|
||||
void device_nes_cart_interface::pcb_start(running_machine &machine, UINT8 *ciram_ptr)
|
||||
void device_nes_cart_interface::pcb_start(running_machine &machine, UINT8 *ciram_ptr, bool cart_mounted)
|
||||
{
|
||||
// Setup PRG
|
||||
m_prg_bank_mem[0] = machine.root_device().membank("prg0");
|
||||
m_prg_bank_mem[1] = machine.root_device().membank("prg1");
|
||||
m_prg_bank_mem[2] = machine.root_device().membank("prg2");
|
||||
m_prg_bank_mem[3] = machine.root_device().membank("prg3");
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (cart_mounted) // disksys expansion can arrive here without the memory banks!
|
||||
{
|
||||
m_prg_bank_mem[i]->configure_entries(0, m_prg.count() / 0x2000, m_prg, 0x2000);
|
||||
m_prg_bank_mem[i]->set_entry(i);
|
||||
m_prg_bank[i] = i;
|
||||
// Setup PRG
|
||||
m_prg_bank_mem[0] = machine.root_device().membank("prg0");
|
||||
m_prg_bank_mem[1] = machine.root_device().membank("prg1");
|
||||
m_prg_bank_mem[2] = machine.root_device().membank("prg2");
|
||||
m_prg_bank_mem[3] = machine.root_device().membank("prg3");
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (m_prg_bank_mem[i])
|
||||
{
|
||||
m_prg_bank_mem[i]->configure_entries(0, m_prg.count() / 0x2000, m_prg, 0x2000);
|
||||
m_prg_bank_mem[i]->set_entry(i);
|
||||
m_prg_bank[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup CHR
|
||||
m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
|
||||
chr8(0, m_chr_source);
|
||||
}
|
||||
|
||||
// Setup CHR
|
||||
m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
|
||||
chr8(0, m_chr_source);
|
||||
|
||||
// Setup NT
|
||||
m_ciram = ciram_ptr;
|
||||
|
||||
@ -733,7 +739,8 @@ nes_cart_slot_device::nes_cart_slot_device(const machine_config &mconfig, const
|
||||
device_slot_interface(mconfig, *this),
|
||||
m_crc_hack(0),
|
||||
m_pcb_id(NO_BOARD),
|
||||
m_must_be_loaded(1)
|
||||
m_must_be_loaded(1),
|
||||
m_empty(TRUE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -770,7 +777,7 @@ void nes_cart_slot_device::device_config_complete()
|
||||
void nes_cart_slot_device::pcb_start(UINT8 *ciram_ptr)
|
||||
{
|
||||
if (m_cart)
|
||||
m_cart->pcb_start(machine(), ciram_ptr);
|
||||
m_cart->pcb_start(machine(), ciram_ptr, cart_mounted());
|
||||
}
|
||||
|
||||
void nes_cart_slot_device::pcb_reset()
|
||||
@ -835,6 +842,7 @@ bool nes_cart_slot_device::call_load()
|
||||
}
|
||||
|
||||
call_load_ines();
|
||||
m_empty = FALSE;
|
||||
}
|
||||
else if ((magic[0] == 'U') && (magic[1] == 'N') && (magic[2] == 'I') && (magic[3] == 'F')) /* If header starts with 'UNIF' it is UNIF */
|
||||
{
|
||||
@ -845,6 +853,7 @@ bool nes_cart_slot_device::call_load()
|
||||
}
|
||||
|
||||
call_load_unif();
|
||||
m_empty = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -853,7 +862,10 @@ bool nes_cart_slot_device::call_load()
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
call_load_pcb();
|
||||
m_empty = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
|
@ -21,6 +21,7 @@ enum
|
||||
STD_UXROM, STD_UN1ROM, UXROM_CC,
|
||||
HVC_FAMBASIC, NES_QJ, PAL_ZZ, STD_EVENT,
|
||||
STD_SXROM_A, STD_SOROM, STD_SOROM_A,
|
||||
STD_DISKSYS,
|
||||
STD_NROM368,//homebrew extension of NROM!
|
||||
/* Discrete components boards (by various manufacturer) */
|
||||
DIS_74X161X138, DIS_74X139X74,
|
||||
@ -172,6 +173,9 @@ public:
|
||||
virtual DECLARE_READ8_MEMBER(nt_r);
|
||||
virtual DECLARE_WRITE8_MEMBER(nt_w);
|
||||
|
||||
// hack until disk system is made modern!
|
||||
virtual void disk_flip_side() { }
|
||||
|
||||
void prg_alloc(size_t size);
|
||||
void prgram_alloc(size_t size);
|
||||
void vrom_alloc(size_t size);
|
||||
@ -212,7 +216,7 @@ public:
|
||||
virtual void scanline_irq(int scanline, int vblank, int blanked) {}
|
||||
|
||||
virtual void pcb_reset() {} // many pcb expect specific PRG/CHR banking at start
|
||||
void pcb_start(running_machine &machine, UINT8 *ciram_ptr);
|
||||
void pcb_start(running_machine &machine, UINT8 *ciram_ptr, bool cart_mounted);
|
||||
void pcb_reg_postload(running_machine &machine);
|
||||
void nes_banks_restore();
|
||||
|
||||
@ -356,6 +360,7 @@ public:
|
||||
const char * get_default_card_unif(UINT8 *ROM, UINT32 len);
|
||||
const char * nes_get_slot(int pcb_id);
|
||||
int nes_get_pcb_id(const char *slot);
|
||||
bool cart_mounted() { return !m_empty; }
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
@ -366,7 +371,10 @@ public:
|
||||
virtual DECLARE_WRITE8_MEMBER(write_m);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_ex);
|
||||
|
||||
|
||||
// hack until disk system is made modern!
|
||||
virtual void disk_flip_side() { if (m_cart) m_cart->disk_flip_side(); }
|
||||
|
||||
int get_pcb_id() { return m_pcb_id; };
|
||||
|
||||
void pcb_start(UINT8 *ciram_ptr);
|
||||
@ -384,6 +392,7 @@ public:
|
||||
device_nes_cart_interface* m_cart;
|
||||
int m_pcb_id;
|
||||
bool m_must_be_loaded;
|
||||
bool m_empty;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
@ -401,4 +410,10 @@ extern const device_type NES_CART_SLOT;
|
||||
#define MCFG_NES_CARTRIDGE_NOT_MANDATORY \
|
||||
static_cast<nes_cart_slot_device *>(device)->set_must_be_loaded(FALSE);
|
||||
|
||||
// Hacky configuration to add a slot with fixed disksys interface
|
||||
#define MCFG_DISKSYS_ADD(_tag, _slot_intf, _def_slot) \
|
||||
MCFG_DEVICE_ADD(_tag, NES_CART_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, true) \
|
||||
MCFG_NES_CARTRIDGE_NOT_MANDATORY
|
||||
|
||||
#endif
|
||||
|
@ -13,8 +13,6 @@
|
||||
#include "emu.h"
|
||||
#include "includes/nes.h"
|
||||
#include "cpu/m6502/n2a03.h"
|
||||
#include "imagedev/flopdrv.h"
|
||||
#include "formats/nes_dsk.h"
|
||||
|
||||
READ8_MEMBER(nes_state::psg_4015_r)
|
||||
{
|
||||
@ -646,14 +644,6 @@ void nes_state::ppu_nmi(int *ppu_regs)
|
||||
}
|
||||
|
||||
|
||||
static const floppy_interface nes_floppy_interface =
|
||||
{
|
||||
FLOPPY_STANDARD_5_25_DSHD,
|
||||
LEGACY_FLOPPY_OPTIONS_NAME(nes_only),
|
||||
"floppy_5_25"
|
||||
};
|
||||
|
||||
|
||||
static MACHINE_CONFIG_START( nes, nes_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", N2A03, NTSC_CLOCK)
|
||||
@ -739,22 +729,108 @@ static MACHINE_CONFIG_DERIVED( dendy, nes )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( famicom, nes )
|
||||
MCFG_DEVICE_REMOVE("nes_slot")
|
||||
MCFG_NES_CARTRIDGE_ADD("nes_slot", nes_cart, NULL)
|
||||
MCFG_NES_CARTRIDGE_NOT_MANDATORY
|
||||
|
||||
MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, nes_floppy_interface)
|
||||
MCFG_SOFTWARE_LIST_ADD("flop_list", "famicom_flop")
|
||||
|
||||
MCFG_CASSETTE_ADD( "tape" )
|
||||
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED)
|
||||
MCFG_CASSETTE_INTERFACE("fc_cass")
|
||||
|
||||
MCFG_SOFTWARE_LIST_ADD("flop_list", "famicom_flop")
|
||||
MCFG_SOFTWARE_LIST_ADD("cass_list", "famicom_cass")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
void nes_state::setup_disk(nes_cart_slot_device *slot)
|
||||
{
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
if (slot)
|
||||
{
|
||||
// Set up memory handlers
|
||||
space.install_read_handler(0x4020, 0x40ff, read8_delegate(FUNC(nes_cart_slot_device::read_ex), (nes_cart_slot_device *)slot));
|
||||
space.install_write_handler(0x4020, 0x40ff, write8_delegate(FUNC(nes_cart_slot_device::write_ex), (nes_cart_slot_device *)slot));
|
||||
space.install_read_handler(0x4100, 0x5fff, read8_delegate(FUNC(nes_cart_slot_device::read_l), (nes_cart_slot_device *)slot));
|
||||
space.install_write_handler(0x4100, 0x5fff, write8_delegate(FUNC(nes_cart_slot_device::write_l), (nes_cart_slot_device *)slot));
|
||||
space.install_read_handler(0x6000, 0x7fff, read8_delegate(FUNC(nes_cart_slot_device::read_m), (nes_cart_slot_device *)slot));
|
||||
space.install_write_handler(0x6000, 0x7fff, write8_delegate(FUNC(nes_cart_slot_device::write_m), (nes_cart_slot_device *)slot));
|
||||
space.install_read_handler(0x8000, 0xffff, read8_delegate(FUNC(nes_cart_slot_device::read_h), (nes_cart_slot_device *)slot));
|
||||
space.install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(nes_cart_slot_device::write_h), (nes_cart_slot_device *)slot));
|
||||
|
||||
slot->m_cart->vram_alloc(0x2000);
|
||||
slot->m_cart->prgram_alloc(0x8000);
|
||||
|
||||
slot->pcb_start(m_ciram);
|
||||
slot->m_cart->pcb_reg_postload(machine());
|
||||
m_ppu->space(AS_PROGRAM).install_readwrite_handler(0, 0x1fff, read8_delegate(FUNC(device_nes_cart_interface::chr_r),slot->m_cart), write8_delegate(FUNC(device_nes_cart_interface::chr_w),slot->m_cart));
|
||||
m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(device_nes_cart_interface::nt_r),slot->m_cart), write8_delegate(FUNC(device_nes_cart_interface::nt_w),slot->m_cart));
|
||||
m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate(FUNC(device_nes_cart_interface::scanline_irq),slot->m_cart));
|
||||
m_ppu->set_hblank_callback(ppu2c0x_hblank_delegate(FUNC(device_nes_cart_interface::hblank_irq),slot->m_cart));
|
||||
m_ppu->set_latch(ppu2c0x_latch_delegate(FUNC(device_nes_cart_interface::ppu_latch),slot->m_cart));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MACHINE_START_MEMBER( nes_state, fds )
|
||||
{
|
||||
m_ciram = auto_alloc_array(machine(), UINT8, 0x800);
|
||||
setup_ioports();
|
||||
// setup the disk expansion instead
|
||||
setup_disk(m_cartslot);
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( fds, famicom )
|
||||
MCFG_MACHINE_START_OVERRIDE( nes_state, fds )
|
||||
MCFG_DEVICE_REMOVE("tape")
|
||||
|
||||
MCFG_DEVICE_REMOVE("nes_slot")
|
||||
MCFG_DISKSYS_ADD("nes_slot", disksys_only, "disksys")
|
||||
|
||||
MCFG_DEVICE_REMOVE("cart_list")
|
||||
MCFG_DEVICE_REMOVE("cass_list")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
MACHINE_START_MEMBER( nes_state, famitwin )
|
||||
{
|
||||
// start the base nes stuff
|
||||
machine_start();
|
||||
|
||||
// if there is no cart inserted, setup the disk expansion instead
|
||||
if (!m_cartslot->m_cart)
|
||||
setup_disk(m_cartslot2);
|
||||
}
|
||||
|
||||
MACHINE_RESET_MEMBER( nes_state, famitwin )
|
||||
{
|
||||
// Reset the mapper variables. Will also mark the char-gen ram as dirty
|
||||
m_cartslot->pcb_reset();
|
||||
// if there is no cart inserted, initialize the disk expansion instead
|
||||
if (!m_cartslot->m_cart)
|
||||
m_cartslot2->pcb_reset();
|
||||
|
||||
// the rest is the same as for nes/famicom/dendy
|
||||
m_maincpu->reset();
|
||||
|
||||
memset(m_pad_latch, 0, sizeof(m_pad_latch));
|
||||
memset(m_zapper_latch, 0, sizeof(m_zapper_latch));
|
||||
m_paddle_latch = 0;
|
||||
m_paddle_btn_latch = 0;
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( famitwin, famicom )
|
||||
|
||||
MCFG_MACHINE_START_OVERRIDE( nes_state, famitwin )
|
||||
MCFG_MACHINE_RESET_OVERRIDE( nes_state, famitwin )
|
||||
|
||||
MCFG_SCREEN_MODIFY("screen")
|
||||
MCFG_SCREEN_UPDATE_DRIVER(nes_state, screen_update_famitwin)
|
||||
|
||||
MCFG_DEVICE_REMOVE("nes_slot")
|
||||
MCFG_NES_CARTRIDGE_ADD("nes_slot", nes_cart, NULL)
|
||||
MCFG_NES_CARTRIDGE_NOT_MANDATORY
|
||||
|
||||
MCFG_DISKSYS_ADD("disk_slot", disksys_only, "disksys")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
|
||||
/* rom regions are just place-holders: they get removed and re-allocated when a cart is loaded */
|
||||
ROM_START( nes )
|
||||
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */
|
||||
ROM_END
|
||||
@ -764,13 +840,11 @@ ROM_START( nespal )
|
||||
ROM_END
|
||||
|
||||
ROM_START( famicom )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 ) /* Main RAM */
|
||||
ROM_SYSTEM_BIOS( 0, "2c33a-01a", "Famicom Disk System Bios")
|
||||
ROMX_LOAD( "rp2c33a-01a.bin", 0xe000, 0x2000, CRC(5e607dcf) SHA1(57fe1bdee955bb48d357e463ccbf129496930b62), ROM_BIOS(1)) // newer, Nintendo logo has no shadow
|
||||
ROM_SYSTEM_BIOS( 1, "2c33-01", "Famicom Disk System Bios, older")
|
||||
ROMX_LOAD( "rp2c33-01.bin", 0xe000, 0x2000, CRC(1c7ae5d5) SHA1(af5af53f66982e749643fdf8b2acbb7d4d3ed229), ROM_BIOS(2)) // older, Nintendo logo has shadow
|
||||
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */
|
||||
ROM_END
|
||||
|
||||
#define rom_fds rom_famicom
|
||||
|
||||
ROM_START( famitwin )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 ) /* Main RAM */
|
||||
ROM_LOAD( "rp2c33a-02.bin", 0xe000, 0x2000, CRC(4df24a6c) SHA1(e4e41472c454f928e53eb10e0509bf7d1146ecc1) ) // "Famicom" logo instead of Nintendo logo
|
||||
@ -799,7 +873,6 @@ ROM_END
|
||||
|
||||
ROM_START( gchinatv )
|
||||
ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) /* Main RAM */
|
||||
ROM_REGION( 0x800, "ciram", ROMREGION_ERASE00 ) /* CI RAM */
|
||||
ROM_END
|
||||
|
||||
/***************************************************************************
|
||||
@ -809,11 +882,12 @@ 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)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1987, nespal, nes, 0, nespal, nes, driver_device, 0, "Nintendo", "Nintendo Entertainment System (PAL)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1983, famicom, nes, 0, famicom, famicom, nes_state, famicom, "Nintendo", "Famicom (w/ Disk System add-on)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1986, famitwin, nes, 0, famicom, famicom, nes_state, famicom, "Sharp", "Famicom Twin", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 198?, m82, nes, 0, nes, nes, driver_device, 0, "Nintendo", "M82 Display Unit", GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1996, drpcjr, nes, 0, famicom, famicom, nes_state, famicom, "Bung", "Doctor PC Jr", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1992, dendy, nes, 0, dendy, nes, driver_device, 0, "Steepler", "Dendy Classic", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 198?, gchinatv, nes, 0, nespal, nes, driver_device, 0, "Golden China", "Golden China TV Game", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1985, nes, 0, 0, nes, nes, driver_device, 0, "Nintendo", "Nintendo Entertainment System / Famicom (NTSC)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1987, nespal, nes, 0, nespal, nes, driver_device, 0, "Nintendo", "Nintendo Entertainment System (PAL)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1983, famicom, nes, 0, famicom, famicom, nes_state, famicom, "Nintendo", "Famicom (NTSC)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1983, fds, nes, 0, fds, famicom, nes_state, famicom, "Nintendo", "Famicom (w/ Disk System add-on)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1986, famitwin, nes, 0, famitwin, famicom, nes_state, famicom, "Sharp", "Famicom Twin", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 198?, m82, nes, 0, nes, nes, driver_device, 0, "Nintendo", "M82 Display Unit", GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1996, drpcjr, nes, 0, famicom, famicom, nes_state, famicom, "Bung", "Doctor PC Jr", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1992, dendy, nes, 0, dendy, nes, driver_device, 0, "Steepler", "Dendy Classic", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
CONS( 198?, gchinatv, nes, 0, nespal, nes, driver_device, 0, "Golden China", "Golden China TV Game", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
m_ppu(*this, "ppu"),
|
||||
m_sound(*this, "nessound"),
|
||||
m_cartslot(*this, "nes_slot"),
|
||||
m_cartslot2(*this, "disk_slot"), // temp hack for famitwin
|
||||
m_cassette(*this, "tape")
|
||||
{ }
|
||||
|
||||
@ -76,7 +77,6 @@ public:
|
||||
int m_last_frame_flip;
|
||||
|
||||
/* misc */
|
||||
|
||||
ioport_port *m_io_ctrlsel;
|
||||
ioport_port *m_io_fckey[9];
|
||||
ioport_port *m_io_subkey[13];
|
||||
@ -95,6 +95,7 @@ public:
|
||||
ioport_port *m_io_paddle;
|
||||
ioport_port *m_io_paddle_btn;
|
||||
ioport_port *m_io_exp;
|
||||
ioport_port *m_io_disksel;
|
||||
|
||||
UINT8 *m_vram;
|
||||
UINT8 *m_ciram; //PPU nametable RAM - external to PPU!
|
||||
@ -103,6 +104,7 @@ public:
|
||||
required_device<ppu2c0x_device> m_ppu;
|
||||
required_device<nesapu_device> m_sound;
|
||||
optional_device<nes_cart_slot_device> m_cartslot;
|
||||
optional_device<nes_cart_slot_device> m_cartslot2;
|
||||
optional_device<cassette_image_device> m_cassette;
|
||||
|
||||
int nes_ppu_vidaccess(int address, int data);
|
||||
@ -122,48 +124,20 @@ public:
|
||||
virtual void video_reset();
|
||||
DECLARE_PALETTE_INIT(nes);
|
||||
UINT32 screen_update_nes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
UINT32 screen_update_famitwin(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_READ8_MEMBER(psg_4015_r);
|
||||
DECLARE_WRITE8_MEMBER(psg_4015_w);
|
||||
DECLARE_WRITE8_MEMBER(psg_4017_w);
|
||||
void state_register();
|
||||
void setup_ioports();
|
||||
|
||||
/***** FDS-floppy related *****/
|
||||
|
||||
DECLARE_WRITE8_MEMBER(fds_chr_w);
|
||||
DECLARE_READ8_MEMBER(fds_chr_r);
|
||||
DECLARE_WRITE8_MEMBER(fds_nt_w);
|
||||
DECLARE_READ8_MEMBER(fds_nt_r);
|
||||
|
||||
int m_disk_expansion;
|
||||
|
||||
UINT8 m_fds_sides;
|
||||
UINT8 *m_fds_data; // here, we store a copy of the disk
|
||||
UINT8 *m_fds_ram; // here, we emulate the RAM adapter
|
||||
|
||||
/* Variables which can change */
|
||||
UINT8 m_fds_motor_on;
|
||||
UINT8 m_fds_door_closed;
|
||||
UINT8 m_fds_current_side;
|
||||
UINT32 m_fds_head_position;
|
||||
UINT8 m_fds_status0;
|
||||
UINT8 m_fds_read_mode;
|
||||
UINT8 m_fds_write_reg;
|
||||
int m_fds_mirroring;
|
||||
|
||||
int m_IRQ_enable, m_IRQ_enable_latch;
|
||||
UINT16 m_IRQ_count, m_IRQ_count_latch;
|
||||
|
||||
/* these are used in the mapper 20 handlers */
|
||||
int m_fds_last_side;
|
||||
int m_fds_count;
|
||||
DECLARE_READ8_MEMBER(nes_fds_r);
|
||||
DECLARE_WRITE8_MEMBER(nes_fds_w);
|
||||
DECLARE_DRIVER_INIT(famicom);
|
||||
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(nes_disk);
|
||||
DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(nes_disk);
|
||||
|
||||
void fds_irq(int scanline, int vblank, int blanked);
|
||||
// these are needed until we modernize the FDS controller
|
||||
DECLARE_MACHINE_START(fds);
|
||||
DECLARE_MACHINE_START(famitwin);
|
||||
DECLARE_MACHINE_RESET(famitwin);
|
||||
void setup_disk(nes_cart_slot_device *slot);
|
||||
|
||||
// input related
|
||||
UINT32 m_pad_latch[4];
|
||||
|
@ -34,12 +34,14 @@ int nes_state::nes_ppu_vidaccess( int address, int data )
|
||||
return data;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void nes_state::machine_reset()
|
||||
{
|
||||
/* Reset the mapper variables. Will also mark the char-gen ram as dirty */
|
||||
if (m_disk_expansion && m_cartslot && !m_cartslot->m_cart)
|
||||
m_ppu->set_hblank_callback(ppu2c0x_hblank_delegate(FUNC(nes_state::fds_irq),this));
|
||||
else if (m_cartslot)
|
||||
// Reset the mapper variables. Will also mark the char-gen ram as dirty
|
||||
if (m_cartslot)
|
||||
m_cartslot->pcb_reset();
|
||||
|
||||
m_maincpu->reset();
|
||||
@ -50,26 +52,16 @@ void nes_state::machine_reset()
|
||||
m_paddle_btn_latch = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_start
|
||||
//-------------------------------------------------
|
||||
|
||||
void nes_state::state_register()
|
||||
{
|
||||
save_item(NAME(m_last_frame_flip));
|
||||
|
||||
save_item(NAME(m_fds_motor_on));
|
||||
save_item(NAME(m_fds_door_closed));
|
||||
save_item(NAME(m_fds_current_side));
|
||||
save_item(NAME(m_fds_head_position));
|
||||
save_item(NAME(m_fds_status0));
|
||||
save_item(NAME(m_fds_read_mode));
|
||||
save_item(NAME(m_fds_write_reg));
|
||||
save_item(NAME(m_fds_last_side));
|
||||
save_item(NAME(m_fds_count));
|
||||
save_item(NAME(m_fds_mirroring));
|
||||
|
||||
save_pointer(NAME(m_ciram), 0x800);
|
||||
|
||||
if (m_disk_expansion)
|
||||
save_pointer(NAME(m_vram), 0x2000);
|
||||
|
||||
save_item(NAME(m_pad_latch));
|
||||
save_item(NAME(m_zapper_latch));
|
||||
save_item(NAME(m_paddle_latch));
|
||||
@ -80,18 +72,9 @@ void nes_state::state_register()
|
||||
save_item(NAME(m_mic_obstruct));
|
||||
save_item(NAME(m_powerpad_latch));
|
||||
save_item(NAME(m_ftrainer_scan));
|
||||
save_item(NAME(m_IRQ_enable));
|
||||
save_item(NAME(m_IRQ_enable_latch));
|
||||
save_item(NAME(m_IRQ_count));
|
||||
save_item(NAME(m_IRQ_count_latch));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// machine_start
|
||||
//-------------------------------------------------
|
||||
|
||||
void nes_state::machine_start()
|
||||
void nes_state::setup_ioports()
|
||||
{
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
@ -115,7 +98,7 @@ void nes_state::machine_start()
|
||||
sprintf(str, "FT_COL%i", i);
|
||||
m_io_ftrainer[i] = ioport(str);
|
||||
}
|
||||
|
||||
|
||||
m_io_ctrlsel = ioport("CTRLSEL");
|
||||
m_io_exp = ioport("EXP");
|
||||
m_io_paddle = ioport("PADDLE");
|
||||
@ -130,7 +113,11 @@ void nes_state::machine_start()
|
||||
m_io_zapper2_y = ioport("ZAPPER2_Y");
|
||||
m_io_powerpad[0] = ioport("POWERPAD1");
|
||||
m_io_powerpad[1] = ioport("POWERPAD2");
|
||||
m_io_disksel = ioport("FLIPDISK");
|
||||
}
|
||||
|
||||
void nes_state::machine_start()
|
||||
{
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
|
||||
// CIRAM (Character Internal RAM)
|
||||
@ -140,6 +127,8 @@ void nes_state::machine_start()
|
||||
m_ciram = auto_alloc_array(machine(), UINT8, 0x800);
|
||||
// other pointers got set in the loading routine, because they 'belong' to the cart itself
|
||||
|
||||
setup_ioports();
|
||||
|
||||
if (m_cartslot && m_cartslot->m_cart)
|
||||
{
|
||||
// Set up memory handlers
|
||||
@ -153,8 +142,6 @@ void nes_state::machine_start()
|
||||
space.install_read_bank(0xe000, 0xffff, "prg3");
|
||||
space.install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(nes_cart_slot_device::write_h), (nes_cart_slot_device *)m_cartslot));
|
||||
|
||||
m_cartslot->pcb_start(m_ciram);
|
||||
m_cartslot->m_cart->pcb_reg_postload(machine());
|
||||
m_ppu->space(AS_PROGRAM).install_readwrite_handler(0, 0x1fff, read8_delegate(FUNC(device_nes_cart_interface::chr_r),m_cartslot->m_cart), write8_delegate(FUNC(device_nes_cart_interface::chr_w),m_cartslot->m_cart));
|
||||
m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(device_nes_cart_interface::nt_r),m_cartslot->m_cart), write8_delegate(FUNC(device_nes_cart_interface::nt_w),m_cartslot->m_cart));
|
||||
m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate(FUNC(device_nes_cart_interface::scanline_irq),m_cartslot->m_cart));
|
||||
@ -162,7 +149,7 @@ void nes_state::machine_start()
|
||||
m_ppu->set_latch(ppu2c0x_latch_delegate(FUNC(device_nes_cart_interface::ppu_latch),m_cartslot->m_cart));
|
||||
|
||||
// install additional handlers (read_h, read_ex, write_ex)
|
||||
if (m_cartslot->get_pcb_id() == STD_EXROM || m_cartslot->get_pcb_id() == STD_NROM368
|
||||
if (m_cartslot->get_pcb_id() == STD_EXROM || m_cartslot->get_pcb_id() == STD_NROM368 || m_cartslot->get_pcb_id() == STD_DISKSYS
|
||||
|| m_cartslot->get_pcb_id() == GG_NROM || m_cartslot->get_pcb_id() == CAMERICA_ALADDIN || m_cartslot->get_pcb_id() == SUNSOFT_DCS
|
||||
|| m_cartslot->get_pcb_id() == BANDAI_DATACH || m_cartslot->get_pcb_id() == BANDAI_KARAOKE || m_cartslot->get_pcb_id() == BTL_2A03_PURITANS || m_cartslot->get_pcb_id() == AVE_MAXI15
|
||||
|| m_cartslot->get_pcb_id() == KAISER_KS7022 || m_cartslot->get_pcb_id() == KAISER_KS7031 || m_cartslot->get_pcb_id() == BMC_VT5201
|
||||
@ -181,32 +168,15 @@ void nes_state::machine_start()
|
||||
space.install_write_handler(0x4020, 0x40ff, write8_delegate(FUNC(nes_cart_slot_device::write_ex), (nes_cart_slot_device *)m_cartslot));
|
||||
}
|
||||
|
||||
if (m_cartslot->get_pcb_id() == KAISER_KS7017 || m_cartslot->get_pcb_id() == UNL_603_5052)
|
||||
if (m_cartslot->get_pcb_id() == KAISER_KS7017 || m_cartslot->get_pcb_id() == UNL_603_5052 || m_cartslot->get_pcb_id() == STD_DISKSYS)
|
||||
{
|
||||
logerror("write_ex & read_ex installed!\n");
|
||||
space.install_read_handler(0x4020, 0x40ff, read8_delegate(FUNC(nes_cart_slot_device::read_ex), (nes_cart_slot_device *)m_cartslot));
|
||||
space.install_write_handler(0x4020, 0x40ff, write8_delegate(FUNC(nes_cart_slot_device::write_ex), (nes_cart_slot_device *)m_cartslot));
|
||||
}
|
||||
}
|
||||
else if (m_disk_expansion) // if there is Disk Expansion and no cart has been loaded, setup memory accordingly
|
||||
{
|
||||
m_ppu->space(AS_PROGRAM).install_readwrite_handler(0, 0x1fff, read8_delegate(FUNC(nes_state::fds_chr_r),this), write8_delegate(FUNC(nes_state::fds_chr_w),this));
|
||||
m_ppu->space(AS_PROGRAM).install_readwrite_handler(0x2000, 0x3eff, read8_delegate(FUNC(nes_state::fds_nt_r),this), write8_delegate(FUNC(nes_state::fds_nt_w),this));
|
||||
|
||||
if (!m_fds_ram)
|
||||
m_fds_ram = auto_alloc_array(machine(), UINT8, 0x8000);
|
||||
if (!m_vram)
|
||||
m_vram = auto_alloc_array(machine(), UINT8, 0x2000);
|
||||
|
||||
space.install_read_handler(0x4030, 0x403f, read8_delegate(FUNC(nes_state::nes_fds_r),this));
|
||||
space.install_read_bank(0x6000, 0xdfff, "fdsram");
|
||||
space.install_read_bank(0xe000, 0xffff, "bank1");
|
||||
|
||||
space.install_write_handler(0x4020, 0x402f, write8_delegate(FUNC(nes_state::nes_fds_w),this));
|
||||
space.install_write_bank(0x6000, 0xdfff, "fdsram");
|
||||
|
||||
membank("bank1")->set_base(machine().root_device().memregion("maincpu")->base() + 0xe000);
|
||||
membank("fdsram")->set_base(m_fds_ram);
|
||||
m_cartslot->pcb_start(m_ciram);
|
||||
m_cartslot->m_cart->pcb_reg_postload(machine());
|
||||
}
|
||||
|
||||
state_register();
|
||||
@ -734,242 +704,8 @@ void nes_state::device_timer(emu_timer &timer, device_timer_id id, int param, vo
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
|
||||
Disk System emulation
|
||||
|
||||
**************************/
|
||||
|
||||
void nes_state::fds_irq( int scanline, int vblank, int blanked )
|
||||
{
|
||||
if (m_IRQ_enable_latch)
|
||||
m_maincpu->set_input_line(M6502_IRQ_LINE, HOLD_LINE);
|
||||
|
||||
if (m_IRQ_enable)
|
||||
{
|
||||
if (m_IRQ_count <= 114)
|
||||
{
|
||||
m_maincpu->set_input_line(M6502_IRQ_LINE, HOLD_LINE);
|
||||
m_IRQ_enable = 0;
|
||||
m_fds_status0 |= 0x01;
|
||||
}
|
||||
else
|
||||
m_IRQ_count -= 114;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(nes_state::nes_fds_r)
|
||||
{
|
||||
UINT8 ret = 0x00;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00: /* $4030 - disk status 0 */
|
||||
ret = m_fds_status0;
|
||||
/* clear the disk IRQ detect flag */
|
||||
m_fds_status0 &= ~0x01;
|
||||
break;
|
||||
case 0x01: /* $4031 - data latch */
|
||||
/* don't read data if disk is unloaded */
|
||||
if (!m_fds_data)
|
||||
ret = 0;
|
||||
else if (m_fds_current_side)
|
||||
{
|
||||
// a bunch of games (e.g. bshashsc and fairypin) keep reading beyond the last track
|
||||
// what is the expected behavior?
|
||||
if (m_fds_head_position > 65500)
|
||||
m_fds_head_position = 0;
|
||||
ret = m_fds_data[(m_fds_current_side - 1) * 65500 + m_fds_head_position++];
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
break;
|
||||
case 0x02: /* $4032 - disk status 1 */
|
||||
/* return "no disk" status if disk is unloaded */
|
||||
if (!m_fds_data)
|
||||
ret = 1;
|
||||
else if (m_fds_last_side != m_fds_current_side)
|
||||
{
|
||||
/* If we've switched disks, report "no disk" for a few reads */
|
||||
ret = 1;
|
||||
m_fds_count++;
|
||||
if (m_fds_count == 50)
|
||||
{
|
||||
m_fds_last_side = m_fds_current_side;
|
||||
m_fds_count = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = (m_fds_current_side == 0); /* 0 if a disk is inserted */
|
||||
break;
|
||||
case 0x03: /* $4033 */
|
||||
ret = 0x80;
|
||||
break;
|
||||
default:
|
||||
ret = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(nes_state::nes_fds_w)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
m_IRQ_count_latch = (m_IRQ_count_latch & 0xff00) | data;
|
||||
break;
|
||||
case 0x01:
|
||||
m_IRQ_count_latch = (m_IRQ_count_latch & 0x00ff) | (data << 8);
|
||||
break;
|
||||
case 0x02:
|
||||
m_IRQ_count = m_IRQ_count_latch;
|
||||
m_IRQ_enable = data;
|
||||
break;
|
||||
case 0x03:
|
||||
// d0 = sound io (1 = enable)
|
||||
// d1 = disk io (1 = enable)
|
||||
break;
|
||||
case 0x04:
|
||||
/* write data out to disk */
|
||||
break;
|
||||
case 0x05:
|
||||
m_fds_motor_on = BIT(data, 0);
|
||||
|
||||
if (BIT(data, 1))
|
||||
m_fds_head_position = 0;
|
||||
|
||||
m_fds_read_mode = BIT(data, 2);
|
||||
if (BIT(data, 3))
|
||||
m_fds_mirroring = PPU_MIRROR_HORZ;
|
||||
else
|
||||
m_fds_mirroring = PPU_MIRROR_VERT;
|
||||
|
||||
if ((!(data & 0x40)) && (m_fds_write_reg & 0x40))
|
||||
m_fds_head_position -= 2; // ???
|
||||
|
||||
m_IRQ_enable_latch = BIT(data, 7);
|
||||
m_fds_write_reg = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(nes_state::fds_chr_w)
|
||||
{
|
||||
m_vram[offset] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(nes_state::fds_chr_r)
|
||||
{
|
||||
return m_vram[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(nes_state::fds_nt_w)
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
int bank;
|
||||
|
||||
switch (page)
|
||||
{
|
||||
case 0:
|
||||
bank = 0;
|
||||
break;
|
||||
case 1:
|
||||
bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 1 : 0;
|
||||
break;
|
||||
case 2:
|
||||
bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 0 : 1;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
bank = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
m_ciram[(bank * 0x400) + (offset & 0x3ff)] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(nes_state::fds_nt_r)
|
||||
{
|
||||
int page = ((offset & 0xc00) >> 10);
|
||||
int bank;
|
||||
|
||||
switch (page)
|
||||
{
|
||||
case 0:
|
||||
bank = 0;
|
||||
break;
|
||||
case 1:
|
||||
bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 1 : 0;
|
||||
break;
|
||||
case 2:
|
||||
bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 0 : 1;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
bank = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return m_ciram[(bank * 0x400) + (offset & 0x3ff)];
|
||||
}
|
||||
|
||||
|
||||
// Disk interface
|
||||
|
||||
static void nes_load_proc( device_image_interface &image )
|
||||
{
|
||||
nes_state *state = image.device().machine().driver_data<nes_state>();
|
||||
int header = 0;
|
||||
state->m_fds_sides = 0;
|
||||
|
||||
if (image.length() % 65500)
|
||||
header = 0x10;
|
||||
|
||||
state->m_fds_sides = (image.length() - header) / 65500;
|
||||
|
||||
if (!state->m_fds_data)
|
||||
state->m_fds_data = auto_alloc_array(image.device().machine(),UINT8,state->m_fds_sides * 65500); // I don't think we can arrive here ever, probably it can be removed...
|
||||
|
||||
/* if there is an header, skip it */
|
||||
image.fseek(header, SEEK_SET);
|
||||
|
||||
image.fread(state->m_fds_data, 65500 * state->m_fds_sides);
|
||||
return;
|
||||
}
|
||||
|
||||
static void nes_unload_proc( device_image_interface &image )
|
||||
{
|
||||
nes_state *state = image.device().machine().driver_data<nes_state>();
|
||||
|
||||
/* TODO: should write out changes here as well */
|
||||
state->m_fds_sides = 0;
|
||||
}
|
||||
|
||||
DRIVER_INIT_MEMBER(nes_state,famicom)
|
||||
{
|
||||
/* initialize the disk system */
|
||||
m_disk_expansion = 1;
|
||||
|
||||
m_fds_sides = 0;
|
||||
m_fds_last_side = 0;
|
||||
m_fds_count = 0;
|
||||
m_fds_motor_on = 0;
|
||||
m_fds_door_closed = 0;
|
||||
m_fds_current_side = 1;
|
||||
m_fds_head_position = 0;
|
||||
m_fds_status0 = 0;
|
||||
m_fds_read_mode = m_fds_write_reg = 0;
|
||||
|
||||
m_fds_mirroring = PPU_MIRROR_VERT; // correct?
|
||||
|
||||
m_fds_ram = auto_alloc_array_clear(machine(), UINT8, 0x8000);
|
||||
save_pointer(NAME(m_fds_ram), 0x8000);
|
||||
|
||||
floppy_get_device(machine(), 0)->floppy_install_load_proc(nes_load_proc);
|
||||
floppy_get_device(machine(), 0)->floppy_install_unload_proc(nes_unload_proc);
|
||||
|
||||
// setup alt input handlers for additional FC input devices
|
||||
address_space &space = machine().device<cpu_device>("maincpu")->space(AS_PROGRAM);
|
||||
space.install_read_handler(0x4016, 0x4016, read8_delegate(FUNC(nes_state::fc_in0_r), this));
|
||||
|
@ -56,12 +56,14 @@ jaguarcd // Atari Jaguar CD
|
||||
|
||||
// Nintendo
|
||||
nes // Nintendo Entertainment System
|
||||
nespal // Nintendo Entertainment System PAL
|
||||
nespal // Nintendo Entertainment System PAL
|
||||
m82 // Nintendo M82 Display Unit
|
||||
famicom // Nintendo Family Computer (a.k.a. Famicom) + Disk System add-on
|
||||
famicom // Nintendo Family Computer (a.k.a. Famicom)
|
||||
fds // Nintendo Family Computer (a.k.a. Famicom) + Disk System add-on
|
||||
famitwin // Sharp Famicom Twin System
|
||||
drpcjr // Bung Doctor PC Jr
|
||||
dendy // Dendy (Classic russian famiclone)
|
||||
gchinatv // Golden China TV Game Centre (Chinese famiclone)
|
||||
gameboy // Nintendo Game Boy Handheld
|
||||
supergb // Nintendo Super Game Boy SNES Cartridge
|
||||
gbpocket // Nintendo Game Boy Pocket Handheld
|
||||
@ -72,7 +74,6 @@ snespal // Nintendo Super Nintendo PAL
|
||||
n64 // Nintendo N64
|
||||
n64dd // Nintendo N64 (64DD Attachment)
|
||||
pokemini // Nintendo Pokemon Mini
|
||||
gchinatv // Golden China TV Game Centre
|
||||
|
||||
megaduck // Megaduck
|
||||
|
||||
|
@ -33,27 +33,43 @@ PALETTE_INIT_MEMBER(nes_state, nes)
|
||||
|
||||
UINT32 nes_state::screen_update_nes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* render the ppu */
|
||||
// render the ppu
|
||||
m_ppu->render(bitmap, 0, 0, 0, 0);
|
||||
|
||||
/* if this is a disk system game, check for the flip-disk key */
|
||||
if (m_disk_expansion && m_cartslot && !m_cartslot->m_cart)
|
||||
// if this is a disk system game, check for the flip-disk key
|
||||
if (m_cartslot &&
|
||||
(m_cartslot->get_pcb_id() == STD_DISKSYS // first scenario = disksys in m_cartslot (= famicom)
|
||||
|| !m_cartslot->cart_mounted())) // second scenario = disk via fixed internal option (= fds)
|
||||
{
|
||||
// latch this input so it doesn't go at warp speed
|
||||
if ((ioport("FLIPDISK")->read() & 0x01) && (!m_last_frame_flip))
|
||||
if ((m_io_disksel->read_safe(0) & 0x01) && (!m_last_frame_flip))
|
||||
{
|
||||
m_cartslot->disk_flip_side();
|
||||
m_last_frame_flip = 1;
|
||||
m_fds_current_side++;
|
||||
if (m_fds_current_side > m_fds_sides)
|
||||
m_fds_current_side = 0;
|
||||
|
||||
if (m_fds_current_side == 0)
|
||||
popmessage("No disk inserted.");
|
||||
else
|
||||
popmessage("Disk set to side %d", m_fds_current_side);
|
||||
}
|
||||
|
||||
if (!(ioport("FLIPDISK")->read() & 0x01))
|
||||
if (!m_io_disksel->read_safe(1) & 0x01)
|
||||
m_last_frame_flip = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Alternative version to support "Disk flip hack" also in the Famicom Twin System (to be removed soonish!)
|
||||
UINT32 nes_state::screen_update_famitwin(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// render the ppu
|
||||
m_ppu->render(bitmap, 0, 0, 0, 0);
|
||||
|
||||
if (m_cartslot2 && !m_cartslot2->cart_mounted())
|
||||
{
|
||||
// latch this input so it doesn't go at warp speed
|
||||
if ((m_io_disksel->read_safe(0) & 0x01) && (!m_last_frame_flip))
|
||||
{
|
||||
m_cartslot2->disk_flip_side();
|
||||
m_last_frame_flip = 1;
|
||||
}
|
||||
|
||||
if (!m_io_disksel->read_safe(1) & 0x01)
|
||||
m_last_frame_flip = 0;
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user