TTDRV.MAC;2/AU/-BF=TTDRV.MAC;1 \ -2,2 .IDENT /19.01/ -11,11 ; VERSION: 19.01 -89 ; HLC003 -- ADD SUPPORT FOR TERMINAL LOGGING. ; % -1544,1544,/;HLC003/ 60$: .IF DF $T$LOG CALL $LOGO ;QUEUE OUTPUT TO LOGGER .ENDC ;.IF DF $T$LOG MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS -2353,,/;HLC003/ .IF DF $T$LOG CALL $LOGU ;QUEUE UNSOLICITED INPUT TO LOGGER .ENDC ;.IF DF $T$LOG -2367,2367,/;HLC003/ 20$: .IF DF $T$LOG CALL $LOGS ;QUEUE SOLICITED INPUT TO LOGGER .ENDC ;.IF DF $T$LOG MOV (R3)+,R1 ;GET STARTING ADDRESS OF BUFFER -4952,,/;HLC003/ .IF DF $T$LOG .DSABL LSB .ENABL LSB ;+ ; $LOGO - QUEUE OUTPUT TO LOGGER TASK IF ACTIVE ; ; THIS ROUTINE IS ENTERED WHENEVER OUTPUT IS SENT TO A TERMINAL. IF ; A LOGGER TASK IS ACTIVE FOR THAT TERMINAL, THE OUTPUT IS COPIED TO ; A LOG BUFFER AND QUEUED TO THE LOGGING TASK. ; ; INPUT: ; ; R3 = A(STATUS WORD) ; R4 = A(SCB) ; R5 = A(UCB) ; ; OUTPUT: ; ; ALL REGISTERS PRESERVED ; ;- $LOGO: CALL LOGSAV ;SAVE ALL REGISTERS CALL LOGACT ;IS LOG TASK ACTIVE ? MOV S.PKT(R4),R2 ;R2 = A(I/O PACKET) MOV U.CNT(R5),R1 ;R1 = DATA LENGTH IF IO.WLB .IF DF T$$RPR TST ATERS(R3) ;WRITING A PROMPT? BPL 1200$ ;IF PL, NO - WE HAVE DATA LENGTH MOV I.PRM+14(R2),R1 ;R1 = LENGTH OF PROMPT 1200$: .ENDC ;.IF DF T$$RPR ADD #5,R1 ;R1 = REQUIRED BUFFER LENGTH CALL $ALOCB ;ALLOCATE A BUFFER BCS 1700$ ;IF CS, NO BUFFER AVAILABLE - PUNT MOV S.PKT(R4),R2 ;R2 = A(I/O PACKET) MOV R0,-(SP) ;SAVE A(BUFFER) CLR (R0)+ ;CLEAR FIRST WORD MOVB #2,(R0)+ ;SET TYPE (OUTPUT) MOVB I.PRM+6(R2),(R0)+ ;INSERT CARRIAGE CONTROL BYTE .IF DF M$$MGE MOV @#KISAR6,-(SP) ;SAVE MAPPING CONTEXT .ENDC ;.IF DF M$$MGE .IF DF T$$RPR TST ATERS(R3) ;WRITING A PROMPT? BPL 1300$ ;IF PL, NO - POOP IN UCNB .IF DF M$$MGE MOV I.PRM+10(R2),@#KISAR6 ;MAP TO TASK - BUFFER MAY BE THERE .ENDC ;.IF DF M$$MGE MOV I.PRM+12(R2),R1 ;R1 = DATA OFFSET MOV I.PRM+14,(R2) ;R2 = DATA LENGTH BR 1400$ ;GO COPY DATA 1300$: .ENDC ;.IF DF T$$RPR .IF DF M$$MGE MOV U.BUF(R5),@#KISAR6 ;MAP TO TASK - BUFFER MAY BE THERE .ENDC ;.IF DF M$$MGE MOV U.BUF+2(R5),R1 ;R1 = DATA OFFSET MOV U.CNT(R5),R2 ;R2 = DATA LENGTH 1400$: MOVB R2,(R0)+ ;INSERT DATA LENGTH BEQ 1600$ ;IF EQ, NO DATA - JUST CARRIAGE CONTROL 1500$: MOVB (R1)+,(R0)+ ;COPY DATA DEC R2 ;DONE? BNE 1500$ ;IF NE, NO - CONTINUE COPYING 1600$: .IF DF M$$MGE MOV (SP)+,@#KISAR6 ;RESTORE MAPPING CONTEXT .ENDC ;.IF DF M$$MGE MOV (SP)+,R1 ;R1 = A(BUFFER) CALL $QLOG ;QUEUE TO LOGGER TASK 1700$: RETURN ;RETURN ;+ ; $LOGU - QUEUE UNSOLICITED INPUT TO LOGGER TASK IF ACTIVE ; ; THIS ROUTINE IS ENTERED WHENEVER UNSOLICITED INPUT IS ABOUT TO BE ; QUEUED TO MCR. IF A LOGGER TASK IS ACTIVE FOR THAT TERMINAL, THE ; INPUT DATA IS COPIED TO A LOG BUFFER AND QUEUED TO THE LOGGING TASK. ; ; INPUT: ; ; R3 = A(A(INPUT DATA)) ; R4 = A(SCB) ; R5 = A(UCB) ; ; OUTPUT: ; ; ALL REGISTERS PRESERVED ; ;- $LOGU: CALL LOGSAV ;SAVE REGISTERS CALL LOGACT ;IS LOG TASK ACTIVE? MOV CURBF-2(R3),R1 ;R1 = A(NEXT BUFFER POSITION) SUB (R3),R1 ;R1 = DATA LENGTH ADD #5,R1 ;R1 = REQUIRED BUFFER LENGTH CALL $ALOCB ;ALLOCATE LOG BUFFER BCS 1700$ ;IF CS, NO BUFFER AVAILABLE - PUNT MOV R0,-(SP) ;SAVE A(BUFFER) CLR (R0)+ ;ZERO FIRST WORD CLRB (R0)+ ;SET TYPE (INPUT) MOVB FNBYT-2(R3),(R0)+ ;SET TERMINAL BYTE MOV CURBF-2(R3),R2 ;R2 = A(END OF DATA) MOV (R3),R1 ;R1 = A(START OF DATA) SUB R1,R2 ;R2 = DATA LENGTH MOVB R2,(R0)+ ;STORE LENGTH BEQ 1900$ ;IF EQ, NO DATA TO COPY 1800$: MOVB (R1)+,(R0)+ ;COPY DATA DEC R2 ;DONE? BNE 1800$ ;IF NE, NO - CONTINUE COPYING 1900$: MOV (SP)+,R1 ;R1 = A(BUFFER) CALL $QLOG ;QUEUE BUFFER TO LOGGER TASK 2000$: RETURN ;RETURN ;+ ; $LOGS - QUEUE UNSOLICITED INPUT TO LOGGER TASK IF ACTIVE ; ; THIS ROUTINE IS ENTERED WHENEVER SOLICITED INPUT HAS BEEN COMPLETED. ; IF A LOGGER TASK IS ACTIVE FOR THIS TERMINAL, THE INPUT DATA IS ; COPIED TO A LOG BUFFER AND QUEUED TO THE LOGGING TASK. ; ; INPUT: ; ; R3 = A(A(START OF BUFFER)) ; R4 = A(SCB) ; R5 = A(UCB) ; ; OUTPUT: ; ; ALL REGISTERS PRESERVED ; ;- $LOGS: CALL LOGSAV ;SAVE REGISTERS CALL LOGACT ;IS LOGGING ACTIVE? MOV U.CNT(R5),R1 ;R1 = ORIGINAL COUNT MOV 2(R3),R0 ;R0 = COUNT REMAINING BIC #177400,R0 ;CLEAR HIGH BYTE SUB R0,R1 ;R1 = DATA LENGTH ADD #5,R1 ;R1 = REQUIRED BUFFER LENGTH CALL $ALOCB ;ALLOCATE A BUFFER BCS 2000$ ;IF CS, BUFFER NOT AVAILABLE - PUNT MOV R0,-(SP) ;SAVE A(BUFFER) CLR (R0)+ ;CLEAR FIRST WORD CLRB (R0)+ ;SET TYPE (INPUT) MOVB 3(R3),(R0)+ ;FINAL BYTE MOV U.CNT(R5),R2 ;R2 = ORIGINAL COUNT MOV 2(R3),R1 ;R1 = COUNT REMAINING BIC #177400,R1 ;CLEAR HIGH BYTE SUB R1,R2 ;R2 = DATA LENGTH MOV (R3),R1 ;R1 = A(DATA) MOVB R2,(R0)+ ;SET DATA LENGTH BEQ 2200$ ;IF EQ, NO DATA TO COPY .IF DF M$$MGE MOV @#KISAR6,-(SP) ;SAVE MAPPING CONTEXT MOV U.BUF(R5),@#KISAR6 ;MAP TO TASK - BUFFER COULD BE THERE .ENDC ;.IF DF M$$MGE 2100$: MOVB (R1)+,(R0)+ ;COPY DATA DEC R2 ;FINISHED? BNE 2100$ ;IF NE, NO - CONTINUE COPYING .IF DF M$$MGE MOV (SP)+,@#KISAR6 ;RESTORE MAPPING CONTEXT .ENDC ;.IF DF M$$MGE 2200$: MOV (SP)+,R1 ;R1 = A(BUFFER) CALL $QLOG ;QUEUE BUFFER TO LOGGING TASK RETURN ;RETURN ;+ ; LOGSAV - SAVE AND RESTORE ALL REGISTERS ; ;- LOGSAV: MOV R4,-(SP) ;SAVE REGISTERS MOV R3,-(SP) MOV R2,-(SP) MOV R1,-(SP) MOV R0,-(SP) MOV 12(SP),-(SP) ;RELOCATE RETURN ADDRESS MOV R5,14(SP) CALL @(SP)+ ;CALL THE CALLER BACK MOV (SP)+,R0 ;RESTORE REGISTERS MOV (SP)+,R1 MOV (SP)+,R2 MOV (SP)+,R3 MOV (SP)+,R4 MOV (SP)+,R5 RETURN ;RETURN ;+ ; LOGACT - DETERMINE IF LOG TASK ACTIVE FOR THIS TERMINAL ; ; INPUT: ; ; R5 = A(UCB) ; ; OUTPUT: ; ; R0,R1 = DESTROYED ; ; RETURN TO (SP) IF LOG TASK ACTIVE ; RETURN TO 2(SP) IF LOG TASK NOT ACTIVE ; ;- LOGACT: MOV TTLOG(R5),R0 ;R0 = A(LOG TASK TCB) BEQ 2400$ ;IF EQ, LOG TASK NOT ACTIVE BIT #TS.EXE!TS.RDN,T.STAT(R0) ;NOT RUNNING OR STOPPING? BNE 2300$ ;IF NE, YES BIT #T2.HLT!T2.ABO!T2.STP!T2.SPN,T.ST2(R0) ;RUNNING? BNE 2300$ ;IF NE, NO MOV T.PCB(R0),R1 ;R1 = A(PCB) BEQ 2300$ ;IF EQ, NOT ACTIVE MOV P.HDR(R1),R1 ;R1 = A(TASK HEADER) CMP TTLOG+2(R5),R1 ;MATCH? BNE 2300$ ;IF NE, NO RETURN ;RETURN - TASK ACTIVE 2300$: CLR TTLOG(R5) ;MAKE NEXT PASS QUICKER 2400$: TST (SP)+ ;POP ACTIVE RETURN FROM STACK RETURN ;RETURN - TASK NOT ACTIVE ;+ ; $QLOG - QUEUE A LOG BUFFER TO LOGGER TASK AND SET EVENT FLAG ; ; INPUT: ; ; R1 = A(BUFFER) ; R5 = A(UCB) ; ; OUTPUT: ; ; BUFFER QUEUED. ; ;- LEFMSK=1 ;LOG EVENT FLAG MASK $QLOG: MOV R5,R0 ;R0 = A(UCB) ADD #TTLOG+4,R0 ;R0 = A(LISTHEAD) CALL $QINSF ;INSERT BUFFER IN QUEUE MOV TTLOG(R5),R0 ;R0 = A(TCB) BIS #LEFMSK,T.EFLG(R0) ;SET EVENT FLAG MOV $ACTHD,$RQSCH ;DECLARE SIGNIFICANT EVENT RETURN ;RETURN .ENDC ;.IF DF $T$LOG /