Added support for driving the speaker line directly with the speaker gate, but
the square wave generator disabled. This feature has been used by old demos and games to play digitized sound before soundcards with DSP became popular.
This commit is contained in:
parent
53d703f6e1
commit
c10e8feea6
@ -38,6 +38,8 @@ Changes after 2.6.9 release:
|
||||
- Networking
|
||||
- bxhub: Added DNS service support for the server "vnet" and connected
|
||||
clients.
|
||||
- Sound
|
||||
- PC speaker now can play digitized sound by driving speaker gate.
|
||||
|
||||
- GUI and display libraries
|
||||
- Added new win32 gui option "traphotkeys" for fullscreen mode.
|
||||
|
@ -324,6 +324,7 @@ public:
|
||||
virtual void beep_off() {
|
||||
bx_gui->beep_off();
|
||||
}
|
||||
virtual void set_line(bx_bool level) {}
|
||||
};
|
||||
|
||||
#if BX_SUPPORT_PCI
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2017 The Bochs Project
|
||||
// Copyright (C) 2001-2018 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -119,6 +119,7 @@ void bx_pit_c::init(void)
|
||||
|
||||
BX_PIT_THIS s.speaker_data_on = 0;
|
||||
BX_PIT_THIS s.speaker_active = 0;
|
||||
BX_PIT_THIS s.speaker_level = 0;
|
||||
|
||||
BX_PIT_THIS s.timer.init();
|
||||
BX_PIT_THIS s.timer.set_OUT_handler(0, irq_handler);
|
||||
@ -170,6 +171,7 @@ void bx_pit_c::register_state(void)
|
||||
bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "pit", "8254 PIT State");
|
||||
new bx_shadow_bool_c(list, "speaker_data_on", &BX_PIT_THIS s.speaker_data_on);
|
||||
new bx_shadow_bool_c(list, "speaker_active", &BX_PIT_THIS s.speaker_active);
|
||||
new bx_shadow_bool_c(list, "speaker_level", &BX_PIT_THIS s.speaker_level);
|
||||
new bx_shadow_num_c(list, "last_usec", &BX_PIT_THIS s.last_usec);
|
||||
new bx_shadow_num_c(list, "last_next_event_time", &BX_PIT_THIS s.last_next_event_time);
|
||||
new bx_shadow_num_c(list, "total_ticks", &BX_PIT_THIS s.total_ticks);
|
||||
@ -295,7 +297,7 @@ void bx_pit_c::write(Bit32u address, Bit32u dvalue, unsigned io_len)
|
||||
Bit64u my_time_usec = bx_virt_timer.time_usec(BX_PIT_THIS is_realtime);
|
||||
Bit64u time_passed = my_time_usec-BX_PIT_THIS s.last_usec;
|
||||
Bit32u value32, time_passed32 = (Bit32u)time_passed;
|
||||
bx_bool new_speaker_active;
|
||||
bx_bool new_speaker_active, new_speaker_level;
|
||||
|
||||
if (time_passed32) {
|
||||
periodic(time_passed32);
|
||||
@ -342,6 +344,13 @@ void bx_pit_c::write(Bit32u address, Bit32u dvalue, unsigned io_len)
|
||||
}
|
||||
BX_PIT_THIS s.speaker_active = new_speaker_active;
|
||||
}
|
||||
if (!BX_PIT_THIS s.speaker_active) {
|
||||
new_speaker_level = BX_PIT_THIS s.speaker_data_on & BX_PIT_THIS s.timer.read_OUT(2);
|
||||
if (BX_PIT_THIS s.speaker_level != new_speaker_level) {
|
||||
DEV_speaker_set_line(new_speaker_level);
|
||||
BX_PIT_THIS s.speaker_level = new_speaker_level;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2017 The Bochs Project
|
||||
// Copyright (C) 2001-2018 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -59,6 +59,7 @@ private:
|
||||
pit_82C54 timer;
|
||||
bx_bool speaker_data_on;
|
||||
bx_bool speaker_active;
|
||||
bx_bool speaker_level;
|
||||
Bit64u last_usec;
|
||||
Bit32u last_next_event_time;
|
||||
Bit64u total_ticks;
|
||||
|
@ -195,6 +195,12 @@ void bx_speaker_c::init(void)
|
||||
waveout = DEV_sound_get_waveout(0);
|
||||
if (waveout != NULL) {
|
||||
beep_active = 0;
|
||||
#if BX_HAVE_REALTIME_USEC
|
||||
dsp_active = 0;
|
||||
dsp_start_usec = bx_get_realtime64_usec();
|
||||
dsp_cb_usec = 0;
|
||||
dsp_count = 0;
|
||||
#endif
|
||||
BX_INIT_MUTEX(beep_mutex);
|
||||
beep_callback_id = waveout->register_wave_callback(theSpeaker, beep_callback);
|
||||
BX_INFO(("Using lowlevel sound support for output"));
|
||||
@ -234,7 +240,7 @@ void bx_speaker_c::reset(unsigned type)
|
||||
#if BX_SUPPORT_SOUNDLOW
|
||||
Bit32u bx_speaker_c::beep_generator(Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
{
|
||||
Bit32u j = 0;
|
||||
Bit32u j = 0, ret = 0;
|
||||
Bit16u beep_samples;
|
||||
static Bit8u beep_level = 0x40;
|
||||
static Bit16u beep_pos = 0;
|
||||
@ -246,8 +252,13 @@ Bit32u bx_speaker_c::beep_generator(Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
beep_samples = (Bit32u)((float)rate / beep_frequency / 2);
|
||||
}
|
||||
if (beep_samples == 0) {
|
||||
#if BX_SUPPORT_SOUNDLOW && BX_HAVE_REALTIME_USEC
|
||||
if (dsp_active) {
|
||||
ret = dsp_generator(rate, buffer, len);
|
||||
}
|
||||
#endif
|
||||
BX_UNLOCK(beep_mutex);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
do {
|
||||
buffer[j++] = 0;
|
||||
@ -265,6 +276,37 @@ Bit32u bx_speaker_c::beep_generator(Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
return len;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_SOUNDLOW && BX_HAVE_REALTIME_USEC
|
||||
Bit32u bx_speaker_c::dsp_generator(Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
{
|
||||
Bit32u i = 0, j = 0;
|
||||
double tmp_dsp_usec, step_usec;
|
||||
static Bit8u dsp_level = 0x40;
|
||||
|
||||
Bit64u new_dsp_cb_usec = bx_get_realtime64_usec() - dsp_start_usec;
|
||||
if (dsp_cb_usec == 0) {
|
||||
dsp_cb_usec = new_dsp_cb_usec - 25000;
|
||||
}
|
||||
tmp_dsp_usec = (double)dsp_cb_usec;
|
||||
step_usec = 1000000.0 / (double)rate;
|
||||
do {
|
||||
if ((i < dsp_count) && (dsp_event_buffer[i] < (Bit64u)tmp_dsp_usec)) {
|
||||
dsp_level ^= 0x80;
|
||||
i++;
|
||||
}
|
||||
buffer[j++] = 0;
|
||||
buffer[j++] = dsp_level;
|
||||
buffer[j++] = 0;
|
||||
buffer[j++] = dsp_level;
|
||||
tmp_dsp_usec += step_usec;
|
||||
} while (j < len);
|
||||
dsp_active = 0;
|
||||
dsp_count = 0;
|
||||
dsp_cb_usec = new_dsp_cb_usec;
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
Bit32u beep_callback(void *dev, Bit16u rate, Bit8u *buffer, Bit32u len)
|
||||
{
|
||||
return ((bx_speaker_c*)dev)->beep_generator(rate, buffer, len);
|
||||
@ -367,3 +409,20 @@ void bx_speaker_c::beep_off()
|
||||
}
|
||||
beep_frequency = 0.0;
|
||||
}
|
||||
|
||||
void bx_speaker_c::set_line(bx_bool level)
|
||||
{
|
||||
if (output_mode == BX_SPK_MODE_SOUND) {
|
||||
#if BX_SUPPORT_SOUNDLOW && BX_HAVE_REALTIME_USEC
|
||||
BX_LOCK(beep_mutex);
|
||||
Bit64u timestamp = bx_get_realtime64_usec() - dsp_start_usec;
|
||||
dsp_active = 1;
|
||||
if (dsp_count < 500) {
|
||||
dsp_event_buffer[dsp_count++] = timestamp;
|
||||
} else {
|
||||
BX_ERROR(("DSP event buffer full"));
|
||||
}
|
||||
BX_UNLOCK(beep_mutex);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2003 David N. Welton <davidw@dedasys.com>.
|
||||
// Copyright (C) 2003-2015 The Bochs Project
|
||||
// Copyright (C) 2003-2018 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -41,8 +41,12 @@ public:
|
||||
|
||||
void beep_on(float frequency);
|
||||
void beep_off();
|
||||
void set_line(bx_bool level);
|
||||
#if BX_SUPPORT_SOUNDLOW
|
||||
Bit32u beep_generator(Bit16u rate, Bit8u *buffer, Bit32u len);
|
||||
#if BX_HAVE_REALTIME_USEC
|
||||
Bit32u dsp_generator(Bit16u rate, Bit8u *buffer, Bit32u len);
|
||||
#endif
|
||||
#endif
|
||||
private:
|
||||
float beep_frequency; // 0 : beep is off
|
||||
@ -58,6 +62,13 @@ private:
|
||||
bx_soundlow_waveout_c *waveout;
|
||||
int beep_callback_id;
|
||||
bx_bool beep_active;
|
||||
#if BX_HAVE_REALTIME_USEC
|
||||
bx_bool dsp_active;
|
||||
Bit64u dsp_start_usec;
|
||||
Bit64u dsp_cb_usec;
|
||||
Bit32u dsp_count;
|
||||
Bit64u dsp_event_buffer[500];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -256,6 +256,7 @@ extern "C" {
|
||||
///////// Speaker macros
|
||||
#define DEV_speaker_beep_on(frequency) bx_devices.pluginSpeaker->beep_on(frequency)
|
||||
#define DEV_speaker_beep_off() bx_devices.pluginSpeaker->beep_off()
|
||||
#define DEV_speaker_set_line(a) bx_devices.pluginSpeaker->set_line(a)
|
||||
|
||||
///////// Memory macros
|
||||
#define DEV_register_memory_handlers(param,rh,wh,b,e) \
|
||||
|
Loading…
Reference in New Issue
Block a user