;*** 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. ; NOLIST ; ; RESTRICTED RIGHTS LEGEND ; ------------------------ ; ; "Use, duplication, or disclosure by the ; government is subject to restrictions as set forth ; in paragraph (b) (3) (B) of the Rights in Technical ; Data and Computer Software clause in DAR ; 7-104.9(a). Contractor/manufacturer is Zenith ; Data Systems Corporation of Hilltop Road, St. ; Joseph, Michigan 49085. ; LIST ;** 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 MOV TODHSEC,0 MOV CL,GETSCB ;GET ADDRESS OF CP/M-86 SCB INT BDOSE MOV CPMSCB,BX MOV CX,TODINTL ;INIT SCB DATE & TIME FIELDS LEA SI,TODINT LEA DI,SCBRDAT[BX] CLD REP MOVSB POPF RET ;* TIMER NOT RUNNING TIMERR: LEA SI,TIMERRM CALL PMSG JMP SYSHLT ;** TIMER INTERRUPT HANDLER ; INTTIM: POP CS:ISAVPC ;SET UP INTERRUPT LOCAL STACK CALL ISETSTK PUSHA ;SAVE ALL REGS MOV AX,CS ;GET DS VALUE MOV DS,AX ; 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 JZ $+5 JMP TIM2INT ;* 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 MOV BX,0 ;ADD # TIC'S TO USER TIC COUNTER MOV ES,BX ADD ES:UTICCNT,AX ADC ES:UTICCNT+2,0 IF R8085 CMP R85MEM,0 ;Q. 8085 PROCESSOR RUNNING JE TIM0INT1 ; BR IF NOT MOV ES,R85MEM ;UPDATE 8 BIT'S TICCNT ADD ES: WORD PTR .000BH,AX ADC ES: WORD PTR .000DH,0 ENDIF TIM0INT1: ; 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 PUSH AX ; DESELECT DRIVE MOV AL,0 OUT FDCON,AL MOV DEVCTL,AL POP AX MOV Z207DSEL,0 ;INSURE SLOT CONTAINS 0 MOV Z207HUD,Z207HUDV ;SET HEAD UNLOAD DELAY ; TIM0INT3: CALL TOD ;UPDATE TOD MOV AL,NOT TIMERS0 ;CLEAR INTERRUPT OUT ZTSTAT,AL JMP TIMINTX ;* HANDLE TIMER 2 INTERRUPTS TIM2INT: MOV TIMEFLG,1 ;SET FLAG MOV AL,NOT TIMERS2 ;CLEAR INTERRUPT OUT ZTSTAT,AL JMP TIMINTX ;** TOD - TIME OF DAY HANDLER (UPDATES CP/M-86 SYSTEM CONTROL ; BLOCK DATE AND TIME FIELDS) TOD: MOV DI,CPMSCB ;GET OFFSET OF SCB ADD AX,TODHSEC ;COMPUTE NEW HUNDREDTHS CMP AX,200 ;Q. DID A LOT OF TIME GO BY (2 SEC) JB TOD1 ; BR IF NOT ; PRELIMINARY HANDLING IF >= 2 SEC BETWEEN TIMER INTERRUPTS XOR DX,DX ;COMPUTE MINUTES/SECONDS/HUNDREDTHS MOV CX,100 DIV CX MOV TODHSEC,DX ;UPDATE HUNDREDTHS MOV CL,60 DIV CL MOV CX,AX ; (CH)=SECONDS , (CL)=MINUTES JMPS TOD2 ; UPDATE HUNDREDTHS TOD1: MOV TODHSEC,AX ;UPDATE HUNDREDTHS MOV CX,0100H ;INCREMENT VALUES FOR SECONDS/MINUTES SUB AX,100 ;Q. MORE THAN 1 SEC ; JC TOD9 ; BR IF NOT JNC $+5 JMP TOD9 MOV TODHSEC,AX ;UPDATE HUNDREDTHS ; UPDATE SECONDS TOD2: MOV AX,WORD PTR SCBATS[DI] ;GET ASCII SECONDS FROM SCB XCHG AL,AH AND AX,0F0FH AAD ;CONVERT TO BINARY ADD AL,CH ;ADD IN SECONDS SINCE LAST UPDATE MOV DL,AL ;Q. >= 60 SECONDS SUB DL,60 JC TOD3 ; BR IF NOT MOV AL,DL ;UPDATE SECONDS INC CL ;UPDATE MINUTES INCREMENT TOD3: AAM ;CONVERT TO ASCII XCHG AL,AH OR AX,'00' MOV WORD PTR SCBATS[DI],AX ;SAVE IN SCB AND AX,0F0FH ;SAVE IN PACKED BCD FIELD ALSO SHL AL,1 SHL AL,1 SHL AL,1 SHL AL,1 OR AL,AH MOV SCBRTS[DI],AL ; UPDATE MINUTES CMP CL,0 ;Q. UPDATE MINUTES ; JE TOD9 ; BR IF NOT JNE $+5 JMP TOD9 MOV AX,WORD PTR SCBATM[DI] ;GET ASCII MINUTES FROM SCB XCHG AL,AH AND AX,0F0FH AAD ;CONVERT TO BINARY ADD AL,CL ;ADD IN MINUTES SINCE LAST UPDATE MOV DL,AL ;Q. >= 60 MINUTES SUB DL,60 JC TOD4 ; BR IF NOT MOV AL,DL ;UPDATE MINUTES TOD4: RCR DL,1 ;SAVE CARRY FLAG AAM ;CONVERT TO ASCII XCHG AL,AH OR AX,'00' MOV WORD PTR SCBATM[DI],AX ;SAVE IN SCB AND AX,0F0FH ;SAVE IN PACKED BCD FIELD ALSO SHL AL,1 SHL AL,1 SHL AL,1 SHL AL,1 OR AL,AH MOV SCBRTM[DI],AL ; UPDATE HOURS RCL DL,1 ;RESTORE CARRY ; JC TOD9 ;BR IF NOT TIME TO UPDATE HOURS JNC $+5 JMP TOD9 MOV AX,WORD PTR SCBATH[DI] ;GET HOURS FROM SCB XCHG AL,AH ADD AL,1 ;BUMP BY 1 AAA OR AL,'0' CMP AX,'24' ;Q. >= 24 HOURS JB TOD5 ; BR IF NOT MOV AX,'00' ;UPDATE HOURS TOD5: RCR DL,1 ;SAVE CARRY FLAG XCHG AL,AH ;SAVE IN SCB MOV WORD PTR SCBATH[DI],AX AND AX,0F0FH ;SAVE IN PACKED BCD FIELD ALSO SHL AL,1 SHL AL,1 SHL AL,1 SHL AL,1 OR AL,AH MOV SCBRTH[DI],AL ; UPDATE DAYS RCL DL,1 ;RESTORE CARRY JB TOD9 ;BR IF NOT TIME TO UPDATE DAYS INC SCBRDAT[DI] ;BUMP ROLANDER DATE FIELD MOV AX,WORD PTR SCBAMO[DI] ;DETERMINE # DAYS IN MONTH XCHG AL,AH AND AX,0F0FH AAD MOV BX,AX DEC BX SHL BX,1 MOV DX,TODDAYS[BX] CMP AL,2 ;Q. FEBRUARY JNE TOD6 ; BR IF NOT TEST SCBAYR+1[DI],03H ;Q. LEAP YEAR JNZ TOD6 ; BR IF NOT MOV DX,'29' ;29 DAYS IN MONTH TOD6: MOV AX,WORD PTR SCBADY[DI] ;GET DAYS FROM SCB XCHG AL,AH CMP AX,DX ;Q. ALREADY LAST DAY OF MONTH JB TOD7 ; BR IF NOT MOV AX,'00' ; RESET DAYS TOD7: RCR DL,1 ;SAVE CARRY FLAG ADD AL,1 ;BUMP DAYS AAA OR AL,'0' XCHG AL,AH ;SAVE IN SCB MOV WORD PTR SCBADY[DI],AX ; UPDATE MONTH RCL DL,1 ;RESTORE CARRY FLAG JB TOD9 ;BR IF NOT TIME TO UPDATE MONTHS MOV AX,WORD PTR SCBAMO[DI] ;GET MONTHS FROM SCB XCHG AL,AH ADD AL,1 ;BUMP 1 MONTH AAA OR AL,'0' CMP AX,'13' ;Q. >= 13 MONTHS JB TOD8 ; BR IF NOT MOV AX,'01' ;RESET MONTHS TOD8: XCHG AL,AH ;SAVE IN SCB MOV WORD PTR SCBAMO[DI],AX ; UPDATE YEARS JB TOD9 ;BR IF NOT TIME TO UPDATE YEARS MOV DX,WORD PTR SCBAYR[DI] ;GET YEARS FROM SCB MOV AL,1 ;BUMP 1 YEAR ADD AL,DH AAA MOV DH,AL MOV AL,0 ADC AL,DL AAA MOV AH,DH OR AX,'00' MOV WORD PTR SCBAYR[DI],AX ;SAVE IN SCB ; TOD9: RET ;** 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 MOV AL,AH OUT ZTIMER+PITC2,AL POPF ;RESTORE INTERRUPT STATUS POP AX RET