summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/nascom1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/machine/nascom1.c')
-rw-r--r--src/mess/machine/nascom1.c295
1 files changed, 295 insertions, 0 deletions
diff --git a/src/mess/machine/nascom1.c b/src/mess/machine/nascom1.c
new file mode 100644
index 00000000000..8acca936a9c
--- /dev/null
+++ b/src/mess/machine/nascom1.c
@@ -0,0 +1,295 @@
+/**********************************************************************
+
+ machine/nascom1.c
+
+**********************************************************************/
+
+/* Core includes */
+#include "emu.h"
+#include "includes/nascom1.h"
+
+/* Components */
+#include "cpu/z80/z80.h"
+#include "machine/wd17xx.h"
+#include "machine/ay31015.h"
+
+/* Devices */
+#include "imagedev/snapquik.h"
+#include "imagedev/cassette.h"
+#include "imagedev/flopdrv.h"
+#include "machine/ram.h"
+
+#define NASCOM1_KEY_RESET 0x02
+#define NASCOM1_KEY_INCR 0x01
+
+
+
+/*************************************
+ *
+ * Global variables
+ *
+ *************************************/
+
+
+
+
+/*************************************
+ *
+ * Floppy
+ *
+ *************************************/
+
+static WRITE_LINE_DEVICE_HANDLER( nascom2_fdc_intrq_w )
+{
+ nascom1_state *drvstate = device->machine().driver_data<nascom1_state>();
+ drvstate->m_nascom2_fdc.irq = state;
+}
+
+static WRITE_LINE_DEVICE_HANDLER( nascom2_fdc_drq_w )
+{
+ nascom1_state *drvstate = device->machine().driver_data<nascom1_state>();
+ drvstate->m_nascom2_fdc.drq = state;
+}
+
+const wd17xx_interface nascom2_wd17xx_interface =
+{
+ DEVCB_LINE_VCC,
+ DEVCB_LINE(nascom2_fdc_intrq_w),
+ DEVCB_LINE(nascom2_fdc_drq_w),
+ {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3}
+};
+
+
+READ8_MEMBER(nascom1_state::nascom2_fdc_select_r)
+{
+ return m_nascom2_fdc.select | 0xa0;
+}
+
+
+WRITE8_MEMBER(nascom1_state::nascom2_fdc_select_w)
+{
+ device_t *fdc = machine().device("wd1793");
+ m_nascom2_fdc.select = data;
+
+ logerror("nascom2_fdc_select_w: %02x\n", data);
+
+ if (data & 0x01) wd17xx_set_drive(fdc,0);
+ if (data & 0x02) wd17xx_set_drive(fdc,1);
+ if (data & 0x04) wd17xx_set_drive(fdc,2);
+ if (data & 0x08) wd17xx_set_drive(fdc,3);
+ if (data & 0x10) wd17xx_set_side(fdc,(data & 0x10) >> 4);
+}
+
+
+/*
+ * D0 -- WD1793 IRQ
+ * D1 -- NOT READY
+ * D2 to D6 -- 0
+ * D7 -- WD1793 DRQ
+ *
+ */
+READ8_MEMBER(nascom1_state::nascom2_fdc_status_r)
+{
+ return (m_nascom2_fdc.drq << 7) | m_nascom2_fdc.irq;
+}
+
+/*************************************
+ *
+ * Keyboard
+ *
+ *************************************/
+
+READ8_MEMBER(nascom1_state::nascom1_port_00_r)
+{
+ static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4", "KEY5", "KEY6", "KEY7", "KEY8" };
+
+ if (m_portstat.stat_count < 9)
+ return (ioport(keynames[m_portstat.stat_count])->read() | ~0x7f);
+
+ return (0xff);
+}
+
+
+WRITE8_MEMBER(nascom1_state::nascom1_port_00_w)
+{
+
+ machine().device<cassette_image_device>(CASSETTE_TAG)->change_state(
+ ( data & 0x10 ) ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR );
+
+ if (!(data & NASCOM1_KEY_RESET))
+ {
+ if (m_portstat.stat_flags & NASCOM1_KEY_RESET)
+ m_portstat.stat_count = 0;
+ }
+ else
+ m_portstat.stat_flags = NASCOM1_KEY_RESET;
+
+ if (!(data & NASCOM1_KEY_INCR))
+ {
+ if (m_portstat.stat_flags & NASCOM1_KEY_INCR)
+ m_portstat.stat_count++;
+ }
+ else
+ m_portstat.stat_flags = NASCOM1_KEY_INCR;
+}
+
+
+
+
+/*************************************
+ *
+ * Cassette
+ *
+ *************************************/
+
+
+READ8_MEMBER(nascom1_state::nascom1_port_01_r)
+{
+ return ay31015_get_received_data( m_hd6402 );
+}
+
+
+WRITE8_MEMBER(nascom1_state::nascom1_port_01_w)
+{
+ ay31015_set_transmit_data( m_hd6402, data );
+}
+
+READ8_MEMBER(nascom1_state::nascom1_port_02_r)
+{
+ UINT8 data = 0x31;
+
+ ay31015_set_input_pin( m_hd6402, AY31015_SWE, 0 );
+ data |= ay31015_get_output_pin( m_hd6402, AY31015_OR ) ? 0x02 : 0;
+ data |= ay31015_get_output_pin( m_hd6402, AY31015_PE ) ? 0x04 : 0;
+ data |= ay31015_get_output_pin( m_hd6402, AY31015_FE ) ? 0x08 : 0;
+ data |= ay31015_get_output_pin( m_hd6402, AY31015_TBMT ) ? 0x40 : 0;
+ data |= ay31015_get_output_pin( m_hd6402, AY31015_DAV ) ? 0x80 : 0;
+ ay31015_set_input_pin( m_hd6402, AY31015_SWE, 1 );
+
+ return data;
+}
+
+
+READ8_DEVICE_HANDLER( nascom1_hd6402_si )
+{
+ return 1;
+}
+
+
+WRITE8_DEVICE_HANDLER( nascom1_hd6402_so )
+{
+}
+
+
+DEVICE_IMAGE_LOAD( nascom1_cassette )
+{
+ nascom1_state *state = image.device().machine().driver_data<nascom1_state>();
+ state->m_tape_size = image.length();
+ state->m_tape_image = (UINT8*)image.ptr();
+ if (!state->m_tape_image)
+ return IMAGE_INIT_FAIL;
+
+ state->m_tape_index = 0;
+ return IMAGE_INIT_PASS;
+}
+
+
+DEVICE_IMAGE_UNLOAD( nascom1_cassette )
+{
+ nascom1_state *state = image.device().machine().driver_data<nascom1_state>();
+ state->m_tape_image = NULL;
+ state->m_tape_size = state->m_tape_index = 0;
+}
+
+
+
+/*************************************
+ *
+ * Snapshots
+ *
+ * ASCII .nas format
+ *
+ *************************************/
+
+SNAPSHOT_LOAD( nascom1 )
+{
+ UINT8 line[35];
+
+ while (image.fread( &line, sizeof(line)) == sizeof(line))
+ {
+ int addr, b0, b1, b2, b3, b4, b5, b6, b7, dummy;
+
+ if (sscanf((char *)line, "%x %x %x %x %x %x %x %x %x %x\010\010\n",
+ &addr, &b0, &b1, &b2, &b3, &b4, &b5, &b6, &b7, &dummy) == 10)
+ {
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b0);
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b1);
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b2);
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b3);
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b4);
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b5);
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b6);
+ image.device().machine().device("maincpu")->memory().space(AS_PROGRAM)->write_byte(addr++, b7);
+ }
+ }
+
+ return IMAGE_INIT_PASS;
+}
+
+
+
+/*************************************
+ *
+ * Initialization
+ *
+ *************************************/
+
+MACHINE_RESET( nascom1 )
+{
+ nascom1_state *state = machine.driver_data<nascom1_state>();
+ state->m_hd6402 = machine.device("hd6402");
+
+ /* Set up hd6402 pins */
+ ay31015_set_input_pin( state->m_hd6402, AY31015_SWE, 1 );
+
+ ay31015_set_input_pin( state->m_hd6402, AY31015_CS, 0 );
+ ay31015_set_input_pin( state->m_hd6402, AY31015_NP, 1 );
+ ay31015_set_input_pin( state->m_hd6402, AY31015_NB1, 1 );
+ ay31015_set_input_pin( state->m_hd6402, AY31015_NB2, 1 );
+ ay31015_set_input_pin( state->m_hd6402, AY31015_EPS, 1 );
+ ay31015_set_input_pin( state->m_hd6402, AY31015_TSB, 1 );
+ ay31015_set_input_pin( state->m_hd6402, AY31015_CS, 1 );
+}
+
+DRIVER_INIT_MEMBER(nascom1_state,nascom1)
+{
+ switch (machine().device<ram_device>(RAM_TAG)->size())
+ {
+ case 1 * 1024:
+ machine().device("maincpu")->memory().space(AS_PROGRAM)->nop_readwrite(
+ 0x1400, 0x9000);
+ break;
+
+ case 16 * 1024:
+ machine().device("maincpu")->memory().space(AS_PROGRAM)->install_readwrite_bank(
+ 0x1400, 0x4fff, "bank1");
+ machine().device("maincpu")->memory().space(AS_PROGRAM)->nop_readwrite(
+ 0x5000, 0xafff);
+ membank("bank1")->set_base(machine().device<ram_device>(RAM_TAG)->pointer());
+ break;
+
+ case 32 * 1024:
+ machine().device("maincpu")->memory().space(AS_PROGRAM)->install_readwrite_bank(
+ 0x1400, 0x8fff, "bank1");
+ machine().device("maincpu")->memory().space(AS_PROGRAM)->nop_readwrite(
+ 0x9000, 0xafff);
+ membank("bank1")->set_base(machine().device<ram_device>(RAM_TAG)->pointer());
+ break;
+
+ case 40 * 1024:
+ machine().device("maincpu")->memory().space(AS_PROGRAM)->install_readwrite_bank(
+ 0x1400, 0xafff, "bank1");
+ membank("bank1")->set_base(machine().device<ram_device>(RAM_TAG)->pointer());
+ break;
+ }
+}