summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/osi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/osi.cpp')
-rw-r--r--src/mame/drivers/osi.cpp908
1 files changed, 908 insertions, 0 deletions
diff --git a/src/mame/drivers/osi.cpp b/src/mame/drivers/osi.cpp
new file mode 100644
index 00000000000..01e59360901
--- /dev/null
+++ b/src/mame/drivers/osi.cpp
@@ -0,0 +1,908 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder, Robbbert, Wilbert Pol
+/*
+
+Ohio Scientific Superboard II Model 600
+
+PCB Layout
+----------
+
+OHIO SCIENTIFIC MODEL 600 REV D
+
+|-------------------------------------------------------------------------------------------|
+| 2114 2114 |
+| LS138 CN1 |
+| IC1 2114 2114 |
+| LS04 LS75 LS75 |
+| 2114 2114 |
+| LS138 |
+| 2114 2114 LS125 LS125 |
+| LS138 |
+| - 2114 2114 8T28 8T28 |
+| | |
+|C| 2114 2114 |
+|N| |
+|3| 2114 2114 6502 |
+| | |
+| - 2114 2114 |
+| |
+| 2114 8T28 ROM0 |
+| LS163 LS157 LS174 |
+| 2114 8T28 ROM1 |
+| CA3130 LS163 LS157 LS02 |
+| 2114 8T28 ROM2 |
+| LS14 LS163 LS157 LS04 |
+| SW1 ROM3 |
+| 7417 7404 LS20 ROM5 7408 LS139 |
+| ROM4 |
+| - 74123 7474 LS163 LS165 7474 |
+|C| |
+|N| 7476 7400 LS157 LS93 LS04 6850 |
+|2| |
+| - 7403 74123 3.7MHz LS86 LS163 LS20 CN4 |
+|-------------------------------------------------------------------------------------------|
+
+Notes:
+ All IC's shown.
+
+ ROM0-5 -
+ 6502 -
+ 6850 - Asynchronous Communications Interface Adapter
+ 8T28 - 4-Bit Bidirectional Bus Transceiver
+ CA3130 - Operational Amplifier
+ CN1 - OSI-48 bus connector
+ CN2 -
+ CN3 -
+ CN4 - sound connector
+ SW1 -
+
+*/
+
+/*
+
+Compukit UK101
+
+PCB Layout
+----------
+
+|-------------------------------------------------------------------------------------------|
+| 2114 2114 |
+| LS138 CN1 |
+| IC1 2114 2114 |
+| 7404 LS75 LS75 |
+| 2114 2114 |
+| LS138 |
+| 2114 2114 LS125 LS125 |
+| LS138 |
+| - 2114* 2114* 8T28* 8T28* |
+| | |
+|C| 2114* 2114* |
+|N| CN4 |
+|3| 2114* 2114* 6502 |
+| | |
+| - 2114* 2114* |
+| |
+| 2114 8T28 ROM0 |
+| 74163 LS157 |
+| 2114 8T28 ROM1 |
+| IC66' 74163 LS157 7402 |
+| ROM2 |
+| IC67' 74163 LS157 7404 |
+| ROM3 |
+| IC68' 7404 7420 ROM5 LS139 |
+| ROM4 |
+| - LS123 7474 74163 74165 LS123 |
+|C| |
+|N| 7476 7400 7493 7404 6850 |
+|2| |
+| - 7403 LS123 8MHz 74163 LS20 |
+|-------------------------------------------------------------------------------------------|
+
+Notes:
+ All IC's shown.
+
+ ROM0-5 -
+ 6502 -
+ 6850 - Asynchronous Communications Interface Adapter
+ 8T28 - 4-Bit Bidirectional Bus Transceiver
+ CN1 - OSI-48 Bus Connector
+ CN2 -
+ CN3 -
+ CN4 - UHF Modulator Output
+ * - present when 8KB of RAM installed
+ ' - present when cassette option installed
+
+*/
+
+/*
+
+Ohio Scientific Single Sided Floppy Interface
+
+PCB Layout
+----------
+
+OSI 470 REV B
+
+|-------------------------------------------------------------------|
+| |
+| 8T26 8T26 |
+| |
+| 7417 |
+| |
+| 6820 6850 7400 U2C |
+| 7417 |
+| |
+| |
+| 7417 7404 |
+| |
+| |
+| 7417 |
+| |
+| 7400 7404 74123 74123 7410 |
+| 4MHz |
+| |
+| |
+| 7400 7493 74390 74390 74390 7404 7430 7404 |
+| |
+| |
+| U6A |
+| |
+|-------------------------------------------------------------------|
+
+Notes:
+ All IC's shown.
+
+ 6850 - Asynchronous Communications Interface Adapter
+ 6820 - Peripheral Interface Adapter
+ 8T26 - 4-Bit Bidirectional Bus Transceiver
+ U2C - PROTO?
+ U6A - PROTO?
+
+*/
+
+/*
+
+ TODO:
+
+ - fix uk101 video to 64x16
+ - floppy PIA is actually a 6820
+ - break key
+ - power on reset
+ - Superboard II revisions A/C/D
+ - uk101 medium resolution graphics
+ - uk101 ay-3-8910 sound
+ - cassette
+ - faster cassette
+ - floppy
+ - wemon?
+
+*/
+
+/* Notes added 2012-05-11 [Robbbert]
+ General
+ - Added F1 key to toggle the sound on 'sb2m600b', to silence the awful screech.
+ - Added F3 key to simulate the RESET / BREAK key on the real keyboard.
+ - These machines only uses uppercase input. Shift-Lock must be on at all times.
+ - At boot you get a screen DCWM or similar:
+ D = boot from floppy
+ C = Cold boot & start BASIC
+ W = Warm boot (don't use after turning on the machine) jump to 0000.
+ M = Monitor (only options are to read/modify memory, Go, Load a tape).
+ - The corrupt error messages in Basic are normal and are documented in the user
+ manual. It's not a bug.
+
+ Compukit UK101
+ - The Monitor ROM that had always been there is for a 32x32 screen. I assume it
+ was the prototype referred to in the first Practical Electronics construction
+ article. Also, the keyboard doesn't work in Basic.
+ - I found a working rom in another emulator, this runs fine on the 64x16 screen.
+ - But, the proper rom that came with the kit needs to be found.
+ - The proper rom (and the prototype) allow you to boot from floppy, but this is
+ not normally fitted. It appears that it would work the same as in the other
+ systems in this driver.
+
+*/
+
+/* Notes added 2013-01-20
+ Added a modified basic rom, which fixes the garbage collection problem.
+ Try the following program with -bios 0 and -bios 1. It will work only
+ with bios 1. You can copy/paste this code, but make sure you include the
+ trailing blank line.
+
+10 DIM A$(3)
+RUN
+PRINT FRE(0)
+
+*/
+
+
+#include "includes/osi.h"
+#include "machine/clock.h"
+
+/* Sound */
+
+static const discrete_dac_r1_ladder osi600_dac =
+{
+ 4, // size of ladder
+ { 180, 180, 180, 180, 0, 0, 0, 0 }, // R68, R69, R70, R71
+ 5, // 5V
+ RES_K(1), // R67
+ 0, // no rGnd
+ 0 // no cFilter
+};
+
+static DISCRETE_SOUND_START( osi600_discrete_interface )
+ DISCRETE_INPUT_DATA(NODE_01)
+
+ DISCRETE_DAC_R1(NODE_02, NODE_01, DEFAULT_TTL_V_LOGIC_1, &osi600_dac)
+ DISCRETE_CRFILTER(NODE_03, NODE_02, (int)(1.0/(1.0/RES_K(1)+1.0/180+1.0/180+1.0/180+1.0/180)), CAP_U(0.1))
+ DISCRETE_OUTPUT(NODE_03, 100)
+ DISCRETE_GAIN(NODE_04, NODE_03, 32767.0/5)
+ DISCRETE_OUTPUT(NODE_04, 100)
+DISCRETE_SOUND_END
+
+#if 0
+static const discrete_dac_r1_ladder osi600c_dac =
+{
+ 8, // size of ladder
+ { RES_K(68), RES_K(33), RES_K(16), RES_K(8.2), RES_K(3.9), RES_K(2), RES_K(1), 510 }, // R73, R71, R70, R67, R68, R69, R75, R74
+ 5, // 5V
+ 510, // R86
+ 0, // no rGnd
+ CAP_U(33) // C63
+};
+#endif
+
+static DISCRETE_SOUND_START( osi600c_discrete_interface )
+ DISCRETE_INPUT_DATA(NODE_01)
+ DISCRETE_INPUT_LOGIC(NODE_10)
+
+ DISCRETE_DAC_R1(NODE_02, NODE_01, DEFAULT_TTL_V_LOGIC_1, &osi600_dac)
+ DISCRETE_ONOFF(NODE_03, NODE_10, NODE_02)
+ DISCRETE_OUTPUT(NODE_03, 100)
+DISCRETE_SOUND_END
+
+/* Keyboard */
+
+READ8_MEMBER( sb2m600_state::keyboard_r )
+{
+ if (m_io_reset->read())
+ m_maincpu->reset();
+
+ UINT8 data = 0xff;
+
+ if (!BIT(m_keylatch, 0))
+ data &= m_io_row0->read();
+ if (!BIT(m_keylatch, 1))
+ data &= m_io_row1->read();
+ if (!BIT(m_keylatch, 2))
+ data &= m_io_row2->read();
+ if (!BIT(m_keylatch, 3))
+ data &= m_io_row3->read();
+ if (!BIT(m_keylatch, 4))
+ data &= m_io_row4->read();
+ if (!BIT(m_keylatch, 5))
+ data &= m_io_row5->read();
+ if (!BIT(m_keylatch, 6))
+ data &= m_io_row6->read();
+ if (!BIT(m_keylatch, 7))
+ data &= m_io_row7->read();
+
+ return data;
+}
+
+WRITE8_MEMBER( sb2m600_state::keyboard_w )
+{
+ m_keylatch = data;
+
+ if (m_io_sound->read())
+ m_discrete->write(space, NODE_01, (data >> 2) & 0x0f);
+}
+
+WRITE8_MEMBER( uk101_state::keyboard_w )
+{
+ m_keylatch = data;
+}
+
+WRITE8_MEMBER( sb2m600_state::ctrl_w )
+{
+ /*
+
+ bit signal description
+
+ 0 _32 screen size (0=32x32, 1=64x16)
+ 1 COLOR EN color enable
+ 2 BK0
+ 3 BK1
+ 4 DAC DISABLE DAC sound enable
+ 5
+ 6
+ 7
+
+ */
+
+ m_32 = BIT(data, 0);
+ m_coloren = BIT(data, 1);
+
+ m_discrete->write(space, NODE_10, BIT(data, 4));
+}
+
+WRITE8_MEMBER( c1p_state::osi630_ctrl_w )
+{
+ /*
+
+ bit description
+
+ 0 AC control enable
+ 1 tone generator enable
+ 2 modem select (0 = printer, 1 = modem)
+ 3
+ 4
+ 5
+ 6
+ 7
+
+ */
+
+ m_beep->set_state(BIT(data, 1));
+}
+
+WRITE8_MEMBER( c1p_state::osi630_sound_w )
+{
+ if (data) m_beep->set_frequency(49152 / data);
+}
+
+/* Disk Drive */
+
+/*
+ C000 FLOPIN FLOPPY DISK STATUS PORT
+
+ BIT FUNCTION
+ 0 DRIVE 0 READY (0 IF READY)
+ 1 TRACK 0 (0 IF AT TRACK 0)
+ 2 FAULT (0 IF FAULT)
+ 3
+ 4 DRIVE 1 READY (0 IF READY)
+ 5 WRITE PROTECT (0 IF WRITE PROTECT)
+ 6 DRIVE SELECT (1 = A OR C, 0 = B OR D)
+ 7 INDEX (0 IF AT INDEX HOLE)
+
+ C002 FLOPOT FLOPPY DISK CONTROL PORT
+
+ BIT FUNCTION
+ 0 WRITE ENABLE (0 ALLOWS WRITING)
+ 1 ERASE ENABLE (0 ALLOWS ERASING)
+ ERASE ENABLE IS ON 200us AFTER WRITE IS ON
+ ERASE ENABLE IS OFF 530us AFTER WRITE IS OFF
+ 2 STEP BIT : INDICATES DIRECTION OF STEP (WAIT 10us FIRST)
+ 0 INDICATES STEP TOWARD 76
+ 1 INDICATES STEP TOWARD 0
+ 3 STEP (TRANSITION FROM 1 TO 0)
+ MUST HOLD AT LEAST 10us, MIN 8us BETWEEN
+ 4 FAULT RESET (0 RESETS)
+ 5 SIDE SELECT (1 = A OR B, 0 = C OR D)
+ 6 LOW CURRENT (0 FOR TRKS 43-76, 1 FOR TRKS 0-42)
+ 7 HEAD LOAD (0 TO LOAD : MUST WAIT 40ms AFTER)
+
+ C010 ACIA DISK CONTROLLER ACIA STATUS PORT
+ C011 ACIAIO DISK CONTROLLER ACIA I/O PORT
+*/
+
+void sb2m600_state::floppy_index_callback(floppy_image_device *floppy, int state)
+{
+ m_fdc_index = state;
+}
+
+READ8_MEMBER( c1pmf_state::osi470_pia_pa_r )
+{
+ /*
+
+ bit description
+
+ 0 _READY DRIVE 1
+ 1 _TRACK 00
+ 2 _FAULT
+ 3 _SECTOR
+ 4 _READY DRIVE 2
+ 5 _WRITE PROTECT
+ 6
+ 7 _INDEX
+
+ */
+
+ return (m_fdc_index << 7);
+}
+
+WRITE8_MEMBER( c1pmf_state::osi470_pia_pa_w )
+{
+ /*
+
+ bit description
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6 drive select
+ 7
+
+ */
+}
+
+WRITE8_MEMBER( c1pmf_state::osi470_pia_pb_w )
+{
+ /*
+
+ bit description
+
+ 0 _WRITE ENABLE
+ 1 _ERASE ENABLE
+ 2 _STEP IN
+ 3 _STEP
+ 4 _FAULT RESET
+ 5 side select
+ 6 _LOW CURRENT
+ 7 _HEAD LOAD
+
+ */
+}
+
+WRITE_LINE_MEMBER( c1pmf_state::osi470_pia_cb2_w )
+{
+}
+
+/* Memory Maps */
+
+static ADDRESS_MAP_START( osi600_mem, AS_PROGRAM, 8, sb2m600_state )
+ AM_RANGE(0x0000, 0x1fff) AM_RAMBANK("bank1")
+ AM_RANGE(0xa000, 0xbfff) AM_ROM
+ AM_RANGE(0xd000, 0xd3ff) AM_RAM AM_SHARE("video_ram")
+ AM_RANGE(0xdf00, 0xdf00) AM_READWRITE(keyboard_r, keyboard_w)
+ AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w)
+ AM_RANGE(0xf001, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w)
+ AM_RANGE(0xf800, 0xffff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( uk101_mem, AS_PROGRAM, 8, uk101_state )
+ AM_RANGE(0x0000, 0x1fff) AM_RAMBANK("bank1")
+ AM_RANGE(0xa000, 0xbfff) AM_ROM
+ AM_RANGE(0xd000, 0xd3ff) AM_RAM AM_SHARE("video_ram")
+ AM_RANGE(0xd400, 0xd7ff) AM_NOP // bios sets this to spaces at boot
+ AM_RANGE(0xdc00, 0xdfff) AM_READ(keyboard_r) AM_WRITE(keyboard_w)
+ AM_RANGE(0xf000, 0xf000) AM_MIRROR(0x00fe) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w)
+ AM_RANGE(0xf001, 0xf001) AM_MIRROR(0x00fe) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w)
+ AM_RANGE(0xf800, 0xffff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( c1p_mem, AS_PROGRAM, 8, c1p_state )
+ AM_RANGE(0x0000, 0x4fff) AM_RAMBANK("bank1")
+ AM_RANGE(0xa000, 0xbfff) AM_ROM
+ AM_RANGE(0xc704, 0xc707) AM_DEVREADWRITE("pia_1", pia6821_device, read, write)
+ AM_RANGE(0xc708, 0xc70b) AM_DEVREADWRITE("pia_2", pia6821_device, read, write)
+ AM_RANGE(0xc70c, 0xc70f) AM_DEVREADWRITE("pia_3", pia6821_device, read, write)
+ AM_RANGE(0xd000, 0xd3ff) AM_RAM AM_SHARE("video_ram")
+ AM_RANGE(0xd400, 0xd7ff) AM_RAM AM_SHARE("color_ram")
+ AM_RANGE(0xd800, 0xd800) AM_WRITE(ctrl_w)
+ AM_RANGE(0xdf00, 0xdf00) AM_READWRITE(keyboard_r, keyboard_w)
+ AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w)
+ AM_RANGE(0xf001, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w)
+ AM_RANGE(0xf7c0, 0xf7c0) AM_WRITE(osi630_sound_w)
+ AM_RANGE(0xf7e0, 0xf7e0) AM_WRITE(osi630_ctrl_w)
+ AM_RANGE(0xf800, 0xffff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( c1pmf_mem, AS_PROGRAM, 8, c1pmf_state )
+ AM_RANGE(0x0000, 0x4fff) AM_RAMBANK("bank1")
+ AM_RANGE(0xa000, 0xbfff) AM_ROM
+ AM_RANGE(0xc000, 0xc003) AM_DEVREADWRITE("pia_0", pia6821_device, read, write) // FDC
+ AM_RANGE(0xc010, 0xc010) AM_DEVREADWRITE("acia_1", acia6850_device, status_r, control_w)
+ AM_RANGE(0xc011, 0xc011) AM_DEVREADWRITE("acia_1", acia6850_device, data_r, data_w)
+ AM_RANGE(0xc704, 0xc707) AM_DEVREADWRITE("pia_1", pia6821_device, read, write)
+ AM_RANGE(0xc708, 0xc70b) AM_DEVREADWRITE("pia_2", pia6821_device, read, write)
+ AM_RANGE(0xc70c, 0xc70f) AM_DEVREADWRITE("pia_3", pia6821_device, read, write)
+ AM_RANGE(0xd000, 0xd3ff) AM_RAM AM_SHARE("video_ram")
+ AM_RANGE(0xd400, 0xd7ff) AM_RAM AM_SHARE("color_ram")
+ AM_RANGE(0xd800, 0xd800) AM_WRITE(ctrl_w)
+ AM_RANGE(0xdf00, 0xdf00) AM_READWRITE(keyboard_r, keyboard_w)
+ AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w)
+ AM_RANGE(0xf001, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w)
+ AM_RANGE(0xf7c0, 0xf7c0) AM_WRITE(osi630_sound_w)
+ AM_RANGE(0xf7e0, 0xf7e0) AM_WRITE(osi630_ctrl_w)
+ AM_RANGE(0xf800, 0xffff) AM_ROM
+ADDRESS_MAP_END
+
+/* Input Ports */
+
+static INPUT_PORTS_START( osi600 )
+ PORT_START("ROW0")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) PORT_TOGGLE
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT SHIFT") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LEFT SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_TAB) PORT_CHAR(27)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("REPEAT") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\')
+
+ PORT_START("ROW1")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
+
+ PORT_START("ROW2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('M')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('N')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('C')
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
+
+ PORT_START("ROW3")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('J')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('G')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('F')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('D')
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('S')
+
+ PORT_START("ROW4")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('T')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('R')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('E')
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('W')
+
+ PORT_START("ROW5")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("LINE FEED") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR(10)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('O')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
+
+ PORT_START("ROW6")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RUB OUT") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
+
+ PORT_START("ROW7")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'')
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&')
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"')
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+
+ PORT_START("Sound")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_TOGGLE
+
+ PORT_START("Reset")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3))
+INPUT_PORTS_END
+
+static INPUT_PORTS_START( uk101 )
+ PORT_INCLUDE(osi600)
+
+ PORT_MODIFY("ROW0")
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(27)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('~')
+
+ PORT_MODIFY("ROW5")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\')
+INPUT_PORTS_END
+
+/* Machine Start */
+
+WRITE_LINE_MEMBER( sb2m600_state::write_cassette_clock )
+{
+ m_acia_0->write_rxd((m_cassette->input() > 0.0) ? 1 : 0);
+
+ m_acia_0->write_txc(state);
+ m_acia_0->write_rxc(state);
+}
+
+WRITE_LINE_MEMBER( sb2m600_state::cassette_tx )
+{
+ m_cassette->output(state ? +1.0 : -1.0);
+}
+
+void sb2m600_state::machine_start()
+{
+ address_space &program = m_maincpu->space(AS_PROGRAM);
+
+ /* configure RAM banking */
+ membank("bank1")->configure_entry(0, memregion(M6502_TAG)->base());
+ membank("bank1")->set_entry(0);
+
+ switch (m_ram->size())
+ {
+ case 4*1024:
+ program.install_readwrite_bank(0x0000, 0x0fff, "bank1");
+ program.unmap_readwrite(0x1000, 0x1fff);
+ break;
+
+ case 8*1024:
+ program.install_readwrite_bank(0x0000, 0x1fff, "bank1");
+ break;
+ }
+
+ /* register for state saving */
+ save_item(NAME(m_keylatch));
+ save_pointer(NAME(m_video_ram.target()), OSI600_VIDEORAM_SIZE);
+}
+
+void c1p_state::machine_start()
+{
+ address_space &program = m_maincpu->space(AS_PROGRAM);
+
+ /* configure RAM banking */
+ membank("bank1")->configure_entry(0, memregion(M6502_TAG)->base());
+ membank("bank1")->set_entry(0);
+
+ switch (m_ram->size())
+ {
+ case 8*1024:
+ program.install_readwrite_bank(0x0000, 0x1fff, "bank1");
+ program.unmap_readwrite(0x2000, 0x4fff);
+ break;
+
+ case 20*1024:
+ program.install_readwrite_bank(0x0000, 0x4fff, "bank1");
+ break;
+ }
+
+ /* register for state saving */
+ save_item(NAME(m_keylatch));
+ save_item(NAME(m_32));
+ save_item(NAME(m_coloren));
+ save_pointer(NAME(m_video_ram.target()), OSI600_VIDEORAM_SIZE);
+ save_pointer(NAME(m_color_ram.target()), OSI630_COLORRAM_SIZE);
+}
+
+void c1pmf_state::machine_start()
+{
+ c1p_state::machine_start();
+
+ // drive select logic missing
+ if (m_floppy0->get_device())
+ m_floppy0->get_device()->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(sb2m600_state::floppy_index_callback), this));
+}
+
+// disk format: 1 head, 36 tracks (? - manual displays a directory listing with 40 tracks),
+// 10 sectors, 256 byte sector length, first sector id 0
+static SLOT_INTERFACE_START( osi_floppies )
+ SLOT_INTERFACE("ssdd", FLOPPY_525_SSDD)
+SLOT_INTERFACE_END
+
+/* F4 Character Displayer */
+static const gfx_layout osi_charlayout =
+{
+ 8, 8, /* 8 x 8 characters */
+ 256, /* 256 characters */
+ 1, /* 1 bits per pixel */
+ { 0 }, /* no bitplanes */
+ /* x offsets */
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ /* y offsets */
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
+ 8*8 /* every char takes 8 bytes */
+};
+
+static GFXDECODE_START( osi )
+ GFXDECODE_ENTRY( "chargen", 0x0000, osi_charlayout, 0, 1 )
+GFXDECODE_END
+
+/* Machine Drivers */
+
+static MACHINE_CONFIG_START( osi600, sb2m600_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD(M6502_TAG, M6502, X1/4) // .98304 MHz
+ MCFG_CPU_PROGRAM_MAP(osi600_mem)
+
+ /* video hardware */
+ MCFG_FRAGMENT_ADD(osi600_video)
+ MCFG_GFXDECODE_ADD("gfxdecode", "palette", osi)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD(DISCRETE_TAG, DISCRETE, 0)
+ MCFG_DISCRETE_INTF(osi600_discrete_interface)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+
+ /* cassette ACIA */
+ MCFG_DEVICE_ADD("acia_0", ACIA6850, 0)
+ MCFG_ACIA6850_TXD_HANDLER(WRITELINE(sb2m600_state, cassette_tx))
+
+ MCFG_DEVICE_ADD("cassette_clock", CLOCK, X1/32)
+ MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(sb2m600_state, write_cassette_clock))
+
+ /* cassette */
+ MCFG_CASSETTE_ADD("cassette")
+
+ /* internal ram */
+ MCFG_RAM_ADD(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("4K")
+ MCFG_RAM_EXTRA_OPTIONS("8K")
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_START( uk101, uk101_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD(M6502_TAG, M6502, UK101_X1/8) // 1 MHz
+ MCFG_CPU_PROGRAM_MAP(uk101_mem)
+
+ /* video hardware */
+ MCFG_FRAGMENT_ADD(uk101_video)
+ MCFG_GFXDECODE_ADD("gfxdecode", "palette", osi)
+
+ /* cassette ACIA */
+ MCFG_DEVICE_ADD("acia_0", ACIA6850, 0)
+ MCFG_ACIA6850_TXD_HANDLER(WRITELINE(sb2m600_state, cassette_tx))
+
+ MCFG_DEVICE_ADD("cassette_clock", CLOCK, 500000)
+ MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(sb2m600_state, write_cassette_clock))
+
+ /* cassette */
+ MCFG_CASSETTE_ADD("cassette")
+
+ /* internal ram */
+ MCFG_RAM_ADD(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("4K")
+ MCFG_RAM_EXTRA_OPTIONS("8K")
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_START( c1p, c1p_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD(M6502_TAG, M6502, X1/4) // .98304 MHz
+ MCFG_CPU_PROGRAM_MAP(c1p_mem)
+
+ /* video hardware */
+ MCFG_FRAGMENT_ADD(osi630_video)
+ MCFG_GFXDECODE_ADD("gfxdecode", "palette", osi)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD(DISCRETE_TAG, DISCRETE, 0)
+ MCFG_DISCRETE_INTF(osi600c_discrete_interface)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+ MCFG_SOUND_ADD("beeper", BEEP, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+
+ MCFG_DEVICE_ADD("pia_1", PIA6821, 0)
+ MCFG_DEVICE_ADD("pia_2", PIA6821, 0)
+ MCFG_DEVICE_ADD("pia_3", PIA6821, 0)
+
+ /* cassette ACIA */
+ MCFG_DEVICE_ADD("acia_0", ACIA6850, 0)
+ MCFG_ACIA6850_TXD_HANDLER(WRITELINE(sb2m600_state, cassette_tx))
+
+ MCFG_DEVICE_ADD("cassette_clock", CLOCK, X1/32)
+ MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(sb2m600_state, write_cassette_clock))
+
+ /* cassette */
+ MCFG_CASSETTE_ADD("cassette")
+
+ /* internal ram */
+ MCFG_RAM_ADD(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("8K")
+ MCFG_RAM_EXTRA_OPTIONS("20K")
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED_CLASS( c1pmf, c1p, c1pmf_state )
+ MCFG_CPU_MODIFY(M6502_TAG)
+ MCFG_CPU_PROGRAM_MAP(c1pmf_mem)
+
+ MCFG_DEVICE_ADD("pia_0", PIA6821, 0)
+ MCFG_PIA_READPA_HANDLER(READ8(c1pmf_state, osi470_pia_pa_r))
+ MCFG_PIA_WRITEPA_HANDLER(WRITE8(c1pmf_state, osi470_pia_pa_w))
+ MCFG_PIA_WRITEPB_HANDLER(WRITE8(c1pmf_state, osi470_pia_pb_w))
+ MCFG_PIA_CB2_HANDLER(WRITELINE(c1pmf_state, osi470_pia_cb2_w))
+
+ /* floppy ACIA */
+ MCFG_DEVICE_ADD("acia_1", ACIA6850, 0)
+
+ MCFG_DEVICE_ADD("floppy_clock", CLOCK, XTAL_4MHz/8) // 250 kHz
+ MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("acia_1", acia6850_device, write_txc))
+
+ MCFG_FLOPPY_DRIVE_ADD("floppy0", osi_floppies, "ssdd", floppy_image_device::default_floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("floppy1", osi_floppies, NULL, floppy_image_device::default_floppy_formats)
+
+ /* internal ram */
+ MCFG_RAM_MODIFY(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("20K")
+MACHINE_CONFIG_END
+
+/* ROMs */
+
+
+
+ROM_START( sb2m600b )
+ ROM_REGION( 0x10000, M6502_TAG, 0 )
+ ROM_LOAD( "basus01.u9", 0xa000, 0x0800, CRC(f4f5dec0) SHA1(b41bf24b4470b6e969d32fe48d604637276f846e) )
+ ROM_LOAD( "basus02.u10", 0xa800, 0x0800, CRC(0039ef6a) SHA1(1397f0dc170c16c8e0c7d02e63099e986e86385b) )
+ ROM_LOAD( "basus04.u12", 0xb800, 0x0800, CRC(8ee6030e) SHA1(71f210163e4268cba2dd78a97c4d8f5dcebf980e) )
+ ROM_LOAD( "monde01.u13", 0xf800, 0x0800, CRC(95a44d2e) SHA1(4a0241c4015b94c436d0f0f58b3dd9d5207cd847) ) // also known as syn600.rom
+ ROM_SYSTEM_BIOS(0, "original", "Original")
+ ROMX_LOAD("basus03.u11", 0xb000, 0x0800, CRC(ca25f8c1) SHA1(f5e8ee93a5e0656657d0cc60ef44e8a24b8b0a80), ROM_BIOS(1) )
+ ROM_SYSTEM_BIOS(1, "fixed", "Fixed")
+ ROMX_LOAD( "basic3.rom", 0xb000, 0x0800, CRC(ac37d575) SHA1(11407eb24d1ba7afb889b7677c987e8be1a61aab), ROM_BIOS(2) )
+
+ ROM_REGION( 0x0800, "chargen",0)
+ ROM_LOAD( "chgsup2.u41", 0x0000, 0x0800, CRC(735f5e0a) SHA1(87c6271497c5b00a974d905766e91bb965180594) )
+
+ ROM_REGION( 0x0800, "user1",0)
+ // Another bios rom
+ ROM_LOAD( "c2 c4 synmon.rom", 0x0000, 0x0800, CRC(03cdbcc5) SHA1(5426ae14522ef485b6089472011db0ae1d192630) )
+ROM_END
+
+// same roms are used in Challenger 2P and 4P
+#define rom_c1p rom_sb2m600b
+#define rom_c1pmf rom_sb2m600b
+
+ROM_START( uk101 )
+ ROM_REGION( 0x10000, M6502_TAG, 0 )
+ ROM_LOAD( "basuk01.ic9", 0xa000, 0x0800, CRC(9d3caa92) SHA1(b2c3d1af0c4f3cead1dbd44aaf5a11680880f772) )
+ ROM_LOAD( "basus02.ic10", 0xa800, 0x0800, CRC(0039ef6a) SHA1(1397f0dc170c16c8e0c7d02e63099e986e86385b) )
+ ROM_LOAD( "basuk03.ic11", 0xb000, 0x0800, CRC(0d011242) SHA1(54bd33522a5d1991086eeeff3a4f73c026be45b6) )
+ ROM_LOAD( "basuk04.ic12", 0xb800, 0x0800, CRC(667223e8) SHA1(dca78be4b98317413376d69119942d692e39575a) )
+ // This monitor came from another emulator and works well on the 64x16 screen
+ ROM_LOAD( "monuk02.ic13", 0xf800, 0x0800, CRC(e5b7028d) SHA1(74f0934014fdf83d33c8d3579e562b53c0683270) )
+ // This monitor is for a 32x32 screen, and could be the prototype referred to in Practical Electronics
+ //ROM_LOAD( "monuk02.ic13", 0xf800, 0x0800, CRC(04ac5822) SHA1(2bbbcd0ca18103fd68afcf64a7483653b925d83e) )
+
+ ROM_REGION( 0x800, "chargen", 0 )
+ ROM_LOAD( "chguk101.ic41", 0x0000, 0x0800, CRC(fce2c84a) SHA1(baa66a7a48e4d62282671ef53abfaf450b888b70) )
+ROM_END
+
+/* Driver Initialization */
+
+void sb2m600_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_SETUP_BEEP:
+ m_beeper->set_state(0);
+ m_beeper->set_frequency(300);
+ break;
+ default:
+ assert_always(FALSE, "Unknown id in sb2m600_state::device_timer");
+ }
+}
+
+DRIVER_INIT_MEMBER(c1p_state,c1p)
+{
+ timer_set(attotime::zero, TIMER_SETUP_BEEP);
+}
+
+
+/* System Drivers */
+
+// YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME
+COMP( 1978, sb2m600b, 0, 0, osi600, osi600, driver_device, 0, "Ohio Scientific", "Superboard II Model 600 (Rev. B)", MACHINE_NOT_WORKING)
+//COMP( 1980, sb2m600c, 0, 0, osi600c, osi600, driver_device, 0, "Ohio Scientific", "Superboard II Model 600 (Rev. C)", MACHINE_NOT_WORKING)
+COMP( 1980, c1p, sb2m600b, 0, c1p, osi600, c1p_state, c1p, "Ohio Scientific", "Challenger 1P Series 2", MACHINE_NOT_WORKING)
+COMP( 1980, c1pmf, sb2m600b, 0, c1pmf, osi600, c1p_state, c1p, "Ohio Scientific", "Challenger 1P MF Series 2", MACHINE_NOT_WORKING)
+COMP( 1979, uk101, sb2m600b, 0, uk101, uk101, driver_device, 0, "Compukit", "UK101", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW)