diff --git a/src/hardware/timer.cpp b/src/hardware/timer.cpp index 06a83a8b..17565188 100644 --- a/src/hardware/timer.cpp +++ b/src/hardware/timer.cpp @@ -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 #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: