summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/abcbus/lux21056.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/abcbus/lux21056.c')
-rw-r--r--src/devices/bus/abcbus/lux21056.c673
1 files changed, 673 insertions, 0 deletions
diff --git a/src/devices/bus/abcbus/lux21056.c b/src/devices/bus/abcbus/lux21056.c
new file mode 100644
index 00000000000..375a5927c47
--- /dev/null
+++ b/src/devices/bus/abcbus/lux21056.c
@@ -0,0 +1,673 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ Luxor 55 21056-00 Xebec Interface Host Adapter emulation
+
+*********************************************************************/
+
+/*
+
+ Use the CHDMAN utility to create a 10MB image for ABC 850:
+
+ $ chdman createhd -o ro202.chd -chs 321,4,32 -ss 256
+ $ chdman createhd -o basf6186.chd -chs 440,4,32 -ss 256
+
+ or a 20MB image for ABC 852:
+
+ $ chdman createhd -o basf6185.chd -chs 440,6,32 -ss 256
+ $ chdman createhd -o nec5126.chd -chs 615,4,32 -ss 256
+
+ or a 60MB image for ABC 856:
+
+ $ chdman createhd -o micr1325.chd -chs 1024,8,32 -ss 256
+
+ Start the abc800 emulator with the ABC 850 attached on the ABC bus,
+ with the new CHD and a UFD-DOS floppy mounted:
+
+ $ mess abc800m -bus abc850 -flop1 ufd631 -hard ro202.chd
+ $ mess abc800m -bus abc850 -bus:abc850:io2 xebec,bios=basf6186 -flop1 ufd631 -hard basf6186.chd
+
+ or with the ABC 852 attached:
+
+ $ mess abc800m -bus abc852 -flop1 ufd631 -hard basf6185.chd
+ $ mess abc800m -bus abc852 -bus:abc852:io2 xebec,bios=nec5126 -flop1 ufd631 -hard nec5126.chd
+
+ or with the ABC 856 attached:
+
+ $ mess abc800m -bus abc856 -flop1 ufd631 -hard micr1325.chd
+
+ Configure the floppy controller for use with an ABC 850:
+
+ - Drive 0 Sides: Double
+ - Drive 1 Sides: Double
+ - Drive 0 Tracks: 40 or 80 depending on the UFD DOS image used
+ - Drive 1 Tracks: 40 or 80 depending on the UFD DOS image used
+ - Card Address: 44 (ABC 832/834/850)
+
+ Reset the emulated machine by pressing F3.
+
+ You should now see the following text at the top of the screen:
+
+ DOS ar UFD-DOS ver. 19
+ DR_: motsvarar MF_:
+
+ Enter "BYE" to get into the UFD-DOS command prompt.
+ Enter "DOSGEN,F HD0:" to start the formatting utility.
+ Enter "J", and enter "J" to confirm the formatting.
+
+ If you have a 20MB image, format the second partition by entering "DOSGEN,F HD1:", "J", and "J".
+
+ If you have a 60MB image, format the third partition by entering "DOSGEN,F HD2:", "J", and "J",
+ and format the fourth partition by entering "DOSGEN,F HD3:", "J", and "J".
+
+ You can now list your freshly created partitions by entering "LIB".
+
+ Or skip all of the above and use the preformatted images in the software list:
+
+ $ mess abc800m -bus abc850 -flop1 ufd631 -hard abc850
+ $ mess abc800m -bus abc852 -flop1 ufd631 -hard abc852
+ $ mess abc800m -bus abc856 -flop1 ufd631 -hard abc856
+
+*/
+
+#include "lux21056.h"
+#include "bus/scsi/s1410.h"
+
+
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#define Z80_TAG "5a"
+#define Z80DMA_TAG "6a"
+#define SASIBUS_TAG "sasi"
+
+#define STAT_DIR \
+ BIT(m_stat, 6)
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type LUXOR_55_21056 = &device_creator<luxor_55_21056_device>;
+
+
+//-------------------------------------------------
+// ROM( luxor_55_21056 )
+//-------------------------------------------------
+
+ROM_START( luxor_55_21056 )
+ ROM_REGION( 0x2000, Z80_TAG, 0 )
+ // ABC 850
+ ROM_SYSTEM_BIOS( 0, "ro202", "Rodime RO202 (CHS: 321,4,32,256)" )
+ ROMX_LOAD( "rodi202.bin", 0x0000, 0x0800, CRC(337b4dcf) SHA1(791ebeb4521ddc11fb9742114018e161e1849bdf), ROM_BIOS(1) ) // Rodime RO202 (http://stason.org/TULARC/pc/hard-drives-hdd/rodime/RO202-11MB-5-25-FH-MFM-ST506.html)
+ ROM_SYSTEM_BIOS( 1, "basf6186", "BASF 6186 (CHS: 440,4,32,256)" )
+ ROMX_LOAD( "basf6186.bin", 0x0000, 0x0800, NO_DUMP, ROM_BIOS(2) ) // BASF 6186 (http://stason.org/TULARC/pc/hard-drives-hdd/basf-magnetics/6186-14MB-5-25-FH-MFM-ST412.html)
+ // ABC 852
+ ROM_SYSTEM_BIOS( 2, "basf6185", "BASF 6185 (CHS: 440,6,32,256)" )
+ ROMX_LOAD( "basf6185.bin", 0x0000, 0x0800, CRC(06f8fe2e) SHA1(e81f2a47c854e0dbb096bee3428d79e63591059d), ROM_BIOS(3) ) // BASF 6185 (http://stason.org/TULARC/pc/hard-drives-hdd/basf-magnetics/6185-22MB-5-25-FH-MFM-ST412.html)
+ ROM_SYSTEM_BIOS( 3, "nec5126", "NEC 5126 (CHS: 615,4,32,256)" )
+ ROMX_LOAD( "nec5126.bin", 0x0000, 0x1000, CRC(17c247e7) SHA1(7339738b87751655cb4d6414422593272fe72f5d), ROM_BIOS(4) ) // NEC 5126 (http://stason.org/TULARC/pc/hard-drives-hdd/nec/D5126-20MB-5-25-HH-MFM-ST506.html)
+ // ABC 856
+ ROM_SYSTEM_BIOS( 4, "micr1325", "Micropolis 1325 (CHS: 1024,8,32,256)" )
+ ROMX_LOAD( "micr1325.bin", 0x0000, 0x0800, CRC(084af409) SHA1(342b8e214a8c4c2b014604e53c45ef1bd1c69ea3), ROM_BIOS(5) ) // Micropolis 1325 (http://stason.org/TULARC/pc/hard-drives-hdd/micropolis/1325-69MB-5-25-FH-MFM-ST506.html)
+ROM_END
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+const rom_entry *luxor_55_21056_device::device_rom_region() const
+{
+ return ROM_NAME( luxor_55_21056 );
+}
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( luxor_55_21056_mem )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( luxor_55_21056_mem, AS_PROGRAM, 8, luxor_55_21056_device )
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0x3fff)
+ AM_RANGE(0x0000, 0x0fff) AM_MIRROR(0x1000) AM_ROM AM_REGION(Z80_TAG, 0)
+ AM_RANGE(0x2000, 0x27ff) AM_MIRROR(0x1800) AM_RAM
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// ADDRESS_MAP( luxor_55_21056_io )
+//-------------------------------------------------
+
+static ADDRESS_MAP_START( luxor_55_21056_io, AS_IO, 8, luxor_55_21056_device )
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0xf8)
+ AM_RANGE(0x00, 0x00) AM_MIRROR(0xf0) AM_DEVREADWRITE(Z80DMA_TAG, z80dma_device, read, write)
+ AM_RANGE(0x08, 0x08) AM_READ(sasi_status_r)
+ AM_RANGE(0x18, 0x18) AM_WRITE(stat_w)
+ AM_RANGE(0x28, 0x28) AM_READ(out_r)
+ AM_RANGE(0x38, 0x38) AM_WRITE(inp_w)
+ AM_RANGE(0x48, 0x48) AM_READWRITE(sasi_data_r, sasi_data_w)
+ AM_RANGE(0x58, 0x58) AM_READWRITE(rdy_reset_r, rdy_reset_w)
+ AM_RANGE(0x68, 0x68) AM_READWRITE(sasi_sel_r, sasi_sel_w)
+ AM_RANGE(0x78, 0x78) AM_READWRITE(sasi_rst_r, sasi_rst_w)
+ADDRESS_MAP_END
+
+
+//-------------------------------------------------
+// z80_daisy_config daisy_chain
+//-------------------------------------------------
+
+static const z80_daisy_config daisy_chain[] =
+{
+ { Z80DMA_TAG },
+ { NULL }
+};
+
+
+//-------------------------------------------------
+// Z80DMA
+//-------------------------------------------------
+
+READ8_MEMBER( luxor_55_21056_device::memory_read_byte )
+{
+ return m_maincpu->space(AS_PROGRAM).read_byte(offset);
+}
+
+WRITE8_MEMBER( luxor_55_21056_device::memory_write_byte )
+{
+ return m_maincpu->space(AS_PROGRAM).write_byte(offset, data);
+}
+
+READ8_MEMBER( luxor_55_21056_device::io_read_byte )
+{
+ return m_maincpu->space(AS_IO).read_byte(offset);
+}
+
+WRITE8_MEMBER( luxor_55_21056_device::io_write_byte )
+{
+ return m_maincpu->space(AS_IO).write_byte(offset, data);
+}
+
+
+WRITE_LINE_MEMBER( luxor_55_21056_device::write_sasi_bsy )
+{
+ m_sasi_bsy = state;
+
+ if (m_sasi_bsy)
+ {
+ m_sasibus->write_sel(!m_sasi_bsy);
+ }
+}
+
+WRITE_LINE_MEMBER( luxor_55_21056_device::write_sasi_io )
+{
+ m_sasi_io = state;
+
+ if (!m_sasi_io)
+ {
+ m_sasi_data_out->write(m_sasi_data);
+ }
+ else
+ {
+ m_sasi_data_out->write(0);
+ }
+}
+
+WRITE_LINE_MEMBER( luxor_55_21056_device::write_sasi_req )
+{
+ m_sasi_req = state;
+
+ if (m_sasi_req)
+ {
+ m_sasibus->write_ack(!m_sasi_req);
+ }
+}
+
+WRITE_LINE_MEMBER( luxor_55_21056_device::write_sasi_cd )
+{
+ m_sasi_cd = state;
+}
+
+WRITE_LINE_MEMBER( luxor_55_21056_device::write_sasi_msg )
+{
+ m_sasi_msg = state;
+}
+
+//-------------------------------------------------
+// MACHINE_DRIVER( luxor_55_21056 )
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( luxor_55_21056 )
+ MCFG_CPU_ADD(Z80_TAG, Z80, XTAL_8MHz/2)
+ MCFG_CPU_PROGRAM_MAP(luxor_55_21056_mem)
+ MCFG_CPU_IO_MAP(luxor_55_21056_io)
+ MCFG_CPU_CONFIG(daisy_chain)
+
+ MCFG_DEVICE_ADD(Z80DMA_TAG, Z80DMA, XTAL_8MHz/2)
+ MCFG_Z80DMA_OUT_BUSREQ_CB(INPUTLINE(Z80_TAG, INPUT_LINE_HALT))
+ MCFG_Z80DMA_OUT_INT_CB(INPUTLINE(Z80_TAG, INPUT_LINE_IRQ0))
+ MCFG_Z80DMA_IN_MREQ_CB(READ8(luxor_55_21056_device, memory_read_byte))
+ MCFG_Z80DMA_OUT_MREQ_CB(WRITE8(luxor_55_21056_device, memory_write_byte))
+ MCFG_Z80DMA_IN_IORQ_CB(READ8(luxor_55_21056_device, io_read_byte))
+ MCFG_Z80DMA_OUT_IORQ_CB(WRITE8(luxor_55_21056_device, io_write_byte))
+
+ MCFG_DEVICE_ADD(SASIBUS_TAG, SCSI_PORT, 0)
+ MCFG_SCSI_DATA_INPUT_BUFFER("sasi_data_in")
+ MCFG_SCSI_REQ_HANDLER(WRITELINE(luxor_55_21056_device, write_sasi_req))
+ MCFG_SCSI_IO_HANDLER(WRITELINE(luxor_55_21056_device, write_sasi_io))
+ MCFG_SCSI_CD_HANDLER(WRITELINE(luxor_55_21056_device, write_sasi_cd))
+ MCFG_SCSI_MSG_HANDLER(WRITELINE(luxor_55_21056_device, write_sasi_msg))
+ MCFG_SCSI_BSY_HANDLER(WRITELINE(luxor_55_21056_device, write_sasi_bsy))
+ MCFG_SCSIDEV_ADD(SASIBUS_TAG ":" SCSI_PORT_DEVICE1, "harddisk", S1410, SCSI_ID_0)
+
+ MCFG_SCSI_OUTPUT_LATCH_ADD("sasi_data_out", SASIBUS_TAG)
+ MCFG_DEVICE_ADD("sasi_data_in", INPUT_BUFFER, 0)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor luxor_55_21056_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( luxor_55_21056 );
+}
+
+
+//-------------------------------------------------
+// INPUT_PORTS( luxor_55_21046 )
+//-------------------------------------------------
+
+INPUT_PORTS_START( luxor_55_21056 )
+ PORT_START("S1")
+ PORT_DIPNAME( 0x3f, 0x24, "Card Address" )
+ PORT_DIPSETTING( 0x20, "32" )
+ PORT_DIPSETTING( 0x21, "33" )
+ PORT_DIPSETTING( 0x22, "34" )
+ PORT_DIPSETTING( 0x23, "35" )
+ PORT_DIPSETTING( 0x24, "36 (ABC 850)" )
+ PORT_DIPSETTING( 0x25, "37" )
+ PORT_DIPSETTING( 0x26, "38" )
+ PORT_DIPSETTING( 0x27, "39" )
+ PORT_DIPSETTING( 0x28, "40" )
+ PORT_DIPSETTING( 0x29, "41" )
+ PORT_DIPSETTING( 0x2a, "42" )
+ PORT_DIPSETTING( 0x2b, "43" )
+ PORT_DIPSETTING( 0x2c, "44" )
+ PORT_DIPSETTING( 0x2d, "45" )
+ PORT_DIPSETTING( 0x2e, "46" )
+ PORT_DIPSETTING( 0x2f, "47" )
+
+ PORT_START("S2")
+ PORT_DIPNAME( 0x01, 0x00, "PROM Size" )
+ PORT_DIPSETTING( 0x00, "2 KB" )
+ PORT_DIPSETTING( 0x01, "8 KB" )
+
+ PORT_START("S3")
+ PORT_DIPNAME( 0x01, 0x00, "RAM Size" )
+ PORT_DIPSETTING( 0x00, "2 KB" )
+ PORT_DIPSETTING( 0x01, "8 KB" )
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor luxor_55_21056_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( luxor_55_21056 );
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// luxor_55_21056_device - constructor
+//-------------------------------------------------
+
+luxor_55_21056_device::luxor_55_21056_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, LUXOR_55_21056, "Luxor 55 21056", tag, owner, clock, "lux21056", __FILE__),
+ device_abcbus_card_interface(mconfig, *this),
+ m_maincpu(*this, Z80_TAG),
+ m_dma(*this, Z80DMA_TAG),
+ m_sasibus(*this, SASIBUS_TAG),
+ m_sasi_data_out(*this, "sasi_data_out"),
+ m_sasi_data_in(*this, "sasi_data_in"),
+ m_s1(*this, "S1"),
+ m_cs(false),
+ m_rdy(0),
+ m_sasi_req(0),
+ m_sasi_io(0),
+ m_sasi_cd(0),
+ m_sasi_msg(0),
+ m_sasi_bsy(0),
+ m_stat(0),
+ m_sasi_data(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void luxor_55_21056_device::device_start()
+{
+ // state saving
+ save_item(NAME(m_cs));
+ save_item(NAME(m_rdy));
+ save_item(NAME(m_inp));
+ save_item(NAME(m_out));
+ save_item(NAME(m_stat));
+ save_item(NAME(m_sasi_req));
+ save_item(NAME(m_sasi_io));
+ save_item(NAME(m_sasi_cd));
+ save_item(NAME(m_sasi_msg));
+ save_item(NAME(m_sasi_bsy));
+ save_item(NAME(m_sasi_data));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void luxor_55_21056_device::device_reset()
+{
+ m_maincpu->reset();
+
+ m_cs = false;
+ m_stat = 0;
+ m_sasi_data = 0;
+
+ set_rdy(m_rdy);
+}
+
+
+
+//**************************************************************************
+// ABC BUS INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// abcbus_cs -
+//-------------------------------------------------
+
+void luxor_55_21056_device::abcbus_cs(UINT8 data)
+{
+ m_cs = (data == m_s1->read());
+}
+
+
+//-------------------------------------------------
+// abcbus_stat -
+//-------------------------------------------------
+
+UINT8 luxor_55_21056_device::abcbus_stat()
+{
+ UINT8 data = 0xff;
+
+ if (m_cs)
+ {
+ data = m_stat & 0xfe;
+ data |= m_rdy ^ STAT_DIR;
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// abcbus_inp -
+//-------------------------------------------------
+
+UINT8 luxor_55_21056_device::abcbus_inp()
+{
+ UINT8 data = 0xff;
+
+ if (m_cs && !STAT_DIR)
+ {
+ data = m_inp;
+
+ if (m_rdy) set_rdy(!m_rdy);
+ }
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// abcbus_out -
+//-------------------------------------------------
+
+void luxor_55_21056_device::abcbus_out(UINT8 data)
+{
+ if (m_cs)
+ {
+ m_out = data;
+
+ if (STAT_DIR && !m_rdy) set_rdy(!m_rdy);
+ }
+}
+
+
+//-------------------------------------------------
+// abcbus_c1 -
+//-------------------------------------------------
+
+void luxor_55_21056_device::abcbus_c1(UINT8 data)
+{
+ if (m_cs)
+ {
+ m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
+ m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
+ }
+}
+
+
+//-------------------------------------------------
+// abcbus_c3 -
+//-------------------------------------------------
+
+void luxor_55_21056_device::abcbus_c3(UINT8 data)
+{
+ if (m_cs)
+ {
+ device_reset();
+ }
+}
+
+
+//-------------------------------------------------
+// sasi_status_r -
+//-------------------------------------------------
+
+READ8_MEMBER( luxor_55_21056_device::sasi_status_r )
+{
+ /*
+
+ bit description
+
+ 0 RDY
+ 1 REQ
+ 2 I/O
+ 3 C/D
+ 4 MSG
+ 5 BSY
+ 6
+ 7
+
+ */
+
+ UINT8 data = 0;
+
+ data |= m_rdy ^ STAT_DIR;
+
+ data |= !m_sasi_req << 1;
+ data |= !m_sasi_io << 2;
+ data |= !m_sasi_cd << 3;
+ data |= !m_sasi_msg << 4;
+ data |= !m_sasi_bsy << 5;
+
+ return data ^ 0xff;
+}
+
+
+//-------------------------------------------------
+// stat_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( luxor_55_21056_device::stat_w )
+{
+ m_stat = data;
+
+ set_rdy(m_rdy);
+}
+
+
+//-------------------------------------------------
+// out_r -
+//-------------------------------------------------
+
+READ8_MEMBER( luxor_55_21056_device::out_r )
+{
+ UINT8 data = m_out;
+
+ if (STAT_DIR && m_rdy) set_rdy(!m_rdy);
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// inp_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( luxor_55_21056_device::inp_w )
+{
+ m_inp = data;
+
+ if (!STAT_DIR && !m_rdy) set_rdy(!m_rdy);
+}
+
+
+//-------------------------------------------------
+// sasi_data_r -
+//-------------------------------------------------
+
+READ8_MEMBER( luxor_55_21056_device::sasi_data_r )
+{
+ UINT8 data = m_sasi_data_in->read();
+
+ m_sasibus->write_ack(!m_sasi_req);
+
+ return data;
+}
+
+
+//-------------------------------------------------
+// sasi_data_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( luxor_55_21056_device::sasi_data_w )
+{
+ m_sasi_data = data;
+
+ if (!m_sasi_io)
+ {
+ m_sasi_data_out->write(m_sasi_data);
+ }
+
+ m_sasibus->write_ack(!m_sasi_req);
+}
+
+
+//-------------------------------------------------
+// rdy_reset_r -
+//-------------------------------------------------
+
+READ8_MEMBER( luxor_55_21056_device::rdy_reset_r )
+{
+ rdy_reset_w(space, offset, 0xff);
+
+ return 0xff;
+}
+
+
+//-------------------------------------------------
+// rdy_reset_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( luxor_55_21056_device::rdy_reset_w )
+{
+ set_rdy(0);
+}
+
+
+//-------------------------------------------------
+// sasi_sel_r -
+//-------------------------------------------------
+
+READ8_MEMBER( luxor_55_21056_device::sasi_sel_r )
+{
+ sasi_sel_w(space, offset, 0xff);
+
+ return 0xff;
+}
+
+
+//-------------------------------------------------
+// sasi_sel_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( luxor_55_21056_device::sasi_sel_w )
+{
+ m_sasibus->write_sel(!m_sasi_bsy);
+}
+
+
+//-------------------------------------------------
+// sasi_rst_r -
+//-------------------------------------------------
+
+READ8_MEMBER( luxor_55_21056_device::sasi_rst_r )
+{
+ sasi_rst_w(space, offset, 0xff);
+
+ return 0xff;
+}
+
+
+//-------------------------------------------------
+// sasi_rst_w -
+//-------------------------------------------------
+
+WRITE8_MEMBER( luxor_55_21056_device::sasi_rst_w )
+{
+ m_sasibus->write_rst(1);
+ m_sasibus->write_rst(0);
+}
+
+
+//-------------------------------------------------
+// set_rdy -
+//-------------------------------------------------
+
+void luxor_55_21056_device::set_rdy(int state)
+{
+ m_rdy = state;
+
+ m_dma->rdy_w(m_rdy ^ STAT_DIR);
+}