From 87b633a97c54f14bdd12616b85f9bfa14431b53d Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 30 Oct 2015 02:58:34 +1100 Subject: [PATCH] osborne1: add 6850ACIA serial port (untested), use configured banking --- src/mame/drivers/osborne1.c | 23 +++- src/mame/includes/osborne1.h | 116 ++++++++++++-------- src/mame/machine/osborne1.c | 202 +++++++++++++++++++++-------------- 3 files changed, 211 insertions(+), 130 deletions(-) diff --git a/src/mame/drivers/osborne1.c b/src/mame/drivers/osborne1.c index 7b64b3ba7e0..ab5786f14cf 100644 --- a/src/mame/drivers/osborne1.c +++ b/src/mame/drivers/osborne1.c @@ -47,6 +47,7 @@ TODO: ***************************************************************************/ #include "includes/osborne1.h" +#include "bus/rs232/rs232.h" #define MAIN_CLOCK 15974400 @@ -167,6 +168,11 @@ static INPUT_PORTS_START( osborne1 ) PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("CNF") + PORT_CONFNAME(0x06, 0x00, "Serial Speed") + PORT_CONFSETTING(0x00, "300/1200") + PORT_CONFSETTING(0x02, "600/1200") + PORT_CONFSETTING(0x04, "1200/4800") + PORT_CONFSETTING(0x06, "2400/9600") PORT_CONFNAME(0x01, 0x00, "Video Output") PORT_CONFSETTING(0x00, "Standard") PORT_CONFSETTING(0x01, "SCREEN-PAC") @@ -235,12 +241,23 @@ static MACHINE_CONFIG_START( osborne1, osborne1_state ) MCFG_PIA_CB2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ren_w)) MCFG_PIA_IRQA_HANDLER(WRITELINE(osborne1_state, ieee_pia_irq_a_func)) - MCFG_DEVICE_ADD( "pia_1", PIA6821, 0) + MCFG_DEVICE_ADD("pia_1", PIA6821, 0) MCFG_PIA_WRITEPA_HANDLER(WRITE8(osborne1_state, video_pia_port_a_w)) MCFG_PIA_WRITEPB_HANDLER(WRITE8(osborne1_state, video_pia_port_b_w)) MCFG_PIA_CB2_HANDLER(WRITELINE(osborne1_state, video_pia_out_cb2_dummy)) MCFG_PIA_IRQA_HANDLER(WRITELINE(osborne1_state, video_pia_irq_a_func)) + MCFG_DEVICE_ADD("acia", ACIA6850, 0) + MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(osborne1_state, serial_acia_irq_func)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, NULL) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_dcd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) + MCFG_RS232_RI_HANDLER(DEVWRITELINE("pia_1", pia6821_device, ca2_w)) + MCFG_DEVICE_ADD("mb8877", MB8877, MAIN_CLOCK/16) MCFG_WD_FDC_FORCE_READY MCFG_FLOPPY_DRIVE_ADD("mb8877:0", osborne1_floppies, "525ssdd", floppy_image_device::default_floppy_formats) @@ -250,9 +267,9 @@ static MACHINE_CONFIG_START( osborne1, osborne1_state ) MCFG_IEEE488_SRQ_CALLBACK(DEVWRITELINE("pia_0", pia6821_device, ca2_w)) MCFG_SOFTWARE_LIST_ADD("flop_list","osborne1") - /* internal ram */ + // internal ram MCFG_RAM_ADD(RAM_TAG) - MCFG_RAM_DEFAULT_SIZE("68K") /* 64KB Main RAM and 4Kbit video attribute RAM */ + MCFG_RAM_DEFAULT_SIZE("68K") // 64bB main RAM and 4kbit video attribute RAM MACHINE_CONFIG_END diff --git a/src/mame/includes/osborne1.h b/src/mame/includes/osborne1.h index 1e69d0aded4..ef94abc0893 100644 --- a/src/mame/includes/osborne1.h +++ b/src/mame/includes/osborne1.h @@ -24,20 +24,23 @@ public: enum { TIMER_VIDEO, + TIMER_ACIA_RXC_TXC, TIMER_SETUP }; - osborne1_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), + osborne1_state(const machine_config &mconfig, device_type type, const char *tag) : + driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_pia0(*this, "pia_0"), m_pia1(*this, "pia_1"), + m_acia(*this, "acia"), m_fdc(*this, "mb8877"), m_beep(*this, "beeper"), m_ram(*this, RAM_TAG), m_ieee(*this, IEEE488_TAG), m_floppy0(*this, "mb8877:0:525ssdd"), m_floppy1(*this, "mb8877:1:525ssdd"), + m_video_timer(NULL), m_keyb_row0(*this, "ROW0"), m_keyb_row1(*this, "ROW1"), m_keyb_row2(*this, "ROW2"), @@ -48,26 +51,13 @@ public: m_keyb_row7(*this, "ROW7"), m_btn_reset(*this, "RESET"), m_cnf(*this, "CNF"), + m_region_maincpu(*this, "maincpu"), m_bank_0xxx(*this, "bank_0xxx"), m_bank_1xxx(*this, "bank_1xxx"), m_bank_fxxx(*this, "bank_fxxx"), - m_region_maincpu(*this, "maincpu") { } + m_acia_rxc_txc_timer(NULL) + { } - virtual void video_start(); - - UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - - bitmap_ind16 m_bitmap; - - required_device m_maincpu; - required_device m_pia0; - required_device m_pia1; - required_device m_fdc; - required_device m_beep; - required_device m_ram; - required_device m_ieee; - required_device m_floppy0; - required_device m_floppy1; DECLARE_WRITE8_MEMBER(bank_0xxx_w); DECLARE_WRITE8_MEMBER(bank_1xxx_w); @@ -87,8 +77,30 @@ public: DECLARE_WRITE_LINE_MEMBER(video_pia_out_cb2_dummy); DECLARE_WRITE_LINE_MEMBER(video_pia_irq_a_func); + DECLARE_WRITE_LINE_MEMBER(serial_acia_irq_func); + + DECLARE_DRIVER_INIT(osborne1); + virtual void machine_reset(); + virtual void video_start(); + UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + TIMER_CALLBACK_MEMBER(video_callback); + TIMER_CALLBACK_MEMBER(setup_callback); + + bitmap_ind16 m_bitmap; + + required_device m_maincpu; + required_device m_pia0; + required_device m_pia1; + required_device m_acia; + required_device m_fdc; + required_device m_beep; + required_device m_ram; + required_device m_ieee; + required_device m_floppy0; + required_device m_floppy1; + /* video related */ - UINT8 m_screen_pac; UINT8 m_resolution; UINT8 m_hc_left; UINT8 m_new_start_x; @@ -96,41 +108,51 @@ public: emu_timer *m_video_timer; UINT8 *m_p_chargen; bool m_beep_state; - DECLARE_DRIVER_INIT(osborne1); - virtual void machine_reset(); - TIMER_CALLBACK_MEMBER(osborne1_video_callback); - TIMER_CALLBACK_MEMBER(setup_osborne1); protected: - required_ioport m_keyb_row0; - required_ioport m_keyb_row1; - required_ioport m_keyb_row2; - required_ioport m_keyb_row3; - required_ioport m_keyb_row4; - required_ioport m_keyb_row5; - required_ioport m_keyb_row6; - required_ioport m_keyb_row7; - required_ioport m_btn_reset; - - required_ioport m_cnf; - - required_memory_bank m_bank_0xxx; - required_memory_bank m_bank_1xxx; - required_memory_bank m_bank_fxxx; - - required_memory_region m_region_maincpu; - - // bank switch control bits - UINT8 m_ub4a_q; - UINT8 m_ub6a_q; - UINT8 m_rom_mode; - UINT8 m_bit_9; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); bool set_rom_mode(UINT8 value); bool set_bit_9(UINT8 value); void update_irq(); + void update_acia_rxc_txc(); - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + // user inputs + required_ioport m_keyb_row0; + required_ioport m_keyb_row1; + required_ioport m_keyb_row2; + required_ioport m_keyb_row3; + required_ioport m_keyb_row4; + required_ioport m_keyb_row5; + required_ioport m_keyb_row6; + required_ioport m_keyb_row7; + required_ioport m_btn_reset; + + // fake inputs for hardware configuration and things that need rewiring + required_ioport m_cnf; + + // pieces of memory + required_memory_region m_region_maincpu; + required_memory_bank m_bank_0xxx; + required_memory_bank m_bank_1xxx; + required_memory_bank m_bank_fxxx; + + // configuration (reloaded on reset) + UINT8 m_screen_pac; + UINT8 m_acia_rxc_txc_div; + UINT8 m_acia_rxc_txc_p_low; + UINT8 m_acia_rxc_txc_p_high; + + // bank switch control bits + UINT8 m_ub4a_q; + UINT8 m_ub6a_q; + UINT8 m_rom_mode; + UINT8 m_bit_9; + + // serial state + int m_acia_irq_state; + int m_acia_rxc_txc_state; + emu_timer *m_acia_rxc_txc_timer; }; #endif /* OSBORNE1_H_ */ diff --git a/src/mame/machine/osborne1.c b/src/mame/machine/osborne1.c index f9fc4b2f7fb..fec58191061 100644 --- a/src/mame/machine/osborne1.c +++ b/src/mame/machine/osborne1.c @@ -55,6 +55,8 @@ READ8_MEMBER( osborne1_state::bank_2xxx_3xxx_r ) data = m_pia0->read(space, offset & 0x03); break; case 0xA00: /* Serial */ + if (offset & 0x01) data = m_acia->data_r(space, 0); + else data = m_acia->status_r(space, 0); break; case 0xC00: /* Video PIA */ data = m_pia1->read(space, offset & 0x03); @@ -77,7 +79,10 @@ WRITE8_MEMBER( osborne1_state::bank_2xxx_3xxx_w ) if ((offset & 0x900) == 0x900) // IEEE488 PIA m_pia0->write(space, offset & 0x03, data); if ((offset & 0xA00) == 0xA00) // Serial - /* not implemented */; + { + if (offset & 0x01) m_acia->data_w(space, 0, data); + else m_acia->control_w(space, 0, data); + } if ((offset & 0xC00) == 0x400) // SCREEN-PAC { m_resolution = data & 0x01; @@ -195,10 +200,6 @@ WRITE_LINE_MEMBER( osborne1_state::ieee_pia_irq_a_func ) } -WRITE_LINE_MEMBER( osborne1_state::video_pia_out_cb2_dummy ) -{ -} - WRITE8_MEMBER( osborne1_state::video_pia_port_a_w ) { m_fdc->dden_w(BIT(data, 0)); @@ -235,42 +236,100 @@ WRITE8_MEMBER( osborne1_state::video_pia_port_b_w ) //logerror("Video pia port b write: %02X\n", data ); } +WRITE_LINE_MEMBER( osborne1_state::video_pia_out_cb2_dummy ) +{ +} + WRITE_LINE_MEMBER( osborne1_state::video_pia_irq_a_func ) { update_irq(); } -//static const struct aica6850_interface osborne1_6850_config = -//{ -// 10, /* tx_clock */ -// 10, /* rx_clock */ -// NULL, /* rx_pin */ -// NULL, /* tx_pin */ -// NULL, /* cts_pin */ -// NULL, /* rts_pin */ -// NULL, /* dcd_pin */ -// NULL /* int_callback */ -//}; - - -void osborne1_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +WRITE_LINE_MEMBER( osborne1_state::serial_acia_irq_func ) { - switch (id) - { - case TIMER_VIDEO: - osborne1_video_callback(ptr, param); - break; - case TIMER_SETUP: - setup_osborne1(ptr, param); - break; - default: - assert_always(FALSE, "Unknown id in osborne1_state::device_timer"); - } + m_acia_irq_state = state; + update_irq(); } -TIMER_CALLBACK_MEMBER(osborne1_state::osborne1_video_callback) +DRIVER_INIT_MEMBER( osborne1_state, osborne1 ) +{ + m_bank_0xxx->configure_entries(0, 1, m_ram->pointer(), 0); + m_bank_0xxx->configure_entries(1, 1, m_region_maincpu->base(), 0); + m_bank_1xxx->configure_entries(0, 1, m_ram->pointer() + 0x1000, 0); + m_bank_1xxx->configure_entries(1, 1, m_region_maincpu->base(), 0); + m_bank_fxxx->configure_entries(0, 1, m_ram->pointer() + 0xF000, 0); + m_bank_fxxx->configure_entries(1, 1, m_ram->pointer() + 0x10000, 0); + + m_video_timer = timer_alloc(TIMER_VIDEO); + m_video_timer->adjust(machine().first_screen()->time_until_pos(1, 0)); + + m_acia_rxc_txc_timer = timer_alloc(TIMER_ACIA_RXC_TXC); + + timer_set(attotime::zero, TIMER_SETUP); +} + +void osborne1_state::machine_reset() +{ + // Refresh configuration + m_screen_pac = 0 != (m_cnf->read() & 0x01); + switch (m_cnf->read() & 0x06) + { + case 0x00: + m_acia_rxc_txc_div = 16; + m_acia_rxc_txc_p_low = 23; + m_acia_rxc_txc_p_high = 29; + break; + case 0x02: + m_acia_rxc_txc_div = 16; + m_acia_rxc_txc_p_low = 9; + m_acia_rxc_txc_p_high = 15; + break; + case 0x04: + m_acia_rxc_txc_div = 16; + m_acia_rxc_txc_p_low = 5; + m_acia_rxc_txc_p_high = 8; + break; + case 0x06: + m_acia_rxc_txc_div = 8; + m_acia_rxc_txc_p_low = 5; + m_acia_rxc_txc_p_high = 8; + break; + } + + // Initialise memory configuration + m_rom_mode = 0; + m_bit_9 = 1; + set_rom_mode(1); + set_bit_9(0); + + // Reset serial state + m_acia_irq_state = 0; + m_acia_rxc_txc_state = 0; + update_acia_rxc_txc(); + + m_resolution = 0; + m_hc_left = 0; + m_p_chargen = memregion( "chargen" )->base(); + + for (unsigned i = 0; i < 0x1000; i++) + m_ram->pointer()[0x10000 + i] |= 0x7F; +} + +void osborne1_state::video_start() +{ + machine().first_screen()->register_screen_bitmap(m_bitmap); +} + +UINT32 osborne1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); + return 0; +} + + +TIMER_CALLBACK_MEMBER(osborne1_state::video_callback) { int const y = machine().first_screen()->vpos(); UINT8 ra = 0; @@ -330,51 +389,31 @@ TIMER_CALLBACK_MEMBER(osborne1_state::osborne1_video_callback) m_video_timer->adjust(machine().first_screen()->time_until_pos(y + 1, 0)); } -TIMER_CALLBACK_MEMBER(osborne1_state::setup_osborne1) +TIMER_CALLBACK_MEMBER(osborne1_state::setup_callback) { m_beep->set_state( 0 ); m_beep->set_frequency( 300 /* 60 * 240 / 2 */ ); m_pia1->ca1_w(0); } -void osborne1_state::machine_reset() + +void osborne1_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - // Initialize memory configuration - m_rom_mode = 0; - m_bit_9 = 1; - set_rom_mode(1); - set_bit_9(0); - - m_screen_pac = 0 != (m_cnf->read() & 0x01); - m_resolution = 0; - m_hc_left = 0; - m_p_chargen = memregion( "chargen" )->base(); - - memset(m_ram->pointer() + 0x10000, 0xFF, 0x1000); -} - - -DRIVER_INIT_MEMBER(osborne1_state,osborne1) -{ - /* Configure the 6850 ACIA */ -// acia6850_config( 0, &osborne1_6850_config ); - m_video_timer = timer_alloc(TIMER_VIDEO); - m_video_timer->adjust(machine().first_screen()->time_until_pos(1, 0)); - - timer_set(attotime::zero, TIMER_SETUP); -} - - -void osborne1_state::video_start() -{ - machine().first_screen()->register_screen_bitmap(m_bitmap); -} - - -UINT32 osborne1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); - return 0; + switch (id) + { + case TIMER_VIDEO: + video_callback(ptr, param); + break; + case TIMER_ACIA_RXC_TXC: + m_acia_rxc_txc_state = m_acia_rxc_txc_state ? 0 : 1; + update_acia_rxc_txc(); + break; + case TIMER_SETUP: + setup_callback(ptr, param); + break; + default: + assert_always(FALSE, "Unknown id in osborne1_state::device_timer"); + } } @@ -383,16 +422,8 @@ bool osborne1_state::set_rom_mode(UINT8 value) if (value != m_rom_mode) { m_rom_mode = value; - if (m_rom_mode) - { - m_bank_0xxx->set_base(m_region_maincpu->base()); - m_bank_1xxx->set_base(m_region_maincpu->base()); - } - else - { - m_bank_0xxx->set_base(m_ram->pointer()); - m_bank_1xxx->set_base(m_ram->pointer() + 0x1000); - } + m_bank_0xxx->set_entry(m_rom_mode); + m_bank_1xxx->set_entry(m_rom_mode); return true; } else @@ -406,7 +437,7 @@ bool osborne1_state::set_bit_9(UINT8 value) if (value != m_bit_9) { m_bit_9 = value; - m_bank_fxxx->set_base(m_ram->pointer() + (m_bit_9 ? 0x10000 : 0xF000)); + m_bank_fxxx->set_entry(m_bit_9); return true; } else @@ -421,6 +452,17 @@ void osborne1_state::update_irq() m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0xF0); else if (m_pia1->irq_a_state()) m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0xF8); + else if (m_acia_irq_state) + m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0xFC); else m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, CLEAR_LINE, 0xFE); } + +void osborne1_state::update_acia_rxc_txc() +{ + m_acia->write_rxc(m_acia_rxc_txc_state); + m_acia->write_txc(m_acia_rxc_txc_state); + attoseconds_t const dividend = (ATTOSECONDS_PER_SECOND / 100) * (m_acia_rxc_txc_state ? m_acia_rxc_txc_p_high : m_acia_rxc_txc_p_low); + attoseconds_t const divisor = (15974400 / 100) / m_acia_rxc_txc_div; + m_acia_rxc_txc_timer->adjust(attotime(0, dividend / divisor)); +}