From d382abd2090b9cf89e696d6a35820a571cf88df1 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Fri, 25 Mar 2005 11:52:32 +0000 Subject: [PATCH] New configuration layer. Runtime changing of settings. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2160 --- src/hardware/cmos.cpp | 48 ++++++--- src/hardware/disney.cpp | 42 +++++--- src/hardware/dma.cpp | 68 +++++++----- src/hardware/gus.cpp | 168 +++++++++++++++++------------ src/hardware/iohandler.cpp | 58 ++++++++-- src/hardware/joystick.cpp | 27 +++-- src/hardware/memory.cpp | 105 +++++++++--------- src/hardware/mpu401.cpp | 76 ++++++++----- src/hardware/pcspeaker.cpp | 49 ++++++--- src/hardware/sblaster.cpp | 199 ++++++++++++++++++++++------------- src/hardware/serialport.cpp | 37 +++++-- src/hardware/softmodem.cpp | 116 ++++++++++++-------- src/hardware/tandy_sound.cpp | 83 +++++++++------ src/hardware/timer.cpp | 102 ++++++++++-------- 14 files changed, 753 insertions(+), 425 deletions(-) diff --git a/src/hardware/cmos.cpp b/src/hardware/cmos.cpp index 8d51aa41..7bd63844 100644 --- a/src/hardware/cmos.cpp +++ b/src/hardware/cmos.cpp @@ -24,6 +24,7 @@ #include "inout.h" #include "mem.h" #include "bios.h" +#include "setup.h" static struct { Bit8u regs[0x40]; @@ -266,20 +267,37 @@ void CMOS_SetRegister(Bitu regNr, Bit8u val) cmos.regs[regNr] = val; }; -void CMOS_Init(Section* sec) { - IO_RegisterWriteHandler(0x70,cmos_selreg,IO_MB); - IO_RegisterWriteHandler(0x71,cmos_writereg,IO_MB); - IO_RegisterReadHandler(0x71,cmos_readreg,IO_MB); - cmos.timer.enabled=false; - cmos.reg=0xa; - cmos_writereg(0x71,0x26,1); - cmos.reg=0xb; - cmos_writereg(0x71,0,1); - /* Fill in extended memory size */ - Bitu exsize=(MEM_TotalPages()*4)-1024; - cmos.regs[0x17]=(Bit8u)exsize; - cmos.regs[0x18]=(Bit8u)(exsize >> 8); - cmos.regs[0x30]=(Bit8u)exsize; - cmos.regs[0x31]=(Bit8u)(exsize >> 8); + +class CMOS:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[2]; + IO_WriteHandleObject WriteHandler[2]; +public: + CMOS(Section* configuration):Module_base(configuration){ + WriteHandler[0].Install(0x70,cmos_selreg,IO_MB); + WriteHandler[1].Install(0x71,cmos_writereg,IO_MB); + ReadHandler[0].Install(0x71,cmos_readreg,IO_MB); + cmos.timer.enabled=false; + cmos.reg=0xa; + cmos_writereg(0x71,0x26,1); + cmos.reg=0xb; + cmos_writereg(0x71,0,1); + /* Fill in extended memory size */ + Bitu exsize=(MEM_TotalPages()*4)-1024; + cmos.regs[0x17]=(Bit8u)exsize; + cmos.regs[0x18]=(Bit8u)(exsize >> 8); + cmos.regs[0x30]=(Bit8u)exsize; + cmos.regs[0x31]=(Bit8u)(exsize >> 8); + } +}; + +static CMOS* test; + +void CMOS_Destroy(Section* sec){ + delete test; } +void CMOS_Init(Section* sec) { + test = new CMOS(sec); + sec->AddDestroyFunction(&CMOS_Destroy,true); +} diff --git a/src/hardware/disney.cpp b/src/hardware/disney.cpp index d11a7f18..15bd7350 100644 --- a/src/hardware/disney.cpp +++ b/src/hardware/disney.cpp @@ -98,20 +98,36 @@ static void DISNEY_CallBack(Bitu len) { } } +class DISNEY: public Module_base { +private: + IO_ReadHandleObject ReadHandler; + IO_WriteHandleObject WriteHandler; + MixerObject MixerChan; +public: + DISNEY(Section* configuration):Module_base(configuration) { + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("disney")) return; + + WriteHandler.Install(DISNEY_BASE,disney_write,IO_MB,3); + ReadHandler.Install(DISNEY_BASE,disney_read,IO_MB,3); + + disney.chan=MixerChan.Install(&DISNEY_CallBack,7000,"DISNEY"); + + disney.status=0x84; + disney.control=0; + disney.used=0; + disney.last_used=0; + } + ~DISNEY(){ } +}; -void DISNEY_Init(Section* sec) { - MSG_Add("DISNEY_CONFIGFILE_HELP","Nothing to setup yet!\n"); - Section_prop * section=static_cast(sec); - if(!section->Get_bool("disney")) return; +static DISNEY* test; - IO_RegisterWriteHandler(DISNEY_BASE,disney_write,IO_MB,3); - IO_RegisterReadHandler(DISNEY_BASE,disney_read,IO_MB,3); - - disney.chan=MIXER_AddChannel(&DISNEY_CallBack,7000,"DISNEY"); - - disney.status=0x84; - disney.control=0; - disney.used=0; - disney.last_used=0; +static void DISNEY_ShutDown(Section* sec){ + delete test; } +void DISNEY_Init(Section* sec) { + test = new DISNEY(sec); + sec->AddDestroyFunction(&DISNEY_ShutDown,true); +} diff --git a/src/hardware/dma.cpp b/src/hardware/dma.cpp index fc0f3c98..43be4cd8 100644 --- a/src/hardware/dma.cpp +++ b/src/hardware/dma.cpp @@ -23,6 +23,7 @@ #include "dma.h" #include "pic.h" #include "paging.h" +#include "setup.h" DmaChannel *DmaChannels[8]; DmaController *DmaControllers[2]; @@ -254,32 +255,51 @@ again: return done; } - - -void DMA_Init(Section* sec) { - Bitu i; - DmaControllers[0] = new DmaController(0); - DmaControllers[1] = new DmaController(1); - - for(i=0;i<8;i++) { - DmaChannels[i] = new DmaChannel(i,i>=4); - } +class DMA:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[0x22]; + IO_WriteHandleObject WriteHandler[0x22]; +public: + DMA(Section* configuration):Module_base(configuration){ + Bitu i; + DmaControllers[0] = new DmaController(0); + DmaControllers[1] = new DmaController(1); - for (i=0;i<0x10;i++) { - Bitu mask=IO_MB; - if (i<8) mask|=IO_MW; - IO_RegisterWriteHandler(i,DMA_Write_Port,mask); - IO_RegisterReadHandler(i,DMA_Read_Port,mask); - if (machine==MCH_VGA) { - IO_RegisterWriteHandler(0xc0+i*2,DMA_Write_Port,mask); - IO_RegisterReadHandler(0xc0+i*2,DMA_Read_Port,mask); + for(i=0;i<8;i++) { + DmaChannels[i] = new DmaChannel(i,i>=4); + } + + for (i=0;i<0x10;i++) { + Bitu mask=IO_MB; + if (i<8) mask|=IO_MW; + WriteHandler[i].Install(i,DMA_Write_Port,mask); + ReadHandler[i].Install(i,DMA_Read_Port,mask); + if (machine==MCH_VGA) { + WriteHandler[0x10+i].Install(0xc0+i*2,DMA_Write_Port,mask); + ReadHandler[0x10+i].Install(0xc0+i*2,DMA_Read_Port,mask); + } + } + WriteHandler[0x20].Install(0x81,DMA_Write_Port,IO_MB,3); + WriteHandler[0x21].Install(0x89,DMA_Write_Port,IO_MB,3); + + ReadHandler[0x20].Install(0x81,DMA_Read_Port,IO_MB,3); + ReadHandler[0x21].Install(0x89,DMA_Read_Port,IO_MB,3); + } + ~DMA(){ + delete DmaControllers[0]; + delete DmaControllers[1]; + for(Bitu i=0;i<8;i++) { + delete DmaChannels[i]; } } - IO_RegisterWriteHandler(0x81,DMA_Write_Port,IO_MB,3); - IO_RegisterWriteHandler(0x89,DMA_Write_Port,IO_MB,3); +}; - IO_RegisterReadHandler(0x81,DMA_Read_Port,IO_MB,3); - IO_RegisterReadHandler(0x89,DMA_Read_Port,IO_MB,3); +static DMA* test; + +void DMA_Destroy(Section* sec){ + delete test; +} +void DMA_Init(Section* sec) { + test = new DMA(sec); + sec->AddDestroyFunction(&DMA_Destroy); } - - diff --git a/src/hardware/gus.cpp b/src/hardware/gus.cpp index 5d0d525f..895a5f0f 100644 --- a/src/hardware/gus.cpp +++ b/src/hardware/gus.cpp @@ -23,7 +23,7 @@ #include "dma.h" #include "pic.h" #include "setup.h" -#include "programs.h" +#include "shell.h" #include "math.h" #include "regs.h" @@ -791,72 +791,106 @@ static void MakeTables(void) { } } -void GUS_Init(Section* sec) { - if(machine!=MCH_VGA) return; - Section_prop * section=static_cast(sec); - if(!section->Get_bool("gus")) return; - - memset(&myGUS,0,sizeof(myGUS)); - memset(GUSRam,0,1024*1024); - - myGUS.rate=section->Get_int("rate"); - - myGUS.portbase = section->Get_hex("base") - 0x200; - myGUS.dma1 = section->Get_int("dma1"); - myGUS.dma2 = section->Get_int("dma2"); - myGUS.irq1 = section->Get_int("irq1"); - myGUS.irq2 = section->Get_int("irq2"); - strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); - - // We'll leave the MIDI interface to the MPU-401 - // Ditto for the Joystick - // GF1 Synthesizer - - IO_RegisterWriteHandler(0x302 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x302 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x303 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x303 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x304 + GUS_BASE,write_gus,IO_MB|IO_MW); - IO_RegisterReadHandler(0x304 + GUS_BASE,read_gus,IO_MB|IO_MW); - - IO_RegisterWriteHandler(0x305 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x305 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterReadHandler(0x206 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x208 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x208 + GUS_BASE,read_gus,IO_MB); - - IO_RegisterWriteHandler(0x209 + GUS_BASE,write_gus,IO_MB); - - IO_RegisterWriteHandler(0x307 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x307 + GUS_BASE,read_gus,IO_MB); - - // Board Only - - IO_RegisterWriteHandler(0x200 + GUS_BASE,write_gus,IO_MB); - IO_RegisterReadHandler(0x20A + GUS_BASE,read_gus,IO_MB); - IO_RegisterWriteHandler(0x20B + GUS_BASE,write_gus,IO_MB); - -// DmaChannels[myGUS.dma1]->Register_TC_Callback(GUS_DMA_TC_Callback); - - MakeTables(); - - int i; - for(i=0;i<32;i++) { - guschan[i] = new GUSChannels(i); +class GUS:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[8]; + IO_WriteHandleObject WriteHandler[9]; + AutoexecObject autoexecline[2]; + MixerObject MixerChan; +public: + GUS(Section* configuration):Module_base(configuration){ + if(machine!=MCH_VGA) return; + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("gus")) return; + + memset(&myGUS,0,sizeof(myGUS)); + memset(GUSRam,0,1024*1024); + + myGUS.rate=section->Get_int("rate"); + + myGUS.portbase = section->Get_hex("base") - 0x200; + myGUS.dma1 = section->Get_int("dma1"); + myGUS.dma2 = section->Get_int("dma2"); + myGUS.irq1 = section->Get_int("irq1"); + myGUS.irq2 = section->Get_int("irq2"); + strcpy(&myGUS.ultradir[0], section->Get_string("ultradir")); + + // We'll leave the MIDI interface to the MPU-401 + // Ditto for the Joystick + // GF1 Synthesizer + ReadHandler[0].Install(0x302 + GUS_BASE,read_gus,IO_MB); + WriteHandler[0].Install(0x302 + GUS_BASE,write_gus,IO_MB); + + WriteHandler[1].Install(0x303 + GUS_BASE,write_gus,IO_MB); + ReadHandler[1].Install(0x303 + GUS_BASE,read_gus,IO_MB); + + WriteHandler[2].Install(0x304 + GUS_BASE,write_gus,IO_MB|IO_MW); + ReadHandler[2].Install(0x304 + GUS_BASE,read_gus,IO_MB|IO_MW); + + WriteHandler[3].Install(0x305 + GUS_BASE,write_gus,IO_MB); + ReadHandler[3].Install(0x305 + GUS_BASE,read_gus,IO_MB); + + ReadHandler[4].Install(0x206 + GUS_BASE,read_gus,IO_MB); + + WriteHandler[4].Install(0x208 + GUS_BASE,write_gus,IO_MB); + ReadHandler[5].Install(0x208 + GUS_BASE,read_gus,IO_MB); + + WriteHandler[5].Install(0x209 + GUS_BASE,write_gus,IO_MB); + + WriteHandler[6].Install(0x307 + GUS_BASE,write_gus,IO_MB); + ReadHandler[6].Install(0x307 + GUS_BASE,read_gus,IO_MB); + + // Board Only + + WriteHandler[7].Install(0x200 + GUS_BASE,write_gus,IO_MB); + ReadHandler[7].Install(0x20A + GUS_BASE,read_gus,IO_MB); + WriteHandler[8].Install(0x20B + GUS_BASE,write_gus,IO_MB); + + // DmaChannels[myGUS.dma1]->Register_TC_Callback(GUS_DMA_TC_Callback); + + MakeTables(); + + int i; + for(i=0;i<32;i++) { + guschan[i] = new GUSChannels(i); + } + // Register the Mixer CallBack + gus_chan=MixerChan.Install(GUS_CallBack,GUS_RATE,"GUS"); + myGUS.gRegData=0x1; + GUSReset(); + myGUS.gRegData=0x0; + int portat = 0x200+GUS_BASE; + // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 + autoexecline[0].Install("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); + autoexecline[1].Install("SET ULTRADIR=%s", myGUS.ultradir); } - // Register the Mixer CallBack - gus_chan=MIXER_AddChannel(GUS_CallBack,GUS_RATE,"GUS"); - myGUS.gRegData=0x1; - GUSReset(); - myGUS.gRegData=0x0; - int portat = 0x200+GUS_BASE; - // ULTRASND=Port,DMA1,DMA2,IRQ1,IRQ2 - SHELL_AddAutoexec("SET ULTRASND=%3X,%d,%d,%d,%d",portat,myGUS.dma1,myGUS.dma2,myGUS.irq1,myGUS.irq2); - SHELL_AddAutoexec("SET ULTRADIR=%s", myGUS.ultradir); + + + ~GUS() { + if(machine!=MCH_VGA) return; + Section_prop * section=static_cast(m_configuration); + if(!section->Get_bool("gus")) return; + + myGUS.gRegData=0x1; + GUSReset(); + myGUS.gRegData=0x0; + + for(Bitu i=0;i<32;i++) { + delete guschan[i]; + } + + memset(&myGUS,0,sizeof(myGUS)); + memset(GUSRam,0,1024*1024); + } +}; + +static GUS* test; + +void GUS_ShutDown(Section* sec) { + delete test; } - +void GUS_Init(Section* sec) { + test = new GUS(sec); + sec->AddDestroyFunction(&GUS_ShutDown,true); +} diff --git a/src/hardware/iohandler.cpp b/src/hardware/iohandler.cpp index 166c547b..7b10a4c5 100644 --- a/src/hardware/iohandler.cpp +++ b/src/hardware/iohandler.cpp @@ -16,12 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: iohandler.cpp,v 1.16 2005-02-10 10:21:08 qbix79 Exp $ */ - -#include "dosbox.h" -#include "inout.h" +/* $Id: iohandler.cpp,v 1.17 2005-03-25 11:52:32 qbix79 Exp $ */ #include +#include "dosbox.h" +#include "inout.h" +#include "setup.h" #include "cpu.h" #include "../src/cpu/lazyflags.h" #include "callback.h" @@ -105,6 +105,36 @@ void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range) { } } +void IO_ReadHandleObject::Install(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range) { + if(!installed) { + installed=true; + m_port=port; + m_mask=mask; + m_range=range; + IO_RegisterReadHandler(port,handler,mask,range); + } else E_Exit("IO_readHandler allready installed port %x",port); +} + +IO_ReadHandleObject::~IO_ReadHandleObject(){ + if(!installed) return; + IO_FreeReadHandler(m_port,m_mask,m_range); +} + +void IO_WriteHandleObject::Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range) { + if(!installed) { + installed=true; + m_port=port; + m_mask=mask; + m_range=range; + IO_RegisterWriteHandler(port,handler,mask,range); + } else E_Exit("IO_writeHandler allready installed port %x",port); +} + +IO_WriteHandleObject::~IO_WriteHandleObject(){ + if(!installed) return; + IO_FreeWriteHandler(m_port,m_mask,m_range); + //LOG_MSG("FreeWritehandler called with port %X",m_port); +} struct IOF_Entry { Bitu cs; @@ -332,10 +362,26 @@ Bitu IO_ReadD(Bitu port) { else return io_readhandlers[2][port](port,4); }; - -void IO_Init(Section * sect) { +class IO :public Module_base { +public: + IO(Section* configuration):Module_base(configuration){ iof_queue.used=0; IO_FreeReadHandler(0,IO_MA,IO_MAX); IO_FreeWriteHandler(0,IO_MA,IO_MAX); + } + ~IO() + { + //Same as the constructor ? + } +}; + +static IO* test; + +void IO_Destroy(Section* sec) { + delete test; } +void IO_Init(Section * sect) { + test = new IO(sect); + sect->AddDestroyFunction(&IO_Destroy); +} diff --git a/src/hardware/joystick.cpp b/src/hardware/joystick.cpp index 0f571fdc..d364f048 100644 --- a/src/hardware/joystick.cpp +++ b/src/hardware/joystick.cpp @@ -18,6 +18,7 @@ #include "dosbox.h" #include "inout.h" +#include "setup.h" #define RANGE 64 @@ -114,11 +115,25 @@ float JOYSTICK_GetMove_Y(Bitu which) return 0.0f; }; -void JOYSTICK_Init(Section* sec) { - IO_RegisterReadHandler(0x201,read_p201,IO_MB); - IO_RegisterWriteHandler(0x201,write_p201,IO_MB); - stick[0].enabled=false; - stick[1].enabled=false; +class JOYSTICK:public Module_base{ +private: + IO_ReadHandleObject ReadHandler; + IO_WriteHandleObject WriteHandler; +public: + JOYSTICK(Section* configuration):Module_base(configuration){ + ReadHandler.Install(0x201,read_p201,IO_MB); + WriteHandler.Install(0x201,write_p201,IO_MB); + stick[0].enabled=false; + stick[1].enabled=false; + } +}; +static JOYSTICK* test; + +void JOYSTICK_Destroy(Section* sec) { + delete test; } - +void JOYSTICK_Init(Section* sec) { + test = new JOYSTICK(sec); + sec->AddDestroyFunction(&JOYSTICK_Destroy,true); +} diff --git a/src/hardware/memory.cpp b/src/hardware/memory.cpp index dfa06a2d..1795de5b 100644 --- a/src/hardware/memory.cpp +++ b/src/hardware/memory.cpp @@ -16,17 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include -#include -#include +/* $Id: memory.cpp,v 1.37 2005-03-25 11:52:32 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" #include "inout.h" #include "setup.h" #include "paging.h" -#include "vga.h" #define PAGES_IN_BLOCK ((1024*1024)/MEM_PAGE_SIZE) #define MAX_MEMORY 64 @@ -91,13 +87,13 @@ public: flags=PFLAG_READABLE|PFLAG_HASROM; } void writeb(PhysPt addr,Bitu val){ - LOG_MSG("Write %x to rom at %x",val,addr); + LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); } void writew(PhysPt addr,Bitu val){ - LOG_MSG("Write %x to rom at %x",val,addr); + LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); } void writed(PhysPt addr,Bitu val){ - LOG_MSG("Write %x to rom at %x",val,addr); + LOG(LOG_CPU,LOG_ERROR)("Write %x to rom at %x",val,addr); } }; @@ -473,50 +469,65 @@ static Bitu read_p92(Bitu port,Bitu iolen) { return memory.a20.controlport | (memory.a20.enabled ? 0x02 : 0); } +class MEMORY:public Module_base{ +private: + IO_ReadHandleObject ReadHandler; + IO_WriteHandleObject WriteHandler; +public: + MEMORY(Section* configuration):Module_base(configuration){ + Bitu i; + Section_prop * section=static_cast(configuration); + + /* Setup the Physical Page Links */ + Bitu memsize=section->Get_int("memsize"); + + if (memsize < 1) memsize = 1; + /* max 63 to solve problems with certain xms handlers */ + if (memsize > MAX_MEMORY-1) { + LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY - 1); + memsize = MAX_MEMORY-1; + } + MemBase = new Bit8u[memsize*1024*1024]; + if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); + memory.pages = (memsize*1024*1024)/4096; + /* Allocate the data for the different page information blocks */ + memory.phandlers=new PageHandler * [memory.pages]; + memory.mhandles=new MemHandle [memory.pages]; + for (i = 0;i < memory.pages;i++) { + memory.phandlers[i] = &ram_page_handler; + memory.mhandles[i] = 0; //Set to 0 for memory allocation + } + /* Setup rom at 0xc0000-0xc8000 */ + for (i=0xc0;i<0xc8;i++) { + memory.phandlers[i] = &rom_page_handler; + } + /* Setup rom at 0xf0000-0x0x100000 */ + for (i=0xf0;i<0x100;i++) { + memory.phandlers[i] = &rom_page_handler; + } + /* Reset some links */ + memory.links.used = 0; + // A20 Line - PS/2 system control port A + WriteHandler.Install(0x92,write_p92,IO_MB); + ReadHandler.Install(0x92,read_p92,IO_MB); + MEM_A20_Enable(false); + } + ~MEMORY(){ + delete [] MemBase; + delete [] memory.phandlers; + delete [] memory.mhandles; + } +}; + +static MEMORY* test; + static void MEM_ShutDown(Section * sec) { - free(MemBase); + delete test; } void MEM_Init(Section * sec) { - Bitu i; - Section_prop * section=static_cast(sec); - - /* Setup the Physical Page Links */ - Bitu memsize=section->Get_int("memsize"); - - if (memsize<1) memsize=1; - /* max 63 to solve problems with certain xms handlers */ - if (memsize>MAX_MEMORY - 1) { - LOG_MSG("Maximum memory size is %d MB",MAX_MEMORY - 1); - memsize=MAX_MEMORY - 1; - } - MemBase=(HostPt)malloc(memsize*1024*1024); - if (!MemBase) E_Exit("Can't allocate main memory of %d MB",memsize); - memory.pages=(memsize*1024*1024)/4096; - /* Allocate the data for the different page information blocks */ - memory.phandlers=new PageHandler * [memory.pages]; - memory.mhandles=new MemHandle [memory.pages]; - for (i=0;iAddDestroyFunction(&MEM_ShutDown); } - - diff --git a/src/hardware/mpu401.cpp b/src/hardware/mpu401.cpp index 74cb7bf4..5e6c0f4b 100644 --- a/src/hardware/mpu401.cpp +++ b/src/hardware/mpu401.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mpu401.cpp,v 1.14 2005-02-10 10:21:09 qbix79 Exp $ */ +/* $Id: mpu401.cpp,v 1.15 2005-03-25 11:52:32 qbix79 Exp $ */ #include #include "dosbox.h" @@ -30,7 +30,6 @@ void MIDI_RawOutByte(Bit8u data); bool MIDI_Available(void); -static Bitu call_irq9; static void MPU401_Event(Bitu); static void MPU401_Reset(void); static void MPU401_EOIHandler(void); @@ -543,7 +542,7 @@ static void MPU401_EOIHandler(void) { } while ((i++)<16); } -static Bitu INT71_Handler() { +static Bitu MPU401_INT71_Handler() { bool signr=0; if (mpu.state.reset) if (!mpu.queue_used) { // hack for "It came to desert" signr=1; @@ -557,7 +556,7 @@ static Bitu INT71_Handler() { IO_Write(0x20,0x62); if (signr) if (mpu.queue_used==1) ClrQueue(); -return CBRET_NONE; + return CBRET_NONE; } static void MPU401_Reset(void) { @@ -590,28 +589,55 @@ static void MPU401_Reset(void) { for (Bitu i=0;i<8;i++) {mpu.playbuf[i].type=OVERFLOW;mpu.playbuf[i].counter=0;} } -void MPU401_Init(Section* sec) { - call_irq9=CALLBACK_Allocate(); /* Allocate handler for IRQ 9 */ - CALLBACK_Setup(call_irq9,&INT71_Handler,CB_IRET,"irq 9 mpu"); - RealSetVec(0x71,CALLBACK_RealPointer(call_irq9)); +class MPU401:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[2]; + IO_WriteHandleObject WriteHandler[2]; + CALLBACK_HandlerObject callbackhandler; + bool installed; /*as it can fail to install by 2 ways (config and no midi)*/ +public: + MPU401(Section* configuration):Module_base(configuration){ + installed = false; + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("mpu401")) return; + if (!MIDI_Available()) return; + /*Enabled and there is a Midi */ + installed = true; + + /* Install a new irq 9 handler that is more suited for the mpu401 */ + callbackhandler.Install(&MPU401_INT71_Handler,CB_IRET,"irq 9 mpu"); + callbackhandler.Set_RealVec(0x71); - Section_prop * section=static_cast(sec); - if(!section->Get_bool("mpu401")) return; + WriteHandler[0].Install(0x330,&MPU401_WriteData,IO_MB); + WriteHandler[1].Install(0x331,&MPU401_WriteCommand,IO_MB); + ReadHandler[0].Install(0x330,&MPU401_ReadData,IO_MB); + ReadHandler[1].Install(0x331,&MPU401_ReadStatus,IO_MB); + + mpu.queue_used=0; + mpu.queue_pos=0; + mpu.mode=M_UART; + + if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; + /*Set IRQ and unmask it(for timequest/princess maker 2) */ + mpu.irq=9; + PIC_SetIRQMask(mpu.irq,false); + MPU401_Reset(); + } + ~MPU401(){ + if(!installed) return; + Section_prop * section=static_cast(m_configuration); + if(!section->Get_bool("intelligent")) return; + PIC_SetIRQMask(mpu.irq,true); + } +}; - if (!MIDI_Available()) return; +static MPU401* test; - IO_RegisterWriteHandler(0x330,&MPU401_WriteData,IO_MB); - IO_RegisterWriteHandler(0x331,&MPU401_WriteCommand,IO_MB); - IO_RegisterReadHandler(0x330,&MPU401_ReadData,IO_MB); - IO_RegisterReadHandler(0x331,&MPU401_ReadStatus,IO_MB); - - mpu.queue_used=0; - mpu.queue_pos=0; - mpu.mode=M_UART; - - if (!(mpu.intelligent=section->Get_bool("intelligent"))) return; - /*Set IRQ and unmask it(for timequest/princess maker 2) */ - mpu.irq=9; - PIC_SetIRQMask(mpu.irq,false); - MPU401_Reset(); +void MPU401_Destroy(Section* sec){ + delete test; +} + +void MPU401_Init(Section* sec) { + test = new MPU401(sec); + sec->AddDestroyFunction(&MPU401_Destroy,true); } diff --git a/src/hardware/pcspeaker.cpp b/src/hardware/pcspeaker.cpp index 00d2ea62..c6d02cfe 100644 --- a/src/hardware/pcspeaker.cpp +++ b/src/hardware/pcspeaker.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /* $Id: pcspeaker.cpp,v 1.19 2005-02-10 10:21:09 qbix79 Exp $ */ + /* $Id: pcspeaker.cpp,v 1.20 2005-03-25 11:52:32 qbix79 Exp $ */ #include #include "dosbox.h" @@ -304,20 +304,39 @@ static void PCSPEAKER_CallBack(Bitu len) { if(spkr.chan) spkr.chan->Enable(false); } } +class PCSPEAKER:public Module_base { +private: + MixerObject MixerChan; +public: + PCSPEAKER(Section* configuration):Module_base(configuration){ + spkr.chan=0; + Section_prop * section=static_cast(configuration); + if(!section->Get_bool("pcspeaker")) return; + spkr.mode=SPKR_OFF; + spkr.last_ticks=0; + spkr.last_index=0; + spkr.rate=section->Get_int("pcrate"); + spkr.pit_max=(1000.0f/PIT_TICK_RATE)*65535; + spkr.pit_half=spkr.pit_max/2; + spkr.pit_new_max=spkr.pit_max; + spkr.pit_new_half=spkr.pit_half; + spkr.pit_index=0; + spkr.used=0; + /* Register the sound channel */ + spkr.chan=MixerChan.Install(&PCSPEAKER_CallBack,spkr.rate,"SPKR"); + } + ~PCSPEAKER(){ + Section_prop * section=static_cast(m_configuration); + if(!section->Get_bool("pcspeaker")) return; + } +}; +static PCSPEAKER* test; + +void PCSPEAKER_ShutDown(Section* sec){ + delete test; +} void PCSPEAKER_Init(Section* sec) { - Section_prop * section=static_cast(sec); - if(!section->Get_bool("pcspeaker")) return; - spkr.mode=SPKR_OFF; - spkr.last_ticks=0; - spkr.last_index=0; - spkr.rate=section->Get_int("pcrate"); - spkr.pit_max=(1000.0f/PIT_TICK_RATE)*65535; - spkr.pit_half=spkr.pit_max/2; - spkr.pit_new_max=spkr.pit_max; - spkr.pit_new_half=spkr.pit_half; - spkr.pit_index=0; - spkr.used=0; - /* Register the sound channel */ - spkr.chan=MIXER_AddChannel(&PCSPEAKER_CallBack,spkr.rate,"SPKR"); + test = new PCSPEAKER(sec); + sec->AddDestroyFunction(&PCSPEAKER_ShutDown,true); } diff --git a/src/hardware/sblaster.cpp b/src/hardware/sblaster.cpp index c1fc2f5d..49d02c4c 100644 --- a/src/hardware/sblaster.cpp +++ b/src/hardware/sblaster.cpp @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include #include #include "dosbox.h" @@ -27,7 +26,7 @@ #include "hardware.h" #include "setup.h" #include "support.h" -#include "programs.h" +#include "shell.h" #define SB_PIC_EVENTS 0 @@ -98,7 +97,6 @@ struct SB_INFO { Bit8u time_constant; DSP_MODES mode; SB_TYPES type; - OPL_Mode oplmode; struct { bool pending_8bit; bool pending_16bit; @@ -1018,80 +1016,133 @@ static void SBLASTER_CallBack(Bitu len) { break; } } +class SBLASTER: public Module_base { +private: + /* Data */ + IO_ReadHandleObject ReadHandler[0x10]; + IO_WriteHandleObject WriteHandler[0x10]; + AutoexecObject autoexecline; + MixerObject MixerChan; -void SBLASTER_Init(Section* sec) { - Bitu i; - Section_prop * section=static_cast(sec); - const char * sbtype=section->Get_string("type"); - sb.hw.base=section->Get_hex("base"); - sb.hw.irq=section->Get_int("irq"); - sb.hw.dma8=section->Get_int("dma"); - sb.hw.dma16=section->Get_int("hdma"); - sb.mixer.enabled=section->Get_bool("mixer"); - sb.mixer.stereo=false; - if (!strcasecmp(sbtype,"sb1")) sb.type=SBT_1; - else if (!strcasecmp(sbtype,"sb2")) sb.type=SBT_2; - else if (!strcasecmp(sbtype,"sbpro1")) sb.type=SBT_PRO1; - else if (!strcasecmp(sbtype,"sbpro2")) sb.type=SBT_PRO2; - else if (!strcasecmp(sbtype,"sb16")) sb.type=SBT_16; - else if (!strcasecmp(sbtype,"none")) sb.type=SBT_NONE; - else sb.type=SBT_16; + /* Support Functions */ + void Find_Type_And_Opl(Section_prop* config,SB_TYPES& type, OPL_Mode& opl_mode){ + const char * sbtype=config->Get_string("type"); + if (!strcasecmp(sbtype,"sb1")) type=SBT_1; + else if (!strcasecmp(sbtype,"sb2")) type=SBT_2; + else if (!strcasecmp(sbtype,"sbpro1")) type=SBT_PRO1; + else if (!strcasecmp(sbtype,"sbpro2")) type=SBT_PRO2; + else if (!strcasecmp(sbtype,"sb16")) type=SBT_16; + else if (!strcasecmp(sbtype,"none")) type=SBT_NONE; + else type=SBT_16; + + if (machine!=MCH_VGA && type==SBT_16) type=SBT_PRO2; - if (machine!=MCH_VGA && sb.type==SBT_16) sb.type=SBT_PRO2; - - /* OPL/CMS Init */ - const char * omode=section->Get_string("oplmode"); - Bitu oplrate=section->Get_int("oplrate"); - OPL_Mode opl_mode; - if (!strcasecmp(omode,"none")) opl_mode=OPL_none; - else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms; - else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; - else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; - else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3; - /* Else assume auto */ - else { - switch (sb.type) { - case SBT_NONE:opl_mode=OPL_none;break; - case SBT_1:opl_mode=OPL_opl2;break; - case SBT_2:opl_mode=OPL_opl2;break; - case SBT_PRO1:opl_mode=OPL_dualopl2;break; - case SBT_PRO2: - case SBT_16: - opl_mode=OPL_opl3;break; + /* OPL/CMS Init */ + const char * omode=config->Get_string("oplmode"); + if (!strcasecmp(omode,"none")) opl_mode=OPL_none; + else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms; + else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2; + else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2; + else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3; + /* Else assume auto */ + else { + switch (type) { + case SBT_NONE:opl_mode=OPL_none;break; + case SBT_1:opl_mode=OPL_opl2;break; + case SBT_2:opl_mode=OPL_opl2;break; + case SBT_PRO1:opl_mode=OPL_dualopl2;break; + case SBT_PRO2: + case SBT_16: + opl_mode=OPL_opl3;break; + } + } + } +public: + SBLASTER(Section* configuration):Module_base(configuration) { + Bitu i; + Section_prop * section=static_cast(configuration); + sb.hw.base=section->Get_hex("base"); + sb.hw.irq=section->Get_int("irq"); + sb.hw.dma8=section->Get_int("dma"); + sb.hw.dma16=section->Get_int("hdma"); + sb.mixer.enabled=section->Get_bool("mixer"); + Bitu oplrate=section->Get_int("oplrate"); + sb.mixer.stereo=false; + OPL_Mode opl_mode; + Find_Type_And_Opl(section,sb.type,opl_mode); + + switch (opl_mode) { + case OPL_none: + WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); + break; + case OPL_cms: + WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB); + CMS_Init(section,sb.hw.base,oplrate); + break; + case OPL_opl2: + CMS_Init(section,sb.hw.base,oplrate); + case OPL_dualopl2: + case OPL_opl3: + OPL_Init(section,sb.hw.base,opl_mode,oplrate); + break; } - } - switch (opl_mode) { - case OPL_none: - IO_RegisterWriteHandler(0x388,adlib_gusforward,IO_MB); - break; - case OPL_cms: - IO_RegisterWriteHandler(0x388,adlib_gusforward,IO_MB); - CMS_Init(section,sb.hw.base,oplrate); - break; - case OPL_opl2: - CMS_Init(section,sb.hw.base,oplrate); - case OPL_dualopl2: - case OPL_opl3: - OPL_Init(section,sb.hw.base,opl_mode,oplrate); - break; - } - if (sb.type==SBT_NONE) return; - sb.chan=MIXER_AddChannel(&SBLASTER_CallBack,22050,"SB"); - sb.dsp.state=DSP_S_NORMAL; + if (sb.type==SBT_NONE) return; - for (i=4;i<=0xf;i++) { - if (i==8 || i==9) continue; - //Disable mixer ports for lower soundblaster - if ((sb.type==SBT_1 || sb.type==SBT_2) && (i==4 || i==5)) continue; - IO_RegisterReadHandler(sb.hw.base+i,read_sb,IO_MB); - IO_RegisterWriteHandler(sb.hw.base+i,write_sb,IO_MB); - } - DSP_Reset(); - CTMIXER_Reset(); - char hdma[8]=""; - if (sb.type==SBT_16) { - sprintf(hdma,"H%d ",sb.hw.dma16); - } - SHELL_AddAutoexec("SET BLASTER=A%3X I%d D%d %sT%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,hdma,sb.type); + sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB"); + sb.dsp.state=DSP_S_NORMAL; + + for (i=4;i<=0xf;i++) { + if (i==8 || i==9) continue; + //Disable mixer ports for lower soundblaster + if ((sb.type==SBT_1 || sb.type==SBT_2) && (i==4 || i==5)) continue; + ReadHandler[i].Install(sb.hw.base+i,read_sb,IO_MB); + WriteHandler[i].Install(sb.hw.base+i,write_sb,IO_MB); + } + DSP_Reset(); + CTMIXER_Reset(); + char hdma[8]=""; + if (sb.type==SBT_16) { + sprintf(hdma,"H%d ",sb.hw.dma16); + } + autoexecline.Install("SET BLASTER=A%3X I%d D%d %sT%d",sb.hw.base,sb.hw.irq,sb.hw.dma8,hdma,sb.type); + } + + ~SBLASTER() { + Bitu i; + Section_prop * section=static_cast(m_configuration); + OPL_Mode opl_mode; + Find_Type_And_Opl(section,sb.type,opl_mode); + + switch (opl_mode) { + case OPL_none: + + break; + case OPL_cms: + +//TODO CMS_Init(section,sb.hw.base,oplrate); + break; + case OPL_opl2: +//TODO CMS_Init(section,sb.hw.base,oplrate); + case OPL_dualopl2: + case OPL_opl3: +//TODO OPL_Init(section,sb.hw.base,opl_mode,oplrate); + break; + } + + if (sb.type==SBT_NONE) return; + DSP_Reset();//Stop everything + } +}; //End of SBLASTER class + + + + +static SBLASTER* test; +void SBLASTER_ShutDown(Section* sec) { + delete test; } +void SBLASTER_Init(Section* sec) { + test = new SBLASTER(sec); + sec->AddDestroyFunction(&SBLASTER_ShutDown,true); +} diff --git a/src/hardware/serialport.cpp b/src/hardware/serialport.cpp index a6d5cb6c..5fce2f6e 100644 --- a/src/hardware/serialport.cpp +++ b/src/hardware/serialport.cpp @@ -17,7 +17,6 @@ */ #include -#include #include #include "dosbox.h" @@ -235,9 +234,9 @@ CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { initdiv = SERIALBASERATE / bps; UpdateBaudrate(); - for (i=base;i<=(base+8);i++) { - IO_RegisterWriteHandler(i+8,WriteSerial,IO_MB); - IO_RegisterReadHandler(i+8,ReadSerial,IO_MB); + for (i=0;i<=8;i++) { + WriteHandler[i].Install(base+i+8,WriteSerial,IO_MB); + ReadHandler[i].Install(base+i+8,ReadSerial,IO_MB); } rqueue=new CFifo(QUEUE_SIZE); @@ -246,16 +245,32 @@ CSerial::CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps) { CSerial::~CSerial(void) { - + //Remove pointer in list if present + for (CSerial_it it=seriallist.begin();it!=seriallist.end();) + if(this==*it) it=seriallist.erase(it); else it++; + + delete rqueue; + delete tqueue; + }; +class SERIALPORTS:public Module_base{ +public: + SERIALPORTS(Section* configuration):Module_base(configuration){ + TIMER_AddTickHandler(&SERIAL_Update); + } + ~SERIALPORTS(){ + TIMER_DelTickHandler(&SERIAL_Update); + } +}; -void SERIAL_Init(Section* sec) { - unsigned long args = 1; - Section_prop * section=static_cast(sec); +static SERIALPORTS* test; -// if(!section->Get_bool("enabled")) return; - - TIMER_AddTickHandler(&SERIAL_Update); +void SERIAL_Destroy(Section* sec){ + delete test; } +void SERIAL_Init(Section* sec) { + test = new SERIALPORTS(sec); + sec->AddDestroyFunction(&SERIAL_Destroy,false); +} diff --git a/src/hardware/softmodem.cpp b/src/hardware/softmodem.cpp index 6f171c91..38d0486b 100644 --- a/src/hardware/softmodem.cpp +++ b/src/hardware/softmodem.cpp @@ -99,7 +99,6 @@ struct telnetClient { }; -static Bitu call_int14; #if 1 @@ -161,8 +160,15 @@ public: //MIXER_SetMode(mhd.chan,MIXER_16MONO); } - - + + ~CSerialModem(){ + if (mhd.socket) { + SDLNet_TCP_DelSocket(mhd.socketset,mhd.socket); + SDLNet_TCP_Close(mhd.socket); + } + if(mhd.listensocket) SDLNet_TCP_Close(mhd.listensocket); + if(mhd.socketset) SDLNet_FreeSocketSet(mhd.socketset); + } void SendLine(const char *line) { rqueue->addb(0xd); @@ -739,58 +745,76 @@ static Bitu INT14_FOSSIL(void) { } -void MODEM_Init(Section* sec) { - - unsigned long args = 1; - Section_prop * section=static_cast(sec); - - if(!section->Get_bool("modem")) return; - - if(SDLNet_Init()==-1) { - LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); - return; - } - - if(!SDLNetInited) { +class VIRTUAL_MODEM:public Module_base { +private: + CALLBACK_HandlerObject callback; +public: + VIRTUAL_MODEM(Section* configuration):Module_base(configuration){ + Section_prop * section=static_cast(configuration); + csm = NULL; + + if(!section->Get_bool("modem")) return; + if(SDLNet_Init()==-1) { LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); return; } - SDLNetInited = true; + + if(!SDLNetInited) { + if(SDLNet_Init()==-1) { + LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); + return; + } + SDLNetInited = true; + } + + Bit16u comport = section->Get_int("comport"); + + + + switch (comport) { + case 1: + csm = new CSerialModem(0x3f0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 2: + csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 3: + csm = new CSerialModem(0x3e0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + case 4: + csm = new CSerialModem(0x2e0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + default: + // Default to COM2 + csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); + break; + + } + + if(csm != NULL) seriallist.push_back(csm); + + //Enable FOSSIL support (GTERM, etc) + callback.Install(&INT14_FOSSIL,CB_IRET,"int14 fossil"); + callback.Set_RealVec(0x14); } - - Bit16u comport = section->Get_int("comport"); - - csm = NULL; - - switch (comport) { - case 1: - csm = new CSerialModem(0x3f0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 2: - csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 3: - csm = new CSerialModem(0x3e0, 4, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - case 4: - csm = new CSerialModem(0x2e0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - default: - // Default to COM2 - csm = new CSerialModem(0x2f0, 3, 57600, section->Get_string("remote"), section->Get_int("listenport")); - break; - + ~VIRTUAL_MODEM(){ + if(!csm) return; + delete csm; } +}; - if(csm != NULL) seriallist.push_back(csm); +static VIRTUAL_MODEM* test; - //Enable FOSSIL support (GTERM, etc) - call_int14=CALLBACK_Allocate(); - CALLBACK_Setup(call_int14,&INT14_FOSSIL,CB_IRET); - RealSetVec(0x14,CALLBACK_RealPointer(call_int14)); +void MODEM_Destroy(Section* sec){ + delete test; +} + + +void MODEM_Init(Section* sec) { + test = new VIRTUAL_MODEM(sec); + sec->AddDestroyFunction(&MODEM_Destroy,true); } #endif - diff --git a/src/hardware/tandy_sound.cpp b/src/hardware/tandy_sound.cpp index 613ee3f4..ea5165fc 100644 --- a/src/hardware/tandy_sound.cpp +++ b/src/hardware/tandy_sound.cpp @@ -306,40 +306,57 @@ static void SN76496_set_gain(int gain) } - - -void TANDYSOUND_Init(Section* sec) { - if (machine!=MCH_TANDY) return; - Section_prop * section=static_cast(sec); - - IO_RegisterWriteHandler(0xc0,SN76496Write,IO_MB,2); - IO_RegisterWriteHandler(0xc4,TandyDACWrite,IO_MB,4); - - - Bit32u sample_rate = section->Get_int("tandyrate"); - tandy.chan=MIXER_AddChannel(&SN76496Update,sample_rate,"TANDY"); - - tandy.enabled=false; - - Bitu i; - struct SN76496 *R = &sn; - R->SampleRate = sample_rate; - SN76496_set_clock(2386360); - for (i = 0;i < 4;i++) R->Volume[i] = 0; - R->LastRegister = 0; - for (i = 0;i < 8;i+=2) - { - R->Register[i] = 0; - R->Register[i + 1] = 0x0f; /* volume = 0 */ +class TANDYSOUND: public Module_base { +private: + IO_WriteHandleObject WriteHandler[2]; + MixerObject MixerChan; +public: + TANDYSOUND(Section* configuration):Module_base(configuration){ + if (machine!=MCH_TANDY) return; + Section_prop * section=static_cast(configuration); + + WriteHandler[0].Install(0xc0,SN76496Write,IO_MB,2); + WriteHandler[1].Install(0xc4,TandyDACWrite,IO_MB,4); + + + Bit32u sample_rate = section->Get_int("tandyrate"); + tandy.chan=MixerChan.Install(&SN76496Update,sample_rate,"TANDY"); + + tandy.enabled=false; + + Bitu i; + struct SN76496 *R = &sn; + R->SampleRate = sample_rate; + SN76496_set_clock(2386360); + for (i = 0;i < 4;i++) R->Volume[i] = 0; + R->LastRegister = 0; + for (i = 0;i < 8;i+=2) + { + R->Register[i] = 0; + R->Register[i + 1] = 0x0f; /* volume = 0 */ + } + + for (i = 0;i < 4;i++) + { + R->Output[i] = 0; + R->Period[i] = R->Count[i] = R->UpdateStep; + } + R->RNG = NG_PRESET; + R->Output[3] = R->RNG & 1; + SN76496_set_gain(0x1); } + ~TANDYSOUND(){ } +}; - for (i = 0;i < 4;i++) - { - R->Output[i] = 0; - R->Period[i] = R->Count[i] = R->UpdateStep; - } - R->RNG = NG_PRESET; - R->Output[3] = R->RNG & 1; - SN76496_set_gain(0x1); + + +static TANDYSOUND* test; + +void TANDYSOUND_ShutDown(Section* sec) { + delete test; } +void TANDYSOUND_Init(Section* sec) { + test = new TANDYSOUND(sec); + sec->AddDestroyFunction(&TANDYSOUND_ShutDown,true); +} diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index d516bffb..06a83a8b 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -16,17 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: timer.cpp,v 1.31 2005-02-10 10:21:10 qbix79 Exp $ */ +/* $Id: timer.cpp,v 1.32 2005-03-25 11:52:32 qbix79 Exp $ */ +#include #include "dosbox.h" #include "inout.h" #include "pic.h" -#include "bios.h" #include "mem.h" -#include "dosbox.h" #include "mixer.h" #include "timer.h" -#include "math.h" +#include "setup.h" static INLINE void BIN2BCD(Bit16u& val) { Bit16u temp=val%10 + (((val/10)%10)<<4)+ (((val/100)%10)<<8) + (((val/1000)%10)<<12); @@ -245,44 +244,61 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) { } -void TIMER_Init(Section* sect) { - IO_RegisterWriteHandler(0x40,write_latch,IO_MB); -// IO_RegisterWriteHandler(0x41,write_latch,IO_MB); - IO_RegisterWriteHandler(0x42,write_latch,IO_MB); - IO_RegisterWriteHandler(0x43,write_p43,IO_MB); - IO_RegisterReadHandler(0x40,read_latch,IO_MB); - IO_RegisterReadHandler(0x41,read_latch,IO_MB); - IO_RegisterReadHandler(0x42,read_latch,IO_MB); - /* Setup Timer 0 */ - pit[0].cntr=0x10000; - pit[0].write_state = 3; - pit[0].read_state = 3; - pit[0].read_latch=0; - pit[0].write_latch=0; - pit[0].mode=3; - pit[0].bcd = false; - pit[0].go_read_latch = true; +class TIMER:public Module_base{ +private: + IO_ReadHandleObject ReadHandler[4]; + IO_WriteHandleObject WriteHandler[4]; +public: + TIMER(Section* configuration):Module_base(configuration){ + WriteHandler[0].Install(0x40,write_latch,IO_MB); + // WriteHandler[1].Install(0x41,write_latch,IO_MB); + WriteHandler[2].Install(0x42,write_latch,IO_MB); + WriteHandler[3].Install(0x43,write_p43,IO_MB); + ReadHandler[0].Install(0x40,read_latch,IO_MB); + ReadHandler[1].Install(0x41,read_latch,IO_MB); + ReadHandler[2].Install(0x42,read_latch,IO_MB); + /* Setup Timer 0 */ + pit[0].cntr=0x10000; + pit[0].write_state = 3; + pit[0].read_state = 3; + pit[0].read_latch=0; + pit[0].write_latch=0; + pit[0].mode=3; + pit[0].bcd = false; + pit[0].go_read_latch = true; + + pit[1].bcd = false; + pit[1].write_state = 1; + pit[1].read_state = 1; + pit[1].go_read_latch = true; + pit[1].cntr = 18; + pit[1].mode = 2; + pit[1].write_state = 3; + + pit[2].read_latch=0; /* MadTv1 */ + pit[2].write_state = 3; /* Chuck Yeager */ + pit[2].read_state = 3; + pit[2].mode=3; + pit[2].bcd=false; + pit[2].cntr=1320; + pit[2].go_read_latch=true; + + pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); + pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); + pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); + + PIC_AddEvent(PIT0_Event,pit[0].delay); + } + ~TIMER(){ + PIC_RemoveEvents(PIT0_Event); + } +}; +static TIMER* test; - pit[1].bcd = false; - pit[1].write_state = 1; - pit[1].read_state = 1; - pit[1].go_read_latch = true; - pit[1].cntr = 18; - pit[1].mode = 2; - pit[1].write_state = 3; - - pit[2].read_latch=0; /* MadTv1 */ - pit[2].write_state = 3; /* Chuck Yeager */ - pit[2].read_state = 3; - pit[2].mode=3; - pit[2].bcd=false; - pit[2].cntr=1320; - pit[2].go_read_latch=true; - - pit[0].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[0].cntr)); - pit[1].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[1].cntr)); - pit[2].delay=(1000.0f/((float)PIT_TICK_RATE/(float)pit[2].cntr)); - - PIC_AddEvent(PIT0_Event,pit[0].delay); +void TIMER_Destroy(Section* sec){ + delete test; +} +void TIMER_Init(Section* sec) { + test = new TIMER(sec); + sec->AddDestroyFunction(&TIMER_Destroy); } -