osborne1: add 6850ACIA serial port (untested), use configured banking

This commit is contained in:
Vas Crabb 2015-10-30 02:58:34 +11:00
parent 82b0259145
commit 87b633a97c
3 changed files with 211 additions and 130 deletions

View File

@ -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

View File

@ -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<cpu_device> m_maincpu;
required_device<pia6821_device> m_pia0;
required_device<pia6821_device> m_pia1;
required_device<mb8877_t> m_fdc;
required_device<beep_device> m_beep;
required_device<ram_device> m_ram;
required_device<ieee488_device> m_ieee;
required_device<floppy_image_device> m_floppy0;
required_device<floppy_image_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<cpu_device> m_maincpu;
required_device<pia6821_device> m_pia0;
required_device<pia6821_device> m_pia1;
required_device<acia6850_device> m_acia;
required_device<mb8877_t> m_fdc;
required_device<beep_device> m_beep;
required_device<ram_device> m_ram;
required_device<ieee488_device> m_ieee;
required_device<floppy_image_device> m_floppy0;
required_device<floppy_image_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_ */

View File

@ -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));
}