diff --git a/.gitattributes b/.gitattributes
index e19b43b2a3f..8ce4db4aea7 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -91,6 +91,7 @@ hash/electron_cart.xml svneol=native#text/xml
hash/ep64_cart.xml svneol=native#text/xml
hash/ep64_cass.xml svneol=native#text/xml
hash/ep64_flop.xml svneol=native#text/xml
+hash/famicom_cass.xml svneol=native#text/xml
hash/famicom_flop.xml svneol=native#text/xml
hash/fm77av.xml svneol=native#text/xml
hash/fm7_cass.xml svneol=native#text/xml
diff --git a/hash/famicom_cass.xml b/hash/famicom_cass.xml
new file mode 100644
index 00000000000..bab4db6bac9
--- /dev/null
+++ b/hash/famicom_cass.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+ Hero
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+ Starkiller
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+ Urban Champ
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+ Kanitori Game
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Keyboard Lesson
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Moon Base 2
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Starship
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sansuu Gokko
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+ Bound Bon-Bon
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Daimajin Attack
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mario Shooter
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ping Pong 1
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ping Pong 2
+ 19??
+ <unknown>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/mess/drivers/nes.c b/src/mess/drivers/nes.c
index 422afacf52d..7487e420f4a 100644
--- a/src/mess/drivers/nes.c
+++ b/src/mess/drivers/nes.c
@@ -589,6 +589,17 @@ static const nes_cart_interface nes_crt_interface =
};
+static const cassette_interface fc_cassette_interface =
+{
+ cassette_default_formats,
+ NULL,
+ (cassette_state)(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED),
+ "fc_cass",
+ NULL
+};
+
+
+
static MACHINE_CONFIG_START( nes, nes_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", N2A03, NTSC_CLOCK)
@@ -618,8 +629,8 @@ static MACHINE_CONFIG_START( nes, nes_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90)
MCFG_NES_CARTRIDGE_ADD("nes_slot", nes_crt_interface, nes_cart, NULL)
- MCFG_SOFTWARE_LIST_ADD("cart_list","nes")
- MCFG_SOFTWARE_LIST_ADD("ntb_list","nes_ntbrom") // Nantettate Baseball mini_carts
+ MCFG_SOFTWARE_LIST_ADD("cart_list", "nes")
+ MCFG_SOFTWARE_LIST_ADD("ntb_list", "nes_ntbrom") // Nantettate Baseball mini_carts
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( nespal, nes )
@@ -672,7 +683,10 @@ static MACHINE_CONFIG_DERIVED( famicom, nes )
MCFG_NES_CARTRIDGE_NOT_MANDATORY
MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, nes_floppy_interface)
- MCFG_SOFTWARE_LIST_ADD("flop_list","famicom_flop")
+ MCFG_SOFTWARE_LIST_ADD("flop_list", "famicom_flop")
+
+ MCFG_CASSETTE_ADD( "tape", fc_cassette_interface )
+ MCFG_SOFTWARE_LIST_ADD("cass_list", "famicom_cass")
MACHINE_CONFIG_END
diff --git a/src/mess/includes/nes.h b/src/mess/includes/nes.h
index fcb7e14ea11..c7ecc8d6bb8 100644
--- a/src/mess/includes/nes.h
+++ b/src/mess/includes/nes.h
@@ -12,6 +12,7 @@
#include "video/ppu2c0x.h"
#include "machine/nes_slot.h"
+#include "imagedev/cassette.h"
// official PCBs
#include "machine/nes_nxrom.h"
@@ -456,7 +457,8 @@ public:
m_maincpu(*this, "maincpu"),
m_ppu(*this, "ppu"),
m_sound(*this, "nessound"),
- m_cartslot(*this, "nes_slot")
+ m_cartslot(*this, "nes_slot"),
+ m_cassette(*this, "tape")
{ }
/* input_related - this part has to be cleaned up (e.g. in_2 and in_3 are not really necessary here...) */
@@ -491,6 +493,7 @@ public:
required_device m_ppu;
required_device m_sound;
optional_device m_cartslot;
+ optional_device m_cassette;
int nes_ppu_vidaccess(int address, int data);
void ppu_nmi(int *ppu_regs);
diff --git a/src/mess/machine/nes.c b/src/mess/machine/nes.c
index 2f009887db1..654c9a88c4f 100644
--- a/src/mess/machine/nes.c
+++ b/src/mess/machine/nes.c
@@ -386,8 +386,15 @@ READ8_MEMBER(nes_state::fc_in0_r)
if ((exp & 0x0f) == 0x02)
{
- // here we should have the tape input
- ret |= 0;
+ // tape input
+ if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY)
+ {
+ double level = m_cassette->input();
+ if (level < 0)
+ ret |= 0x00;
+ else
+ ret |= 0x02;
+ }
}
ret |= ((m_in_0.i0 >> m_in_0.shift) & 0x01);
@@ -486,7 +493,9 @@ WRITE8_MEMBER(nes_state::fc_in0_w)
if ((exp & 0x0f) == 0x02 || (exp & 0x0f) == 0x03)
{
- // here we should also have the tape output
+ // tape output (not fully tested)
+ if ((m_cassette->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD)
+ m_cassette->output(((data & 0x07) == 0x07) ? +1.0 : -1.0);
if (BIT(data, 2)) // keyboard active
{