The threshold value for some Commodore 64 loaders
I'm referring to those loaders using an IRQ handler routine and FLAG line(1) interrupt. For some reason, the Threshold value for them is often omitted in docs.
Here there's a note about how to extract it. I will refer to the ASM code of a loader I just found, which uses CIA #1, Timer B. Other loaders may use a different combination, but the results are the same.
Before changing the vector to main IRQ handler (by writing to $FFFE/$FFFF) we have:
LDA #$1F ; disable Timer A interrupt
STA $DC0D ; disable Timer B interrupt
; disable TOD clock alarm interrupt
; disable serial shift register interrupt
; disable FLAG line(1) interrupt
...
LDA #$A0 ; Timer B Countdown start value
STA $DC06
LDA #$03
STA $DC07
The loader's own IRQ handler looks this way:
PHA
TYA
PHA
LDA $DC07
LDY #$11 ; Re-Start Timer B
STY $DC0F ; Force latched value to be loaded to Timer B counter
; Timer B counts microprocessor cycles
INC $D020
EOR #$02 ; Revert bit
LSR
LSR
ROR $A9 ; Move it to MSb of $A9 (Endianess: LSbF)
BCC done ; Whole byte read?
NOP
LDA $DC0D
PLA
TAY
PLA
RTI
What this code does is to compare the Timer B Countdown value with $0200. Since the initial value is $03A0 (clock cycles), and it counts DOWN to 0, if the Countdown is at a value greater than $0200 clock cycles when a pulse received on FLAG line(1), the latter is shorter than $01A0 clock cycles. $01A0 is therefore the Threshold value (in clock cycles).
In our example, the TAP value is then:
TAP threshold byte = Threshold (in microseconds) * 0.123156 = $34
where the Threshold (in microseconds) is Threshold * 1e6/CPUFrequency.
Regards,
Luigi.
(1) on CIA #1, this FLAG line is connected to the Cassette Read line of the Cassette Port.