;*** TIMER DRIVER ; ; * * * N O T E * * * ; IN ORDER FOR THE 8253 TO HAVE TIME TO PROCESS INFO BETWEEN MULTIPLE ; OUTPUTS AND OUTPUT/INPUTS, A DUMMY INPUT FROM THE DIP SWITCH PORT IS ; DONE TO PROVIDE THE NECESSARY DELAY. ; ;** INITIALIZATION ; INTIM: PUSHF CLI ; MAKE SURE ALL COUNTER READ CYCLES ARE COMPLETED IN AL,ZTIMER+PITC0 IN AL,ZDIPSW IN AL,ZTIMER+PITC0 IN AL,ZDIPSW IN AL,ZTIMER+PITC1 IN AL,ZDIPSW IN AL,ZTIMER+PITC1 IN AL,ZDIPSW IN AL,ZTIMER+PITC2 IN AL,ZDIPSW IN AL,ZTIMER+PITC2 ; INIT COUNTER MODES IN AL,ZDIPSW MOV AL,PITSC0+PITRLW+PITMSW OUT ZTIMER+PITCW,AL ;COUNTER 0 - SQUARE WAVE GENERATOR IN AL,ZDIPSW MOV AL,PITSC1+PITRLW+PITMITC OUT ZTIMER+PITCW,AL ;COUNTER 1 - EVENT COUNTER IN AL,ZDIPSW MOV AL,PITSC2+PITRLW+PITMITC OUT ZTIMER+PITCW,AL ;COUNTER 2 - INT ON TERMINAL COUNT ; INIT COUNTER VALUES IN AL,ZDIPSW MOV AL,0 ;TIMER 1 OUT ZTIMER+PITC1,AL IN AL,ZDIPSW MOV AL,0 OUT ZTIMER+PITC1,AL IN AL,ZDIPSW MOV AX,TIMEVAL ;TIMER 0 OUT ZTIMER+PITC0,AL IN AL,ZDIPSW MOV AL,AH OUT ZTIMER+PITC0,AL ; WAIT FOR FIRST RISING CLOCK FROM COUNTER 0 MOV AL,NOT TIMERS0 OUT ZTSTAT,AL XOR CX,CX INTIM1: IN AL,ZTSTAT TEST AL,TIMERS0 LOOPZ INTIM1 JCXZ TIMERR ; CLEAR ANY PENDING INTERRUPTS MOV AL,NOT (TIMERS0+TIMERS2) OUT ZTSTAT,AL ; INIT WORK VARIABLES MOV TIMEFLG,0 MOV PTICCNT,0 MOV TICCNT,0 MOV TICCNT+2,0 POPF RET ;* TIMER NOT RUNNING TIMERR: LEA SI,TIMERRM CALL PMSG JMP SYSHLT ;** TIMER INTERRUPT HANDLER ; INTTIM: PUSHA ;SAVE ALL REGS MOV AX,CS ;GET DS VALUE MOV DS,AX MOV ES,BANK1 ;GET ES VALUE ; CHECK CAUSE OF INTERRUPT IN AL,ZTSTAT ;GET CAUSE OF TIMER INTERRUPT TEST AL,TIMERS0 ;Q. IS IT TIMER 0 JNZ TIM0INT ; BR IF YES TEST AL,TIMERS2 ;Q. IS IT TIMER 2 JNZ TIM2INT ; BR IF YES ;* TIMER INTERRUPT HANDLER EXIT TIMINTX: POPA JMP INTX2 ;* HANDLE TIMER 0 INTERRUPTS TIM0INT: MOV AL,PITSC1+PITRLCL OUT ZTIMER+PITCW,AL ;LATCH COUNTER 1 VALUE IN AL,ZDIPSW IN AL,ZTIMER+PITC1 ;GET COUNTER 1 VALUE MOV AH,AL IN AL,ZDIPSW IN AL,ZTIMER+PITC1 XCHG AH,AL XCHG PTICCNT,AX ;(AX)=PREVIOUS COUNTER VALUE ;'PTICCNT'=CURRENT COUNTER VALUE SUB AX,PTICCNT ;(AX)=# TIC'S ADD TICCNT,AX ;ADD # TIC'S TO 32 BIT TIC COUNTER ADC TICCNT+2,0 ; HANDLE FUNCTIONS ASSOCIATED WITH Z207 CMP Z207HUD,0 ;Q. HEAD UNLOAD DELAY DONE JE TIM0INT2 ; BR IF YES SUB Z207HUD,AX ; UPDATE VALUE JAE TIM0INT2 MOV Z207HUD,0 TIM0INT2: CMP Z207DSEL,0 ;Q. TIME TO DESELECT DRIVE JE TIM0INT3 ; BR IF NOT SUB Z207DSEL,AX ; UPDATE VALUE JA TIM0INT3 ; BR IF STILL NOT TIME TO DESELECT MOV AL,0 ; DESELECT DRIVE OUT FDCON,AL MOV DEVCTL,AL MOV Z207DSEL,0 ;INSURE SLOT CONTAINS 0 MOV Z207HUD,Z207HUDV ;SET HEAD UNLOAD DELAY TIM0INT3: MOV AL,NOT TIMERS0 ;CLEAR INTERRUPT OUT ZTSTAT,AL JMPS TIMINTX ;* HANDLE TIMER 2 INTERRUPTS TIM2INT: MOV TIMEFLG,1 ;SET FLAG MOV AL,NOT TIMERS2 ;CLEAR INTERRUPT OUT ZTSTAT,AL JMPS TIMINTX ;** DELAY ROUTINES USING TIMER 2 ; ; MAXIMUM DELAY IS 65536*4 uS (~262 mS) ; ; COUNTER VALUE FOR N mS = N*250 ; COUNTER VALUE FOR N uS = (N+3)/4 ;* WDLY - SET TIMER AND WAIT ; ; ENTRY: (AX)=COUNTER VALUE ; EXIT: NONE ; USES: NONE ; WDLY: CALL NWDLY ;SET TIMER WDLY1: CMP TIMEFLG,0 ;Q. TIME UP JE WDLY1 ; BR IF NOT RET ;* NWDLY - SET TIMER RUNNING AND DO NOT WAIT ; ; ENTRY: (AX)=COUNTER VALUE ; EXIT: NONE ; USES: NONE ; NWDLY: PUSH AX PUSH AX MOV AL,PITSC2+PITRLW+PITMITC OUT ZTIMER+PITCW,AL ;SET MODE (ALSO STOPS TIMER 2) IN AL,ZDIPSW POP AX PUSHF ;DISABLE INTERRUPTS CLI MOV TIMEFLG,0 ;CLEAR TIMER 2 FLAG OUT ZTIMER+PITC2,AL ;INSERT TIMER COUNTER VALUE IN AL,ZDIPSW XCHG AL,AH OUT ZTIMER+PITC2,AL POPF ;RESTORE INTERRUPT STATUS POP AX RET