diff options
Diffstat (limited to 'src/mame/drivers/acrnsys1.cpp')
-rw-r--r-- | src/mame/drivers/acrnsys1.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/src/mame/drivers/acrnsys1.cpp b/src/mame/drivers/acrnsys1.cpp new file mode 100644 index 00000000000..23d35f2807a --- /dev/null +++ b/src/mame/drivers/acrnsys1.cpp @@ -0,0 +1,282 @@ +// license:BSD-3-Clause +// copyright-holders:Dirk Best, Robbbert +/****************************************************************************** + + Acorn System 1 (Microcomputer Kit) + + Skeleton driver + + Driver by Dirk Best + +2011-06-26 Keyboard & display fixed. [Robbbert] + + +http://speleotrove.com/acorn/ + +- (modify) Memory display and modification l (load) Reads a block of bytes from tape +X (go) Run program starting at an address r (return) Resume after a breakpoint +p (point) Inserts or removes breakpoint (up) Increment displayed address +s (store) Writes a block of bytes to tape (down) Decrement displayed address + +Pasting: + 0-F : as is + (inc) : ^ + (dec) : V + M (memory) : - + G (Go) : X + +Test Paste: + -0100^11^22^33^44^55^66^77^88^99^-0100^ + Now press up-arrow to confirm the data has been entered. + + +Example usage: Turn on. Press -. Mode letter will show 'A'. Type in an address + (example FE00). Press - (or any command key). Contents will show + on the right. Use Up & Down keys to cycle through addresses. + +To save a tape, press S then enter start address, press S, enter end address+1, + start recording and press S. The save only takes a few seconds. + +To load a tape, the display must just have dots, (reset if necessary), start + playing tape and immediately press L. The last digit will flicker + as the bytes load. At the end, the dots will show again. There's + no error checking, so if it doesn't work, reset and try again. + +Note that left-most digit is not wired up, and therefore will always be blank. + +******************************************************************************/ + +#include "emu.h" +#include "cpu/m6502/m6502.h" +#include "machine/ins8154.h" +#include "machine/74145.h" +#include "imagedev/cassette.h" +#include "sound/wave.h" +#include "acrnsys1.lh" + + +class acrnsys1_state : public driver_device +{ +public: + acrnsys1_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_ttl74145(*this, "ic8_7445"), + m_cass(*this, "cassette"), + m_digit(0) + { } + + DECLARE_READ8_MEMBER(ins8154_b1_port_a_r); + DECLARE_WRITE8_MEMBER(ins8154_b1_port_a_w); + DECLARE_WRITE8_MEMBER(acrnsys1_led_segment_w); + TIMER_DEVICE_CALLBACK_MEMBER(acrnsys1_c); + TIMER_DEVICE_CALLBACK_MEMBER(acrnsys1_p); +private: + required_device<cpu_device> m_maincpu; + required_device<ttl74145_device> m_ttl74145; + required_device<cassette_image_device> m_cass; + UINT8 m_digit; + UINT8 m_cass_data[4]; + bool m_cass_state; + bool m_cassold; +}; + + + +/*************************************************************************** + KEYBOARD HANDLING +***************************************************************************/ +// bit 7 is cassin +READ8_MEMBER( acrnsys1_state::ins8154_b1_port_a_r ) +{ + UINT8 data = 0x7f, i, key_line = m_ttl74145->read(); + + for (i = 0; i < 8; i++) + { + if (BIT(key_line, i)) + { + char kbdrow[6]; + sprintf(kbdrow,"X%X",i); + data = (ioport(kbdrow)->read() & 0x38) | m_digit; + break; + } + } + data |= m_cass_data[2]; + return data; +} + +// bit 6 is cassout +WRITE8_MEMBER( acrnsys1_state::ins8154_b1_port_a_w ) +{ + m_digit = data & 0x47; + m_ttl74145->write(m_digit & 7); + m_cass_state = BIT(data, 6); +} + +TIMER_DEVICE_CALLBACK_MEMBER(acrnsys1_state::acrnsys1_c) +{ + m_cass_data[3]++; + + if (m_cass_state != m_cassold) + { + m_cass_data[3] = 0; + m_cassold = m_cass_state; + } + + if (m_cass_state) + m_cass->output(BIT(m_cass_data[3], 0) ? -1.0 : +1.0); // 2400Hz + else + m_cass->output(BIT(m_cass_data[3], 1) ? -1.0 : +1.0); // 1200Hz +} + +TIMER_DEVICE_CALLBACK_MEMBER(acrnsys1_state::acrnsys1_p) +{ + /* cassette - turn 1200/2400Hz to a bit */ + m_cass_data[1]++; + UINT8 cass_ws = (m_cass->input() > +0.03) ? 1 : 0; + + if (cass_ws != m_cass_data[0]) + { + m_cass_data[0] = cass_ws; + m_cass_data[2] = ((m_cass_data[1] < 12) ? 128 : 0); + m_cass_data[1] = 0; + } +} + +/*************************************************************************** + LED DISPLAY +***************************************************************************/ + +WRITE8_MEMBER( acrnsys1_state::acrnsys1_led_segment_w ) +{ + UINT8 key_line = m_ttl74145->read(); + + output_set_digit_value(key_line, data); +} + + +/*************************************************************************** + ADDRESS MAPS +***************************************************************************/ + +static ADDRESS_MAP_START( acrnsys1_map, AS_PROGRAM, 8, acrnsys1_state ) + AM_RANGE(0x0000, 0x03ff) AM_RAM + AM_RANGE(0x0e00, 0x0e7f) AM_MIRROR(0x100) AM_DEVREADWRITE("b1", ins8154_device, ins8154_r, ins8154_w) + AM_RANGE(0x0e80, 0x0eff) AM_MIRROR(0x100) AM_RAM + AM_RANGE(0xf800, 0xf9ff) AM_MIRROR(0x600) AM_ROM +ADDRESS_MAP_END + + +/*************************************************************************** + INPUT PORTS +***************************************************************************/ + +static INPUT_PORTS_START( acrnsys1 ) + PORT_START("X0") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X1") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X2") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X3") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X4") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X5") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X6") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR('^') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("X7") + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR('V') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT(0xc7, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("reset") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RST") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("switch") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Switch") PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT(0xfe, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("config") + PORT_CONFNAME( 0x03, 0x00, "Switch connected to") + PORT_CONFSETTING( 0x00, "IRQ" ) + PORT_CONFSETTING( 0x01, "NMI" ) + PORT_CONFSETTING( 0x02, "RST" ) +INPUT_PORTS_END + + +/*************************************************************************** + MACHINE DRIVERS +***************************************************************************/ + +static MACHINE_CONFIG_START( acrnsys1, acrnsys1_state ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", M6502, 1008000) /* 1.008 MHz */ + MCFG_CPU_PROGRAM_MAP(acrnsys1_map) + + MCFG_DEFAULT_LAYOUT(layout_acrnsys1) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) + + /* devices */ + MCFG_DEVICE_ADD("b1", INS8154, 0) + MCFG_INS8154_IN_A_CB(READ8(acrnsys1_state, ins8154_b1_port_a_r)) + MCFG_INS8154_OUT_A_CB(WRITE8(acrnsys1_state, ins8154_b1_port_a_w)) + MCFG_INS8154_OUT_B_CB(WRITE8(acrnsys1_state, acrnsys1_led_segment_w)) + MCFG_DEVICE_ADD("ic8_7445", TTL74145, 0) + MCFG_CASSETTE_ADD( "cassette" ) + MCFG_TIMER_DRIVER_ADD_PERIODIC("acrnsys1_c", acrnsys1_state, acrnsys1_c, attotime::from_hz(4800)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("acrnsys1_p", acrnsys1_state, acrnsys1_p, attotime::from_hz(40000)) +MACHINE_CONFIG_END + + +/*************************************************************************** + ROM DEFINITIONS +***************************************************************************/ + +ROM_START( acrnsys1 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD("acrnsys1.bin", 0xf800, 0x0200, CRC(43dcfc16) SHA1(b987354c55beb5e2ced761970c3339b895a8c09d)) +ROM_END + + +/*************************************************************************** + GAME DRIVERS +***************************************************************************/ + +/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ +COMP( 1978, acrnsys1, 0, 0, acrnsys1, acrnsys1, driver_device, 0, "Acorn", "Acorn System 1", 0 ) |