diff options
author | 2015-10-09 19:10:52 +1100 | |
---|---|---|
committer | 2015-10-09 19:10:52 +1100 | |
commit | bc6aa6be4b31305d054f60a491808f3797ecde40 (patch) | |
tree | 52d08df68e91efdd6ba13b1a9ffec3c39731af0e /src | |
parent | 565b835ee137ef29e0650a3416d62719c858a07a (diff) |
eti660: fixed various issues, marked as Working [Robbbert]
Diffstat (limited to 'src')
-rw-r--r-- | src/mame/drivers/eti660.c | 210 | ||||
-rw-r--r-- | src/mame/includes/eti660.h | 46 |
2 files changed, 183 insertions, 73 deletions
diff --git a/src/mame/drivers/eti660.c b/src/mame/drivers/eti660.c index 80b490eff0f..238ec6d9b6f 100644 --- a/src/mame/drivers/eti660.c +++ b/src/mame/drivers/eti660.c @@ -1,21 +1,40 @@ // license:BSD-3-Clause -// copyright-holders:Curt Coder -/* +// copyright-holders:Curt Coder, Robbbert +/***************************************************************************************** - TODO: + ETI project 660, featured in the Australian magazine Electronics Today International. + + Commands: + R - Reset (use this before any other instruction) + S - Step + 0 - Enter modify memory mode + 2 - Save memory to cassette + 4 - Load memory from cassette + 6 - start binary program + 8 - start chip-8 program. + + To modify memory, press R, 0, enter 4-digit address, S, enter data, S, continue on. + R to escape. - - does not boot! - - reset key - - allocate color ram - - quickload - - color on + To save a tape, enter the start address into 0400,0401 (big endian), and the end + address into 0402,0403. Press R. Press record on the tape, press 2. - - keyboard not working - - foreground is black, according to the construction article it should be white. - - it is supposed to reset itself at boot, but that isn't working. You must press R. - - Pressing F3 causes it to jump into the weeds. + To load a tape, enter the start and end addresses as above. Press R, 4. Screen goes + black. Press play on tape. If the screen is still black after the tape ends, press R. + + All chip-8 programs start at 0600. The manual says the max end address is 7FF (gives + 512 bytes), but you can fill up all of memory (gives 2560 bytes). + + TODO: + - sometimes there's no sound when started. You may need to hard reset until it beeps. + - don't know why, but the expected behaviour of our 6821 pia isn't what this machine + expects, so had to add a couple of hacks. + - doesn't run programs for other chip-8 computers (this might be normal?) + - we support BIN files, but have none to test with. + - in Invaders, can't shoot them + - in Maze, the result is rubbish (works in Emma02 emulator) -*/ +**************************************************************************************************/ #include "includes/eti660.h" @@ -23,25 +42,37 @@ READ8_MEMBER( eti660_state::pia_r ) { - int pia_offset = m_maincpu->get_memory_address() & 0x03; + UINT8 pia_offset = m_maincpu->get_memory_address() & 0x03; return m_pia->read(space, pia_offset); } WRITE8_MEMBER( eti660_state::pia_w ) { - int pia_offset = m_maincpu->get_memory_address() & 0x03; + UINT8 pia_offset = m_maincpu->get_memory_address() & 0x03; + + // Some PIA hacks here, as mentioned in the ToDo. + if (pia_offset == 1) + { + // switch color on when requested (test with Wipeout game) + if (data == 0x2c) + m_color_on = 1; + // enable keyboard + if (data == 0x20) + data = 0x24; + } m_pia->write(space, pia_offset, data); } WRITE8_MEMBER( eti660_state::colorram_w ) { - int colorram_offset = m_maincpu->get_memory_address() & 0xff; + offset = m_maincpu->get_memory_address() - 0xc80; - colorram_offset = ((colorram_offset & 0xf8) >> 1) || (colorram_offset & 0x03); + UINT8 colorram_offset = (((offset & 0x1f0) >> 1) | (offset & 0x07)); - m_color_ram[colorram_offset] = data; + if (colorram_offset < 0xc0) + m_color_ram[colorram_offset] = data; } /* Memory Maps */ @@ -49,7 +80,9 @@ WRITE8_MEMBER( eti660_state::colorram_w ) static ADDRESS_MAP_START( eti660_map, AS_PROGRAM, 8, eti660_state ) ADDRESS_MAP_GLOBAL_MASK(0xfff) AM_RANGE(0x0000, 0x03ff) AM_ROM - AM_RANGE(0x0400, 0x0fff) AM_RAM + AM_RANGE(0x0400, 0x047f) AM_RAM + AM_RANGE(0x0480, 0x05ff) AM_RAM AM_SHARE("videoram") + AM_RANGE(0x0600, 0x0fff) AM_RAM ADDRESS_MAP_END static ADDRESS_MAP_START( eti660_io_map, AS_IO, 8, eti660_state ) @@ -60,31 +93,34 @@ static ADDRESS_MAP_START( eti660_io_map, AS_IO, 8, eti660_state ) ADDRESS_MAP_END /* Input Ports */ - static INPUT_PORTS_START( eti660 ) - PORT_START("PA0") + PORT_START("KEY.0") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("KEY.1") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("PA1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') + PORT_START("KEY.2") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') + PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("PA2") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') + PORT_START("KEY.3") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') - - PORT_START("PA3") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("SPECIAL") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_R) @@ -112,7 +148,13 @@ READ_LINE_MEMBER( eti660_state::gdata_r ) READ_LINE_MEMBER( eti660_state::clear_r ) { - return BIT(m_special->read(), 0); + // A hack to make the machine reset itself on + // boot, like the real one does. + if (m_resetcnt < 0xffff) + m_resetcnt++; + if (m_resetcnt == 0xff00) + return 0; + return BIT(m_special->read(), 0); // R key } READ_LINE_MEMBER( eti660_state::ef2_r ) @@ -122,7 +164,7 @@ READ_LINE_MEMBER( eti660_state::ef2_r ) READ_LINE_MEMBER( eti660_state::ef4_r ) { - return BIT(m_special->read(), 1); + return BIT(m_special->read(), 1); // S key } WRITE_LINE_MEMBER( eti660_state::q_w ) @@ -139,9 +181,19 @@ WRITE_LINE_MEMBER( eti660_state::q_w ) WRITE8_MEMBER( eti660_state::dma_w ) { - UINT8 colorram_offset = ((offset & 0xf8) >> 1) | (offset & 0x03); + offset -= 0x480; + + m_color = 7; + + if (m_color_on) + { + UINT8 colorram_offset = ((offset & 0x1f0) >> 1) | (offset & 0x07); - m_color = m_color_ram[colorram_offset]; + if (colorram_offset < 0xc0) + m_color = m_color_ram[colorram_offset]; + } + else + m_color = m_p_videoram[offset] ? 7 : 0; m_cti->con_w(0); // HACK m_cti->dma_w(space, offset, data); @@ -166,14 +218,13 @@ READ8_MEMBER( eti660_state::pia_pa_r ) */ - UINT8 data = 0xf0; + UINT8 i, data = 0xff; + + for (i = 0; i < 4; i++) + if BIT(m_keylatch, i) + return m_io_keyboard[i]->read(); - if (!BIT(m_keylatch, 0)) data &= m_pa0->read(); - if (!BIT(m_keylatch, 1)) data &= m_pa1->read(); - if (!BIT(m_keylatch, 2)) data &= m_pa2->read(); - if (!BIT(m_keylatch, 3)) data &= m_pa3->read(); - - return data | m_keylatch; + return data; } WRITE8_MEMBER( eti660_state::pia_pa_w ) @@ -193,7 +244,57 @@ WRITE8_MEMBER( eti660_state::pia_pa_w ) */ - m_keylatch = data & 0x0f; + m_keylatch = data ^ 0xff; +} + +void eti660_state::machine_reset() +{ + m_resetcnt = 0; + m_color_on = 0; + // fix for F3 soft reboot + m_maincpu->set_state_int(COSMAC_R0, 0); // set R0 to start of rom + m_maincpu->set_state_int(COSMAC_P, 0); // set R0 as the PC register +} + +void eti660_state::machine_start() +{ + save_item(NAME(m_color_ram)); +} + +QUICKLOAD_LOAD_MEMBER( eti660_state, eti660 ) +{ + address_space &space = m_maincpu->space(AS_PROGRAM); + int i; + int quick_addr = 0x600; + int quick_length; + dynamic_buffer quick_data; + int read_; + int result = IMAGE_INIT_FAIL; + + quick_length = image.length(); + quick_data.resize(quick_length); + read_ = image.fread( &quick_data[0], quick_length); + if (read_ != quick_length) + { + image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Cannot read the file"); + image.message(" Cannot read the file"); + } + else + { + for (i = 0; i < quick_length; i++) + if ((quick_addr + i) < 0x1000) + space.write_byte(i + quick_addr, quick_data[i]); + + /* display a message about the loaded quickload */ + if (strcmp(image.filetype(), "bin") == 0) + image.message(" Quickload: size=%04X : start=%04X : end=%04X : Press 6 to start",quick_length,quick_addr,quick_addr+quick_length); + else + image.message(" Quickload: size=%04X : start=%04X : end=%04X : Press 8 to start",quick_length,quick_addr,quick_addr+quick_length); + + result = IMAGE_INIT_PASS; + } + + return result; } /* Machine Drivers */ @@ -224,6 +325,8 @@ static MACHINE_CONFIG_START( eti660, eti660_state ) MCFG_DEVICE_ADD(MC6821_TAG, PIA6821, 0) MCFG_PIA_READPA_HANDLER(READ8(eti660_state, pia_pa_r)) MCFG_PIA_WRITEPA_HANDLER(WRITE8(eti660_state, pia_pa_w)) + MCFG_PIA_IRQA_HANDLER(DEVWRITELINE(CDP1802_TAG, cosmac_device, int_w)) MCFG_DEVCB_INVERT + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE(CDP1802_TAG, cosmac_device, int_w)) MCFG_DEVCB_INVERT MCFG_CASSETTE_ADD("cassette") MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED) @@ -231,6 +334,9 @@ static MACHINE_CONFIG_START( eti660, eti660_state ) /* internal ram */ MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("3K") + + /* quickload */ + MCFG_QUICKLOAD_ADD("quickload", eti660_state, eti660, "bin,c8,ch8", 2) MACHINE_CONFIG_END /* ROMs */ @@ -240,5 +346,5 @@ ROM_START( eti660 ) ROM_LOAD( "eti660.bin", 0x0000, 0x0400, CRC(811dfa62) SHA1(c0c4951e02f873f15560bdc3f35cdf3f99653922) ) ROM_END -/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ -COMP( 1981, eti660, 0, 0, eti660, eti660, driver_device, 0, "Electronics Today International", "ETI-660", MACHINE_NOT_WORKING ) +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP( 1981, eti660, 0, 0, eti660, eti660, driver_device, 0, "Electronics Today International", "ETI-660", 0 ) diff --git a/src/mame/includes/eti660.h b/src/mame/includes/eti660.h index 6298475d66a..0502bcd0cbd 100644 --- a/src/mame/includes/eti660.h +++ b/src/mame/includes/eti660.h @@ -8,6 +8,7 @@ #include "emu.h" #include "cpu/cosmac/cosmac.h" #include "imagedev/cassette.h" +#include "imagedev/snapquik.h" #include "machine/ram.h" #include "machine/6821pia.h" #include "machine/rescap.h" @@ -28,28 +29,16 @@ class eti660_state : public driver_device { public: eti660_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, CDP1802_TAG), - m_cti(*this, CDP1864_TAG), - m_pia(*this, MC6821_TAG), - m_cassette(*this, "cassette"), - m_pa0(*this, "PA0"), - m_pa1(*this, "PA1"), - m_pa2(*this, "PA2"), - m_pa3(*this, "PA3"), - m_special(*this, "SPECIAL") + : driver_device(mconfig, type, tag) + , m_p_videoram(*this, "videoram") + , m_maincpu(*this, CDP1802_TAG) + , m_cti(*this, CDP1864_TAG) + , m_pia(*this, MC6821_TAG) + , m_cassette(*this, "cassette") + , m_io_keyboard(*this, "KEY") + , m_special(*this, "SPECIAL") { } - required_device<cosmac_device> m_maincpu; - required_device<cdp1864_device> m_cti; - required_device<pia6821_device> m_pia; - required_device<cassette_image_device> m_cassette; - required_ioport m_pa0; - required_ioport m_pa1; - required_ioport m_pa2; - required_ioport m_pa3; - required_ioport m_special; - DECLARE_READ8_MEMBER( pia_r ); DECLARE_WRITE8_MEMBER( pia_w ); DECLARE_WRITE8_MEMBER( colorram_w ); @@ -63,13 +52,28 @@ public: DECLARE_WRITE8_MEMBER( dma_w ); DECLARE_READ8_MEMBER( pia_pa_r ); DECLARE_WRITE8_MEMBER( pia_pa_w ); + DECLARE_QUICKLOAD_LOAD_MEMBER( eti660 ); + required_shared_ptr<UINT8> m_p_videoram; + +private: + required_device<cosmac_device> m_maincpu; + required_device<cdp1864_device> m_cti; + required_device<pia6821_device> m_pia; + required_device<cassette_image_device> m_cassette; + required_ioport_array<4> m_io_keyboard; + required_ioport m_special; + + virtual void machine_start(); + virtual void machine_reset(); + UINT16 m_resetcnt; /* keyboard state */ UINT8 m_keylatch; /* video state */ - UINT8 m_color_ram[0x100]; + UINT8 m_color_ram[0xc0]; UINT8 m_color; + bool m_color_on; }; #endif |