diff --git a/include/Makefile.am b/include/Makefile.am index b37389c8..2e7808f6 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -24,6 +24,7 @@ mixer.h \ modules.h \ mouse.h \ paging.h \ +pci_bus.h \ pic.h \ programs.h \ render.h \ diff --git a/include/logging.h b/include/logging.h index e645d2ea..7faf84cd 100644 --- a/include/logging.h +++ b/include/logging.h @@ -27,6 +27,7 @@ enum LOG_TYPES { LOG_PIT,LOG_KEYBOARD,LOG_PIC, LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, LOG_IO, + LOG_PCI, LOG_MAX }; @@ -65,6 +66,10 @@ struct LOG void operator()(char const* , double , double , double ) { } void operator()(char const* , double , double , double , double ) { } void operator()(char const* , double , double , double , double , double ) { } + void operator()(char const* , double , double , double , double , double , double ) { } + void operator()(char const* , double , double , double , double , double , double , double) { } + + void operator()(char const* , char const* ) { } void operator()(char const* , char const* , double ) { } @@ -73,7 +78,7 @@ struct LOG void operator()(char const* , double , double, char const* ) { } void operator()(char const* , char const*, char const*) { } - + void operator()(char const* , double , double , double , char const* ) { } }; //add missing operators to here //try to avoid anything smaller than bit32... void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2)); diff --git a/include/pci_bus.h b/include/pci_bus.h new file mode 100644 index 00000000..470114ff --- /dev/null +++ b/include/pci_bus.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2002-2011 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOSBOX_PCI_H +#define DOSBOX_PCI_H + +//#define PCI_FUNCTIONALITY_ENABLED 0 + +#if defined PCI_FUNCTIONALITY_ENABLED + +#define PCI_MAX_PCIDEVICES 10 +#define PCI_MAX_PCIFUNCTIONS 8 + + +class PCI_Device { +private: + Bits pci_id, pci_subfunction; + Bit16u vendor_id, device_id; + + // subdevices declarations, they will respond to pci functions 1 to 7 + // (main device is attached to function 0) + Bitu num_subdevices; + PCI_Device* subdevices[PCI_MAX_PCIFUNCTIONS-1]; + +public: + PCI_Device(Bit16u vendor, Bit16u device); + + Bits PCIId(void) { + return pci_id; + } + Bits PCISubfunction(void) { + return pci_subfunction; + } + Bit16u VendorID(void) { + return vendor_id; + } + Bit16u DeviceID(void) { + return device_id; + } + + void SetPCIId(Bitu number, Bits subfct); + + bool AddSubdevice(PCI_Device* dev); + void RemoveSubdevice(Bits subfct); + + PCI_Device* GetSubdevice(Bits subfct); + + Bit16u NumSubdevices(void) { + if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return PCI_MAX_PCIFUNCTIONS-1; + return num_subdevices; + } + + Bits GetNextSubdeviceNumber(void) { + if (num_subdevices>=PCI_MAX_PCIFUNCTIONS-1) return -1; + return num_subdevices+1; + } + + virtual Bits ParseReadRegister(Bit8u regnum)=0; + virtual Bits ParseWriteRegister(Bit8u regnum,Bit8u value)=0; + virtual bool InitializeRegisters(Bit8u registers[256])=0; + +}; + +bool PCI_IsInitialized(); + +RealPt PCI_GetPModeInterface(void); + +#endif + +#endif diff --git a/src/debug/debug_gui.cpp b/src/debug/debug_gui.cpp index c2fa4576..c57872fb 100644 --- a/src/debug/debug_gui.cpp +++ b/src/debug/debug_gui.cpp @@ -245,6 +245,7 @@ void LOG_StartUp(void) { loggrp[LOG_MISC].front="MISC"; loggrp[LOG_IO].front="IO"; + loggrp[LOG_PCI].front="PCI"; /* Register the log section */ Section_prop * sect=control->AddSection_prop("log",LOG_Init); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index d95de3f8..79fb5db8 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -41,6 +41,7 @@ #include "mapper.h" #include "ints/int10.h" #include "render.h" +#include "pci_bus.h" Config * control; MachineType machine; @@ -73,6 +74,10 @@ void MIXER_Init(Section*); void MIDI_Init(Section*); void HARDWARE_Init(Section*); +#if defined(PCI_FUNCTIONALITY_ENABLED) +void PCI_Init(Section*); +#endif + void KEYBOARD_Init(Section*); //TODO This should setup INT 16 too but ok ;) void JOYSTICK_Init(Section*); @@ -446,6 +451,12 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&VGA_Init); secprop->AddInitFunction(&KEYBOARD_Init); + +#if defined(PCI_FUNCTIONALITY_ENABLED) + secprop=control->AddSection_prop("pci",&PCI_Init,false); //PCI bus +#endif + + secprop=control->AddSection_prop("mixer",&MIXER_Init); Pbool = secprop->Add_bool("nosound",Property::Changeable::OnlyAtStart,false); Pbool->Set_help("Enable silent mode, sound is still emulated though."); diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 5631a06d..1ec7e67d 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -2,12 +2,12 @@ AM_CPPFLAGS = -I$(top_srcdir)/include SUBDIRS = serialport -EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h +EXTRA_DIST = opl.cpp opl.h adlib.h dbopl.h pci_devices.h noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ - memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ + memory.cpp mixer.cpp pcspeaker.cpp pci_bus.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \ cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp dbopl.cpp diff --git a/src/hardware/pci_bus.cpp b/src/hardware/pci_bus.cpp new file mode 100644 index 00000000..f958cda2 --- /dev/null +++ b/src/hardware/pci_bus.cpp @@ -0,0 +1,438 @@ +/* + * Copyright (C) 2002-2011 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +#include "dosbox.h" +#include "inout.h" +#include "mem.h" +#include "pci_bus.h" +#include "setup.h" +#include "debug.h" +#include "callback.h" +#include "regs.h" + + +#if defined(PCI_FUNCTIONALITY_ENABLED) + +static Bit32u pci_caddress=0; // current PCI addressing +static Bitu pci_devices_installed=0; // number of registered PCI devices + +static Bit8u pci_cfg_data[PCI_MAX_PCIDEVICES][PCI_MAX_PCIFUNCTIONS][256]; // PCI configuration data +static PCI_Device* pci_devices[PCI_MAX_PCIDEVICES]; // registered PCI devices + + +// PCI address +// 31 - set for a PCI access +// 30-24 - 0 +// 23-16 - bus number (0x00ff0000) +// 15-11 - device number (slot) (0x0000f800) +// 10- 8 - subfunction number (0x00000700) +// 7- 2 - config register # (0x000000fc) + +static void write_pci_addr(Bitu port,Bitu val,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Write PCI address :=%x",val); + pci_caddress=val; +} + +static void write_pci_register(PCI_Device* dev,Bit8u regnum,Bit8u value) { + // vendor/device/class IDs/header type/etc. are read-only + if ((regnum<0x04) || ((regnum>=0x06) && (regnum<0x0c)) || (regnum==0x0e)) return; + if (dev==NULL) return; + switch (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][0x0e]&0x7f) { // header-type specific handling + case 0x00: + if ((regnum>=0x28) && (regnum<0x30)) return; // subsystem information is read-only + break; + case 0x01: + case 0x02: + default: + break; + } + + // call device routine for special actions and the + // possibility to discard/replace the value that is to be written + Bits parsed_register=dev->ParseWriteRegister(regnum,value); + if (parsed_register>=0) + pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]=(Bit8u)(parsed_register&0xff); +} + +static void write_pci(Bitu port,Bitu val,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Write PCI data :=%x (len %d)",port,val,iolen); + + // check for enabled/bus 0 + if ((pci_caddress & 0x80ff0000) == 0x80000000) { + Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); + Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); + Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); + LOG(LOG_PCI,LOG_NORMAL)(" Write to device %x register %x (function %x) (:=%x)",devnum,regnum,fctnum,val); + + if (devnum>=pci_devices_installed) return; + PCI_Device* masterdev=pci_devices[devnum]; + if (masterdev==NULL) return; + if (fctnum>masterdev->NumSubdevices()) return; + + PCI_Device* dev=masterdev->GetSubdevice(fctnum); + if (dev==NULL) return; + + // write data to PCI device/configuration + switch (iolen) { + case 1: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); break; + case 2: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); + write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); break; + case 4: write_pci_register(dev,regnum+0,(Bit8u)(val&0xff)); + write_pci_register(dev,regnum+1,(Bit8u)((val>>8)&0xff)); + write_pci_register(dev,regnum+2,(Bit8u)((val>>16)&0xff)); + write_pci_register(dev,regnum+3,(Bit8u)((val>>24)&0xff)); break; + } + } +} + + +static Bitu read_pci_addr(Bitu port,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Read PCI address -> %x",pci_caddress); + return pci_caddress; +} + +// read single 8bit value from register file (special register treatment included) +static Bit8u read_pci_register(PCI_Device* dev,Bit8u regnum) { + switch (regnum) { + case 0x00: + return (Bit8u)(dev->VendorID()&0xff); + case 0x01: + return (Bit8u)((dev->VendorID()>>8)&0xff); + case 0x02: + return (Bit8u)(dev->DeviceID()&0xff); + case 0x03: + return (Bit8u)((dev->DeviceID()>>8)&0xff); + + case 0x0e: + return (pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum]&0x7f) | + ((dev->NumSubdevices()>0)?0x80:0x00); + default: + break; + } + + // call device routine for special actions and possibility to discard/remap register + Bits parsed_regnum=dev->ParseReadRegister(regnum); + if ((parsed_regnum>=0) && (parsed_regnum<256)) + return pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][parsed_regnum]; + + return 0xff; +} + +static Bitu read_pci(Bitu port,Bitu iolen) { + LOG(LOG_PCI,LOG_NORMAL)("Read PCI data -> %x",pci_caddress); + + if ((pci_caddress & 0x80ff0000) == 0x80000000) { + Bit8u devnum = (Bit8u)((pci_caddress >> 11) & 0x1f); + Bit8u fctnum = (Bit8u)((pci_caddress >> 8) & 0x7); + Bit8u regnum = (Bit8u)((pci_caddress & 0xfc) + (port & 0x03)); + if (devnum>=pci_devices_installed) return 0xffffffff; + LOG(LOG_PCI,LOG_NORMAL)(" Read from device %x register %x (function %x); addr %x", + devnum,regnum,fctnum,pci_caddress); + + PCI_Device* masterdev=pci_devices[devnum]; + if (masterdev==NULL) return 0xffffffff; + if (fctnum>masterdev->NumSubdevices()) return 0xffffffff; + + PCI_Device* dev=masterdev->GetSubdevice(fctnum); + + if (dev!=NULL) { + switch (iolen) { + case 1: + { + Bit8u val8=read_pci_register(dev,regnum); + return val8; + } + case 2: + { + Bit16u val16=read_pci_register(dev,regnum); + val16|=(read_pci_register(dev,regnum+1)<<8); + return val16; + } + case 4: + { + Bit32u val32=read_pci_register(dev,regnum); + val32|=(read_pci_register(dev,regnum+1)<<8); + val32|=(read_pci_register(dev,regnum+2)<<16); + val32|=(read_pci_register(dev,regnum+3)<<24); + return val32; + } + default: + break; + } + } + } + return 0xffffffff; +} + + +static Bitu PCI_PM_Handler() { + LOG_MSG("PCI PMode handler, function %x",reg_ax); + return CBRET_NONE; +} + + +PCI_Device::PCI_Device(Bit16u vendor, Bit16u device) { + pci_id=-1; + pci_subfunction=-1; + vendor_id=vendor; + device_id=device; + num_subdevices=0; + for (Bitu dct=0;dct=0) && (number=0) && (subfct0) && (subfctNumSubdevices()) { + delete subdevices[subfct-1]; + subdevices[subfct-1]=NULL; + // should adjust things like num_subdevices as well... + } + } +} + +PCI_Device* PCI_Device::GetSubdevice(Bits subfct) { + if (subfct>=PCI_MAX_PCIFUNCTIONS) return NULL; + if (subfct>0) { + if (subfct<=this->NumSubdevices()) return subdevices[subfct-1]; + } else if (subfct==0) { + return this; + } + return NULL; +} + + +// queued devices (PCI device registering requested before the PCI framework was initialized) +static const Bitu max_rqueued_devices=16; +static Bitu num_rqueued_devices=0; +static PCI_Device* rqueued_devices[max_rqueued_devices]; + + +#include "pci_devices.h" + +class PCI:public Module_base{ +private: + bool initialized; + +protected: + IO_WriteHandleObject PCI_WriteHandler[5]; + IO_ReadHandleObject PCI_ReadHandler[5]; + + CALLBACK_HandlerObject callback_pci; + +public: + + PhysPt GetPModeCallbackPointer(void) { + return Real2Phys(callback_pci.Get_RealPointer()); + } + + bool IsInitialized(void) { + return initialized; + } + + // set up port handlers and configuration data + void InitializePCI(void) { + // install PCI-addressing ports + PCI_WriteHandler[0].Install(0xcf8,write_pci_addr,IO_MD); + PCI_ReadHandler[0].Install(0xcf8,read_pci_addr,IO_MD); + // install PCI-register read/write handlers + for (Bitu ct=0;ct<4;ct++) { + PCI_WriteHandler[1+ct].Install(0xcfc+ct,write_pci,IO_MB); + PCI_ReadHandler[1+ct].Install(0xcfc+ct,read_pci,IO_MB); + } + + for (Bitu dev=0; dev=0) { + // specific slot specified, basic check for validity + if (slot>=PCI_MAX_PCIDEVICES) return -1; + } else { + // auto-add to new slot, check if one is still free + if (pci_devices_installed>=PCI_MAX_PCIDEVICES) return -1; + } + + if (!initialized) InitializePCI(); + + if (slot<0) slot=pci_devices_installed; // use next slot + Bits subfunction=0; // main device unless specific already-occupied slot is requested + if (pci_devices[slot]!=NULL) { + subfunction=pci_devices[slot]->GetNextSubdeviceNumber(); + if (subfunction<0) E_Exit("Too many PCI subdevices!"); + } + + if (device->InitializeRegisters(pci_cfg_data[slot][subfunction])) { + device->SetPCIId(slot, subfunction); + if (pci_devices[slot]==NULL) { + pci_devices[slot]=device; + pci_devices_installed++; + } else { + pci_devices[slot]->AddSubdevice(device); + } + + return slot; + } + + return -1; + } + + void Deinitialize(void) { + initialized=false; + pci_devices_installed=0; + num_rqueued_devices=0; + pci_caddress=0; + + for (Bitu dev=0; devNumSubdevices()>0) { + for (Bitu sct=1;sctGetSubdevice(sct); + if (sdev!=NULL) { + if ((sdev->VendorID()==vendor_id) && (sdev->DeviceID()==device_id)) { + pci_devices[dct]->RemoveSubdevice(sct); + } + } + } + } + + if ((pci_devices[dct]->VendorID()==vendor_id) && (pci_devices[dct]->DeviceID()==device_id)) { + delete pci_devices[dct]; + pci_devices[dct]=NULL; + } + } + } + + // check if all devices have been removed + bool any_device_left=false; + for (Bitu dct=0;dct=pci_devices_installed) break; + if (pci_devices[dct]!=NULL) { + any_device_left=true; + break; + } + } + if (!any_device_left) Deinitialize(); + + Bitu last_active_device=PCI_MAX_PCIDEVICES; + for (Bitu dct=0;dct0) { + // register all devices that have been added before the PCI bus was instantiated + for (Bitu dct=0;dctRegisterPCIDevice(rqueued_devices[dct]); + } + num_rqueued_devices=0; + } + } + + ~PCI(){ + initialized=false; + pci_devices_installed=0; + num_rqueued_devices=0; + } + +}; + +static PCI* pci_interface=NULL; + + +PhysPt PCI_GetPModeInterface(void) { + if (pci_interface) { + return pci_interface->GetPModeCallbackPointer(); + } + return 0; +} + +bool PCI_IsInitialized() { + if (pci_interface) return pci_interface->IsInitialized(); + return false; +} + + +void PCI_ShutDown(Section* sec){ + delete pci_interface; + pci_interface=NULL; +} + +void PCI_Init(Section* sec) { + pci_interface = new PCI(sec); + sec->AddDestroyFunction(&PCI_ShutDown,false); +} + +#endif diff --git a/src/hardware/pci_devices.h b/src/hardware/pci_devices.h new file mode 100644 index 00000000..9a026807 --- /dev/null +++ b/src/hardware/pci_devices.h @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2002-2011 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index cf3c6438..d3564c52 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -26,6 +26,7 @@ #include "inout.h" #include "pic.h" #include "hardware.h" +#include "pci_bus.h" #include "joystick.h" #include "mouse.h" #include "setup.h" @@ -354,8 +355,120 @@ static Bitu INT1A_Handler(void) { TandyDAC_Handler(reg_ah); break; case 0xb1: /* PCI Bios Calls */ - LOG(LOG_BIOS,LOG_ERROR)("INT1A:PCI bios call %2X",reg_al); + LOG(LOG_BIOS,LOG_WARN)("INT1A:PCI bios call %2X",reg_al); +#if defined(PCI_FUNCTIONALITY_ENABLED) + switch (reg_al) { + case 0x01: // installation check + if (PCI_IsInitialized()) { + reg_ah=0x00; + reg_al=0x01; // cfg space mechanism 1 supported + reg_bx=0x0210; // ver 2.10 + reg_cx=0x0000; // only one PCI bus + reg_edx=0x20494350; + reg_edi=PCI_GetPModeInterface(); + CALLBACK_SCF(false); + } else { + CALLBACK_SCF(true); + } + break; + case 0x02: { // find device + Bitu devnr=0; + Bitu count=0x100; + Bit32u devicetag=(reg_cx<<16)|reg_dx; + Bits found=-1; + for (Bitu i=0; i<=count; i++) { + IO_WriteD(0xcf8,0x80000000|(i<<8)); // query unique device/subdevice entries + if (IO_ReadD(0xcfc)==devicetag) { + if (devnr==reg_si) { + found=i; + break; + } else { + // device found, but not the SIth device + devnr++; + } + } + } + if (found>=0) { + reg_ah=0x00; + reg_bh=0x00; // bus 0 + reg_bl=(Bit8u)(found&0xff); + CALLBACK_SCF(false); + } else { + reg_ah=0x86; // device not found + CALLBACK_SCF(true); + } + } + break; + case 0x03: { // find device by class code + Bitu devnr=0; + Bitu count=0x100; + Bit32u classtag=reg_ecx&0xffffff; + Bits found=-1; + for (Bitu i=0; i<=count; i++) { + IO_WriteD(0xcf8,0x80000000|(i<<8)); // query unique device/subdevice entries + if (IO_ReadD(0xcfc)!=0xffffffff) { + IO_WriteD(0xcf8,0x80000000|(i<<8)|0x08); + if ((IO_ReadD(0xcfc)>>8)==classtag) { + if (devnr==reg_si) { + found=i; + break; + } else { + // device found, but not the SIth device + devnr++; + } + } + } + } + if (found>=0) { + reg_ah=0x00; + reg_bh=0x00; // bus 0 + reg_bl=(Bit8u)(found&0xff); + CALLBACK_SCF(false); + } else { + reg_ah=0x86; // device not found + CALLBACK_SCF(true); + } + } + break; + case 0x08: // read configuration byte + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + reg_cl=IO_ReadB(0xcfc+(reg_di&3)); + CALLBACK_SCF(false); + break; + case 0x09: // read configuration word + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + reg_cx=IO_ReadW(0xcfc+(reg_di&2)); + CALLBACK_SCF(false); + break; + case 0x0a: // read configuration dword + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + reg_ecx=IO_ReadD(0xcfc+(reg_di&3)); + CALLBACK_SCF(false); + break; + case 0x0b: // write configuration byte + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + IO_WriteB(0xcfc+(reg_di&3),reg_cl); + CALLBACK_SCF(false); + break; + case 0x0c: // write configuration word + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + IO_WriteW(0xcfc+(reg_di&2),reg_cx); + CALLBACK_SCF(false); + break; + case 0x0d: // write configuration dword + IO_WriteD(0xcf8,0x80000000|(reg_bx<<8)|(reg_di&0xfc)); + IO_WriteD(0xcfc+(reg_di&3),reg_ecx); + CALLBACK_SCF(false); + break; + default: + LOG(LOG_BIOS,LOG_ERROR)("INT1A:PCI BIOS: unknown function %x (%x %x %x)", + reg_ax,reg_bx,reg_cx,reg_dx); + CALLBACK_SCF(true); + break; + } +#else CALLBACK_SCF(true); +#endif break; default: LOG(LOG_BIOS,LOG_ERROR)("INT1A:Undefined call %2X",reg_ah); diff --git a/visualc_net/dosbox.vcproj b/visualc_net/dosbox.vcproj index 5a36f2ef..596a464e 100644 --- a/visualc_net/dosbox.vcproj +++ b/visualc_net/dosbox.vcproj @@ -480,6 +480,9 @@ + + @@ -831,6 +834,9 @@ + +