1
0
Fork 0

New configuration layer. Runtime changing of settings.

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2160
This commit is contained in:
Peter Veenstra 2005-03-25 11:52:32 +00:00
parent 3b4e696309
commit d382abd209
14 changed files with 753 additions and 425 deletions

View file

@ -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);
}

View file

@ -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<Section_prop *>(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<Section_prop *>(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);
}

View file

@ -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);
}

View file

@ -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<Section_prop *>(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<Section_prop *>(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<Section_prop *>(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);
}

View file

@ -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 <string.h>
#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);
}

View file

@ -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);
}

View file

@ -16,17 +16,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* $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<Section_prop *>(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<Section_prop *>(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;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
IO_RegisterWriteHandler(0x92,write_p92,IO_MB);
IO_RegisterReadHandler(0x92,read_p92,IO_MB);
MEM_A20_Enable(false);
/* shutdown function */
test = new MEMORY(sec);
sec->AddDestroyFunction(&MEM_ShutDown);
}

View file

@ -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 <string.h>
#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<Section_prop *>(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<Section_prop *>(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<Section_prop *>(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);
}

View file

@ -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 <math.h>
#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<Section_prop *>(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<Section_prop *>(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<Section_prop *>(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);
}

View file

@ -16,7 +16,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <assert.h>
#include <string.h>
#include <math.h>
#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<Section_prop *>(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<Section_prop *>(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<Section_prop *>(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);
}

View file

@ -17,7 +17,6 @@
*/
#include <string.h>
#include <assert.h>
#include <list>
#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<Section_prop *>(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);
}

View file

@ -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<Section_prop *>(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<Section_prop *>(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

View file

@ -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<Section_prop *>(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<Section_prop *>(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);
}

View file

@ -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 <math.h>
#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);
}