.SBTTL $SEMTX - SET USER EMT EXIT ; CALLED WITH: R1 - (LO) EMT NUMBER ; R2 - EMT TRANSFER ADDRESS $SEMTX: CMPB R1,$UMTBL ;COMPARE EMT CODE VS TABLE SIZE BHIS ERR3 ;IF TOO LARGE, ERROR $PUSH R1 ;SAVE R1 BIC #377*40,R1 ;LEAVING ONLY EMT CODE ASL R1 ;CONVERT TO WRD INDEX CMP $UMTBL+2(R1),#ERR2 ;IS THIS SLOT FREE? BNE ERR3 ;IF NOT, ERROR MOV R2,$UMTBL+2(R1) ;PUT TRANSFER ADDRESS INTO TABLE $POP R1 $RTT ;AND RETURN .IF NE, KF.DBG .PAGE .SBTTL $SEXIT - SET PROCESS EXIT ; ; CALLED WITH: R0 - (LO) PROCESS TO SET EXIT ON ; (HI) OPCODE TO BE SIGNALLED WITH ; $SEXIT: $PUSH R0,R1 $CVPCT ;CONVERT PID INTO PCT ADDRESS CMP R0,$APCT ;TRYING TO SET ON OURSELVES BEQ ERR8 ;IF SO, ERROR TST PCTDBG(R0) ;SOMEONE ELSE DEBUGGING THIS GUY? BNE ERR8 ;IF SO, ERROR MOV (SP),R1 ;GET OPCODE CLRB R1 BISB $APID,R1 ;MERGE IN OUR PID MOV R1,PCTDBG(R0) ;INDICATE WE ARE DEBUGGING BIC #PS.NDB,@$APFLG ; THIS PROCESS $POP R1,R0 $RTT ERR8: BUGHLT ;INVALID SET/REMOVE EXIT $ERR8: NOP .PAGE .SBTTL $REXIT - REMOVE PROCESS EXIT ; ; CALLED WITH: R0 - (LO) PROCESS ID ; $REXIT: $PUSH R0 $CVPCT ;GET PCT ADDRESS CMPB PCTDBG(R0),$APID ;WERE WE DEBUGGING IT? BNE ERR8 ;IF NOT, GIVE ERROR CLR PCTDBG(R0) ;NOT DEBUGGING ANY MORE BIS #PS.NDB,@$APFLG ;DON'T NEED REGISTER SNAPSHOTS $POP R0 $RTT .ENDC .PAGE .SBTTL $SIGNL - SIGNAL A PROCESS ; ; CALLED WITH: R0 - (LO) PROCESS ID ; (HI) OPCODE ; R1 - SIGNAL DATA ; $SGNLI: $SIGNL: $PUSH R2,R0 .IF NE, KF.SCD $GETPS -(SP) ;MAKE SURE TO RUN IN PEACE $DSABL ;BUT WITHOUT TRACE BIC #-400,R0 ;TYPE PROCID CALL TYPEN MOV #SSIG,R0 ;AND MESSAGE CALL TYPE MOV 2(SP),R0 $PUTPS (SP)+ ;COVER TRACKS .ENDC $CVPCT ;CONVERT PID TO PCT ADDRESS MOV R0,R2 ;GET PCT ADDR BIS #PS.RDY,PCTFLG(R2) ;FLAG PROCESS AS SIGNALLED ADD #PCTMQH,R2 ;AND POINT TO ITS MESSAGE QUEUE $GTBLK ;GET MESSAGE QUEUE ELEMENT MOV R1,MQDATA(R0) ;SET DATA FIELD MOVB 1(SP),MQOPC(R0) ; SIGNAL OPCODE MOVB $APID,MQPID(R0) ;AND PUT IN OUR PID $ENQ ;ENQUEUE ON MESSAGE QUEUE INC SCHDFLG ;AND MARK AS HAVING ENABLED SOMEONE BIT #PS.PMT,@$APFLG ;CAN WE PREEMPT THIS PROCESS? BEQ 1$ ;IF NOT, THEN DON'T JSR PC,DSCHD ;AND RUN THE SCHEDULER 1$: $POP R0,R2 $RTT ;THEN CONTINUE WITH THIS GUY .IF NE, KF.SCD .CSECT MOSDAT SSIG: .ASCIZ / Sg/<12> .EVEN .CSECT MOS .ENDC .PAGE .SBTTL $WAIT - DESCHEDULE PROCESS AND WAIT FOR ANY SIGNAL ; ; CALLED WITH: NOTHING ; ; RETURNS WITH: R0 - (LO) SIGNAL OPCODE ; (HI) SIGNALLER'S PID ; R1 - SIGNAL DATA ; $WAIT: $PUSH R2 MOV $APCT,R2 ;GET OUR PROCESS PCT ADD #PCTMQH,R2 ;... POINT TO MESSAGE QUEUE TST @R2 ;MESSAGES WAITING? BEQ 2$ ;NOPE, SLEEP BIT #PS.MMS,@$APFLG ;IS HE ALLOWED TO GO GET THEM? BEQ 3$ ;NO, TAKE A ROUND IN THE SCHEDULER 1$: $DEQ ;REMOVE AN ELEMENT BNE WTEX ;IF EXISTS, EXIT 2$: BIC #PS.RDY,@$APFLG ;RESET READY FLAG AND WAIT FOR SIGNAL 3$: JSR PC,DSCHD ;SCHEDULE PROCESS BR 1$ ;AND LOOK AGAIN .PAGE .SBTTL $WAITS - DESCHEDULE PROCESS AND WAIT FOR SPECIFIC SIGNAL ; ; CALLED WITH: R0 - DESIRED OPCODE ; ; RETURNS WITH: R0 - (LO) SIGNAL OPCODE ; (HI) SIGNALLER'S PID ; R1 - SIGNAL DATA ; $WAITS: $PUSH R2 MOV $APCT,R1 ;GET PCT POINTER ADD #PCTMQH,R1 ;... POINT TO MESSAGE QUEUE TST @R1 ;MESSAGES WAITING? BEQ 2$ ;NOPE, SLEEP BIT #PS.MMS,@$APFLG ;IS HE ALLOWED TO GO GET THEM? BEQ 3$ ;NO, TAKE A ROUND IN THE SCHEDULER 1$: MOV @R1,R2 ;GET LINK TO NEXT MQ ELEMENT BNE 4$ ;IF EXISTS, CHECK OPCODE 2$: BIC #PS.RDY,@$APFLG ;RESET READY FLAG AND WAIT FOR SIGNAL 3$: JSR PC,DSCHD ;SCHEDULE PROCESS BR 1$ ;AND TRY AGAIN 4$: CMPB R0,MQOPC(R2) ;OPCODE MATCHES? BEQ WTEXT ;IF SO, EXIT MOV R2,R1 ;ELSE, TRY NEXT ELEMENT BR 1$ WTEXT: MOV R2,R0 ;SET POINT TO ELEMENT TO BE REMOVED MOV $APCT,R2 ADD #PCTMQH,R2 ;POINT TO MESSAGE QUEUE $QDEL ;AND DELETE FROM QUEUE WTEX: $RLBLK ;RELEASE MQ ELEMENT MOV MQDATA(R0),R1 ;AND SIGNAL DATA MOV MQOPC(R0),R0 ;GET SIGNALLER'S PID/OPC $POP R2 $RTT .PAGE .SBTTL $WAITM - DESCHEDULE AND WAIT FOR ANY OF A GROUP OF SIGNALS ; ; CALLED WITH: R0 - OPCODE GROUP FLAGS ; ; RETURNS WITH: R0 - (LO) SIGNAL OPCODE ; (HI) SIGNALLER'S PID ; R1 - SIGNAL DATA ; $WAITM: $PUSH R2,R3 MOV $APCT,R1 ;GET ACTIVE PCT ADD #PCTMQH,R1 ;POINT TO MESSAGE QUEUE TST @R1 ;MESSAGES WAITING? BEQ 2$ ;NOPE, SLEEP BIT #PS.MMS,@$APFLG ;IS HE ALLOWED TO GO GET THEM? BEQ 3$ ;NO, TAKE A ROUND IN THE SCHEDULER 1$: MOV @R1,R2 ;GET LINK TO NEXT ELEMENT BNE 4$ ;IF EXISTS, CHECK OPCODE 2$: BIC #PS.RDY,@$APFLG ;RESET READY FLAG AND WAIT FOR SIGNAL 3$: JSR PC,DSCHD ;SCHEDULE PROCESS BR 1$ ;AND TRY AGAIN 4$: MOVB MQOPC(R2),R3 ;GET SIGNAL OPCODE BIC #^C17,R3 ;CLEAR ALL BUT LOW 4 BITS ASL R3 ;CONVERT TO WORD INDEX BIT BITTBL(R3),R0 ;CHECK IF OPCODE GROUP SPECIFIED BNE 5$ ;IF SO, EXIT MOV R2,R1 ;ELSE, REMEMBER OLD POINTER BR 1$ ;AND TRY TO GET NEW ELEMENT 5$: $POP R3 ;RECOVER R3 BR WTEXT ;AND EXIT .CSECT MOSDAT BITTBL: .WORD 1 ;TABLE TO TRANSLATE NUMBER INTO .WORD 2 ; BIT POSITIONS .WORD 4 .WORD 10 .WORD 20 .WORD 40 .WORD 100 .WORD 200 .WORD 400 .WORD 1000 .WORD 2000 .WORD 4000 .WORD 10000 .WORD 20000 .WORD 40000 .WORD 100000 .CSECT MOS .PAGE .SBTTL FSHMQ - REMOVE SIGNALS FROM ACTIVE PID'S MESSAGE QUEUE ; ; CALLED WITH: R0 - (LO) OPCODE ; R1 - SIGNAL DATA ; FSHMQ: $PUSH R0,R2,R1 MOV $APCT,R2 ;GET PCT POINTER ADD #PCTMQH,R2 ;... POINT TO MESSAGE QUEUE 1$: MOV R2,R1 ;REMEMBER PREVIOUS ELEMENT MOV (R1),R2 ;GET LINK TO NEXT MQ ELEMENT BEQ 2$ ;IF DOESN'T EXIST, EXIT CMPB R0,MQOPC(R2) ;OPCODE MATCHES? BNE 1$ ;IF NOT, LOOK AT NEXT ENTRY CMP (SP),MQDATA(R2) ;SAME DATA WORD? BNE 1$ ;IF NOT, LOOK AGAIN MOV R2,R0 ;SET POINT TO ELEMENT TO BE REMOVED MOV $APCT,R2 ADD #PCTMQH,R2 ;POINT TO MESSAGE QUEUE $QDEL ;AND DELETE FROM QUEUE $RLBLK ;RELEASE MQ ELEMENT BR 1$ ;AND LOOK AT NEXT MQE 2$: $POP R1,R2,R0 RTS PC .IF NE, KF.DBG .PAGE .SBTTL $SUSPR - SUSPEND PROCESS ; ; CALLED WITH: R0 - (LO) PID ; $SUSPR: $PUSH R0 $CVPCT ;GET PCT ADDRESS BIS #PS.FZN,PCTFLG(R0) ;MARK PROCESS AS FROZEN CMP R0,$APCT ;DOING IT TO OURSELVES? BNE 1$ ;IF NOT, SKIP JSR PC,DSCHD ;ELSE, RUN SCHEDULER 1$: $POP R0 $RTT .PAGE .SBTTL $THAWP - RELEASE SUSPENDED PROCESS ; ; CALLED WITH: R0 - (LO) PID ; $THAWP: $PUSH R0 $CVPCT ;GET PCT ADDRESS BIC #PS.SPN,PCTFLG(R0) ;CLEAR SUSPENDED FLAGS $POP R0 $RTT .ENDC .PAGE .SBTTL $STIME - ENQUEUE A DELAYED SIGNAL ; ; $STIME - TIMER INITIALIZER ; ; CALLED WITH: R0 - TIMER SIGNAL OPCODE ; R1 - TIMER SIGNAL DATA ; R2 - TIMER SIGNAL DELAY, TICKS ; IF DELAY = 0, CANCEL SIGNAL ; ; RETURNS WITH: R5 THRU R0 - UNCHANGED ; $ITIME: $PUSH R2 ;FLAG AS RECURRING TIMER SIGNAL BR STIME $STIME: CLR -(SP) ;FLAG AS ONCE-ONLY TIMER SIGNAL STIME: $PUSH R2,R0 TST R2 ;ADDING OR REMOVING TIMER SIGNAL? BEQ CANTIM ;IF 0, CANCELLING PREVIOUS SIGNAL $GTBLK ;GET A TIMER ELEMENT MOVB $APID,TQPID(R0) ;REMEMBER CALLER'S PID MOVB (SP),TQOPC(R0) ; SIGNAL OPCODE MOV R1,TQDATA(R0) ;AND SIGNAL DATA MOV 4(SP),TQINT(R0) ;INDICATE SIGNAL TYPE MOV R2,TQCNT(R0) ;INIT WORKING TIME COUNTER ADD MINTIM,TQCNT(R0) SUB TIMLFT,TQCNT(R0) ;ADD TIME SINCE LAST QUEUE UPDATE CMP R2,TIMLFT ;DELAY LESS THAN TIME REMAINING? BHIS 1$ ;IF NOT, SKIP MOV R2,TIMLFT ;RESET REMAINING TIME COUNTER MOV TQCNT(R0),MINTIM ; AND SOONEST SIGNAL TIME 1$: MOV #$TIMQ,R2 ;GET POINTER TO TIMER SIGNAL QUEUE $ENQ ;ENQUEUE ON TIMER QUEUE STMEXT: $POP R0,R2 TST (SP)+ ;DISCARD FLAG $RTT ;AND RETURN CANTIM: SWAB R0 ;PUT OPCODE INTO HIGH BYTE CLRB R0 ;ZERO OUT LOW BYTE BISB $APID,R0 ;MERGE IN OUR PID $PUSH R1 ;SAVE TIMER SIGNAL DATA MOV #$TIMQ,R2 ;GET POINTER TO TIMER QUEUE 1$: MOV R2,R1 ;REMEMBER CURRENT PTR AS PREVIOUS PTR MOV (R1),R2 ;GET NEXT LINK BEQ 2$ ;IF NO MORE, EXIT CMP R0,TQPID(R2) ;DOES PID/OPC COMPARE? BNE 1$ ;IF NOT, LOOK AGAIN CMP (SP),TQDATA(R2) ;DOES DATA COMPARE? BNE 1$ ;IF NOT, LOOK AGAIN $PUSH R0 ;SAVE PID/OPC MOV R2,R0 ;GET ELEMENT POINTER MOV #$TIMQ,R2 ;AND QUEUE HEAD $QDEL ;REMOVE TIMER ELEMENT FROM THE QUEUE $RLBLK ;AND RELEASE THE ELEMENT BLOCK $POP R0 ;RECOVER PID/OPC 2$: $POP R1 SWAB R0 ;GET OPC BACK IN LOW BYTE JSR PC,FSHMQ ;REMOVE SIGNAL FROM MESSAGE QUEUE BR STMEXT .PAGE .SBTTL $TIMER - TIMER INTERRUPT HANDLER $TIMER: ADD #1,$TOD+2 ;INCREMENT TIME OF DAY COUNTER ADC $TOD DEC TIMLFT ;DECREMENT DOWN COUNTER BNE 6$ ;IF NOT EXPIRED, EXIT $PUSH R0,R1,R2,R3,R4 ; R0 - POINTER TO TIMER QUEUE ELEMENT ; R1 - POINTER TO PREVIOUS BLOCK ; R2 - ADDRESS OF TIMER QUEUE HEAD/TAIL POINTERS ; R3 - POINTER TO NEXT QUEUE ELEMENT ; R4 - MINIMUM TIME-TO-EXPIRATION OF TQE PROCESSED MOV #3600.,R4 ;SET MAXIMUM REFRESH INTERVAL 1 MINUTE MOV #$TIMQ,R2 ;GET POINTER TO TIMER QUEUE HEAD MOV R2,R1 ;SET AS PREVIOUS BLOCK BR 4$ ;AND ENTER LOOP 1$: SUB MINTIM,TQCNT(R0) ;SUBTRACT TIME ELAPSED BHI 2$ ;IF NOT EXPIRED, SKIP $PUSH R0,R1 ;SAVE TQ POINTER & PREVIOUS POINTER MOV TQDATA(R0),R1 ;GET SIGNAL DATA MOV TQPID(R0),R0 ;AND PID/OPC $SGNLI R0,R0,R1 ;SIGNAL HIM $POP R1,R0 ;RECOVER POINTER MOV TQINT(R0),TQCNT(R0) ;RESET WORKING COUNTER BNE 2$ ;IF CONTINUING SIGNAL, SKIP DELETION MOV (R0),R3 ;GET LINK TO NEXT ELEMENT $QDEL ;DELETE THIS BLOCK $RLBLK ;RETURN IT TO FREE STORAGE MOV R3,R0 ;NEXT BLOCK NOW CURRENT BLOCK ; AND DON'T CHAGE PREVIOUS BLK POINTER BR 5$ ;NOW CHECK NEXT TQ ELEMENT 2$: CMP TQCNT(R0),R4 ;IS TIME LEFT SMALLEST SO FAR? BHIS 3$ ;IF NOT, SKIP MOV TQCNT(R0),R4 ;ELSE, REMEMBER ITS TIME 3$: MOV R0,R1 ;REMEMBER THIS AS PREVIOUS ELEMENT 4$: MOV (R1),R0 ;GET LINK TO NEXT ELEMENT 5$: BNE 1$ ;HANDLER IT IF IT EXISTS MOV R4,MINTIM ;REMEMBER START OF DOWNN-COUNTER MOV R4,TIMLFT ;RESET DOWN COUNTER $POP R4,R3,R2,R1,R0 6$: $RTT ;AND RETURN FROM INTERRUPT .PAGE .SBTTL $SETOD - SET TIME-OF-DAY ; CALLED WITH: R0 - TIME-OF-DAY MSW ; R1 - TIME-OF-DAY LSW $SETOD: MOV R0,$TOD ;SAVE NEW TIME-OF-DAY MOV R1,$TOD+2 $RTT .SBTTL $GETOD - GET TIME-OF-DAY ; RETURNS WITH: R0 - TIME-OF-DAY MSW ; R1 - TIME-OF-DAY LSW $GETOD: MOV $TOD,R0 ;GET TIME-OF-DAY MOV $TOD+2,R1 $RTT .PAGE .SBTTL $GAPID - GET ACTIVE PROCESS' PID ; RETURNS WITH: R0 - ACTIVE PID $GAPID: CLRB R0 ;ZAP OUT LOW BYTE BISB $APID,R0 ;MERGE IN PID $RTT ;AND RETURN .PAGE .SBTTL $GPSTS - GET PROCESS' STATUS ; CALLED WITH: R0 - PID ; ; RETURNS WITH: R0 - PID ; R1 - PROCESS' STATUS FLAGS $GPSTS: CMPB R0,$PCTVT ;VALID PROCESS ID BHI 1$ ;IF INVALID, RETURN ERROR $PUSH R0 $CVPCT ;GET PCT ADDRESS MOV PCTFLG(R0),R1 ;GET STATUS FLAGS $POP R0 $RTT 1$: CLR R0 $RTT .PAGE .SBTTL $GPNAM - GET PROCESS' NAME ; CALLED WITH: R0 - PID ; ; RETURNS WITH: R0,R1,R2 - NAME OF PROCESS $GPNAM: $CVPCT ;GET PCT ADDRESS MOV PCTNAM+2(R0),R1 MOV PCTNAM+4(R0),R2 MOV PCTNAM(R0),R0 $RTT .IF NE, KF.DBG .PAGE .SBTTL $GPREG - GET PROCESS' REGISTER ; CALLED WITH: R0 - PID ; R1 - REGISTER NUMBER ; ; RETURNS WITH: R0 - (LO) PID ; (HI) REGISTER NUMBER ; R1 - CONTENTS OF REGISTER $GPREG: $PUSH R0 $CVPCT ;GET ADDRESS OF PCT CMPB PCTDBG(R0),$APID ;ARE WE DEBUGGING IT? BNE 1$ ;IF NOT, DON'T GET TO SEE ANYTHING MOV (SP),R1 ;GET REGISTER NUMBER CLRB R1 SWAB R1 ;INTO LOW BYTE CMP R1,#10 ;VALID REGISTER NUMBER BHI 1$ ;IF NOT, IGNORE ADD R0,R1 ;ADDRESS REGISTER IN PCT SAVE AREA MOV PCTREG(R1),R1 ;GET ITS CONTENTS 1$: $POP R0 $RTT .PAGE .SBTTL $SPREG - SET PROCESS' REGISTER ; CALLED WITH: R0 - (LO) PID ; (HI) REGISTER NUMBER ; R1 - DESIRED CONTENTS OF REGISTER $SPREG: $PUSH R0,R1 $CVPCT ;GET ADDRESS OF PCT CMPB PCTDBG(R0),$APID ;ARE WE DEBUGGING IT? BNE 1$ ;IF NOT, DON'T GET TO SEE ANYTHING MOV (SP),R1 ;GET REGISTER NUMBER CLRB R1 SWAB R1 ;INTO LOW BYTE CMP R1,#10 ;VALID REGISTER NUMBER BHI 1$ ;IF NOT, IGNORE BIS BITTBL(R1),PCTDBF(R0) ;MARK REGISTER AS MODIFIED ADD R0,R1 ;ADDRESS REGISTER IN PCT SAVE AREA MOV (SP),PCTREG(R1) ;MOVE IN NEW CONTENTS 1$: $POP R1,R0 $RTT .ENDC .PAGE .SBTTL $CVPCT - CONVERT PID INO PCT ADDRESS ; CALLED WITH: R0 - PID ; ; RETURNS WITH: R0 - CORRESPONDING PCT ADDRESS $CVPCT: BIC #377*400,R0 ;CLEAR HIGH BYTE BEQ 1$ ;IF PID=0, USE ACTIVE PCT CMP R0,$PCTVT ;COMPARE VS LARGEST PID BHI ERR6 ;IF TOO LARGE, ERROR ASL R0 ;CONVERT TO WORD INDEX MOV $PCTVT(R0),R0 ;GET PCT ADDRESS RTS PC ;AND RETURN 1$: MOV $APCT,R0 ;GET OUR PCT ADDRESS RTS PC ;AND RETURN ERR6: BUGHLT ;INVALID PID ERROR HALT $ERR6: NOP ;GET DDT TO GIVE OUT $ENQ AS ADDR .PAGE .SBTTL $ENQ -- PLACE QUEUE ELEMENT IN FIFO QUEUE ; CALLED WITH: R0 - ADDRESS OF NEW QUEUE ELEMENT ; R2 - ADDRESS OF HEAD,TAIL POINTERS $ENQ: CLR (R0) ;CLEAR LINK OF NEW QUEUE EL MOV R0,@2(R2) ;LINK OLD TAIL TO NEW TAIL MOV R0,2(R2) ;UPDATE TAIL POINTER RTS PC ;RETURN .SBTTL $DEQ -- REMOVE ELEMENT FROM FIFO QUEUE ; CALLED WITH: R2 - ADDRESS OF HEAD,TAIL POINTERS ; ; RETURNS WITH: R0 - ADDRESS OF REMOVED QUEUE ELEMENT ; CC Z BIT SET IF QUEUE WAS EMPTY $DEQ: MOV (R2),R0 ;GET ELEMENT AT HEAD BEQ 1$ ;IF EMPTY, EXIT MOV (R0),(R2) ;UPDATE QUEUE HEAD POINTER BNE 1$ ;IF NOT EMPTY, SKIP MOV R2,2(R2) ;ELSE, POINT TAIL TOWARDS HEAD POINTER 1$: RTS PC ;RETURN .SBTTL $QDEL -- DELETE AN ENTRY FROM A QUEUE ; CALLED WITH: R0 - ADDRESS OF ELEMENT TO DELETE ; R1 - ADDRESS OF ELEMENT PREVIOUS TO ELEMENT TO DELETE ; R2 - ADDRESS OF HEAD,TAIL POINTERS $QDEL: MOV (R0),(R1) ;LINK AROUND DELETED ELEMENT BNE 1$ ;IF NOT DELETING TAIL, SKIP MOV R1,2(R2) ;ELSE, UPDAE TAIL POINTER 1$: RTS PC ;RETURN $MPMBT: .PAGE .SBTTL SYSTEM PARAMETER STORAGE .CSECT MOSDAT APCT: $APCT: .WORD 0 ;ADDR OF ACTIVE PROCESS' PCT APID: $APID: .WORD 0 ;ACTIVE PROCESS ID $APFLG: .WORD 0 ;ADDR OF ACTIVE PROCESS' CAP FLAGS SCHDFLG: .WORD 0 ;SAYS THAT SOMEONE WAS SCHEDULED $TIMQ: .WORD 0 ;TIMER QUEUE HEAD .WORD 0 ;TIMER QUEUE TAIL MINTIM: .WORD 0 ;SMALLEST TIME DELAY TIMLFT: .WORD 0 ;TIME LEFT TILL NEXT SIGNAL EXPIRES TOD: $TOD: .WORD 0,0 ;TIME-OF-DAY .IF NE, KF.DBG BPTSAV: .WORD 0 ;BREAKPOINT HANDLER ADDR SAVE AREA .ENDC .END $BEGIN