                .DO     External
                .LSTON
                .Page
;>>>>>>>>>>>>>>>>>>>>>>>>
;>
;>      Module: Selftest
;>
;>      THIS MODULE IS INTENDED TO RUN IN BANK 1
;>
;>      FUNCTION: MtrSpd
;>      FUNCTION: TrackCount
;>      FUNCTION: SctrCount
;>      FUNCTION: RwTest
;>
;>>>>>>>>>>>>>>>>>>>>>>>>
                .LSTOFF
                .FIN
                .DO     Internal
                .LSTON
                .Page
                .FIN
                
SelfTest:       Tm      Excpt_Stat,#PwrRst ;check for power reset
                Jr      Z,ST_MtrSpd
                
                Ld      !r0,Scr_Cntr ;otherwise finish time on disk speed
                Or      !r0,Scr_Cntr+1
                Jr      Z,ST_MtrSpd
                
                 Ld     !r2,Scr_Cntr
                 Ld     !r3,Scr_Cntr+1
                Call    MsWait

ST_MtrSpd:      Call    MtrSpd
                Jr      Nz,Slf_Leave
                
                And     SlfTst_Result,#$FF-Disk_Speed

Slf_Tracks:     Call    TrackCount
                And     SlfTst_Result,#$FF-Servo_Fail
                
Slf_Sectors:    Call    SctrCount
                Jr      Nz,Slf_Leave
                
                And     SlfTst_Result,#$FF-Sector_Cnt
                
Slf_State:      Call    Load_Status ;check state machine static state
                And     !r0,#YMask
                Jr      Nz,Slf_Leave
                
                And     SlfTst_Result,#$FF-State_Fail
                
Slf_RwTest:     Call    RwTest ;see if we can read and write
                Jr      Z,Slf_Leave
                
                And     SlfTst_Result,#$FF-Rw_Fail
                
Slf_Leave:      Jp      Bank_Ret

                .LSTOFF
                .DO     External
                .LSTON
                .Page
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>
;>      Function: MtrSpd  { Motor Speed }
;>
;>      This function is responsible for measuring the motor
;>      speed. This is done by timing the interval between
;>      consectutive index marks.
;>
;>      Inputs: { none }
;>
;>      Outputs:
;>              MtrSpd : BOOLEAN { zero flag NOT set if failure }
;>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .LSTOFF
                .FIN
                .DO     Internal
                .LSTON
                .Page
                .FIN
                

MtrSpd:         And     Irq,#$FF-Irq_Index ;clear old event
                Clr     !r0
                Clr     !r1 ;clear counter
                Ld      !r4,#16 ;load dead man timer
                Clr     !r5
                Call    SetDmt ;entering critcal section - don't hangup!
                
MtrSpd_1:       Tm      Irq,#Irq_Index ;wait for index to come around
                Jr      Z,MtrSpd_1
                
                And     Irq,#$FF-Irq_Index-Irq_Sector ;clear events
                Call    ClrDmt ;leave crtical section
                
MtrSpd_Lp:      Tm      Irq,#Irq_Index ;wait for one rev
                Jr      Nz,MtrSpd_End
                Incw    !!r0            ;.0142 ms/lp or 70.4 cnts/ms
                Decw    !!r4
                Jr      Nz,MtrSpd_Lp
                
MtrSpd_End:      Ld     !rE,!r1
                 Ld     !rD,!r0
                 Ld     !rC,#0
                 Ld     !r2,#.HIBYTE. Div3_19
                 Ld     !r3,#.LOWBYTE. Div3_19
                Call    Bank_Call ;get speed within tolerence in !r2
                .LSTOFF
                .DO     W_10MB
                .LSTON
                Ld      !r0,#1 ;assume failure
                Cp      !r2,#$44 ;accepts speeds between 18.5 ms and 20.5 ms
                Jr      Lt,MtrSpd_Lv
                Cp      !r2,#$4C
                Jr      Gt,MtrSpd_Lv
                Ld      !r0,#0 ;otherwise pass
                .FIN
                .DO     W_20MB+W_40MB
                .LSTON
                Ld      !r0,#1 ;assume failure
                Cp      !r2,#$48 ;accepts speeds between 18.5 ms and 20.5 ms
                Jr      Lt,MtrSpd_Lv
                Cp      !r2,#$4C
                Jr      Gt,MtrSpd_Lv
                Ld      !r0,#0 ;otherwise pass
                .FIN
                
MtrSpd_Lv:      Or      !r0,!r0 ;set flags
                Ret
                
                .LSTOFF
                .DO     External
                .LSTON
                .Page
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>
;>      Function: TrackCount
;>
;>      This function is responsible for counting the number of
;>      tracks that are available on the servo.
;>
;>      Inputs: { none }
;>
;>      Outputs:
;>              TrackCount : BOOLEAN { zero flag NOT set if failure }
;>
;>      Algorithm:
;>
;>      BEGIN
;>       Restore( FormatRecal )
;>       Seek( Cyl=0 )
;>      END
;>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .LSTOFF
                .FIN
                .DO     Internal
                .LSTON
                .Page
                .FIN

TrackCount:
                 Ld     !r2,#.HIBYTE. ResetServo
                 Ld     !r3,#.LOWBYTE. ResetServo
                Call    Bank_Call ;try to get the servo in a nice state
                
                And     DiskStat,#$FF-RdHdrRecal ;don't read any headers!
                
                 Ld     !r0,#DataRecal
                 Ld     !r2,#.HIBYTE. Restore
                 Ld     !r3,#.LOWBYTE. Restore
                Call    Bank_Call
                
                 Ld     !rC,#0 ;cylinder = 0
                 Ld     !rD,#$69
                 Ld     !rE,#0 ;head = 0
                 Ld     !rF,#0 ;sector = 0
                 Ld     !r2,#.HIBYTE. Seek
                 Ld     !r3,#.LOWBYTE. Seek
                Call    Bank_Call
                Ret
                
                .LSTOFF
                .DO     External
                .LSTON
                .Page
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>
;>      Function: SctrCount
;>
;>      This function counts the number of sector marks between
;>      successive index marks and returns a true value if
;>      the number of sectors counted equals NbrSctrs.
;>
;>      Inputs: { none }
;>
;>      Outputs:
;>              SctrCount : BOOLEAN { zero flag is set if true }
;>
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .LSTOFF
                .FIN
                .DO     Internal
                .LSTON
                .Page
                .FIN

SctrCount:
                Clr     !r2 ;count := 0
                
                And     Irq,#$FF-Irq_Index ;clear old index marks

S_Cnt_1:        Tm      Irq,#Irq_Index ;wait for index mark
                Jr      Z,S_Cnt_1
                
                And     Irq,#Irq_Index-Irq_Sector ;clear old events
                
S_Cnt_3:        Tm      Port3,#IndexMark ;While NOT( Index )
                Jr      Nz,S_Cnt_End
                Tm      Irq,#Irq_Sector
                Jr      Z,S_Cnt_3
                Inc     !r2 ;bump the sector count
                And     Irq,#$FF-Irq_Sector
                Jr      S_Cnt_3
                
S_Cnt_End:      Cp      !r2,#NbrSctrs
                
                Ret
                
                .LSTOFF
                .DO     External
                .LSTON
                .Page
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>
;>      Function: RwTest
;>
;>      This test moves the heads over a track away from the data
;>      area { useable data area } and performs a write verify 
;>      on block zero of that track. If a failure occurs, the test
;>      will continue on the next sequential sector on that track
;>      until all sectors have been written to. If there are no 
;>      successful transfers on any of the sectors of this track then
;>      the test is assumed to have failed.
;>
;>      Inputs: { none }
;>
;>      Outputs:
;>              RwTest : BOOLEAN { zero flag set if failure }
;>
;>      Algorithm:
;>
;>      BEGIN
;>       Seek( RwTest track )
;>       REPEAT
;>        IF NOT( WrVer_Common ) AND ( RdErrCnt = 10 )
;>         THEN 
;>          Sector := Sector + 1
;>          IF ( Sector > NbrSctrs )
;>           THEN Done := True
;>         ELSE Done := True
;>       UNTIL Done
;>       IF ( Sector > NbrSctrs )
;>        THEN RwTest := False
;>        ELSE RwTest := True
;>      END
;>              
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .LSTOFF
                .FIN
                .DO     Internal
                .LSTON
                .Page
                .FIN

RwTest:
                Or      DiskStat,#RdHdrRecal
                 Ld     !r0,#DataRecal
                 Ld     !r2,#.HIBYTE. Restore
                 Ld     !r3,#.LOWBYTE. Restore
                Call    Bank_Call
                 Ld     !r5,#0
                Push    Excpt_Stat ;save state
                Jr      Z,RwTest_End
                Pop     Excpt_Stat

RwTest1:        Push    Excpt_Stat
                Or      Excpt_Stat,#Recovery ;let the controller recover errors
                
                 Ld     !rC,#Tst_HiCyl
                 Ld     !rD,#Tst_LoCyl
                 Ld     !rE,#Tst_Head
                 Ld     !rF,#Tst_Sctr
                Call    New_Seek
                
                Ld      !r5,#NbrSctrs
                
RwTest_Lp:       Ld     !r2,#.HIBYTE. Zero_Header
                 Ld     !r3,#.LOWBYTE. Zero_Header
                Call    Bank_Call
                
                Push    !r5
                 Or     DiskStat,#Wr_Op
                 Ld     !r2,#.HIBYTE. WrBlk_Vector
                 Ld     !r3,#.LOWBYTE. WrBlk_Vector
                Call    Bank_Call
                Pop     !r5
                Jr      Z,Rw_Next
                
                Ld      RdErrCnt,#10 ;assume a failure
                Push    !r5
                 And    DiskStat,#$FF-Wr_Op
                 Ld     !r2,#.HIBYTE. RdBlk_Vector
                 Ld     !r3,#.LOWBYTE. RdBlk_Vector
                Call    Bank_Call
                Pop     !r5
                Jr      Nz,RwTest_End
                
                Tm      !r0,#RdNoHdrFnd
                Jr      Nz,Rw_Next
                Ld      !r0,RdErrCnt
                And     !r0,#$0F ;mask off unwanted status
                Cp      !r0,#10
                Jr      Nz,RwTest_End
                
Rw_Next:        Inc     Sector
                Djnz    !r5,RwTest_Lp
                
RwTest_End:      Ld     !r2,#.HIBYTE. Park_Heads
                 Ld     !r3,#.LOWBYTE. Park_Heads
                Call    Bank_Call
                
                Pop     Excpt_Stat ;recover original exception state
                Or      !r5,!r5 ;set zero flag
                Ret
                
                .LSTOFF
                
