; ; file : timer.drv.text ; date : 04-January-1984 kb ; ; INCLUDE FILES USED : ; timer.clk.text ;HAS CALANDER CLOCK CODE ; /ccos/os.gbl.asm.text ;OS GLOBAL EQUATES ; ; 04-06-82 kb Added version date before TIMERDRV - entry point ; 04-23-82 kb Changed IORESULT definitions to use the global file definitions ; 04-23-82 kb Removed volume name from timer.clk.text include ; 06-07-82 kb Changed for new rev. 4 processor board changes, will find the ; correct address to use (either $30FE1 or $30F81) ; added storage loc to save correct address ; 07-07-82 kb Added Header to driver ; 07-07-82 kb Fixed error in equates for different rev board address equates ; 09-20-82 lf Changed write clock to stop/start clock in order to zero ; seconds and tenths fields (in TIMER.CLK.TEXT) ; 08-02-83 kb Added test for skip first flag in interrupt routine. Stream lined ; timer unitstatus routines. ; 11-07-83 kb changed clock read/write for uniplex. ; 11-28-83 kb added timer tick counter in Static Ram ($7DA - long). ; 01-04-84 kb changed the VIA counter value to correct value for system clock. ; 01-05-84 kb chang to clock read code. ; ; INCLUDE OS GLOBALS HERE ; LIST OFF INCLUDE '/CCOS/OS.GBL.ASM.TEXT' LIST ON ; page ; EQUATES FOR ALL TIMER DRIVER SOFTWARE ; ; BIT NUMBER DEFINITIONS ; BITD0 EQU 0 ;BIT 0 BITD1 EQU 1 ;BIT 1 BITD2 EQU 2 ;BIT 2 BITD3 EQU 3 ;BIT 3 BITD4 EQU 4 ;BIT 4 BITD5 EQU 5 ;BIT 5 BITD6 EQU 6 ;BIT 6 BITD7 EQU 7 ;BIT 7 ; ; TIMER INTERRUPT VECTOR ADDRESS ; VECTOR EQU $000074 ;INTERRUPT VECTOR #5 ; ; TIMER TABLE INDICES ; TFLAGS EQU 0 ;TIMER TABLE FLAGS PTRUSRTN EQU 2 ;POINTER TO USER SERVICE ROUTINE TCOUNT EQU 6 ;# OF 50 MS. TICKS BEFORE CALL TDWNCNT EQU 8 ;WORKING DOWN COUNTER REGA4 EQU TDWNCNT+2 ;REGISTER A4 SAVE AREA REGA5 EQU REGA4+4 ;REGISTER A5 SAVE AREA ; ; TIMER TABLE FLAGS BIT DEFINITIONS ; VALIDENT EQU BITD0 ;VALID ENTRY FLAG CONT1SHT EQU BITD1 ;CONTINUOUS/1-SHOT MODE FLAG SKIP1ST EQU BITD2 ;SKIP FIRST CALL FLAG ENBLDSBL EQU BITD3 ;ENABLE/DISABLE FLAG ; ; BELL PARAMETER BLOCK INDICES ; FREQ EQU 0 ;FREQUENCY OF BELL PATTERN EQU 2 ;PATTERN OF SPEAKER ON AND OFFS DURATN EQU 4 ;DURATION OF BELL ; ; INTERNAL FLAG BIT DEFINITIONS ; SHUTOFF EQU BITD0 ;SHUTOFF BELL FLAG ; ; VIA ADDRESSES ; ACR EQU $30F77 ;AUXILLARY CONTROL REGISTER IER EQU $30F7D ;INTERRUPT ENABLE REGISTER IFR EQU $30F7B ;INTERRUPT FLAGS REGISTER T1LL EQU $30F6D ;TIMER 1 LATCH LOW T1LH EQU $30F6F ;TIMER 1 LATCH HIGH T1CL EQU $30F69 ;TIMER 1 COUNTER LOW - READ ONLY T1CH EQU $30F6B ;TIMER 1 COUNTER HIGH T2LL EQU $30F71 ;TIMER 2 LATCH LOW T2CH EQU $30F73 ;TIMER 2 COUNTER HIGH SHIFTREG EQU $30F75 ;SHIFT REGISTER ; ; VIA REGISTER VALUES ; ACRBYTE EQU $40 ;ACR DATA - T1 FREE RUN DISABLE PB7 RUNT2 EQU $10 ;MASK TO COUNT DOWN T2 STOPT2 EQU $EF ;COMPLEMENTED RUNT2 TO STOP T2 DISABL EQU $7F ;DISABLE ALL INTERRUPTS ENBLT1 EQU $C0 ;ENABLE IRQ FOR T1 CLEAR EQU $FF ;CLEAR ALL IFR STAT BITS T2INT EQU $20 ;TIMER #2 INTERRUPT FLAG BIT ;*1/4/83 kb* ; change counter value because system clock is not 16 meg but 16.364 megherz TIME EQU 51137 ;50,000 MICRO SECONDS ;*1/4/83 kb* TIMEH EQU TIME/256 ;HI ORDER BYTE OF TIME VALUE TIMEL EQU TIME-(TIMEH*256) ;LOW ORDER BYTE OF TIME VALUE ; ; CONTEXT SWITCHING DEFINITIONS ; SPNDFLG EQU SCsusreq ;SUSPEND FLAG SPWAITC EQU SCsusinh ;WAIT SUSPEND COUNTED SEMAPHORE CURPROC EQU SCprocno ;CURRENT PROCESS # INDEX PPTBL EQU $BB ;PTR TO PROCESS TABLE SCHEDPTR EQU $BB ;PTR TO ENTRY OF SCHEDULER SCHDA4 EQU $BB ;REG. A4 VALUE FOR SCHEDULER SCHDA5 EQU $BB ;REG. A5 VALUE FOR SCHEDULER ; PTLEN EQU $CC ;LENGTH OF PROCESS TABLE ENTRY NUMREGS EQU 15 ;NUMBER OF REGISTERS SSAVED IN PTBL PTPC EQU NUMREGS*4 ;PROCESS TABLE-PC FIELD PTSR EQU PTPC+4 ;PROCESS TABLE-SR FIELD ; SCHEDSR EQU $2700 ;SCHEDULER SR-NO INTERRUPTS ; ; IORESULT ERROR CODES ; INVPRM EQU IOEuiopm ;INVALID UNIT I/O PARAMETER NOTLEGIT EQU IOEioreq ;NOT LEGITIMATE CALL INVTBLID EQU IOEtblid ;INVALID TABLE ENTRY ID TBLFULL EQU IOEtblfl ;TIMER TABLE FULL INVFNC EQU IOEfnccd ;invalid function code ; ; MISCELLANEOUS EQUATES ; CPticks EQU $7DA ;timer tick counter *kb 11/28/83* UNMCMD EQU 6 ;UNMOUNT COMMAND CODE ENABLEC EQU 4 ;ENABLE FUNCTION CODE CARRYST EQU $01 ;CARRY SET IN CCR ON EQU 1 OFF EQU 0 page ; TIMER INTERRUPT SERVICE ROUTINE ; INTERNAL REGISTER USEAGE : ; A0 - TEMP ; A1 - TEMP ; A2 - TIMER TABLE ADDRESS ; A3 - ADDRESS OF CURRENT ENTRY'S FLAG'S LOW ORDER BYTE ; ; D0 - TEMP ; D1 - TEMP ; D2 - INDEX TO CURRENT ENTRY IN TIMER TABLE ; page ; ; TIMER INTERRUPT SERVICE ROUTINE ; THIS ROUTINE IS INVOKED WHEN THE 50 MILLISECOND INTERVAL TIMER INTERRUPT ; OCCURS. IT CHECKS EACH ENTRY OF THE TIMER TABLE TO SEE IF IT'S USER SERVICE ; ROUTINE SHOULD BE CALLED. ; TIMINT MOVEM.L D0-D7/A0-A6,-(SP) ;SAVE USER'S REGISTERS MOVE.B T1CL.L,D0 ;RESET VIA IFR T2 BIT ADDQ.L #1, CPticks.W ;count ints *kb 11/28/83* ; ; for i := 1 to NUMENTS do ; LEA TIMERTBL,A2 ;ADDRESS OF TIMER TABLE CLR.L D2 ;START WITH FIRST ENTRY ; ; IF HAVE VALID ENTRY THAT IS NOT DISABLE THEN SEE IF SHOULD CALL USER SERVICE ROUTINE ; TINEXT LEA TFLAGS+1(A2,D2.W),A3 ;ADDRESS OF CURRENT FLAGS + 1 BTST #VALIDENT,(A3) ;VALID ENTRY? BOFF.S TICHKNXT ;NO, SEE IF ANOTHER ENTRY *kb 8/2/83* BTST #ENBLDSBL,(A3) ;IS ENTRY ENABLED? BON.S TICHKNXT ;NO, SEE IF ANOTHER ENTRY *kb 8/2/83* ; ; GOT VALID ENTRY - TEST IF SHOULD CALL USER SERVICE ROUTINE ; SUBQ.W #1,TDWNCNT(A2,D2.W) ;DOWN COUNT *kb 8/2/83* BNE.S TICHKNXT ;NOT DONE, SEE IF ANOTHER ENTRY BCLR #SKIP1ST, (A3) ;should Skip first? *kb 8/2/83* BON.S TICHKNXT ;yes, see if another entry *kb 8/2/83* ; MOVEM.L D2/A2-A3,-(SP) ;SAVE WORKING REGISTERS MOVEA.L REGA4(A2,D2.W),A4 ;SETUP USERS A4 AND A5 MOVEA.L REGA5(A2,D2.W),A5 ;REGISTERS MOVEA.L PTRUSRTN(A2,D2.W),A0 ;ADDRESS USER SERVICE ROUTINE JSR (A0) ;CALL USER SERVICE ROUTINE MOVEM.L (SP)+,D2/A2-A3 ;RESTORE REGISTERS ; ; RESET DOWN COUNTER - ASSUME CONTINUOUS MODE ; MOVE.W TCOUNT(A2,D2.W),TDWNCNT(A2,D2.W) ; ; IF ENTRY IS IN 1 SHOT MODE THEN DELETE THE ENTRY. ; BTST #CONT1SHT,(A3) ;1 SHOT MODE? BEQ.S TICHKNXT ;NO, SEE IF ANOTHER ENTRY BCLR #VALIDENT,(A3) ;YES, DELETE ENTRY ; ; INCREMENT INDEX - IF NOT PAST END OF TABLE THEN DO NEXT ENTRY ; TICHKNXT ADDI.W #TIMTLEN,D2 ;INDEX TO NEXT ENTRY CMPI.W #TABLELN,D2 ;PAST END OF TABLE? BNE.S TINEXT ;NO, DO NEXT ENTRY ; ; SEE IF SHOULD DO CONTEXT SWITCH ; ; BSR.S CHKCS ;RETURNS (A0) PTR TO SYSCOM ; BEQ.S DOCS ;DOES OWN EXIT(RTE) ; MOVEM.L (SP)+,D0-D7/A0-A6 ;RESTORE USER REGISTERS TUNRTE RTE ;used by unitunmount page ; ; DOCS - DO CONTEXT SWITCH ; ENTRY : MUST BE A GOTO CALL VIA A JUMP OR BRA NOT A SUBROUTINE ; CALL. NO EXTRA STUFF ON STACK. ; THE TOP OF STACK MUST BE THE USER'S REGISTERS ; (A0) = POINTER TO SYSCOM ; DOCS CLR.B SPNDFLG(A0) ;CLEAR SUSPEND FLAG ; ; SAVE EXISTING PROCESSES CONTEXT (PARTIAL, SCHEDULER DOES REST) ; MOVE.W CURPROC(A0),D0 ;GET CURRENT PROCESS # MULU #PTLEN,D0 ;CALC INDEX TO PROCESS TABLE ENTRY MOVEA.L PPTBL(A0),A1 ;ADDRESS OF PROCESS TABLE LEA 0(A1,D0.W),A2 ;ADDRESS OF ENTRY MOVEQ #NUMREGS-1,D1 ;COUNT OF POPS ; DCSMOVR MOVE.L (SP)+,(A2)+ ;SAVE REGISTERS IN ENTRY DBF D1,DCSMOVR ;IN ORDER D0-A6 ; MOVE.W (SP)+,PTSR(A2) ;SAVE SR AND PC OF CURRENT MOVE.W (SP)+,PTPC(A2) ;PROCESS ; ; CALL SCHEDULER VIA A FAKED RTE ; MOVE.L SCHEDPTR(A0),-(SP) ;ENTRY POINT TO SCHEDULER MOVE.W #SCHEDSR,-(SP) ;SR FOR SCHEDULER ; MOVE.L SCHDA4(A0),A4 ;SCHEDULER IS A PASCAL GLOBAL SUBROUTINE MOVE.L SCHDA5(A0),A5 ;NEEDS ITS VALUES FOR A4 & A5 RTE page ; ; CHKCS - SEE IF SHOULD DO A CONTEXT SWITCH ; EXIT : (NE) - DON'T DO CONTEXT SWITCH ; (EQ) - DO SWITCH ; (A0) = POINTER TO SYSCOM ; IF (SUSPEND FLAG IS CLEAR) THEN DON'T DO SWITCH ; CHKCS MOVE.L PSYSCOM.W,A0 ;ADDRESS OF SYSCOM TST.B SPNDFLG(A0) ;FLAG CLEAR? BEQ.S CCSDONT ;YES ; ; IF (SUSPEND WAIT COUNTED SEMAPHORE = 0) THEN DO CONTEXT SWITCH ; TST.B SPWAITC(A0) BRA.S CCSEXIT ; CCSDONT MOVEQ #1,D0 ;FORCE DONT (NE) CCSEXIT RTS page ; ; UNIT I/O PARAMETER PASSING DEFINITION ; ; COMMAND UNIT ADDR COUNT BLOCK MODE IORESULT BUSY ; 0 - INSTALL DO.W D7.W ; 1 - READ D0.W D1.L D2.W D5.W D7.W ; 2 - WRITE D0.W D1.L D2.W D5.W D7.W ; 3 - CLEAR D0.W D7.W ; 4 - BUSY D0.W D7.W D6.W ; 5 - STATUS D0.W D1.L D2.W D7.W ; 6 - UNMOUNT D0.W D7.W ; ; ALL REGISTER VALUES ON ENTRY ARE SAVED AND RESTORED EXCEPT D6 & D7. ; INTERNAL REGISTER USEAGE : ; A0 - TEMP (GLOBAL) ; A1 - TEMP (GLOBAL) ; A2 - ADDRESS OF TIMER TABLE (GLOBAL) ; A3 - ADDRESS OF USER'S BUFFER ADDRESS (GLOBAL) ; A4 - ADDRESS OF INTERNAL FLAGS BYTE (BELL) ; A5 - ADDRESS OF VIA SHIFT REGISTER (BELL) ; A6 - ADDRESS OF VIA INTERRUPT ENABLE REGISTER (INSTALL) ; ; D0 - TEMP ; D1 - TEMP ; D2 - COUNT OR CONTROL ; D3 - TABLE ENTRY INDEX ; D4 - PATTERN FOR BELL ; page ; GLOBAL TIMERDRV ; ; TIMER DRIVER ; TIMERDRV BRA.S TIMR001 ;*070782* JUMP AROUND HEADER DATA.B 0 ;DEVICE NOT BLOCKED DATA.B 31 ;VALID CMDS - NOT UNITSTATUS DATA.B 84,01,05,0 ;DATE January 05, 1984 DATA.B hmlen ;HEADER MSG LENGTH xxx010 DATA.B 'TIMER driver' ;HEADER MSG hmlen EQU %-xxx010 ; TIMR001 CMPI.W #UNMCMD,D4 ;VALID COMMAND BHI.S TIMDERR ;NO movem.l D1-D6/A0-A6,-(SP) ;*** temp* for busy return in D0 CLR.L D7 ;CLEAR IORESULT MOVEA.L D1,A3 ;ADDRESS OF USERS BUFFER LEA TIMDTBL,A1 ;TURN THE COMMAND INTO A LSL.W #1,D4 ;INDEX TO THE FUNCTION MOVE.W 0(A1,D4.W),D4 JSR 0(A1,D4.W) ;DO FUNCTION movem.l (SP)+,D1-D6/A0-A6 ;*** temp* for busy return in D0 RTS ; ; Invalid Command Error ; TIMDERR MOVE.W #NOTLEGIT,D7 RTS ; ; THE TIMER DRIVER JUMP TABLE ; TIMDTBL DATA.W TIMINST-TIMDTBL ;UNITINISTALL DATA.W TIMRD-TIMDTBL ;UNITREAD DATA.W TIMWR-TIMDTBL ;UNITWRITE DATA.W TIMCLR-TIMDTBL ;UNITCLEAR DATA.W TIMBSY-TIMDTBL ;UNITBUSY DATA.W TIMST-TIMDTBL ;UNITSTATUS DATA.W TIMUNMT-TIMDTBL ;UNITUNMOUNT page ; ; TIMBSY - UNITRBUSY ; BUSY FROM THE TIMER IS CURRENTLY UNDEFINED. ; TIMBSY MOVE.W #NOTLEGIT,D7 RTS ; ; TIMCLR - UNITCLEAR ; CLEAR THE TIMER IS CURRENTLY UNDEFINED. ; TIMCLR MOVE.W #NOTLEGIT,D7 RTS page ; ; TIMWR - UNITWRITE ; TIMRD - UNITREAD ; ; CODE FOR CALANDER CLOCK : IN INCLUDE FILE timer.clk.text ; INCLUDE 'TIMER.CLK.TEXT' page ; ; TIMINST - UNITINSTALL ; INSTALL THE TIMER INTERRUPT ROUTINE AND SET UP THE VIA ; TIMINST CLR.L CPticks.W ;clear tick cntr *kb 11/28/83* ; LEA IER.L,A6 MOVE.B #DISABL,(A6) ;TURN OFF ALL INTERUPTS ON VIA ; ; INITIALIZE TIMER TABLE ; LEA TIMERTBL,A0 ;ADDRESS OF TIMER TABLE LEA TIMERTBL+(TIMTLEN*NUMENTS),A1 ;1ST BYTE AFTER TABLE ; TINST10 MOVE.W #0,(A0) ;CLEAR FLAGS OF EACH ENTRY ADDA.W #TIMTLEN,A0 ;POINT AT NEXT ENTRY CMPA.L A0,A1 ;AT END OF TABLE BNE.S TINST10 ;NO ; ; PUT ADDRESS OF INTERRUPT ROUTINE IN VECTOR ; LEA TIMINT,A0 MOVE.L A0,VECTOR.W ; ; SETUP VIA ; MOVE.B #ACRBYTE,ACR.L ;FREE RUN MODE PB7 OUTPUT DISABLED MOVE.B #TIMEL,T1LL.L ;TIMER #1 LATCH LOW MOVE.B #TIMEH,T1LH.L ;TIMER #1 LATCH HIGH MOVE.B #TIMEH,T1CH.L ;TIMER #1 COUNTER HIGH - FORCE LOAD MOVE.B #CLEAR,IFR.L ;CLEAR IFR ; ; ENABLE TIMER #2 ; MOVE.B #ENBLT1,(A6) ;TURN INTERUPTS ON FOR T1 ; ; INITIALIZE CLOCK - SOURCE IN TIMER.CLK.TEXT INCLUDE FILE ; BRA INITCLK ;DOES RETURN WHEN INITCLK DOES page ; ; TIMUNMT - UNITUNMOUNT ; TURN OFF THE VIA INTERRUPTS AND POINT THE TIMER INTERRUPT VECTOR AT A RTE. ; TIMUNMT MOVE.B #DISABL,IER.L ;TURN OFF ALL INTERUPTS ON VIA LEA TUNRTE,A0 ;WITH TIMER INTERRUPT CODE MOVE.L A0,VECTOR.W ;POINT VECTOR AT RTE RTS page ; ; TIMST - UNITSTATUS ; THIS PPROCEDURE CONTAINS THE BELL ROUTINE AND THE 4 TIMER TABLE MANIPULATION ; PROCEDURES, CREATE, DELETE, DISABLE, AND ENABLE. ; ; ENTRY : D2 - CONTROL CODE USED TO SELECT FUNCTIONS ; A3 - BUFFER ADDRESS = PTR TO PARAMETER BLOCK ; TIMST CMPI.W #ENABLEC,D2 ;VALID FUNCTION CODE BHI.S TSTERR ;NO ; LEA TIMERTBL,A2 ;ADDRESS OF TIMER TABLE LEA TSTTBL,A1 ;TURN THE CONTROL CODE INTO A LSL.W #1,D2 ;INDEX TO THE FUNCTION MOVE.W 0(A1,D2.W),D2 JMP 0(A1,D2.W) ;DO FUNCTION ; ; Invalid Function Code Error ; TSTERR MOVEQ #INVFNC,D7 ;*kb 8/2/83* RTS ; ; THE TIMER DRIVER JUMP TABLE ; TSTTBL DATA.W TSTBELL-TSTTBL ;BELL DATA.W TSTCRE8-TSTTBL ;CREATE TABLE ENTRY DATA.W TSTDELT-TSTTBL ;DELETE TABLE ENTRY DATA.W TSTDSBL-TSTTBL ;DISABLE TABLE ENTRY DATA.W TSTENBL-TSTTBL ;ENABLE TABLE ENTRY page ; ; TSTCRE8 - CREATE TABLE ENTRY ; ENTRY : A3 = ADDRESS OF PARAMETER BLOCK ; A2 = ADDRESS OF TIMER TABLE ; A4 = VALUE WHEN TIMER DRIVER CALLED ; A5 = VALUE WHEN TIMER DRIVER CALLED ; PARAMETER BLOCK : ; 1) ADDRESS OF USER SERVICE ROUTINE TO INSTALL IN ENTRY (LONGWORD) ; 2) COUNT OF 50 MILLISECOND PERIODS TO WAIT (WORD) ; 3) FLAGS (WORD) - ; bit D1 = CONTINUOUS/1SHOT MODE FLAG ; bit D2 = SKIP FIRST CALL FLAG ; 4) RETURN SPACE FOR TABLE ENTRY ID, THE ENTRY NUMBER (WORD) ; TSTCRE8 CLR.L D0 ;ENTRY # CLR.L D3 ;ENTRY INDEX ; ; FIND AN UNUSED ENTRY IF ONE AVAILABLE ; TCRCKNXT BTST #VALIDENT,TFLAGS+1(A2,D3.W) BEQ.S TCRFOUND ;FOUND ONE ADDI.W #TIMTLEN,D3 ;ELSE SEE IF AT END OF TABLE ADDQ.W #1,D0 ;NEXT ENTRY NUMBER CMPI.W #NUMENTS,D0 ;IN TABLE? BNE.S TCRCKNXT ;YES ; ; ERROR TABLE FULL ; MOVEQ #TBLFULL,D7 ;*kb 8/2/83* BRA.S TCREXIT ; ; FOUND UNUSED ENTRY - SET IT UP ; TCRFOUND MOVE.L (A3)+,PTRUSRTN(A2,D3.W) ;PUT IN USER SERVICE RTN ADDRES MOVE.W (A3),TCOUNT(A2,D3.W) ;COUNT OF 50 MS. TICKS MOVE.W (A3)+,TDWNCNT(A2,D3.W) ;SET DOWN COUNTER MOVE.W (A3)+,D1 ;GET FLAGS BSET #VALIDENT,D1 ;SHOW ENTRY IN USE BCLR #ENBLDSBL,D1 ;SHOW ENABLED MOVE.L A4,REGA4(A2,D3.W) ;SAVE USERS A4 AND A5 REGISTERS MOVE.L A5,REGA5(A2,D3.W) ; ; RETURN TO USER TABLE ENTRY ID (THE ENTRY NUMBER) ; MOVE.W D0,(A3) MOVE.W D1,TFLAGS(A2,D3.W) ;last, set flags in entry *kb 8/2/83* TCREXIT RTS page ; *kb 8/2/83* ; TSTDELT - DELETE TABLE ENTRY ; ENTRY : A3 = ADDRESS OF PARAMETER BLOCK ; A2 = ADDRESS OF TIMER TABLE ; PARAMETER BLOCK : ; 1) TABLE ENTRY ID, ENTRY # TO ENTRY (WORD) ; TSTDELT BSR.S VALIDID ;IS ID VALID? *kb 8/2/83* BNE.S TDELEXIT ;INVALID-ERROR EXIT *kb 8/2/83* ; ; VALID ENTRY INDEX - DELETE ENTRY ; BCLR #VALIDENT,TFLAGS+1(A2,D3.W) TDELEXIT RTS ; *kb 8/2/83* ; ; TSTDSBL - DISABLE TABLE ENTRY ; ENTRY : A3 = ADDRESS OF PARAMETER BLOCK ; A2 = ADDRESS OF TIMER TABLE ; PARAMETER BLOCK : ; 1) TABLE ENTRY ID, ENTRY # TO ENTRY (WORD) ; TSTDSBL BSR.S VALIDID ;IS ID VALID? *kb 8/2/83* BNE.S TDSBEXIT ;INVALID-ERROR EXIT *kb 8/2/83* ; ; VALID ENTRY INDEX - DISABLE ENTRY ; BSET #ENBLDSBL,TFLAGS+1(A2,D3.W) TDSBEXIT RTS page ; *kb 8/2/83* ; TSTENBL - ENABLE TABLE ENTRY ; ENTRY : A3 = ADDRESS OF PARAMETER BLOCK ; A2 = ADDRESS OF TIMER TABLE ; PARAMETER BLOCK : ; 1) TABLE ENTRY ID, ENTRY # TO ENTRY (WORD) ; TSTENBL BSR.S VALIDID ;IS ID VALID? *kb 8/2/83* BNE.S TENBEXIT ;INVALID-ERROR EXIT *kb 8/2/83* ; ; VALID ENTRY INDEX - ENABLE ENTRY AND RESTART DOWN COUNTER ; MOVE.W TCOUNT(A2,D3.W),TDWNCNT(A2,D3.W) BCLR #ENBLDSBL,TFLAGS+1(A2,D3.W) TENBEXIT RTS ; ; *kb 8/2/83* ; VALIDID - VALIDATE TABLE ENTRY ID IN PARAMETER ; ENTRY : A3 = ADDRESS OF PARAMETER BLOCK ; EXIT : D3 = TABLE INDEX ; (NE) = INVALID TABLE ENTRY ID *kb 8/2/83* ; (EQ) = VALID TABLE ENTRY ID *kb 8/2/83* ; VALIDID MOVE.W (A3),D3 ;GET TABLE ENTRY ID ; ; TABLE ENTRY ID IS THE ENTRY NUMBER - MAKE SURE LESS THAN NUMBER OF ENTRIES IN TABLE ; CMPI.W #NUMENTS-1,D3 ;IS INDEX LESS THAN TABLELN? BLS.S VALCALC ;YES, CALCULATE INDEX ; VALERR MOVEQ #INVTBLID,D7 ;*kb 8/2/83* BRA.S VALEXIT ; ; HAVE VALID TABLE ENTRY ; VALCALC MULU #TIMTLEN,D3 ;CALCULATE INDEX CLR.L D0 ;CLEAR CARRY VALEXIT RTS page ; TSTBELL - BELL ROUTINE ; ENTRY : A3 = ADDRESS OF PARAMETER BLOCK ; PARAMETER BLOCK : ; 1) FREQUENCY (WORD) ; 2) SPEAKER ON/OFF PATTERN (BYTE) ; 3) FILLER (BYTE) ; 4) DURATION IN 50 MILLISECOND PERIODS (WORD) ; INIT VIA FOR FREQUENCY W/O DISTURBING TIMER #1 ; TSTBELL LEA SHIFTREG.L,A5 MOVE.B #0,(A5) ;TURNOFF BELL FOR SURE ORI.B #RUNT2,ACR.L ;SET TIMER #2 AS COUNT DOWWN BSR.S SETT2 ;PUT FREQUENCY IN TIMER LEA IFLAGS,A4 BCLR #SHUTOFF,(A4) ;PUT TIMER ON ; ; CALL CREATE TO SETUP ONE SHOT INTERVAL TIMER CALL ; LEA IPRMBLK,A1 ;ADDR OF INTERNAL PARM BLOCK MOVE.L A3,-(SP) ;SAVE PARAMETER BLOCK ADDRESS MOVE.W DURATN(A3),D0 ;SAVE THE COUNT MOVEA.L A1,A3 ;CREATE EXPECTS PRM BLK ADR IN A3 LEA BELSRVR,A0 ;BELL SERVICE ROUTINE ADDRESS MOVE.L A0,(A1)+ ;PUT IN PARAMETER BLOCK MOVE.W D0,(A1) ;PUT IN COUNT BSR TSTCRE8 ;CALL CREATE MOVE.L (SP)+,A3 ;BELL PARAMETER BLOCK ADDRESS ; MOVE.B PATTERN(A3),(A5) ;TURN ON BELL ; ; WAIT FOR SHUT OFF ; TBELWAIT BTST #SHUTOFF,(A4) ;DONE? BEQ.S TBELWAIT ;NO ; ; DONE SHUT OFF TIMER #2 AND BELL ; TBELDONE MOVE.B #0,(A5) ;CLEAR SHIFT REG TO SHUT OFF BELL ANDI.B #STOPT2,ACR.L TBELEXIT RTS page ; ; SETT2 - SET TIMER #2 TO FREQUENCY IN PARAMETER BLOCK ; SETT2 MOVE.B 1(A3),T2LL.L ;SET LATCH MOVE.B (A3),T2CH.L ;SET COUNTER AND CLEAR IFR T2 FLAG RTS ; ; BELL TIMER SERVICE ROUTINE ; BELSRVR LEA IFLAGS,A0 ;TELL BELL ROUTINE DONE BSET #SHUTOFF,(A0) ;& TO SHUT OFF SPEAKER AND RTS ;TIMER #2 page ; ; ; DATA AREA ; CONSTANTS FOR CALANDER CLOCK ; CONVERSION ARRAYS BCD TO BINARY/REGISTER TO PARAMETER BLOCK CONVERSION ; DETAIL DATA.B 9,11,10,8,7,6,5,4,3,2,1,0 ;REGISTERS WHICH MAKE THE PARAMETERS NUMBER DATA.B 1,2,2,2,2,2,1 ;# OF REGISTERS FOR PARAMEETER DATA.B 0 ;**** FILL ***** ; ; CONVERSION ARRAYS FOR PARAMETER BLOCK TO REGISTER ARRAY CONVERSION ; INREGB DATA.B 6,5,5,4,4,3,3,2,2,0,1,1,7 ;WHICH PARAM IN REG[i] (BINARY) NIBBLE DATA.B 0,0,1,0,1,0,1,0,1,0,0,1,0 ;WHICH NIBBLE- 1=HI ; ; RANGE VALUES FOR CLOCK PARAMTER BLOCK FIELDS, 1 BYTE LOW, 1 BYTE HI FOR EACH ; OF 8 PARAMTER BLOCK FIELDS ; RANGES DATA.B 1,7,1,12,1,31,0,23,0,59,0,59,0,9,0,3 ; ; VARIABLE DATA AREA ; ; THE TIMER TABLE - 10 ENTRIES ; TIMERTBL DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 0 TIMTLEN EQU %-TIMERTBL ;length of entry DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 1 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 2 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 3 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 4 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 5 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 6 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 7 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 8 DATA.W 0,0,0,0,0,0,0,0,0 ; ENTRY # 9 TABLELN EQU %-TIMERTBL ;length of table in bytes NUMENTS EQU TABLELN/TIMTLEN ;# of entries in table ; ; INTERNAL FLAGS AND PARAMETER BLOCK ; IFLAGS DATA.W 0 ;USE ONLY 1ST BYTE IPRMBLK DATA.W 0,0,0,2,0 ;BELL USES FOR CREATE CALL ; THE ADDRESS AND COUNT ARE SET IN THE BELL ROUTINE - FLAGS ARE ALWAYS ; ONE-SHOT MODE ONLY. ; ; CLOCK DATA AREA ; CLOCK ADDRESS AND SELECT LATCH ADDRESS SAVE AREA ; ADDRREG DATA.L 0 ;{CHANGE 6/7} ; REGISTER ARRAY HOLD ; REGARRAY DATA.B 0,0,0,0,0,0,0,0,0,0,0,0 RARDLEN EQU %-REGARRAY ;NUMBER OF REGISTERS READ DATA.B 0 RAWRLEN EQU %-REGARRAY ;NUMBER OF REGISTERS WRITTEN DATA.B 0 ;FILL ; ; NIBBLE HOLD FOR PARAMETER TO REGISTER CONVERSION ; HI DATA.B 0,0,0,0,0,0,0,0 LOW DATA.B 0,0,0,0,0,0,0,0 ; END TIMERDRV