.Page ;++ ;-- TimIt .Equ * Lda #5 ; Time 6 pulses Sta Temp2 Clc ; Should stay clear unless explicitly set Jsr WtZero ; Look for low, then first high Bcs RsOut ; 2,3 10 No edge within timeout period Jsr RsEdge ; 8 8 Now at known locationo Bcs RsOut ; 2,3 10 No edge within timeout period Lda #0 ; 2 12 Sta RangeL ; 3 15 Sta RangeH ; 3 18 Zero both bytes of counter ;++ ; WtZero & RsEdge both have 36 cycles (18.0 uSec) per tick of RangeL:H ;-- $20 Jsr WtZero ; Look for low Bcs RsOut ; 2,3 Jsr RsEdge ; Wait for next edge on pulse Bcs RsOut ; 2,3 Dec Temp2 ; 5 When less than zero then exit Bpl $20 ; 2,3 15*(2+@+%+#) = 180 cycles RsOut .Equ * Rts ; 6 Common exit point WtZero .Equ * Bit K000 ; 3 ccV set to Zero Bvc RsEd ; 3 6 RsEdge .Equ * ; Look for a rising edge Bit K0FF ; 3 3 ccV eq 0 == low, ccV eq 1 == high Bvs ReEd ; 3 6 RsEd .Equ * Ldy #00 ; 2 8 Ldx #0A0 ; 2 10 Constant timeout for pulse counting $10 Dey ; 2 2 Bne $20 ; 2,3 4,5 Dex ; 2 6 Bne $30 ; 2,3 8,9 Sec ; 2 10 When X-reg = 0 then return error Rts $20 Nop ; 2 7 Nop ; 2 9 Waste time $30 Inc RangeL ; 5 14 Bne $40 ; 2,3 16,17 Inc RangeH ; 5 21 Bne $50 ; 3 24 Always taken ?? $40 Pha ; 3 20 Waste more time Pla ; 4 24 $50 Lda Q7L ; 4 Bit7=0 ==>tach low, else tach high Bvc $70 ; 2,3 30,31 ccV ==> look for low Bpl $90 ; 2,3 32,33 If high then fall thru & exit Nop ; 2 34 $60 Rts ; 6 $70 Bpl $60 ; 2,3 33,34 If low then exit $90 Bcc $10 ; 3 36 Always taken?? -- 18.0 uSec loop ChkLrg .Equ * Lda #Lrge ; 5 Sta Temp1 ; For speed adjustment Lda #WLow Beq ChkComm ChkSml .Equ * Lda #Smal ; 1 Sta Temp1 Lda #TLow ;++ ; ChkComm ; if H < TL ; then AdjPlus ; else if H > TL ; then TstHih ; else if L < Tl ; then AdjPlus ; else if L = TL ; then OK ; TstHih ; If H > Th ; then AdjMinus ; else if H <> Th ; then OK ; else if L <= TH ; then OK ; else AdjMinus ;-- ChkComm .Equ * Sta InxPtrL ; Ptr to which constraints ( low of high ) Lda CurClass ; Current track class Asl A ; *2 to address word array Tay Lda RangeH Cmp @InxPtrL,y ; High must be greater than or equal to lowtable,y Bcc AdjPlus ; High byte low, must spin slower Bne TsHih ; High byte greater -- must see if w/in high boundary Inc Lda RangeL Cmp @InxPtrL,y ; Must be greater than or equal to table,y Bcc AdjPlus ; High bytes = and low byte low - slow it down Beq ChkOK ; Both bytes are equal so within range Clc TsHih .Equ * ; ccC=1 if branched to here so add +1 for not 'Iny' Tya Adc #TblJmp ; 9. Tay ; Index now points at high side of range Lda @InxPtrL,y Cmp RangeH ; High byte must be <= high boundary Bcc AdjMinus ; High byte is too high, spin disk faster Bne ChkOK ; If <> then low byte must be w/in range Iny ; Point @ low byte of boundary value Lda @InxPtrL,y Cmp RangeL ; Low byte is too high, spin disk faster ChjkOK .Equ * Clc Rts AdjPlus .Equ * ; ccC = 0 already Ldy CurClass Lda MSpdTbl,y Adc TEmp1 ; Add adjustment value Sta MSpdTbl,y Sec Rts AdjMinus .Equ * Ldy CurClass Lda MSpdTbl,y Sec Sbc Temp1 Sta MSpdTbl,y Sec Rts SpdChk .Equ * ; Main entry point for speed check Lda #WHih ; '11'x Sta InxPtrH Jsr SetTach ; Make sure in Tach sense mode Jsr TimIt ; Time 6 pulses & abort on timeout Bcs SpdErr Jsr ChkLrg ; Must be within +/- 2% Bcc SpdDone Lda #101. ; 100 times total for attempts to adjust Sta Counter $10 Dec Counter Beq SpdErr ; Try for 100 times and abort upon inability to adjust Jsr SetSpeed Lda ScDly Jsr Wait Jsr Timit Bcs SpdErr Jsr ChkLrg Bcs $10 ; Loop until speed within +/- 2% $32 Sec ; Make sure error flag is set Dec Counter Beq SpdErr ; Try for 100 times and abort upon inability to adjust Jsr ChkSml ; Now loop until within +/- .5% Bcc SpdDone Jsr SetSpeed Lda ScDelay Jsr Wait Jsr TimIt Bcc $32 SpdErr .Equ* Lda #SErrTmt SpdDone .Equ * Rts