Added new bochsrc option to control the speaker output mode. The choices 'sound'
(lowlevel sound output), 'system' (system beep on Linux and Windows) and 'gui' (forward beep to related gui methods) are available.
This commit is contained in:
parent
f1c6be0bc8
commit
c3740c0e6e
@ -721,6 +721,17 @@ debugger_log: -
|
||||
#=======================================================================
|
||||
parport1: enabled=1, file="parport.out"
|
||||
|
||||
#=======================================================================
|
||||
# SPEAKER:
|
||||
# This defines the PC speaker output mode. In the 'sound' mode the beep
|
||||
# is generated by the square wave generator which is a part of the
|
||||
# lowlevel sound support. The 'system' mode is only available on Linux
|
||||
# and Windows. On Linux /dev/console is used for output and on Windows
|
||||
# the Beep() function. The 'gui' mode forwards the beep to the related
|
||||
# gui methods (currently only used by the Carbon gui).
|
||||
#=======================================================================
|
||||
speaker: enabled=1, mode=sound
|
||||
|
||||
#=======================================================================
|
||||
# SB16:
|
||||
# This defines the SB16 sound emulation. It can have several of the
|
||||
|
@ -43,11 +43,71 @@
|
||||
|
||||
bx_speaker_c *theSpeaker= NULL;
|
||||
|
||||
#define BX_SPK_MODE_NONE 0
|
||||
#define BX_SPK_MODE_SOUND 1
|
||||
#define BX_SPK_MODE_SYSTEM 2
|
||||
#define BX_SPK_MODE_GUI 3
|
||||
|
||||
// builtin configuration handling functions
|
||||
|
||||
void speaker_init_options(void)
|
||||
{
|
||||
static const char *speaker_mode_list[] = {
|
||||
#if BX_SUPPORT_SOUNDLOW
|
||||
"sound",
|
||||
#endif
|
||||
#if defined(__linux__) || defined(WIN32)
|
||||
"system",
|
||||
#endif
|
||||
"gui",
|
||||
NULL
|
||||
};
|
||||
|
||||
bx_list_c *sound = (bx_list_c*)SIM->get_param("sound");
|
||||
bx_list_c *menu = new bx_list_c(sound, "speaker", "PC speaker output configuration");
|
||||
menu->set_options(menu->SERIES_ASK);
|
||||
bx_param_bool_c *enabled = new bx_param_bool_c(menu, "enabled", "Enable speaker output",
|
||||
"Enables the PC speaker output", 1);
|
||||
bx_param_enum_c *mode = new bx_param_enum_c(menu, "mode", "Speaker output mode",
|
||||
"The mode can be one these: 'sound', 'system' or 'gui'",
|
||||
speaker_mode_list, 0, 0);
|
||||
mode->set_ask_format("Select speker output mode [%s] ");
|
||||
bx_list_c *deplist = new bx_list_c(NULL);
|
||||
deplist->add(mode);
|
||||
enabled->set_dependent_list(deplist);
|
||||
}
|
||||
|
||||
Bit32s speaker_options_parser(const char *context, int num_params, char *params[])
|
||||
{
|
||||
if (!strcmp(params[0], "speaker")) {
|
||||
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SPEAKER);
|
||||
for (int i=1; i<num_params; i++) {
|
||||
if (SIM->parse_param_from_list(context, params[i], base) < 0) {
|
||||
BX_ERROR(("%s: unknown parameter for speaker ignored.", context));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BX_PANIC(("%s: unknown directive '%s'", context, params[0]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bit32s speaker_options_save(FILE *fp)
|
||||
{
|
||||
return SIM->write_param_list(fp, (bx_list_c*) SIM->get_param(BXPN_SOUND_SPEAKER), NULL, 0);
|
||||
}
|
||||
|
||||
// device plugin entry points
|
||||
|
||||
int libspeaker_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
|
||||
{
|
||||
theSpeaker = new bx_speaker_c();
|
||||
bx_devices.pluginSpeaker = theSpeaker;
|
||||
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theSpeaker, BX_PLUGIN_SPEAKER);
|
||||
// add new configuration parameters for the config interface
|
||||
speaker_init_options();
|
||||
// register add-on options for bochsrc and command line
|
||||
SIM->register_addon_option("speaker", speaker_options_parser, speaker_options_save);
|
||||
return(0); // Success
|
||||
}
|
||||
|
||||
@ -55,8 +115,12 @@ void libspeaker_LTX_plugin_fini(void)
|
||||
{
|
||||
bx_devices.pluginSpeaker = &bx_devices.stubSpeaker;
|
||||
delete theSpeaker;
|
||||
SIM->unregister_addon_option("speaker");
|
||||
((bx_list_c*)SIM->get_param("sound"))->remove("speaker");
|
||||
}
|
||||
|
||||
// the device object
|
||||
|
||||
bx_speaker_c::bx_speaker_c()
|
||||
{
|
||||
put("speaker", "SPEAK");
|
||||
@ -80,22 +144,21 @@ bx_speaker_c::~bx_speaker_c()
|
||||
|
||||
void bx_speaker_c::init(void)
|
||||
{
|
||||
outputinit = 0;
|
||||
#if defined(WIN32)
|
||||
useBeep = FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bx_speaker_c::reset(unsigned type)
|
||||
{
|
||||
if (!outputinit) {
|
||||
outputinit = 1;
|
||||
#if BX_SUPPORT_SOUNDLOW
|
||||
if (DEV_soundmod_beep_off()) {
|
||||
BX_INFO(("Using lowlevel sound support for output"));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// Read in values from config interface
|
||||
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SPEAKER);
|
||||
// Check if the device is disabled or not configured
|
||||
if (!SIM->get_param_bool("enabled", base)->get()) {
|
||||
BX_INFO(("PC speaker output disabled"));
|
||||
// mark unused plugin for removal
|
||||
((bx_param_bool_c*)((bx_list_c*)SIM->get_param(BXPN_PLUGIN_CTRL))->get_by_name("sb16"))->set(0);
|
||||
return;
|
||||
}
|
||||
const char *mode = SIM->get_param_enum("mode", base)->get_selected();
|
||||
if (!strcmp(mode, "sound")) {
|
||||
output_mode = BX_SPK_MODE_SOUND;
|
||||
BX_INFO(("Using lowlevel sound support for output"));
|
||||
} else if (!strcmp(mode, "system")) {
|
||||
output_mode = BX_SPK_MODE_SYSTEM;
|
||||
#ifdef __linux__
|
||||
consolefd = open("/dev/console", O_WRONLY);
|
||||
if (consolefd != -1) {
|
||||
@ -106,7 +169,24 @@ void bx_speaker_c::reset(unsigned type)
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
BX_INFO(("Using system beep for output"));
|
||||
useBeep = TRUE;
|
||||
#endif
|
||||
} else if (!strcmp(mode, "gui")) {
|
||||
output_mode = BX_SPK_MODE_GUI;
|
||||
BX_INFO(("Forwarding beep to gui"));
|
||||
} else {
|
||||
output_mode = BX_SPK_MODE_NONE;
|
||||
}
|
||||
outputinit = 0;
|
||||
}
|
||||
|
||||
void bx_speaker_c::reset(unsigned type)
|
||||
{
|
||||
if (!outputinit) {
|
||||
outputinit = 1;
|
||||
#if BX_SUPPORT_SOUNDLOW
|
||||
if (!DEV_soundmod_beep_off()) {
|
||||
BX_ERROR(("Failed to use lowlevel sound support for output"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -116,29 +196,29 @@ void bx_speaker_c::reset(unsigned type)
|
||||
void bx_speaker_c::beep_on(float frequency)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
if (useBeep && (beep_frequency != 0.0)) {
|
||||
if ((output_mode == BX_SPK_MODE_SYSTEM) && (beep_frequency != 0.0)) {
|
||||
beep_off();
|
||||
}
|
||||
#endif
|
||||
beep_frequency = frequency;
|
||||
|
||||
if (output_mode == BX_SPK_MODE_SOUND) {
|
||||
#if BX_SUPPORT_SOUNDLOW
|
||||
if (DEV_soundmod_beep_on(frequency))
|
||||
return;
|
||||
DEV_soundmod_beep_on(frequency);
|
||||
#endif
|
||||
} else if (output_mode == BX_SPK_MODE_SYSTEM) {
|
||||
#ifdef __linux__
|
||||
if (consolefd != -1) {
|
||||
this->info("pc speaker on with frequency %f", frequency);
|
||||
ioctl(consolefd, KIOCSOUND, (int)(clock_tick_rate/frequency));
|
||||
}
|
||||
if (consolefd != -1) {
|
||||
BX_DEBUG(("PC speaker on with frequency %f", frequency));
|
||||
ioctl(consolefd, KIOCSOUND, (int)(clock_tick_rate/frequency));
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
if (useBeep) {
|
||||
usec_start = bx_pc_system.time_usec();
|
||||
}
|
||||
#endif
|
||||
|
||||
// give the gui a chance to signal beep on
|
||||
bx_gui->beep_on(frequency);
|
||||
} else if (output_mode == BX_SPK_MODE_GUI) {
|
||||
// give the gui a chance to signal beep on
|
||||
bx_gui->beep_on(frequency);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
@ -163,28 +243,28 @@ DWORD WINAPI BeepThread(LPVOID)
|
||||
|
||||
void bx_speaker_c::beep_off()
|
||||
{
|
||||
if (output_mode == BX_SPK_MODE_SOUND) {
|
||||
#if BX_SUPPORT_SOUNDLOW
|
||||
if (DEV_soundmod_beep_off())
|
||||
return;
|
||||
DEV_soundmod_beep_off();
|
||||
#endif
|
||||
if (beep_frequency != 0.0) {
|
||||
} else if (output_mode == BX_SPK_MODE_SYSTEM) {
|
||||
if (beep_frequency != 0.0) {
|
||||
#ifdef __linux__
|
||||
if (consolefd != -1) {
|
||||
ioctl(consolefd, KIOCSOUND, 0);
|
||||
}
|
||||
if (consolefd != -1) {
|
||||
ioctl(consolefd, KIOCSOUND, 0);
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
// FIXME: sound should start at beep_on() and end here
|
||||
if (useBeep) {
|
||||
// FIXME: sound should start at beep_on() and end here
|
||||
DWORD threadID;
|
||||
beep_info.msec = (DWORD)((bx_pc_system.time_usec() - usec_start) / 1000);
|
||||
beep_info.frequency = (DWORD)beep_frequency;
|
||||
CreateThread(NULL, 0, BeepThread, NULL, 0, &threadID);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
} else if (output_mode == BX_SPK_MODE_GUI) {
|
||||
// give the gui a chance to signal beep off
|
||||
bx_gui->beep_off();
|
||||
|
||||
beep_frequency = 0.0;
|
||||
}
|
||||
|
||||
beep_frequency = 0.0;
|
||||
}
|
||||
|
@ -41,12 +41,12 @@ public:
|
||||
private:
|
||||
float beep_frequency; // 0 : beep is off
|
||||
bx_bool outputinit;
|
||||
unsigned output_mode;
|
||||
#ifdef __linux__
|
||||
/* Do we have access? If not, just skip everything else. */
|
||||
signed int consolefd;
|
||||
const static unsigned int clock_tick_rate = 1193180;
|
||||
#elif defined(WIN32)
|
||||
BOOL useBeep;
|
||||
Bit64u usec_start;
|
||||
#endif
|
||||
};
|
||||
|
@ -172,6 +172,7 @@
|
||||
#define BXPN_PNIC_ENABLED "network.pcipnic.enabled"
|
||||
#define BXPN_E1000 "network.e1000"
|
||||
#define BXPN_E1000_ENABLED "network.e1000.enabled"
|
||||
#define BXPN_SOUND_SPEAKER "sound.speaker"
|
||||
#define BXPN_SOUND_SB16 "sound.sb16"
|
||||
#define BXPN_SB16_DMATIMER "sound.sb16.dmatimer"
|
||||
#define BXPN_SB16_LOGLEVEL "sound.sb16.loglevel"
|
||||
|
Loading…
Reference in New Issue
Block a user