Bochs/bochs/iodev/sound/sb16.cc

3200 lines
90 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// 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
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2009-12-04 22:50:29 +03:00
//
/////////////////////////////////////////////////////////////////////////
// The original version of the SB16 support written and donated by Josef Drexler
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
// is used to know when we are exporting symbols and when we are importing.
#define BX_PLUGGABLE
#include "iodev.h"
- apply patch.ifdef-disabled-options. Comments from that patch are below: For a whole lot of configure options, I put #if...#endif around code that is specific to the option, even in files which are normally only compiled when the option is on. This allows me to create a MS Visual C++ 6.0 workspace that supports many of these options. The workspace will basically compile every file all the time, but the code for disabled options will be commented out by the #if...#endif. This may one day lead to simplification of the Makefiles and configure scripts, but for the moment I'm leaving Makefiles and configure scripts alone. Affected options: BX_SUPPORT_APIC (cpu/apic.cc) BX_SUPPORT_X86_64 (cpu/*64.cc) BX_DEBUGGER (debug/*) BX_DISASM (disasm/*) BX_WITH_nameofgui (gui/*) BX_SUPPORT_CDROM (iodev/cdrom.cc) BX_NE2K_SUPPORT (iodev/eth*.cc, iodev/ne2k.cc) BX_SUPPORT_APIC (iodev/ioapic.cc) BX_IODEBUG_SUPPORT (iodev/iodebug.cc) BX_PCI_SUPPORT (iodev/pci*.cc) BX_SUPPORT_SB16 (iodev/sb*.cc) Modified Files: cpu/apic.cc cpu/arith64.cc cpu/ctrl_xfer64.cc cpu/data_xfer64.cc cpu/fetchdecode64.cc cpu/logical64.cc cpu/mult64.cc cpu/resolve64.cc cpu/shift64.cc cpu/stack64.cc debug/Makefile.in debug/crc.cc debug/dbg_main.cc debug/lexer.l debug/linux.cc debug/parser.c debug/parser.y disasm/dis_decode.cc disasm/dis_groups.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/macintosh.cc gui/rfb.cc gui/sdl.cc gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxmain.cc gui/x.cc iodev/cdrom.cc iodev/eth.cc iodev/eth_arpback.cc iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_packetmaker.cc iodev/eth_tap.cc iodev/eth_tuntap.cc iodev/eth_win32.cc iodev/ioapic.cc iodev/iodebug.cc iodev/ne2k.cc iodev/pci.cc iodev/pci2isa.cc iodev/sb16.cc iodev/soundlnx.cc iodev/soundwin.cc
2002-11-19 08:47:45 +03:00
#if BX_SUPPORT_SB16
#include "soundlow.h"
#include "soundmod.h"
#include "sb16.h"
#include "opl.h"
#include <math.h>
#define LOG_THIS theSB16Device->
bx_sb16_c *theSB16Device = NULL;
Bit32u fmopl_callback(void *dev, Bit16u rate, Bit8u *buffer, Bit32u len);
// builtin configuration handling functions
void sb16_init_options(void)
{
static const char *sb16_mode_list[] = {
"0",
"1",
"2",
"3",
NULL
};
bx_param_c *sound = SIM->get_param("sound");
bx_list_c *menu = new bx_list_c(sound, "sb16", "SB16 Configuration");
menu->set_options(menu->SHOW_PARENT);
bx_param_bool_c *enabled = new bx_param_bool_c(menu,
"enabled",
"Enable SB16 emulation",
"Enables the SB16 emulation",
1);
bx_param_enum_c *midimode = new bx_param_enum_c(menu,
"midimode",
"Midi mode",
"Controls the MIDI output switches.",
sb16_mode_list,
0, 0);
bx_param_filename_c *midifile = new bx_param_filename_c(menu,
"midifile",
"MIDI file",
"The filename is where the MIDI data is sent to in mode 2 or 3.",
"", BX_PATHNAME_LEN);
bx_param_enum_c *wavemode = new bx_param_enum_c(menu,
"wavemode",
"Wave mode",
"Controls the wave output switches.",
sb16_mode_list,
0, 0);
bx_param_filename_c *wavefile = new bx_param_filename_c(menu,
"wavefile",
"Wave file",
"This is the file where the wave output is stored",
"", BX_PATHNAME_LEN);
bx_param_num_c *loglevel = new bx_param_num_c(menu,
"loglevel",
"Log level",
"Controls how verbose the SB16 emulation is (0 = no log, 5 = all errors and infos).",
0, 5,
0);
bx_param_filename_c *logfile = new bx_param_filename_c(menu,
"log",
"Log file",
"The file to write the SB16 emulator messages to.",
"", BX_PATHNAME_LEN);
logfile->set_extension("log");
bx_param_num_c *dmatimer = new bx_param_num_c(menu,
"dmatimer",
"DMA timer",
"Microseconds per second for a DMA cycle.",
0, BX_MAX_BIT32U,
0);
bx_list_c *deplist = new bx_list_c(NULL);
deplist->add(midimode);
deplist->add(wavemode);
deplist->add(loglevel);
deplist->add(dmatimer);
enabled->set_dependent_list(deplist);
deplist = new bx_list_c(NULL);
deplist->add(midifile);
midimode->set_dependent_list(deplist, 0);
midimode->set_dependent_bitmap(2, 0x1);
midimode->set_dependent_bitmap(3, 0x1);
deplist = new bx_list_c(NULL);
deplist->add(wavefile);
wavemode->set_dependent_list(deplist, 0);
wavemode->set_dependent_bitmap(2, 0x1);
wavemode->set_dependent_bitmap(3, 0x1);
deplist = new bx_list_c(NULL);
deplist->add(logfile);
loglevel->set_dependent_list(deplist);
loglevel->set_options(loglevel->USE_SPIN_CONTROL);
}
Bit32s sb16_options_parser(const char *context, int num_params, char *params[])
{
if (!strcmp(params[0], "sb16")) {
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16);
int enable = 1;
SIM->get_param_bool("enabled", base)->set(1);
for (int i = 1; i < num_params; i++) {
if (!strncmp(params[i], "enabled=", 8)) {
SIM->get_param_bool("enabled", base)->parse_param(&params[i][8]);
enable = SIM->get_param_bool("enabled", base)->get();
} else if (!strncmp(params[i], "midi=", 5)) {
SIM->get_param_string("midifile", base)->set(&params[i][5]);
} else if (!strncmp(params[i], "wave=", 5)) {
SIM->get_param_string("wavefile", base)->set(&params[i][5]);
} else if (SIM->parse_param_from_list(context, params[i], base) < 0) {
BX_ERROR(("%s: unknown parameter for sb16 ignored.", context));
}
}
if ((enable != 0) && (SIM->get_param_num("dmatimer", base)->get() == 0)) {
SIM->get_param_bool("enabled", base)->set(0);
}
} else {
BX_PANIC(("%s: unknown directive '%s'", context, params[0]));
}
return 0;
}
Bit32s sb16_options_save(FILE *fp)
{
return SIM->write_param_list(fp, (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16), NULL, 0);
}
// device plugin entry points
int CDECL libsb16_LTX_plugin_init(plugin_t *plugin, plugintype_t type)
{
theSB16Device = new bx_sb16_c();
BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theSB16Device, BX_PLUGIN_SB16);
// add new configuration parameter for the config interface
sb16_init_options();
// register add-on option for bochsrc and command line
SIM->register_addon_option("sb16", sb16_options_parser, sb16_options_save);
return(0); // Success
}
void CDECL libsb16_LTX_plugin_fini(void)
{
delete theSB16Device;
SIM->unregister_addon_option("sb16");
((bx_list_c*)SIM->get_param("sound"))->remove("sb16");
}
// some shortcuts to save typing
#define LOGFILE BX_SB16_THIS logfile
#define MPU BX_SB16_THIS mpu401
#define DSP BX_SB16_THIS dsp
#define MIXER BX_SB16_THIS mixer
#define EMUL BX_SB16_THIS emuldata
#define OPL BX_SB16_THIS opl
#define BX_SB16_WAVEOUT1 BX_SB16_THIS waveout[0]
#define BX_SB16_WAVEOUT2 BX_SB16_THIS waveout[1]
#define BX_SB16_WAVEIN BX_SB16_THIS wavein
#define BX_SB16_MIDIOUT1 BX_SB16_THIS midiout[0]
#define BX_SB16_MIDIOUT2 BX_SB16_THIS midiout[1]
// here's a safe way to print out null pointeres
#define MIGHT_BE_NULL(x) ((x==NULL)? "(null)" : x)
// the device object
bx_sb16_c::bx_sb16_c(void)
{
2001-06-27 23:16:01 +04:00
put("SB16");
memset(&mpu401, 0, sizeof(mpu401));
memset(&dsp, 0, sizeof(dsp));
memset(&opl, 0, sizeof(opl));
currentdma8 = 0;
currentdma16 = 0;
mpu401.timer_handle = BX_NULL_TIMER_HANDLE;
dsp.timer_handle = BX_NULL_TIMER_HANDLE;
opl.timer_handle = BX_NULL_TIMER_HANDLE;
waveout[0] = NULL;
waveout[1] = NULL;
wavein = NULL;
midiout[0] = NULL;
midiout[1] = NULL;
wavemode = 0;
midimode = 0;
loglevel = 0;
logfile = NULL;
rt_conf_id = -1;
}
bx_sb16_c::~bx_sb16_c(void)
{
SIM->unregister_runtime_config_handler(rt_conf_id);
closemidioutput();
if (BX_SB16_WAVEOUT1 != NULL) {
BX_SB16_WAVEOUT1->unregister_wave_callback(fmopl_callback_id);
}
closewaveoutput();
delete [] DSP.dma.chunk;
if (LOGFILE != NULL)
fclose(LOGFILE);
SIM->get_bochs_root()->remove("sb16");
bx_list_c *misc_rt = (bx_list_c*)SIM->get_param(BXPN_MENU_RUNTIME_MISC);
misc_rt->remove("sb16");
BX_DEBUG(("Exit"));
}
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
void bx_sb16_c::init(void)
{
unsigned addr, i;
// Read in values from config interface
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16);
// Check if the device is disabled or not configured
if (!SIM->get_param_bool("enabled", base)->get()) {
BX_INFO(("SB16 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;
}
create_logfile();
BX_SB16_THIS midimode = SIM->get_param_enum("midimode", base)->get();
BX_SB16_THIS wavemode = SIM->get_param_enum("wavemode", base)->get();
BX_SB16_THIS dmatimer = SIM->get_param_num("dmatimer", base)->get();
BX_SB16_THIS loglevel = SIM->get_param_num("loglevel", base)->get();
// always initialize lowlevel driver
BX_SB16_WAVEOUT1 = DEV_sound_get_waveout(0);
if (BX_SB16_WAVEOUT1 == NULL) {
BX_PANIC(("Couldn't initialize waveout driver"));
BX_SB16_THIS wavemode &= ~1;
} else {
BX_SB16_THIS fmopl_callback_id = BX_SB16_WAVEOUT1->register_wave_callback(BX_SB16_THISP, fmopl_callback);
}
if (BX_SB16_THIS wavemode & 2) {
BX_SB16_WAVEOUT2 = DEV_sound_get_waveout(1);
if (BX_SB16_WAVEOUT2 == NULL) {
BX_PANIC(("Couldn't initialize wave file driver"));
}
}
BX_SB16_WAVEIN = DEV_sound_get_wavein();
if (BX_SB16_WAVEIN == NULL) {
BX_PANIC(("Couldn't initialize wavein driver"));
}
BX_SB16_MIDIOUT1 = DEV_sound_get_midiout(0);
if (BX_SB16_MIDIOUT1 == NULL) {
BX_PANIC(("Couldn't initialize midiout driver"));
}
if (BX_SB16_THIS midimode & 2) {
BX_SB16_MIDIOUT2 = DEV_sound_get_midiout(1);
if (BX_SB16_MIDIOUT2 == NULL) {
BX_PANIC(("Couldn't initialize midi file driver"));
}
}
DSP.dma.chunk = new Bit8u[BX_SOUNDLOW_WAVEPACKETSIZE];
DSP.dma.chunkindex = 0;
DSP.outputinit = (BX_SB16_THIS wavemode & 1);
DSP.inputinit = 0;
MPU.outputinit = 0;
if (DSP.dma.chunk == NULL)
{
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(2), "Couldn't allocate wave buffer - wave output disabled.");
BX_SB16_THIS wavemode = 0;
}
BX_INFO(("midi=%d,'%s' wave=%d,'%s' log=%d,'%s' dmatimer=%d",
BX_SB16_THIS midimode, MIGHT_BE_NULL(SIM->get_param_string("midifile", base)->getptr()),
BX_SB16_THIS wavemode, MIGHT_BE_NULL(SIM->get_param_string("wavefile", base)->getptr()),
BX_SB16_THIS loglevel, MIGHT_BE_NULL(SIM->get_param_string("log", base)->getptr()),
BX_SB16_THIS dmatimer));
// allocate the FIFO buffers - except for the MPUMIDICMD buffer
// these sizes are generous, 16 or 8 would probably be sufficient
MPU.datain.init((int) 64); // the input
MPU.dataout.init((int) 64); // and output
MPU.cmd.init((int) 64); // and command buffers
MPU.midicmd.init((int) 256); // and the midi command buffer (note- large SYSEX'es have to fit!)
DSP.datain.init((int) 64); // the DSP input
DSP.dataout.init((int) 64); // and output buffers
EMUL.datain.init((int) 64); // the emulator ports
EMUL.dataout.init((int) 64); // for changing emulator settings
// reset all parts of the hardware by
// triggering their reset functions
// reset the Emulator port
emul_write(0x00);
// reset the MPU401
mpu_command(0xff);
MPU.last_delta_time = 0xffffffff;
// reset the DSP
DSP.dma.highspeed = 0;
DSP.dma.mode = 0;
DSP.irqpending = 0;
DSP.midiuartmode = 0;
DSP.nondma_mode = 0;
DSP.nondma_count = 0;
DSP.samplebyte = 0;
DSP.resetport = 1; // so that one call to dsp_reset is sufficient
dsp_reset(0); // (reset is 1 to 0 transition)
DSP.testreg = 0;
BX_SB16_IRQ = -1; // will be initialized later by the mixer reset
for (i=0; i<BX_SB16_MIX_REG; i++)
MIXER.reg[i] = 0xff;
MIXER.reg[0x00] = 0; // reset register
MIXER.reg[0x80] = 2; // IRQ 5
MIXER.reg[0x81] = 2; // 8-bit DMA 1, no 16-bit DMA
MIXER.reg[0x82] = 2 << 5; // no IRQ pending
MIXER.reg[0xfd] = 16; // ???
MIXER.reg[0xfe] = 6; // ???
set_irq_dma(); // set the IRQ and DMA
// call the mixer reset
mixer_writeregister(0x00);
mixer_writedata(0x00);
// reset the FM emulation
OPL.timer_running = 0;
for (i=0; i<2; i++) {
OPL.tmask[i] = 0;
OPL.tflag[i] = 0;
}
for (i=0; i<4; i++) {
OPL.timer[i] = 0;
OPL.timerinit[i] = 0;
}
adlib_init(44100);
// csp
memset(&BX_SB16_THIS csp_reg[0], 0, sizeof(BX_SB16_THIS csp_reg));
BX_SB16_THIS csp_reg[5] = 0x01;
BX_SB16_THIS csp_reg[9] = 0xf8;
// Allocate the IO addresses, 2x0..2xf, 3x0..3x4 and 388..38b
for (addr=BX_SB16_IO; addr<BX_SB16_IO+BX_SB16_IOLEN; addr++) {
2006-05-06 19:19:57 +04:00
DEV_register_ioread_handler(this, &read_handler, addr, "SB16", 1);
DEV_register_iowrite_handler(this, &write_handler, addr, "SB16", 1);
}
for (addr=BX_SB16_IOMPU; addr<BX_SB16_IOMPU+BX_SB16_IOMPULEN; addr++) {
2006-05-06 19:19:57 +04:00
DEV_register_ioread_handler(this, &read_handler, addr, "SB16", 1);
DEV_register_iowrite_handler(this, &write_handler, addr, "SB16", 1);
}
for (addr=BX_SB16_IOADLIB; addr<BX_SB16_IOADLIB+BX_SB16_IOADLIBLEN; addr++) {
2006-05-06 19:19:57 +04:00
DEV_register_ioread_handler(this, read_handler, addr, "SB16", 1);
DEV_register_iowrite_handler(this, write_handler, addr, "SB16", 1);
}
writelog(BOTHLOG(1),
2006-05-06 19:19:57 +04:00
"SB16 emulation initialised, IRQ %d, IO %03x/%03x/%03x, DMA %d/%d",
BX_SB16_IRQ, BX_SB16_IO, BX_SB16_IOMPU, BX_SB16_IOADLIB,
BX_SB16_DMAL, BX_SB16_DMAH);
// initialize the timers
if (MPU.timer_handle == BX_NULL_TIMER_HANDLE) {
MPU.timer_handle = DEV_register_timer
(BX_SB16_THISP, mpu_timer, 500000 / 384, 1, 1, "sb16.mpu");
// midi timer: active, continuous, 500000 / 384 seconds (384 = delta time, 500000 = sec per beat at 120 bpm. Don't change this!)
}
if (DSP.timer_handle == BX_NULL_TIMER_HANDLE) {
DSP.timer_handle = DEV_register_timer
(BX_SB16_THISP, dsp_dmatimer, 1, 1, 0, "sb16.dsp");
// dma timer: inactive, continuous, frequency variable
}
if (OPL.timer_handle == BX_NULL_TIMER_HANDLE) {
OPL.timer_handle = DEV_register_timer
(BX_SB16_THISP, opl_timer, 80, 1, 0, "sb16.opl");
// opl timer: inactive, continuous, frequency 80us
}
writelog(MIDILOG(4), "Timers initialized, midi %d, dma %d, opl %d",
MPU.timer_handle, DSP.timer_handle, OPL.timer_handle);
MPU.current_timer = 0;
// init runtime parameters
bx_list_c *misc_rt = (bx_list_c*)SIM->get_param(BXPN_MENU_RUNTIME_MISC);
bx_list_c *menu = new bx_list_c(misc_rt, "sb16", "SB16 Runtime Options");
menu->set_options(menu->SHOW_PARENT | menu->USE_BOX_TITLE);
menu->add(SIM->get_param("midimode", base));
menu->add(SIM->get_param("midifile", base));
menu->add(SIM->get_param("wavemode", base));
menu->add(SIM->get_param("wavefile", base));
menu->add(SIM->get_param("loglevel", base));
menu->add(SIM->get_param("log", base));
menu->add(SIM->get_param("dmatimer", base));
SIM->get_param_enum("wavemode", base)->set_handler(sb16_param_handler);
SIM->get_param_string("wavefile", base)->set_handler(sb16_param_string_handler);
SIM->get_param_num("midimode", base)->set_handler(sb16_param_handler);
SIM->get_param_string("midifile", base)->set_handler(sb16_param_string_handler);
SIM->get_param_num("dmatimer", base)->set_handler(sb16_param_handler);
SIM->get_param_num("loglevel", base)->set_handler(sb16_param_handler);
SIM->get_param_string("log", base)->set_handler(sb16_param_string_handler);
// register handler for correct sb16 parameter handling after runtime config
BX_SB16_THIS rt_conf_id = SIM->register_runtime_config_handler(this, runtime_config_handler);
BX_SB16_THIS midi_changed = 0;
BX_SB16_THIS wave_changed = 0;
}
void bx_sb16_c::reset(unsigned type)
{
}
2006-05-27 19:54:49 +04:00
void bx_sb16_c::register_state(void)
{
unsigned i;
2006-05-27 19:54:49 +04:00
char name[8];
bx_list_c *chip, *ins_map, *patch;
2006-05-27 19:54:49 +04:00
bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "sb16", "SB16 State");
bx_list_c *mpu = new bx_list_c(list, "mpu");
2006-05-27 19:54:49 +04:00
new bx_shadow_bool_c(mpu, "uartmode", &MPU.uartmode);
new bx_shadow_bool_c(mpu, "irqpending", &MPU.irqpending);
new bx_shadow_bool_c(mpu, "forceuartmode", &MPU.forceuartmode);
new bx_shadow_bool_c(mpu, "singlecommand", &MPU.singlecommand);
new bx_shadow_num_c(mpu, "current_timer", &MPU.current_timer);
new bx_shadow_num_c(mpu, "last_delta_time", &MPU.last_delta_time);
bx_list_c *patchtbl = new bx_list_c(mpu, "patchtable");
for (i=0; i<16; i++) {
2006-05-27 19:54:49 +04:00
sprintf(name, "0x%02x", i);
patch = new bx_list_c(patchtbl, name);
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(patch, "banklsb", &MPU.banklsb[i]);
new bx_shadow_num_c(patch, "bankmsb", &MPU.bankmsb[i]);
new bx_shadow_num_c(patch, "program", &MPU.program[i]);
}
bx_list_c *dsp = new bx_list_c(list, "dsp");
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(dsp, "resetport", &DSP.resetport, BASE_HEX);
new bx_shadow_num_c(dsp, "speaker", &DSP.speaker, BASE_HEX);
new bx_shadow_num_c(dsp, "prostereo", &DSP.prostereo, BASE_HEX);
new bx_shadow_bool_c(dsp, "irqpending", &DSP.irqpending);
new bx_shadow_bool_c(dsp, "midiuartmode", &DSP.midiuartmode);
new bx_shadow_bool_c(dsp, "nondma_mode", &DSP.nondma_mode);
new bx_shadow_num_c(dsp, "nondma_count", &DSP.nondma_count);
new bx_shadow_num_c(dsp, "samplebyte", &DSP.samplebyte, BASE_HEX);
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(dsp, "testreg", &DSP.testreg, BASE_HEX);
bx_list_c *dma = new bx_list_c(dsp, "dma");
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(dma, "mode", &DSP.dma.mode);
new bx_shadow_num_c(dma, "bps", &DSP.dma.bps);
new bx_shadow_num_c(dma, "timer", &DSP.dma.timer);
new bx_shadow_bool_c(dma, "fifo", &DSP.dma.fifo);
new bx_shadow_bool_c(dma, "output", &DSP.dma.output);
new bx_shadow_bool_c(dma, "highspeed", &DSP.dma.highspeed);
new bx_shadow_num_c(dma, "count", &DSP.dma.count);
new bx_shadow_num_c(dma, "chunkindex", &DSP.dma.chunkindex);
new bx_shadow_num_c(dma, "chunkcount", &DSP.dma.chunkcount);
new bx_shadow_num_c(dma, "timeconstant", &DSP.dma.timeconstant);
new bx_shadow_num_c(dma, "blocklength", &DSP.dma.blocklength);
new bx_shadow_num_c(dma, "samplerate", &DSP.dma.param.samplerate);
new bx_shadow_num_c(dma, "bits", &DSP.dma.param.bits);
new bx_shadow_num_c(dma, "channels", &DSP.dma.param.channels);
new bx_shadow_num_c(dma, "format", &DSP.dma.param.format);
new bx_shadow_num_c(dma, "volume", &DSP.dma.param.volume);
new bx_shadow_num_c(list, "fm_volume", &fm_volume);
new bx_shadow_data_c(list, "chunk", DSP.dma.chunk, BX_SOUNDLOW_WAVEPACKETSIZE);
new bx_shadow_data_c(list, "csp_reg", BX_SB16_THIS csp_reg, 256, 1);
bx_list_c *opl = new bx_list_c(list, "opl");
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(opl, "timer_running", &OPL.timer_running);
for (i=0; i<2; i++) {
sprintf(name, "chip%d", i+1);
chip = new bx_list_c(opl, name);
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(chip, "index", &OPL.index[i]);
new bx_shadow_num_c(chip, "timer1", &OPL.timer[i*2]);
new bx_shadow_num_c(chip, "timer2", &OPL.timer[i*2+1]);
new bx_shadow_num_c(chip, "timerinit1", &OPL.timerinit[i*2]);
new bx_shadow_num_c(chip, "timerinit2", &OPL.timerinit[i*2+1]);
new bx_shadow_num_c(chip, "tmask", &OPL.tmask[i]);
new bx_shadow_num_c(chip, "tflag", &OPL.tflag[i]);
}
new bx_shadow_num_c(list, "mixer_regindex", &MIXER.regindex, BASE_HEX);
new bx_shadow_data_c(list, "mixer_reg", MIXER.reg, BX_SB16_MIX_REG, 1);
bx_list_c *emul = new bx_list_c(list, "emul");
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(emul, "remaps", &EMUL.remaps);
bx_list_c *remap = new bx_list_c(emul, "remaplist");
for (i=0; i<BX_SB16_MAX_REMAPS; i++) {
2006-05-27 19:54:49 +04:00
sprintf(name, "0x%02x", i);
ins_map = new bx_list_c(remap, name);
2006-05-27 19:54:49 +04:00
new bx_shadow_num_c(ins_map, "oldbankmsb", &EMUL.remaplist[i].oldbankmsb);
new bx_shadow_num_c(ins_map, "oldbanklsb", &EMUL.remaplist[i].oldbanklsb);
new bx_shadow_num_c(ins_map, "oldprogch", &EMUL.remaplist[i].oldprogch);
new bx_shadow_num_c(ins_map, "newbankmsb", &EMUL.remaplist[i].newbankmsb);
new bx_shadow_num_c(ins_map, "newbanklsb", &EMUL.remaplist[i].newbanklsb);
new bx_shadow_num_c(ins_map, "newprogch", &EMUL.remaplist[i].newprogch);
}
adlib_register_state(list);
2006-05-27 19:54:49 +04:00
}
void bx_sb16_c::after_restore_state(void)
{
set_irq_dma();
adlib_after_restore_state();
2006-05-27 19:54:49 +04:00
}
void bx_sb16_c::runtime_config_handler(void *this_ptr)
{
bx_sb16_c *class_ptr = (bx_sb16_c *) this_ptr;
class_ptr->runtime_config();
}
void bx_sb16_c::runtime_config(void)
{
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16);
if (BX_SB16_THIS midi_changed != 0) {
BX_SB16_THIS closemidioutput();
if (BX_SB16_THIS midi_changed & 1) {
BX_SB16_THIS midimode = SIM->get_param_num("midimode", base)->get();
if (BX_SB16_THIS midimode & 2) {
BX_SB16_MIDIOUT2 = DEV_sound_get_midiout(1);
if (BX_SB16_MIDIOUT2 == NULL) {
BX_PANIC(("Couldn't initialize midi file driver"));
}
}
}
// writemidicommand() re-opens the output device / file on demand
BX_SB16_THIS midi_changed = 0;
}
if (BX_SB16_THIS wave_changed != 0) {
if (BX_SB16_THIS wavemode & 2) {
BX_SB16_THIS closewaveoutput();
}
if (BX_SB16_THIS wave_changed & 1) {
BX_SB16_THIS wavemode = SIM->get_param_enum("wavemode", base)->get();
DSP.outputinit = (BX_SB16_THIS wavemode & 1);
if (BX_SB16_THIS wavemode & 2) {
BX_SB16_WAVEOUT2 = DEV_sound_get_waveout(1);
if (BX_SB16_WAVEOUT2 == NULL) {
BX_PANIC(("Couldn't initialize wave file driver"));
}
}
}
// dsp_dma() re-opens the output file on demand
BX_SB16_THIS wave_changed = 0;
}
}
// the timer functions
2006-05-27 19:54:49 +04:00
void bx_sb16_c::mpu_timer (void *this_ptr)
{
((bx_sb16_c *) this_ptr)->mpu401.current_timer++;
}
2006-05-06 19:19:57 +04:00
void bx_sb16_c::dsp_dmatimer(void *this_ptr)
{
bx_sb16_c *This = (bx_sb16_c *) this_ptr;
// raise the DRQ line. It is then lowered by the dma read / write functions
// when the next byte has been sent / received.
// However, don't do this if the next byte/word will fill up the
// output buffer and the output functions are not ready yet
// or if buffer is empty in input mode.
if (!This->dsp.nondma_mode) {
if ((This->dsp.dma.chunkindex + 1 < BX_SOUNDLOW_WAVEPACKETSIZE) &&
(This->dsp.dma.count > 0)) {
if (((This->dsp.dma.output == 0) && (This->dsp.dma.chunkcount > 0)) ||
(This->dsp.dma.output == 1)) {
if ((DSP.dma.param.bits == 8) || (BX_SB16_DMAH == 0)) {
DEV_dma_set_drq(BX_SB16_DMAL, 1);
} else {
DEV_dma_set_drq(BX_SB16_DMAH, 1);
}
}
}
} else {
dsp_getsamplebyte(0);
dsp_getsamplebyte(This->dsp.samplebyte);
dsp_getsamplebyte(0);
dsp_getsamplebyte(This->dsp.samplebyte);
This->dsp.nondma_count++;
}
}
void bx_sb16_c::opl_timer (void *this_ptr)
{
((bx_sb16_c *) this_ptr)->opl_timerevent();
}
// the various IO handlers
// The DSP/FM music part
// dsp_reset() resets the DSP after the sequence 1/0. Returns
// 0xaa on the data port
void bx_sb16_c::dsp_reset(Bit32u value)
{
writelog(WAVELOG(4), "DSP Reset port write value %x", value);
dsp_disable_nondma();
// just abort high speed mode if it is set
if (DSP.dma.highspeed != 0)
2006-05-06 19:19:57 +04:00
{
DSP.dma.highspeed = 0;
writelog(WAVELOG(4), "High speed mode aborted");
return;
2006-05-06 19:19:57 +04:00
}
2006-05-06 19:19:57 +04:00
if ((DSP.resetport == 1) && (value == 0))
{
// 1-0 sequences to reset port, do one of the following:
// if in UART MIDI mode, abort it, don't reset
// if in Highspeed mode (not SB16!), abort it, don't reset
// otherwise reset
if (DSP.midiuartmode != 0)
2006-05-06 19:19:57 +04:00
{ // abort UART MIDI mode
DSP.midiuartmode = 0;
writelog(MIDILOG(4), "DSP UART MIDI mode aborted");
return;
}
// do the reset
writelog(WAVELOG(4), "DSP resetting...");
if (DSP.irqpending != 0)
2006-05-06 19:19:57 +04:00
{
DEV_pic_lower_irq(BX_SB16_IRQ);
writelog(WAVELOG(4), "DSP reset: IRQ untriggered");
}
if (DSP.dma.mode != 0)
2006-05-06 19:19:57 +04:00
{
writelog(WAVELOG(4), "DSP reset: DMA aborted");
DSP.dma.mode = 1; // no auto init anymore
dsp_dmadone();
}
DSP.resetport = 0;
DSP.speaker = 0;
DSP.irqpending = 0;
DSP.midiuartmode = 0;
DSP.prostereo = 0;
DSP.dma.mode = 0;
DSP.dma.fifo = 0;
DSP.dma.output = 0;
DSP.dma.param.channels = 1;
DSP.dma.count = 0;
DSP.dma.highspeed = 0;
DSP.dma.chunkindex = 0;
DSP.dataout.reset(); // clear the buffers
DSP.datain.reset();
DSP.dataout.put(0xaa); // acknowledge the reset
2006-05-06 19:19:57 +04:00
}
else
DSP.resetport = value;
}
// dsp_dataread() reads the data port of the DSP
Bit32u bx_sb16_c::dsp_dataread()
{
Bit8u value = 0xff;
// if we are in MIDI UART mode, call the mpu401 part instead
if (DSP.midiuartmode != 0)
value = mpu_dataread();
else
2006-05-06 19:19:57 +04:00
{
// default behaviour: if none available, return last byte again
// if (DSP.dataout.empty() == 0)
DSP.dataout.get(&value);
}
writelog(WAVELOG(4), "DSP Data port read, result = %x", value);
return(value);
}
// dsp_datawrite() writes a command or data byte to the data port
void bx_sb16_c::dsp_datawrite(Bit32u value)
{
int bytesneeded;
2007-04-08 19:02:50 +04:00
Bit8u index = 0, mode = 0, value8 = 0;
Bit16u length = 0;
writelog(WAVELOG(4), "DSP Data port write, value %x", value);
// in high speed mode, any data passed to DSP is a sample
if (DSP.dma.highspeed != 0)
2006-05-06 19:19:57 +04:00
{
dsp_getsamplebyte(value);
return;
}
// route information to mpu401 part if in MIDI UART mode
if (DSP.midiuartmode != 0)
2006-05-06 19:19:57 +04:00
{
mpu_datawrite(value);
return;
}
if (DSP.datain.hascommand() == 1) // already a command pending, add to argument list
2006-05-06 19:19:57 +04:00
{
if (DSP.datain.put(value) == 0)
{
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(3), "DSP command buffer overflow for command %02x",
DSP.datain.currentcommand());
}
2006-05-06 19:19:57 +04:00
}
else // no command pending, set one up
{
bytesneeded = 0; // find out how many arguments the command takes
switch (value)
{ // all fallbacks intended!
case 0x04:
case 0x0f:
case 0x10:
case 0x40:
case 0x38:
case 0xe0:
case 0xe2:
2006-05-06 19:19:57 +04:00
case 0xe4:
case 0xf9:
bytesneeded = 1;
break;
case 0x05:
case 0x0e:
case 0x14:
case 0x16:
case 0x17:
case 0x41:
case 0x42:
case 0x48:
case 0x74:
case 0x75:
case 0x76:
case 0x77:
case 0x80:
bytesneeded = 2;
break;
// 0xb0 ... 0xbf:
2006-05-06 19:19:57 +04:00
case 0xb0:
case 0xb1:
case 0xb2:
case 0xb3:
case 0xb4:
case 0xb5:
case 0xb6:
case 0xb7:
case 0xb8:
case 0xb9:
case 0xba:
case 0xbb:
case 0xbc:
case 0xbd:
case 0xbe:
case 0xbf:
// 0xc0 ... 0xcf:
2006-05-06 19:19:57 +04:00
case 0xc0:
case 0xc1:
case 0xc2:
case 0xc3:
case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
case 0xc8:
case 0xc9:
case 0xca:
case 0xcb:
case 0xcc:
case 0xcd:
case 0xce:
case 0xcf:
bytesneeded = 3;
break;
}
DSP.datain.newcommand(value, bytesneeded);
}
if (DSP.datain.commanddone() == 1) // command is complete, process it
2006-05-06 19:19:57 +04:00
{
writelog(WAVELOG(4), "DSP command %x with %d arg bytes",
2006-05-06 19:19:57 +04:00
DSP.datain.currentcommand(), DSP.datain.bytes());
switch (DSP.datain.currentcommand())
2006-05-06 19:19:57 +04:00
{
// DSP commands - comments are the parameters for
// this command, and/or the output
// ASP commands (Advanced Signal Processor)
// undocumented (?), just from looking what an SB16 does
case 0x04:
DSP.datain.get(&value8);
break;
case 0x05:
DSP.datain.get(&value8);
DSP.datain.get(&value8);
break;
case 0x0e:
DSP.datain.get(&index);
DSP.datain.get(&value8);
BX_SB16_THIS csp_reg[index] = value;
break;
case 0x0f:
DSP.datain.get(&index);
DSP.dataout.put(BX_SB16_THIS csp_reg[index]);
break;
// direct mode DAC
case 0x10:
// 1: 8bit sample
if (!DSP.nondma_mode) {
DSP.dma.param.samplerate = 22050;
DSP.dma.param.bits = 16;
DSP.dma.param.channels = 2;
DSP.dma.param.format = 1;
DSP.dma.chunkcount = 8820;
DSP.dma.chunkindex = 0;
bx_pc_system.activate_timer(DSP.timer_handle, 45, 1);
DSP.nondma_mode = 1;
DSP.nondma_count = 0;
}
DSP.datain.get(&DSP.samplebyte);
2006-05-06 19:19:57 +04:00
break;
// uncomp'd, normal DAC DMA
case 0x14:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc0, 0x00, length, 0);
break;
// 2-bit comp'd, normal DAC DMA, no ref byte
case 0x16:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc0, 0x00, length, 2);
break;
// 2-bit comp'd, normal DAC DMA, 1 ref byte
case 0x17:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc0, 0x00, length, 2|8);
break;
// uncomp'd, auto DAC DMA
case 0x1c:
// none
dsp_dma(0xc4, 0x00, DSP.dma.blocklength, 0);
break;
// 2-bit comp'd, auto DAC DMA, 1 ref byte
case 0x1f:
// none
dsp_dma(0xc4, 0x00, DSP.dma.blocklength, 2|8);
break;
// direct mode ADC
case 0x20:
// o1: 8bit sample
DSP.dataout.put(0x80); // put a silence, for now.
break;
// uncomp'd, normal ADC DMA
case 0x24:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc8, 0x00, length, 0);
break;
// uncomp'd, auto ADC DMA
case 0x2c:
// none
dsp_dma(0xcc, 0x00, DSP.dma.blocklength, 0);
break;
// ? polling mode MIDI input
case 0x30:
break;
// ? interrupt mode MIDI input
case 0x31:
break;
// 0x34..0x37: UART mode MIDI output
case 0x34:
// UART mode MIDI input/output
case 0x35:
// UART polling mode MIDI IO with time stamp
case 0x36:
// UART interrupt mode MIDI IO with time stamp
case 0x37:
// Fallbacks intended - all set the midi uart mode
DSP.midiuartmode = 1;
break;
// MIDI output
case 0x38:
DSP.datain.get(&value8);
// route to mpu401 part
mpu_datawrite(value8);
break;
// set time constant
case 0x40:
// 1: timeconstant
DSP.datain.get(&value8);
DSP.dma.timeconstant = value8 << 8;
DSP.dma.param.samplerate = (Bit32u) 256000000L / ((Bit32u) 65536L - (Bit32u) DSP.dma.timeconstant);
2006-05-06 19:19:57 +04:00
break;
// set samplerate for input
case 0x41:
// (fallback intended)
// set samplerate for output
case 0x42:
// 1,2: hi(frq) lo(frq)
DSP.datain.getw1(&(DSP.dma.param.samplerate));
DSP.dma.timeconstant = 65536 - (Bit32u) 256000000 / (Bit32u) DSP.dma.param.samplerate;
2006-05-06 19:19:57 +04:00
break;
// set block length
case 0x48:
// 1,2: lo(blk len) hi(blk len)
DSP.datain.getw(&(DSP.dma.blocklength));
2006-05-06 19:19:57 +04:00
break;
// 4-bit comp'd, normal DAC DMA, no ref byte
case 0x74:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc0, 0x00, length, 4);
break;
// 4-bit comp'd, normal DAC DMA, 1 ref byte
case 0x75:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc0, 0x00, length, 4|8);
break;
// 3-bit comp'd, normal DAC DMA, no ref byte
case 0x76:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc0, 0x00, length, 3);
break;
// 3-bit comp'd, normal DAC DMA, 1 ref byte
case 0x77:
// 1,2: lo(length) hi(length)
DSP.datain.getw(&length);
dsp_dma(0xc0, 0x00, length, 3|8);
break;
// 4-bit comp'd, auto DAC DMA, 1 ref byte
case 0x7d:
// none
dsp_dma(0xc4, 0x00, DSP.dma.blocklength, 4|8);
break;
// 3-bit comp'd, auto DAC DMA, 1 ref byte
case 0x7f:
// none
dsp_dma(0xc4, 0x00, DSP.dma.blocklength, 3|8);
break;
// silence period
case 0x80:
// 1,2: lo(silence) hi(silence) (len in samples)
DSP.datain.getw(&length);
// TODO
2006-05-06 19:19:57 +04:00
break;
// 8-bit auto DAC DMA, highspeed
case 0x90:
//none
dsp_dma(0xc4, 0x00, DSP.dma.blocklength, 16);
break;
// 8-bit normal DAC DMA, highspeed
case 0x91:
//none
dsp_dma(0xc0, 0x00, DSP.dma.blocklength, 16);
break;
// 8-bit auto ADC DMA, highspeed
case 0x98:
//none
dsp_dma(0xcc, 0x00, DSP.dma.blocklength, 16);
break;
case 0x99: // 8-bit normal DMA
//none
dsp_dma(0xc8, 0x00, DSP.dma.blocklength, 16);
break;
// switch to mono for SBPro DAC/ADC
case 0xa0:
// none
DSP.prostereo = 1;
break;
// switch to stereo for SBPro DAC/ADC
case 0xa8:
//// none
DSP.prostereo = 2;
break;
// 0xb0 ... 0xbf:
// 16 bit DAC/ADC DMA, general commands
// fallback intended
case 0xb0:
case 0xb1:
case 0xb2:
case 0xb3:
case 0xb4:
case 0xb5:
case 0xb6:
case 0xb7:
case 0xb8:
case 0xb9:
case 0xba:
case 0xbb:
case 0xbc:
case 0xbd:
case 0xbe:
case 0xbf:
// 0xc0 ... 0xcf:
// 8 bit DAC/ADC DMA, general commands
case 0xc0:
case 0xc1:
case 0xc2:
case 0xc3:
case 0xc4:
case 0xc5:
case 0xc6:
case 0xc7:
case 0xc8:
case 0xc9:
case 0xca:
case 0xcb:
case 0xcc:
case 0xcd:
case 0xce:
case 0xcf:
2006-05-06 19:19:57 +04:00
DSP.datain.get(&mode);
DSP.datain.getw(&length);
dsp_dma(DSP.datain.currentcommand(), mode, length, 0);
break;
// pause 8 bit DMA transfer
case 0xd0:
// none
if (DSP.dma.mode != 0)
dsp_disabledma();
break;
// speaker on
case 0xd1:
// none
DSP.speaker = 1;
break;
// speaker off
case 0xd3:
// none
DSP.speaker = 0;
break;
// continue 8 bit DMA, see 0xd0
case 0xd4:
// none
if (DSP.dma.mode != 0)
dsp_enabledma();
break;
// pause 16 bit DMA
case 0xd5:
// none
if (DSP.dma.mode != 0)
dsp_disabledma();
break;
// continue 16 bit DMA, see 0xd5
case 0xd6:
// none
if (DSP.dma.mode != 0)
dsp_enabledma();
break;
// read speaker on/off (out ff=on, 00=off)
case 0xd8:
// none, o1: speaker; ff/00
DSP.dataout.put((DSP.speaker == 1)?0xff:0x00);
2006-05-06 19:19:57 +04:00
break;
// stop 16 bit auto DMA
case 0xd9:
// none
if (DSP.dma.mode != 0)
{
DSP.dma.mode = 1; // no auto init anymore
dsp_dmadone();
}
break;
// stop 8 bit auto DMA
case 0xda:
// none
if (DSP.dma.mode != 0)
{
DSP.dma.mode = 1; // no auto init anymore
dsp_dmadone();
}
break;
// DSP identification
case 0xe0:
DSP.datain.get(&value8);
DSP.dataout.put(~value8);
break;
// get version, out 2 bytes (major, minor)
case 0xe1:
// none, o1/2: version major.minor
DSP.dataout.put(4);
if (DSP.dataout.put(5) == 0)
2006-05-06 19:19:57 +04:00
{
writelog(WAVELOG(3), "DSP version couldn't be written - buffer overflow");
}
break;
case 0xe2:
DSP.datain.get(&value8);
// TODO
writelog(WAVELOG(3), "undocumented DSP command %x ignored (value = 0x%02x)",
DSP.datain.currentcommand(), value8);
break;
2006-05-06 19:19:57 +04:00
case 0xe3:
// none, output: Copyright string
// the Windows driver needs the exact text, otherwise it
// won't load. Same for diagnose.exe
DSP.dataout.puts("COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.");
DSP.dataout.put(0); // need extra string end
break;
// write test register
case 0xe4:
2006-05-06 19:19:57 +04:00
DSP.datain.get(&DSP.testreg);
break;
// read test register
case 0xe8:
2006-05-06 19:19:57 +04:00
DSP.dataout.put(DSP.testreg);
break;
// Trigger 8-bit IRQ
case 0xf2:
DSP.dataout.put(0xaa);
DSP.irqpending = 1;
MIXER.reg[0x82] |= 1; // reg 82 shows the kind of IRQ
DEV_pic_raise_irq(BX_SB16_IRQ);
break;
// ??? - Win98 needs this
case 0xf9:
DSP.datain.get(&value8);
switch (value8) {
case 0x0e:
DSP.dataout.put(0xff);
break;
case 0x0f:
DSP.dataout.put(0x07);
break;
case 0x37:
DSP.dataout.put(0x38);
break;
default:
DSP.dataout.put(0x00);
}
break;
2006-05-06 19:19:57 +04:00
// unknown command
default:
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(3), "unknown DSP command %x, ignored",
DSP.datain.currentcommand());
break;
}
DSP.datain.clearcommand();
DSP.datain.flush();
2006-05-06 19:19:57 +04:00
}
}
// dsp_dma() initiates all kinds of dma transfers
void bx_sb16_c::dsp_dma(Bit8u command, Bit8u mode, Bit16u length, Bit8u comp)
{
int ret;
bx_list_c *base;
bx_bool issigned;
// command: 8bit, 16bit, in/out, single/auto, fifo
// mode: mono/stereo, signed/unsigned
// (for info on command and mode see sound blaster programmer's manual,
// cmds bx and cx)
// length: number of samples - not number of bytes
// comp: bit-coded are: type of compression; ref-byte; highspeed
// D0..D2: 0=none, 2,3,4 bits ADPCM
// D3: ref-byte
// D6: highspeed
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(4), "DMA initialized. Cmd %02x, mode %02x, length %d, comp %d",
command, mode, length, comp);
dsp_disable_nondma();
if ((command >> 4) == 0xb) // 0xb? = 16 bit DMA
2006-05-06 19:19:57 +04:00
{
DSP.dma.param.bits = 16;
DSP.dma.bps = 2;
2006-05-06 19:19:57 +04:00
}
else // 0xc? = 8 bit DMA
2006-05-06 19:19:57 +04:00
{
DSP.dma.param.bits = 8;
DSP.dma.bps = 1;
2006-05-06 19:19:57 +04:00
}
// Prevent division by zero in some instances
if (DSP.dma.param.samplerate == 0)
DSP.dma.param.samplerate = 10752;
command &= 0x0f;
DSP.dma.output = 1 - (command >> 3); // 1=output, 0=input
DSP.dma.mode = 1 + ((command >> 2) & 1); // 0=none, 1=normal, 2=auto
DSP.dma.fifo = (command >> 1) & 1; // ? not sure what this is
DSP.dma.param.channels = ((mode >> 5) & 1) + 1;
if (DSP.dma.param.channels == 2)
DSP.dma.bps *= 2;
DSP.dma.blocklength = length;
issigned = (mode >> 4) & 1;
DSP.dma.highspeed = (comp >> 4) & 1;
DSP.dma.chunkindex = 0;
DSP.dma.chunkcount = 0;
Bit32u sampledatarate = (Bit32u) DSP.dma.param.samplerate * (Bit32u) DSP.dma.bps;
if (DSP.dma.param.bits == 8 || (DSP.dma.param.bits == 16 && BX_SB16_DMAH != 0)) {
DSP.dma.count = DSP.dma.blocklength;
} else {
DSP.dma.count = ((DSP.dma.blocklength + 1) << 1) - 1;
}
DSP.dma.timer = BX_SB16_THIS dmatimer * BX_DMA_BUFFER_SIZE / sampledatarate;
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(5), "DMA is %db, %dHz, %s, %s, mode %d, %s, %s, %d bps, %d usec/DMA",
DSP.dma.param.bits, DSP.dma.param.samplerate,
(DSP.dma.param.channels == 2)?"stereo":"mono",
2006-05-06 19:19:57 +04:00
(DSP.dma.output == 1)?"output":"input", DSP.dma.mode,
(issigned == 1)?"signed":"unsigned",
2006-05-06 19:19:57 +04:00
(DSP.dma.highspeed == 1)?"highspeed":"normal speed",
sampledatarate, DSP.dma.timer);
DSP.dma.param.format = issigned | ((comp & 7) << 1) | ((comp & 8) << 4);
// write the output to the device/file
if (DSP.dma.output == 1) {
if (BX_SB16_THIS wavemode & 2) {
if ((DSP.outputinit & 2) == 0) {
base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16);
bx_param_string_c *waveparam = SIM->get_param_string("wavefile", base);
if (BX_SB16_WAVEOUT2->openwaveoutput(waveparam->getptr()) == BX_SOUNDLOW_OK)
DSP.outputinit |= 2;
else
DSP.outputinit &= ~2;
if (((DSP.outputinit & BX_SB16_THIS wavemode) & 2) == 0) {
writelog(WAVELOG(2), "Error opening file %s. Wave file output disabled.",
waveparam->getptr());
BX_SB16_THIS wavemode = DSP.outputinit;
}
}
}
DSP.dma.chunkcount = sampledatarate / 10; // 0.1 sec
if (DSP.dma.chunkcount > BX_SOUNDLOW_WAVEPACKETSIZE) {
DSP.dma.chunkcount = BX_SOUNDLOW_WAVEPACKETSIZE;
}
} else {
if (DSP.inputinit == 0) {
ret = BX_SB16_WAVEIN->openwaveinput(SIM->get_param_string(BXPN_SOUND_WAVEIN)->getptr(), sb16_adc_handler);
if (ret != BX_SOUNDLOW_OK) {
writelog(WAVELOG(2), "Error: Could not open wave input device.");
} else {
DSP.inputinit = 1;
}
}
if (DSP.inputinit == 1) {
ret = BX_SB16_WAVEIN->startwaverecord(&DSP.dma.param);
if (ret != BX_SOUNDLOW_OK) {
writelog(WAVELOG(2), "Error: Could not start wave record.");
}
}
DSP.dma.chunkcount = 0;
2006-05-06 19:19:57 +04:00
}
dsp_enabledma();
}
Bit32u bx_sb16_c::sb16_adc_handler(void *this_ptr, Bit32u buflen)
{
bx_sb16_c *class_ptr = (bx_sb16_c*)this_ptr;
class_ptr->dsp_adc_handler(buflen);
return 0;
}
Bit32u bx_sb16_c::dsp_adc_handler(Bit32u buflen)
{
Bit32u len;
len = DSP.dma.chunkcount - DSP.dma.chunkindex;
if (len > 0) {
memmove(DSP.dma.chunk, DSP.dma.chunk+DSP.dma.chunkindex, len);
DSP.dma.chunkcount = len;
}
DSP.dma.chunkindex = 0;
if ((DSP.dma.chunkcount + buflen) > BX_SOUNDLOW_WAVEPACKETSIZE) {
DSP.dma.chunkcount = BX_SOUNDLOW_WAVEPACKETSIZE;
len = DSP.dma.chunkcount + buflen - BX_SOUNDLOW_WAVEPACKETSIZE;
BX_DEBUG(("dsp_adc_handler(): unhandled len=%d", len));
} else {
DSP.dma.chunkcount += buflen;
len = 0;
}
BX_SB16_WAVEIN->getwavepacket(DSP.dma.chunkcount, DSP.dma.chunk);
return len;
}
// dsp_enabledma(): Start the DMA timer and thus the transfer
void bx_sb16_c::dsp_enabledma()
{
2006-05-06 19:19:57 +04:00
bx_pc_system.activate_timer(DSP.timer_handle, DSP.dma.timer, 1);
}
// dsp_disabledma(): Stop the DMA timer and thus the transfer, but don't abort it
void bx_sb16_c::dsp_disabledma()
{
2006-05-06 19:19:57 +04:00
bx_pc_system.deactivate_timer(DSP.timer_handle);
}
void bx_sb16_c::dsp_disable_nondma()
{
if (DSP.nondma_mode) {
bx_pc_system.deactivate_timer(DSP.timer_handle);
DSP.nondma_mode = 0;
}
}
// dsp_bufferstatus() checks if the DSP is ready for data/commands
Bit32u bx_sb16_c::dsp_bufferstatus()
{
Bit32u result = 0x7f;
2006-05-06 19:19:57 +04:00
// MSB set -> not ready for commands
if (DSP.datain.full() == 1) result |= 0x80;
writelog(WAVELOG(4), "DSP Buffer status read, result %x", result);
return(result);
}
// dsp_status() checks if the DSP is ready to send data
Bit32u bx_sb16_c::dsp_status()
{
Bit32u result = 0x7f;
// read might be to acknowledge IRQ
2006-05-06 19:19:57 +04:00
if (DSP.irqpending != 0)
{
MIXER.reg[0x82] &= (~0x01);
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(4), "8-bit DMA or SBMIDI IRQ acknowledged");
if ((MIXER.reg[0x82] & 0x07) == 0) {
DSP.irqpending = 0;
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_pic_lower_irq(BX_SB16_IRQ);
}
2006-05-06 19:19:57 +04:00
}
// if buffer is not empty, there is data to be read
if (DSP.dataout.empty() == 0) result |= 0x80;
writelog(WAVELOG(4), "DSP output status read, result %x", result);
return(result);
}
// dsp_irq16ack() notifies that the 16bit DMA IRQ has been acknowledged
Bit32u bx_sb16_c::dsp_irq16ack()
{
Bit32u result = 0xff;
2006-05-06 19:19:57 +04:00
if (DSP.irqpending != 0)
{
MIXER.reg[0x82] &= (~0x02);
if ((MIXER.reg[0x82] & 0x07) == 0) {
DSP.irqpending = 0;
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_pic_lower_irq(BX_SB16_IRQ);
}
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(4), "16-bit DMA IRQ acknowledged");
}
else
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(3), "16-bit DMA IRQ acknowledged but not active!");
return result;
}
2006-05-06 19:19:57 +04:00
// the DMA handlers
// highlevel input and output handlers - rerouting to/from file,device
// write a wave packet to the output device
void bx_sb16_c::dsp_sendwavepacket()
{
if (DSP.nondma_mode) {
if (DSP.nondma_count == 0) {
dsp_disable_nondma();
return;
}
DSP.nondma_count = 0;
}
if (DSP.dma.chunkindex == 0)
return;
if (BX_SB16_THIS wavemode & 1) {
BX_SB16_WAVEOUT1->sendwavepacket(DSP.dma.chunkindex, DSP.dma.chunk, &DSP.dma.param);
}
if (BX_SB16_THIS wavemode & 2) {
BX_SB16_WAVEOUT2->sendwavepacket(DSP.dma.chunkindex, DSP.dma.chunk, &DSP.dma.param);
2006-05-06 19:19:57 +04:00
}
DSP.dma.chunkindex = 0;
}
// put a sample byte into the output buffer
void bx_sb16_c::dsp_getsamplebyte(Bit8u value)
{
if (DSP.dma.chunkindex < DSP.dma.chunkcount)
DSP.dma.chunk[DSP.dma.chunkindex++] = value;
if (DSP.dma.chunkindex >= DSP.dma.chunkcount)
dsp_sendwavepacket();
}
// read a sample byte from the input buffer
Bit8u bx_sb16_c::dsp_putsamplebyte()
{
Bit8u value = DSP.dma.chunk[DSP.dma.chunkindex++];
if (DSP.dma.chunkindex >= DSP.dma.chunkcount) {
DSP.dma.chunkcount = 0;
DSP.dma.chunkindex = 0;
}
return value;
}
// called when the last byte of a DMA transfer has been received/sent
void bx_sb16_c::dsp_dmadone()
{
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(4), "DMA transfer done, triggering IRQ");
if ((DSP.dma.output == 1) && (DSP.dma.mode != 2)) {
dsp_sendwavepacket(); // flush the output
} else if ((DSP.dma.output == 0) && (DSP.dma.mode != 2)) {
BX_SB16_WAVEIN->stopwaverecord();
2006-05-06 19:19:57 +04:00
}
2006-05-06 19:19:57 +04:00
// generate the appropriate IRQ
if (DSP.dma.param.bits == 8)
MIXER.reg[0x82] |= 1;
2006-05-06 19:19:57 +04:00
else
MIXER.reg[0x82] |= 2;
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_pic_raise_irq(BX_SB16_IRQ);
DSP.irqpending = 1;
2006-05-06 19:19:57 +04:00
// if auto-DMA, reinitialize
if (DSP.dma.mode == 2)
2006-05-06 19:19:57 +04:00
{
if (DSP.dma.param.bits == 8 || (DSP.dma.param.bits == 16 && BX_SB16_DMAH != 0)) {
DSP.dma.count = DSP.dma.blocklength;
} else {
DSP.dma.count = ((DSP.dma.blocklength + 1) << 1) - 1;
}
2006-05-06 19:19:57 +04:00
writelog(WAVELOG(4), "auto-DMA reinitializing to length %d", DSP.dma.count);
}
else
2006-05-06 19:19:57 +04:00
{
DSP.dma.mode = 0;
dsp_disabledma();
2006-05-06 19:19:57 +04:00
}
}
// now the actual transfer routines, called by the DMA controller
// note that read = from application to soundcard (output),
// and write = from soundcard to application (input)
Bit16u bx_sb16_c::dma_read8(Bit8u *buffer, Bit16u maxlen)
{
Bit16u len = 0;
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_dma_set_drq(BX_SB16_DMAL, 0); // the timer will raise it again
writelog(WAVELOG(5), "Received 8-bit DMA: 0x%02x, %d remaining ",
buffer[0], DSP.dma.count);
do {
dsp_getsamplebyte(buffer[len++]);
DSP.dma.count--;
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
if (DSP.dma.count == 0xffff) // last byte received
dsp_dmadone();
return len;
}
Bit16u bx_sb16_c::dma_write8(Bit8u *buffer, Bit16u maxlen)
{
Bit16u len = 0;
DEV_dma_set_drq(BX_SB16_DMAL, 0); // the timer will raise it again
do {
buffer[len++] = dsp_putsamplebyte();
DSP.dma.count--;
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
writelog(WAVELOG(5), "Sent 8-bit DMA: 0x%02x, %d remaining ",
buffer[0], DSP.dma.count);
if (DSP.dma.count == 0xffff) // last byte sent
dsp_dmadone();
return len;
}
Bit16u bx_sb16_c::dma_read16(Bit16u *buffer, Bit16u maxlen)
{
Bit16u len = 0;
Bit8u *buf8;
DEV_dma_set_drq(BX_SB16_DMAH, 0); // the timer will raise it again
writelog(WAVELOG(5), "Received 16-bit DMA: 0x%04x, %d remaining ",
buffer[0], DSP.dma.count);
do {
buf8 = (Bit8u*)(buffer+len);
dsp_getsamplebyte(buf8[0]);
dsp_getsamplebyte(buf8[1]);
len++;
DSP.dma.count--;
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
if (DSP.dma.count == 0xffff) // last word received
dsp_dmadone();
return len;
}
Bit16u bx_sb16_c::dma_write16(Bit16u *buffer, Bit16u maxlen)
{
Bit16u len = 0;
Bit8u *buf8;
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_dma_set_drq(BX_SB16_DMAH, 0); // the timer will raise it again
do {
buf8 = (Bit8u*)(buffer+len);
buf8[0] = dsp_putsamplebyte();
buf8[1] = dsp_putsamplebyte();
len++;
DSP.dma.count--;
} while ((len < maxlen) && (DSP.dma.count != 0xffff));
writelog(WAVELOG(5), "Sent 16-bit DMA: 0x%4x, %d remaining ",
buffer[0], DSP.dma.count);
if (DSP.dma.count == 0xffff) // last word sent
dsp_dmadone();
return len;
}
Bit16u bx_sb16_c::calc_output_volume(Bit8u reg1, Bit8u reg2, bx_bool shift)
{
Bit8u vol1, vol2;
float fvol1, fvol2;
Bit16u result;
vol1 = (MIXER.reg[reg1] >> 3);
vol2 = (MIXER.reg[reg2] >> 3);
fvol1 = pow(10.0f, (float)(31-vol1)*-0.065f);
fvol2 = pow(10.0f, (float)(31-vol2)*-0.065f);
result = (Bit8u)(255 * fvol1 * fvol2);
if (shift) result <<= 8;
return result;
}
2006-05-06 19:19:57 +04:00
// the mixer, supported type is CT1745 (as in an SB16)
void bx_sb16_c::mixer_writedata(Bit32u value)
{
int i;
Bit8u set_output_vol = 0;
// do some action depending on what register was written
switch (MIXER.regindex)
2006-05-06 19:19:57 +04:00
{
case 0: // initialize mixer
writelog(BOTHLOG(4), "Initializing mixer...");
MIXER.reg[0x04] = 0xcc;
MIXER.reg[0x0a] = 0x00;
MIXER.reg[0x22] = 0xcc;
MIXER.reg[0x26] = 0xcc;
MIXER.reg[0x28] = 0x00;
MIXER.reg[0x2e] = 0x00;
MIXER.reg[0x3c] = 0x1f;
MIXER.reg[0x3d] = 0x15;
MIXER.reg[0x3e] = 0x0b;
for (i=0x30; i<=0x35; i++)
2006-05-06 19:19:57 +04:00
MIXER.reg[i] = 0xc0;
for (i=0x36; i<=0x3b; i++)
2006-05-06 19:19:57 +04:00
MIXER.reg[i] = 0x00;
for (i=0x3f; i<=0x43; i++)
2006-05-06 19:19:57 +04:00
MIXER.reg[i] = 0x00;
for (i=0x44; i<=0x47; i++)
2006-05-06 19:19:57 +04:00
MIXER.reg[i] = 0x80;
MIXER.regindex = 0; // next mixer register read is register 0
set_output_vol = 3;
break;
case 0x04: // DAC level
MIXER.reg[0x32] = (value & 0xf0) | 0x08;
MIXER.reg[0x33] = ((value & 0x0f) << 4) | 0x08;
set_output_vol = 1;
break;
case 0x0a: // microphone level
MIXER.reg[0x3a] = (value << 5) | 0x18;
break;
case 0x22: // master volume
MIXER.reg[0x30] = (value & 0xf0) | 0x08;
MIXER.reg[0x31] = ((value & 0x0f) << 4) | 0x08;
set_output_vol = 3;
break;
case 0x26: // FM level
MIXER.reg[0x34] = (value & 0xf0) | 0x08;
MIXER.reg[0x35] = ((value & 0x0f) << 4) | 0x08;
set_output_vol = 2;
break;
case 0x28: // CD audio level
MIXER.reg[0x36] = (value & 0xf0) | 0x08;
MIXER.reg[0x37] = ((value & 0x0f) << 4) | 0x08;
break;
case 0x2e: // line in level
MIXER.reg[0x38] = (value & 0xf0) | 0x08;
MIXER.reg[0x39] = ((value & 0x0f) << 4) | 0x08;
break;
case 0x30: // master volume left
MIXER.reg[0x22] &= 0x0f;
MIXER.reg[0x22] |= (value & 0xf0);
set_output_vol = 3;
break;
case 0x31: // master volume right
MIXER.reg[0x22] &= 0xf0;
MIXER.reg[0x22] |= (value >> 4);
set_output_vol = 3;
break;
case 0x32: // DAC level left
MIXER.reg[0x04] &= 0x0f;
MIXER.reg[0x04] |= (value & 0xf0);
set_output_vol = 1;
break;
case 0x33: // DAC level right
MIXER.reg[0x04] &= 0xf0;
MIXER.reg[0x04] |= (value >> 4);
set_output_vol = 1;
break;
case 0x34: // FM level left
MIXER.reg[0x26] &= 0x0f;
MIXER.reg[0x26] |= (value & 0xf0);
set_output_vol = 2;
break;
case 0x35: // FM level right
MIXER.reg[0x26] &= 0xf0;
MIXER.reg[0x26] |= (value >> 4);
set_output_vol = 2;
break;
case 0x36: // CD audio level left
MIXER.reg[0x28] &= 0x0f;
MIXER.reg[0x28] |= (value & 0xf0);
break;
case 0x37: // CD audio level right
MIXER.reg[0x28] &= 0xf0;
MIXER.reg[0x28] |= (value >> 4);
break;
case 0x38: // line in level left
MIXER.reg[0x2e] &= 0x0f;
MIXER.reg[0x2e] |= (value & 0xf0);
break;
case 0x39: // line in level right
MIXER.reg[0x2e] &= 0xf0;
MIXER.reg[0x2e] |= (value >> 4);
break;
case 0x3a: // microphone level
MIXER.reg[0x0a] = (value >> 5);
break;
case 0x3b:
case 0x3c:
case 0x3d:
case 0x3e:
case 0x3f:
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x44:
case 0x45:
case 0x46:
case 0x47:
break;
case 0x80: // IRQ mask
case 0x81: // DMA mask
MIXER.reg[MIXER.regindex] = value;
set_irq_dma(); // both 0x80 and 0x81 handled
return;
default: // ignore read-only registers
return;
2006-05-06 19:19:57 +04:00
}
// store the value
if (MIXER.regindex != 0) {
MIXER.reg[MIXER.regindex] = value;
}
if (set_output_vol & 1) {
DSP.dma.param.volume = calc_output_volume(0x30, 0x32, 0);
DSP.dma.param.volume |= calc_output_volume(0x31, 0x33, 1);
}
if (set_output_vol & 2) {
BX_SB16_THIS fm_volume = calc_output_volume(0x30, 0x34, 0);
BX_SB16_THIS fm_volume |= calc_output_volume(0x31, 0x35, 1);
}
writelog(BOTHLOG(4), "mixer register %02x set to %02x",
2006-05-06 19:19:57 +04:00
MIXER.regindex, MIXER.reg[MIXER.regindex]);
}
Bit32u bx_sb16_c::mixer_readdata()
{
writelog(BOTHLOG(4), "read from mixer register %02x returns %02x",
2006-05-06 19:19:57 +04:00
MIXER.regindex, MIXER.reg[MIXER.regindex]);
return(MIXER.reg[MIXER.regindex]);
}
void bx_sb16_c::mixer_writeregister(Bit32u value)
{
MIXER.regindex = value;
}
void bx_sb16_c::set_irq_dma()
{
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
static bx_bool isInitialized=0;
int newirq;
int oldDMA8, oldDMA16;
// set the IRQ according to the value in mixer register 0x80
switch (MIXER.reg[0x80])
2006-05-06 19:19:57 +04:00
{
case 1:
newirq = 2;
break;
case 2:
newirq = 5;
break;
case 4:
newirq = 7;
break;
case 8:
newirq = 10;
break;
default:
newirq = 5;
writelog(BOTHLOG(3), "Bad value %02x in mixer register 0x80. IRQ set to %d",
2006-05-06 19:19:57 +04:00
MIXER.reg[0x80], newirq);
MIXER.reg[0x80] = 2;
2006-05-06 19:19:57 +04:00
}
if (newirq != BX_SB16_IRQ) // a different IRQ was set
2006-05-06 19:19:57 +04:00
{
if (BX_SB16_IRQ > 0)
2006-05-06 19:19:57 +04:00
DEV_unregister_irq(BX_SB16_IRQ, "SB16");
BX_SB16_IRQ = newirq;
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_register_irq(BX_SB16_IRQ, "SB16");
2006-05-06 19:19:57 +04:00
}
// set the 8 bit DMA
oldDMA8=BX_SB16_DMAL;
switch (MIXER.reg[0x81] & 0x0f)
2006-05-06 19:19:57 +04:00
{
case 1:
BX_SB16_DMAL = 0;
break;
case 2:
BX_SB16_DMAL = 1;
break;
case 8:
BX_SB16_DMAL = 3;
break;
default:
BX_SB16_DMAL = 1;
writelog(BOTHLOG(3), "Bad value %02x in mixer register 0x81. DMA8 set to %d",
2006-05-06 19:19:57 +04:00
MIXER.reg[0x81], BX_SB16_DMAL);
MIXER.reg[0x81] &= (~0x0f);
MIXER.reg[0x81] |= (1 << BX_SB16_DMAL);
2006-05-06 19:19:57 +04:00
}
// Unregister the previous DMA if initialized
2006-05-06 19:19:57 +04:00
if ((isInitialized) && (oldDMA8 != BX_SB16_DMAL))
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_dma_unregister_channel(oldDMA8);
// And register the new 8bits DMA Channel
2006-05-06 19:19:57 +04:00
if ((!isInitialized) || (oldDMA8 != BX_SB16_DMAL))
DEV_dma_register_8bit_channel(BX_SB16_DMAL, dma_read8, dma_write8, "SB16");
// and the 16 bit DMA
oldDMA16=BX_SB16_DMAH;
switch (MIXER.reg[0x81] >> 4)
2006-05-06 19:19:57 +04:00
{
case 0:
BX_SB16_DMAH = 0; // no 16-bit DMA
break;
case 2:
BX_SB16_DMAH = 5;
break;
case 4:
BX_SB16_DMAH = 6;
break;
case 8:
BX_SB16_DMAH = 7;
break;
default:
BX_SB16_DMAH = 0;
writelog(BOTHLOG(3), "Bad value %02x in mixer register 0x81. DMA16 set to %d",
2006-05-06 19:19:57 +04:00
MIXER.reg[0x81], BX_SB16_DMAH);
MIXER.reg[0x81] &= (~0xf0);
// MIXER.reg[0x81] |= (1 << BX_SB16_DMAH);
// no default 16 bit channel!
2006-05-06 19:19:57 +04:00
}
// Unregister the previous DMA if initialized
2006-05-06 19:19:57 +04:00
if ((isInitialized) && (oldDMA16 != 0) && (oldDMA16 != BX_SB16_DMAH))
Add plugin support to Bochs by merging all the changes from the BRANCH_PLUGINS branch! Authors: Bryce Denney Christophe Bothamy Kevin Lawton (we grabbed a lot of plugin code from plex86) Testing help from: Volker Ruppert Don Becker (Psyon) Jeremy Parsons (Br'fin) The change log is too long to paste in here. To read the change log, do cvs log patches/patch.final-from-BRANCH_PLUGINS.gz All the changes and a detailed description are contained in a patch called patch.final-from-BRANCH_PLUGINS.gz. To look at the complete patch, do cvs upd -r1.1 patches/patch.final-from-BRANCH_PLUGINS.gz Then you will have a local copy of the patch, which you can gunzip and play with however you want. Modified Files: .bochsrc Makefile.in aclocal.m4 bochs.h config.h.in configure configure.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h state_file.h bios/Makefile.in bios/rombios.c cpu/Makefile.in cpu/access.cc cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer32.cc cpu/exception.cc cpu/fetchdecode.cc cpu/fetchdecode64.cc cpu/flag_ctrl.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io.cc cpu/logical16.cc cpu/logical32.cc cpu/logical8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/protect_ctrl.cc cpu/segment_ctrl_pro.cc cpu/shift16.cc cpu/shift32.cc cpu/stack64.cc cpu/string.cc cpu/tasking.cc debug/Makefile.in debug/dbg_main.cc disasm/Makefile.in doc/docbook/user/user.dbk dynamic/Makefile.in fpu/Makefile.in gui/Makefile.in gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/control.cc gui/control.h gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/sdlkeys.h gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h gui/x.cc gui/keymaps/sdl-pc-de.map gui/keymaps/sdl-pc-us.map gui/keymaps/x11-pc-de.map instrument/example0/instrument.h instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/Makefile.in iodev/biosdev.cc iodev/biosdev.h iodev/cdrom.cc iodev/cmos.cc iodev/cmos.h iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_tap.cc iodev/floppy.cc iodev/floppy.h iodev/guest2host.cc iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/iodebug.cc iodev/iodebug.h iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.cc iodev/ne2k.h iodev/parallel.cc iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pci2isa.cc iodev/pci2isa.h iodev/pic.cc iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/scancodes.cc iodev/scancodes.h iodev/serial.cc iodev/serial.h iodev/slowdown_timer.cc iodev/slowdown_timer.h iodev/unmapped.cc iodev/unmapped.h iodev/vga.cc iodev/vga.h memory/Makefile.in memory/memory.cc memory/memory.h memory/misc_mem.cc misc/bximage.c misc/niclist.c Added Files: README-plugins extplugin.h ltdl.c ltdl.h ltdlconf.h.in ltmain.sh plugin.cc plugin.h
2002-10-25 01:07:56 +04:00
DEV_dma_unregister_channel(oldDMA16);
// And register the new 16bits DMA Channel
2006-05-06 19:19:57 +04:00
if ((BX_SB16_DMAH != 0) && (oldDMA16 != BX_SB16_DMAH))
DEV_dma_register_16bit_channel(BX_SB16_DMAH, dma_read16, dma_write16, "SB16");
// If not already initialized
if(!isInitialized) {
isInitialized=1;
} else {
writelog(BOTHLOG(1), "Resources set to I%d D%d H%d",
BX_SB16_IRQ, BX_SB16_DMAL, BX_SB16_DMAH);
}
}
2006-05-06 19:19:57 +04:00
// now the MPU 401 part
// the MPU 401 status port shows if input or output are ready
// Note that the bits are inverse to their meaning
Bit32u bx_sb16_c::mpu_status()
{
Bit32u result = 0;
if ((MPU.datain.full() == 1) ||
((BX_SB16_THIS midimode & 1) &&
(BX_SB16_MIDIOUT1->midiready() == BX_SOUNDLOW_ERR)))
2006-05-06 19:19:57 +04:00
result |= 0x40; // output not ready
if (MPU.dataout.empty() == 1)
2006-05-06 19:19:57 +04:00
result |= 0x80; // no input available
writelog(MIDILOG(4), "MPU status port, result %02x", result);
return(result);
}
// the MPU 401 command port
void bx_sb16_c::mpu_command(Bit32u value)
{
int i;
int bytesneeded;
if (MPU.cmd.hascommand() == 1) // already a command pending, abort that one
2006-05-06 19:19:57 +04:00
{
if ((MPU.cmd.currentcommand() != value) ||
(MPU.cmd.commanddone() == 0))
2006-05-06 19:19:57 +04:00
// it's a different command, or the old one isn't done yet, abort it
{
MPU.cmd.clearcommand();
MPU.cmd.flush();
}
// if it's the same one, and we just completed the argument list,
// we leave it as it is and process it here
}
if (MPU.cmd.hascommand() == 0) // no command pending, set one up
2006-05-06 19:19:57 +04:00
{
bytesneeded = 0;
if ((value >> 4) == 14) bytesneeded = 1;
MPU.cmd.newcommand(value, bytesneeded);
2006-05-06 19:19:57 +04:00
}
if (MPU.cmd.commanddone() == 1) // command is complete, process it
2006-05-06 19:19:57 +04:00
{
switch (MPU.cmd.currentcommand())
{
case 0x3f:
writelog(MIDILOG(5), "MPU cmd: UART mode on");
MPU.uartmode=1;
MPU.irqpending=1;
MPU.singlecommand=0;
if (BX_SB16_IRQMPU != -1) {
MIXER.reg[0x82] |= 4;
DEV_pic_raise_irq(BX_SB16_IRQMPU);
}
break;
case 0xff:
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(4), "MPU cmd: Master reset of device");
MPU.uartmode=MPU.forceuartmode;
MPU.singlecommand=0;
for (i=0; i<16; i++)
{
MPU.banklsb[i] = 0;
MPU.bankmsb[i] = 0;
MPU.program[i] = 0;
}
MPU.cmd.reset();
MPU.dataout.reset();
MPU.datain.reset();
MPU.midicmd.reset();
break;
case 0xd0: // d0 and df: prefix for midi command
case 0xdf: // like uart mode, but only a single command
MPU.singlecommand = 1;
writelog(MIDILOG(4), "MPU: prefix %02x received",
2006-05-06 19:19:57 +04:00
MPU.cmd.currentcommand());
break;
default:
writelog(MIDILOG(3), "MPU cmd: unknown command %02x ignored",
MPU.cmd.currentcommand());
break;
}
// Need to put an MPU_ACK into the data port if command successful
// we'll fake it even if we didn't process the command, so as to
2006-05-06 19:19:57 +04:00
// allow detection of the MPU 401.
if (MPU.dataout.put(0xfe) == 0)
writelog(MIDILOG(3), "MPU_ACK error - output buffer full");
MPU.cmd.clearcommand(); // clear the command from the buffer
}
}
// MPU 401 data port/read: contains an MPU_ACK after receiving a command
// Will contain other data as well when other than UART mode is supported
Bit32u bx_sb16_c::mpu_dataread()
{
2006-05-06 19:19:57 +04:00
Bit8u res8bit;
Bit32u result;
2006-05-06 19:19:57 +04:00
// also acknowledge IRQ?
if (MPU.irqpending != 0)
{
MPU.irqpending = 0;
MIXER.reg[0x82] &= (~4);
if ((MIXER.reg[0x82] & 0x07) == 0)
DEV_pic_lower_irq(BX_SB16_IRQMPU);
writelog(MIDILOG(4), "MPU IRQ acknowledged");
}
2006-05-06 19:19:57 +04:00
if (MPU.dataout.get(&res8bit) == 0) {
writelog(MIDILOG(3), "MPU data port not ready - no data in buffer");
result = 0xff;
}
else
result = (Bit32u) res8bit;
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(4), "MPU data port, result %02x", result);
2006-05-06 19:19:57 +04:00
return(result);
}
// MPU 401 data port/write: This is where the midi stream comes from,
// as well as arguments to any pending command
void bx_sb16_c::mpu_datawrite(Bit32u value)
{
writelog(MIDILOG(4), "write to MPU data port, value %02x", value);
if (MPU.cmd.hascommand() == 1)
2006-05-06 19:19:57 +04:00
{ // there is a command pending, add arguments to it
if (MPU.cmd.put(value) == 0)
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(3), "MPU Command arguments too long - buffer full");
if (MPU.cmd.commanddone() == 1)
2006-05-06 19:19:57 +04:00
BX_SB16_THIS mpu_command(MPU.cmd.currentcommand());
}
else if ((MPU.uartmode == 0) && (MPU.singlecommand == 0))
2006-05-06 19:19:57 +04:00
{
// Hm? No UART mode, but still data? Maybe should send it
// to the command port... Only SBMPU401.EXE does this...
writelog(MIDILOG(4), "MPU Data %02x received but no UART mode. Assuming it's a command.", value);
mpu_command(value);
return;
2006-05-06 19:19:57 +04:00
}
else // no MPU command pending, in UART mode, this has to be midi data
mpu_mididata(value);
}
// A byte of midi data has been received
void bx_sb16_c::mpu_mididata(Bit32u value)
{
// first, find out if it is a midi command or midi data
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool ismidicommand = 0;
if (value >= 0x80)
2006-05-06 19:19:57 +04:00
{ // bit 8 usually denotes a midi command...
ismidicommand = 1;
2006-05-06 19:19:57 +04:00
if ((value == 0xf7) && (MPU.midicmd.currentcommand() == 0xf0))
// ...except if it is a continuing SYSEX message, then it just
// denotes the end of a SYSEX chunk, not the start of a message
{
ismidicommand = 0; // first, it's not a command
MPU.midicmd.newcommand(MPU.midicmd.currentcommand(),
2006-05-06 19:19:57 +04:00
MPU.midicmd.bytes());
// Then, set needed bytes to current buffer
// because we didn't know the length before
}
}
if (ismidicommand == 1)
2006-05-06 19:19:57 +04:00
{ // this is a command, check if an old one is pending
if (MPU.midicmd.hascommand() == 1)
2006-05-06 19:19:57 +04:00
{
writelog(MIDILOG(3), "Midi command %02x incomplete, has %d of %d bytes.",
MPU.midicmd.currentcommand(), MPU.midicmd.bytes(),
MPU.midicmd.commandbytes());
2006-05-06 19:19:57 +04:00
// write as much as we can. Should we do this?
processmidicommand(0);
// clear the pending command
MPU.midicmd.clearcommand();
MPU.midicmd.flush();
}
// find the number of arguments to the command
static const signed eventlength[] = { 2, 2, 2, 2, 1, 1, 2, 255};
// note - length 255 commands have unknown length
MPU.midicmd.newcommand(value, eventlength[(value & 0x70) >> 4]);
2006-05-06 19:19:57 +04:00
}
else // no command, just arguments to the old command
2006-05-06 19:19:57 +04:00
{
if (MPU.midicmd.hascommand() == 0)
2006-05-06 19:19:57 +04:00
{ // no command pending, ignore the data
writelog(MIDILOG(3), "Midi data %02x received, but no command pending?", value);
return;
}
// just some data to the command
if (MPU.midicmd.put(value) == 0)
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(3), "Midi buffer overflow!");
if (MPU.midicmd.commanddone() == 1)
2006-05-06 19:19:57 +04:00
{
// the command is complete, process it
writelog(MIDILOG(5), "Midi command %02x complete, has %d bytes.",
MPU.midicmd.currentcommand(), MPU.midicmd.bytes());
2006-05-06 19:19:57 +04:00
processmidicommand(0);
// and remove the command from the buffer
MPU.midicmd.clearcommand();
MPU.midicmd.flush();
}
}
}
// The emulator port/read: See if commands were successful
Bit32u bx_sb16_c::emul_read()
{
2006-05-06 19:19:57 +04:00
Bit8u res8bit;
Bit32u result;
2006-05-06 19:19:57 +04:00
if (EMUL.datain.get(&res8bit) == 0)
{
writelog(3, "emulator port not ready - no data in buffer");
result = 0x00;
}
else result = (Bit32u) res8bit;
2006-05-06 19:19:57 +04:00
writelog(4, "emulator port, result %02x", result);
2006-05-06 19:19:57 +04:00
return(result);
}
// Emulator port/write: Changing instrument mapping etc.
void bx_sb16_c::emul_write(Bit32u value)
{
2007-04-08 19:02:50 +04:00
Bit8u value8 = 0;
writelog(4, "write to emulator port, value %02x", value);
if (EMUL.dataout.hascommand() == 0) // no command pending, set it up
2006-05-06 19:19:57 +04:00
{
static signed char cmdlength[] = { 0, 0, 4, 2, 6, 1, 0, 0, 1, 1, 0, 1};
if (value > 11)
{
2006-05-06 19:19:57 +04:00
writelog(3, "emulator command %02x unknown, ignored.", value);
return;
}
2006-05-06 19:19:57 +04:00
writelog(5, "emulator command %02x, needs %d arguments",
value, cmdlength[value]);
EMUL.dataout.newcommand(value, cmdlength[value]);
EMUL.datain.reset();
EMUL.datain.put(0xfe);
}
else
EMUL.dataout.put(value); // otherwise just add data
if (EMUL.dataout.commanddone() == 1)
2006-05-06 19:19:57 +04:00
{ // process the command
writelog(4, "executing emulator command %02x with %d arguments",
EMUL.dataout.currentcommand(), EMUL.dataout.bytes());
switch (EMUL.dataout.currentcommand())
{
case 0: // reinit of emulator
writelog(4, "Emulator reinitialized");
EMUL.remaps = 0;
EMUL.dataout.reset();
EMUL.datain.reset();
EMUL.datain.put(0xfe);
break;
case 1: // dummy command to reset state of emulator port
// just give a few times to end any commands
break;
case 2: // map bank
if (EMUL.remaps >= BX_SB16_MAX_REMAPS) break;
2006-05-06 19:19:57 +04:00
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].oldbankmsb));
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].oldbanklsb));
EMUL.remaplist[EMUL.remaps].oldprogch = 0xff;
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].newbankmsb));
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].newbanklsb));
EMUL.remaplist[EMUL.remaps].newprogch = 0xff;
EMUL.datain.put(4);
writelog(4, "Map bank command received, from %d %d to %d %d",
EMUL.remaplist[EMUL.remaps].oldbankmsb,
EMUL.remaplist[EMUL.remaps].oldbanklsb,
EMUL.remaplist[EMUL.remaps].newbankmsb,
EMUL.remaplist[EMUL.remaps].newbanklsb);
EMUL.remaps++;
break;
case 3: // map program change
if (EMUL.remaps >= BX_SB16_MAX_REMAPS) break;
2006-05-06 19:19:57 +04:00
EMUL.remaplist[EMUL.remaps].oldbankmsb = 0xff;
EMUL.remaplist[EMUL.remaps].oldbanklsb = 0xff;
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].oldprogch));
EMUL.remaplist[EMUL.remaps].newbankmsb = 0xff;
EMUL.remaplist[EMUL.remaps].newbanklsb = 0xff;
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].newprogch));
EMUL.datain.put(2);
writelog(4, "Map program change received, from %d to %d",
EMUL.remaplist[EMUL.remaps].oldprogch,
EMUL.remaplist[EMUL.remaps].newprogch);
EMUL.remaps++;
break;
case 4: // map bank and program change
if (EMUL.remaps >= BX_SB16_MAX_REMAPS) break;
2006-05-06 19:19:57 +04:00
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].oldbankmsb));
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].oldbanklsb));
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].oldprogch));
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].newbankmsb));
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].newbanklsb));
EMUL.dataout.get (& (EMUL.remaplist[EMUL.remaps].newprogch));
EMUL.datain.put(6);
writelog(4, "Complete remap received, from %d %d %d to %d %d %d",
EMUL.remaplist[EMUL.remaps].oldbankmsb,
EMUL.remaplist[EMUL.remaps].oldbanklsb,
EMUL.remaplist[EMUL.remaps].oldprogch,
EMUL.remaplist[EMUL.remaps].newbankmsb,
EMUL.remaplist[EMUL.remaps].newbanklsb,
EMUL.remaplist[EMUL.remaps].newprogch);
EMUL.remaps++;
break;
case 5: EMUL.dataout.get(&value8); // dump emulator state
switch (value8)
{
case 0:
2006-05-06 19:19:57 +04:00
EMUL.datain.puts("SB16 Emulator for Bochs\n");
break;
case 1:
EMUL.datain.puts("UART mode=%d (force=%d)\n",
2006-05-06 19:19:57 +04:00
MPU.uartmode, MPU.forceuartmode);
break;
case 2:
2006-05-06 19:19:57 +04:00
EMUL.datain.puts("timer=%d\n", MPU.current_timer);
break;
case 3:
2006-05-06 19:19:57 +04:00
EMUL.datain.puts("%d remappings active\n", EMUL.remaps);
break;
case 4:
2006-05-06 19:19:57 +04:00
EMUL.datain.puts("Resources are A%3x I%d D%d H%d T%d P%3x; Adlib at %3x\n",
BX_SB16_IO, BX_SB16_IRQ, BX_SB16_DMAL,
BX_SB16_DMAH, 6, BX_SB16_IOMPU, BX_SB16_IOADLIB);
break;
default:
EMUL.datain.puts("no info. Only slots 0..4 have values.\n");
2006-05-06 19:19:57 +04:00
break;
}
break;
case 6: // close midi and wave files and/or output
BX_SB16_THIS closemidioutput();
BX_SB16_THIS midimode = 0;
BX_SB16_THIS closewaveoutput();
BX_SB16_THIS wavemode = 0;
break;
case 7: // clear bank/program mappings
EMUL.remaps = 0;
writelog(4, "Bank/program mappings cleared.");
break;
case 8: // set force uart mode on/off
EMUL.dataout.get(&value8);
MPU.forceuartmode = value8;
if (value8 != 0)
MPU.uartmode = MPU.forceuartmode;
writelog(4, "Force UART mode = %d", MPU.forceuartmode);
break;
case 9: // enter specific OPL2/3 mode
// this feature has been removed
break;
case 10: // check emulator present
EMUL.datain.put(0x55);
break;
case 11: // send data to midi device
EMUL.dataout.get(&value8);
mpu_mididata(value8);
}
EMUL.dataout.clearcommand();
EMUL.dataout.flush();
2006-05-06 19:19:57 +04:00
}
}
// and finally the OPL (FM emulation) part
// this is called whenever one of the timer elapses
void bx_sb16_c::opl_timerevent()
{
Bit16u mask;
2006-05-06 19:19:57 +04:00
for (int i=0; i<4; i++) {
if ((OPL.tmask[i/2] & (1 << (i % 2))) != 0) { // only running timers
if ((i % 2) == 0) {
mask = 0xff;
} else {
mask = 0x3ff;
}
if (((++OPL.timer[i]) & mask) == 0) { // overflow occured, set flags accordingly
OPL.timer[i] = OPL.timerinit[i]; // reset the counter
if ((OPL.tmask[i/2] >> (6 - (i % 2))) == 0) { // set flags only if unmasked
writelog(MIDILOG(5), "OPL Timer Interrupt: Chip %d, Timer %d", i/2, 1 << (i % 2));
OPL.tflag[i/2] |= 1 << (6 - (i % 2)); // set the overflow flag
OPL.tflag[i/2] |= 1 << 7; // set the IRQ flag
}
}
2006-05-06 19:19:57 +04:00
}
}
}
// return the status of one of the OPL2's, or the
// base status of the OPL3
Bit32u bx_sb16_c::opl_status(int chipid)
{
Bit32u status = OPL.tflag[chipid];
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(5), "OPL status of chip %d is %02x", chipid, status);
return status;
}
// write to the data port
void bx_sb16_c::opl_data(Bit32u value, int chipid)
{
int index = OPL.index[chipid];
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(4), "Write to OPL(%d) register %02x: %02x",
chipid, index, value);
switch (index & 0xff) {
2006-05-06 19:19:57 +04:00
// the two timer counts
case 0x02:
OPL.timerinit[chipid * 2] = OPL.timer[chipid * 2] = value;
break;
case 0x03:
OPL.timerinit[chipid * 2 + 1] = OPL.timer[chipid * 2 + 1] = (value << 2);
break;
// the timer masks
case 0x04:
if (chipid == 0) {
2006-05-06 19:19:57 +04:00
opl_settimermask(value, chipid);
}
break;
2006-05-06 19:19:57 +04:00
}
}
// called for a write to port 4 of either chip
void bx_sb16_c::opl_settimermask(int value, int chipid)
{
if ((value & 0x80) != 0) { // reset IRQ and timer flags
// all other bits ignored!
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(5), "IRQ Reset called");
OPL.tflag[chipid] = 0;
return;
2006-05-06 19:19:57 +04:00
}
OPL.tmask[chipid] = value & 0x63;
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(5), "New timer mask for chip %d is %02x",
chipid, OPL.tmask[chipid]);
// do we have to activate or deactivate the timer?
if (((value & 0x03) != 0) ^ (OPL.timer_running != 0)) {
if ((value & 0x03) != 0) { // yes, it's different. Start or stop?
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(5), "Starting timers");
bx_pc_system.activate_timer(OPL.timer_handle, 80, 1);
2006-05-06 19:19:57 +04:00
OPL.timer_running = 1;
} else {
2006-05-06 19:19:57 +04:00
writelog(MIDILOG(5), "Stopping timers");
bx_pc_system.deactivate_timer(OPL.timer_handle);
2006-05-06 19:19:57 +04:00
OPL.timer_running = 0;
}
}
}
Bit32u bx_sb16_c::fmopl_generator(Bit16u rate, Bit8u *buffer, Bit32u len)
{
bx_bool ret = adlib_getsample(rate, (Bit16s*)buffer, len / 4, BX_SB16_THIS fm_volume);
return ret ? len : 0;
}
Bit32u fmopl_callback(void *dev, Bit16u rate, Bit8u *buffer, Bit32u len)
{
return ((bx_sb16_c*)dev)->fmopl_generator(rate, buffer, len);
}
/* Handlers for the midi commands/midi file output */
// write the midi command to the midi file
void bx_sb16_c::writemidicommand(int command, int length, Bit8u data[])
{
bx_param_string_c *midiparam;
/* We need to determine the time elapsed since the last MIDI command */
int deltatime = currentdeltatime();
/* Initialize output device/file if necessary and not done yet */
if (BX_SB16_THIS midimode > 0) {
if ((MPU.outputinit & BX_SB16_THIS midimode) != BX_SB16_THIS midimode) {
writelog(MIDILOG(4), "Initializing Midi output.");
if (BX_SB16_THIS midimode & 1) {
midiparam = SIM->get_param_string(BXPN_SOUND_MIDIOUT);
if (BX_SB16_MIDIOUT1->openmidioutput(midiparam->getptr()) == BX_SOUNDLOW_OK)
MPU.outputinit |= 1;
else
MPU.outputinit &= ~1;
}
if (BX_SB16_THIS midimode & 2) {
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16);
midiparam = SIM->get_param_string("midifile", base);
if (BX_SB16_MIDIOUT2->openmidioutput(midiparam->getptr()) == BX_SOUNDLOW_OK)
MPU.outputinit |= 2;
else
MPU.outputinit &= ~2;
}
if ((MPU.outputinit & BX_SB16_THIS midimode) != BX_SB16_THIS midimode) {
writelog(MIDILOG(2), "Error: Couldn't open midi output. Midi disabled.");
BX_SB16_THIS midimode = MPU.outputinit;
return;
2006-05-06 19:19:57 +04:00
}
}
if (BX_SB16_THIS midimode & 1) {
BX_SB16_MIDIOUT1->sendmidicommand(deltatime, command, length, data);
}
if (BX_SB16_THIS midimode & 2) {
BX_SB16_MIDIOUT2->sendmidicommand(deltatime, command, length, data);
}
2006-05-06 19:19:57 +04:00
}
}
// determine how many delta times have passed since
// this function was called last
int bx_sb16_c::currentdeltatime()
{
int deltatime;
// counting starts at first access
if (MPU.last_delta_time == 0xffffffff)
MPU.last_delta_time = MPU.current_timer;
deltatime = MPU.current_timer - MPU.last_delta_time;
MPU.last_delta_time = MPU.current_timer;
return deltatime;
}
// process the midi command stored in MPU.midicmd.to the midi driver
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
void bx_sb16_c::processmidicommand(bx_bool force)
{
int i, channel;
Bit8u value;
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool needremap = 0;
channel = MPU.midicmd.currentcommand() & 0xf;
// we need to log bank changes and program changes
if ((MPU.midicmd.currentcommand() >> 4) == 0xc)
2006-05-06 19:19:57 +04:00
{ // a program change
value = MPU.midicmd.peek(0);
writelog(MIDILOG(1), "* ProgramChange channel %d to %d",
2006-05-06 19:19:57 +04:00
channel, value);
MPU.program[channel] = value;
needremap = 1;
2006-05-06 19:19:57 +04:00
}
else if ((MPU.midicmd.currentcommand() >> 4) == 0xb)
2006-05-06 19:19:57 +04:00
{ // a control change, could be a bank change
if (MPU.midicmd.peek(0) == 0)
2006-05-06 19:19:57 +04:00
{ // bank select MSB
value = MPU.midicmd.peek(1);
writelog(MIDILOG(1), "* BankSelectMSB (%x %x %x) channel %d to %d",
MPU.midicmd.peek(0), MPU.midicmd.peek(1), MPU.midicmd.peek(2),
channel, value);
MPU.bankmsb[channel] = value;
needremap = 1;
}
else if (MPU.midicmd.peek(0) == 32)
2006-05-06 19:19:57 +04:00
{ // bank select LSB
value = MPU.midicmd.peek(1);
writelog(MIDILOG(1), "* BankSelectLSB channel %d to %d",
channel, value);
MPU.banklsb[channel] = value;
needremap = 1;
}
}
Bit8u temparray[256];
i = 0;
while (MPU.midicmd.empty() == 0)
MPU.midicmd.get(&(temparray[i++]));
writemidicommand(MPU.midicmd.currentcommand(), i, temparray);
// if single command, revert to command mode
if (MPU.singlecommand != 0)
2006-05-06 19:19:57 +04:00
{
MPU.singlecommand = 0;
2006-05-06 19:19:57 +04:00
}
2006-05-06 19:19:57 +04:00
if ((force == 0) && (needremap == 1))
// have to check the remap lists, and remap program change if necessary
midiremapprogram(channel);
}
// check if a program change has to be remapped, and do it if necessary
void bx_sb16_c::midiremapprogram(int channel)
{
int bankmsb,banklsb,program;
Bit8u commandbytes[2];
bankmsb = MPU.bankmsb[channel];
banklsb = MPU.banklsb[channel];
program = MPU.program[channel];
2006-05-06 19:19:57 +04:00
for(int i = 0; i < EMUL.remaps; i++)
{
if (((EMUL.remaplist[i].oldbankmsb == bankmsb) ||
(EMUL.remaplist[i].oldbankmsb == 0xff)) &&
((EMUL.remaplist[i].oldbanklsb == banklsb) ||
(EMUL.remaplist[i].oldbanklsb == 0xff)) &&
((EMUL.remaplist[i].oldprogch == program) ||
(EMUL.remaplist[i].oldprogch == 0xff)))
2006-05-06 19:19:57 +04:00
{
writelog(5, "Remapping instrument for channel %d", channel);
if ((EMUL.remaplist[i].newbankmsb != bankmsb) &&
(EMUL.remaplist[i].newbankmsb != 0xff))
2006-05-06 19:19:57 +04:00
{ // write control change bank msb
MPU.bankmsb[channel] = EMUL.remaplist[i].newbankmsb;
commandbytes[0] = 0;
commandbytes[1] = EMUL.remaplist[i].newbankmsb;
writemidicommand(0xb0 | channel, 2, commandbytes);
}
if ((EMUL.remaplist[i].newbanklsb != banklsb) &&
(EMUL.remaplist[i].newbanklsb != 0xff))
2006-05-06 19:19:57 +04:00
{ // write control change bank lsb
MPU.banklsb[channel] = EMUL.remaplist[i].newbanklsb;
commandbytes[0] = 32;
commandbytes[1] = EMUL.remaplist[i].newbanklsb;
writemidicommand(0xb0 | channel, 2, commandbytes);
}
if ((EMUL.remaplist[i].newprogch != program) &&
(EMUL.remaplist[i].newprogch != 0xff))
2006-05-06 19:19:57 +04:00
{ // write program change
MPU.program[channel] = EMUL.remaplist[i].newprogch;
commandbytes[0] = EMUL.remaplist[i].newprogch;
writemidicommand(0xc0 | channel, 1, commandbytes);
}
}
}
}
void bx_sb16_c::closemidioutput()
{
if (BX_SB16_THIS midimode > 0) {
if (MPU.outputinit & 1) {
BX_SB16_MIDIOUT1->closemidioutput();
MPU.outputinit &= ~1;
}
if (MPU.outputinit & 2) {
BX_SB16_MIDIOUT2->closemidioutput();
MPU.outputinit &= ~2;
}
}
}
void bx_sb16_c::closewaveoutput()
{
if (BX_SB16_THIS wavemode > 0) {
if (DSP.outputinit & 2) {
BX_SB16_WAVEOUT2->closewaveoutput();
DSP.outputinit &= ~2;
}
}
}
2006-05-06 19:19:57 +04:00
// static IO port read callback handler
// redirects to non-static class handler to avoid virtual functions
Bit32u bx_sb16_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
{
#if !BX_USE_SB16_SMF
bx_sb16_c *class_ptr = (bx_sb16_c *) this_ptr;
2006-05-06 19:19:57 +04:00
return class_ptr->read(address, io_len);
}
Bit32u bx_sb16_c::read(Bit32u address, unsigned io_len)
{
#else
UNUSED(this_ptr);
#endif // !BX_USE_SB16_SMF
bx_pc_system.isa_bus_delay();
switch (address) {
2006-05-06 19:19:57 +04:00
// 2x0: FM Music Status Port
// 2x8 and 388 are aliases
case BX_SB16_IO + 0x00:
case BX_SB16_IO + 0x08:
case BX_SB16_IOADLIB + 0x00:
return opl_status(0);
2006-05-06 19:19:57 +04:00
// 2x1: reserved (w: FM Music Data Port)
// 2x9 and 389 are aliases
case BX_SB16_IO + 0x01:
case BX_SB16_IO + 0x09:
case BX_SB16_IOADLIB + 0x01:
break;
2006-05-06 19:19:57 +04:00
// 2x2: Advanced Music Status Port
// or (for SBPro1) FM Music Status Port 2
// 38a is an alias
case BX_SB16_IO + 0x02:
case BX_SB16_IOADLIB + 0x02:
return opl_status(1);
2006-05-06 19:19:57 +04:00
// 2x3: reserved (w: Adv. FM Music Data Port)
// or (for SBPro1) FM Music Data Port 2
// 38b is an alias
case BX_SB16_IO + 0x03:
case BX_SB16_IOADLIB + 0x03:
break;
2006-05-06 19:19:57 +04:00
// 2x4: reserved (w: Mixer Register Port)
case BX_SB16_IO + 0x04:
break;
2006-05-06 19:19:57 +04:00
// 2x5: Mixer Data Port
case BX_SB16_IO + 0x05:
return mixer_readdata();
2006-05-06 19:19:57 +04:00
// 2x6: reserved (w: DSP Reset)
case BX_SB16_IO + 0x06:
break;
2006-05-06 19:19:57 +04:00
// 2x7: reserved
case BX_SB16_IO + 0x07:
break;
2006-05-06 19:19:57 +04:00
// 2x8: FM Music Status Port (OPL-2)
// handled above
2006-05-06 19:19:57 +04:00
// 2x9: reserved (w: FM Music Data Port)
// handled above
2006-05-06 19:19:57 +04:00
// 2xa: DSP Read Data Port
case BX_SB16_IO + 0x0a:
return dsp_dataread();
2006-05-06 19:19:57 +04:00
// 2xb: reserved
case BX_SB16_IO + 0x0b:
break;
2006-05-06 19:19:57 +04:00
// 2xc: DSP Buffer Status Port
case BX_SB16_IO + 0x0c:
return dsp_bufferstatus();
2006-05-06 19:19:57 +04:00
// 2xd: reserved
case BX_SB16_IO + 0x0d:
break;
2006-05-06 19:19:57 +04:00
// 2xe: DSP Data Status Port
case BX_SB16_IO + 0x0e:
return dsp_status();
2006-05-06 19:19:57 +04:00
// 2xf: DSP Acknowledge 16bit DMA IRQ
case BX_SB16_IO + 0x0f:
return dsp_irq16ack();
2006-05-06 19:19:57 +04:00
// 3x0: MPU Data Port Read
case BX_SB16_IOMPU + 0x00:
return mpu_dataread();
2006-05-06 19:19:57 +04:00
// 3x1: MPU Status Port
case BX_SB16_IOMPU + 0x01:
return mpu_status();
2006-05-06 19:19:57 +04:00
// 3x2: reserved
case BX_SB16_IOMPU + 0x02:
break;
2006-05-06 19:19:57 +04:00
// 3x3: *Emulator* Port
case BX_SB16_IOMPU + 0x03:
return emul_read();
2003-02-24 21:35:48 +03:00
2006-05-06 19:19:57 +04:00
}
// If we get here, the port wasn't valid
writelog(3, "Read access to 0x%04x: unsupported port!", address);
return(0xff);
}
// static IO port write callback handler
// redirects to non-static class handler to avoid virtual functions
void bx_sb16_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
{
#if !BX_USE_SB16_SMF
bx_sb16_c *class_ptr = (bx_sb16_c *) this_ptr;
class_ptr->write(address, value, io_len);
}
void bx_sb16_c::write(Bit32u address, Bit32u value, unsigned io_len)
{
#else
UNUSED(this_ptr);
#endif // !BX_USE_SB16_SMF
bx_pc_system.isa_bus_delay();
switch (address) {
2006-05-06 19:19:57 +04:00
// 2x0: FM Music Register Port
// 2x8 and 388 are aliases
case BX_SB16_IO + 0x00:
case BX_SB16_IO + 0x08:
case BX_SB16_IOADLIB + 0x00:
OPL.index[0] = value;
adlib_write_index(address, value);
return;
2006-05-06 19:19:57 +04:00
// 2x1: FM Music Data Port
// 2x9 and 389 are aliases
case BX_SB16_IO + 0x01:
case BX_SB16_IO + 0x09:
case BX_SB16_IOADLIB + 0x01:
opl_data(value, 0);
adlib_write(opl_index, value);
return;
2006-05-06 19:19:57 +04:00
// 2x2: Advanced FM Music Register Port
// or (for SBPro1) FM Music Register Port 2
// 38a is an alias
case BX_SB16_IO + 0x02:
case BX_SB16_IOADLIB + 0x02:
OPL.index[1] = value;
adlib_write_index(address, value);
return;
2006-05-06 19:19:57 +04:00
// 2x3: Advanced FM Music Data Port
// or (for SBPro1) FM Music Data Port 2
// 38b is an alias
case BX_SB16_IO + 0x03:
case BX_SB16_IOADLIB + 0x03:
opl_data(value, 1);
adlib_write(opl_index, value);
return;
2006-05-06 19:19:57 +04:00
// 2x4: Mixer Register Port
case BX_SB16_IO + 0x04:
mixer_writeregister(value);
return;
2006-05-06 19:19:57 +04:00
// 2x5: Mixer Data Portr,
case BX_SB16_IO + 0x05:
mixer_writedata(value);
return;
2006-05-06 19:19:57 +04:00
// 2x6: DSP Reset
case BX_SB16_IO + 0x06:
dsp_reset(value);
return;
2006-05-06 19:19:57 +04:00
// 2x7: reserved
case BX_SB16_IO + 0x07:
break;
2006-05-06 19:19:57 +04:00
// 2x8: FM Music Register Port (OPL-2)
// handled above
2006-05-06 19:19:57 +04:00
// 2x9: FM Music Data Port
// handled above
2006-05-06 19:19:57 +04:00
// 2xa: reserved (r: DSP Data Port)
case BX_SB16_IO + 0x0a:
break;
2006-05-06 19:19:57 +04:00
// 2xb: reserved
case BX_SB16_IO + 0x0b:
break;
2006-05-06 19:19:57 +04:00
// 2xc: DSP Write Command/Data
case BX_SB16_IO + 0x0c:
dsp_datawrite(value);
return;
2006-05-06 19:19:57 +04:00
// 2xd: reserved
case BX_SB16_IO + 0x0d:
break;
2006-05-06 19:19:57 +04:00
// 2xe: reserved (r: DSP Buffer Status)
case BX_SB16_IO + 0x0e:
break;
2006-05-06 19:19:57 +04:00
// 2xf: reserved
case BX_SB16_IO + 0x0f:
break;
2006-05-06 19:19:57 +04:00
// 3x0: MPU Command Port
case BX_SB16_IOMPU + 0x00:
mpu_datawrite(value);
return;
2006-05-06 19:19:57 +04:00
// 3x1: MPU Data Port
case BX_SB16_IOMPU + 0x01:
mpu_command(value);
return;
2006-05-06 19:19:57 +04:00
// 3x2: reserved
case BX_SB16_IOMPU + 0x02:
break;
2006-05-06 19:19:57 +04:00
// 3x3: *Emulator* Port
case BX_SB16_IOMPU + 0x03:
emul_write(value);
return;
2006-05-06 19:19:57 +04:00
}
// if we arrive here, the port is unsupported
writelog(3, "Write access to 0x%04x (value = 0x%02x): unsupported port!",
2006-05-06 19:19:57 +04:00
address, value);
}
void bx_sb16_c::create_logfile(void)
{
bx_list_c *base = (bx_list_c*) SIM->get_param(BXPN_SOUND_SB16);
bx_param_string_c *logfile = SIM->get_param_string("log", base);
if (logfile->isempty()) {
SIM->get_param_num("loglevel", base)->set(0);
return;
}
if (SIM->get_param_num("loglevel", base)->get() > 0) {
LOGFILE = fopen(logfile->getptr(),"w"); // logfile for errors etc.
if (LOGFILE == NULL) {
BX_ERROR(("Error opening file %s. Logging disabled.", logfile->getptr()));
SIM->get_param_num("loglevel", base)->set(0);
}
}
}
void bx_sb16_c::writelog(int loglev, const char *str, ...)
{
if ((LOGFILE == NULL) && (BX_SB16_THIS loglevel != 0)) {
create_logfile();
}
2006-05-06 19:19:57 +04:00
// append a line to the log file, if desired
if (BX_SB16_THIS loglevel >= loglev) {
fprintf(LOGFILE, FMT_TICK, bx_pc_system.time_ticks());
fprintf(LOGFILE, " (%d) ", loglev);
va_list ap;
va_start(ap, str);
vfprintf(LOGFILE, str, ap);
va_end(ap);
fprintf(LOGFILE, "\n");
fflush(LOGFILE);
}
}
// the round-robin FIFO buffers of the SB16
bx_sb16_buffer::bx_sb16_buffer()
{
2006-05-06 19:19:57 +04:00
length = 0; // total bytes in buffer
head = 0; // pointer to next slot available for new data
tail = 0; // pointer to next slot to be read from
buffer = NULL; // pointer to the actual data
}
void bx_sb16_buffer::init(int bufferlen)
{
2006-05-06 19:19:57 +04:00
if (buffer != NULL) // Was it initialized before?
delete buffer;
length = bufferlen;
buffer = new Bit8u[length];
if (buffer == NULL)
2006-05-06 19:19:57 +04:00
length = 0; // This will be checked later
reset();
}
void bx_sb16_buffer::reset()
{
2006-05-06 19:19:57 +04:00
head = 0; // Reset the pointers
tail = 0;
clearcommand(); // no current command set
}
2006-05-06 19:19:57 +04:00
bx_sb16_buffer::~bx_sb16_buffer()
{
if (buffer != NULL)
delete [] buffer;
buffer = NULL;
length = 0;
}
// Report how many bytes are available
int bx_sb16_buffer::bytes(void)
{
if (empty() != 0)
return 0; // empty / not initialized
int bytes = head - tail;
if (bytes < 0) bytes += length;
return (bytes);
}
// This puts one byte into the buffer
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::put(Bit8u data)
{
if (full() != 0)
2006-05-06 19:19:57 +04:00
return 0; // buffer full
2006-05-06 19:19:57 +04:00
buffer[head++] = data; // Write data, and increase write pointer
head %= length; // wrap it around so it stays inside the data
2006-05-06 19:19:57 +04:00
return 1; // put was successful
}
// This writes a formatted string to the buffer
2008-12-11 21:01:56 +03:00
bx_bool bx_sb16_buffer::puts(const char *data, ...)
{
if (data == NULL)
return 0; // invalid string
//char string[length];
char *string;
int index = 0;
string = new char[length];
va_list ap;
va_start(ap, data);
vsprintf(string, data, ap);
va_end(ap);
2006-05-06 19:19:57 +04:00
if ((int) strlen(string) >= length)
BX_PANIC(("bx_sb16_buffer: puts() too long!"));
while (string[index] != 0)
2006-05-06 19:19:57 +04:00
{
if (put((Bit8u) string[index]) == 0)
{
delete [] string;
return 0; // buffer full
}
index++;
2006-05-06 19:19:57 +04:00
}
delete [] string;
return 1;
}
// This returns if the buffer is full, i.e. if a put will fail
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::full(void)
{
if (length == 0)
return 1; // not initialized
2006-05-06 19:19:57 +04:00
if (((head + 1) % length) == tail)
return 1; // buffer full
2006-05-06 19:19:57 +04:00
return 0; // buffer has some space left
}
// This reads the next available byte from the buffer
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::get(Bit8u *data)
{
if (empty() != 0)
{
// Buffer is empty. Still, if it was initialized, return
// the last byte again.
if (length > 0)
(*data) = buffer[ (tail - 1) % length ];
2006-05-06 19:19:57 +04:00
return 0; // buffer empty
}
2006-05-06 19:19:57 +04:00
(*data) = buffer[tail++]; // read data and increase read pointer
tail %= length; // and wrap it around to stay inside the data
2006-05-06 19:19:57 +04:00
return 1; // get was successful
}
// Read a word in lo/hi order
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::getw(Bit16u *data)
{
Bit8u dummy;
if (bytes() < 2)
2006-05-06 19:19:57 +04:00
{
if (bytes() == 1)
2006-05-06 19:19:57 +04:00
{
get(&dummy);
*data = (Bit16u) dummy;
}
else
2006-05-06 19:19:57 +04:00
dummy = 0;
return 0;
2006-05-06 19:19:57 +04:00
}
get(&dummy);
*data = (Bit16u) dummy;
get(&dummy);
*data |= ((Bit16u) dummy) << 8;
return 1;
}
// Read a word in hi/lo order
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::getw1(Bit16u *data)
{
Bit8u dummy;
if (bytes() < 2)
2006-05-06 19:19:57 +04:00
{
if (bytes() == 1)
2006-05-06 19:19:57 +04:00
{
get(&dummy);
*data = ((Bit16u) dummy) << 8;
2006-05-06 19:19:57 +04:00
}
else
2006-05-06 19:19:57 +04:00
dummy = 0;
return 0;
2006-05-06 19:19:57 +04:00
}
get(&dummy);
*data = ((Bit16u) dummy) << 8;
get(&dummy);
*data |= (Bit16u) dummy;
return 1;
}
// This returns if the buffer is empty, i.e. if a get will fail
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::empty(void)
{
if (length == 0)
return 1; // not inialized
if (head == tail)
return 1; // buffer empty
2006-05-06 19:19:57 +04:00
return 0; // buffer contains data
}
// Flushes the buffer
void bx_sb16_buffer::flush(void)
{
tail = head;
return;
}
// Peeks ahead in the buffer
// Warning: No checking if result is valid. Must call bytes() to check that!
Bit8u bx_sb16_buffer::peek(int offset)
{
2006-05-06 19:19:57 +04:00
return buffer[(tail + offset) % length];
}
// Set a new active command
void bx_sb16_buffer::newcommand(Bit8u newcmd, int bytes)
{
command = newcmd;
havecommand = 1;
bytesneeded = bytes;
}
// Return the currently active command
Bit8u bx_sb16_buffer::currentcommand(void)
{
return command;
}
// Clear the active command
void bx_sb16_buffer::clearcommand(void)
{
command = 0;
havecommand = 0;
bytesneeded = 0;
}
// return if the command has received all necessary bytes
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::commanddone(void)
{
if (hascommand() == 0)
return 0; // no command pending - not done then
if (bytes() >= bytesneeded)
return 1; // yes, it's done
return 0; // no, it's not
}
// return if there is a command pending
- Apply patch.replace-Boolean rev 1.3. Every "Boolean" is now changed to a "bx_bool" which is always defined as Bit32u on all platforms. In Carbon specific code, Boolean is still used because the Carbon header files define it to unsigned char. - this fixes bug [ 623152 ] MacOSX: Triple Exception Booting win95. The bug was that some code in Bochs depends on Boolean to be a 32 bit value. (This should be fixed, but I don't know all the places where it needs to be fixed yet.) Because Carbon defined Boolean as an unsigned char, Bochs just followed along and used the unsigned char definition to avoid compile problems. This exposed the dependency on 32 bit Boolean on MacOS X only and led to major simulation problems, that could only be reproduced and debugged on that platform. - On the mailing list we debated whether to make all Booleans into "bool" or our own type. I chose bx_bool for several reasons. 1. Unlike C++'s bool, we can guarantee that bx_bool is the same size on all platforms, which makes it much less likely to have more platform-specific simulation differences in the future. (I spent hours on a borrowed MacOSX machine chasing bug 618388 before discovering that different sized Booleans were the problem, and I don't want to repeat that.) 2. We still have at least one dependency on 32 bit Booleans which must be fixed some time, but I don't want to risk introducing new bugs into the simulation just before the 2.0 release. Modified Files: bochs.h config.h.in gdbstub.cc logio.cc main.cc pc_system.cc pc_system.h plugin.cc plugin.h bios/rombios.c cpu/apic.cc cpu/arith16.cc cpu/arith32.cc cpu/arith64.cc cpu/arith8.cc cpu/cpu.cc cpu/cpu.h cpu/ctrl_xfer16.cc cpu/ctrl_xfer32.cc cpu/ctrl_xfer64.cc cpu/data_xfer16.cc cpu/data_xfer32.cc cpu/data_xfer64.cc cpu/debugstuff.cc cpu/exception.cc cpu/fetchdecode.cc cpu/flag_ctrl_pro.cc cpu/init.cc cpu/io_pro.cc cpu/lazy_flags.cc cpu/lazy_flags.h cpu/mult16.cc cpu/mult32.cc cpu/mult64.cc cpu/mult8.cc cpu/paging.cc cpu/proc_ctrl.cc cpu/segment_ctrl_pro.cc cpu/stack_pro.cc cpu/tasking.cc debug/dbg_main.cc debug/debug.h debug/sim2.cc disasm/dis_decode.cc disasm/disasm.h doc/docbook/Makefile docs-html/cosimulation.html fpu/wmFPUemu_glue.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/gui.cc gui/gui.h gui/keymap.cc gui/keymap.h gui/macintosh.cc gui/nogui.cc gui/rfb.cc gui/sdl.cc gui/siminterface.cc gui/siminterface.h gui/term.cc gui/win32.cc gui/wx.cc gui/wxmain.cc gui/wxmain.h gui/x.cc instrument/example0/instrument.cc instrument/example0/instrument.h instrument/example1/instrument.cc instrument/example1/instrument.h instrument/stubs/instrument.cc instrument/stubs/instrument.h iodev/cdrom.cc iodev/cdrom.h iodev/cdrom_osx.cc iodev/cmos.cc iodev/devices.cc iodev/dma.cc iodev/dma.h iodev/eth_arpback.cc iodev/eth_packetmaker.cc iodev/eth_packetmaker.h iodev/floppy.cc iodev/floppy.h iodev/guest2host.h iodev/harddrv.cc iodev/harddrv.h iodev/ioapic.cc iodev/ioapic.h iodev/iodebug.cc iodev/iodev.h iodev/keyboard.cc iodev/keyboard.h iodev/ne2k.h iodev/parallel.h iodev/pci.cc iodev/pci.h iodev/pic.h iodev/pit.cc iodev/pit.h iodev/pit_wrap.cc iodev/pit_wrap.h iodev/sb16.cc iodev/sb16.h iodev/serial.cc iodev/serial.h iodev/vga.cc iodev/vga.h memory/memory.h memory/misc_mem.cc
2002-10-25 15:44:41 +04:00
bx_bool bx_sb16_buffer::hascommand(void)
{
return havecommand;
}
int bx_sb16_buffer::commandbytes(void)
{
return bytesneeded;
}
// runtime parameter handlers
Bit64s bx_sb16_c::sb16_param_handler(bx_param_c *param, int set, Bit64s val)
{
if (set) {
const char *pname = param->get_name();
if (!strcmp(pname, "dmatimer")) {
BX_SB16_THIS dmatimer = (Bit32u)val;
} else if (!strcmp(pname, "loglevel")) {
BX_SB16_THIS loglevel = (int)val;
} else if (!strcmp(pname, "midimode")) {
if (val != BX_SB16_THIS midimode) {
BX_SB16_THIS midi_changed |= 1;
}
} else if (!strcmp(pname, "wavemode")) {
if (val != BX_SB16_THIS wavemode) {
BX_SB16_THIS wave_changed |= 1;
}
} else {
BX_PANIC(("sb16_param_handler called with unexpected parameter '%s'", pname));
}
}
return val;
}
const char* bx_sb16_c::sb16_param_string_handler(bx_param_string_c *param, int set,
const char *oldval, const char *val,
int maxlen)
{
if ((set) && (strcmp(val, oldval))) {
const char *pname = param->get_name();
if (!strcmp(pname, "wavefile")) {
BX_SB16_THIS wave_changed |= 2;
} else if (!strcmp(pname, "midifile")) {
BX_SB16_THIS midi_changed |= 2;
} else if (!strcmp(pname, "log")) {
if (LOGFILE != NULL) {
fclose(LOGFILE);
LOGFILE = NULL;
}
// writelog() re-opens the log file on demand
} else {
BX_PANIC(("sb16_param_string_handler called with unexpected parameter '%s'", pname));
}
}
return val;
}
- apply patch.ifdef-disabled-options. Comments from that patch are below: For a whole lot of configure options, I put #if...#endif around code that is specific to the option, even in files which are normally only compiled when the option is on. This allows me to create a MS Visual C++ 6.0 workspace that supports many of these options. The workspace will basically compile every file all the time, but the code for disabled options will be commented out by the #if...#endif. This may one day lead to simplification of the Makefiles and configure scripts, but for the moment I'm leaving Makefiles and configure scripts alone. Affected options: BX_SUPPORT_APIC (cpu/apic.cc) BX_SUPPORT_X86_64 (cpu/*64.cc) BX_DEBUGGER (debug/*) BX_DISASM (disasm/*) BX_WITH_nameofgui (gui/*) BX_SUPPORT_CDROM (iodev/cdrom.cc) BX_NE2K_SUPPORT (iodev/eth*.cc, iodev/ne2k.cc) BX_SUPPORT_APIC (iodev/ioapic.cc) BX_IODEBUG_SUPPORT (iodev/iodebug.cc) BX_PCI_SUPPORT (iodev/pci*.cc) BX_SUPPORT_SB16 (iodev/sb*.cc) Modified Files: cpu/apic.cc cpu/arith64.cc cpu/ctrl_xfer64.cc cpu/data_xfer64.cc cpu/fetchdecode64.cc cpu/logical64.cc cpu/mult64.cc cpu/resolve64.cc cpu/shift64.cc cpu/stack64.cc debug/Makefile.in debug/crc.cc debug/dbg_main.cc debug/lexer.l debug/linux.cc debug/parser.c debug/parser.y disasm/dis_decode.cc disasm/dis_groups.cc gui/amigaos.cc gui/beos.cc gui/carbon.cc gui/macintosh.cc gui/rfb.cc gui/sdl.cc gui/term.cc gui/win32.cc gui/wx.cc gui/wxdialog.cc gui/wxmain.cc gui/x.cc iodev/cdrom.cc iodev/eth.cc iodev/eth_arpback.cc iodev/eth_fbsd.cc iodev/eth_linux.cc iodev/eth_null.cc iodev/eth_packetmaker.cc iodev/eth_tap.cc iodev/eth_tuntap.cc iodev/eth_win32.cc iodev/ioapic.cc iodev/iodebug.cc iodev/ne2k.cc iodev/pci.cc iodev/pci2isa.cc iodev/sb16.cc iodev/soundlnx.cc iodev/soundwin.cc
2002-11-19 08:47:45 +03:00
#endif /* if BX_SUPPORT_SB16 */