summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/einstein.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/einstein.cpp')
-rw-r--r--src/mame/drivers/einstein.cpp577
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 )