From c4c3f9978d0544680736d619170a0464b1b30fbc Mon Sep 17 00:00:00 2001 From: Robbbert Date: Fri, 5 Jul 2019 02:25:50 +1000 Subject: MT 06756: nascom2, nascom1: Cassette records no signal --- src/mame/drivers/nascom1.cpp | 182 +++++++++++++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 57 deletions(-) diff --git a/src/mame/drivers/nascom1.cpp b/src/mame/drivers/nascom1.cpp index 30288be22b0..f3c0e89176e 100644 --- a/src/mame/drivers/nascom1.cpp +++ b/src/mame/drivers/nascom1.cpp @@ -12,12 +12,15 @@ To Do: - Nascom2 has two dipswitch banks, and a memory control header - Nascom3 (Gemini), nothing usable found -Cassette: +Cassette (nascom1): It outputs a string of pulses at 1953.125Hz to indicate a 1, and blank tape for 0. This means that no tape will present a 0 to the UART instead of the expected 1 (idle). Part of the cassette schematic is missing, so a few liberties have been taken. The result is you can save a file and load it back. Haven't found wav files on the net to test with. +Cassette (nascom2): + Standard Kansas City format, switchable (with a real switch) between 300 and 1200 baud. + *****************************************************************************************************/ #include "emu.h" @@ -31,7 +34,6 @@ Cassette: #include "machine/z80pio.h" #include "machine/timer.h" -#include "sound/wave.h" #include "speaker.h" #include "bus/generic/slot.h" @@ -50,18 +52,18 @@ Cassette: class nascom_state : public driver_device { public: - nascom_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_ram(*this, RAM_TAG), - m_hd6402(*this, "hd6402"), - m_cass(*this, "cassette"), - m_screen(*this, "screen"), - m_gfxdecode(*this, "gfxdecode"), - m_palette(*this, "palette"), - m_videoram(*this, "videoram"), - m_gfx1_region(*this, "gfx1"), - m_keyboard(*this, "KEY.%u", 0) + nascom_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_ram(*this, RAM_TAG) + , m_hd6402(*this, "hd6402") + , m_cass(*this, "cassette") + , m_screen(*this, "screen") + , m_gfxdecode(*this, "gfxdecode") + , m_palette(*this, "palette") + , m_videoram(*this, "videoram") + , m_gfx1_region(*this, "gfx1") + , m_keyboard(*this, "KEY.%u", 0) { } void nascom(machine_config &config); @@ -79,6 +81,8 @@ protected: DECLARE_READ8_MEMBER(nascom1_port_01_r); DECLARE_WRITE8_MEMBER(nascom1_port_01_w); DECLARE_READ8_MEMBER(nascom1_port_02_r); + DECLARE_READ_LINE_MEMBER(hd6402_si); + DECLARE_WRITE_LINE_MEMBER(hd6402_so); void screen_update(bitmap_ind16 &bitmap, const rectangle &cliprect, int char_height); @@ -91,20 +95,14 @@ protected: required_memory_region m_gfx1_region; required_ioport_array<8> m_keyboard; -private: int m_tape_size; uint8_t *m_tape_image; int m_tape_index; uint8_t m_kb_select; uint8_t m_kb_control; bool m_cassinbit, m_cassoutbit, m_cassold; - u16 m_cass_cnt[2]; u8 m_port00; - TIMER_DEVICE_CALLBACK_MEMBER(kansas_r); - DECLARE_READ_LINE_MEMBER(nascom1_hd6402_si); - DECLARE_WRITE_LINE_MEMBER(nascom1_hd6402_so); - DECLARE_WRITE_LINE_MEMBER(kansas_w); DECLARE_DEVICE_IMAGE_LOAD_MEMBER( load_nascom1_cassette ); DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER( unload_nascom1_cassette ); template DECLARE_SNAPSHOT_LOAD_MEMBER( snapshot_cb ); @@ -113,28 +111,31 @@ private: class nascom1_state : public nascom_state { public: - nascom1_state(const machine_config &mconfig, device_type type, const char *tag) : - nascom_state(mconfig, type, tag) + nascom1_state(const machine_config &mconfig, device_type type, const char *tag) + : nascom_state(mconfig, type, tag) { } void nascom1(machine_config &config); - uint32_t screen_update_nascom(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); private: void nascom1_io(address_map &map); void nascom1_mem(address_map &map); + TIMER_DEVICE_CALLBACK_MEMBER(nascom1_kansas_r); + DECLARE_WRITE_LINE_MEMBER(nascom1_kansas_w); + u16 m_cass_cnt[2]; }; class nascom2_state : public nascom_state { public: - nascom2_state(const machine_config &mconfig, device_type type, const char *tag) : - nascom_state(mconfig, type, tag), - m_nasbus(*this, NASBUS_TAG), - m_socket1(*this, "socket1"), - m_socket2(*this, "socket2"), - m_lsw1(*this, "lsw1") + nascom2_state(const machine_config &mconfig, device_type type, const char *tag) + : nascom_state(mconfig, type, tag) + , m_clock(*this, "uart_clock") + , m_nasbus(*this, NASBUS_TAG) + , m_socket1(*this, "socket1") + , m_socket2(*this, "socket2") + , m_lsw1(*this, "lsw1") { } void nascom2(machine_config &config); @@ -142,7 +143,12 @@ public: void init_nascom2c(); + DECLARE_INPUT_CHANGED_MEMBER(cass_speed); + private: + TIMER_DEVICE_CALLBACK_MEMBER(nascom2_kansas_r); + DECLARE_MACHINE_RESET(nascom2); + DECLARE_WRITE_LINE_MEMBER(nascom2_kansas_w); DECLARE_WRITE_LINE_MEMBER(ram_disable_w); DECLARE_WRITE_LINE_MEMBER(ram_disable_cpm_w); uint32_t screen_update_nascom(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); @@ -155,12 +161,13 @@ private: void nascom2_mem(address_map &map); void nascom2c_mem(address_map &map); - virtual void machine_reset() override; - + required_device m_clock; required_device m_nasbus; required_device m_socket1; required_device m_socket2; required_ioport m_lsw1; + u8 m_cass_data[4]; + bool m_cass_speed; }; @@ -221,17 +228,17 @@ READ8_MEMBER( nascom_state::nascom1_port_02_r ) return data; } -READ_LINE_MEMBER( nascom_state::nascom1_hd6402_si ) +READ_LINE_MEMBER( nascom_state::hd6402_si ) { return m_cassinbit; } -WRITE_LINE_MEMBER( nascom_state::nascom1_hd6402_so ) +WRITE_LINE_MEMBER( nascom_state::hd6402_so ) { m_cassoutbit = state; } -WRITE_LINE_MEMBER( nascom_state::kansas_w ) +WRITE_LINE_MEMBER( nascom1_state::nascom1_kansas_w ) { // incoming 3906.25Hz if (state) @@ -246,7 +253,7 @@ WRITE_LINE_MEMBER( nascom_state::kansas_w ) m_hd6402->write_tcp(state); } -TIMER_DEVICE_CALLBACK_MEMBER( nascom_state::kansas_r ) +TIMER_DEVICE_CALLBACK_MEMBER( nascom1_state::nascom1_kansas_r ) { // cassette - pulses = 1; no pulses = 0 m_cass_cnt[1]++; @@ -266,6 +273,45 @@ TIMER_DEVICE_CALLBACK_MEMBER( nascom_state::kansas_r ) } } +WRITE_LINE_MEMBER( nascom2_state::nascom2_kansas_w ) +{ + // incoming @19230Hz + u8 twobit = m_cass_data[3] & 3; + + if (state) + { + if (twobit == 0) + m_cassold = m_cassoutbit; + + if (m_cassold) + m_cass->output(BIT(m_cass_data[3], 2) ? -1.0 : +1.0); // 2400Hz + else + m_cass->output(BIT(m_cass_data[3], 3) ? -1.0 : +1.0); // 1200Hz + + m_cass_data[3]++; + } + + if (m_cass_speed || !twobit) + { + m_hd6402->write_tcp(state); + m_hd6402->write_rcp(state); + } +} + +TIMER_DEVICE_CALLBACK_MEMBER( nascom2_state::nascom2_kansas_r ) +{ + /* cassette - turn 1200/2400Hz to a bit */ + m_cass_data[1]++; + uint8_t cass_ws = (m_cass->input() > +0.04) ? 1 : 0; + + if (cass_ws != m_cass_data[0]) + { + m_cass_data[0] = cass_ws; + m_cassinbit = (m_cass_data[1] < 12) ? 1 : 0; + m_cass_data[1] = 0; + } +} + // This stuff has never been connected up - what's it for? DEVICE_IMAGE_LOAD_MEMBER( nascom_state::load_nascom1_cassette ) { @@ -413,6 +459,20 @@ void nascom_state::machine_reset() m_hd6402->write_cs(1); } +MACHINE_RESET_MEMBER(nascom2_state, nascom2) +{ + machine_reset(); + + // nascom2: restore speed at machine start + m_cass_speed = ioport("DSW0")->read(); + + // base machine reset + nascom_state::machine_reset(); + + // restart address (on the real system, a12 to a15 are forced to 1 for one memory cycle) + m_maincpu->set_state_int(Z80_PC, m_lsw1->read() << 12); +} + void nascom_state::init_nascom() { // install extra memory @@ -422,14 +482,6 @@ void nascom_state::init_nascom() } } -void nascom2_state::machine_reset() -{ - // base machine reset - nascom_state::machine_reset(); - - // restart address (on the real system, a12 to a15 are forced to 1 for one memory cycle) - m_maincpu->set_state_int(Z80_PC, m_lsw1->read() << 12); -} // since we don't know for which regions we should disable ram, we just let other devices // overwrite the region they need, and re-install our ram when they are disabled @@ -659,6 +711,11 @@ static INPUT_PORTS_START( nascom2 ) PORT_MODIFY("KEY.7") PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(']') PORT_CHAR('_') + PORT_START("DSW0") + PORT_DIPNAME(0x01, 0x00, "Cassette Baud Rate") PORT_CHANGED_MEMBER(DEVICE_SELF, nascom2_state, cass_speed, nullptr) + PORT_DIPSETTING(0x00, "300") + PORT_DIPSETTING(0x01, "1200") + // link switch on board PORT_START("lsw1") PORT_DIPNAME(0x0f, 0x00, "Restart address") @@ -705,6 +762,11 @@ static INPUT_PORTS_START( nascom2c ) PORT_DIPSETTING(0x0f, "F000H") INPUT_PORTS_END +INPUT_CHANGED_MEMBER(nascom2_state::cass_speed) +{ + m_cass_speed = newval ? 1 : 0; +} + //************************************************************************** // MACHINE DRIVERS @@ -724,29 +786,24 @@ void nascom_state::nascom(machine_config &config) GFXDECODE(config, m_gfxdecode, m_palette, gfx_nascom1); PALETTE(config, m_palette, palette_device::MONOCHROME); + // pio + Z80PIO(config, "z80pio", 16_MHz_XTAL / 8); + + // internal extra ram + RAM(config, m_ram).set_default_size("48K").set_extra_options("8K,16K,32K"); + // uart AY31015(config, m_hd6402); - m_hd6402->read_si_callback().set(FUNC(nascom_state::nascom1_hd6402_si)); - m_hd6402->write_so_callback().set(FUNC(nascom_state::nascom1_hd6402_so)); + m_hd6402->read_si_callback().set(FUNC(nascom_state::hd6402_si)); + m_hd6402->write_so_callback().set(FUNC(nascom_state::hd6402_so)); m_hd6402->set_auto_rdav(true); - clock_device &uart_clock(CLOCK(config, "uart_clock", (16_MHz_XTAL / 16) / 256)); - uart_clock.signal_handler().set(FUNC(nascom_state::kansas_w)); - uart_clock.signal_handler().append(m_hd6402, FUNC(ay31015_device::write_rcp)); - // cassette is connected to the uart CASSETTE(config, m_cass); m_cass->set_interface("nascom_cass"); m_cass->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED); SPEAKER(config, "mono").front_center(); - WAVE(config, "wave", m_cass).add_route(ALL_OUTPUTS, "mono", 0.05); - TIMER(config, "kansas_r").configure_periodic(FUNC(nascom_state::kansas_r), attotime::from_hz(40000)); - - // pio - Z80PIO(config, "z80pio", 16_MHz_XTAL / 8); - - // internal extra ram - RAM(config, m_ram).set_default_size("48K").set_extra_options("8K,16K,32K"); + m_cass->add_route(ALL_OUTPUTS, "mono", 0.05); // devices snapshot_image_device &snapshot(SNAPSHOT(config, "snapshot", "nas", attotime::from_msec(500))); @@ -767,6 +824,11 @@ void nascom1_state::nascom1(machine_config &config) // software SOFTWARE_LIST(config, "snap_list").set_original("nascom_snap").set_filter("NASCOM1"); + + clock_device &uart_clock(CLOCK(config, "uart_clock", (16_MHz_XTAL / 16) / 256)); + uart_clock.signal_handler().set(FUNC(nascom1_state::nascom1_kansas_w)); + uart_clock.signal_handler().append(m_hd6402, FUNC(ay31015_device::write_rcp)); + TIMER(config, "kansas_r").configure_periodic(FUNC(nascom1_state::nascom1_kansas_r), attotime::from_hz(40000)); } void nascom2_state::nascom2(machine_config &config) @@ -777,6 +839,8 @@ void nascom2_state::nascom2(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &nascom2_state::nascom2_mem); m_maincpu->set_addrmap(AS_IO, &nascom2_state::nascom2_io); + MCFG_MACHINE_RESET_OVERRIDE(nascom2_state, nascom2 ) + // video hardware m_screen->set_size(48 * 8, 16 * 14); m_screen->set_visarea(0, 48 * 8 - 1, 0, 16 * 14 - 1); @@ -804,6 +868,10 @@ void nascom2_state::nascom2(machine_config &config) SOFTWARE_LIST(config, "snap_list").set_original("nascom_snap").set_filter("NASCOM2"); SOFTWARE_LIST(config, "socket_list").set_original("nascom_socket"); SOFTWARE_LIST(config, "floppy_list").set_original("nascom_flop"); + + CLOCK(config, m_clock, (16_MHz_XTAL / 32) / 26); + m_clock->signal_handler().set(FUNC(nascom2_state::nascom2_kansas_w)); + TIMER(config, "kansas_r").configure_periodic(FUNC(nascom2_state::nascom2_kansas_r), attotime::from_hz(40000)); } void nascom2_state::nascom2c(machine_config &config) -- cgit v1.2.3