summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/genpc.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2012-08-21 10:41:19 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2012-08-21 10:41:19 +0000
commit7285b359d259b2ae0fdf85096571c386ec8c991a (patch)
treea027aff57f1a255f9ec6cfd3b68cabe4b6683998 /src/mess/machine/genpc.c
parent67c425e90757876a6716b7867df30c0149912e74 (diff)
Merge of MESS sources (no whatsnew)
Diffstat (limited to 'src/mess/machine/genpc.c')
-rw-r--r--src/mess/machine/genpc.c861
1 files changed, 861 insertions, 0 deletions
diff --git a/src/mess/machine/genpc.c b/src/mess/machine/genpc.c
new file mode 100644
index 00000000000..ec9f708f30a
--- /dev/null
+++ b/src/mess/machine/genpc.c
@@ -0,0 +1,861 @@
+/***************************************************************************
+
+ machine/genpc.c
+
+
+***************************************************************************/
+
+#include "emu.h"
+#include "includes/genpc.h"
+
+#include "machine/i8255.h"
+#include "machine/pic8259.h"
+#include "machine/pit8253.h"
+#include "sound/speaker.h"
+#include "machine/ram.h"
+#include "imagedev/cassette.h"
+
+#define VERBOSE_PIO 0 /* PIO (keyboard controller) */
+
+#define PIO_LOG(N,M,A) \
+ do { \
+ if(VERBOSE_PIO>=N) \
+ { \
+ if( M ) \
+ logerror("%11.6f: %-24s",machine().time().as_double(),(char*)M ); \
+ logerror A; \
+ } \
+ } while (0)
+
+
+/*************************************************************************
+ *
+ * PC DMA stuff
+ *
+ *************************************************************************/
+
+READ8_DEVICE_HANDLER(pc_page_r)
+{
+ return 0xFF;
+}
+
+
+WRITE8_DEVICE_HANDLER(pc_page_w)
+{
+ ibm5160_mb_device *board = downcast<ibm5160_mb_device *>(device);
+ switch(offset % 4)
+ {
+ case 1:
+ board->m_dma_offset[2] = data;
+ break;
+ case 2:
+ board->m_dma_offset[3] = data;
+ break;
+ case 3:
+ board->m_dma_offset[0] = board->m_dma_offset[1] = data;
+ break;
+ }
+}
+
+
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_dma_hrq_changed )
+{
+ device_set_input_line(m_maincpu, INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE);
+
+ /* Assert HLDA */
+ m_dma8237->hack_w(state);
+}
+
+
+READ8_MEMBER( ibm5160_mb_device::pc_dma_read_byte )
+{
+ address_space *spaceio = m_maincpu->space(AS_PROGRAM);
+ offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0x0F0000;
+ return spaceio->read_byte( page_offset + offset);
+}
+
+
+WRITE8_MEMBER( ibm5160_mb_device::pc_dma_write_byte )
+{
+ address_space *spaceio = m_maincpu->space(AS_PROGRAM);
+ offs_t page_offset = (((offs_t) m_dma_offset[m_dma_channel]) << 16) & 0x0F0000;
+
+ spaceio->write_byte( page_offset + offset, data);
+}
+
+
+READ8_MEMBER( ibm5160_mb_device::pc_dma8237_1_dack_r )
+{
+ return m_isabus->dack_r(1);
+}
+
+READ8_MEMBER( ibm5160_mb_device::pc_dma8237_2_dack_r )
+{
+ return m_isabus->dack_r(2);
+}
+
+
+READ8_MEMBER( ibm5160_mb_device::pc_dma8237_3_dack_r )
+{
+ return m_isabus->dack_r(3);
+}
+
+
+WRITE8_MEMBER( ibm5160_mb_device::pc_dma8237_1_dack_w )
+{
+ m_isabus->dack_w(1,data);
+}
+
+WRITE8_MEMBER( ibm5160_mb_device::pc_dma8237_2_dack_w )
+{
+ m_isabus->dack_w(2,data);
+}
+
+
+WRITE8_MEMBER( ibm5160_mb_device::pc_dma8237_3_dack_w )
+{
+ m_isabus->dack_w(3,data);
+}
+
+
+WRITE8_MEMBER( ibm5160_mb_device::pc_dma8237_0_dack_w )
+{
+ m_u73_q2 = 0;
+ m_dma8237->dreq0_w( m_u73_q2 );
+}
+
+
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_dma8237_out_eop )
+{
+ return m_isabus->eop_w(state == ASSERT_LINE ? 0 : 1 );
+}
+
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_dack0_w ) { if (!state) m_dma_channel = 0; }
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_dack1_w ) { if (!state) m_dma_channel = 1; }
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_dack2_w ) { if (!state) m_dma_channel = 2; }
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_dack3_w ) { if (!state) m_dma_channel = 3; }
+
+I8237_INTERFACE( pc_dma8237_config )
+{
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma_hrq_changed),
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_out_eop),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma_read_byte),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma_write_byte),
+
+ { DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_1_dack_r),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_2_dack_r),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_3_dack_r) },
+
+
+ { DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_0_dack_w),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_1_dack_w),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_2_dack_w),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dma8237_3_dack_w) },
+
+ // DACK's
+ { DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dack0_w),
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dack1_w),
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dack2_w),
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_dack3_w) }
+};
+
+
+/*************************************************************
+ *
+ * pic8259 configuration
+ *
+ *************************************************************/
+WRITE_LINE_MEMBER(ibm5160_mb_device::pc_cpu_line)
+{
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, state);
+}
+
+const struct pic8259_interface pc_pic8259_config =
+{
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_cpu_line),
+ DEVCB_LINE_VCC,
+ DEVCB_NULL
+};
+
+
+WRITE_LINE_MEMBER(ibm5160_mb_device::pc_speaker_set_spkrdata)
+{
+ m_pc_spkrdata = state ? 1 : 0;
+ speaker_level_w( m_speaker, m_pc_spkrdata & m_pc_input );
+}
+
+
+/*************************************************************
+ *
+ * pit8253 configuration
+ *
+ *************************************************************/
+
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_pit8253_out1_changed )
+{
+ /* Trigger DMA channel #0 */
+ if ( m_out1 == 0 && state == 1 && m_u73_q2 == 0 )
+ {
+ m_u73_q2 = 1;
+ m_dma8237->dreq0_w( m_u73_q2 );
+ }
+ m_out1 = state;
+}
+
+
+WRITE_LINE_MEMBER( ibm5160_mb_device::pc_pit8253_out2_changed )
+{
+ m_pc_input = state ? 1 : 0;
+ speaker_level_w( m_speaker, m_pc_spkrdata & m_pc_input );
+}
+
+
+const struct pit8253_config pc_pit8253_config =
+{
+ {
+ {
+ XTAL_14_31818MHz/12, /* heartbeat IRQ */
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE("pic8259", pic8259_ir0_w)
+ }, {
+ XTAL_14_31818MHz/12, /* dram refresh */
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_pit8253_out1_changed)
+ }, {
+ XTAL_14_31818MHz/12, /* pio port c pin 4, and speaker polling enough */
+ DEVCB_NULL,
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_pit8253_out2_changed)
+ }
+ }
+};
+
+/**********************************************************
+ *
+ * PPI8255 interface
+ *
+ *
+ * PORT A (input)
+ *
+ * Directly attached to shift register which stores data
+ * received from the keyboard.
+ *
+ * PORT B (output)
+ * 0 - PB0 - TIM2GATESPK - Enable/disable counting on timer 2 of the 8253
+ * 1 - PB1 - SPKRDATA - Speaker data
+ * 2 - PB2 - - Enable receiving data from the keyboard when keyboard is not locked.
+ * 3 - PB3 - - Dipsswitch set selector
+ * 4 - PB4 - ENBRAMPCK - Enable ram parity check
+ * 5 - PB5 - ENABLEI/OCK - Enable expansion I/O check
+ * 6 - PB6 - - Connected to keyboard clock signal
+ * 0 = ignore keyboard signals
+ * 1 = accept keyboard signals
+ * 7 - PB7 - - Clear/disable shift register and IRQ1 line
+ * 0 = normal operation
+ * 1 = clear and disable shift register and clear IRQ1 flip flop
+ *
+ * PORT C
+ * 0 - PC0 - - Dipswitch 0/4 SW1
+ * 1 - PC1 - - Dipswitch 1/5 SW1
+ * 2 - PC2 - - Dipswitch 2/6 SW1
+ * 3 - PC3 - - Dipswitch 3/7 SW1
+ * 4 - PC4 - SPK - Speaker/cassette data
+ * 5 - PC5 - I/OCHCK - Expansion I/O check result
+ * 6 - PC6 - T/C2OUT - Output of 8253 timer 2
+ * 7 - PC7 - PCK - Parity check result
+ *
+ * IBM5150 SW1:
+ * 0 - OFF - One or more floppy drives
+ * ON - Diskless operation
+ * 1 - OFF - 8087 present
+ * ON - No 8087 present
+ * 2+3 - Used to determine on board memory configuration
+ * OFF OFF - 64KB
+ * ON OFF - 48KB
+ * OFF ON - 32KB
+ * ON ON - 16KB
+ * 4+5 - Used to select display
+ * OFF OFF - Monochrome
+ * ON OFF - CGA, 80 column
+ * OFF ON - CGA, 40 column
+ * ON ON - EGA/VGA display
+ * 6+7 - Used to select number of disk drives
+ * OFF OFF - four disk drives
+ * ON OFF - three disk drives
+ * OFF ON - two disk drives
+ * ON ON - one disk drive
+ *
+ **********************************************************/
+WRITE_LINE_MEMBER( ibm5160_mb_device::keyboard_clock_w )
+{
+ if ( m_ppi_clock_signal != state )
+ {
+ if ( m_ppi_keyb_clock && m_ppi_shift_enable )
+ {
+ m_ppi_clock_signal = state;
+ if ( ! m_ppi_keyboard_clear )
+ {
+ /* Data is clocked in on a high->low transition */
+ if ( ! state )
+ {
+ UINT8 trigger_irq = m_ppi_shift_register & 0x01;
+
+ m_ppi_shift_register = ( m_ppi_shift_register >> 1 ) | ( m_ppi_data_signal << 7 );
+ if ( trigger_irq )
+ {
+ pic8259_ir1_w(m_pic8259, 1);
+ m_ppi_shift_enable = 0;
+ m_ppi_clock_signal = 0;
+ m_pc_kbdc->clock_write_from_mb(m_ppi_clock_signal);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+WRITE_LINE_MEMBER( ibm5160_mb_device::keyboard_data_w )
+{
+ m_ppi_data_signal = state;
+}
+
+READ8_MEMBER (ibm5160_mb_device::pc_ppi_porta_r)
+{
+ int data = 0xFF;
+ /* KB port A */
+ if (m_ppi_keyboard_clear)
+ {
+ /* 0 0 - no floppy drives
+ * 1 Not used
+ * 2-3 The number of memory banks on the system board
+ * 4-5 Display mode
+ * 11 = monochrome
+ * 10 - color 80x25
+ * 01 - color 40x25
+ * 6-7 The number of floppy disk drives
+ */
+ data = ioport("DSW0")->read();
+ }
+ else
+ {
+ data = m_ppi_shift_register;
+ }
+ PIO_LOG(1,"PIO_A_r",("$%02x\n", data));
+ return data;
+}
+
+
+READ8_MEMBER ( ibm5160_mb_device::pc_ppi_portc_r )
+{
+ int timer2_output = pit8253_get_output( m_pit8253, 2 );
+ int data=0xff;
+
+ data&=~0x80; // no parity error
+ data&=~0x40; // no error on expansion board
+ /* KB port C: equipment flags */
+ if (m_ppi_portc_switch_high)
+ {
+ /* read hi nibble of S2 */
+ data = (data & 0xf0) | ((ioport("DSW0")->read() >> 4) & 0x0f);
+ PIO_LOG(1,"PIO_C_r (hi)",("$%02x\n", data));
+ }
+ else
+ {
+ /* read lo nibble of S2 */
+ data = (data & 0xf0) | (ioport("DSW0")->read() & 0x0f);
+ PIO_LOG(1,"PIO_C_r (lo)",("$%02x\n", data));
+ }
+
+ if ( m_ppi_portb & 0x01 )
+ {
+ data = ( data & ~0x10 ) | ( timer2_output ? 0x10 : 0x00 );
+ }
+ data = ( data & ~0x20 ) | ( timer2_output ? 0x20 : 0x00 );
+
+ return data;
+}
+
+
+WRITE8_MEMBER( ibm5160_mb_device::pc_ppi_portb_w )
+{
+ /* PPI controller port B*/
+ m_ppi_portb = data;
+ m_ppi_portc_switch_high = data & 0x08;
+ m_ppi_keyboard_clear = data & 0x80;
+ m_ppi_keyb_clock = data & 0x40;
+ pit8253_gate2_w(m_pit8253, BIT(data, 0));
+ pc_speaker_set_spkrdata( data & 0x02 );
+
+ m_ppi_clock_signal = ( m_ppi_keyb_clock ) ? 1 : 0;
+ m_pc_kbdc->clock_write_from_mb(m_ppi_clock_signal);
+
+ /* If PB7 is set clear the shift register and reset the IRQ line */
+ if ( m_ppi_keyboard_clear )
+ {
+ pic8259_ir1_w(m_pic8259, 0);
+ m_ppi_shift_register = 0;
+ m_ppi_shift_enable = 1;
+ }
+}
+
+
+I8255A_INTERFACE( pc_ppi8255_interface )
+{
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_ppi_porta_r),
+ DEVCB_NULL,
+ DEVCB_NULL,
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_ppi_portb_w),
+ DEVCB_DEVICE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, pc_ppi_portc_r),
+ DEVCB_NULL
+};
+
+static const isa8bus_interface isabus_intf =
+{
+ // interrupts
+ DEVCB_DEVICE_LINE("pic8259", pic8259_ir2_w),
+ DEVCB_DEVICE_LINE("pic8259", pic8259_ir3_w),
+ DEVCB_DEVICE_LINE("pic8259", pic8259_ir4_w),
+ DEVCB_DEVICE_LINE("pic8259", pic8259_ir5_w),
+ DEVCB_DEVICE_LINE("pic8259", pic8259_ir6_w),
+ DEVCB_DEVICE_LINE("pic8259", pic8259_ir7_w),
+
+ // dma request
+ DEVCB_DEVICE_LINE_MEMBER("dma8237", am9517a_device, dreq1_w),
+ DEVCB_DEVICE_LINE_MEMBER("dma8237", am9517a_device, dreq2_w),
+ DEVCB_DEVICE_LINE_MEMBER("dma8237", am9517a_device, dreq3_w)
+};
+
+static const pc_kbdc_interface pc_kbdc_intf =
+{
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, keyboard_clock_w),
+ DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, ibm5160_mb_device, keyboard_data_w)
+};
+
+/**********************************************************
+ *
+ * NMI handling
+ *
+ **********************************************************/
+
+static WRITE8_DEVICE_HANDLER( nmi_enable_w )
+{
+ ibm5160_mb_device *board = downcast<ibm5160_mb_device *>(device);
+
+ board->m_nmi_enabled = BIT(data,7);
+ board->m_isabus->set_nmi_state(board->m_nmi_enabled);
+
+}
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type IBM5160_MOTHERBOARD = &device_creator<ibm5160_mb_device>;
+
+//**************************************************************************
+// DEVICE CONFIGURATION
+//**************************************************************************
+
+static MACHINE_CONFIG_FRAGMENT( ibm5160_mb_config )
+ MCFG_PIT8253_ADD( "pit8253", pc_pit8253_config )
+
+ MCFG_I8237_ADD( "dma8237", XTAL_14_31818MHz/3, pc_dma8237_config )
+
+ MCFG_PIC8259_ADD( "pic8259", pc_pic8259_config )
+
+ MCFG_I8255A_ADD( "ppi8255", pc_ppi8255_interface )
+
+ MCFG_ISA8_BUS_ADD("isa", "maincpu", isabus_intf)
+
+ MCFG_PC_KBDC_ADD("pc_kbdc", pc_kbdc_intf)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD(SPEAKER_TAG, SPEAKER_SOUND, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor ibm5160_mb_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( ibm5160_mb_config );
+}
+
+
+static INPUT_PORTS_START( ibm5160_mb )
+ PORT_START("DSW0") /* IN1 */
+ PORT_DIPNAME( 0xc0, 0x40, "Number of floppy drives")
+ PORT_DIPSETTING( 0x00, "1" )
+ PORT_DIPSETTING( 0x40, "2" )
+ PORT_DIPSETTING( 0x80, "3" )
+ PORT_DIPSETTING( 0xc0, "4" )
+ PORT_DIPNAME( 0x30, 0x30, "Graphics adapter")
+ PORT_DIPSETTING( 0x00, "EGA/VGA" )
+ PORT_DIPSETTING( 0x10, "Color 40x25" )
+ PORT_DIPSETTING( 0x20, "Color 80x25" )
+ PORT_DIPSETTING( 0x30, "Monochrome" )
+ PORT_DIPNAME( 0x0c, 0x0c, "RAM banks")
+ PORT_DIPSETTING( 0x00, "1 - 16/ 64/256K" )
+ PORT_DIPSETTING( 0x04, "2 - 32/128/512K" )
+ PORT_DIPSETTING( 0x08, "3 - 48/192/576K" )
+ PORT_DIPSETTING( 0x0c, "4 - 64/256/640K" )
+ PORT_DIPNAME( 0x02, 0x00, "8087 installed")
+ PORT_DIPSETTING( 0x00, DEF_STR(No) )
+ PORT_DIPSETTING( 0x02, DEF_STR(Yes) )
+ PORT_DIPNAME( 0x01, 0x01, "Any floppy drive installed")
+ PORT_DIPSETTING( 0x00, DEF_STR(No) )
+ PORT_DIPSETTING( 0x01, DEF_STR(Yes) )
+INPUT_PORTS_END
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor ibm5160_mb_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( ibm5160_mb );
+}
+
+
+void ibm5160_mb_device::static_set_cputag(device_t &device, const char *tag)
+{
+ ibm5160_mb_device &board = downcast<ibm5160_mb_device &>(device);
+ board.m_cputag = tag;
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// ibm5160_mb_device - constructor
+//-------------------------------------------------
+
+ibm5160_mb_device::ibm5160_mb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, IBM5160_MOTHERBOARD, "IBM5160_MOTHERBOARD", tag, owner, clock),
+ m_maincpu(*owner, "maincpu"),
+ m_pic8259(*this, "pic8259"),
+ m_dma8237(*this, "dma8237"),
+ m_pit8253(*this, "pit8253"),
+ m_ppi8255(*this, "ppi8255"),
+ m_speaker(*this, SPEAKER_TAG),
+ m_isabus(*this, "isa"),
+ m_pc_kbdc(*this, "pc_kbdc")
+{
+}
+
+void ibm5160_mb_device::install_device(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_device_func rhandler, const char* rhandler_name, write8_device_func whandler, const char *whandler_name)
+{
+ int buswidth = machine().firstcpu->memory().space_config(AS_IO)->m_databus_width;
+ switch(buswidth)
+ {
+ case 8:
+ m_maincpu->memory().space(AS_IO)->install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name, 0);
+ break;
+ case 16:
+ m_maincpu->memory().space(AS_IO)->install_legacy_readwrite_handler(*dev, start, end, mask, mirror, rhandler, rhandler_name, whandler, whandler_name,0xffff);
+ break;
+ default:
+ fatalerror("IBM5160_MOTHERBOARD: Bus width %d not supported", buswidth);
+ break;
+ }
+}
+
+void ibm5160_mb_device::install_device_write(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, write8_device_func whandler, const char *whandler_name)
+{
+ int buswidth = machine().firstcpu->memory().space_config(AS_IO)->m_databus_width;
+ switch(buswidth)
+ {
+ case 8:
+ m_maincpu->memory().space(AS_IO)->install_legacy_write_handler(*dev, start, end, mask, mirror, whandler, whandler_name,0);
+ break;
+ case 16:
+ m_maincpu->memory().space(AS_IO)->install_legacy_write_handler(*dev, start, end, mask, mirror, whandler, whandler_name, 0xffff);
+ break;
+ default:
+ fatalerror("IBM5160_MOTHERBOARD: Bus width %d not supported", buswidth);
+ break;
+ }
+}
+
+void ibm5160_mb_device::install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_delegate rhandler, write8_delegate whandler)
+{
+ int buswidth = m_maincpu->memory().space_config(AS_IO)->m_databus_width;
+ switch(buswidth)
+ {
+ case 8:
+ m_maincpu->memory().space(AS_IO)->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0);
+ break;
+ case 16:
+ m_maincpu->memory().space(AS_IO)->install_readwrite_handler(start, end, mask, mirror, rhandler, whandler, 0xffff);
+ break;
+ default:
+ fatalerror("IBM5160_MOTHERBOARD: Bus width %d not supported", buswidth);
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void ibm5160_mb_device::device_start()
+{
+ install_device(0x0000, 0x000f, 0, 0, read8_delegate(FUNC(am9517a_device::read), (am9517a_device*)m_dma8237), write8_delegate(FUNC(am9517a_device::write), (am9517a_device*)m_dma8237) );
+ install_device(m_pic8259, 0x0020, 0x0021, 0, 0, FUNC(pic8259_r), FUNC(pic8259_w) );
+ install_device(m_pit8253, 0x0040, 0x0043, 0, 0, FUNC(pit8253_r), FUNC(pit8253_w) );
+
+ // install_device(m_ppi8255, 0x0060, 0x0063, 0, 0, FUNC(i8255a_r), FUNC(i8255a_w) );
+ int buswidth = machine().firstcpu->memory().space_config(AS_IO)->m_databus_width;
+ switch(buswidth)
+ {
+ case 8:
+ m_maincpu->memory().space(AS_IO)->install_readwrite_handler(0x0060, 0x0063, 0, 0, read8_delegate(FUNC(i8255_device::read), (i8255_device*)m_ppi8255), write8_delegate(FUNC(i8255_device::write), (i8255_device*)m_ppi8255), 0);
+ break;
+ case 16:
+ m_maincpu->memory().space(AS_IO)->install_readwrite_handler(0x0060, 0x0063, 0, 0, read8_delegate(FUNC(i8255_device::read), (i8255_device*)m_ppi8255), write8_delegate(FUNC(i8255_device::write), (i8255_device*)m_ppi8255), 0xffff);
+ break;
+ default:
+ fatalerror("IBM5160_MOTHERBOARD: Bus width %d not supported", buswidth);
+ break;
+ }
+
+ install_device(this, 0x0080, 0x0087, 0, 0, FUNC(pc_page_r), FUNC(pc_page_w) );
+ install_device_write(this, 0x00a0, 0x00a1, 0, 0, FUNC(nmi_enable_w));
+ /* MESS managed RAM */
+ if ( machine().device<ram_device>(RAM_TAG)->pointer() )
+ membank( "bank10" )->set_base( machine().device<ram_device>(RAM_TAG)->pointer() );
+}
+
+IRQ_CALLBACK(ibm5160_mb_device::pc_irq_callback)
+{
+ device_t *pic = device->machine().device("mb:pic8259");
+ return pic8259_acknowledge( pic );
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void ibm5160_mb_device::device_reset()
+{
+ device_set_irq_callback(m_maincpu, pc_irq_callback);
+
+ m_u73_q2 = 0;
+ m_out1 = 2; // initial state of pit output is undefined
+ m_pc_spkrdata = 0;
+ m_pc_input = 0;
+ m_dma_channel = 0;
+ memset(m_dma_offset,0,sizeof(m_dma_offset));
+ m_ppi_portc_switch_high = 0;
+ m_ppi_speaker = 0;
+ m_ppi_keyboard_clear = 0;
+ m_ppi_keyb_clock = 0;
+ m_ppi_portb = 0;
+ m_ppi_clock_signal = 0;
+ m_ppi_data_signal = 0;
+ m_ppi_shift_register = 0;
+ m_ppi_shift_enable = 0;
+ m_nmi_enabled = 0;
+ speaker_level_w( m_speaker, 0 );
+}
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type IBM5150_MOTHERBOARD = &device_creator<ibm5150_mb_device>;
+
+//**************************************************************************
+// DEVICE CONFIGURATION
+//**************************************************************************
+static const cassette_interface ibm5150_cassette_interface =
+{
+ cassette_default_formats,
+ NULL,
+ (cassette_state)(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED),
+ NULL,
+ NULL
+};
+
+static MACHINE_CONFIG_FRAGMENT( ibm5150_mb_config )
+ MCFG_FRAGMENT_ADD(ibm5160_mb_config)
+
+ MCFG_CASSETTE_ADD( CASSETTE_TAG, ibm5150_cassette_interface )
+MACHINE_CONFIG_END
+
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+machine_config_constructor ibm5150_mb_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( ibm5150_mb_config );
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// ibm5150_mb_device - constructor
+//-------------------------------------------------
+
+ibm5150_mb_device::ibm5150_mb_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : ibm5160_mb_device(mconfig, tag, owner, clock),
+ m_cassette(*this, CASSETTE_TAG)
+{
+}
+
+void ibm5150_mb_device::device_start()
+{
+ ibm5160_mb_device::device_start();
+}
+void ibm5150_mb_device::device_reset()
+{
+ ibm5160_mb_device::device_reset();
+}
+
+READ8_MEMBER (ibm5150_mb_device::pc_ppi_porta_r)
+{
+ int data = 0xFF;
+ /* KB port A */
+ if (m_ppi_keyboard_clear)
+ {
+ /* 0 0 - no floppy drives
+ * 1 Not used
+ * 2-3 The number of memory banks on the system board
+ * 4-5 Display mode
+ * 11 = monochrome
+ * 10 - color 80x25
+ * 01 - color 40x25
+ * 6-7 The number of floppy disk drives
+ */
+ data = ioport("DSW0")->read() & 0xF3;
+ switch ( machine().device<ram_device>(RAM_TAG)->size() )
+ {
+ case 16 * 1024:
+ data |= 0x00;
+ break;
+ case 32 * 1024: /* Need to verify if this is correct */
+ data |= 0x04;
+ break;
+ case 48 * 1024: /* Need to verify if this is correct */
+ data |= 0x08;
+ break;
+ default:
+ data |= 0x0C;
+ break;
+ }
+ }
+ else
+ {
+ data = m_ppi_shift_register;
+ }
+ PIO_LOG(1,"PIO_A_r",("$%02x\n", data));
+ return data;
+}
+
+
+READ8_MEMBER ( ibm5150_mb_device::pc_ppi_portc_r )
+{
+ int timer2_output = pit8253_get_output( m_pit8253, 2 );
+ int data=0xff;
+
+ data&=~0x80; // no parity error
+ data&=~0x40; // no error on expansion board
+ /* KB port C: equipment flags */
+ if (m_ppi_portc_switch_high)
+ {
+ /* read hi nibble of SW2 */
+ data = data & 0xf0;
+
+ switch ( machine().device<ram_device>(RAM_TAG)->size() - 64 * 1024 )
+ {
+ case 64 * 1024: data |= 0x00; break;
+ case 128 * 1024: data |= 0x02; break;
+ case 192 * 1024: data |= 0x04; break;
+ case 256 * 1024: data |= 0x06; break;
+ case 320 * 1024: data |= 0x08; break;
+ case 384 * 1024: data |= 0x0A; break;
+ case 448 * 1024: data |= 0x0C; break;
+ case 512 * 1024: data |= 0x0E; break;
+ case 576 * 1024: data |= 0x01; break;
+ case 640 * 1024: data |= 0x03; break;
+ case 704 * 1024: data |= 0x05; break;
+ case 768 * 1024: data |= 0x07; break;
+ case 832 * 1024: data |= 0x09; break;
+ case 896 * 1024: data |= 0x0B; break;
+ case 960 * 1024: data |= 0x0D; break;
+ }
+ if ( machine().device<ram_device>(RAM_TAG)->size() > 960 * 1024 )
+ data |= 0x0D;
+
+ PIO_LOG(1,"PIO_C_r (hi)",("$%02x\n", data));
+ }
+ else
+ {
+ /* read lo nibble of S2 */
+ data = (data & 0xf0) | (ioport("DSW0")->read() & 0x0f);
+ PIO_LOG(1,"PIO_C_r (lo)",("$%02x\n", data));
+ }
+
+ if ( ! ( m_ppi_portb & 0x08 ) )
+ {
+ double tap_val = m_cassette->input();
+
+ if ( tap_val < 0 )
+ {
+ data &= ~0x10;
+ }
+ else
+ {
+ data |= 0x10;
+ }
+ }
+ else
+ {
+ if ( m_ppi_portb & 0x01 )
+ {
+ data = ( data & ~0x10 ) | ( timer2_output ? 0x10 : 0x00 );
+ }
+ }
+ data = ( data & ~0x20 ) | ( timer2_output ? 0x20 : 0x00 );
+
+ return data;
+}
+
+
+WRITE8_MEMBER( ibm5150_mb_device::pc_ppi_portb_w )
+{
+ /* KB controller port B */
+ m_ppi_portb = data;
+ m_ppi_portc_switch_high = data & 0x08;
+ m_ppi_keyboard_clear = data & 0x80;
+ m_ppi_keyb_clock = data & 0x40;
+ pit8253_gate2_w(m_pit8253, BIT(data, 0));
+ pc_speaker_set_spkrdata( data & 0x02 );
+
+ m_cassette->change_state(( data & 0x08 ) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR);
+
+ m_ppi_clock_signal = ( m_ppi_keyb_clock ) ? 1 : 0;
+ m_pc_kbdc->clock_write_from_mb(m_ppi_clock_signal);
+
+
+ /* If PB7 is set clear the shift register and reset the IRQ line */
+ if ( m_ppi_keyboard_clear )
+ {
+ pic8259_ir1_w(m_pic8259, 0);
+ m_ppi_shift_register = 0;
+ m_ppi_shift_enable = 1;
+ }
+}