osborne1: correct beeper frequency (generated from video logic)

This commit is contained in:
Vas Crabb 2015-10-30 21:29:01 +11:00
parent 3f919cb083
commit 59672e4005
4 changed files with 64 additions and 87 deletions

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Wilbert Pol // copyright-holders:Wilbert Pol,Vas Crabb
/*************************************************************************** /***************************************************************************
Osborne-1 driver file Osborne-1 driver file
@ -54,10 +54,6 @@ the correct rates). MAME's bitbanger seems to be able to accept the ACIA
output at this rate, but the ACIA screws up when consuming data from MAME's output at this rate, but the ACIA screws up when consuming data from MAME's
bitbanger. bitbanger.
TODO:
- Verify frequency of the beep/audio alarm.
***************************************************************************/ ***************************************************************************/
#include "includes/osborne1.h" #include "includes/osborne1.h"
@ -242,9 +238,9 @@ static MACHINE_CONFIG_START( osborne1, osborne1_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", osborne1) MCFG_GFXDECODE_ADD("gfxdecode", "palette", osborne1)
MCFG_PALETTE_ADD_MONOCHROME_GREEN_HIGHLIGHT("palette") MCFG_PALETTE_ADD_MONOCHROME_GREEN_HIGHLIGHT("palette")
MCFG_SPEAKER_STANDARD_MONO( "mono" ) MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD( "beeper", BEEP, 0 ) MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
MCFG_SOUND_ROUTE( ALL_OUTPUTS, "mono", 1.00 ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
MCFG_DEVICE_ADD("pia_0", PIA6821, 0) MCFG_DEVICE_ADD("pia_0", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(DEVREAD8(IEEE488_TAG, ieee488_device, dio_r)) MCFG_PIA_READPA_HANDLER(DEVREAD8(IEEE488_TAG, ieee488_device, dio_r))

View File

@ -172,7 +172,7 @@ WRITE8_MEMBER(uzebox_state::port_d_w)
// ---- --xx UART MIDI // ---- --xx UART MIDI
if ((m_port_d ^ data) & 0x80) if ((m_port_d ^ data) & 0x80)
{ {
m_speaker->level_w(data & 0x80); m_speaker->level_w((data & 0x80) ? 1 : 0);
} }
m_port_d = data; m_port_d = data;
} }

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Wilbert Pol // copyright-holders:Wilbert Pol,Vas Crabb
/***************************************************************************** /*****************************************************************************
* *
* includes/osborne1.h * includes/osborne1.h
@ -11,10 +11,10 @@
#include "emu.h" #include "emu.h"
#include "cpu/z80/z80.h" #include "cpu/z80/z80.h"
#include "sound/beep.h" #include "sound/speaker.h"
#include "bus/ieee488/ieee488.h"
#include "machine/6821pia.h" #include "machine/6821pia.h"
#include "machine/6850acia.h" #include "machine/6850acia.h"
#include "bus/ieee488/ieee488.h"
#include "machine/ram.h" #include "machine/ram.h"
#include "machine/wd_fdc.h" #include "machine/wd_fdc.h"
@ -24,23 +24,21 @@ public:
enum enum
{ {
TIMER_VIDEO, TIMER_VIDEO,
TIMER_ACIA_RXC_TXC, TIMER_ACIA_RXC_TXC
TIMER_SETUP
}; };
osborne1_state(const machine_config &mconfig, device_type type, const char *tag) : osborne1_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag), driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_speaker(*this, "speaker"),
m_pia0(*this, "pia_0"), m_pia0(*this, "pia_0"),
m_pia1(*this, "pia_1"), m_pia1(*this, "pia_1"),
m_acia(*this, "acia"), m_acia(*this, "acia"),
m_fdc(*this, "mb8877"), m_fdc(*this, "mb8877"),
m_beep(*this, "beeper"),
m_ram(*this, RAM_TAG), m_ram(*this, RAM_TAG),
m_ieee(*this, IEEE488_TAG), m_ieee(*this, IEEE488_TAG),
m_floppy0(*this, "mb8877:0:525ssdd"), m_floppy0(*this, "mb8877:0:525ssdd"),
m_floppy1(*this, "mb8877:1:525ssdd"), m_floppy1(*this, "mb8877:1:525ssdd"),
m_video_timer(NULL),
m_keyb_row0(*this, "ROW0"), m_keyb_row0(*this, "ROW0"),
m_keyb_row1(*this, "ROW1"), m_keyb_row1(*this, "ROW1"),
m_keyb_row2(*this, "ROW2"), m_keyb_row2(*this, "ROW2"),
@ -55,6 +53,7 @@ public:
m_bank_0xxx(*this, "bank_0xxx"), m_bank_0xxx(*this, "bank_0xxx"),
m_bank_1xxx(*this, "bank_1xxx"), m_bank_1xxx(*this, "bank_1xxx"),
m_bank_fxxx(*this, "bank_fxxx"), m_bank_fxxx(*this, "bank_fxxx"),
m_video_timer(NULL),
m_acia_rxc_txc_timer(NULL) m_acia_rxc_txc_timer(NULL)
{ } { }
@ -84,28 +83,20 @@ public:
virtual void video_start(); virtual void video_start();
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); 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<cpu_device> m_maincpu;
required_device<speaker_sound_device> m_speaker;
required_device<pia6821_device> m_pia0; required_device<pia6821_device> m_pia0;
required_device<pia6821_device> m_pia1; required_device<pia6821_device> m_pia1;
required_device<acia6850_device> m_acia; required_device<acia6850_device> m_acia;
required_device<mb8877_t> m_fdc; required_device<mb8877_t> m_fdc;
required_device<beep_device> m_beep;
required_device<ram_device> m_ram; required_device<ram_device> m_ram;
required_device<ieee488_device> m_ieee; required_device<ieee488_device> m_ieee;
required_device<floppy_image_device> m_floppy0; required_device<floppy_image_device> m_floppy0;
required_device<floppy_image_device> m_floppy1; required_device<floppy_image_device> m_floppy1;
emu_timer *m_video_timer;
UINT8 *m_p_chargen;
bool m_beep_state;
protected: protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
TIMER_CALLBACK_MEMBER(video_callback);
bool set_rom_mode(UINT8 value); bool set_rom_mode(UINT8 value);
bool set_bit_9(UINT8 value); bool set_bit_9(UINT8 value);
@ -144,9 +135,13 @@ protected:
UINT8 m_rom_mode; UINT8 m_rom_mode;
UINT8 m_bit_9; UINT8 m_bit_9;
// video registers // onboard video state
UINT8 m_scroll_x; UINT8 m_scroll_x;
UINT8 m_scroll_y; UINT8 m_scroll_y;
UINT8 m_beep_state;
emu_timer *m_video_timer;
bitmap_ind16 m_bitmap;
UINT8 *m_p_chargen;
// SCREEN-PAC registers // SCREEN-PAC registers
UINT8 m_resolution; UINT8 m_resolution;

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause // license:BSD-3-Clause
// copyright-holders:Wilbert Pol // copyright-holders:Wilbert Pol,Vas Crabb
/*************************************************************************** /***************************************************************************
There are three IRQ sources: There are three IRQ sources:
@ -35,10 +35,10 @@ READ8_MEMBER( osborne1_state::bank_2xxx_3xxx_r )
UINT8 data = 0xFF; UINT8 data = 0xFF;
switch (offset & 0x0F00) switch (offset & 0x0F00)
{ {
case 0x100: /* Floppy */ case 0x100: // Floppy
data = m_fdc->read(space, offset & 0x03); data = m_fdc->read(space, offset & 0x03);
break; break;
case 0x200: /* Keyboard */ case 0x200: // Keyboard
if (offset & 0x01) data &= m_keyb_row0->read(); if (offset & 0x01) data &= m_keyb_row0->read();
if (offset & 0x02) data &= m_keyb_row1->read(); if (offset & 0x02) data &= m_keyb_row1->read();
if (offset & 0x04) data &= m_keyb_row3->read(); if (offset & 0x04) data &= m_keyb_row3->read();
@ -48,17 +48,17 @@ READ8_MEMBER( osborne1_state::bank_2xxx_3xxx_r )
if (offset & 0x40) data &= m_keyb_row6->read(); if (offset & 0x40) data &= m_keyb_row6->read();
if (offset & 0x80) data &= m_keyb_row7->read(); if (offset & 0x80) data &= m_keyb_row7->read();
break; break;
case 0x400: /* SCREEN-PAC */ case 0x400: // SCREEN-PAC
if (m_screen_pac) data &= 0xFB; if (m_screen_pac) data &= 0xFB;
break; break;
case 0x900: /* IEEE488 PIA */ case 0x900: // IEEE488 PIA
data = m_pia0->read(space, offset & 0x03); data = m_pia0->read(space, offset & 0x03);
break; break;
case 0xA00: /* Serial */ case 0xA00: // Serial
if (offset & 0x01) data = m_acia->data_r(space, 0); if (offset & 0x01) data = m_acia->data_r(space, 0);
else data = m_acia->status_r(space, 0); else data = m_acia->status_r(space, 0);
break; break;
case 0xC00: /* Video PIA */ case 0xC00: // Video PIA
data = m_pia1->read(space, offset & 0x03); data = m_pia1->read(space, offset & 0x03);
break; break;
} }
@ -255,12 +255,11 @@ DRIVER_INIT_MEMBER( osborne1_state, osborne1 )
m_bank_fxxx->configure_entries(0, 1, m_ram->pointer() + 0xF000, 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_bank_fxxx->configure_entries(1, 1, m_ram->pointer() + 0x10000, 0);
m_p_chargen = memregion("chargen")->base();
m_video_timer = timer_alloc(TIMER_VIDEO); m_video_timer = timer_alloc(TIMER_VIDEO);
m_video_timer->adjust(machine().first_screen()->time_until_pos(1, 0)); m_video_timer->adjust(machine().first_screen()->time_until_pos(1, 0));
m_acia_rxc_txc_timer = timer_alloc(TIMER_ACIA_RXC_TXC); m_acia_rxc_txc_timer = timer_alloc(TIMER_ACIA_RXC_TXC);
timer_set(attotime::zero, TIMER_SETUP);
} }
void osborne1_state::machine_reset() void osborne1_state::machine_reset()
@ -302,10 +301,11 @@ void osborne1_state::machine_reset()
m_acia_rxc_txc_state = 0; m_acia_rxc_txc_state = 0;
update_acia_rxc_txc(); update_acia_rxc_txc();
// Reset video hardware
m_resolution = 0; m_resolution = 0;
m_hc_left = 1; m_hc_left = 1;
m_p_chargen = memregion( "chargen" )->base();
// The low bits of attribute RAM are not physically present and hence always read high
for (unsigned i = 0; i < 0x1000; i++) for (unsigned i = 0; i < 0x1000; i++)
m_ram->pointer()[0x10000 + i] |= 0x7F; m_ram->pointer()[0x10000 + i] |= 0x7F;
} }
@ -322,10 +322,26 @@ UINT32 osborne1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap
} }
void osborne1_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
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;
default:
assert_always(FALSE, "Unknown id in osborne1_state::device_timer");
}
}
TIMER_CALLBACK_MEMBER(osborne1_state::video_callback) TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
{ {
int const y = machine().first_screen()->vpos(); int const y = machine().first_screen()->vpos();
UINT8 ra = 0; UINT8 const ra = y % 10;
// Check for start/end of visible area and clear/set CA1 on video PIA // Check for start/end of visible area and clear/set CA1 on video PIA
if (y == 0) if (y == 0)
@ -335,7 +351,6 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
if (y < 240) if (y < 240)
{ {
ra = y % 10;
// Draw a line of the display // Draw a line of the display
UINT16 *p = &m_bitmap.pix16(y); UINT16 *p = &m_bitmap.pix16(y);
bool const hires = m_screen_pac & m_resolution; bool const hires = m_screen_pac & m_resolution;
@ -360,9 +375,9 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
// past 0x7F // past 0x7F
UINT16 const col = hires ? ((m_scroll_x & 0x60) + (m_hc_left ? 0x09 : 0x01) + 0x17) : (m_scroll_x + 0x0B); UINT16 const col = hires ? ((m_scroll_x & 0x60) + (m_hc_left ? 0x09 : 0x01) + 0x17) : (m_scroll_x + 0x0B);
for ( UINT16 x = 0; x < (hires ? 104 : 52); x++ ) for (UINT16 x = 0; x < (hires ? 104 : 52); x++)
{ {
UINT16 offs = row | ((col + x) & 0x7F); UINT16 const offs = row | ((col + x) & 0x7F);
UINT8 const chr = m_ram->pointer()[0xF000 + offs]; UINT8 const chr = m_ram->pointer()[0xF000 + offs];
UINT8 const dim = m_ram->pointer()[0x10000 + offs] & 0x80; UINT8 const dim = m_ram->pointer()[0x10000 + offs] & 0x80;
@ -388,10 +403,8 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
} }
} }
if ((ra == 2) || (ra == 6)) // The beeper is gated so it's active four out of every ten scanlines
m_beep->set_state(m_beep_state); m_speaker->level_w((m_beep_state && (ra & 0x04)) ? 1 : 0);
else
m_beep->set_state(0);
// Check reset key if necessary - it affects NMI // Check reset key if necessary - it affects NMI
if (!m_ub6a_q) if (!m_ub6a_q)
@ -400,33 +413,6 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
m_video_timer->adjust(machine().first_screen()->time_until_pos(y + 1, 0)); m_video_timer->adjust(machine().first_screen()->time_until_pos(y + 1, 0));
} }
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::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
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");
}
}
bool osborne1_state::set_rom_mode(UINT8 value) bool osborne1_state::set_rom_mode(UINT8 value)
{ {