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
// copyright-holders:Wilbert Pol
// copyright-holders:Wilbert Pol,Vas Crabb
/***************************************************************************
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
bitbanger.
TODO:
- Verify frequency of the beep/audio alarm.
***************************************************************************/
#include "includes/osborne1.h"
@ -242,9 +238,9 @@ static MACHINE_CONFIG_START( osborne1, osborne1_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", osborne1)
MCFG_PALETTE_ADD_MONOCHROME_GREEN_HIGHLIGHT("palette")
MCFG_SPEAKER_STANDARD_MONO( "mono" )
MCFG_SOUND_ADD( "beeper", BEEP, 0 )
MCFG_SOUND_ROUTE( ALL_OUTPUTS, "mono", 1.00 )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
MCFG_DEVICE_ADD("pia_0", PIA6821, 0)
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
if ((m_port_d ^ data) & 0x80)
{
m_speaker->level_w(data & 0x80);
m_speaker->level_w((data & 0x80) ? 1 : 0);
}
m_port_d = data;
}

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
// copyright-holders:Wilbert Pol,Vas Crabb
/*****************************************************************************
*
* includes/osborne1.h
@ -11,10 +11,10 @@
#include "emu.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/6850acia.h"
#include "bus/ieee488/ieee488.h"
#include "machine/ram.h"
#include "machine/wd_fdc.h"
@ -24,23 +24,21 @@ public:
enum
{
TIMER_VIDEO,
TIMER_ACIA_RXC_TXC,
TIMER_SETUP
TIMER_ACIA_RXC_TXC
};
osborne1_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_speaker(*this, "speaker"),
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"),
@ -55,6 +53,7 @@ public:
m_bank_0xxx(*this, "bank_0xxx"),
m_bank_1xxx(*this, "bank_1xxx"),
m_bank_fxxx(*this, "bank_fxxx"),
m_video_timer(NULL),
m_acia_rxc_txc_timer(NULL)
{ }
@ -84,28 +83,20 @@ public:
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<speaker_sound_device> m_speaker;
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;
emu_timer *m_video_timer;
UINT8 *m_p_chargen;
bool m_beep_state;
protected:
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_bit_9(UINT8 value);
@ -133,29 +124,33 @@ protected:
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;
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;
UINT8 m_ub4a_q;
UINT8 m_ub6a_q;
UINT8 m_rom_mode;
UINT8 m_bit_9;
// video registers
UINT8 m_scroll_x;
UINT8 m_scroll_y;
// onboard video state
UINT8 m_scroll_x;
UINT8 m_scroll_y;
UINT8 m_beep_state;
emu_timer *m_video_timer;
bitmap_ind16 m_bitmap;
UINT8 *m_p_chargen;
// SCREEN-PAC registers
UINT8 m_resolution;
UINT8 m_hc_left;
UINT8 m_resolution;
UINT8 m_hc_left;
// serial state
int m_acia_irq_state;
int m_acia_rxc_txc_state;
emu_timer *m_acia_rxc_txc_timer;
int m_acia_irq_state;
int m_acia_rxc_txc_state;
emu_timer *m_acia_rxc_txc_timer;
};
#endif /* OSBORNE1_H_ */

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Wilbert Pol
// copyright-holders:Wilbert Pol,Vas Crabb
/***************************************************************************
There are three IRQ sources:
@ -35,10 +35,10 @@ READ8_MEMBER( osborne1_state::bank_2xxx_3xxx_r )
UINT8 data = 0xFF;
switch (offset & 0x0F00)
{
case 0x100: /* Floppy */
case 0x100: // Floppy
data = m_fdc->read(space, offset & 0x03);
break;
case 0x200: /* Keyboard */
case 0x200: // Keyboard
if (offset & 0x01) data &= m_keyb_row0->read();
if (offset & 0x02) data &= m_keyb_row1->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 & 0x80) data &= m_keyb_row7->read();
break;
case 0x400: /* SCREEN-PAC */
case 0x400: // SCREEN-PAC
if (m_screen_pac) data &= 0xFB;
break;
case 0x900: /* IEEE488 PIA */
case 0x900: // IEEE488 PIA
data = m_pia0->read(space, offset & 0x03);
break;
case 0xA00: /* Serial */
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 */
case 0xC00: // Video PIA
data = m_pia1->read(space, offset & 0x03);
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(1, 1, m_ram->pointer() + 0x10000, 0);
m_p_chargen = memregion("chargen")->base();
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()
@ -302,10 +301,11 @@ void osborne1_state::machine_reset()
m_acia_rxc_txc_state = 0;
update_acia_rxc_txc();
// Reset video hardware
m_resolution = 0;
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++)
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)
{
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
if (y == 0)
@ -335,7 +351,6 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
if (y < 240)
{
ra = y % 10;
// Draw a line of the display
UINT16 *p = &m_bitmap.pix16(y);
bool const hires = m_screen_pac & m_resolution;
@ -360,9 +375,9 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
// past 0x7F
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 dim = m_ram->pointer()[0x10000 + offs] & 0x80;
@ -388,10 +403,8 @@ TIMER_CALLBACK_MEMBER(osborne1_state::video_callback)
}
}
if ((ra == 2) || (ra == 6))
m_beep->set_state(m_beep_state);
else
m_beep->set_state(0);
// The beeper is gated so it's active four out of every ten scanlines
m_speaker->level_w((m_beep_state && (ra & 0x04)) ? 1 : 0);
// Check reset key if necessary - it affects NMI
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));
}
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)
{