diff options
Diffstat (limited to 'src/mame/drivers/einstein.cpp')
-rw-r--r-- | src/mame/drivers/einstein.cpp | 577 |
1 files changed, 334 insertions, 243 deletions
diff --git a/src/mame/drivers/einstein.cpp b/src/mame/drivers/einstein.cpp index 4a333745f5b..ce1d75f413b 100644 --- a/src/mame/drivers/einstein.cpp +++ b/src/mame/drivers/einstein.cpp @@ -1,79 +1,162 @@ -// license:GPL-2.0+ -// copyright-holders:Kevin Thacker, Dirk Best, Phill Harvey-Smith +// license: GPL-2.0+ +// copyright-holders: Kevin Thacker, Dirk Best, Phill Harvey-Smith +// thanks-to: Chris Coxall, Andrew Dunipace /****************************************************************************** Tatung Einstein - TMS9129 VDP Graphics - 16k ram - - Z80 CPU (4 MHz) - - Z80 CTC (4 MHz) - channel 0 is serial transmit clock - channel 1 is serial receive clock - trigger for channel 0,1 and 2 is a 2 MHz clock - trigger for channel 3 is the terminal count of channel 2 - - Intel 8251 Serial (2 MHz clock?) - - WD1770 Floppy Disc controller - density is fixed, 4 drives and double sided supported - - AY-3-8910 PSG (2 MHz) - port A and port B are connected to the keyboard. Port A is keyboard - line select, Port B is data. - - printer connected to port A of PIO. /ACK from printer is connected to /ASTB. - D7-D0 of PIO port A is printer data lines. - ARDY of PIO is connected to /STROBE on printer. - - user port is port B of PIO - keyboard connected to port A and port B of PSG - TODO: - - The ADC is not emulated! - - printer emulation needs checking! - - Many thanks to Chris Coxall for the schematics of the TC-01, the dump of the - system rom and a dump of a Xtal boot disc. - - Many thanks to Andrew Dunipace for his help with the 80-column card - and Speculator hardware (Spectrum emulator). - - Kevin Thacker [MESS driver] - - - 2011-Mar-14, Phill Harvey-Smith. - Having traced out the circuit of the TK02 80 coumn card, I have changed the - emulation to match what the hardware does, the emulation was mostly correct, - just some minor issues with the addressing of the VRAM, and bit 0 of the - status register is the latched output of the 6845 DE, and not vblank. - - Also added defines to stop the log being flooded with keyboard messages :) + - Einstein 256 support (need bios dump) ******************************************************************************/ #include "emu.h" -#include "includes/einstein.h" - #include "cpu/z80/z80.h" #include "cpu/z80/z80daisy.h" +#include "cpu/z80/z80daisy_generic.h" +#include "bus/centronics/ctronics.h" +#include "bus/einstein/pipe/pipe.h" +#include "bus/einstein/userport/userport.h" +#include "bus/rs232/rs232.h" +#include "machine/adc0844.h" #include "machine/clock.h" +#include "machine/i8251.h" +#include "machine/ram.h" +#include "machine/rescap.h" +#include "machine/timer.h" +#include "machine/wd_fdc.h" +#include "machine/z80ctc.h" #include "machine/z80pio.h" +#include "video/tms9928a.h" #include "sound/ay8910.h" +#include "screen.h" #include "softlist.h" #include "speaker.h" +/*************************************************************************** + CONSTANTS +***************************************************************************/ + #define VERBOSE_KEYBOARD 0 #define VERBOSE_DISK 0 +#define XTAL_X001 XTAL_10_738635MHz +#define XTAL_X002 XTAL_8MHz + +#define IC_I001 "i001" /* Z8400A */ +#define IC_I030 "i030" /* AY-3-8910 */ +#define IC_I038 "i038" /* TMM9129 */ +#define IC_I042 "i042" /* WD1770-PH */ +#define IC_I050 "i050" /* ADC0844CCN */ +#define IC_I058 "i058" /* Z8430A */ +#define IC_I060 "i060" /* uPD8251A */ +#define IC_I063 "i063" /* Z8420A */ + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +class einstein_state : public driver_device +{ +public: + einstein_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, IC_I001), + m_keyboard_daisy(*this, "keyboard_daisy"), + m_adc_daisy(*this, "adc_daisy"), + m_fire_daisy(*this, "fire_daisy"), + m_pipe(*this, "pipe"), + m_fdc(*this, IC_I042), + m_ram(*this, RAM_TAG), + m_psg(*this, IC_I030), + m_centronics(*this, "centronics"), + m_strobe_timer(*this, "strobe"), + m_bios(*this, "bios"), + m_bank1(*this, "bank1"), + m_bank2(*this, "bank2"), + m_bank3(*this, "bank3"), + m_floppy{ { *this, IC_I042 ":0" }, { *this, IC_I042 ":1" }, { *this, IC_I042 ":2" }, { *this, IC_I042 ":3" } }, + m_line(*this, "LINE%u", 0), + m_extra(*this, "EXTRA"), + m_buttons(*this, "BUTTONS"), + m_rom_enabled(0), + m_keyboard_line(0), m_keyboard_data(0xff), + m_centronics_busy(0), m_centronics_perror(0), m_centronics_fault(0), m_strobe(-1), + m_int(0) + {} + + DECLARE_INPUT_CHANGED_MEMBER(joystick_button); + TIMER_DEVICE_CALLBACK_MEMBER(keyboard_timer_callback); + DECLARE_WRITE8_MEMBER(keyboard_line_write); + DECLARE_READ8_MEMBER(keyboard_data_read); + DECLARE_READ8_MEMBER(reset_r); + DECLARE_WRITE8_MEMBER(reset_w); + DECLARE_READ8_MEMBER(rom_r); + DECLARE_WRITE8_MEMBER(rom_w); + template <int src> DECLARE_WRITE_LINE_MEMBER(int_w); + DECLARE_READ8_MEMBER(kybint_msk_r); + DECLARE_WRITE8_MEMBER(kybint_msk_w); + DECLARE_WRITE8_MEMBER(adcint_msk_w); + DECLARE_WRITE8_MEMBER(fireint_msk_w); + DECLARE_WRITE8_MEMBER(drsel_w); + DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); + DECLARE_WRITE_LINE_MEMBER(write_centronics_perror); + DECLARE_WRITE_LINE_MEMBER(write_centronics_fault); + DECLARE_WRITE_LINE_MEMBER(ardy_w); + TIMER_DEVICE_CALLBACK_MEMBER(strobe_callback); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + void einstein_scan_keyboard(); + + required_device<cpu_device> m_maincpu; + required_device<z80daisy_generic_device> m_keyboard_daisy; + required_device<z80daisy_generic_device> m_adc_daisy; + required_device<z80daisy_generic_device> m_fire_daisy; + required_device<tatung_pipe_device> m_pipe; + required_device<wd1770_device> m_fdc; + required_device<ram_device> m_ram; + required_device<ay8910_device> m_psg; + required_device<centronics_device> m_centronics; + required_device<timer_device> m_strobe_timer; + required_memory_region m_bios; + required_memory_bank m_bank1; + required_memory_bank m_bank2; + required_memory_bank m_bank3; + required_device<floppy_connector> m_floppy[4]; + required_ioport_array<8> m_line; + required_ioport m_extra; + required_ioport m_buttons; + + int m_rom_enabled; + + uint8_t m_keyboard_line; + uint8_t m_keyboard_data; + + int m_centronics_busy; + int m_centronics_perror; + int m_centronics_fault; + int m_strobe; + + int m_int; +}; + /*************************************************************************** KEYBOARD ***************************************************************************/ +INPUT_CHANGED_MEMBER( einstein_state::joystick_button ) +{ + int button_down = (m_buttons->read() & 0x03) != 0x03; + m_fire_daisy->int_w(button_down ? ASSERT_LINE : CLEAR_LINE); +} + /* refresh keyboard data. It is refreshed when the keyboard line is written */ void einstein_state::einstein_scan_keyboard() { @@ -91,26 +174,16 @@ void einstein_state::einstein_scan_keyboard() m_keyboard_data = data; } -TIMER_DEVICE_CALLBACK_MEMBER(einstein_state::einstein_keyboard_timer_callback) +TIMER_DEVICE_CALLBACK_MEMBER( einstein_state::keyboard_timer_callback ) { /* re-scan keyboard */ einstein_scan_keyboard(); - /* if /fire1 or /fire2 is 0, signal a fire interrupt */ - if ((m_buttons->read() & 0x03) != 0) - { - m_interrupt |= EINSTEIN_FIRE_INT; - } - - /* keyboard data changed? */ if (m_keyboard_data != 0xff) - { - /* generate interrupt */ - m_interrupt |= EINSTEIN_KEY_INT; - } + m_keyboard_daisy->int_w(ASSERT_LINE); } -WRITE8_MEMBER(einstein_state::einstein_keyboard_line_write) +WRITE8_MEMBER( einstein_state::keyboard_line_write ) { if (VERBOSE_KEYBOARD) logerror("einstein_keyboard_line_write: %02x\n", data); @@ -121,7 +194,7 @@ WRITE8_MEMBER(einstein_state::einstein_keyboard_line_write) einstein_scan_keyboard(); } -READ8_MEMBER(einstein_state::einstein_keyboard_data_read) +READ8_MEMBER( einstein_state::keyboard_data_read ) { /* re-scan the keyboard */ einstein_scan_keyboard(); @@ -137,62 +210,58 @@ READ8_MEMBER(einstein_state::einstein_keyboard_data_read) FLOPPY DRIVES ***************************************************************************/ -WRITE8_MEMBER(einstein_state::einstein_drsel_w) +WRITE8_MEMBER(einstein_state::drsel_w) { - if(VERBOSE_DISK) - logerror("%s: einstein_drsel_w %02x\n", machine().describe_context(), data); + if (VERBOSE_DISK) + logerror("%s: drsel_w %02x\n", machine().describe_context(), data); - /* bit 0 to 3 select the drive */ - static const char *names[] = { IC_I042 ":0", IC_I042 ":1", IC_I042 ":2", IC_I042 ":3" }; floppy_image_device *floppy = nullptr; - for(int i=0; i<4; i++) { - if(BIT(data, i)) { - floppy_connector *con = machine().device<floppy_connector>(names[i]); - if(con) - floppy = con->get_device(); - } - } - /* double sided drive connected? */ - if (m_config->read() & data) - { - /* bit 4 selects the side then */ - //floppy->ss_w(BIT(data, 4)); - } - if (floppy) floppy->ss_w(0); + if (BIT(data, 0)) floppy = m_floppy[0]->get_device(); + if (BIT(data, 1)) floppy = m_floppy[1]->get_device(); + if (BIT(data, 2)) floppy = m_floppy[2]->get_device(); + if (BIT(data, 3)) floppy = m_floppy[3]->get_device(); + + if (floppy) + floppy->ss_w(BIT(data, 4)); + m_fdc->set_floppy(floppy); } /*************************************************************************** - UART + CENTRONICS ***************************************************************************/ -WRITE_LINE_MEMBER(einstein_state::einstein_serial_transmit_clock) +WRITE_LINE_MEMBER( einstein_state::write_centronics_busy ) { - m_uart->write_txc(state); + m_centronics_busy = state; } -WRITE_LINE_MEMBER(einstein_state::einstein_serial_receive_clock) +WRITE_LINE_MEMBER( einstein_state::write_centronics_perror ) { - m_uart->write_rxc(state); + m_centronics_perror = state; } +WRITE_LINE_MEMBER( einstein_state::write_centronics_fault ) +{ + m_centronics_fault = state; +} -/*************************************************************************** - MEMORY BANKING -***************************************************************************/ - -void einstein_state::einstein_page_rom() +WRITE_LINE_MEMBER( einstein_state::ardy_w ) { - m_bank1->set_base(m_rom_enabled ? m_region_bios->base() : m_ram->pointer()); + if (m_strobe == 0 && state == 1) + { + m_centronics->write_strobe(1); + m_strobe_timer->adjust(attotime::from_double(TIME_OF_74LS123(RES_K(10), CAP_N(1)))); + } + + m_strobe = state; } -/* writing to this port is a simple trigger, and switches between RAM and ROM */ -WRITE8_MEMBER(einstein_state::einstein_rom_w) +TIMER_DEVICE_CALLBACK_MEMBER( einstein_state::strobe_callback ) { - m_rom_enabled ^= 1; - einstein_page_rom(); + m_centronics->write_strobe(0); } @@ -200,8 +269,6 @@ WRITE8_MEMBER(einstein_state::einstein_rom_w) INTERRUPTS ***************************************************************************/ -/* int priority */ -/* keyboard int->ctc/adc->pio */ static const z80_daisy_config einstein_daisy_chain[] = { { "keyboard_daisy" }, @@ -212,30 +279,39 @@ static const z80_daisy_config einstein_daisy_chain[] = { nullptr } }; -WRITE_LINE_MEMBER(einstein_state::write_centronics_busy) -{ - m_centronics_busy = state; -} - -WRITE_LINE_MEMBER(einstein_state::write_centronics_perror) +template <int src> WRITE_LINE_MEMBER( einstein_state::int_w ) { - m_centronics_perror = state; -} + int old = m_int; -WRITE_LINE_MEMBER(einstein_state::write_centronics_fault) -{ - m_centronics_fault = state; + if (state) + { + m_int |= (1 << src); + if (!old) + { + m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); + m_pipe->host_int_w(ASSERT_LINE); + } + } + else + { + m_int &= ~(1 << src); + if (old && !m_int) + { + m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); + m_pipe->host_int_w(CLEAR_LINE); + } + } } -READ8_MEMBER(einstein_state::einstein_kybintmsk_r) +READ8_MEMBER( einstein_state::kybint_msk_r ) { uint8_t data = 0; - /* clear key int. a read of this I/O port will do this or a reset */ - m_interrupt &= ~EINSTEIN_KEY_INT; + // reading this port clears the keyboard interrupt + m_keyboard_daisy->int_w(CLEAR_LINE); /* bit 0 and 1: fire buttons on the joysticks */ - data |= m_buttons->read(); + data |= m_buttons->read() & 0x03; /* bit 2 to 4: printer status */ data |= m_centronics_busy << 2; @@ -246,62 +322,27 @@ READ8_MEMBER(einstein_state::einstein_kybintmsk_r) data |= m_extra->read(); if(VERBOSE_KEYBOARD) - logerror("%s: einstein_kybintmsk_r %02x\n", machine().describe_context(), data); + logerror("%s: kybint_msk_r %02x\n", machine().describe_context(), data); return data; } -WRITE8_MEMBER(einstein_state::einstein_kybintmsk_w) +WRITE8_MEMBER( einstein_state::kybint_msk_w ) { - logerror("%s: einstein_kybintmsk_w %02x\n", machine().describe_context(), data); - - /* set mask from bit 0 */ - if (data & 0x01) - { - logerror("key int is disabled\n"); - m_interrupt_mask &= ~EINSTEIN_KEY_INT; - } - else - { - logerror("key int is enabled\n"); - m_interrupt_mask |= EINSTEIN_KEY_INT; - } + logerror("KEY interrupt %s\n", BIT(data, 0) ? "disabled" : "enabled"); + m_keyboard_daisy->mask_w(BIT(data, 0)); } -/* writing to this I/O port sets the state of the mask; D0 is used */ -/* writing 0 enables the /ADC interrupt */ -WRITE8_MEMBER(einstein_state::einstein_adcintmsk_w) +WRITE8_MEMBER( einstein_state::adcint_msk_w ) { - logerror("%s: einstein_adcintmsk_w %02x\n", machine().describe_context(), data); - - if (data & 0x01) - { - logerror("adc int is disabled\n"); - m_interrupt_mask &= ~EINSTEIN_ADC_INT; - } - else - { - logerror("adc int is enabled\n"); - m_interrupt_mask |= EINSTEIN_ADC_INT; - } + logerror("ADC interrupt %s\n", BIT(data, 0) ? "disabled" : "enabled"); + m_adc_daisy->mask_w(BIT(data, 0)); } -/* writing to this I/O port sets the state of the mask; D0 is used */ -/* writing 0 enables the /FIRE interrupt */ -WRITE8_MEMBER(einstein_state::einstein_fire_int_w) +WRITE8_MEMBER( einstein_state::fireint_msk_w ) { - logerror("%s: einstein_fire_int_w %02x\n", machine().describe_context(), data); - - if (data & 0x01) - { - logerror("fire int is disabled\n"); - m_interrupt_mask &= ~EINSTEIN_FIRE_INT; - } - else - { - logerror("fire int is enabled\n"); - m_interrupt_mask |= EINSTEIN_FIRE_INT; - } + logerror("FIRE interrupt %s\n", BIT(data, 0) ? "disabled" : "enabled"); + m_fire_daisy->mask_w(BIT(data, 0)); } @@ -309,8 +350,42 @@ WRITE8_MEMBER(einstein_state::einstein_fire_int_w) MACHINE EMULATION ***************************************************************************/ +READ8_MEMBER( einstein_state::rom_r ) +{ + m_rom_enabled ^= 1; + m_bank1->set_entry(m_rom_enabled); + + return 0xff; +} + +WRITE8_MEMBER( einstein_state::rom_w ) +{ + m_rom_enabled ^= 1; + m_bank1->set_entry(m_rom_enabled); +} + +READ8_MEMBER( einstein_state::reset_r ) +{ + m_psg->reset(); + m_fdc->reset(); + + return 0xff; +} + +WRITE8_MEMBER( einstein_state::reset_w ) +{ + m_psg->reset(); + m_fdc->reset(); +} + void einstein_state::machine_start() { + // initialize memory mapping + m_bank1->configure_entry(0, m_ram->pointer()); + m_bank1->configure_entry(1, m_bios->base()); + m_bank2->set_base(m_ram->pointer()); + m_bank3->set_base(m_ram->pointer() + 0x8000); + // setup expansion slot m_pipe->set_program_space(&m_maincpu->space(AS_PROGRAM)); m_pipe->set_io_space(&m_maincpu->space(AS_IO)); @@ -318,16 +393,16 @@ void einstein_state::machine_start() void einstein_state::machine_reset() { - /* initialize memory mapping */ - m_bank2->set_base(m_ram->pointer()); - m_bank3->set_base(m_ram->pointer() + 0x8000); + // rom enabled on reset m_rom_enabled = 1; - einstein_page_rom(); + m_bank1->set_entry(m_rom_enabled); - /* a reset causes the fire int, adc int, keyboard int mask - to be set to 1, which causes all these to be DISABLED */ - m_interrupt = 0; - m_interrupt_mask = 0; + // interrupt mask enabled + m_keyboard_daisy->mask_w(1); + m_adc_daisy->mask_w(1); + m_fire_daisy->mask_w(1); + + m_strobe = -1; } @@ -340,34 +415,25 @@ static ADDRESS_MAP_START( einstein_mem, AS_PROGRAM, 8, einstein_state ) AM_RANGE(0x8000, 0x0ffff) AM_RAMBANK("bank3") ADDRESS_MAP_END -/* The I/O ports are decoded into 8 blocks using address lines A3 to A7 */ +// I/O ports are decoded into 8 blocks using address lines A3 to A7 static ADDRESS_MAP_START( einstein_io, AS_IO, 8, einstein_state ) ADDRESS_MAP_UNMAP_HIGH - /* block 0, ay8910 psg */ + AM_RANGE(0x00, 0x00) AM_MIRROR(0xff04) AM_READWRITE(reset_r, reset_w) AM_RANGE(0x02, 0x02) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I030, ay8910_device, data_r, address_w) AM_RANGE(0x03, 0x03) AM_MIRROR(0xff04) AM_DEVWRITE(IC_I030, ay8910_device, data_w) - /* block 1, tms9928a vdp */ - AM_RANGE(0x08, 0x08) AM_MIRROR(0xff06) AM_DEVREADWRITE("tms9929a", tms9929a_device, vram_read, vram_write) - AM_RANGE(0x09, 0x09) AM_MIRROR(0xff06) AM_DEVREADWRITE("tms9929a", tms9929a_device, register_read, register_write) - /* block 2, i8251 uart */ + AM_RANGE(0x08, 0x08) AM_MIRROR(0xff06) AM_DEVREADWRITE("vdp", tms9129_device, vram_read, vram_write) + AM_RANGE(0x09, 0x09) AM_MIRROR(0xff06) AM_DEVREADWRITE("vdp", tms9129_device, register_read, register_write) AM_RANGE(0x10, 0x10) AM_MIRROR(0xff06) AM_DEVREADWRITE(IC_I060, i8251_device, data_r, data_w) AM_RANGE(0x11, 0x11) AM_MIRROR(0xff06) AM_DEVREADWRITE(IC_I060, i8251_device, status_r, control_w) - /* block 3, wd1770 floppy controller */ AM_RANGE(0x18, 0x1b) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I042, wd1770_device, read, write) - /* block 4, internal controls */ - AM_RANGE(0x20, 0x20) AM_MIRROR(0xff00) AM_READWRITE(einstein_kybintmsk_r, einstein_kybintmsk_w) - AM_RANGE(0x21, 0x21) AM_MIRROR(0xff00) AM_WRITE(einstein_adcintmsk_w) - AM_RANGE(0x23, 0x23) AM_MIRROR(0xff00) AM_WRITE(einstein_drsel_w) - AM_RANGE(0x24, 0x24) AM_MIRROR(0xff00) AM_WRITE(einstein_rom_w) - AM_RANGE(0x25, 0x25) AM_MIRROR(0xff00) AM_WRITE(einstein_fire_int_w) - /* block 5, z80ctc */ + AM_RANGE(0x20, 0x20) AM_MIRROR(0xff00) AM_READWRITE(kybint_msk_r, kybint_msk_w) + AM_RANGE(0x21, 0x21) AM_MIRROR(0xff00) AM_WRITE(adcint_msk_w) + AM_RANGE(0x23, 0x23) AM_MIRROR(0xff00) AM_WRITE(drsel_w) + AM_RANGE(0x24, 0x24) AM_MIRROR(0xff00) AM_READWRITE(rom_r, rom_w) + AM_RANGE(0x25, 0x25) AM_MIRROR(0xff00) AM_WRITE(fireint_msk_w) AM_RANGE(0x28, 0x2b) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I058, z80ctc_device, read, write) - /* block 6, z80pio */ - AM_RANGE(0x30, 0x33) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I063, z80pio_device, read, write) -#if 0 - /* block 7, adc */ - AM_RANGE(0x38, 0x38) AM_MIRROR(0xff07) AM_DEVREADWRITE_LEGACY(IC_I050, adc0844_r, adc0844_w) -#endif + AM_RANGE(0x30, 0x33) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I063, z80pio_device, read_alt, write_alt) + AM_RANGE(0x38, 0x38) AM_MIRROR(0xff07) AM_DEVREADWRITE("adc", adc0844_device, read, write) ADDRESS_MAP_END @@ -462,41 +528,31 @@ static INPUT_PORTS_START( einstein ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - /* fire buttons for analogue joysticks */ + // fire buttons for analogue joysticks PORT_START("BUTTONS") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 1 Button 1") PORT_PLAYER(1) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 2 Button 1") PORT_PLAYER(2) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 1 Button 1") PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, einstein_state, joystick_button, nullptr) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 2 Button 1") PORT_PLAYER(2) PORT_CHANGED_MEMBER(DEVICE_SELF, einstein_state, joystick_button, nullptr) PORT_BIT(0xfc, IP_ACTIVE_HIGH, IPT_UNUSED) - /* analog joystick 1 x axis */ - PORT_START("JOY1_X") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) PORT_PLAYER(1) PORT_REVERSE - - /* analog joystick 1 y axis */ - PORT_START("JOY1_Y") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) PORT_PLAYER(1) PORT_REVERSE - - /* analog joystick 2 x axis */ - PORT_START("JOY2_X") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) PORT_PLAYER(2) PORT_REVERSE - - /* analog joystick 2 Y axis */ - PORT_START("JOY2_Y") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) PORT_PLAYER(2) PORT_REVERSE - - PORT_START("config") - PORT_CONFNAME(0x01, 0x00, "Floppy drive #1") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x01, "Double sided") - PORT_CONFNAME(0x02, 0x00, "Floppy drive #2") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x02, "Double sided") - PORT_CONFNAME(0x04, 0x00, "Floppy drive #3") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x04, "Double sided") - PORT_CONFNAME(0x08, 0x00, "Floppy drive #4") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x08, "Double sided") + PORT_START("analogue_1_x") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(1) + PORT_CODE_DEC(KEYCODE_4_PAD) PORT_CODE_INC(KEYCODE_6_PAD) + PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + + PORT_START("analogue_1_y") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(1) + PORT_CODE_DEC(KEYCODE_8_PAD) PORT_CODE_INC(KEYCODE_2_PAD) + PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) + PORT_REVERSE + + PORT_START("analogue_2_x") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + + PORT_START("analogue_2_y") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) + PORT_REVERSE INPUT_PORTS_END @@ -505,7 +561,12 @@ INPUT_PORTS_END ***************************************************************************/ static SLOT_INTERFACE_START( einstein_floppies ) - SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) + SLOT_INTERFACE("3ss", TEAC_FD_30A) + SLOT_INTERFACE("3ds", FLOPPY_3_DSDD) + SLOT_INTERFACE("525ssqd", FLOPPY_525_SSQD) + SLOT_INTERFACE("525qd", FLOPPY_525_QD) + SLOT_INTERFACE("35ssdd", FLOPPY_35_SSDD) + SLOT_INTERFACE("35dd", FLOPPY_35_DD) SLOT_INTERFACE_END static MACHINE_CONFIG_START( einstein ) @@ -517,17 +578,20 @@ static MACHINE_CONFIG_START( einstein ) /* this is actually clocked at the system clock 4 MHz, but this would be too fast for our driver. So we update at 50Hz and hope this is good enough. */ - MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", einstein_state, einstein_keyboard_timer_callback, attotime::from_hz(50)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", einstein_state, keyboard_timer_callback, attotime::from_hz(50)) MCFG_DEVICE_ADD(IC_I063, Z80PIO, XTAL_X002 / 2) - MCFG_Z80PIO_OUT_INT_CB(INPUTLINE(IC_I001, INPUT_LINE_IRQ0)) + MCFG_Z80PIO_OUT_INT_CB(WRITELINE(einstein_state, int_w<0>)) MCFG_Z80PIO_OUT_PA_CB(DEVWRITE8("cent_data_out", output_latch_device, write)) - MCFG_Z80PIO_OUT_PB_CB(DEVWRITELINE("centronics", centronics_device, write_strobe)) + MCFG_Z80PIO_OUT_ARDY_CB(WRITELINE(einstein_state, ardy_w)) + MCFG_Z80PIO_IN_PB_CB(DEVREAD8("user", einstein_userport_device, read)) + MCFG_Z80PIO_OUT_PB_CB(DEVWRITE8("user", einstein_userport_device, write)) + MCFG_Z80PIO_OUT_BRDY_CB(DEVWRITELINE("user", einstein_userport_device, brdy_w)) MCFG_DEVICE_ADD(IC_I058, Z80CTC, XTAL_X002 / 2) - MCFG_Z80CTC_INTR_CB(INPUTLINE(IC_I001, INPUT_LINE_IRQ0)) - MCFG_Z80CTC_ZC0_CB(WRITELINE(einstein_state, einstein_serial_transmit_clock)) - MCFG_Z80CTC_ZC1_CB(WRITELINE(einstein_state, einstein_serial_receive_clock)) + MCFG_Z80CTC_INTR_CB(WRITELINE(einstein_state, int_w<1>)) + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE(IC_I060, i8251_device, write_txc)) + MCFG_Z80CTC_ZC1_CB(DEVWRITELINE(IC_I060, i8251_device, write_rxc)) MCFG_Z80CTC_ZC2_CB(DEVWRITELINE(IC_I058, z80ctc_device, trg3)) MCFG_CLOCK_ADD("ctc_trigger", XTAL_X002 / 4) @@ -536,24 +600,34 @@ static MACHINE_CONFIG_START( einstein ) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(IC_I058, z80ctc_device, trg2)) /* Einstein daisy chain support for non-Z80 devices */ - MCFG_DEVICE_ADD("keyboard_daisy", EINSTEIN_KEYBOARD_DAISY, 0) - MCFG_DEVICE_ADD("adc_daisy", EINSTEIN_ADC_DAISY, 0) - MCFG_DEVICE_ADD("fire_daisy", EINSTEIN_FIRE_DAISY, 0) + MCFG_Z80DAISY_GENERIC_ADD("keyboard_daisy", 0xf7) + MCFG_Z80DAISY_GENERIC_INT_CB(WRITELINE(einstein_state, int_w<2>)) + MCFG_Z80DAISY_GENERIC_ADD("adc_daisy", 0xfb) + MCFG_Z80DAISY_GENERIC_INT_CB(WRITELINE(einstein_state, int_w<3>)) + MCFG_Z80DAISY_GENERIC_ADD("fire_daisy", 0xfd) + MCFG_Z80DAISY_GENERIC_INT_CB(WRITELINE(einstein_state, int_w<4>)) /* video hardware */ - MCFG_DEVICE_ADD( "tms9929a", TMS9929A, XTAL_10_738635MHz / 2 ) - MCFG_TMS9928A_VRAM_SIZE(0x4000) /* 16k RAM, provided by IC i040 and i041 */ + MCFG_DEVICE_ADD("vdp", TMS9129, XTAL_10_738635MHz / 2) + MCFG_TMS9928A_VRAM_SIZE(0x4000) // 16k RAM, provided by IC i040 and i041 MCFG_TMS9928A_SET_SCREEN("screen") MCFG_TMS9928A_SCREEN_ADD_PAL("screen") - MCFG_SCREEN_UPDATE_DEVICE("tms9929a", tms9929a_device, screen_update) + MCFG_SCREEN_UPDATE_DEVICE("vdp", tms9129_device, screen_update) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD(IC_I030, AY8910, XTAL_X002 / 4) - MCFG_AY8910_PORT_B_READ_CB(READ8(einstein_state, einstein_keyboard_data_read)) - MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(einstein_state, einstein_keyboard_line_write)) + MCFG_AY8910_PORT_B_READ_CB(READ8(einstein_state, keyboard_data_read)) + MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(einstein_state, keyboard_line_write)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.20) + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_INTR_CB(DEVWRITELINE("adc_daisy", z80daisy_generic_device, int_w)) + MCFG_ADC0844_CH1_CB(IOPORT("analogue_1_x")) + MCFG_ADC0844_CH2_CB(IOPORT("analogue_1_y")) + MCFG_ADC0844_CH3_CB(IOPORT("analogue_2_x")) + MCFG_ADC0844_CH4_CB(IOPORT("analogue_2_y")) + /* printer */ MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") MCFG_CENTRONICS_ACK_HANDLER(DEVWRITELINE(IC_I063, z80pio_device, strobe_a)) @@ -563,15 +637,27 @@ static MACHINE_CONFIG_START( einstein ) MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") - /* uart */ - MCFG_DEVICE_ADD(IC_I060, I8251, 0) + MCFG_TIMER_DRIVER_ADD("strobe", einstein_state, strobe_callback) + // uart + MCFG_DEVICE_ADD(IC_I060, I8251, XTAL_X002 / 4) + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + + // rs232 port + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE(IC_I060, i8251_device, write_rxd)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE(IC_I060, i8251_device, write_dsr)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE(IC_I060, i8251_device, write_cts)) + + // floppy MCFG_WD1770_ADD(IC_I042, XTAL_X002) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":0", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":1", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":2", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":3", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":0", einstein_floppies, "3ss", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":1", einstein_floppies, "3ss", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":2", einstein_floppies, "525qd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":3", einstein_floppies, "525qd", floppy_image_device::default_floppy_formats) /* software lists */ MCFG_SOFTWARE_LIST_ADD("disk_list","einstein") @@ -583,6 +669,11 @@ static MACHINE_CONFIG_START( einstein ) // tatung pipe connector MCFG_TATUNG_PIPE_ADD("pipe") + MCFG_TATUNG_PIPE_NMI_HANDLER(INPUTLINE(IC_I001, INPUT_LINE_NMI)) + + // user port + MCFG_EINSTEIN_USERPORT_ADD("user") + MCFG_EINSTEIN_USERPORT_BSTB_HANDLER(DEVWRITELINE(IC_I063, z80pio_device, strobe_b)) MACHINE_CONFIG_END @@ -609,7 +700,7 @@ ROM_END ROM_START( einst256 ) ROM_REGION(0x8000, "bios", 0) - ROM_LOAD("tc256.rom", 0x0000, 0x4000, CRC(ef8dad88) SHA1(eb2102d3bef572db7161c26a7c68a5fcf457b4d0) ) + ROM_LOAD("tc256.rom", 0x0000, 0x4000, BAD_DUMP CRC(ef8dad88) SHA1(eb2102d3bef572db7161c26a7c68a5fcf457b4d0) ) ROM_END @@ -619,4 +710,4 @@ ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS COMP( 1984, einstein, 0, 0, einstein, einstein, einstein_state, 0, "Tatung", "Einstein TC-01", 0 ) -COMP( 1984, einst256, 0, 0, einstein, einstein, einstein_state, 0, "Tatung", "Einstein 256", MACHINE_NOT_WORKING ) +COMP( 1986, einst256, 0, 0, einstein, einstein, einstein_state, 0, "Tatung", "Einstein 256", MACHINE_NOT_WORKING ) |