Previous 199869 Revisions Next

r32067 Thursday 11th September, 2014 at 21:01:45 UTC by Fabio Priuli
(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 :-)
[hash]nes.xml
[src/emu/bus]bus.mak
[src/emu/bus/nes]nes_carts.c nes_carts.h nes_pcb.inc nes_slot.c nes_slot.h
[src/mess]mess.lst
[src/mess/drivers]nes.c
[src/mess/includes]nes.h
[src/mess/machine]nes.c
[src/mess/video]nes.c

trunk/src/emu/bus/nes/nes_carts.c
r32066r32067
5151   SLOT_INTERFACE_INTERNAL("txsrom",           NES_TXSROM)
5252// ExROM
5353   SLOT_INTERFACE_INTERNAL("exrom",            NES_EXROM)
54// RAM expansion + Disk System add-on
55   SLOT_INTERFACE_INTERNAL("disksys",          NES_DISKSYS)
5456// Nintendo Custom boards
5557   SLOT_INTERFACE_INTERNAL("pal_zz",           NES_ZZ_PCB)
5658   SLOT_INTERFACE_INTERNAL("nes_qj",           NES_QJ_PCB)
r32066r32067
355357//
356358   SLOT_INTERFACE_INTERNAL("unknown",          NES_NROM)  //  a few pirate dumps uses the wrong mapper...
357359SLOT_INTERFACE_END
360
361SLOT_INTERFACE_START(disksys_only)
362   // RAM expansion + Disk System add-on
363   SLOT_INTERFACE("disksys",                   NES_DISKSYS)
364SLOT_INTERFACE_END
trunk/src/emu/bus/nes/nes_slot.c
r32066r32067
663663}
664664
665665
666void device_nes_cart_interface::pcb_start(running_machine &machine, UINT8 *ciram_ptr)
666void device_nes_cart_interface::pcb_start(running_machine &machine, UINT8 *ciram_ptr, bool cart_mounted)
667667{
668   // Setup PRG
669   m_prg_bank_mem[0] = machine.root_device().membank("prg0");
670   m_prg_bank_mem[1] = machine.root_device().membank("prg1");
671   m_prg_bank_mem[2] = machine.root_device().membank("prg2");
672   m_prg_bank_mem[3] = machine.root_device().membank("prg3");
673   for (int i = 0; i < 4; i++)
668   if (cart_mounted)      // disksys expansion can arrive here without the memory banks!
674669   {
675      m_prg_bank_mem[i]->configure_entries(0, m_prg.count() / 0x2000, m_prg, 0x2000);
676      m_prg_bank_mem[i]->set_entry(i);
677      m_prg_bank[i] = i;
670      // Setup PRG
671      m_prg_bank_mem[0] = machine.root_device().membank("prg0");
672      m_prg_bank_mem[1] = machine.root_device().membank("prg1");
673      m_prg_bank_mem[2] = machine.root_device().membank("prg2");
674      m_prg_bank_mem[3] = machine.root_device().membank("prg3");
675      for (int i = 0; i < 4; i++)
676      {
677         if (m_prg_bank_mem[i])
678         {
679            m_prg_bank_mem[i]->configure_entries(0, m_prg.count() / 0x2000, m_prg, 0x2000);
680            m_prg_bank_mem[i]->set_entry(i);
681            m_prg_bank[i] = i;
682         }
683      }
684     
685      // Setup CHR
686      m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
687      chr8(0, m_chr_source);
678688   }
679689
680   // Setup CHR
681   m_chr_source = m_vrom_chunks ? CHRROM : CHRRAM;
682   chr8(0, m_chr_source);
683
684690   // Setup NT
685691   m_ciram = ciram_ptr;
686692
r32066r32067
733739                  device_slot_interface(mconfig, *this),
734740                  m_crc_hack(0),
735741                  m_pcb_id(NO_BOARD),
736                  m_must_be_loaded(1)
742                  m_must_be_loaded(1),
743                  m_empty(TRUE)
737744{
738745}
739746
r32066r32067
770777void nes_cart_slot_device::pcb_start(UINT8 *ciram_ptr)
771778{
772779   if (m_cart)
773      m_cart->pcb_start(machine(), ciram_ptr);
780      m_cart->pcb_start(machine(), ciram_ptr, cart_mounted());
774781}
775782
776783void nes_cart_slot_device::pcb_reset()
r32066r32067
835842            }
836843
837844            call_load_ines();
845            m_empty = FALSE;
838846         }
839847         else if ((magic[0] == 'U') && (magic[1] == 'N') && (magic[2] == 'I') && (magic[3] == 'F')) /* If header starts with 'UNIF' it is UNIF */
840848         {
r32066r32067
845853            }
846854
847855            call_load_unif();
856            m_empty = FALSE;
848857         }
849858         else
850859         {
r32066r32067
853862         }
854863      }
855864      else
865      {
856866         call_load_pcb();
867         m_empty = FALSE;
868      }
857869   }
858870
859871   return IMAGE_INIT_PASS;
trunk/src/emu/bus/nes/nes_carts.h
r32066r32067
2020#include "bandai.h"
2121#include "datach.h"
2222#include "discrete.h"
23#include "disksys.h"
2324#include "event.h"
2425#include "irem.h"
2526#include "jaleco.h"
r32066r32067
6566
6667// supported devices
6768SLOT_INTERFACE_EXTERN(nes_cart);
69SLOT_INTERFACE_EXTERN(disksys_only);
6870
6971#endif // __NES_CARTS_H__
trunk/src/emu/bus/nes/nes_slot.h
r32066r32067
2121   STD_UXROM, STD_UN1ROM, UXROM_CC,
2222   HVC_FAMBASIC, NES_QJ, PAL_ZZ, STD_EVENT,
2323   STD_SXROM_A, STD_SOROM, STD_SOROM_A,
24   STD_DISKSYS,
2425   STD_NROM368,//homebrew extension of NROM!
2526   /* Discrete components boards (by various manufacturer) */
2627   DIS_74X161X138, DIS_74X139X74,
r32066r32067
172173   virtual DECLARE_READ8_MEMBER(nt_r);
173174   virtual DECLARE_WRITE8_MEMBER(nt_w);
174175
176   // hack until disk system is made modern!
177   virtual void disk_flip_side() { }
178
175179   void prg_alloc(size_t size);
176180   void prgram_alloc(size_t size);
177181   void vrom_alloc(size_t size);
r32066r32067
212216   virtual void scanline_irq(int scanline, int vblank, int blanked) {}
213217
214218   virtual void pcb_reset() {} // many pcb expect specific PRG/CHR banking at start
215   void pcb_start(running_machine &machine, UINT8 *ciram_ptr);
219   void pcb_start(running_machine &machine, UINT8 *ciram_ptr, bool cart_mounted);
216220   void pcb_reg_postload(running_machine &machine);
217221   void nes_banks_restore();
218222
r32066r32067
356360   const char * get_default_card_unif(UINT8 *ROM, UINT32 len);
357361   const char * nes_get_slot(int pcb_id);
358362   int nes_get_pcb_id(const char *slot);
363   bool cart_mounted() { return !m_empty; }
359364
360365   // reading and writing
361366   virtual DECLARE_READ8_MEMBER(read_l);
r32066r32067
366371   virtual DECLARE_WRITE8_MEMBER(write_m);
367372   virtual DECLARE_WRITE8_MEMBER(write_h);
368373   virtual DECLARE_WRITE8_MEMBER(write_ex);
369
374   
375   // hack until disk system is made modern!
376   virtual void disk_flip_side() { if (m_cart) m_cart->disk_flip_side(); }
377   
370378   int get_pcb_id() { return m_pcb_id; };
371379
372380   void pcb_start(UINT8 *ciram_ptr);
r32066r32067
384392   device_nes_cart_interface*      m_cart;
385393   int m_pcb_id;
386394   bool                            m_must_be_loaded;
395   bool                            m_empty;
387396};
388397
389398// device type definition
r32066r32067
401410#define MCFG_NES_CARTRIDGE_NOT_MANDATORY                                     \
402411   static_cast<nes_cart_slot_device *>(device)->set_must_be_loaded(FALSE);
403412
413// Hacky configuration to add a slot with fixed disksys interface
414#define MCFG_DISKSYS_ADD(_tag, _slot_intf, _def_slot) \
415   MCFG_DEVICE_ADD(_tag, NES_CART_SLOT, 0) \
416   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, true) \
417   MCFG_NES_CARTRIDGE_NOT_MANDATORY
418
404419#endif
trunk/src/emu/bus/nes/nes_pcb.inc
r32066r32067
3737   { "tqrom",            STD_TQROM },
3838   { "txsrom",           STD_TXSROM },
3939   { "exrom",            STD_EXROM },
40   { "disksys",          STD_DISKSYS },
4041   { "pal_zz",           PAL_ZZ },
4142   { "nes_qj",           NES_QJ },
4243   { "nes_event",        STD_EVENT },
trunk/src/emu/bus/bus.mak
r32066r32067
878878BUSOBJS += $(BUSOBJ)/nes/cony.o
879879BUSOBJS += $(BUSOBJ)/nes/datach.o
880880BUSOBJS += $(BUSOBJ)/nes/discrete.o
881BUSOBJS += $(BUSOBJ)/nes/disksys.o
881882BUSOBJS += $(BUSOBJ)/nes/event.o
882883BUSOBJS += $(BUSOBJ)/nes/ggenie.o
883884BUSOBJS += $(BUSOBJ)/nes/henggedianzi.o
trunk/src/mess/mess.lst
r32066r32067
5656
5757// Nintendo
5858nes       // Nintendo Entertainment System
59nespal  // Nintendo Entertainment System PAL
59nespal    // Nintendo Entertainment System PAL
6060m82       // Nintendo M82 Display Unit
61famicom   // Nintendo Family Computer (a.k.a. Famicom) + Disk System add-on
61famicom   // Nintendo Family Computer (a.k.a. Famicom)
62fds       // Nintendo Family Computer (a.k.a. Famicom) + Disk System add-on
6263famitwin  // Sharp Famicom Twin System
6364drpcjr    // Bung Doctor PC Jr
6465dendy     // Dendy (Classic russian famiclone)
66gchinatv  // Golden China TV Game Centre (Chinese famiclone)
6567gameboy   // Nintendo Game Boy Handheld
6668supergb   // Nintendo Super Game Boy SNES Cartridge
6769gbpocket  // Nintendo Game Boy Pocket Handheld
r32066r32067
7274n64       // Nintendo N64
7375n64dd     // Nintendo N64 (64DD Attachment)
7476pokemini  // Nintendo Pokemon Mini
75gchinatv // Golden China TV Game Centre
7677
7778megaduck  // Megaduck
7879
trunk/src/mess/drivers/nes.c
r32066r32067
1313#include "emu.h"
1414#include "includes/nes.h"
1515#include "cpu/m6502/n2a03.h"
16#include "imagedev/flopdrv.h"
17#include "formats/nes_dsk.h"
1816
1917READ8_MEMBER(nes_state::psg_4015_r)
2018{
r32066r32067
646644}
647645
648646
649static const floppy_interface nes_floppy_interface =
650{
651   FLOPPY_STANDARD_5_25_DSHD,
652   LEGACY_FLOPPY_OPTIONS_NAME(nes_only),
653   "floppy_5_25"
654};
655
656
657647static MACHINE_CONFIG_START( nes, nes_state )
658648   /* basic machine hardware */
659649   MCFG_CPU_ADD("maincpu", N2A03, NTSC_CLOCK)
r32066r32067
739729MACHINE_CONFIG_END
740730
741731static MACHINE_CONFIG_DERIVED( famicom, nes )
742   MCFG_DEVICE_REMOVE("nes_slot")
743   MCFG_NES_CARTRIDGE_ADD("nes_slot", nes_cart, NULL)
744   MCFG_NES_CARTRIDGE_NOT_MANDATORY
745
746   MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, nes_floppy_interface)
747   MCFG_SOFTWARE_LIST_ADD("flop_list", "famicom_flop")
748
749732   MCFG_CASSETTE_ADD( "tape" )
750733   MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED)
751734   MCFG_CASSETTE_INTERFACE("fc_cass")
752735
736   MCFG_SOFTWARE_LIST_ADD("flop_list", "famicom_flop")
753737   MCFG_SOFTWARE_LIST_ADD("cass_list", "famicom_cass")
754738MACHINE_CONFIG_END
755739
740void nes_state::setup_disk(nes_cart_slot_device *slot)
741{
742   address_space &space = m_maincpu->space(AS_PROGRAM);
756743
757/* rom regions are just place-holders: they get removed and re-allocated when a cart is loaded */
744   if (slot)
745   {
746      // Set up memory handlers
747      space.install_read_handler(0x4020, 0x40ff, read8_delegate(FUNC(nes_cart_slot_device::read_ex), (nes_cart_slot_device *)slot));
748      space.install_write_handler(0x4020, 0x40ff, write8_delegate(FUNC(nes_cart_slot_device::write_ex), (nes_cart_slot_device *)slot));
749      space.install_read_handler(0x4100, 0x5fff, read8_delegate(FUNC(nes_cart_slot_device::read_l), (nes_cart_slot_device *)slot));
750      space.install_write_handler(0x4100, 0x5fff, write8_delegate(FUNC(nes_cart_slot_device::write_l), (nes_cart_slot_device *)slot));
751      space.install_read_handler(0x6000, 0x7fff, read8_delegate(FUNC(nes_cart_slot_device::read_m), (nes_cart_slot_device *)slot));
752      space.install_write_handler(0x6000, 0x7fff, write8_delegate(FUNC(nes_cart_slot_device::write_m), (nes_cart_slot_device *)slot));
753      space.install_read_handler(0x8000, 0xffff, read8_delegate(FUNC(nes_cart_slot_device::read_h), (nes_cart_slot_device *)slot));
754      space.install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(nes_cart_slot_device::write_h), (nes_cart_slot_device *)slot));
755     
756      slot->m_cart->vram_alloc(0x2000);
757      slot->m_cart->prgram_alloc(0x8000);
758     
759      slot->pcb_start(m_ciram);
760      slot->m_cart->pcb_reg_postload(machine());
761      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));
762      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));
763      m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate(FUNC(device_nes_cart_interface::scanline_irq),slot->m_cart));
764      m_ppu->set_hblank_callback(ppu2c0x_hblank_delegate(FUNC(device_nes_cart_interface::hblank_irq),slot->m_cart));
765      m_ppu->set_latch(ppu2c0x_latch_delegate(FUNC(device_nes_cart_interface::ppu_latch),slot->m_cart));
766   }
767}
768
769
770MACHINE_START_MEMBER( nes_state, fds )
771{   
772   m_ciram = auto_alloc_array(machine(), UINT8, 0x800);
773   setup_ioports();
774   // setup the disk expansion instead
775   setup_disk(m_cartslot);
776}
777
778static MACHINE_CONFIG_DERIVED( fds, famicom )
779   MCFG_MACHINE_START_OVERRIDE( nes_state, fds )
780   MCFG_DEVICE_REMOVE("tape")
781
782   MCFG_DEVICE_REMOVE("nes_slot")
783   MCFG_DISKSYS_ADD("nes_slot", disksys_only, "disksys")
784
785   MCFG_DEVICE_REMOVE("cart_list")
786   MCFG_DEVICE_REMOVE("cass_list")
787MACHINE_CONFIG_END
788
789
790MACHINE_START_MEMBER( nes_state, famitwin )
791{
792   // start the base nes stuff
793   machine_start();
794
795   // if there is no cart inserted, setup the disk expansion instead
796   if (!m_cartslot->m_cart)
797      setup_disk(m_cartslot2);
798}
799
800MACHINE_RESET_MEMBER( nes_state, famitwin )
801{
802   // Reset the mapper variables. Will also mark the char-gen ram as dirty
803   m_cartslot->pcb_reset();
804   // if there is no cart inserted, initialize the disk expansion instead
805   if (!m_cartslot->m_cart)
806      m_cartslot2->pcb_reset();
807   
808   // the rest is the same as for nes/famicom/dendy
809   m_maincpu->reset();
810   
811   memset(m_pad_latch, 0, sizeof(m_pad_latch));
812   memset(m_zapper_latch, 0, sizeof(m_zapper_latch));
813   m_paddle_latch = 0;
814   m_paddle_btn_latch = 0;   
815}
816
817static MACHINE_CONFIG_DERIVED( famitwin, famicom )
818
819   MCFG_MACHINE_START_OVERRIDE( nes_state, famitwin )
820   MCFG_MACHINE_RESET_OVERRIDE( nes_state, famitwin )
821
822   MCFG_SCREEN_MODIFY("screen")
823   MCFG_SCREEN_UPDATE_DRIVER(nes_state, screen_update_famitwin)
824
825   MCFG_DEVICE_REMOVE("nes_slot")
826   MCFG_NES_CARTRIDGE_ADD("nes_slot", nes_cart, NULL)
827   MCFG_NES_CARTRIDGE_NOT_MANDATORY
828
829   MCFG_DISKSYS_ADD("disk_slot", disksys_only, "disksys")
830MACHINE_CONFIG_END
831
832
833
758834ROM_START( nes )
759835   ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 )  /* Main RAM */
760836ROM_END
r32066r32067
764840ROM_END
765841
766842ROM_START( famicom )
767   ROM_REGION( 0x10000, "maincpu", 0 )  /* Main RAM */
768   ROM_SYSTEM_BIOS( 0, "2c33a-01a", "Famicom Disk System Bios")
769   ROMX_LOAD( "rp2c33a-01a.bin", 0xe000, 0x2000, CRC(5e607dcf) SHA1(57fe1bdee955bb48d357e463ccbf129496930b62), ROM_BIOS(1)) // newer, Nintendo logo has no shadow
770   ROM_SYSTEM_BIOS( 1, "2c33-01", "Famicom Disk System Bios, older")
771   ROMX_LOAD( "rp2c33-01.bin", 0xe000, 0x2000, CRC(1c7ae5d5) SHA1(af5af53f66982e749643fdf8b2acbb7d4d3ed229), ROM_BIOS(2)) // older, Nintendo logo has shadow
843   ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 )  /* Main RAM */
772844ROM_END
773845
846#define rom_fds rom_famicom
847
774848ROM_START( famitwin )
775849   ROM_REGION( 0x10000, "maincpu", 0 )  /* Main RAM */
776850   ROM_LOAD( "rp2c33a-02.bin", 0xe000, 0x2000, CRC(4df24a6c) SHA1(e4e41472c454f928e53eb10e0509bf7d1146ecc1) ) // "Famicom" logo instead of Nintendo logo
r32066r32067
799873
800874ROM_START( gchinatv )
801875   ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 )  /* Main RAM */
802   ROM_REGION( 0x800,   "ciram", ROMREGION_ERASE00 )  /* CI RAM */
803876ROM_END
804877
805878/***************************************************************************
r32066r32067
809882***************************************************************************/
810883
811884/*     YEAR  NAME      PARENT  COMPAT MACHINE   INPUT    INIT    COMPANY       FULLNAME */
812CONS( 1985, nes,       0,      0,     nes,      nes, driver_device,     0,       "Nintendo",  "Nintendo Entertainment System / Famicom (NTSC)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
813CONS( 1987, nespal,    nes,    0,     nespal,   nes, driver_device,     0,       "Nintendo",  "Nintendo Entertainment System (PAL)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
814CONS( 1983, famicom,   nes,    0,     famicom,  famicom, nes_state, famicom, "Nintendo",  "Famicom (w/ Disk System add-on)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
815CONS( 1986, famitwin,  nes,    0,     famicom,  famicom, nes_state, famicom, "Sharp",     "Famicom Twin", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
816CONS( 198?, m82,       nes,    0,     nes,      nes, driver_device,     0,       "Nintendo",  "M82 Display Unit", GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
817CONS( 1996, drpcjr,    nes,    0,     famicom,  famicom, nes_state, famicom, "Bung",      "Doctor PC Jr", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
818CONS( 1992, dendy,     nes,    0,     dendy,    nes, driver_device,     0,       "Steepler",  "Dendy Classic", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
819CONS( 198?, gchinatv,  nes,    0,     nespal,   nes, driver_device,     0,       "Golden China",  "Golden China TV Game", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
885CONS( 1985, nes,       0,      0,     nes,      nes,     driver_device,     0,       "Nintendo",  "Nintendo Entertainment System / Famicom (NTSC)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
886CONS( 1987, nespal,    nes,    0,     nespal,   nes,     driver_device,     0,       "Nintendo",  "Nintendo Entertainment System (PAL)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
887CONS( 1983, famicom,   nes,    0,     famicom,  famicom, nes_state,         famicom, "Nintendo",  "Famicom (NTSC)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
888CONS( 1983, fds,       nes,    0,     fds,      famicom, nes_state,         famicom, "Nintendo",  "Famicom (w/ Disk System add-on)", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
889CONS( 1986, famitwin,  nes,    0,     famitwin, famicom, nes_state,         famicom, "Sharp",     "Famicom Twin", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
890CONS( 198?, m82,       nes,    0,     nes,      nes,     driver_device,     0,       "Nintendo",  "M82 Display Unit", GAME_IMPERFECT_GRAPHICS | GAME_NOT_WORKING | GAME_SUPPORTS_SAVE )
891CONS( 1996, drpcjr,    nes,    0,     famicom,  famicom, nes_state,         famicom, "Bung",      "Doctor PC Jr", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
892CONS( 1992, dendy,     nes,    0,     dendy,    nes,     driver_device,     0,       "Steepler",  "Dendy Classic", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
893CONS( 198?, gchinatv,  nes,    0,     nespal,   nes,     driver_device,     0,       "Golden China",  "Golden China TV Game", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
trunk/src/mess/machine/nes.c
r32066r32067
3434   return data;
3535}
3636
37//-------------------------------------------------
38//  machine_reset
39//-------------------------------------------------
40
3741void nes_state::machine_reset()
3842{
39   /* Reset the mapper variables. Will also mark the char-gen ram as dirty */
40   if (m_disk_expansion && m_cartslot && !m_cartslot->m_cart)
41      m_ppu->set_hblank_callback(ppu2c0x_hblank_delegate(FUNC(nes_state::fds_irq),this));
42   else if (m_cartslot)
43   // Reset the mapper variables. Will also mark the char-gen ram as dirty
44   if (m_cartslot)
4345      m_cartslot->pcb_reset();
4446
4547   m_maincpu->reset();
r32066r32067
5052   m_paddle_btn_latch = 0;
5153}
5254
55//-------------------------------------------------
56//  machine_start
57//-------------------------------------------------
58
5359void nes_state::state_register()
5460{
5561   save_item(NAME(m_last_frame_flip));
5662
57   save_item(NAME(m_fds_motor_on));
58   save_item(NAME(m_fds_door_closed));
59   save_item(NAME(m_fds_current_side));
60   save_item(NAME(m_fds_head_position));
61   save_item(NAME(m_fds_status0));
62   save_item(NAME(m_fds_read_mode));
63   save_item(NAME(m_fds_write_reg));
64   save_item(NAME(m_fds_last_side));
65   save_item(NAME(m_fds_count));
66   save_item(NAME(m_fds_mirroring));
67
6863   save_pointer(NAME(m_ciram), 0x800);
6964
70   if (m_disk_expansion)
71      save_pointer(NAME(m_vram), 0x2000);
72
7365   save_item(NAME(m_pad_latch));
7466   save_item(NAME(m_zapper_latch));
7567   save_item(NAME(m_paddle_latch));
r32066r32067
8072   save_item(NAME(m_mic_obstruct));
8173   save_item(NAME(m_powerpad_latch));
8274   save_item(NAME(m_ftrainer_scan));
83   save_item(NAME(m_IRQ_enable));
84   save_item(NAME(m_IRQ_enable_latch));
85   save_item(NAME(m_IRQ_count));
86   save_item(NAME(m_IRQ_count_latch));
8775}
8876
89
90//-------------------------------------------------
91//  machine_start
92//-------------------------------------------------
93
94void nes_state::machine_start()
77void nes_state::setup_ioports()
9578{
9679   for (int i = 0; i < 9; i++)
9780   {
r32066r32067
11598      sprintf(str, "FT_COL%i", i);
11699      m_io_ftrainer[i] = ioport(str);
117100   }
118
101   
119102   m_io_ctrlsel        = ioport("CTRLSEL");
120103   m_io_exp            = ioport("EXP");
121104   m_io_paddle         = ioport("PADDLE");
r32066r32067
130113   m_io_zapper2_y      = ioport("ZAPPER2_Y");
131114   m_io_powerpad[0]    = ioport("POWERPAD1");
132115   m_io_powerpad[1]    = ioport("POWERPAD2");
116   m_io_disksel        = ioport("FLIPDISK");
117}
133118
119void nes_state::machine_start()
120{
134121   address_space &space = m_maincpu->space(AS_PROGRAM);
135122
136123   // CIRAM (Character Internal RAM)
r32066r32067
140127   m_ciram = auto_alloc_array(machine(), UINT8, 0x800);
141128   // other pointers got set in the loading routine, because they 'belong' to the cart itself
142129
130   setup_ioports();
131
143132   if (m_cartslot && m_cartslot->m_cart)
144133   {
145134      // Set up memory handlers
r32066r32067
153142      space.install_read_bank(0xe000, 0xffff, "prg3");
154143      space.install_write_handler(0x8000, 0xffff, write8_delegate(FUNC(nes_cart_slot_device::write_h), (nes_cart_slot_device *)m_cartslot));
155144
156      m_cartslot->pcb_start(m_ciram);
157      m_cartslot->m_cart->pcb_reg_postload(machine());
158145      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));
159146      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));
160147      m_ppu->set_scanline_callback(ppu2c0x_scanline_delegate(FUNC(device_nes_cart_interface::scanline_irq),m_cartslot->m_cart));
r32066r32067
162149      m_ppu->set_latch(ppu2c0x_latch_delegate(FUNC(device_nes_cart_interface::ppu_latch),m_cartslot->m_cart));
163150
164151      // install additional handlers (read_h, read_ex, write_ex)
165      if (m_cartslot->get_pcb_id() == STD_EXROM || m_cartslot->get_pcb_id() == STD_NROM368
152      if (m_cartslot->get_pcb_id() == STD_EXROM || m_cartslot->get_pcb_id() == STD_NROM368 || m_cartslot->get_pcb_id() == STD_DISKSYS
166153         || m_cartslot->get_pcb_id() == GG_NROM || m_cartslot->get_pcb_id() == CAMERICA_ALADDIN || m_cartslot->get_pcb_id() == SUNSOFT_DCS
167154         || 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
168155         || m_cartslot->get_pcb_id() == KAISER_KS7022 || m_cartslot->get_pcb_id() == KAISER_KS7031 || m_cartslot->get_pcb_id() == BMC_VT5201
r32066r32067
181168         space.install_write_handler(0x4020, 0x40ff, write8_delegate(FUNC(nes_cart_slot_device::write_ex), (nes_cart_slot_device *)m_cartslot));
182169      }
183170
184      if (m_cartslot->get_pcb_id() == KAISER_KS7017 || m_cartslot->get_pcb_id() == UNL_603_5052)
171      if (m_cartslot->get_pcb_id() == KAISER_KS7017 || m_cartslot->get_pcb_id() == UNL_603_5052 || m_cartslot->get_pcb_id() == STD_DISKSYS)
185172      {
186173         logerror("write_ex & read_ex installed!\n");
187174         space.install_read_handler(0x4020, 0x40ff, read8_delegate(FUNC(nes_cart_slot_device::read_ex), (nes_cart_slot_device *)m_cartslot));
188175         space.install_write_handler(0x4020, 0x40ff, write8_delegate(FUNC(nes_cart_slot_device::write_ex), (nes_cart_slot_device *)m_cartslot));
189176      }
190   }
191   else if (m_disk_expansion)  // if there is Disk Expansion and no cart has been loaded, setup memory accordingly
192   {
193      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));
194      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));
195177
196      if (!m_fds_ram)
197         m_fds_ram = auto_alloc_array(machine(), UINT8, 0x8000);
198      if (!m_vram)
199         m_vram = auto_alloc_array(machine(), UINT8, 0x2000);
200
201      space.install_read_handler(0x4030, 0x403f, read8_delegate(FUNC(nes_state::nes_fds_r),this));
202      space.install_read_bank(0x6000, 0xdfff, "fdsram");
203      space.install_read_bank(0xe000, 0xffff, "bank1");
204
205      space.install_write_handler(0x4020, 0x402f, write8_delegate(FUNC(nes_state::nes_fds_w),this));
206      space.install_write_bank(0x6000, 0xdfff, "fdsram");
207
208      membank("bank1")->set_base(machine().root_device().memregion("maincpu")->base() + 0xe000);
209      membank("fdsram")->set_base(m_fds_ram);
178      m_cartslot->pcb_start(m_ciram);
179      m_cartslot->m_cart->pcb_reg_postload(machine());
210180   }
211181
212182   state_register();
r32066r32067
734704}
735705
736706
737/**************************
738
739 Disk System emulation
740
741**************************/
742
743void nes_state::fds_irq( int scanline, int vblank, int blanked )
744{
745   if (m_IRQ_enable_latch)
746      m_maincpu->set_input_line(M6502_IRQ_LINE, HOLD_LINE);
747
748   if (m_IRQ_enable)
749   {
750      if (m_IRQ_count <= 114)
751      {
752         m_maincpu->set_input_line(M6502_IRQ_LINE, HOLD_LINE);
753         m_IRQ_enable = 0;
754         m_fds_status0 |= 0x01;
755      }
756      else
757         m_IRQ_count -= 114;
758   }
759}
760
761READ8_MEMBER(nes_state::nes_fds_r)
762{
763   UINT8 ret = 0x00;
764
765   switch (offset)
766   {
767      case 0x00: /* $4030 - disk status 0 */
768         ret = m_fds_status0;
769         /* clear the disk IRQ detect flag */
770         m_fds_status0 &= ~0x01;
771         break;
772      case 0x01: /* $4031 - data latch */
773         /* don't read data if disk is unloaded */
774         if (!m_fds_data)
775            ret = 0;
776         else if (m_fds_current_side)
777         {
778            // a bunch of games (e.g. bshashsc and fairypin) keep reading beyond the last track
779            // what is the expected behavior?
780            if (m_fds_head_position > 65500)
781               m_fds_head_position = 0;
782            ret = m_fds_data[(m_fds_current_side - 1) * 65500 + m_fds_head_position++];
783         }
784         else
785            ret = 0;
786         break;
787      case 0x02: /* $4032 - disk status 1 */
788         /* return "no disk" status if disk is unloaded */
789         if (!m_fds_data)
790            ret = 1;
791         else if (m_fds_last_side != m_fds_current_side)
792         {
793            /* If we've switched disks, report "no disk" for a few reads */
794            ret = 1;
795            m_fds_count++;
796            if (m_fds_count == 50)
797            {
798               m_fds_last_side = m_fds_current_side;
799               m_fds_count = 0;
800            }
801         }
802         else
803            ret = (m_fds_current_side == 0); /* 0 if a disk is inserted */
804         break;
805      case 0x03: /* $4033 */
806         ret = 0x80;
807         break;
808      default:
809         ret = 0x00;
810         break;
811   }
812
813   return ret;
814}
815
816WRITE8_MEMBER(nes_state::nes_fds_w)
817{
818   switch (offset)
819   {
820      case 0x00:
821         m_IRQ_count_latch = (m_IRQ_count_latch & 0xff00) | data;
822         break;
823      case 0x01:
824         m_IRQ_count_latch = (m_IRQ_count_latch & 0x00ff) | (data << 8);
825         break;
826      case 0x02:
827         m_IRQ_count = m_IRQ_count_latch;
828         m_IRQ_enable = data;
829         break;
830      case 0x03:
831         // d0 = sound io (1 = enable)
832         // d1 = disk io (1 = enable)
833         break;
834      case 0x04:
835         /* write data out to disk */
836         break;
837      case 0x05:
838         m_fds_motor_on = BIT(data, 0);
839
840         if (BIT(data, 1))
841            m_fds_head_position = 0;
842
843         m_fds_read_mode = BIT(data, 2);
844         if (BIT(data, 3))
845            m_fds_mirroring = PPU_MIRROR_HORZ;
846         else
847            m_fds_mirroring = PPU_MIRROR_VERT;
848
849         if ((!(data & 0x40)) && (m_fds_write_reg & 0x40))
850            m_fds_head_position -= 2; // ???
851
852         m_IRQ_enable_latch = BIT(data, 7);
853         m_fds_write_reg = data;
854         break;
855   }
856}
857
858WRITE8_MEMBER(nes_state::fds_chr_w)
859{
860   m_vram[offset] = data;
861}
862
863READ8_MEMBER(nes_state::fds_chr_r)
864{
865   return m_vram[offset];
866}
867
868WRITE8_MEMBER(nes_state::fds_nt_w)
869{
870   int page = ((offset & 0xc00) >> 10);
871   int bank;
872
873   switch (page)
874   {
875      case 0:
876         bank = 0;
877         break;
878      case 1:
879         bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 1 : 0;
880         break;
881      case 2:
882         bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 0 : 1;
883         break;
884      case 3:
885      default:
886         bank = 1;
887         break;
888   }
889
890   m_ciram[(bank * 0x400) + (offset & 0x3ff)] = data;
891}
892
893READ8_MEMBER(nes_state::fds_nt_r)
894{
895   int page = ((offset & 0xc00) >> 10);
896   int bank;
897
898   switch (page)
899   {
900      case 0:
901         bank = 0;
902         break;
903      case 1:
904         bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 1 : 0;
905         break;
906      case 2:
907         bank = (m_fds_mirroring == PPU_MIRROR_VERT) ? 0 : 1;
908         break;
909      case 3:
910      default:
911         bank = 1;
912         break;
913   }
914
915   return m_ciram[(bank * 0x400) + (offset & 0x3ff)];
916}
917
918
919// Disk interface
920
921static void nes_load_proc( device_image_interface &image )
922{
923   nes_state *state = image.device().machine().driver_data<nes_state>();
924   int header = 0;
925   state->m_fds_sides = 0;
926
927   if (image.length() % 65500)
928      header = 0x10;
929
930   state->m_fds_sides = (image.length() - header) / 65500;
931
932   if (!state->m_fds_data)
933      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...
934
935   /* if there is an header, skip it */
936   image.fseek(header, SEEK_SET);
937
938   image.fread(state->m_fds_data, 65500 * state->m_fds_sides);
939   return;
940}
941
942static void nes_unload_proc( device_image_interface &image )
943{
944   nes_state *state = image.device().machine().driver_data<nes_state>();
945
946   /* TODO: should write out changes here as well */
947   state->m_fds_sides =  0;
948}
949
950707DRIVER_INIT_MEMBER(nes_state,famicom)
951708{
952   /* initialize the disk system */
953   m_disk_expansion = 1;
954
955   m_fds_sides = 0;
956   m_fds_last_side = 0;
957   m_fds_count = 0;
958   m_fds_motor_on = 0;
959   m_fds_door_closed = 0;
960   m_fds_current_side = 1;
961   m_fds_head_position = 0;
962   m_fds_status0 = 0;
963   m_fds_read_mode = m_fds_write_reg = 0;
964
965   m_fds_mirroring = PPU_MIRROR_VERT;  // correct?
966
967   m_fds_ram = auto_alloc_array_clear(machine(), UINT8, 0x8000);
968   save_pointer(NAME(m_fds_ram), 0x8000);
969
970   floppy_get_device(machine(), 0)->floppy_install_load_proc(nes_load_proc);
971   floppy_get_device(machine(), 0)->floppy_install_unload_proc(nes_unload_proc);
972
973709   // setup alt input handlers for additional FC input devices
974710   address_space &space = machine().device<cpu_device>("maincpu")->space(AS_PROGRAM);
975711   space.install_read_handler(0x4016, 0x4016, read8_delegate(FUNC(nes_state::fc_in0_r), this));
trunk/src/mess/includes/nes.h
r32066r32067
6969         m_ppu(*this, "ppu"),
7070         m_sound(*this, "nessound"),
7171         m_cartslot(*this, "nes_slot"),
72         m_cartslot2(*this, "disk_slot"),   // temp hack for famitwin
7273         m_cassette(*this, "tape")
7374      { }
7475
r32066r32067
7677   int m_last_frame_flip;
7778
7879   /* misc */
79
8080   ioport_port       *m_io_ctrlsel;
8181   ioport_port       *m_io_fckey[9];
8282   ioport_port       *m_io_subkey[13];
r32066r32067
9595   ioport_port       *m_io_paddle;
9696   ioport_port       *m_io_paddle_btn;
9797   ioport_port       *m_io_exp;
98   ioport_port       *m_io_disksel;
9899
99100   UINT8      *m_vram;
100101   UINT8      *m_ciram; //PPU nametable RAM - external to PPU!
r32066r32067
103104   required_device<ppu2c0x_device> m_ppu;
104105   required_device<nesapu_device> m_sound;
105106   optional_device<nes_cart_slot_device> m_cartslot;
107   optional_device<nes_cart_slot_device> m_cartslot2;
106108   optional_device<cassette_image_device> m_cassette;
107109
108110   int nes_ppu_vidaccess(int address, int data);
r32066r32067
122124   virtual void video_reset();
123125   DECLARE_PALETTE_INIT(nes);
124126   UINT32 screen_update_nes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
127   UINT32 screen_update_famitwin(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
125128   DECLARE_READ8_MEMBER(psg_4015_r);
126129   DECLARE_WRITE8_MEMBER(psg_4015_w);
127130   DECLARE_WRITE8_MEMBER(psg_4017_w);
128131   void state_register();
132   void setup_ioports();
129133
130   /***** FDS-floppy related *****/
131
132   DECLARE_WRITE8_MEMBER(fds_chr_w);
133   DECLARE_READ8_MEMBER(fds_chr_r);
134   DECLARE_WRITE8_MEMBER(fds_nt_w);
135   DECLARE_READ8_MEMBER(fds_nt_r);
136
137   int m_disk_expansion;
138
139   UINT8 m_fds_sides;
140   UINT8 *m_fds_data;    // here, we store a copy of the disk
141   UINT8 *m_fds_ram; // here, we emulate the RAM adapter
142
143   /* Variables which can change */
144   UINT8 m_fds_motor_on;
145   UINT8 m_fds_door_closed;
146   UINT8 m_fds_current_side;
147   UINT32 m_fds_head_position;
148   UINT8 m_fds_status0;
149   UINT8 m_fds_read_mode;
150   UINT8 m_fds_write_reg;
151   int m_fds_mirroring;
152
153   int m_IRQ_enable, m_IRQ_enable_latch;
154   UINT16 m_IRQ_count, m_IRQ_count_latch;
155
156   /* these are used in the mapper 20 handlers */
157   int m_fds_last_side;
158   int m_fds_count;
159   DECLARE_READ8_MEMBER(nes_fds_r);
160   DECLARE_WRITE8_MEMBER(nes_fds_w);
161134   DECLARE_DRIVER_INIT(famicom);
162135
163   DECLARE_DEVICE_IMAGE_LOAD_MEMBER(nes_disk);
164   DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(nes_disk);
136   // these are needed until we modernize the FDS controller
137   DECLARE_MACHINE_START(fds);
138   DECLARE_MACHINE_START(famitwin);
139   DECLARE_MACHINE_RESET(famitwin);
140   void setup_disk(nes_cart_slot_device *slot);
165141
166   void fds_irq(int scanline, int vblank, int blanked);
167
168142   // input related
169143   UINT32 m_pad_latch[4];
170144   UINT8 m_zapper_latch[2][3];
trunk/src/mess/video/nes.c
r32066r32067
3333
3434UINT32 nes_state::screen_update_nes(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
3535{
36   /* render the ppu */
36   // render the ppu
3737   m_ppu->render(bitmap, 0, 0, 0, 0);
3838
39   /* if this is a disk system game, check for the flip-disk key */
40   if (m_disk_expansion && m_cartslot && !m_cartslot->m_cart)
39   // if this is a disk system game, check for the flip-disk key
40   if (m_cartslot &&
41       (m_cartslot->get_pcb_id() == STD_DISKSYS   // first scenario = disksys in m_cartslot (= famicom)
42         || !m_cartslot->cart_mounted()))   // second scenario = disk via fixed internal option (= fds)
4143   {
4244      // latch this input so it doesn't go at warp speed
43      if ((ioport("FLIPDISK")->read() & 0x01) && (!m_last_frame_flip))
45      if ((m_io_disksel->read_safe(0) & 0x01) && (!m_last_frame_flip))
4446      {
47         m_cartslot->disk_flip_side();
4548         m_last_frame_flip = 1;
46         m_fds_current_side++;
47         if (m_fds_current_side > m_fds_sides)
48            m_fds_current_side = 0;
49
50         if (m_fds_current_side == 0)
51            popmessage("No disk inserted.");
52         else
53            popmessage("Disk set to side %d", m_fds_current_side);
5449      }
5550
56      if (!(ioport("FLIPDISK")->read() & 0x01))
51      if (!m_io_disksel->read_safe(1) & 0x01)
5752         m_last_frame_flip = 0;
5853   }
5954   return 0;
6055}
56
57// Alternative version to support "Disk flip hack" also in the Famicom Twin System (to be removed soonish!)
58UINT32 nes_state::screen_update_famitwin(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
59{
60   // render the ppu
61   m_ppu->render(bitmap, 0, 0, 0, 0);
62
63   if (m_cartslot2 && !m_cartslot2->cart_mounted())
64   {
65      // latch this input so it doesn't go at warp speed
66      if ((m_io_disksel->read_safe(0) & 0x01) && (!m_last_frame_flip))
67      {
68         m_cartslot2->disk_flip_side();
69         m_last_frame_flip = 1;
70      }
71     
72      if (!m_io_disksel->read_safe(1) & 0x01)
73         m_last_frame_flip = 0;
74   }
75   return 0;
76}
trunk/hash/nes.xml
r32066r32067
7900879008      </part>
7900979009   </software>
7901079010
79011<!-- Romless cart for the RAM expansion + Disk System drive (drive ROM is included in the drive device) -->
79012   <software name="disksys">
79013      <description>Family Computer Disk System (Jpn)</description>
79014      <year>1986</year>
79015      <publisher>Nintendo</publisher>
79016      <info name="usage" value="This only is only supported by Famicom"/>
79017      <part name="cart" interface="nes_cart">
79018         <feature name="slot" value="disksys" />
79019         <!-- This is a fake and unused PRG dataarea to avoid changing the loading routines for the moment-->
79020         <dataarea name="prg" size="32768">
79021            <rom value="0xff" size="32768" offset="0" loadflag="fill" />
79022         </dataarea>
79023         <!-- 8k VRAM on cartridge -->
79024         <dataarea name="vram" size="8192">
79025         </dataarea>
79026         <!-- 32k WRAM on cartridge -->
79027         <dataarea name="wram" size="32768">
79028         </dataarea>
79029      </part>
79030   </software>
79031
7901179032</softwarelist>

Previous 199869 Revisions Next


© 1997-2024 The MAME Team