.TITLE OFF ; VERSION V006A ;   001 ; ; COPYRIGHT 1973 DIGITAL EQUIPMENT CORP., MAYNARD MASS.,01754 ; ; ; STANDARD REGISTER DEFINITIONS ; R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; THIS FILE IS CONDITIONALLY ASSEMBLED ON THE FOLLOWING ;  SWITCHES: ;  IF IO.XTH=0, MUST REASSEMBLE ;  IF NO.TIM IS DEFINED, MUST REASSEMBLE. .IFNDF IO.XTH IO.XTH=7   ;DEFAULT VALUE .ENDC ; ; GLOBAL DEFINITIONS ; .GLOBL EOFF ;OFF HANDLER .GLOBL ESTART ;START HANDLER .GLOBL EXRUN ;EXIT .GLOBL OFFCL ;DELETE HANDLER .GLOBL XIT ;EXIT ; ; GLOBAL REFERENCES ; .GLOBL BACKGD ;BACKGROUND ACTIVE FLAG ; .IFDF RSX11B .GLOBL BFTAB$ ;BUFFER ADDRESS FOR RSX11B .ENDC ; .GLOBL BUSY ;BACKGROUND BUSY. .IFNE IO.XTH .GLOBL CL.SER ;SEARCH FOR NEXT USER OF A DEVICE .ENDC .GLOBL COMMAN ;ILLEGAL OR UNRECOGNIZED COMMAND. .IFNDF NO.TIM .GLOBL CONV ;ROUTINE TO CONVERT MILLISECONDS TO TICKS .ENDC .GLOBL CUTI ;CUT A SLOT(ALT ENTRY TO CUTSL) .GLOBL CUTSL ;CUT A SLOT .GLOBL DCO ;HEAD OF DDB CHAIN .GLOBL DV.STS ;ROUTINE TO FAKE AN INTERRUPT .GLOBL FLBF ;DISPLACEMENT TO FILE BUFFER ADDRESS   ;STORAGE IN TASK RTH .GLOBL FLTB ;DISPLACEMENT TO FILE TABLE ADDRESS   ;STORAGE IN TASK RTH .IFNE IO.XTH .GLOBL FREEI ;ROUTINE TO FREE A DDB (ALT ENTRY TO FREE) .ENDC .GLOBL HSASI ;HIGH SPEED ACTIVATE SUBROUTINE. .GLOBL IENT ;LINK LIST ENTER ROUTINE .GLOBL INITLS ;INITIALIZE STACK ROUTINE .GLOBL IP ;RTH-INITIAL PRIORITY (LOW BYTE),#OF SHARED RES .GLOBL ISAD ;BOTTOM WORD OF SYSTEM STACK .GLOBL LAPU ;LOWEST SLOT TASKS USE .GLOBL LEV ;HEAD OF THE LINK LISTS .GLOBL LEVEX ;SHIFT TASK TO ORIGINAL PRIORITY .GLOBL LEVEXA ;ALTERNATE ENTRY TO LEVEX .GLOBL MN ;-N .GLOBL NEWSA ;NEW PROGRAM ACTIVE FLAG .GLOBL NP ;RTH-NUMBER PASSED IN CALL .GLOBL OFFS ;INITIALIZE ROUTINE FOR EOFF AND OFFCL .IFNE IO.XTH .GLOBL OP.GB ;ALT ENTRY TO OP.GB .ENDC .GLOBL OTSV ;RTH--FORTRAN IMPURE AREA POINTER .GLOBL PL4 ;PRIORITY LEVEL 4 .GLOBL PL7 ;PRIORITY LEVEL 7 .GLOBL PRWT ;COUNT OF TASKS WAITING FOR PROCESSOR .GLOBL PS ;ADDRESS OF PROCESSOR STATUS REGISTER. .GLOBL PSTB ;PRIORITY STATUS .GLOBL PTBK ;BACKWARD POINTER LIST .GLOBL PTFW ;FORWARD POINTER LIST .GLOBL REACTA ;ALTERNATE ENTRY TO REACT .GLOBL RSA ;BACKGROUND TASK RESTART ADDRESS. .GLOBL SA ;RTH-SUSPENDED STACK ADDRESS .GLOBL SHORT ;SHORT CALL SEQUENCE ERROR. .GLOBL SL ;MINUTES AT START(HI BYTE),SECONDS AT LAST UPDA .GLOBL SLOT ;NO SLOT AVAILABLE. .GLOBL SM ;MAXIMUM LEVEL 1 RUN TIME(SECONDS) .GLOBL SRTI ;COMMON SYSTEM EXIT. .IFNDF NO.TIM .GLOBL STCT ;ROUTINE TO START A COUNTER .ENDC .GLOBL SUTB ;SUSPEND STATUS .GLOBL SYAUA ;SYSTEM,USER ACTIVE FLAG .GLOBL SY.DFL ;DDB-FLAG BYTE. .GLOBL SY.DPR ;DDB-PERMANENT DDB BIT. .GLOBL SY.DVL ;DDB-SUSPEND LEVEL COUNTS. .GLOBL SY.RES ;DDB-RESERVED FLAG. .GLOBL SY.RTN ;DDB-TASK DDB RESERVED FOR (BYTE) .GLOBL SY.SPN ;DDB-SUSPEND NUMBER (BYTE) .GLOBL SY.TWR ;DDB-THE OWNER IS WAITING. .IFNE IO.XTH .GLOBL S.ED ;ROUTINE TO ENTER A DRIVER AT MISCELLANEOUS ENT .ENDC .GLOBL S.RRES ;SYSTEM REGISTER RESTORE ROUTINE/ .GLOBL S.RSAV ;SYSTEM REGISTER SAVE ROUTINE/ .GLOBL S.STAT ;PROCESSOR STATUS WORD. .GLOBL TACKW ;TACK A SLOT TO WAITING LIST .GLOBL TFILE ;ROUTINE TO FILE AWAY A TASK .GLOBL TR ;RTH-TRAP VECTOR SETTING. 0 IF NONE. .GLOBL TSLOT ;ROUTINE TO FIND A TIMER SLOT .IFNDF NO.TIM .GLOBL UNCLK ;ROUTINE TO UNCLOCK A TASK .ENDC .GLOBL UPSTK ;USER STACK AT ENTRY TO EXEC .GLOBL WDTB ;HEADER ADDRESS TABLE .GLOBL WL ;RTA-WAITING LIST HEAD(LOW BYTE)&TAIL(HIGH BYTE .GLOBL WTCH ;WATCH DOG TIMER(LOW BYTE) .GLOBL WTCHD ;WATCH DOG TIMER POINTER ; ; DELETE REQUESTS FOR A TASK FROM BOTH THE TASK ; REQUEST QUEUE AND THE TIMER LIST. IF A DATA ; WORD IS SPECIFIED, THEN ONLY THOSE ENTRIES ; THAT MATCH ARE DELETED. OTHERWISE ALL ENTRIES ; THAT REFERENCE THE DESIGNATED TASK ARE DELETED. ; THIS ROUTINE CORRESPONDS TO THE FORTRAN ; CALL "CALL DELETE(PRG,...)". ; OFFCL: JSR PC,OFFS  ;OFF INITIALIZE SUBROUTINE  BGE CLRSC  ;BRANCH IF DATA    CLR R4  ;INDICATE NO DATA    CLRSC: MOV R1,-(SP) ;HEADER ADDRESS    MOV R0,-(SP) ;TASK NO     .IFNDF NO.TIM  ;CONDITIONAL TIME DEPENDENT SCHEDULING RESLS: MOVB LEV,R1  ;START OF TIMER LIST    BEQ WLEND  ;IF EQ NO MORE ENTRIES TBSLP: CMPB (SP),SUTB(R1) ;IS THIS REFERENCE TO TASK BEING CLEARE BNE WLSTP  ;IN NE SKIP OVER ENTRY CMPB PSTB(R1),#MN ;CHECK FOR WAIT. BEQ WLSTP  ;OFF CODE WILL TAKE CARE OF WAIT TST R4  ;DATA TO TEST? BEQ CUTHR  ;IF EQ NONE TO CHECK MOVB PSTB(R1),R2 ;GET EXTENSION INDEX BNE OFFCLA  ;GO CHECK EXTENSIONS ; NO EXTENSION MEANS THE DATA IS 0. TST @(R5)  ;CONDITIONAL ON 0? BR OFFCLB OFFCLA: CMP @(R5),SUTB(R2) ;DATA MATCH? OFFCLB: BNE WLSTP  ;NO-DON'T CUT. CUTHR: MOVB PSTB(R1),-(SP) ;GET EXTENSION INDEX JSR PC,CUTSL ;CUT TIMER SLOT MOVB (SP)+,R1 ;GET EXTENSION INDEX BEQ RESLS  ;IF EQ NO EXTENSION JSR PC,TACKW ;RELEASE EXTENSION SLOT BR RESLS  ;GO AGAIN FROM START WLSTP: MOVB PTFW(R1),R1 ;NEXT IS TIMER LIST    CMPB R1,LEV  ;IS THIS THE END OF LIST? BNE TBSLP  ;      .ENDC WLEND: MOV #WL,R3  ;DISPLACEMENT OF TASK LINKED LIST  ADD 2(SP),R3 ;ADDRESS OF LINKED LIST WAITING  ; ; THE FOLLOWING SCAN OF THE WAITING QUEUE OF REQUESTS ; FOR A TASK MUST BE EXECUTED WITH INTERRUPTS OFF ; SO THAT NO REQUESTS MAY BE MADE VIA "HSASI" THAT ; REFERENCE THE SAME SLOT WHILE THE SCAN IS IN PROGRESS. ; MOV #PL7,PS  ;LOCK OUT INTS DURING SCAN MOVB (R3),R1  ;INDEX OF FIRST WAITING CALL BEQ OFCLX  ;IF EQ NONE TO WORRY ABOUT MOV R3,R0  ;SAVE LIST HEADER ADDRESS CLR -(SP)  ;CLEAR LST SLOT INDEX WLLRT: MOVB PTFW(R1),R2 ;GET INDEX OF NEXT SLOT TST R4  ;ANY DATA TO CHECK? BEQ WLTAC  ;IF EQ NO-GO CUT SLOT CMP @(R5),WDTB(R1) ;COMPARE DATA ENTRIES BEQ WLTAC  ;IF EQ CUT IT OUT MOV R1,(SP)  ;SAVE LAST SLOT INDEX ADD #PTFW,R1 ;MAKE REAL ADDRESS MOV R1,R0  ;LAST HEADER ADDRESS BR WLENR  ;GO TO END TO CHECK FOR MORE WLTAC: JSR PC,TACKW ;ADD SLOT TOMWAITING LIST MOVB R2,(R0)  ;STORE NEW FORWARD POINTER CMPB 1(R3),R1 ;IS THIS LAST SLOT? BNE WLENR  ;IF NE DON'T STORE NEW LAST MOVB (SP),1(R3) ;STORE NEW LAST INDEX WLENR: MOV R2,R1  ;NEXT TO R1 BNE WLLRT  ;IF NE MORE TO SCAN TST (SP)+  ;POP OFF LAST INDEX OFCLX: MOV #PL4,PS  ;LOWER PRIORITY CMP (SP)+,(SP)+ ;ADD 4 TO STACK POINTER CMP -(R5),-(R5) ;SUBTRACT 4 FROM R5 ; ; OFF REAL TIME EMT ; EOFF: JSR PC,OFFS  ;OFF INITIALIZE SUBROUTINE  BLT OFFA  ;IS DATA SPECIFIED BRANCH IF NONE  CMP NP(R1),@(R5)+ ;IS DATA IN HEADER EQUAL TO DATA  BNE EXRUNB  ;IF NE NO MATCH OFFA: MOVB PSTB(R0),R3 ;IS TASK ACTIVE    BPL STATCK  ;BRANCH IF ACTIVE    BIC #177700,R3 ;CLEAR ALL BUT PRIORITY   MOV R0,R2  ;TASK NUMBER FOR KILL CHECK   MOV WDTB(R0),R0 ;HEADER ADDRESS TO R0    OFFX: JMP KILLT  ;      STATCK: INCB NEWSA  ;CAUSE SCAN AFTER TASK TURNED OFF MOVB SUTB(R0),R3 ;STATUS OF SUSPEND    BLE OF.SA  ;SKIP SCAP OF DDB'S IF 0 OR NEGATIVE ST .IFNE IO.XTH  ;CHECK IF ANY IO AT ALL. ; ; SCAN THE DDB'S FOR THIS SUSPEND NUMBER. ;  IF FOUND, DECREMENT THE PROPER LEVEL COUNTER. ; ; MOV DCO,R5  ;GET PTR TO HEAD OF DDB CHAIN OF.SC: BEQ OF.SA  ;DONE - CMPB R3,SY.SPN(R5) ;IS THIS THE DESIRED SUSPEND #? BEQ OF.SB  ;YES - GO DECREMENT COUNTER MOV -10(R5),R5 ;NO - CONTINUE SCAN BR OF.SC OF.SB: MOVB PSTB(R0),R4 ;GET PRIORITY LEVEL ADD R5,R4  ;ADD TO DDB ADDRESS. DECB SY.DVL-1(R4) .ENDC OF.SA: .IFNDF NO.TIM  ;TIME DEPENDENT SCHEDULING. CMPB R3,#376  ;IS IT WAIT SUSPEND   BNE ACTOF  ;BRANCH IF NOT WAIT    MOVB LEV,R4  ;START OF WAIT LIST    OFFL: CMPB SUTB(R4),R0 ;IS THIS TIMER SLOT USED FOR   BEQ WTTST  ;BRANCH IF SLOT USED BY THIS TASK  NWSLT: MOVB PTFW(R4),R4 ;NEXT ON LIST     CMPB R4,LEV  ;IS THIS END OF LIST    BEQ ACTOF  ;BRANCH NO TIMER SLOT    BR OFFL  ;RETURN FOR CHECK    WTTST: CMPB PSTB(R4),#MN ;IS THIS A WAIT? BNE NWSLT  ;      MOV R0,-(SP) ;SAVE TASK NUMBER    MOV R4,R1  ;INDICATE SLOT TO CUT    JSR PC,CUTSL ;REMOVE SLOT     MOV (SP)+,R0 ;READ TASK NAME    MOV WDTB(R0),R1 ;RECALL HEADER ADDRESS. .ENDC ACTOF: MOVB SYAUA,R4 ;ACTIVE PROGRAM USER LEVEL   MOV WDTB(R4),R4 ;HEADER OF PROGRAM    JSR PC,TFILE ;FILE AWAY THE TASK  042 ACTOFA: MOVB R0,SYAUA ;MAKE TASK TO TURN OFF ACTIVE TASK     ;FOR EXIT ROUTINE WHICH FOLLOWS  MOV SA(R1),UPSTK ;MAKE SAVED USER STACK CORRESPOND  ADD #WTCH,R1 ;CALCULATE WATCHDOG ADDRESS MOV R1,WTCHD ;SET NEW ADDRESS ;PROGRAM AT USER LEVEL GET TO HERE WHEN DONE BY TRAP XIT: EXRUN: MOVB SYAUA,R2 ;TASK # MOV WDTB(R2),R0 ;HEADER ADDRESS .IFNE IO.XTH  ;IO SWITCH. TSTB IP+1(R0) ;SHARED RESOURCES IN USE? BNE EXRUNC  ;YES,GO RELEASE THESE .ENDC TSTB SUTB(R2) ;TASK RUNNING NOW? BEQ EXRUNA  ;YES - JSR PC,REACTA ;NO - GO TALLY PRWT EXRUNA: CLR R4  ;INDICATE ZERO SUSPEND STATE FOR LEVEX  CLR R5  ;INDICATE NO TABLE MARKED BY LEVEL X  JSR PC,LEVEX ;SHIFT TO ORIGINAL PRIORITY IF CHANGE T MOV R1,R2  ;      MOV WDTB(R2),R0 ;ADDRESS OF HEADER    CLR TR(R0)  ;INDICATE NO "TRAP" DESIRED   BR EXRES EXRUNB: BR SHSRT  ;EXIT TO SRTI EXRUNC: JMP SCHLR  ;AUX JUMP TO RELEASE DEVICES EXRES: MOV #PL7,PS  ;LOCK OUT INTS MOV OTSV(R0),R5 ;FORTRAN IMPURE POINTER BEQ EXRES1  ;BRANCH IF NOT CLR 14(R5)  ;CLEAR OVERLAY LOAD INDICATOR EXRES1: ; .IFDF RSX11B ; TST FLTB(R0) ;FILE TABLE SLOT TO BE RELEASED? BEQ KILLT2  ;BRANCH IF NOT CLR @FLTB(R0) ;YES, CLEAR SLOT ENTRY... CLR FLTB(R0) ;... AND ADDRESS IN TASK RTH KILLT2: MOV FLBF(R0),R5 ;FILE BUFFER BEING USED? BEQ KILLT3  ;BRANCH IF NOT CLR FLBF(R0) ;CLEAR ADDRESS IN TASK RTH MOV BFTAB$,(R5) ;ADDRESS OF NEXT TO CURRENT BUFFER MOV R5,BFTAB$ ;STORE CURRENT BUFFER AS FIRST KILLT3: ; .ENDC ; MOVB WL(R0),R1 ;FIRST WAITING     BEQ TRNFF  ;BRANCH IF NONE    MOV WDTB(R1),NP(R0) ;PASS DATA TO PROGRAM CALLED  MOVB PTFW(R1),WL(R0) ;MOVE NEXT INDEX TO HEADER BNE ADTLT  ;IF NE MORE IN LIST CLR WL(R0)  ;INDICATE NONE WAITING    ADTLT: MOV #PL4,PS  ;DROP LEVEL MOVB SUTB(R1),-(SP) ;SAVE INDEX OF TASK IN STACK JSR PC,TACKW ;RELEASE QUEUE SLOT JSR PC,INITLS ;INITIALIZE STACK MOVB (SP)+,R1 ;RETRIEVE TASK INDEX .IFNDF NO.TIM BEQ SHSRT  ;IF EQ NONE MOVB PSTB(R1),R4 ;GET EXTENSION INDEX MOV WDTB(R4),R0 ;GET CYCLE TO R0 JSR PC,STCT  ;START COUNTER COUNTING  .ENDC SHSRT: BR CSCAN1  ;RETURN TRNFF: CMPB R2,BACKGD ;BACKGROUND TASK? BNE KILLT0  ;NO, CONTINUE EXIT PROCESSING BITB #100,SL+1(R0) ;YES, IS RESTART BIT SET? BEQ KILLT1  ;NO, CONTINUE EXIT PROCESSING BICB #100,SL+1(R0) ;YES, RESET THE BIT MOV #PL4,PS  ;SET EXEC LEVEL JSR PC,INITLS ;REACTIVATE THE BACKGROUND TASK BR CSCAN1  ;GO TO COMMON SYSTEM EXIT KILLT1: CLRB BACKGD  ;CLEAR BACKGD SLOT # CLR RSA  ;CLEAR THE RESTART ADDRESS KILLT0: DECB PRWT-1(R3) ;ONE LESS TASK ON THIS LEVEL BIS #100377,SUTB(R2) ;SET TASK INACTIVE KILLT: MOV #PL7,PS  ;LOCK OUT INTS TSTB SL+1(R0) ;TEST FOR KILL BPL CSCAN  ;NO- BICB #200,SL+1(R0) ;REMOVE KILL MARK CLR SUTB(R2) ;CLEAR TASK DEFINITION CLR WDTB(R2) ; MOV #PL4,PS  ;ALLOW INTS MOV R3,-(SP) ;SAVE LEVEL INDEX MOV R2,-(SP) ;SAVE TASK SLOT INDEX .IFNDF NO.TIM MOV R2,R0  ;TASK SLOT TO R0 CLR R4  ;SPECIFY NO TIME ARRAY JSR PC,UNCLK ;REMOVE TIME OF DAY ENTRIES .ENDC MOV (SP)+,R1 ;TASK SLOT TO R1 MOV (SP)+,R0 ;LEVEL INDEX TO R0 JSR R5,CUTI  ;REMOVE SLOT    CMP R1,LAPU  ;IS THIS HIGHEST SLOT?   BNE CSCAN  ;NO -      KILLTA: ADD #2,R1  ;CALCULATE NEW LOWEST TASK BEQ KILLTA  ;SLOT INDEX TST WDTB(R1) ;THIS SLOT EMPTY? BEQ KILLTA  ;IF EQ YES MOV R1,LAPU  ;STORE NEW LOWEST SLOT INDEX CSCAN: INCB NEWSA  ;CAUSE EXECUTIVE SCAN    CSCAN1: JMP SRTI  ;RETURN TO SYSTEM .IFNE IO.XTH  ;IO SWITCH ; ;THIS ROUTINE SCANS THE DDB CHAIN TO FIND ALL DEVICES THIS ;TASK IS INVOLVED WITH. ; IT SUSPENDS THE TASK AS OWNER OF DDB IF A DATA ; XFER IS IN PROGRESS. ; FOR RESERVED DDB'S, IT FREES THE DDB AND ; REMOVES IT FROM THE CHAIN IF NECESSARY. ; ON ENTRY, R2=TASK#; HEADER ADR IN R0 SCHLR: MOV R0,R1  ;HEADER TO R1 MOV #DCO,R5  ;GET PTR TO FIRST POINTER SCHLG: MOV (R5),R0  ;GET PTR. BEQ SCHLA  ;DONE IF PTR=0. CMPB R2,SY.RTN(R0) ;THIS TASK? BNE SCHLC  ;NO - MOVB SY.DFL(R0),R3 ;GET DDB FLAGS. BPL SCHLB  ;NOT LOCKED - ;CALL DRIVER TO CANCEL OPERATION. ON ; RETURN, IF STILL LOCKED, SUSPEND. ELSE ; GO ON TO NEXT PART OF SCAN (AT SCHLB) ; JSR R5,S.RSAV ;SAVE REGS MOV #6,R1  ;FUNCTION IS CANCEL JSR PC,S.ED  ;CALL DRIVER MOV #PL4,PS  ;DROP PRIORITY LEVEL JSR R5,S.RRES ;RESTORE REGS MOVB SY.DFL(R0),R3 ;GET DDB FLAGS AGAIN BPL SCHLB  ;NOT LOCKED MOVB #-3,R4  ;SET EXIT INDICATOR INCB NEWSA  ;CAUSE A NEW SCAN JMP OP.GB  ;FINISH IN OPEN SCHLB: BITB #SY.RES,R3 ;DDB RESERVED? BEQ SCHLD  ;NO- JSR PC,FREEI ;YES-FREE THE DDB. BICB #SY.TWR,SY.DFL(R0) ;TASK IS NOT WAITING NOW. MOV #SCHLD,-(SP) ; FROM SCHLD JSR R5,DV.STS ;FAKE AN INTERRUPT MOV -2(R0),R2 ;DEVICE ADR MOVB 6(R2),S.STAT ;DROP TO DEVICE PRIORITY JMP CL.SER  ;GO SEARCH FOR SOMEONE TO USE DDB. ; ; COMES BACK HERE AFTER TRYING TO START SOMEONE ELSE. ; SCHLD: BITB #SY.DPR,R3 ;PERMANENT DDB? BEQ SCHLF  ;NO - TSTB IP+1(R1) ;YES - ANY MORE SHARED RESOURCES? BEQ SCHLA  ;NO-DONE SCHLC: SUB #10,R0  ;MOVE R0 TO NEXT POINTER. MOV R0,R5  ; BR SCHLG  ;TRY NEXT DDB. SCHLF: MOV -10(R0),(R5) ;REMOVE THIS DDB FROM CHAIN. TSTB IP+1(R1) ;ANY MORE SHARED RESOURCES. BNE SCHLG  ;YES - KEEP GOING. SCHLA: JMP EXRUN  ;GO CONTINUE EXIT .ENDC ; ; ERROR DESIGNATION ENTRY POINTS ; COMDER: MOV #COMMAN,R1 ;COMMAND ERROR BR ERXIT  ; SHRTM: MOV #SHORT,R1 ;SHORT CALL SEQUENCE BR ERXIT  ; NSLOT: MOV #SLOT,R1 ;NO SLOTS AVAILABLE BR ERXIT  ; BKBUSY: MOV #BUSY,R1 ;BACKGROUND BUSY ERXIT: MOV #ISAD,SP ;CLEAN ALL GARBAGE OFF STACK MOV R5,-(SP) ;OPTIONAL INFO IS R5 ADDRESS MOV R1,-(SP) ;CLASS,NUMBER MOVB SYAUA,-(SP) ;TASK INDEX IOT   ;OUTPUT ERROR MESSAGE GSTRT: JMP SRTI  ;RETURN TO SYSTEM ; ; START TASK REAL TIME EMT ; ESTART: CMP (R5),#404 ;CHECK FOR ENOUGH PARAMETERS STRT1: BLT SHRTM  ;IF LT ERROR MOV #2,@10(R5) ;ASSUME BAD CALL JSR PC,OFFS  ;GET HEADER ADDRESS AND TASK IN MOV R0,-(SP) ;TASK INDEX TO STACK MOV SM(R1),-(SP) ;BACKGROUND FLAG TO STACK BGE STRT3  ;IF GE NOT BACKGROUND TSTB BACKGD  ;TEST IF BACKGROUND BUSY BNE BKBUSY  ;IF NE BUSY STRT3: MOV @(R5)+,R1 ;GET DELAY MOV @(R5)+,R4 ;GET DELAY UNITS .IFNDF NO.TIM JSR R5,CONV  ;CONVERT DELAY BR ERXIT  ;BAD TIME UNIT OR VALUE MOV R0,-(SP) ;MOVE DELAY TO STACK .ENDC CLR -(SP)  ;CLEAR DATA WORD CMP -10(R5),#405 ;DATA SPECIFIED? BLT STRT5  ;IF LT NO MOV @2(R5),(SP) ;MOVE DATA TO STACK STRT5: .IFNDF NO.TIM CLR -(SP)  ;CLEAR CYCLE WORD CMP -10(R5),#406 ;CYCLE SPECIFIED? BLT STRT7  ;IF LT NO MOV @4(R5),R1 ;GET CYCLE JSR R5,CONV  ;CONVERT CYCLE TO TICKS STRT6: BR ERXIT  ;BAD UNITS OR VALUE MOV R0,(SP)  ;MOVE CYCLE TO STACK STRT7: MOV (SP)+,R4 ;CYCLE TO R4 .ENDC MOV (SP)+,R2 ;DATA TO R2 .IFNDF NO.TIM MOV (SP)+,R3 ;DELAY TO R3 .ENDC MOV (SP)+,R1 ;BACKGROUND ERROR .IFNDF NO.TIM MOV R4,R0  ;TEST FOR CYCLE OR DELAY BIS R3,R0  ;OR WORDS TOGETHER BNE STRT9  ;IF NE CYCLE OR DELAY SPECIFIED .ENDC MOVB (SP),R0  ;TASK INDEX TO R0(LEAVE ON STAC MOV R1,-(SP) ;SAVE BACKGROUND FLAG. JSR R5,HSASI ;ACTIVATE TASK BR NSLOT  ;MAKE LIKE NO SLOTS AVAILABLE TST (SP)+  ;BACKGROUND? BGE STRT8A  ;NO- MOVB (SP),BACKGD ;SET BACKGROUND BUSY. STRT8A: TST (SP)+  ;DISCARD TASK INDEX. STRT8: DEC @(R5)+  ;SET SUCESSFUL STATUS BR GSTRT  ;RETURN .IFNDF NO.TIM STRT9: TST R1  ;TEST FOR BACKGROUND BMI COMDER  ;IF NEG ERROR JSR R5,TSLOT ;GET A SLOT STRT10: BR NSLOT  ;NO SLOT AVAILABLE MOV (SP)+,SUTB(R1) ;SET TASK INDEX IN SLOT CLRB PSTB(R1) ;CLEAR EXTENSION INDEX MOV R4,R0  ;TEST FOR CYCLE OR DATA BIS R2,R0  ;OR WORDS TOGETHER BEQ STRT12  ;IF EQ NONE MOV R1,-(SP) ;SAVE TIMER SLOT INDEX JSR R5,TSLOT ;GET A SLOT BR STRT13  ;NO SLOTS AVAILABLE MOV R4,WDTB(R1) ;SET CYCLE BEQ STRT11  ;IF NO CYCLE GO NOW TST R3  ;MUST BE A DELAY BNE STRT11  ;IF NE OKAY INC R3  ;MAKE DELAY 1 TICK STRT11: MOV R2,SUTB(R1) ;STORE DATA IN EXTENSION SLOT MOV (SP)+,R0 ;GET TIMER SLOT INDEX MOVB R0,PTBK(R1) ;SET BACKWARD POINTER OF EXTENSION SLOT CLRB PTFW(R1) ;CLEAR FORWARD POINTER MOVB R1,PSTB(R0) ;SET EXTENSION POINTER IN TIMER SLOT MOV R0,R1  ;SET TO CORRECT SLOT STRT12: MOV R3,R0  ;DELAY TO R0 JSR PC,STCT  ;SET COUNTER UP PROPERLY CLR R2  ;SET TIMER LIST INDEX JSR R5,IENT  ;ENTER TIMER SLOT IN LIST BR STRT8  ;EXIT STRT13: MOV (SP)+,R1 ;TIMER SLOT TO R1 JSR PC,TACKW ;RELEASE SLOT BR STRT10  ;RETURN .ENDC .END