Fix timers. Timer irq will now be removed if a mode 0 is programmed (fixes DSTROY). Added some explanation on why this should happen. Changed the old check to use to old timer mode instead of the new mode.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2261
This commit is contained in:
parent
154ad64370
commit
bc49a1ce91
1 changed files with 24 additions and 8 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: timer.cpp,v 1.32 2005-03-25 11:52:32 qbix79 Exp $ */
|
||||
/* $Id: timer.cpp,v 1.33 2005-08-07 17:33:15 qbix79 Exp $ */
|
||||
|
||||
#include <math.h>
|
||||
#include "dosbox.h"
|
||||
|
@ -121,6 +121,7 @@ static void counter_latch(Bitu counter) {
|
|||
|
||||
|
||||
static void write_latch(Bitu port,Bitu val,Bitu iolen) {
|
||||
//LOG(LOG_PIT,LOG_ERROR)("port %X write:%X state:%X",port,val,pit[port-0x40].write_state);
|
||||
Bitu counter=port-0x40;
|
||||
PIT_Block * p=&pit[counter];
|
||||
if(p->bcd == true) BIN2BCD(p->write_latch);
|
||||
|
@ -152,7 +153,7 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) {
|
|||
switch (counter) {
|
||||
case 0x00: /* Timer hooked to IRQ 0 */
|
||||
if (p->new_mode || p->mode == 0 ) {
|
||||
p->new_mode=false;
|
||||
p->new_mode=false;
|
||||
PIC_AddEvent(PIT0_Event,p->delay);
|
||||
} else LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer set without new control word");
|
||||
LOG(LOG_PIT,LOG_NORMAL)("PIT 0 Timer at %.2f Hz mode %d",1000.0/p->delay,p->mode);
|
||||
|
@ -168,6 +169,7 @@ static void write_latch(Bitu port,Bitu val,Bitu iolen) {
|
|||
}
|
||||
|
||||
static Bitu read_latch(Bitu port,Bitu iolen) {
|
||||
//LOG(LOG_PIT,LOG_ERROR)("port read %X",port);
|
||||
Bit32u counter=port-0x40;
|
||||
if (pit[counter].go_read_latch == true)
|
||||
counter_latch(counter);
|
||||
|
@ -204,6 +206,7 @@ static Bitu read_latch(Bitu port,Bitu iolen) {
|
|||
}
|
||||
|
||||
static void write_p43(Bitu port,Bitu val,Bitu iolen) {
|
||||
//LOG(LOG_PIT,LOG_ERROR)("port 43 %X",val);
|
||||
Bitu latch=(val >> 6) & 0x03;
|
||||
switch (latch) {
|
||||
case 0:
|
||||
|
@ -220,15 +223,28 @@ static void write_p43(Bitu port,Bitu val,Bitu iolen) {
|
|||
} else {
|
||||
pit[latch].read_state = (val >> 4) & 0x03;
|
||||
pit[latch].write_state = (val >> 4) & 0x03;
|
||||
pit[latch].mode = (val >> 1) & 0x07;
|
||||
if (pit[latch].mode>5)
|
||||
pit[latch].mode-=4; //6,7 become 2 and 3
|
||||
if (latch==0) {
|
||||
Bit8u mode = (val >> 1) & 0x07;
|
||||
/* Don't set it directly so counter_output uses the old mode */
|
||||
|
||||
/* If the line goes from low to up => generate irq.
|
||||
* ( BUT needs to stay up until acknowlegded by the cpu!!! therefore: )
|
||||
* If the line goes to low => disable irq.
|
||||
* Mode 0 starts with a low line. (so always disable irq)
|
||||
* Mode 2,3 start with a high line.
|
||||
* counter_output tells if the current counter is high or low
|
||||
* So actually a mode 2 timer enables and disables irq al the time. (not handled) */
|
||||
|
||||
if (mode > 5)
|
||||
mode -= 4; //6,7 become 2 and 3
|
||||
if (latch == 0) {
|
||||
PIC_RemoveEvents(PIT0_Event);
|
||||
if (!counter_output(0) && pit[latch].mode)
|
||||
if (!counter_output(0) && mode)
|
||||
PIC_ActivateIRQ(0);
|
||||
if(!mode)
|
||||
PIC_DeActivateIRQ(0);
|
||||
}
|
||||
pit[latch].new_mode = true;
|
||||
pit[latch].new_mode = true;
|
||||
pit[latch].mode = mode; //Set the correct mode (here)
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
|
|
Loading…
Add table
Reference in a new issue