; SHARED PART OF PERM FOR PSR COMPILER ;******************* ;* PERM0S VSN 12 * ;* 23.APR.80 * ;******************* PON=2 POFF=3 DELETE=5; EMT DELETE TASK GETID=14; EMT 12. - GET ID PONPOF=21; EMT 17. - PON POFF TTID=1 DKID=3 DIRID=4 LPID=14 LOADID=41; ACTUAL ID OF LOADER TASK ***** MAY CHANGE ************** LNB=R5 ; ************************************************************* ; FAULT VALUES FOR PROGRAM TERMINATION FEOF = 31; FAULT 25, NO FILE OR END OF FILE SYNFLT = 32; FAULT 26, SYNTAX FAULT ON I/O STRING DSCFLT = 33; FAULT 27, DISC I/O FAIL (EG ILLEGAL BLOCK) DSCFUL = 34; FAULT 28, DISC OR DIRECT IS FULL UP ; ************************************************************ RDSYX=0; INDEX INTO STREAM DESCRIPOR NEXYX=2; DITTO GETBX=4; DITTO SER=6 REPLY=7 UNIT=10 FSYS=11 NAME=12; BIA NAME(0:5) BLOCK=20 OFFSET=22 NCHARX=22 PTX=24 MAXX=26 BUFFS=30 ; INDEX TO STRAM DESCRIPTOR - FROM OFFSET RDSY=-22 NEXY=-20; ; NEXTX-OFFSET GETB=-16 ; GETBX-OFFSET NCHAR=0; =NCHARX-OFFSET PT=2; =PTX-OFFSET MAX=4; =MAXX-OFFSET ; ****************************** ; NOTE: ON OUTPUT * ; PT IS MAPPED TO NCHAR * ; PRSY IS MAPPED TO RDSY* ; ****************************** ; LAYOUT OF READ/WRITE I/O SEGMENT (SEG 7 ADDR=160000) RDSPSR=160000 NXYPSR=160002 PRSPSR=160004 SINP =160006 SOUT =160010 PSTOP =160012 CLOSE =160014 SIGNAL=160016 ; ADDRESS OF PERM VARIABLES X =160020 Y =160022 INSTRM=160024 OUTSTR=160026 ID =160030 CALLID=160031 STRPTS=160032; %INTEGERARRAY STRPTS(0:7) TOP=160052 UNFYS=160054 GLA=160056 INTCHR=160060 STR0ID = 160061 SPARE=160062 ; END OF PERM VARIABLES ZERO=60 ONE=61 NINE=71 A=101 Z=132 SLASH=57 COMMA=54 DOT=56 OPENBR=50 CLSEBR=51 ; ************************************************************ .=20000 ; ************************************************************ MOV #-2, R0; KILL TASK ADDRESS JMP DOSTOP BR ENTRY; NORMAL ENTRY BR SPENTR; SYSTEM TASK ENTRY SPON,SPOFF,PONOFF,MAPVRT,GETABS SGETID,STIME,SLINKN,SMAPHW,TIMEP,DATEP SETSTREAMS:; ROUTINE TO SET UP THE STREAM DESCRIPTORS ; ON ENTRY:_ R0 -> BUFFER CONTANING THE FILE DESCRIPTORS (TERM IN LF) ENTRY: MOV R0,R5; PUT PARAM INTO R5 EMT GETID MOV R0,@#ID MOV #SINP, R0 MOV #SELECTINPUT, (R0)+ MOV #SELOUT, (R0)+ MOV #DOSTOP, (R0)+; %AND SET UP %STOP MOVB R4, @#CALLID; REMEMBER WHO CALLED SWAB R4 MOVB R4, @#STR0ID MOV R3, @#UNFYS MOV #CLSE, (R0)+ MOV #SIGNL1, (R0)+ MOV R1, @#GLA; SAVE TOP OF GLA MOV #SPARE,R4; POINTER TO FREE SPACE IN I/O SEG CLR R3; R3=CURRENT STREAM*2 MOV R2, -(SP); LOADER FLAG BNE LOADSP MOVB @#STR0ID,R2; R2 (ON ENTRY TO STUFF) IS P_SERVICE CLR R0; 0=CHAR TYPE, 2=FILE TYPE JSR PC,STUFF; SET ASIDE SPACE FOR TT INPUT LOADSP: CLR -(SP); SET ASIDE A LOCATION ADD #2,R3; R3=1*2 SS1: MOVB (R5)+,R0; GET NEXT CHAR CMPB #12,R0; NEWLINE? BNE SS4; NO, SO CONTINUE THE CHECK CMP #10,R3; HAS OUTPUT(0) BEEN SET UP? BGT SS2; NOT YET, SO SET UP ; DO INITIAL SELECTION OF STREAMS AND JUMP TO IMP PROGRAM TST (SP)+; DUMP 'INIT' POINTER MOV (SP)+, R0; PICK UP 'LOADER' FLAG BNE OUTONLY; IS LOADER, SO DONT DO SELECT INPUT CLR -(SP) JSR PC,@SINP; SELECT INPUT(0) OUTONLY: CLR -(SP) JSR PC,@SOUT; SELECT OUTPUT(0) CLR R1; ENSURE TOP OF STACK PT OK MOV R4, @#TOP MOV @#GLA, R1; PICK UP TOP OF GLA SPENTR: MOV 2(R1), R1; PICK UP S#GO POINTER (ZERO IN OLD CASE) BEQ OLDTPE; OLD TYPE JSR PC, @(R1)+; AND ENTER LIKE EXTERNAL ROUTINE OLDTPE: MOV #40020, PC; ENTER IMP PROGRAM ; ********** SS2: DEC R5; SET UP OUTPUT(0), THEN GET IT TO READ NL AGAIN SS3: MOV #10,R3; OUTPUT(0) MOVB @#STR0ID,R2 CLR R0; CHAR TYPE STREAM JSR PC,STUFF; SET UP OUTPUT(0) CLR (SP); AND CLEAR 'INITIALISED' POINTER ADD #2, R3; AND DO OUTPUT(1) BR SS1; AND GET NEXT SS4: ; TRY NEXT CHECK CMPB #SLASH,R0 BEQ SS3; DO OUTPUT STREAMS NOW CMPB #COMMA,R0; IS IT ','? BNE SS5; NO, SO DO NEXT CHECK ; YES, SO MOVEW TO NEXT SS6: ADD #2,R3; STEP R3 TO NEXT STREAM CLR (SP); SET 'DONE' MARKER BR SS1; AND GET NEXT CHAR SS5: ; NEXT CHECK CMPB #DOT,R0; IS IT '.'? BNE SS7; NO, SO LOOK FOR FILE NAME ; YES, SO MUST BE A DEVICE TST (SP); ALREADY SET UP? BEQ SS5A; NO, SO LOOK FOR DEVICE MOVB -(R1), R0; PICK UP LAST CHAR SUB #ZERO, R0; CONVERT TO 0 OR 1 BLT FAILT; LESS THAN ZERO ??? CMP #4, R0; NO, SO CHECK FOR ONE TO FOUR BLT FAILT; NEITHER, SO FAIL PROGRAM MOVB R0, -2(R1); WRITE UNIT INTO UNIT BYTE MOVB DISCT(R0), -4(R1); FILL IN SERVICE NUMBER BR SS1; GO FOR NEXT CHAR DISCT: 001403; .BYTE 3,3 007010; .BYTE 8.,14. 000034; .BYTE 28., 0 SS5A: MOVB (R5)+,R1; GET NEXT TWO CHARS INTO A WORD SWAB R1 BISB (R5)+,R1 MOV #DEVTAB,R0; TABLE OF POSSIBLES CLR R2; INDEX SS5B: MOV (R0)+,(SP); INDICATE LOOKING (+HOLDS TEST DEVICE) BEQ FAILT; END OF TABLE, SO FAULT CMP (SP),R1; GOT IT? BEQ SS5C; YES, SO EXIT INC R2; INDEX BR SS5B; AND CHECK NEXT SS5C: TST R2 BNE SS5C1; NOT TT, SO LOOK UP MOVB @#STR0ID, R2; TT, SO USE AMENDED NO BR SS5C2; AND CONTINUE SS5C1: MOVB DEVIDS(R2),R2; GET ITS SERVICE NUMBER SS5C2: CLR R0; CHAR TYPE JSR PC,STUFF; AND ALLOCATE SPACE BR SS1; TAKE THE COMMA SS7: ; CHECK FOR LEGAL FILE NAME CMP #ZERO,R0 BGT FAIL CMP #NINE,R0 BGE SS8; BETWEEN 0-9 CMP #A,R0 BGT FAIL CMP #Z,R0 BLT FAIL SS8: TST (SP); FIRST TIME? BNE SS9; NO, SO DONT SET UP MOV R0,-(SP); SAVE THE CHAR MOV #DKID,R2; GET ID OF DISC TASK MOV #2,R0; FILE TYPE JSR PC,STUFF; DECLARE THE SPACE ADD #610,R4; AALLOW FOR DISC BUFFER MOV R4,R1 SUB #1016,R1; POINT AT BEGINNING OF 'NAME' MOV (SP)+,R0; RESTORE THE CHAR INC (SP); BEEN HERE BEFORE POINTER SS9: MOVB R0,(R1)+; PLANT CHAR BR SS1; GET THE NEXT FAIL: CMP #OPENBR, R0; IS IT FILE SYS DEFF BNE FAILT; NO, SO FAIL TST (SP); FILE SPEC? BEQ FAILT; NO, SO FAIL MOVB (R5)+, R1; GET NEXT CHAR SUB #ZERO, R1; MAKE IT NUMBER MOVB (R5)+, R0; GET NEXT CHAR (2ND NUMBER OR ')') CMP #CLSEBR, R0 BEQ FAIL2; YES, SO EXIT ASL R1 ASL R1 ASL R1 ADD R0, R1; ADD IN SECOND NUMBER SUB #ZERO, R1; -'0' MOVB (R5)+, R0; GET THE ')' CMP #CLSEBR, R0 BNE FAILT FAIL2: CMP #77, R1; LEGAL? BLT FAILT; NOPE MOV STRPTS(R3), R0; GET PT TO STREAM MOVB R1, FSYS(R0); AND PLANT IN FSYS JMP SS1; AND GET NEXT FAILT: MOV #SYNFLT,R0 JMP DOSTOP STUFF: MOV R4,STRPTS(R3); PLANT POINTER TO STREAM DEFINITION CLR (R4)+; FIRST TIME FLAG MOV R0,(R4)+; TYPE OF STREAM FLAG CLR (R4)+; GETB MOVB R2,(R4)+; SERVICE TASK MOVB @#ID,(R4)+; REPLY MOV @#UNFYS, (R4)+ MOV #TYPE1,R1 MOV #6,R0; COPY 6. WORDS STLP: MOV (R1)+,(R4)+ DEC R0 BNE STLP ADD #172, (R4); SET MAX TO POINT AT END OF BUFFER ADD #172,R4; SPACE FOR BUFFER RTS PC; AND RETURN ; ******************************************************************* ; READSYMBOL, NEXTSYMBOL, PRINTSYMBOL, SELECT INPUT, SELECT OUTPUT ETC ; ******************************************************************** NEXTSYMBOL: MOV @X,R1 BGE NSOK; NEXTSYMBOL PRESENT MOV @#X,R0; NEXTSYMBOL NOT THERE, SO PICK UP STREAM POINTER JSR PC,@GETB(R0); GET A BUFFER ; CHAR IS INB R1 NSOK: RTS PC READSYMBOL: ; STACK CONTAINS:- RA, ^S RS1: MOV @#X,R0; PICK UP STREAM BUFFER POINTER MOV (R0),R1; LOOK FOR NEXTSYMBOL BGE RS2; ITS THERE JSR PC,@GETB(R0); GET A BUFFER RS2: ; GOT CHAR IN R1 INC PT(R0); STEP THE POINTER CMP PT(R0),MAX(R0); REACHED THE END? BNE RS3; NO, SO EXIT MOV #100000,(R0); MAKE NEXTSYMBOL NOT PRESENT BR RS4; AND HOP IT RS3: MOVB @PT(R0),(R0); PICK UP 'NEXTSYMBOL' BIC #177400,(R0); ENSURE ONLY 8 BITS RS4: MOV (SP)+,R0; PICK UP RETURN ADDRESS MOV R1,@(SP)+; PLANT CHAR THROUGH POINTER, AND POP THE ADDRESS MOV R0,PC; RETURN TO CALLER ; *************************************************************** ; THE GET BUFFER ROUTINE USED IS DEPENDANT ON WHETHER CHAR OR FILE ; *************************************************************** GETB1: ; CHARACTER GET BUFFER SUB #OFFSET,R0; POINT TO BEGINNING OF STREAM DESCRIPTOR MOV R4,-(SP); SAVE R4 MOV R0,R4; REMEBER ADDR OF DESC MOV SER(R4),R0; PICK UP SERVICE/REPLY MOV R4,R2 ADD #BUFFS,R2; POINT TO INPUT BUFFER CLR R1; READ REQUEST EMT PONPOF ; ON RETURN R1 WILL INDICATE SUCCESS/FAILURE AND LENGTH TST R1 BEQ EOF; END OF FILE BUFFCOM: MOV R4,R0; STREAM DESC ADD #BUFFS,R0; POINT TO FIRST CHAR MOV R0,PTX(R4); SET PT UP ADD R0,R1; ^END OF BUFFER MOV R1,MAXX(R4); PLANT IN MAX ADD #OFFSET,R4; POINT TO NORAMAL POSITION MOVB @PT(R4),(R4); PICK UP NEXTSYMBOL BIC #177400,(R4); AND ENSURE 8 BITS MOV (R4),R1; PUT BACK IN R1 MOV R4,R0; RESTORE R0 TO POINT TO 'NEXTSY' MOV (SP)+,R4; RESTORE USERS R4 RTS PC; AND RETURN EOF: MOV (SP)+, R4; RESTORE R4 TST (SP)+; TOSS RA AWAY EOF2: MOV #100004, R1; EOF CHAR JMP RS4; AND EXIT EFAIL: MOV #FEOF, R0; PLANT EOF FAILED CODE EFAIL2: JMP DOSTOP; AND DO '%STOP' DFAIL: MOV #DSCFLT, R0 BR EFAIL2 GETBF2: ; FILE GET BUFFER ROUTINE SUB #OFFSET,R0; POINT BACK TO BEGINNING MOV R4,-(SP); AND SAVE R4 MOV R0,R4 MOV BLOCK(R4), R3; PICK UP BLOCK NUMBER BEQ EOF; HIT END-OF-FILE CLR R1; DO A READ MOV R4,R2 ADD #BUFFS,R2; POINT TO BUFFER MOV SER(R4),R0; SERVICE AND REPLY EMT PONPOF; ASK FOR BLOCK ; GOT BLOCK TST R1; SUCCESS/FAILURE FLAG BNE DFAIL; DISC FAIL MOV BLOCK(R4), R3 MOV R4, R2 ADD #UNIT, R2; CONSTRUCT PT TO FILE DESC MOV #1,R1; GET NEXT SERVICE SWAB R0; GET SERVICE/REPLY AGAIN INC R0; USE DIRECTORY SERVICE (DISC+1) EMT PONPOF MOV R1,BLOCK(R4) MOV #1000,R1 BR BUFFCOM; COMMON WITH GETBF1 ; ****************************************************************** ; SELECT INPUT ; ****************************************************************** SELECTINPUT: ; STACK CONTAINS RA AND PARAM MOV 2(SP),R0; PICK UP PARAM MOV R0,@#INSTRM ASL R0 MOV STRPTS(R0),R0; GET POINTER TO DESCRIPTOR MOV R0,@#X; AND SET UP THE POINTER BEQ INNULL; NULL STREAM ADD #OFFSET,@#X; INTO 'OFFSET' POSITION SIAGN: MOV (R0),@#RDSPSR; SET UP ROUTINE CALL RDSYX(R0) BEQ NOTSETUP; FIRST TIME THROUGH JUMP OUT MOV NEXYX(R0),@#NXYPSR; SET UP NEXTSYMBOL ENTRY POINT SIRET: MOV (SP)+,R3; GET RA TST (SP)+; POP PARAM MOV R3,PC; AND RETURN NOTSETUP: MOV R1,-(SP); SAVE R1?????? TST NEXYX(R0); ON FIRST ENTRY, NEXY CONTAINS TYPE:- ; TYPE = 0 - CHAR STREAM ; TYPE = 2 - FILE STREAM BEQ INCHAR BR INFILE INNULL: MOV #EOF2,@#RDSPSR MOV #NULLNS,@#NXYPSR ; WAS NULLRS - NOT DEFINED? BR SIRET; AND RETURN NULLNS: MOV #100004,R1 RTS PC INCHAR: ; SET UP STREAM FOR CHARACTER HANDLING MOV #READSYMBOL,(R0); ,RDSYX(R0) MOV #NEXTSYMBOL,NEXYX(R0) MOV #GETB1,GETBX(R0) INCH2: MOV #100000,OFFSET(R0); SET NEXTSYMBOL NOT PRESENT MOV (SP)+,R1; RESTORE R1 BR SIAGN; AND SET IT UP INFILE: ; SET UP STREAM FOR FILE HANDLING MOV R4,-(SP); SAVE R4 MOV R0,R4; STREAM DESC ->R4 MOV R4,R2 ADD #SER,R2; POINT R2 AT SERVICE/REPLY MOV (R2)+,R0; SERVICE/REPLY INC R0; BUT USE DIRECTORY HANDLER ; R2 POINTS TO NAME DESCRIPTOR (+UNIT ETC) CLR R1; SERVICE=EXAMINE EMT PONPOF MOV R1,BLOCK(R4); PLANT BLOCK NUMBER BEQ INEOF; NO FILE INE2: MOV R4,R0; PICK UP STREAM POINTER AGAIN MOV #READSYMBOL,(R4)+ MOV #NEXTSYMBOL,(R4)+ MOV #GETBF2,(R4) MOV (SP)+,R4; RESTORE USERS R4 BR INCH2; FINISH SETTING UP INEOF: CMPB @#ID, #LOADID BEQ INE2; ITS THE LOADER, SO LET IT THROUGH JMP EFAIL; OTHERWISE, FAIL IT ; ********************************************************************** ; OUTPUT ROUTINES ; ********************************************************************** PRINTSYMBOL:; STACK CONTAINS RA, CHAR ; CHARACTER VERSION! MOV @#Y,R0 MOV 2(SP),R1; PICK UP THE CHAR CMP R1,#100000; PROMPT CHAR? BEQ DOPUT1; YES, SO OUTPUT BUFFER MOVB R1,@0(R0); PLANT INDIRECT THROUGH POINTER INC (R0); AND STEP POINTER CMPB #12,R1; IS IT NL? BEQ DOPUT1; YES, SO OUTPUT BUFFER CMP MAX(R0),(R0); HAVE WE REACHED THE END OF THE BUFFER? BEQ DOPUT1; YES, SO OUTPUT BUFFER NULLPS: ; NULL PRINTSYMBOL - JUST RETURN PRET: MOV (SP)+,(SP); SHUFFLE PARAM DOWN RTS PC; AND RETURN DOPUT1: MOV #PRET,-(SP); DO A PSEUDO JSR PC,DOPUT; RTS PC DOPUT:; BUFFER OUTPUT ROUTINE FOR CHARACTER I/O MOV R4,-(SP); SAVE USERS R4 MOV R3, -(SP) MOV R2, -(SP) MOV R0,R4; AND GET POINTER MOV (R0), R3; R3 CONTAINS POINTER TO END SUB #OFFSET,R4; POINT BACK TO BEGINNING MOV SER(R4),R0; GET SERVICE NUMBER MOV R4,R2; CONSTRUCT POINTER TO BUFFER ADD #BUFFS,R2; BY ADDING BUFFER OFFSET SUB R2, R3; AND SUBTACT FROM END TO GIVE LENGTH MOV #1, R1; 1=WRITE EMT PONPOF; SEND IT ADD #BUFFS,R4; POINTS TO BUFFER MOV R4,-6(R4); AND POINT 'POINTER' TO IT PBR: MOV (SP)+, R2 MOV (SP)+, R3 MOV (SP)+, R4 RTS PC; AND RETURN ; ********************************************************************* ; FILE HANDLING PRINTSYMBOL AND PUT BUFFER ; ********************************************************************* DISCPS:; STACK CONTAINS RA, CHAR ; DISC VERSION MOV @#Y,R0; GET STREAM DESCRIPTOR MOV 2(SP),R1; CHAR MOVB R1,@0(R0); AND PLANT THROUGH POINTER INC (R0) CMP MAX(R0),(R0); END OF BUFFER? BNE PRET; NO, SO COMMON EXIT ; DISC PUT BUFFER ; WRITES OUT THE CURRENT BLOCK, THEN GETS ANOTHER BLOCK AND INITS IT MOV #PRET, -(SP); DO A PSEUDO JSR PC,DPUT; RTS PC DPUT: MOV R4, -(SP); SAVE USERS R4 MOV R3, -(SP) MOV R2, -(SP) MOV R0,R4 SUB #OFFSET,R4; POINT AT BEGINNING MOV BLOCK(R4), R3 MOV R4,R2 ADD #BUFFS,R2; CONSTRUCT BUFFER POINTER IN R2 MOV #1, R1; WRITE OPERATION MOV SER(R4),R0; SERVICE NUMBER EMT PONPOF TST R1; SUCCESS/FAIL FLAG BEQ DPS1; OK FAILX: JMP DFAIL; DISC FAILED DPS1: ; NOW FIND THE NEXT BLOCK MOV #4, R1; OPERATION=APPEND MOV BLOCK(R4),R3; LAST BLOCK NO MOV SER(R4),R0; SERVICE NO OF DISC INC R0; CHANGED TO DIRECTORY MOV R4, R2 ADD #UNIT, R2; CONSTRUCT PT TO FILE DESC EMT PONPOF JSR PC,DPSET; SET BUFFER UP ETC BR PBR DPSET: ; SET UP BLOCK MOV R1,BLOCK(R4); REMEMBER NEXT BLOCK BNE DPS2; OK CLR RDSYX(R4); ENSURE IT WONT TRY AGAIN MOV #DSCFUL, R0; SET R0 = 28 JMP DOSTOP; AND STOP TASKS DPS2: MOV #400,R0; SET 400 WORDS MOV R4, R3 ADD #OFFSET, R3 MOV R3,R2 ADD #6,R2; POINT AT BEGINNING OF BUFFER MOV R2,(R3); LEAVE PT SET UP CLLP: MOV #2004,(R2)+; PLANT EOF IN BUFFER DEC R0 BNE CLLP; AND LOOP TILL DONE MOV R2, MAX(R3); AND SET UP MAX RTS PC ; ****************************************************************** ; SELECT OUTPUT ; ****************************************************************** SELOUT: ; SELECT OUTPUT, STACK CONTAINS R.A. AND STREAM NO MOV 2(SP),R0; GET STREAM NO ADD #4,R0; INTO OUTPUT RANGE MOV R0,@#OUTSTR; INTO STREAM NO ASL R0; WORD INDEX MOV STRPTS(R0),R0; AND PICK UP DESCRIPTOR BEQ OTNULL; THE NULL STREAM MOV R0,R1; CONSTRUCT POINTER TO OFFSET IN R1 ADD #OFFSET,R1 MOV R1,@#Y; AND REMEMBER IN OUT POINTER SOAGN: MOV (R0),@#PRSPSR; AND PLANT IN PRINTSYMBOL POINTER BNE PRET; ALREADY SET UP, SO RETURN ; SO FIRST TIME THROUGH TST NEXYX(R0); STREAM TYPE BNE OTFILE; FILE TYPE ; CHAR TYPE MOV #PRINTS,(R0); SET UP PRINTSYMBOL ROUTINE POINTER MOV R0,(R1); CONSTRUCT POINTER TO START OF BUFFER IN 'PT' ADD #BUFFS,(R1) BR SOAGN; AND DUMP THE ADDRESS ; OUTPUT FILE TYPE OTFILE: MOV R4,-(SP); SAVE USER R4 MOV R0,R4; AND REMEMBER STREAM POINTER MOV #DISCPS,(R0); DUMP FILE PRINTSYMBOL BIS #200, NAME(R0); MAKE IT 'TEMP' MOV R0,R2; POINT TO SER/REPLY ADD #SER,R2 MOV (R2)+,R0; R2 NOW POINTS TO FILE NAME ETC INC R0; USE DIRECTORY SERVICE MOV #2,R1; DESTROY FILE EMT PONPOF SWAB R0; GET DIR SERVICE AGAIN MOV #3,R1; CREATE FILE EMT PONPOF ;R1 CONTAINS FIRST BLOCK NO JSR PC,DPSET; SET UP BLOCK, POINTERS ETC MOV R4,R0; RESTORE FILE DESC INTO R0 MOV (SP)+,R4; AND USERS R4 BR SOAGN; AND FINALISE SETTIN G UP ; NULL STREAM OTNULL: MOV #NULLPS,@#PRSPSR JMP PRET; AND RETURN ; *************************************************************** ; CLOSE ; *************************************************************** ; RA, PARAM ON STACK ; PARAM=0 => INPUT ; PARAM=4 => OUTPUT ; CLOSES CURRENT STREAM AND SELECTS ZERO CLSE: TST R0 BNE CLOUT; CLOSE OUTPUT ; OTHERWISE INPUT MOV @#X, R1; GET CURRENT DESCRIPTOR BEQ CLRET; NULL STREAM CLR RDSY(R1) CLR R0; ASSUME CHAR STREAM CMP GETB(R1), #GETBF2; IS IT? BNE CLSI1; YES, SO JUMP MOV #2, R0 CLSI1: MOV R0, NEXY(R1); STUFF TYPE CLRET: CLR -(SP); SELECT INPUT(0) JSR PC, SELECTINPUT RTS PC; AND RETURN TO USER CLOUT: ; CLOSE OUTPUT MOV @#Y, R0 MOV RDSY(R0), R1; IS IT INITIALISED? BEQ CLORET; NO, SO LEAVE ALONE CLR RDSY(R0) CMP #DISCPS, R1; IS IT A DISC STREAM? BEQ CLO2; YES, SO BRANCH JSR PC, DOPUT; DO A CHARACTER PUT BUFFER BR CLORET; AND RETURN CLO2: OFF2=OFFSET-SER MOV R4, -(SP); SAVE R4 MOV R0, R4 SUB #OFF2, R4 MOV (R4), R0; GET SER NUMBER MOV R4, R2; CONSTRUCT POINTER ADD #22, R2; BUFFS-SER MOV 12(R4), R3; BLOCK NUMBER MOV #1, R1; WRITE EMT PONPOF TST R1 BEQ CLO3; OK JMP DFAIL; OTHERWISE FAILED CLO3: MOV (R4)+,R0 INC R0 MOV R4, R2 MOV #6, R1; RENAME TEMP EMT PONPOF MOV (SP)+, R4; RESTORE R4 CLORET: CLR -(SP); SELECT OUTPUT(0) JSR PC, SELOUT RTS PC ; ********************************************************** ; STOP ; ********************************************************** DOSTOP: MOV R0, -(SP); SAVE STOP CODE ; CLOSE ALL THE OUTPUT STREAMS! MOV #6, R5 STRPT1=STRPTS+10; DO OUTPUT STREAMS ONLY DOST0: MOV STRPT1(R5), @#Y; SET UP STREAM BEQ DOST00; NULL STREAM ADD #OFFSET, @#Y MOV #4, R0; INDICATE OUTPUT STREAM JSR PC, CLSE; AND CLOSE IT DOST00: SUB #2,R5; NEXT STREAM DOWN BNE DOST0; NOT FINISHED MOV @#ID, R0; GET CALLER (AND ID) SWAB R0; AND GET READY TO SEND IT MOV #2, R1; SERVICE = STOPPING MOV (SP)+, R3; AND STOP CODE EMT PON CLR R0 EMT DELETE; AND DELETE THE TASK DEVTAB: ; THIS TABLE WILL HAVE TO BE CONSTRUCTED IN WORDS FROM EMAS 52124; .ASCII /TT/ 46120; .ASCII /PL/ 52062; .ASCII /2T/ 52063; .ASCII /3T/ (LETTERS ARE REVERSED) 0 ; TABLE TERMINATOR DEVIDS: ; DITTO TO LAST 6001; .BYTE TTID, LPID 12423; .BYTE T2ID, T3ID (19. AND 21.) 0 TYPE1: ; RDSY, NEXY, GETB, SER, REPLY - NOT PLANTED BY THIS ; 0; UNIT/FSYS 20040; SP, SP - NAME IS 6 CHARS 20040 20040 0; BLOCK NO 0; NEXTSYMBOL 0; PT ; MAX NOT ALLOWED FOR MONITOR=160012 EVENT=2 EVINF=4 ELIST=6 PROG=12 SIGNL1: MOV (SP), R0 MOV R4, -(SP) MOV R5, -(SP) SIG0: SUB PROG(R4), R0 CLR R2; CALCULATE TEXTUAL LEVEL MOV LNB, R3 TST (R3)+ CMP LNB, (R4) BEQ SIG2 SIG1: INC R2 CMP LNB, (R3)+ BNE SIG1 SIG2: MOV ELIST(R4), R1; EVENT LIST BEQ SIG5 SIG3: ADD PROG(R4), R1 CMP R0, (R1) BLOS SIG4; TOO EARLY CMP R0, 2(R1) BHI SIG4; TOO LATE CMP R2, 6(R1) BNE SIG4; WRONG LEVEL BIT 4(R1), 6(SP) BEQ SIG5; EVENT NOT TRAPPED MOV 6(SP), EVENT(R4) MOV 10(SP), EVINF(R4) JMP 12(R1); RE-ENTER PROGRAM SIG4: MOV 10(R1), R1 BNE SIG3 SIG5: TST R2; OUTERMOST LEVEL? BEQ SIG6; YES, GIVE UP MOV (LNB), LNB; PSEUDO RETURN MOV (LNB)+, R0; RETURN ADDRESS BIT -2(R0), #1; EXTERNAL? BEQ SIG0 MOV (R3), R4; YES, RECOVER GLA BR SIG0 SIG6: MOV (SP)+, LNB; RESTORE CONTENT MOV (SP)+, R4 MOV (SP)+, R2; FAILURE ADDRESS MOV (SP)+, R1; EVENT MOV (SP)+, R0; EXTRA INFO MOV @#MONITOR, PC; CALL MONITOR SPON: MOV 2(SP), R3 MOV (R3)+, R0 MOV (R3)+, R1 MOV (R3)+, R2 MOV (R3), R3 EMT 2; EMT PON SPONR: MOV (SP)+, (SP) RTS PC SPOFF: MOV @2(SP), R0 EMT 3 MOV R0, -(SP) MOV 4(SP), R0 MOV (SP)+, (R0)+ MOV R1, (R0)+ MOV R2, (R0)+ MOV R3, (R0) BR SPONR PONOFF: MOV R4, -(SP) MOV 4(SP), R4 MOV (R4)+, R0 MOV (R4)+, R1 MOV (R4)+, R2 MOV (R4), R3 EMT PONPOF; EMT PONPOFF SUB #6, R4 MOV R0, (R4)+ MOV R1, (R4)+ MOV R2, (R4)+ MOV R3, (R4) MOV (SP)+, R4 BR SPONR MAPVRT: MOV (SP)+, R3; RA MOV (SP)+, R2 MOV (SP)+, R1 MOV (SP)+, R0 EMT 12; EMT MAP VIRTUAL (10) MOV R3, PC GETABS: ; %INTEGER VAD, LEN, ID MOV (SP)+, R3; RA MOV (SP)+, R0; ID MOV (SP)+, R2; LEN (=0 => DROP) MOV (SP), R1; VAD ;072127; ASH R1, -13. - RIGHT ; 177763 ROL R1 ROL R1 ROL R1 ROL R1 BIC #177770, R1; CLEAR TOP BITS EMT 13; MAP ABS ; R0 = PAR, R1 = PDR CLRB R1 ASR R1 ASR R1; LEN IN WORDS ADD #100, R1 ADD (SP)+, R2; R2=LEN+VAD BIC #160000, R2; AS INDEX IN SEGMENT CMP R2, R1 BGT GETABX; OUT OF SEGMENT MOV R0, R1; RESULT (PAGES) MOV R3, PC; AND RETURN GETABX: CLR R1; FAILED MOV R3, PC; AND RETURN SGETID: EMT GETID MOV R0, R1 RTS PC STIME: ; %INTEGER TICKS MOV (SP)+, R3 MOV (SP)+, R0; TICKS EMT 10; EMT 8. MOV R3, PC SLINKN: ; %INTEGER SER MOV (SP)+, R3 MOV (SP)+, R0; SER EMT 15; EMT 13. MOV R3, PC SMAPHW: ; %INTEGER SEGS MOV (SP)+, R3 MOV (SP)+, R0; SEGS EMT 17; EMT 15. MOV R3, PC TIMEP: ; TICKS FROM IPL (OR SET UP) DATEP: ; DATE (IN THREE WORDS) .END