[comp.sys.amiga.tech] ciatimer.c - Another bug

chk@dretor.dciem.dnd.ca (C. Harald Koch) (01/14/89)

There is a bug in StartCIATimer() that only shows up when you try to switch
to Timer B on either CIA. Here is the offending code:

>/* start the timer, clear pending interrupts, and enable timer A
> * Interrupts */
>StartCIATimer()
>{
>	ciacr &= ~(CIACRAF_RUNMODE);	/* set it to reload on overflow */
>	ciacr |= (CIACRAF_LOAD | CIAICRF_TA);
                                 ^^^^^^^^^^
>	SetICR(CIAResource,CLEAR|CIAICRF_TA);
>	AbleICR(CIAResource, CIAICRF_SETCLR | CIAICRF_TA);
>}

What we are trying to do in this statement is start the timer. To start the
timer, we set bit 0 in the appropriate timer control register (ciacr points
to this).  The flags CIAICRF_TA just *happens* to be bit 0, so this works
for Timer A.  However, CIAICRF_TB is bit 1, which causes the timer B output
to appear on line 7 of the parallel port. On CIAB, this is the disk motor
control, so when we change the code to use TimerB on CIAB, the disk motor
starts, not the timer.

The CIAICRF_ flags are for the interrupt control register, not the timer
control registers. The correct flag in this case is CIACRAF_START or
CIACRBF_START, depending on which timer you are using. The statement becomes

>	ciacr |= (CIACRAF_LOAD | CIACRAF_START);

And everything works hunky-dory.

Note that in StopCIATimer() the START bit is cleared correctly... This bug
seems to be a simple oversight on karl@sugar's part.

Disclaimer: I didn't find this bug; Kodiak pointed it out to me via E-Mail
after I described the symptoms to him. Thanks, Kodiak!
-- 
C. Harald Koch		NTT Systems, Inc., Toronto, Ontario
chk@zorac.dciem.dnd.ca, chk@gpu.utcs.toronto.edu, chk@chkent.UUCP
"I give you my phone number. If you worry, call me. I'll make you happy."