.TITLE VTY - VTY SERVICE TASK .SBTTL VTY - TITLE PAGE .IDENT /V02.08/ ; ; ************************************************************************ ; * ; THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS ONLY. DIGITAL EQUIPMENT * ; COMPUTER USER'S SOCIETY, DIGITAL EQUIPMENT CORPORATION, MONSANTO, AND * ; THE AUTHOR DISCLAIM ALL WARRANTIES ON THE PROGRAM, INCLUDING WITHOUT * ; LIMITATION, ALL IMPLIED WARRANTIES OF MERCHANTABLITY AND FITNESS. * ; * ; FULL PERMISSION AND CONSENT IS HEREBY GIVEN TO DECUS AND TO THE DECUS * ; SPECIAL INTEREST GROUPS TO REPRODUCE, DISTRIBUTE, AND PUBLISH AND * ; PERMIT OTHERS TO REPRODUCE IN WHOLE OR IN PART, IN ANY FORM AND * ; WITHOUT RESTRICTION, THIS PROGRAM AND ANY INFORMATION RELATING THERETO * ; * ; ************************************************************************ ; ; VERSION: V02.08 ; ; AUTHOR: RW STAMERJOHN MAPS 28-SEP-77 ; ; MODIFICATIONS: ; ; V01.01 RWS 09-JAN-78 REWROTE OUTPUT LOGIC TO SOLVE QIO ; PROBLEMS (TO MANY BEING ISSUED). ; ; V02.00 RWS 10-AUG-78 CONVERTED TO PHASE II INTERFACES, ; PRACTICALLY TOTAL REWRITE IN SOME ; AREAS. ; ; V02.01 RWS 08-SEP-78 RENAME REMOTE TASK TO RSXVT3 ; ; V02.02 RWS 08-SEP-78 CHANGE SIZE OF ECHO BUFFERS TO 10. ; CHARACTERS. ; ; V02.03 RWS 08-SEP-78 TRY IN 2 TICS FOR MORE OUTPUT FOR ; PARTIAL OUTPUT BUFFERS ; ; V02.04 RWS 08-SEP-78 MULTI-BUFFER INPUT ; ; V02.05 RWS 08-SEP-78 ADD CONTROL-O SUPPORT ; ; V02.06 RWS 11-SEP-78 ADD CONDITIONAL ACCOUNTING SUPPORT ; ; V02.07 RWS 21-SEP-78 CLEAN UP DOCUMENTATION ; ; V02.08 RWS 28-OCT-78 USE TWO CHANNELS ; ; THIS TASK IS THE PASSIVE END OF VTY SERVICE. USE WITH RSXVTY FROM THE ; DECSYSTEM-10. ; ; ASSEMBLY INSTRUCTIONS: ; ; OBJECT,LISTING=NETLIB/ML,VTY ; ; IF ACCOUNTING IS DESIRED, ALSO DEFINE THE SYMBOL V$$INF. .SBTTL VTY - GLOBAL DEFINITIONS ; ; SYSTEM MACROS: ; ; SYSTEM DIRECTIVE MACROS: ; .MCALL ALUN$S ;ASSIGN LUN .MCALL ASTX$S ;EXIT AST .MCALL EXIT$S ;EXIT TASK .MCALL WTSE$S ;WAIT FOR EVENT FLAG .MCALL SETF$S,CLEF$S ;SET/CLEAR EVENT FLAG .MCALL ICHR$S,OCHR$S ;PTY DIRECTIVES .MCALL MRKT$S ;ISSUE MARK TIME .MCALL GTSK$S ;GET TASK PARAMETERS .MCALL DSAR$S ;DISABLE AST'S ; ; DECNET PHASE II MACROS: ; .MCALL OPN$,OPN$E ;OPEN TASK FOR DECNET I/O .MCALL CLSW$,CLSW$E ;CLOSE TASK FROM DECNET I/O .MCALL SPAW$,SPAW$E ;SPECIFY DECNET MAILBOX AST ADDRESS .MCALL GNDW$,GNDW$E ;GET NETWORK DATA .MCALL ACCW$,ACCW$E ;ACCEPT LOGICAL CONNECTION .MCALL CONW$,CONW$E ;CONNECT TO REMOTE TASK .MCALL REJW$,REJW$E ;REJECT LOGICAL CONNECTION .MCALL SND$,SND$E ;TRANSMIT DATA TO REMOTE PARTNER .MCALL REC$,REC$E ;RECIEVE DATA FROM REMOTE PARTNER .MCALL CONB$$ ;DEFINE CONNECT BLOCK .MCALL CRBDF$ ;DEFINE CONNECT BLOCK OFFSETS .MCALL CNBDF$ ;DEFINE CONNECT BLOCK OFFSETS .MCALL NSSYM$ ;DEFINE NETWORK SYMBOLS .MCALL IOERR$ ;DEFINE ERROR SYMBOLS ; ; ERROR PROCESSING MACROS: ; .MCALL DIRERR ;DIRECTIVE ERRORS .MCALL QIOERR ;I/O STATUS ERRORS ; ; GLOBAL DECLARATIONS: ; .GLOBL START ;TASK ENTRY ADDRESS ; ; GLOBAL REFERENCES: ; .GLOBL $DSW ;DIRECTIVE STATUS RETURN .SBTTL VTY - DATA DEFINITIONS ; ; LOCAL SYMBOLS: ; ; DEFINE DECNET SYMBOLS. ; CRBDF$ ; CNBDF$ ; NSSYM$ ; IOERR$ ; ; ; DEFINE NO ERROR MESSAGE PROCESSING. ; D$$MSG = 0 ;NO DIRECTIVE ERROR MESSAGES. Q$$MSG = 0 ;NO QIO ERROR MESSAGES. ; ; EVENT FLAGS. ; EV.DON = 17. ;NO VTY CONNECTIONS FLAG. EV.WTQ = 18. ;QIO WAIT EVENT FLAG. ; ; LUN DEFINITIONS. ; NTLUN = 1 ;CONNECTION LUN. PTLUN = 2 ;START OF VTY LUNS. PTUNT = 77 ;HIGHEST PTY UNIT NUMBER. ; ; MARKER SYMBOLICS. ; MARKR = 377 ;MARKER CHARACTER. CNTRLO = 17 ;CONTROL-O ; ; I/O BUFFER SYMBOLICS. ; B.HDR = 6 ;SIZE OF OUTPUT BUFFER HEADER. I.NUM = 4 ;NUMBER OF INPUT BUFFERS. I.SIZ = 040+B.HDR ;SIZE OF INPUT BUFFER. O.NUM = 4 ;NUMBER OF OUTPUT BUFFERS. O.SIZ = 124+B.HDR ;SIZE OF OUTPUT BUFFER. E.NUM = 4 ;NUMBER OF ECHO BUFFERS. E.SIZ = 012+B.HDR ;SIZE OF ECHO BUFFER ; ; PTY TABLE OFFSETS AND BITS. ; P.IOS = 0 ;I/O STATUS P.FLG = 4 ;FLAG WORD. P.TTY = 6 ;PTY TERMINAL NUMBER. P.PTY = 7 ;PTY NUMBER. P.LNI = 10 ;VTY DECNET INPUT LUN. P.LNO = 12 ;VTY DECNET OUTPUT LUN P.IWT = 14 ;INPUT WAIT QUEUE P.OWT = 16 ;PARTIAL BUFFER ADDRESS P.OHD = 20 ;OUTPUT BUFFER HEADER. P.EHD = 22 ;ECHO BUFFER HEADER. P.IBF = 24 ;START OF INPUT BUFFERS. P.OBF = P.IBF+ ;START OF OUTPUT BUFFERS. P.EBF = P.OBF+ ;START OF ECHO BUFFERS. P.SIZ = P.EBF+ ;SIZE OF PTY TABLE. ; PF.USE = 000001 ;PTY IN USE BIT. PF.SCN = 000002 ;PTY ENABLED FOR OUTPUT SCANNING. PF.SPD = 000004 ;PTY SUSPENDED. PF.PWT = 000010 ;PARTIAL BUFFER PENDING ; ; LOCAL DATA STRUCTURES: .IF DF V$$INF ; ; ACCOUNTING BUFFERS ; SP1CNT::.WORD 0 ;NUMBER OF INPUT (NO ECHO) SUSPENDS SP2CNT::.WORD 0 ;TOTAL NUMBER OF INPUT SUSPENDS OU1CNT::.WORD 0 ;NUMBER OUTPUTS FROM POSAST OU2CNT::.WORD 0 ;NUMBER OF PARTIAL AST'S OU3CNT::.WORD 0 ;NUMBER FULL OUTPUTS FROM PASAST OU4CNT::.WORD 0 ;NUMBER PARTIAL REQUES FROM PASAST OU5CNT::.WORD 0 ;NUMBER NO MORE OUTPUTS FROM PARAST INPCNT::.BLKW I.SIZ-B.HDR ;SIZE OF INPUTS ECHCNT::.BLKW E.SIZ-B.HDR ;SIZE OF ECHO OUTPUTS OUTCNT::.BLKW O.SIZ-B.HDR ;SIZE OF OUTPUTS .ENDC ; ; NETWORK CALL'S: ; OPNNET: OPN$ NTLUN,EV.WTQ,IOSTAT,OPNAST,<0> CLSNET: CLSW$ NTLUN,EV.WTQ,IOSTAT, MAILBX: SPAW$ NTLUN,EV.WTQ,IOSTAT,, MAILGT: GNDW$ NTLUN,EV.WTQ,IOSTAT,, REJECT: REJW$ NTLUN,EV.WTQ,IOSTAT,, ACCEPT: ACCW$ ,EV.WTQ,IOSTAT,, CONNCT: CONW$ ,EV.WTQ,IOSTAT,, SNDECH: SND$ ,,,ECHAST,<0,0> SNDOUT: SND$ ,,,OUTAST,<0,0> SNDTTY: SND$ ,,,INIAST,<0,1> RCVCHR: REC$ ,,,CRVAST,<0,I.SIZ-B.HDR> ; .PSECT $$$VTY ; ; N.B. THIS PSECT MUST BE THE LAST IN THE TASK. THE PTY TABLES ARE ; ALLOCATED FROM PTTBL TO THE END OF THE TASK. ; ; LOCAL VARIABLES. ; NULFLG: .WORD -1 ;COUNT OF ACTIVE VTY'S PTYNUM: .WORD 0 ;NUMBER OF PTY'S ; ; LOCAL BUFFERS ; IOSTAT: .BLKW 2 ;GENERAL PURPOSE I/O STATUS BUFFER. BUFFER: .BLKB N.CBL ;GENERAL PURPOSE BUFFER. CONBLK: CONB$$ ,,,,,, ; ; PTY BUFFERS. ; PTTBL: ;REF. LABEL .BLKB P.SIZ ;ALLOCATE AT LEAST ONE BUFFER. ; .PSECT .SBTTL VTY * MAIN-LINE TASK CODE ;+ ; ; THIS IS THE MAIN-LINE CODE FOR THE VTY SERVICE TASK. IT SETS UP THE PTY ; TABLES BASED ON THER AMOUNT OF AVAILABLE SPACE AND CONNECTS TO DECNET. THE ; MAIN-LINE CODE THEN SLEEPS, WAKING UP WHEN ALL VTY'S HAVE DISCONNECTED. ; ;- ; START:: ;REF. LABEL. GTSK$S #BUFFER ;GET TASK PARAMETERS (SIZE) ; ; SETUP TO CONSTRUCT PTY TABLES. ; CLR R1 ;CLEAR NUMBER OF PTY'S AVAILABLE MOV #PTTBL,R2 ;GET PTY TABLE ADDRESS MOV #PTLUN,R3 ;GET START OF PTY LUN'S MOV #PTUNT,R4 ;GET START OF PTY UNITS ; ; LOOP THROUGH AVAILABLE MEMORY AND SETUP PTY TABLES. ; 10$: MOV R2,R5 ;GET END OF THIS ENTRY ADD #P.SIZ,R5 ; CMP R5,BUFFER+G.TSTS ;IS ENTRY IN LEGAL TASK SPACE? BHI 20$ ; IF HI - NO, NO MORE SPACE ALUN$S R3,#"TT,R4 ;ASSIGN LUN TO PTY DIRERR <,> ; IF FAILS, NO MORE PTY'S ALUN$S R3,#"NS,#0 ;ASSIGN LUN TO NETWORK DIRERR ; FAIL ON ALL ERRORS MOV R3,P.LNI(R2) ;STORE LUN NUMBER INC R3 ;ADVANCE TO NEXT LUN ALUN$S R3,#"NS,#0 ;ASSIGN LUN TO NETWORK DIRERR ; FAIL ON ALL ERRORS MOV R3,P.LNO(R2) ;STORE LUN NUMBER INC R3 ;ADVANCE LUN NUMBER MOVB R1,P.PTY(R2) ;STORE PTY NUMBER MOVB R4,P.TTY(R2) ;STORE TERMINAL NUMBER CLR P.FLG(R2) ;CLEAR PTY CONTROL FLAGS MOV R5,R2 ;SET START OF NEXT POSSIBLE CELL INC R1 ;COUNT PTY DEC R4 ;ADVANCE TO NEXT TTY BR 10$ ;CONTINUE CHECKING MEMORY ; ; WHEN NO MORE MEMORY OR PTY'S, FALL TO HERE. ; 20$: MOV R1,PTYNUM ;SAVE NUMBER OF PTY'S BEQ 30$ ; IF EQ - NO SENSE BEING HERE OPN$E OPNNET,,,,, ;OPEN TASK FOR DECNET I/O DIRERR ; FAIL ON ALL ERRORS ; ; GOTO SLEEP UNTIL ALL PTY ACTIVITY STOPS. REMAINDER OF TASK EXECUTES AT ; AST LEVEL. ; WTSE$S #EV.DON ;SLEEP TILL WOKE UP. ; ; WHEN WOKEN, TERMINATE DECNET AND EXIT TASK. ; CLSW$E CLSNET ;CLOSE DECNET I/O DIRERR ; FAIL ON ALL ERRORS QIOERR IOSTAT,#NTLUN ; FAIL ON ALL ERRORS 30$: EXIT$S ;EXIT TASK .SBTTL OPNAST * COMPLETE NETWORK OPEN PROCESS ;+ ; THIS AST INITIATES THE NETWORK DATA AST. IT THEN FALLS INTO THE NETWORK ; AST CODE ON THE NEXT PAGE. ; ; INITIATED BY: ; ; COMPLETION OF THE NETWORK OPN CALL. ; ; EXIT STATE: ; ; NETWORK AST DECLARED SUCCESSFULLY. ; ; NEXT STATE: ; ; FALLS INTO NETWORK AST CODE ON NEXT PAGE. ;- OPNAST: ;REF. LABEL MOV (SP)+,R0 ;GET I/O STATUS BUFFER ADDRESS QIOERR (R0),#NTLUN ; FAIL ON ALL ERRORS SPAW$E MAILBX ;SETUP NETWORK AST FOR MAILBOX DIRERR ; FAIL ON ALL ERRORS QIOERR IOSTAT,#NTLUN ; FAIL ON ALL ERRORS ; ; FALL INTO NEXT PAGE....... ; .SBTTL SPAAST * NETWORK DATA QUEUE AST ;+ ; THIS AST HANDLES ITEMS ENTERING IN THE NETWORK DATA QUEUE. THE ITEMS ARE ; RETRIEVED AND PROCESSED ACCORDING TO TYPE. ; ; INTIATED BY: ; ; NETWORK SOFTWARE WHEN ENTRY MADE INTO NETWORK MAILBOX QUEUE. ; ; EXIT STATE: ; ; MAILBOX QUEUE EMPTIED. CONNECT REQUEST ARE ACCEPTED IS RESOURCES (PTY'S) ; ARE AVAILABLE, OTHERWISE, THE CONNECT IS REJECTED. INTERRUPT MESSAGES ; ARE IGNORED. ALL OTHER AST REASONS ARE ASSUMED TO BE LINK TERMINATION ; AND FREE THE PTY FOR USE. ; ; NEXT STATE: ; ; IF CONNECT REQUEST SEEN AND VALIDATED, THE ACCEPT CALL WILL ; CAUSE A AST AT INIAST. ; ; OTHERWISE, THE NEXT STATE IS INDETMINATE. IF THE CODE SEES NO ; PTY'S ARE ACTIVE, IT WILL BLOCK AST'S, SET THE DONE EVENT FLAG, ; AND EXIT TO THE MAINLINE CODE. ;- SPAAST: ;REF. LABEL. GNDW$E MAILGT ;GET NETWORK DATA DIRERR ; FAIL ON ALL ERRORS QIOERR IOSTAT,#NTLUN,<,> ;PROCESS ERRORS BR 10$ ;CHECK TYPE OF ENTRY ; ; COME HERE WHEN NO MORE ENTRIES IN NETWORK DATA QUEUE. CHECK IF PTY'S ; ACTIVE, IF NOT RETURN TO MAIN LINE CODE AND EXIT. ; 30$: TST NULFLG ;ARE ANY PTY'S ACTIVE? BGE 31$ ; IF GE - YES. DSAR$S ;DISABLE AST'S SETF$S #EV.DON ;WAKE UP MAINLINE CODE 31$: ASTX$S ;EXIT AST. ; ; COME HERE TO CHECK TYPE OF ITEM, DISPATCH CORRECTLY. ; 10$: CMPB #NT.CON,IOSTAT+1 ;IS THIS A CONNECT REQUEST? BEQ 20$ ; IF EQ - YES, GO HANDLE CMPB #NT.INT,IOSTAT+1 ;IS THIS AN INTERRUPT MESSAGE? BEQ SPAAST ; IF EQ - YES, IGNORE ; ; ALL OTHER REQUEST CAUSE SHUTDOWN OF THE LOGICAL LINK. ; MOVB IOSTAT+3,R0 ;GET LUN DISCONNECT IS FOR MOV #PTTBL,R5 ;GET PTY TABLE ADDRESS MOV PTYNUM,R1 ;GET NUMBER OF PTY'S 11$: CMPB R0,P.LNI(R5) ;IS THIS CORRECT PTY. BEQ 12$ ; IF EQ - YES. ADD #P.SIZ,R5 ;ADVANCE TO NEXT LUN SOB R1,11$ ;LOOP TILL DONE BR SPAAST ; IF NO MATCH, JUST TRY AGAIN 12$: CLR P.FLG(R5) ;CLEAR PTY FLAGS DEC NULFLG ;COUNT PTY INACTIVE BR SPAAST ;TRY FOR ANOTHER DATA ITEM IN QUEUE ; ; COME HERE TO VALIDATE CONNECT REQUEST. ; 20$: MOV #PTTBL,R5 ;GET PTY TABLES MOV PTYNUM,R1 ;GET NUMBER OF ENTRIES 22$: BIT #PF.USE,P.FLG(R5) ;IS PTY AVAILABLE? BEQ 24$ ; IF EQ - YES ADD #P.SIZ,R5 ;ADVANCE TO NEXT ENTRY SOB R1,22$ ;LOOP TILL DONE 23$: REJW$E REJECT ;REJECT CONNECTION DIRERR ; FAIL ON ALL ERRORS QIOERR IOSTAT,#NTLUN,<> ; FAIL ON ALL ERRORS BR 25$ ;LOOP FOR MORE NETWORK DATA 24$: ACCW$E ACCEPT,P.LNI(R5) ;ACCEPT CONNECTION DIRERR ; FAIL ON ALL ERRORS QIOERR IOSTAT,P.LNI(R5),<> ; FAIL ON ALL ERRORS MOV #BUFFER+N.SND,R0 ;GET SOURCE TASK MOV #CONBLK+N.RND,R1 ;GET CONNECT BLOCK FIELDS MOV #/2,R2 ;GET SIZE OF SOURCE DESCRIPTOR 21$: MOV (R0)+,(R1)+ ;MOVE DESCRIPTOR SOB R2,21$ ;LOOP TILL DONE CONW$E CONNCT,P.LNO(R5) ;ISSUE CONNECT DIRERR ; FAIL ON ALL ERRORS QIOERR IOSTAT,P.LNO(R5) ; FAIL ON ALL ERRORS BIS #PF.USE,P.FLG(R5) ;MARK PTY IN USE INC NULFLG ;COUNT PTY ACTIVE MOV R5,R4 ;GET ADDRESS OF PTY NUMBER ADD #P.TTY,R4 ; SND$E SNDTTY,P.LNO(R5),,R5,, ;SEND TTY NUMBER. DIRERR ; FAIL ON ALL ERRORS 25$: JMP SPAAST ;TRY FOR MORE DATA. .SBTTL INIAST * INITIALIZE NEW PTY ;+ ; THIS AST INITIALIZES A NEW PTY FOR VIRTUAL I/O. ; ; INITIATED BY: ; ; COMPLETION OF TTY NUMBER SEND TO REMOTE. ; ; EXIT STATE: ; ; PTY BUFFERS LINKED TO FREE LIST, PTY SCANNING ENABLED, AND INTIAL ; READ REQUESTS ISSUED. ; ; NEXT STATE: ; ; CRVAST WHEN INPUT AST IS SATISFIED, POSAST WHEN TIME ELAPSES. ;- INIAST: ;REF. LABEL MOV (SP)+,R5 ;GET PTY TABLE ADDRESS CMPB #IS.SUC,(R5) ;WAS TTY OUTPUT SUCCESSFUL? BNE 20$ ; IF NE - NO, JUST EXIT ; ; SETUP PTY OUTPUT BUFFER RINGS. ; CLR P.IWT(R5) ;CLEAR INPUT WAIT QUEUE CLR P.OWT(R5) ;CLEAR OUTPUT WAIT QUEUE MOV R5,R4 ;COPY PTY TABLE HEADER ADD #P.EBF+B.HDR,R4 ;GET FIRST LINK WORD IN BUFFER MOV R4,P.EHD(R5) ;POINT TO FIRST ENTRY MOV #E.NUM,R3 ;GET NUMBER OF BUFFERS 10$: MOV R4,R2 ;COPY BUFFER ADDRESS ADD #E.SIZ,R4 ;GET NEXT BUFFER ADDRESS MOV R4,(R2) ;STORE BUFFER LINK SOB R3,10$ ;LOOP TILL DONE CLR (R2) ;CLEAR LAST POINTER MOV R5,R4 ;COPY PTY TABLE HEADER ADD #P.OBF+B.HDR,R4 ;GET FIRST LINK WORD IN BUFFER MOV R4,P.OHD(R5) ;POINT TO FIRST ENTRY MOV #O.NUM,R3 ;GET NUMBER OF BUFFERS 11$: MOV R4,R2 ;COPY BUFFER ADDRESS ADD #O.SIZ,R4 ;GET NEXT BUFFER ADDRESS MOV R4,(R2) ;STORE BUFFER LINK SOB R3,11$ ;LOOP TILL DONE CLR (R2) ;CLEAR LAST POINTER ; ; ISSUE INPUT CHARACTER RECEIVES. ; MOV R5,R4 ;COPY BUFFER ADDRESS ADD #P.IBF,R4 ;POINT AT INPUT BUFFER MOV #I.NUM,R3 ;SET NUMBER OF BUFFERS 12$: MOV R4,R2 ;COPY BUFFER ADDRESS ADD #4,R2 ;SKIP I/O STATUS BLOCK MOV R5,(R2)+ ;STORE TABLE ADDRESS REC$E RCVCHR,P.LNI(R5),,R4,, ;INPUT CHARS DIRERR ;FAIL ON ALL ERRORS ADD #I.SIZ,R4 ;ADVANCE TO NEXT BUFFER SOB R3,12$ ;LOOP TILL DONE ; ; START TIMER IF NECESSARY. ; TST NULFLG ;IS THIS FIRST PTY BNE 20$ ; IF NE - NO, SKIP MRKT$S ,#1.,#1,#POSAST ;START TIME ; ; EXIT AST. ; 20$: ASTX$S ; .SBTTL CRVAST * PROCESS INPUT CHARACTERS ;+ ; THIS AST INPUTS CHARACTERS RECEIVED FROM THE REMOTE TO THE PTY AND SENDS ; ANY ECHOS TO THE REMOTE. ; ; INITIATED BY: ; ; COMPLETION OF INPUT QIO ISSUED FROM SPAAST. ; ; COMPLETION OF INPUT QIO ISSUED FROM THIS ROUTINE. ; ; EXIT STATE: ; ; ALL CHARACTERS RECEIVED ARE FEED TO THE PTY AND IF ECHO DESIRED ; (BIT 7 OFF), ECHO IS SENT TO THE REMOTE. ANOTHER INPUT REQUEST ; IS ISSUED. ; ; IF A BUFFER CANNOT BE ALLOCATED FOR ECHOING, THE AST IS SUSPENDED. ; IT WILL BE RESUMED BY ECHAST WHEN A BUFFER IS FREE. THE PTY OUTPUT ; SCANNER FOR THE SUSPENDED PTY IS ALSO SUSPENDED FOR THIS CONDITION. ; ; IF ANOTHER INPUT COMPLETES FOR A SUSPENDED PTY, IT IS CHAINED TO ; THE LIST OF SUSPENDED INPUT BUFFERS. ; ; NEXT STATE: ; ; IF AN ECHO IS SENT TO THE REMOTE, THE COMPLETION OF THE ECHO QIO ; WILL CAUSE AN AST AT THE ECHO DONE PROCESSOR (ECHAST). ; ; IF A BUFFER ALLOCATION FAILS, THE NEXT ECHO DONE AST WILL CONTINUE ; THE SUSPENDED PROCESSING OF CHARACTERS. ; ; WHEN ALL CHARACTERS ARE PROCESSED, THE COMPLETION OF THE INPUT REQUEST ; WILL CAUSE AN AST AT THIS ROUTINE. ;_ .ENABL LSB CRVAST: ;REF. LABEL. MOV (SP)+,R4 ;GET I/O STATUS ADDRESS CMPB #IS.SUC,(R4) ;CHECK FOR RECEIVE SUCCESS BEQ 1$ ; IF EQ - YES, CONTINUE ASTX$S ;EXIT AST ; ; SETUP FOR INPUT CHARACTER PROCESSING. ; 1$: ;REF. LABEL .IF DF V$$INF MOV 2(R4),R3 ;GET CHARACTERS IN BUFFER ASL R3 ;MAKE INTO WORD INDEX INC INPCNT(R3) ;COUNT THIS NUMBER RECIEVED .ENDC CRVCHN: MOV R4,-(SP) ;SAVE INPUT BUFFER ADDRESS TST (R4)+ ;SKIP STATUS CODE MOV (R4)+,R3 ;SET NUMBER OF CHARACTERS RECEIVED MOV (R4)+,R5 ;GET PTY TABLE ADDRESS BIT #PF.SPD,P.FLG(R5) ;IS PTY INPUT DISABLED? BNE 5$ ; IF NE - YES, TRY LATER BIC #PF.SCN,P.FLG(R5) ;DISABLE PTY OUTPUT SCANNING. ; ; TRY FOR ANY ECHO BEFORE FEEDING INPUT TO PTY. ; CRVSPD: ;REF. LABEL. CALL GETECH ;GET AN ECHO BUFFER. BCC 10$ ; IF CC - CONTINUE .IF DF V$$INF INC SP1CNT ;COUNT ECHO SUSPEND .ENDC 5$: JMP 50$ ; SUSPEND INPUT 10$: MOV R2,-(SP) ;SAVE BUFFER ADDRESS MOV R1,-(SP) ;SAVE BUFFER SIZE OCHR$S P.PTY(R5),R1,R2 ;TRY FOR ECHO FROM PTY. DIRERR <> ; BRANCH WHEN NONE. ADD $DSW,R2 ;UPDATE BUFFER POINTER. SUB $DSW,R1 ;AND REMAINING SIZE. BNE 20$ ; IF NE - DID NOT FILL BUFFER. 11$: MOV (SP)+,R1 ;GET SIZE OF BUFFER MOV (SP)+,R2 ;GET START OF BUFFER MOV R2,R0 ;COPY BUFFER ADDRESS MOV R5,-(R2) ;STORE PTY TABLE ADDRESS SUB #4,R2 ;GET ADDRESS OF IOSTATUS BLOCK SND$E SNDECH,P.LNO(R5),,R2,, ;SEND CHARS. DIRERR ; FAIL ON ERROR .IF DF V$$INF ASL R1 ;MAKE CHARACTER COUNT IN WORD INDEX INC ECHCNT(R1) ;COUNT THIS NUMBER SENT .ENDC BR CRVSPD ;TRY FOR MORE ECHO. ; ; START FEEDING CHARACTERS TO PTY AND GETTING ECHO. ; 20$: DEC R3 ;COUNT CHARACTER. BLT 30$ ; IF LT - DONE. MOVB (R4)+,R0 ;GET NEXT CHARACTER. CMPB #MARKR,R0 ;IS THIS MARKER. BEQ 23$ ; IF EQ - YES, RETURN MARKER. BIC #177600,R0 ;CLEAR ALL BUT 7-BIT ASCII. ICHR$S P.PTY(R5),R0 ;INPUT CHARACTER TO PTY. DIRERR ; FAIL ON ERROR. CMPB #CNTRLO,R0 ;IS THIS A CONTROL-O BNE 21$ ; IF NE - SKIP MOVB R0,(R2)+ ;RETURN CONTROL-O DEC R1 ;COUNT CHARACTER BEQ 11$ ; IF EQ - OUTPUT BUFFER 21$: OCHR$S P.PTY(R5),R1,R2 ;TRY FOR ECHO. DIRERR <> ; BRANCH WHEN NONE. TSTB -1(R4) ;DO WE WANT ECHO. BPL 22$ ; IF PL - YES. CMPB R0,(R2) ;IS ECHO CHARACTER WE SENT. BNE 22$ ; IF NE - NO, TAKE AS ECHO. CMP #1,$DSW ;WAS ONLY ONE CHARACTER RETURNED. BEQ 20$ ; IF EQ - YES, IGNORE CHARACTER. 22$: ADD $DSW,R2 ;UPDATE BUFFER POINTER. SUB $DSW,R1 ;AND REMAINING SIZE. BEQ 11$ ; IF EQ - FULL BUFFER, OUTPUT. BR 20$ ;TRY FOR ANOTHER CHARACTER. ; ; RETURN MARKER WITHOUT USING AS CHARACTER. ; 23$: MOVB R0,(R2)+ ;STORE IN ECHO BUFFER. DEC R1 ;COUNT CHARACTER. BEQ 11$ ; IF EQ - FULL BUFFER, OUTPUT. BR 20$ ;GET ANOTHER CHARCTER. ; ; ALL DONE. ; 30$: BIS #PF.SCN,P.FLG(R5) ;ENABLE SCANNING. ; ; OUTPUT ANY PARTIAL BUFFER AND EXIT AST. ; SUB (SP)+,R1 ;GET NUMBER CHARACTERS IN BUFFER NEG R1 ; MOV (SP)+,R0 ;GET START OF BUFFER CMP R2,R0 ;HAS BUFFER POINTER MOVED. BEQ 40$ ; IF EQ - NO, DEALLOCATE BUFFER. MOV R0,R2 ;GET START OF BUFFER. MOV R5,-(R2) ;STORE ADDRESS OF PTY TABLE SUB #4,R2 ;GET ADDRESS OF I/O STATUS BLOCK SND$E SNDECH,P.LNO(R5),,R2,, ;SEND CHARS. DIRERR ; FAIL ON ERROR .IF DF V$$INF ASL R1 ;MAKE CHARACTER COUNT IN WORD INDEX INC ECHCNT(R1) ;COUNT THIS NUMBER SENT .ENDC BR 41$ ;ISSUE NEXT INPUT. ; 40$: CALL RTNECH ;RETURN EMPTY BUFFER TO POOL. 41$: MOV (SP)+,R4 ;GET BUFFER ADDRESS MOV R4,R2 ;COPY BUFFER ADDRESS ADD #4,R2 ;SKIP I/O STATUS BLOCK MOV R5,(R2)+ ;SET PTY TABLE ADDRESS REC$E RCVCHR,P.LNI(R5),,R4,, ;INPUT CHARS DIRERR ; FAIL ON ALL ERRORS MOV P.IWT(R5),R4 ;GET NEXT CHAINED BUFFER BEQ 60$ ; IF EQ - NO BUFFER MOV (R4),P.IWT(R5) ;RELINK CHAIN TO HEADER MOV R5,6(R4) ;FORCE CORRECT TABLE ADDRESS JMP CRVCHN ;RESUME WITH NEW BUFFER ; ; SUSPEND TILL BUFFER IS FREE. ; 50$: BIS #PF.SPD,P.FLG(R5) ;SET WE ARE SUSPENDED. .IF DF V$$INF INC SP2CNT ;COUNT TOTAL BUFFERS SUSPENDED .ENDC MOV (SP)+,R1 ;GET BUFFER ADDRESS ADD #P.IWT,R5 ;GET BUFFER HEADER 51$: MOV (R5),R0 ;GET LINK POINTER BEQ 52$ ; IF EQ - END OF CHAIN MOV R0,R5 ;GET NEW POINTER BR 51$ ;CONTINUE CHECK 52$: MOV R1,(R5) ;LINK BUFFER TO CHAIN CLR (R1)+ ;CLEAR LINK MOV R3,(R1)+ ;SET CHARACATERS IN BUFFER MOV R4,(R1)+ ;SET CURRENT BUFFER ADDRESS 60$: ASTX$S ;EXIT THIS AST. .DSABL LSB .SBTTL POSAST * PROCESS OUTPUT CHARACTERS ;+ ; THIS AST SCANS THE PTY'S FOR OUTPUT AND SENDS ANY OUTPUT TO THE REMOTE. ; ; INITIATED BY: ; ; OCCURANCE OF MARK TIME EVENT ISSUED EITHER FROM PW2AST OR HERE. ; ; EXIT STATE: ; ; ALL PTY'S SCANNED FOR OUTPUT AND OUTPUT SENT TO REMOTE. IF AN ; ATTEMPT TO GET AN OUTPUT BUFFER FAILS, ROUTINE QUITS SCAN. THE ; TIMER IS RESET ON EXIT. ; ; IF THE OUTPUT BUFFER IS PARTIALLY FILLED, A 2 TIC TIMER IS SET ; AND THE BUFFER PARAMETERS SAVED. LATER, MORE OUTPUT WILL BE TRIED ; FOR. ; ; NEXT STATE: ; ; IF OUTPUT WAS SENT, THE COMPLETION OF THE OUTPUT QIO WILL CAUSE ; AN AST AT THE OUTPUT DONE PROCESSOR (OUTAST). ; ; IF A PARTIAL BUFFER OCCURS, THE 2 TIC TIMER WILL PASS CONTROL TO ; PARAST. THE EVENT FLAG IS THE PTY NUMBER-1. ; ; AN AST WILL OCCUR HERE WHEN THE RESET TIME GOES OFF. ;_ POSAST: ;REF. LABEL. TST (SP)+ ;REMOVE ARGUMENT FROM STACK. MOV #PTTBL,R5 ;GET PTY TABLE ADDRESS. MOV PTYNUM,R4 ;AND NUMBER OF ENTRIES. 10$: BIT #PF.SCN,P.FLG(R5) ;SHOULD WE SCAN THIS PTY. BEQ 20$ ; IF EQ - NO. BIT #PF.PWT,P.FLG(R5) ;ARE WE WAITING FOR A PARTIAL BUFFER? BNE 20$ ; IF NE - YES. 11$: CALL GETBUF ;TRY FOR AN OUTPUT BUFFER. BCS 20$ ; IF CS - NO BUFFER, GOTO NEXT PTY. OCHR$S P.PTY(R5),R1,R2 ;TRY FOR ANY OUTPUT. DIRERR <> ; BRANCH WHEN NONE. MOV R1,R3 ;SAVE BUFFER SIZE. MOV $DSW,R1 ;GET NUMBER OF CHARACTERS FOUND. MOV R2,R0 ;COPY BUFFER ADDRESS MOV R5,-(R2) ;SAVE PTY TABLE ADDRESS CMP R1,R3 ;IS BUFFER FILLED COMPLETLY? BLT 13$ ; IF LT - NO, TRY FORE MORE LATER SUB #4,R2 ;GET I/O STATUS BLOCK ADDRESS SND$E SNDOUT,P.LNO(R5),,R2,, ;SEND CHARS. DIRERR ; FAIL ON ALL ERRORS .IF DF V$$INF ASL R1 ;MAKE CHARACTER COUNT IN WORD INDEX INC OUTCNT(R1) ;COUNT NUMBER SENT INC OU1CNT ;COUNT FULL OUTPUT .ENDC BR 11$ ; TRY FOR MORE OUTPUT. ; ; SAVE PARTIAL BUFFER INFORMATION AND TRY AGAIN LATER. ; 13$: ADD R1,R0 ;GET FIRST FREE LOCATION MOV R0,-(R2) ;SAVE FIRST FREE LOCATION SUB R1,R3 ;GET CHARACTERS REMAINING MOV R3,-(R2) ;SAVE CHARACTERS REMAINING MOV R2,P.OWT(R5) ;SAVE BUFFER ADDRESS BIS #PF.PWT,P.FLG(R5) ;MARK IN PARTIAL BUFFER STATE MOVB P.PTY(R5),R0 ;GET PTY NUMBER INC R0 ;CONVERT TO EVENT FLAG MRKT$S R0,#2,#1,#PARAST ;ISSUE 2 TIC MARK TIME BR 20$ ;GOTO NEXT PTY ; ; RETURN BUFFER AND ADVANCE TO NEXT ENTRY. ; 12$: CALL RTNBUF ;RETURN BUFFER. 20$: ADD #P.SIZ,R5 ;ADVANCE TO NEXT ENTRY. DEC R4 ;CHECK IF DONE BNE 10$ ; IF NE - NO, LOOP AGAIN ; ; RESET TIMER AND EXIT AST. ; MRKT$S ,#15.,#1,#POSAST ;REISSUE TIMER. DIRERR ; FAIL ON ERRORS. ASTX$S ;EXIT AST. .SBTTL PARAST * PROCESS PARTIAL OUTPUT AST ;+ ; THIS AST PROCESSES THE PARTIAL OUTPUT BUFFER MARK TIME AST. ; ; INITIATED BY: ; ; OCCURANCE OF MARK TIME EVENT ISSUED FROM POSAST/PARAST FOR PARTIAL ; BUFFERS. ; ; EXIT STATE: ; ; PARTIAL BUFFER IS ATTEMPTED TO BE FILLED AND OUTPUT TO REMOTE. ; ; NEXT STATE: ; ; IF CHARACTERS OBTAINED FROM TERMINAL, FULL BUFFERS ARE OUTPUT AND ; ANOTHER PARTIAL BUFFER STARTED. IF NO CHARACTERS OBTAINED, BUFFER ; IS OUTPUT AND PTY TAKEN OUT OF PARTIAL BUFFER MODE. ;- PARAST: ;REF. LABEL .IF DF V$$INF INC OU2CNT ;COUNT PARTIAL AST .ENDC MOV (SP)+,R0 ;GET EVENT FLAG NUMBER DEC R0 ;CONVERT TO PTY NUMBER MOV #PTTBL,R5 ;GET PTY TABLE ADDRESS MOV PTYNUM,R4 ;GET NUMBER OF PTY'S 10$: CMPB R0,P.PTY(R5) ;IS THIS EVENT FOR THIS PTY? BEQ 20$ ; IF EQ - YES ADD #P.SIZ,R5 ;ADVANCE TO NEXT PTY SOB R4,10$ ;LOOP TILL DONE JMP 50$ ;EXIT AST ; ; SET PARTIAL BUFFER PARAMETERS. ; 20$: MOV P.OWT(R5),R0 ;GET PARTIAL BUFFER ADDRESS MOV (R0)+,R1 ;GET CHARACTERS REMAINING MOV (R0)+,R2 ;GET START OF EMPTY PART TST (R0)+ ;SKIP TABLE ADDRESS MOV #O.SIZ-B.HDR,-(SP) ;SET TRUE SIZE OF BUFFER MOV R0,-(SP) ;SET TRUE START OF BUFFER BR 22$ ;CONTINUE IN COMMON CODE ; ; GET ANOTHER BUFFER. ; 21$: CALL GETBUF ;TRY FOR A BUFFER BCS 40$ ; IF CS - NO BUFFER MOV R1,-(SP) ;STORE SIZE OF BUFFER MOV R2,-(SP) ;STORE START OF BUFFER ; ; TRY FOR CHARACTER OUTPUT. ; 22$: OCHR$S P.PTY(R5),R1,R2 ;TRY FOR OUTPUT DIRERR <> ; BRANCH ON NO CHARACTERS CMP $DSW,R1 ;IS BUFFER FULL? BNE 23$ ; IF NE - NO, ACT LIKE PARTIAL MOV (SP)+,R2 ;RECOVER START OF BUFFER MOV (SP)+,R1 ;RECIVER SIZE OF BUFFER MOV R2,R0 ;SAVE BUFFER ADDRESS MOV R5,-(R2) ;SAVE PTY TABLE ADDRESS SUB #4,R2 ;SET R2 TO I/O STATUS ADDRESS SND$E SNDOUT,P.LNO(R5),,R2,, ;SEND BUFFER DIRERR ;FAIL ON ALL ERRORS .IF DF V$$INF ASL R1 ;MAKE CHARACTER COUNT IN WORD INDEX INC OUTCNT(R1) ;COUNT NUMBER SENT INC OU3CNT ;COUNT FULL SEND FROM PARAST .ENDC BR 21$ ;TRY FOR ANOTHER BUFFER ; ; STILL PARTIAL BUFFER, REQUE TO THIS ROUTINE. ; 23$: SUB $DSW,R1 ;UPDATE CHARACTERS REMAINING ADD $DSW,R2 ;UPDATE START OF FREE BUFFER MOV (SP)+,R0 ;GET START OF BUFFER TST (SP)+ ;SKIP TRUE SIZE TST -(R0) ;SKIP PTY ADDRESS MOV R2,-(R0) ;SAVE START OF EMPTY BUFFER MOV R1,-(R0) ;SAVE CHARACTERS REMAINING MOV R0,P.OWT(R5) ;STORE BUFFER POINTER MOVB P.PTY(R5),R0 ;GET PTY NUMBER INC R0 ;MAKE INTO EVENT FLAG MRKT$S R0,#2,#1,#PARAST ;FIRE OFF ANOTHER PARTIAL AST .IF DF V$$INF INC OU4CNT ;COUNT PARTIAL STARTING FROM PASATS .ENDC BR 50$ ;EXIT AST ; ; NO MORE OUTPUT, OUTPUT BUFFER (IF ANY). ; 30$: MOV (SP)+,R2 ;GET START OF BUFFER SUB R1,(SP) ;GET NUMBER CHARACTERS IN BUFFER MOV (SP)+,R1 ; BEQ 31$ ; IF EQ - NO CHARACTERS MOV R2,R0 ;SAVE BUFFER ADDRESS MOV R5,-(R2) ;SAVE PTY TABLE ADDRESS SUB #4,R2 ;POSITION TO I/O STATUS BLOCK SND$E SNDOUT,P.LNO(R5),,R2,, ;SEND BUFFER DIRERR ;FAIL ON ALL ERRORS .IF DF V$$INF ASL R1 ;MAKE CHARACTER COUNT INTO WORD INDEX INC OUTCNT(R1) ;COUNT NUMBER SENT INC OU5CNT ;COUNT EMPTY SEND FROM PASATS .ENDC BR 40$ ;TURN OFF PARTIAL MODE 31$: CALL RTNBUF ;RETURN EMPTY BUFFER ; ; EXIT, TURNING OFF PARTIAL MODE IF NECESSARY. ; 40$: BIC #PF.PWT,P.FLG(R5) ;TURN OFF MODE 50$: ASTX$S ;EXIT AST .SBTTL ECHAST * ECHO COMPLETION AST. ;+ ; THIS AST RETURNS AN ECHO BUFFER TO THE PTY POOL AND CHECKS IF ; THE PTY HAS SUSPENDED ITSELF BECAUSE OF LACK OF BUFFERS. ; ; INTIATED BY: ; ; COMPLETION OF ECHO AST ISSUED FROM CRVAST. ; ; EXIT STATE: ; ; BUFFER RETURNED TO POOL. IF SOME INPUT HAD SUSPEND ITSELF BECAUSE ; OF NO BUFFERS, IT IS RESUMED BY JUMPING TO CRVSPD. OTHERWISE A ; NORMAL EXIT IS TAKEN. ; ; NEXT STATE: ; ; THIS ROUTINE CAUSES NO FURTHER AST'S. ; ; SPECIAL NOTES: ; ; THE I/O STATUS ADDRESS IS OF THE BUFFER, NOT THE PTY TABLE. ; THE I/O STATUS IS NOT CHECKED FOR FAILURE, IF SOMETHING HAPPENS ; THE READ REQUEST WILL SHOW IT. THE PTY TABLE ADDRESS IF BUFFER+4. ;- ECHAST: ;REF. LABEL. MOV (SP)+,R2 ;GET I/O STATUS ADDRESS. ADD #4,R2 ;GET PTY NUMBER IN R5. MOV (R2)+,R5 ; CALL RTNECH ;RETURN BUFFER. ; ; IS PTY SUSPENDED WAITING FOR THIS BUFFER. ; BIT #PF.SPD,P.FLG(R5) ;IS PTY SUSPENDED? BEQ 20$ ; IF EQ - NO, ALL DONE. BIC #PF.SPD,P.FLG(R5) ;CLEAR PTY SUSPENDED. MOV P.IWT(R5),R0 ;GET NEW BUFFER MOV R0,-(SP) ;SAVE BUFFER ADDRESS ON STACK MOV (R0)+,P.IWT(R5) ;RELINK BUFFER MOV (R0)+,R3 ;GET REMAINING SIZE MOV (R0)+,R4 ;AND CURRENT BUFFER POINTER JMP CRVSPD ;RESUME PTY PROCESSING. ; ; EXIT AST. ; 20$: ASTX$S ;EXIT AST. .SBTTL OUTAST * OUTPUT COMPLETION AST. ;+ ; THIS AST RETURNS AN OUTPUT BUFFER TO THE PTY POOL. ; ; INTIATED BY: ; ; COMPLETION OF OUTPUT AST ISSUED FROM POSAST. ; ; EXIT STATE: ; ; BUFFER RETURNED TO POOL. ; ; NEXT STATE: ; ; THIS ROUTINE CAUSES NO FURTHER AST'S. ; ; SPECIAL NOTES: ; ; THE I/O STATUS ADDRESS IS OF THE BUFFER, NOT THE PTY TABLE. ; THE I/O STATUS IS NOT CHECKED FOR FAILURE, IF SOMETHING HAPPENS ; THE READ REQUEST WILL SHOW IT. THE PTY TABLE ADDRESS IF BUFFER+4. ;- OUTAST: ;REF. LABEL. MOV (SP)+,R2 ;GET I/O STATUS ADDRESS. ADD #4,R2 ;GET PTY NUMBER IN R5. MOV (R2)+,R5 ; CALL RTNBUF ;RETURN BUFFER. ; ; EXIT AST. ; 20$: ASTX$S ;EXIT AST. .SBTTL GET??? * GET ECHO/OUTPUT BUFFER. ;+ ; THIS ROUTINE ALLOCATES AN ECHO/OUTPUT BUFFER. ; ; CALLING SEQUENCE: ; ; CALL BY: JSR PC,GET??? (ECH/BUF) ; BCS (NO BUFFER) ; ; CALL WITH: R5 = PTY TABLE ADDRESS. ; ; EXITS WITH: IF SUCCESSFUL: C = 0 ; R1 = SIZE OF BUFFER ; R2 = ADDRESS OF BUFFER ; ; IF NOT: C = 1 ; ; SPECIAL NOTES: ; ; THE BUFFER HAS A 6 BYTE HEADER BEFORE THE ADDRESS POINTED TO BY ; R2. THIS HEADER IS THE I/O STATUS BLOCK FOR THE BUFFER AND A WORD ; TO STORE THE PTY TABLE ADDRESS INTO. ; ; REGISTERS: ; ; USES R1,R2 SAVES R0,R3-R5. ;- GETECH: ;REF. LABEL. MOV P.EHD(R5),R2 ;GET NEXT BUFFER. BEQ CSBUFR ; IF EQ - NO BUFFER, ERROR. MOV (R2),P.EHD(R5) ;SET NEXT FREE BUFFER. MOV #E.SIZ-B.HDR,R1 ;SET SIZE OF BUFFER. BR CCBUFR ;RETURN BUFFER FOUND. GETBUF: ;REF. LABEL. MOV P.OHD(R5),R2 ;GET NEXT BUFFER. BEQ CSBUFR ;IF EQ - NO BUFFER, ERROR. MOV (R2),P.OHD(R5) ;SET NEXT FREE BUFFER. MOV #O.SIZ-B.HDR,R1 ;SET SIZE OF BUFFER. ; ; RETURN GOOD BUFFER. ; CCBUFR: CLC ;SET GOOD BUFFER. RETURN ;EXIT. ; ; RETURN NO BUFFER. ; CSBUFR: SEC ;SET NO BUFFER. RETURN ;EXIT. .SBTTL RTN??? * RETURN ECHO/OUTPUT BUFFER TO POOL ;+ ; THIS ROUTINE RETURNS AN ECHO/OUTPUT BUFFER TO THE FREE POOL. ; ; CALLING SEQUENCE: ; ; CALL BY: JSR PC,RTN??? (ECH/BUF) ; ; CALL WITH: R2 = BUFFER ADDRESS. ; R5 = PTY TABLE ADDRESS. ; ; EXITS WITH: BUFFER RETURNED. ; ; REGISTERS: ; ; USES R2,R5 SAVES R0-R5 ;- RTNECH: ;REF. LABEL. MOV P.EHD(R5),(R2) ;LINK REST OF LIST TO NEW BUFFER. MOV R2,P.EHD(R5) ;LINK BUFFER TO TOP OF LIST. RETURN ; RTNBUF: ;REF. LABEL. MOV P.OHD(R5),(R2) ;LINK REST OF LIST TO NEW BUFFER. MOV R2,P.OHD(R5) ;LINK BUFFER TO TOP OF LIST. RETURN ; .END START