From 1c2bf685d7fed0d1059b25b4941d56f57fd8ae6c Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 28 Mar 2004 13:04:45 +0000 Subject: [PATCH] Fix some adlib detection issues when cycles is too high Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1741 --- src/hardware/adlib.cpp | 6 ++++-- src/hardware/fmopl.c | 43 +++++++++++++++++++++++++++--------------- src/hardware/ymf262.c | 42 +++++++++++++++++++++++++++-------------- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/hardware/adlib.cpp b/src/hardware/adlib.cpp index 40505abf..74815639 100644 --- a/src/hardware/adlib.cpp +++ b/src/hardware/adlib.cpp @@ -55,7 +55,8 @@ namespace OPL2 { YM3812TimerOver(val>>8,val & 0xff); } void TimerHandler(int channel,double interval_Sec) { - PIC_AddEvent(TimerOver,1000000*interval_Sec,channel); + if (interval_Sec==0.0) return; + PIC_AddEvent(TimerOver,(Bitu)(1000000.0*interval_Sec),channel); } } #undef OSD_CPU_H @@ -67,7 +68,8 @@ namespace THEOPL3 { YMF262TimerOver(val>>8,val & 0xff); } void TimerHandler(int channel,double interval_Sec) { - PIC_AddEvent(TimerOver,1000000*interval_Sec,channel); + if (interval_Sec==0.0) return; + PIC_AddEvent(TimerOver,(Bitu)(1000000.0*interval_Sec),channel); } } diff --git a/src/hardware/fmopl.c b/src/hardware/fmopl.c index 5a838eb5..94274475 100644 --- a/src/hardware/fmopl.c +++ b/src/hardware/fmopl.c @@ -276,6 +276,7 @@ typedef struct fm_opl_f { UINT8 wavesel; /* waveform select enable flag */ int T[2]; /* timer counters */ + int TC[2]; UINT8 st[2]; /* timer enable */ #if BUILD_Y8950 @@ -1485,27 +1486,27 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v) } else { /* set IRQ mask ,timer enable*/ - UINT8 st1 = v&1; - UINT8 st2 = (v>>1)&1; + OPL->st[0] = v&1; + OPL->st[1] = (v>>1)&1; /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ OPL_STATUS_RESET(OPL, v & 0x78 ); OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); - /* timer 2 */ - if(OPL->st[1] != st2) - { - double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0; - OPL->st[1] = st2; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); - } /* timer 1 */ - if(OPL->st[0] != st1) + if(OPL->st[0]) { - double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0; - OPL->st[0] = st1; + OPL->TC[0]=OPL->T[0]*20; + double interval = (double)OPL->T[0]*OPL->TimerBase; if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); } + /* timer 2 */ + if(OPL->st[1]) + { + OPL->TC[1]=OPL->T[1]*20; + double interval =(double)OPL->T[1]*OPL->TimerBase; + if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); + } } break; #if BUILD_Y8950 @@ -1915,8 +1916,20 @@ static unsigned char OPLRead(FM_OPL *OPL,int a) } #endif - - /* OPL and OPL2 */ + if (OPL->st[0]) { + if (OPL->TC[0]) OPL->TC[0]--; + else { + OPL->TC[0]=OPL->T[0]*20; + OPL_STATUS_SET(OPL,0x40); + } + } + if (OPL->st[1]) { + if (OPL->TC[1]) OPL->TC[1]--; + else { + OPL->TC[1]=OPL->T[1]*20; + OPL_STATUS_SET(OPL,0x40); + } + } return OPL->status & (OPL->statusmask|0x80); } @@ -1999,7 +2012,7 @@ static int OPLTimerOver(FM_OPL *OPL,int c) } } /* reload timer */ - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); +// if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); return OPL->status>>7; } diff --git a/src/hardware/ymf262.c b/src/hardware/ymf262.c index 5ecaa05f..e9bd41f2 100644 --- a/src/hardware/ymf262.c +++ b/src/hardware/ymf262.c @@ -242,6 +242,7 @@ typedef struct { UINT8 rhythm; /* Rhythm mode */ int T[2]; /* timer counters */ + int TC[2]; UINT8 st[2]; /* timer enable */ UINT32 address; /* address register */ @@ -1726,27 +1727,27 @@ static void OPL3WriteReg(OPL3 *chip, int r, int v) } else { /* set IRQ mask ,timer enable */ - UINT8 st1 = v & 1; - UINT8 st2 = (v>>1) & 1; + chip->st[0] = v & 1; + chip->st[1] = (v>>1) & 1; /* IRQRST,T1MSK,t2MSK,x,x,x,ST2,ST1 */ OPL3_STATUS_RESET(chip, v & 0x60); OPL3_STATUSMASK_SET(chip, (~v) & 0x60 ); - /* timer 2 */ - if(chip->st[1] != st2) - { - double interval = st2 ? (double)chip->T[1]*chip->TimerBase : 0.0; - chip->st[1] = st2; - if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+1,interval); - } /* timer 1 */ - if(chip->st[0] != st1) + if(chip->st[0]) { - double interval = st1 ? (double)chip->T[0]*chip->TimerBase : 0.0; - chip->st[0] = st1; + chip->TC[0]=chip->T[0]*20; + double interval = (double)chip->T[0]*chip->TimerBase; if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+0,interval); } + /* timer 2 */ + if(chip->st[1]) + { + chip->TC[1]=chip->T[1]*20; + double interval =(double)chip->T[1]*chip->TimerBase; + if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+1,interval); + } } break; case 0x08: /* x,NTS,x,x, x,x,x,x */ @@ -2440,7 +2441,20 @@ static unsigned char OPL3Read(OPL3 *chip,int a) { if( a==0 ) { - /* status port */ + if (chip->st[0]) { + if (chip->TC[0]) chip->TC[0]--; + else { + chip->TC[0]=chip->T[0]*20; + OPL3_STATUS_SET(chip,0x40); + } + } + if (chip->st[1]) { + if (chip->TC[1]) chip->TC[1]--; + else { + chip->TC[1]=chip->T[1]*20; + OPL3_STATUS_SET(chip,0x40); + } + } return chip->status; } @@ -2460,7 +2474,7 @@ static int OPL3TimerOver(OPL3 *chip,int c) OPL3_STATUS_SET(chip,0x40); } /* reload timer */ - if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+c,(double)chip->T[c]*chip->TimerBase); +// if (chip->TimerHandler) (chip->TimerHandler)(chip->TimerParam+c,(double)chip->T[c]*chip->TimerBase); return chip->status>>7; }