.TITLE PASLIB -- RUN-TIME SUPPORT .IDENT /780407/ .MCALL FDBDF$,FDAT$A,FDRC$A,FDOP$A,FDBF$A,OPEN$R,OPEN$W .MCALL GET$,PUT$,NMBLK$,FSRSZ$,QIOW$,DIR$,CLOSE$,DELET$ .MCALL FINIT$,EXIT$S,GTSK$S,GMCR$ ; ; PASCAL RUN-TIME SUPPORT ; FILE SUPPORT AND INITIALIZATION ; ; HEAP DEFINITION: ; .PSECT ......,RW,GBL,OVR ; HPSIZE=100 ;BARE BONES HEAP SIZE CURHP: .WORD 0 ;CURRENT HEAP POINTER .HEAP.::.WORD HPSIZE ;(NUMBER OF BYTES IN HEAP) .WORD 0 ;(TOP OF HEAP) .WORD 0 ;(PREVIOUS HEAP) .WORD HPSIZE-8. ;(CURRENT HEAP SIZE) .BLKW 100 ;DEFAULT HEAP AREA ; ; USAGE: IN TKB COMMAND FILE: ; ; EXTSCT=......:SIZE ; .PSECT PASPAS,RW,GBL,OVR PASPAS:: BSSBLK: .BLKW 1 ;START OF GLOBALS ; .PAGE ; .PSECT $$FILE ; ; PASCAL FILE BLOCK DEFINITION BUFVAR =0 EOF =2 FLAGS =3 IN =1 ;OPEN FOR IN FLAG OUT =2 ;OPEN FOR OUT FLAG ISTTY =4 ;FILE IS TTY FLAG MAXSIZ =4 FDBPNT =6 VALID =8. BUFFER =10. BUFSIZ =512. FILSIZ =BUFFER+BUFSIZ ; ; ;LAYOUT OF GLOBALS: OUTPUT=2 INPUT=OUTPUT+FILSIZ ; .PAGE .SBTTL $$$000 - INIT ; INIT - INITIALIZE HEAP AND USERS CONSOLE ; PARMS ; REGISTER USAGE ; R0 -> HEAP, SCRATCH ; R1 - SCRATCH ; R2 - SCRATCH ; R3 -> (OUT,IN) FILE BLOCKS ; R4 - SCRATCH ; R5 - SCRATCH ; CALLS: P$FINT ; $$$000:: ; MAKE DUMMY STACK FRAME MOV (SP)+,R4 ;POP RETURN ADDRESS INTO R4 DIR$ #GMCR ;GET MCR COMMAND LINE MOV @#$DSW,R0 ;SIZE OF COMMAND LINE OR ERROR BLT 100$ ;NO COMMAND LINE ENTERED MOV #GMCR+G.MCRB,R1 ;START OF MCR COMMAND BUFFER MOV SP,R2 ;CURRENT STACK POINTER SUB #32.,R2 ;FIRST POINTER LOCATION CLR R3 ;COUNT OF ARGUMENTS MOV R1,(R2)+ ;POINTER TO MCR TASK NAME INC R3 10$: CMP R2,SP ;DONE?? BEQ 50$ ;FINISH UP 15$: CMPB (R1)+,#40 ;LOOK FOR A BLANK BEQ 20$ ;GOT IT DEC R0 ;DECREMENT CHARACTER COUNT BNE 15$ ;KEEP LOOKING MOVB #0,(R1) ;NULL STRING 16$: CMP R2,SP ;DONE?? BEQ 50$ ;FINISH UP MOV R1,(R2)+ ;ADDRESS OF NULL STRING BR 16$ ;FILL UNTIL DONE 20$: MOVB #0,-1(R1) ;TERMINATE STRING DEC R0 ;DECREMENT CHARACTER COUNT 21$: CMPB (R1),#40 ;SKIP BLANKS BNE 22$ MOVB #0,(R1) DEC R0 BEQ 16$ ;MAKE REST OF ARGUEMENTS NULL INC R1 BR 21$ 22$: MOV R1,(R2)+ ;STORE STRING START ADDRESS INC R3 ;COUNT OF STRINGS BR 10$ 50$: SUB #32.,SP ;NEW STACK TOP MOV R3,-(SP) ;NUMBER OF ARGUEMENTS (ARGC) MOV SP,R3 ;POINTER TO NUMBER OF ARGUEMENTS MOV R3,-(SP) ;PUT IT IN THE STACK FRAME SUB #32.,R2 ;FIRST STRING POINTER MOV R2,-(SP) ;(ARGV)@ BR 110$ 100$: CLR -(SP) ;NO ARGUEMENTS CLR -(SP) ;NO POINTERS TO ARGUEMENTS 110$: CLR -(SP) ;BUILD DUMMY STACK FRAME CLR -(SP) ; CLR -(SP) ; MOV SP,R5 ;LEVEL ZERO STACK FRAME FINIT$ ;INITIALIZE RSX-11D FILE SYSTEM ; INITIALIZE HEAP MOV #.HEAP.,R1 ;LOCATION OF HEAP GTSK$S R1 ;GET TASK PARAMTERS MOV G.TSTS(R1),R2 ;TASK SIZE IN BYTES SUB #2,R2 SUB #.HEAP.,R2 ;SIZE OF THE HEAP MOV R1,CURHP ;CURRENT HEAP POINTER MOV R2,(R1)+ ;NUMBER OF BYTES IN THE HEAP MOV R1,(R1) ;(TOP OF HEAP) ADD #6,(R1)+ ;... CLR (R1)+ ;(PREVIOUS HEAP) SUB #8.,R2 MOV R2,(R1)+ ;CURRENT SIZE OF THE HEAP MOV #64,R2 60$: CLR (R1)+ SOB R2,60$ ;ZERO OUT HEAP ; INITIALIZE CONSOLE OUTPUT MOV #BSSBLK+OUTPUT,R3 ;R3 -> OUTPUT FILE BLOCK MOV R3,(R3) ADD #BUFFER,(R3)+ ;BUFFER VARIABLE POINTER MOV #*256.+1,(R3)+ ;EOF=TRUE, FLAGS=OUT+ISTTY MOV #1,(R3)+ ;MAXSIZE=1 BYTE MOV #5,(R3)+ ;LOGICAL UNIT TO USE CLR (R3) ;CLEAR FIRST BUFFER VARIABLE ; INITIALIZE CONSOLE INPUT MOV #BSSBLK+INPUT,R3 ;R3 -> INPUT FILE BLOCK MOV R3,(R3) ADD #BUFFER,(R3)+ ;BUFFER VARIABLE POINTER MOV #*256.,(R3)+ ;EOF=FALSE, FLAGS=IN+ISTTY MOV #1,(R3)+ ;MAXSIZE=1 BYTE MOV #5,(R3)+ ;LOGICAL UNIT TO USE CLR (R3) ;CLEAR FIRST BUFFER VARIABLE ; RETURN JMP (R4) .PAGE .SBTTL $$$001 - EXIT ; EXIT - RETURN TO MONITOR ; PARMS ; R5 -> GLOBALS ; REGISTER USAGE ; R0,R1,R2,R3,R4 - NOT USED ; $$$001:: MOV #BSSBLK+OUTPUT,R0 JSR PC,P$FBRK ;FLUSH STANDARD OUTPUT ; EXIT TO MONITOR EXIT$S .PAGE .SBTTL $$$004 - NEW ; GET A BLOCK FROM THE HEAP ; PARMS ; 1. POINTER TO CURRENT HEAP ; 2. SIZE REQUESTED (IN BYTES, WILL BE ROUNDED UP TO MULTIPLE OF FOUR) ; REGISTER USAGE ; R0 = SIZE ; R1 -> CURRENT HEAP ; R2,R3,R4 - NOT USED ; $$$004:: MOV 2(SP),R0 ;PARAMETER = SIZE INC R0 ;ROUND UP SIZE TO BIC #1,R0 ;...TO A MULTIPLE OF TWO BLE 5$ ;VALID REQUEST? MOV CURHP,R1 ;CURRENT HEAP BEQ 5$ ;ERROR, NO HEAP HEADER CMP R0,6(R1) ;++P01 CHECK CURRENT SIZE BHI 5$ ;++P01 NOT ENOUGH ROOM SUB R0,6(R1) ;++P01 ADJUST CURRENT SIZE MOV 2(R1),2(SP) ;RETURN POINTER ADD R0,2(R1) ;ADJUST POINTER TO TOP OF HEAP RTS PC ; 5$: CLR 2(SP) ;RETURN NIL POINTER JUST IN CASE MOV #10,-(SP) ;PASCAL NEW - HEAP OVERFLOW JSR PC,P$HERR RTS PC .PAGE .SBTTL $$$006 - MARK ; MARK THE HEAP ; PARMS ; 1. POINTER TO POINTER TO CURRENT HEAP ; REGISTER USAGE ; R0 - SCRATCH ; R1 -> CURRENT HEAP POINTER ; R2 -> NEW HEAP ; R3 - SCRATCH ; R4 - NOT USED ; $$$006:: MOV R2,-(SP) MOV R3,-(SP) MOV #CURHP,R1 ;CURRENT HEAP POINTER MOV (R1),R3 ;R3->HEAP HEADER BEQ 5$ ;ERROR, NO HEAP MOV 6(R3),R0 ;CURRENT SIZE CMP R0,#8. BLT 5$ ;NOT ENOUGH ROOM MOV 2(R3),R2 ;R2->TOP OF HEAP MOV R2,R3 MOV R0,(R3)+ ;INITIALIZE HEAP HEADER WITH SIZE, MOV R2,(R3) ADD #8.,(R3)+ ;...POINTER TO TOP OF HEAP, MOV (R1),(R3)+ ;...LINK TO OLD HEAP MOV R0,(R3) SUB #8.,(R3) ;...AND CURRENT SIZE MOV R2,(R1) ;UPDATE CURRENT HEAP POINTER BR 6$ ; 5$: MOV #11,-(SP) ;PASCAL MARK - HEAP OVERFLOW JSR PC,P$HERR 6$: MOV (SP)+,R3 MOV (SP)+,R2 RTS PC .PAGE .SBTTL $$$007 - RELEASE ; CUT BACK HEAP TO LAST MARK ; PARMS ; 1. POINTER TO POINTER TO CURRENT HEAP ; REGISTER USAGE ; R0 -> CURRENT HEAP POINTER ; R1 -> CURRENT/DISCARDED HEAP HEADER ; R2,R3,R4 - NOT USED ; $$$007:: MOV #CURHP,R0 ;CURRENT HEAP POINTER MOV (R0),R1 ;R1->CURRENT HEAP HEADER BEQ 5$ ;ERROR, NO CURRENT HEAP MOV 4(R1),(R0) ;PREVIOUS HEAP BECOMES CURRENT HEAP BEQ 5$ ;ERROR, NO PREVIOUS HEAP RTS PC ; 5$: MOV #12,-(SP) ;PASCAL RELEASE - NO PREVIOUS HEAP JSR PC,P$HERR RTS PC .PAGE .SBTTL $$$016 - FILE BLOCK INIT ; FILE BLOCK INITIALIZATION ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. MAXIMUM SIZE OF BUFFER VARIABLE (BYTES) ; REGISTER USAGE ; R0 = SCRATCH ; R1 -> FILE VARIABLE $$$016:: MOV 4(SP),R1 ;GET FIRST PARM MOV (SP)+,2(SP) ;MOVE DOWN RETURN ADDRESS ; MOV R1,R0 MOV R1,(R0) ADD #BUFFER,(R0)+ ;@BUFVAR MOV #1,(R0)+ ;EOF=TRUE MOV (SP)+,(R0)+ ;BUFVAR SIZE CLR (R0)+ ;FDBPNT CLR (R0)+ ;VALID CLR (R0) ;CLEAR FIRST WORD IN BUFFER RTS PC .PAGE .SBTTL $$$017 - OPEN_A_FILE ; PARMS: ; 1. POINTER TO PASCAL FILE BLOCK ; 2. POINTER TO ASCII STRING CONTAINING FILE NAME ; 3. FILE ATTRIBUTES ; 4. MODE 0=READ, 1=WRITE, 2=UPDATE ; ; REGISTER USAGE ; R0 -> FILE BLOCK ; R1 - SCRATCH ; R2,R3,R4 - SCRATCH (SAVED AND RESTORED) ; MODES: .WORD IN,OUT,OUT ; $$$017:: MOV 10(SP),R0 ;GET FIRST PARM MOV (SP)+,6(SP) ;MOVE DOWN RETURN ADDRESS MOV (SP)+,R1 ;GET FOURTH PARM ASL R1 MOV MODES(R1),R1 ;INPUT/OUTPUT MODE MOV (SP)+,FATTR ;GET THIRD PARAMETER MOV R3,-(SP) MOV 2(SP),R3 ;GET SECOND PARM MOV R2,2(SP) P$FOPN: ; TSTB FLAGS(R0) ;ALREADY OPENED? BEQ 2$ JSR PC,P$FCLO ;YES, CLOSE IT. ; 2$: MOVB R1,FLAGS(R0) ;NEW FILE DIRECTION CLR FDSBK ;ZERO DEVICE STRING LENGTH, CLR FDSBK+4 ;DIRECTORY STRING LENGTH, CLR FDSBK+10 ;AND FILENAME LENGTH MOV R3,R1 ;START OF FILE STRING B0: CMPB (R3),#': BNE L0 MOV R1,FDSBK+2 ;POINTER TO START OF STRING MOV R3,R2 SUB R1,R2 INC R2 MOV R2,FDSBK ;LENGTH OF DEVICE STRING MOV R3,R1 INC R1 ;START OF NEXT STRING BR L1 L0: CMPB (R3),#'] BNE L2 MOV R1,FDSBK+6 ;POINTER TO START OF STRING MOV R3,R2 SUB R1,R2 INC R2 MOV R2,FDSBK+4 ;LENGTH OF DIRECTORY STRING MOV R3,R1 INC R1 ;START OF NEXT STRING BR L3 L2: TSTB 1(R3) BNE L4 MOV R1,FDSBK+12 ;POINTER TO START OF STRING MOV R3,R2 SUB R1,R2 INC R2 MOV R2,FDSBK+10 ;LENGTH OF FILENAME STRING L4: L3: L1: INC R3 TSTB (R3) BNE B0 TST FDBPNT(R0) BNE L6 MOV #FDBPTR,R3 B1: TST -(R3) BEQ L7 CMP R3,#FDBUSE BNE B1 L7: TST (R3) BNE L11 INC (R3) ADD #FDBPTR-FDBUSE,R3 MOV (R3),R3 MOV R3,FDBPNT(R0) BR L12 L11: MOV #1,-(SP) CALL P$HERR ;PASCAL RESET/REWRITE - NO FDB SPACE BR EXT017 L12: L6: MOV FDBPNT(R0),R3 MOV (R0),F.URBD+2(R3) ;PASCAL BUFFER ADDRESS BITB #IN,FLAGS(R0) BNE 106$ MOVB FATTR,F.RATT(R3);SET USER DEFINED RECORD ATTRIBUTES MOV R0,-(SP) OPEN$W R3 MOV (SP)+,R0 BCC EXT017 CLRB EOF(R0) 111$: BICB #IN!OUT,FLAGS(R0) MOV #2,-(SP) JSR PC,P$HERR ;PASCAL RESET - FILE NOT FOUND ;PASCAL REWRITE - UNABLE TO OPEN FILE BR EXT017 106$: MOV R0,-(SP) OPEN$R R3 MOV (SP)+,R0 BCC 107$ MOVB #1,EOF(R0) BR 111$ 107$: CLRB EOF(R0) ;YES, FALSE => EOF BITB #ISTTY,FLAGS(R0);IS IT A TERMINAL? BNE EXT017 JSR PC,P$FFST ;NO, GET FIRST BUFFERFULL EXT017: MOV (SP)+,R3 MOV (SP)+,R2 RTS PC ; .PAGE .SBTTL $$$020 - CLOSE ; PARMS: ; 1. FILE BLOCK ; REGISTER USAGE ; R2,R3,R4 - NOT USED ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: P$FBRK ; $$$020:: MOV 2(SP),R0 MOV (SP)+,(SP) ; P$FCLO: TSTB FLAGS(R0) ;WAS FILE OPEN? BEQ 1$ ;IF NOT, SKIP ALL OF THIS JSR PC,P$FBRK ;YES, DUMP FINAL BUFFER(IF OUTPUT) ; BITB #ISTTY,FLAGS(R0);IS IT A TTY?? BNE 1$ ;YES, SKIP CLOSING MOV R0,-(SP) MOV FDBPNT(R0),R0 CLOSE$ R0 MOV (SP)+,R0 ; 1$: RTS PC .PAGE .SBTTL $$$021 - GET ; PARMS ; 1. FILE BLOCK ; 2. SIZE OF LAST BUFFER VARIABLE ; REGISTER USAGE ; R0 -> FILE BLOCK ; R1 -> START OF LEFTOVERS IN BUFFER ; R2,R3 - SCRATCH ; R4 - NOT USED ; CALLS: P$FNXT ; $$$021:: MOV 4(SP),R0 MOV (SP)+,2(SP) MOV (SP)+,R1 MOV R2,-(SP) MOV R3,-(SP) ; TSTB EOF(R0) ;PASCAL EOF SET BNE ERR001 ;IT MUST NOT BE ADD R1,(R0) ;BUMP BUFFER VARIABLE POINTER SUB R1,VALID(R0) ;REDUCE SIZE OF REMAINING DATA CMP VALID(R0),MAXSIZ(R0) ;IS THERE ENOUGH DATA FOR THIS BGE 1$ ;...BUFFER VARIABLE MOV (R0),R2 ;R2 -> LEFTOVERS (IF ANY) MOV R0,R1 ADD #BUFFER,R1 ;R1 -> START OF BUFFER MOV R1,(R0) ;NEW BUFFER VARIABLE POINTER MOV VALID(R0),R3 ;NO, GET SIZE OF LEFTOVERS IN R3 BGT 3$ CLR R3 ;JUST IN CASE BR 2$ ;SKIP THE MOVE ; MOVE LEFTOVER DATA TO THE FRONT OF THE BUFFER 3$: MOVB (R2)+,(R1)+ SOB R3,3$ MOV VALID(R0),R3 ;RESTORE SIZE OF LEFTOVERS ; 2$: JSR PC,P$FNXT ;GET NEXT BUFFERFULL 1$: BR EXT021 ;...AND RETURN ; ; ERR001: MOV #3,-(SP) ;PASCAL GET - EOF ON GET JSR PC,P$HERR EXT021: MOV (SP)+,R3 MOV (SP)+,R2 RTS PC .PAGE ; SUBROUTINE TO GET (FIRST) NEXT BUFFERFULL ; EXPECTS ; R3 = SIZE OF LEFTOVERS ; R0 -> FILE BLOCK ; REGISTER USAGE ; R3 = SIZE OF LEFTOVERS, SCRATCH ; R1,R2 - SCRATCH ; R0 -> FILE BLOCK ; R4 - NOT USED ; P$FFST: CLR R3 ;FIRST BUFFER, NO LEFTOVERS P$FNXT: BITB #IN,FLAGS(R0) ;OPENED FOR INPUT? BEQ GES01 ;IF NOT, SKIP ALL OF THIS BITB #ISTTY,FLAGS(R0);TERMINAL???? BNE GESTRM MOV (R0),R1 ;GET POINTER TO START OF BUFFER ADD R3,R1 ;INCREASE BY LEFTOVERS MOV R3,-(SP) ;SAVE SIZE OF LEFTOVERS MOV #BUFSIZ,R2 SUB R3,R2 ;REDUCE BY SIZE OF LEFTOVERS MOV FDBPNT(R0),R3 GES: MOV R0,-(SP) GET$ R3,R1,R2 ;GET NEXT RECORD MOV (SP)+,R0 BCS GES3 ;GET ERROR CHECK FOR END OF FILE MOV F.NRBD(R3),VALID(R0) ;NUMBER OF BYTES IN THE RECORD BEQ GES ;ZERO LENGTH RECORD, REPEAT GET BITB #FD.CR,F.RATT(R3) ;IS IT A TEXT FILE? BEQ GES0 ;NO, TREAT AS BINARY ADD VALID(R0),R1 ;POINT TO END OF BUFFER MOVB #12,(R1)+ ;INSERT LINE FEED TO INDICATE ENDOFLINE INC VALID(R0) GES0: MOV (SP)+,R3 ;RESTORE SIZE OF LETOVERS ADD VALID(R0),R3 ;ADD NR OF BYTES JUST READ TO LEFTOVERS GES00:: MOV R3,VALID(R0) ;UPDATE VALID BGT GES01 ;IF ANY VALID DATA THEN SKIP THE NEXT GES2: MOVB #1,EOF(R0) ;SET PASCAL EOF TO TRUE GES01: RTS PC ; GES3: CMPB #IE.EOF,F.ERR(R3) ;END OF FILE BNE ERR001 CLR VALID(R0) ;NO VALID DATA BR GES0 ; GESTRM: MOV #IO.RVB,$$QIOW+Q.IOFN MOVB FDBPNT(R0),$$QIOW+Q.IOLU MOV (R0),$$QIOW+Q.IOPL MOV MAXSIZ(R0),$$QIOW+Q.IOPL+2 DIR$ #$$QIOW CMP #IE.EOF,IOST BEQ GES2 CMP #IS.CR,IOST ;CARRIAGE RETURN WAS THE TERMINATOR BEQ GES4 MOV IOST+2,VALID(R0) BR GES5 GES4: MOVB #15,(R0) ;PUT CARRIAGE RETURN IN THE BUFFER MOV #1,VALID(R0) ;ONE CHARACTER TRANSFERRED GES5: RTS PC ; $$QIOW: QIOW$ IO.RVB,1,32.,50.,IOST,, IOST: .WORD 0,0 .PAGE .SBTTL $$$022 - PUT ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. SIZE OF BUFFER VARIABLE TO PUT ; REGISTER USE ; R1 = SIZE OF BUFFER VARIABLE ; R2,R3 - NOT USED ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: P$FBRK ; $$$022:: MOV 4(SP),R0 MOV (SP)+,2(SP) MOV (SP)+,R1 ; P$FPUT: TSTB EOF(R0) ;YES, IS EOF SET? BEQ ERR002 MOV R1,-(SP) ;SAVE R1 BITB #ISTTY,FLAGS(R0);TERMINAL? BNE 2$ ;YES, DO NOT PROCESS MOV FDBPNT(R0),R1 ;FDB POINTER BITB #FD.CR,F.RATT(R1);IS THIS A TEXT FILE? BEQ 2$ ;NO, TREAT AS BINARY CMPB #12,@(R0) ;IS THIS CHARACTER A LINE FEED? BNE 2$ ;NO, DON'T NEED A BREAK JSR PC,P$FBRK ;FLUSH THE BUFFER MOV (SP)+,R1 ;POP OFF UNUSED PARAMETER BR 1$ ;RETURN 2$: MOV (SP)+,R1 ;SIZE OF BUFFER VARIABLE ADD R1,(R0) ;BUMP BUFFER VARIABLE POINTER ADD VALID(R0),R1 ;R1=NEW SIZE OF VALID DATA MOV R1,VALID(R0) ;UPDATE VALID ADD MAXSIZ(R0),R1 ;CHECK TO SEE IF THERE IS ROOM CMP R1,#BUFSIZ ;...ENOUGH FOR NEXT BUFFER VARIABLE BLE 1$ JSR PC,P$FBRK ;NOT ENOUGH ROOM, FLUSH THE BUFFER ; 1$: RTS PC ; ; ERR002: MOV #4,-(SP) ;PASCAL PUT - NO EOF ON PUT JSR PC,P$HERR RTS PC .PAGE .SBTTL $$$023 - BREAK ; PARMS ; 1. POINTER TO FILE BLOCK ; REGISTER USE ; R1,R2 - NOT USED ; R0 -> FILE BLOCK ; R4 - NOT USED ; $$$023:: MOV 2(SP),R0 MOV (SP)+,(SP) ; P$FBRK: BITB #OUT,FLAGS(R0) ;OPENED FOR OUTPUT? BEQ 1$ TST VALID(R0) ;ANY VALID DATA BLE 1$ BITB #ISTTY,FLAGS(R0);TERMINAL? BNE 2$ MOV R0,-(SP) MOV R1,-(SP) MOV FDBPNT(R0),R1 MOV VALID(R0),F.NRBD(R1) MOV R0,R1 ADD #BUFFER,R1 PUT$ FDBPNT(R0),R1 MOV (SP)+,R1 MOV (SP)+,R0 3$: MOV R0,(R0) ;RE-INITIALIZE BUFFER VARIABLE POINTER ADD #BUFFER,(R0) CLR VALID(R0) ;...AND COUNT ; 1$: RTS PC ; 2$: MOV #IO.WVB,$$QIOW+Q.IOFN MOVB FDBPNT(R0),$$QIOW+Q.IOLU MOV R0,-(SP) ADD #BUFFER,(SP) MOV (SP)+,$$QIOW+Q.IOPL MOV VALID(R0),$$QIOW+Q.IOPL+2 DIR$ #$$QIOW BR 3$ .PAGE .SBTTL $$$024 - READ CHARACTER ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. POINTER TO CHARACTER ; REGISTER USAGE ; R3 - SIZE OF BUFFER VARIABLE ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: $$$021 ; $$$024:: MOV 4(SP),R0 MOV (SP)+,2(SP) ; P$FRDC: BITB #ISTTY,FLAGS(R0);TERMINAL? BNE 1$ ; MOVB @(R0),@(SP)+ ;NO, MOVE THEN GET MOV R0,-(SP) MOV #1,-(SP) JSR PC,$$$021 BR 2$ ; 1$: MOV R0,-(SP) MOV #1,-(SP) JSR PC,$$$021 ;YES, GET THEN MOVE MOVB @(R0),@(SP)+ ; 2$: RTS PC .PAGE .SBTTL $$$025 - WRITE CHARACTER ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. CHARACTER ; 3. WIDTH OF FIELD ; REGISTER USAGE ; R2 - BUFFER VARIABLE SIZE ; R1 - HOLDS PAD CHAR TO P$FPAD ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: P$FPUT,P$FPAD ; RASH ASSUMPTION: P$FPUT DOES NOT DISTURB R2,R3 ; $$$025:: MOV 6(SP),R0 MOV (SP)+,4(SP) ; P$FWRC: CMPB 2(SP),#12 ;IS CHAR A LINE FEED? BNE 1$ ; BITB #ISTTY,FLAGS(R0);IS THIS A TERMINAL?? BEQ 1$ ;NO, SKIP CR PROCESSING MOVB #15,@(R0) ;YES, SYSTEM LIKES TO SEE A MOV #1,R1 ;...CR BEFORE EVERY LF JSR PC,P$FPUT ; 1$: MOVB 2(SP),@(R0) ;MOVE THE CHAR INTO THE BUFFER MOV #1,R1 ;AND PUT JSR PC,P$FPUT ; MOV (SP)+,R1 ;FIELD WIDTH MOV R2,(SP) ;SAVE R2 OVER CHARACTER ALREADY OUTPUT MOV #' ,R2 ; PAD CHAR IS BLANK DEC R1 ;WIDTH - 1 IS NR OF PADS JSR PC,P$FPAD MOV (SP)+,R2 ; RTS PC .PAGE .SBTTL $$$027 - WRITE STRING ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. POINTER TO STRING ; 3. LENGTH OF STRING ; 4. WIDTH OF FIELD ; REGISTER USAGE ; R3 - SIZE OF BUFFER VARIABLE ; R2 - HOLDS PAD CHAR TO P$FPAD ; R1 - SCRATCH ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: P$FPUT,P$FPAD ; RASH ASSUMPTION: P$FPUT DOES NOT DISTURB R2,R3 ; $$$027:: MOV 8.(SP),R0 MOV (SP)+,6(SP) ; TST (SP) ;WIDTH > 0? BGT 1$ ; MOV 2(SP),(SP) ;NO, MAKE IT SAME AS LENGTH 1$: SUB 2(SP),(SP) ;WIDTH NOW IS NR OF BLANKS FOR PADDING BGE 4$ ADD (SP),2(SP) ;LENGTH IS NOW FIELD WIDTH 4$: MOV 2(SP),R1 ;GET LENGTH BLT 2$ ;IF LENGTH <= 0, SKIP STRING OUTPUT ; MOV R3,-(SP) MOV R1,R3 3$: MOVB @6(SP),@(R0) ;MOVE A CHAR INC 6(SP) ;BUMP POINTER MOV #1,R1 ;AND PUT JSR PC,P$FPUT SOB R3,3$ MOV (SP)+,R3 ; 2$: MOV (SP)+,R1 ;GET WIDTH OF PAD CMP (SP)+,(SP)+ ;DISCARD LENGTH AND POINTER TO STRING MOV R2,-(SP) MOV #' ,R2 ; PAD CHAR IS BLANK JSR PC,P$FPAD ;OUTPUT TRAILING BLANKS (IF ANY) MOV (SP)+,R2 ; RTS PC .PAGE ; P$FPAD - PUTS OUT PAD CHARACTERS ; EXPECTS ; R2 = PAD CHARACTER ; R1 = CHARACTER COUNT ; R0 -> FILE BLOCK ; REGISTER USAGE ; R1 - BUFFER VARIABLE SIZE ; R2 - CHARACTER FOR PAD ; R3 - COUNTER ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: P$FPUT ; RASH ASSUMPTION: P$FPUT DOES NOT DISTURB R1, R2 ; P$FPAD: TST R1 BLE 1$ ; MOV R3,-(SP) MOV R1,R3 2$: MOVB R2,@(R0) MOV #1,R1 JSR PC,P$FPUT SOB R3,2$ MOV (SP)+,R3 ; 1$: RTS PC .PAGE .SBTTL $$$029 - WRITE BOOLEAN(@FILEVAR,BOOLEAN,FIELD WIDTH) ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. BOOLEAN VALUE ; 3 FIELD WIDTH ; REGISTERS ; ; CALLS: $$$027 (MODIFIES STACK AND FAKES A CALL) $$$029:: MOV (SP),-(SP) ;JACK UP RETURN ADDRESS MOV 4(SP),2(SP) ;MOVE UP FIELD WIDTH MOV #5,4(SP) ;STRING LENGTH 5 TST 6(SP) ;CHECK WHICH STRING BEQ 1$ ; TO PRINT MOV #TSTR,6(SP) ; "TRUE" BR 2$ 1$: MOV #FSTR,6(SP) ; "FALSE" 2$: JMP $$$027 ;PRINT THE STRING TSTR: .ASCII /TRUE / FSTR: .ASCII /FALSE/ .PAGE .SBTTL $$$030 - READ INTEGER ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. POINTER TO INTEGER VARIABLE ; REGISTERS ; R3 - SCRATCH ; R1 - SCRATCH ; R2 - SCRATCH, VALUE OF CONVERTED INTEGER ; R0 -> FILE BLOCK ; R4 -> SCRATCH ; CALLS: $$$021, P$TCAI $$$030:: MOV 4(SP),R0 ; UNPACK PARMS--GET -> FILE BLOCK MOV (SP)+,2(SP) ; SAVE RETURN ADDR. MOV (SP)+,R1 ; POINTER TO RESULT MOV R2,-(SP) MOV R3,-(SP) MOV R1,-(SP) ;POINTER BACK ON TOP OF STACK 1$: CMPB #' ,@(R0) ; IGNORE CONTROL CHARS & SPACES BLT 2$ MOV R0,-(SP) MOV #1,-(SP) JSR PC,$$$021 BR 1$ 2$: MOV #1,R3 CMPB #'+,@(R0) ; CHECK FOR SIGN BNE 4$ MOV R0,-(SP) MOV #1,-(SP) JSR PC,$$$021 ; BUMP PAST '+' 3$: JSR PC,P$TCAI ; CONVERT FOLLOWING INTEGER BR 5$ 4$: CMPB #'-,@(R0) BNE 3$ ; NO SIGN--JUST CONVERT MOV R0,-(SP) MOV #1,-(SP) JSR PC,$$$021 ; BUMP PAST '-' JSR PC,P$TCAI ; CONVERT NEG R2 ; NEGATE 5$: MOV R2,@(SP)+ ; STORE RESULT, POP STACK MOV (SP)+,R3 MOV (SP)+,R2 RTS PC ; GO HOME .PAGE ;P$TCAI - CONVERT ASCII TO INTEGER ; EXPECTS ; R0 -> FILE BLOCK ; REGISTER USAGE ; R3 - SCRATCH ; R1 - SCRATCH ; R2 - FINAL VALUE RETURNED ; R0 -> FILE BLOCK ; R4 - SCRATCH ; CALLS: $$$021 P$TCAI: MOV R4,-(SP) ; SAVE R4 CLR -(SP) ; TEMP FOR CONVERTED VALUE 1$: MOVB @(R0),R4 ; NEXT (FIRST) DIGIT SUB #'0,R4 BLT 2$ ; QUIT ON NON-DIGIT CMP #9.,R4 BLT 2$ ; MUST BE IN RANGE 0..9 MOV (SP)+,R1 MUL #10.,R1 ; SINGLE PRECISION MULT. ADD R4,R1 ; ADD IN LAST DIGIT MOV R1,-(SP) ; HOLD INTERMEDIATE RESULT MOV R0,-(SP) MOV #1,-(SP) ; # BYTES... JSR PC,$$$021 ; ...TO GET BR 1$ ; GET NEXT DIGIT ; 2$: MOV (SP)+,R2 ; POP RETURN VALUE MOV (SP)+,R4 ; RESTORE R4 RTS PC ; AND GO HOME .PAGE .SBTTL $$$031 - WRITE INTEGER ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. INTEGER TO BE OUTPUT ; 3. WIDTH OF FIELD ; REGISTER USAGE ; R1 - INPUT VALUE ; R3 - WIDTH, PAD CHAR TO P$FPAD ; R2 -> CONVERTED STRING ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: P$FPAD, P$TCIA, P$FPUT ; $$$031:: MOV 6(SP),R0 ; UNPACK STACK FRAME; -> FILE BLOCK MOV (SP)+,4(SP) ; RETURN ADDRESS MOV R2,-(SP) MOV R3,-(SP) MOV SP,R1 ;R1 -> LOCAL WORK SPACE SUB #6,SP ;SIZE OF WORKSPACE = 6 BYTES MOV 12.(SP),R2 ;R2 = VALUE TO BE PRINTED BGE 1$ NEG R2 ;GET ABSOLUTE VALUE 1$: MOV R2,R3 ;PREPARE FOR DIVIDE CLR R2 DIV #10.,R2 ;DIVIDE VALUE BY 10 ADD #'0,R3 ;MAKE ASCII DIGIT OF REMAINDER MOVB R3,-(R1) ;STORE IT IN WORKSPACE TST R2 ;IS ANYTHING LEFT BNE 1$ ;YES, LOOP ON TST 12.(SP) ;WAS ORINGINAL VALUE <0 BGE 2$ MOVB #'-,-(R1) ;YES, MOVE IN A MINUS SIGN 2$: MOV 10.(SP),R3 ;GET FIELD LENGTH MOV SP,R2 ;COMPUTE LENGTH OF STRING BUILT ADD #6,R2 SUB R1,R2 ;R2 = LENGTH OF STRING MOV R1,-(SP) ;SAVE POINTER TO STRING MOV R2,-(SP) ;SAVE LENGTH OF STRING SUB R2,R3 ;COMPUTE PADDING NEEDED BLE 3$ ;BRANCH IF NONE NEEDED MOVB #40,R2 MOV R3,R1 JSR PC,P$FPAD ;OUTPUT PAD CHARACTERS 3$: MOV (SP)+,R3 ;RESTORE LENGTH OF STRING TO R3 MOV (SP)+,R2 ;RESTORE ADDRESS OF STRING TO R2 4$: MOVB (R2)+,@(R0) ;PUT OUT STRING MOV #1,R1 JSR PC,P$FPUT SOB R3,4$ 5$: ADD #6,SP ;DELETE WORKSPACE MOV (SP)+,R3 MOV (SP)+,R2 CMP (SP)+,(SP)+ ;POP OFF REMAINING PARAMTERS RTS PC .PAGE .SBTTL $$$039 - WRITE OCTAL ; PARMS ; 1. POINTER TO FILE BLOCK ; 2. INTEGER TO BE OUTPUT ; 3. WIDTH OF FIELD (>= 6) ; REGISTER USAGE ; R3 - SCRATCH ; R2 - PAD CHARACTER, VALUE TO CONVERT ; R1 - PAD COUNT, LOOP COUNT ; R0 -> FILE BLOCK ; R4 - NOT USED ; CALLS: P$FPAD, P$FPUT ; $$$039:: MOV 6(SP),R0 ; UNPACK STACK FRAME; -> FILE BLOCK MOV (SP)+,4(SP) ; RETURN ADDRESS MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV 6(SP),R1 ; WIDTH OF FIELD BLE 2$ SUB #6,R1 BGT 1$ ; PAD WITH BLANKS BEQ 2$ ; NO PADDING MOV #'*,R2 ; PAD WITH *'S NEG R1 JSR PC,P$FPAD BR 3$ 1$: MOV #' ,R2 JSR PC,P$FPAD ; OUTPUT BLANKS 2$: MOV #6,R4 MOV 8.(SP),R3 ; INTEGER VALUE CLR R2 ASHC #1,R2 ; 1ST DIGIT IS ONE BIT 4$: ADD #'0,R2 ; CONVERT TO DIGIT MOVB R2,@(R0) MOV #1,R1 ; UPDATE ONE BYTE JSR PC,P$FPUT CLR R2 ASHC #3,R2 ; NEXT DIGIT SOB R4,4$ 3$: MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 CMP (SP)+,(SP)+ RTS PC .PAGE .SBTTL P$HERR - ERROR OUTPUT ; ; ERROR OUTPUT ; ; ERROR SUMMARY: ; ; 1 - RESET/REWRITE - NO FDB SPACE ; 2 - RESET - FILE NOT FOUND ; 3 - GET - EOF ON INPUT ; 4 - PUT - NO EOF ON OUTPUT ; 10 - NEW - HEAP OVERFLOW ; 11 - MARK - HEAP OVERFLOW ; 12 - RELEASE - NO PREVIOUS HEAP ; P$HERR: MOV 2(SP),R1 ;ERROR CODE MOV (SP)+,(SP) ;PUSH DOWN RETURN ADDRESS MOV #ASCBUF,R0 ;ADDRESS FOR ASCII STRING MOV R2,-(SP) CLR R2 CALL $CBDMG ;CONVERT TO ASCII MOV (SP)+,R2 SUB #MASK,R0 ;STRING LENGTH MOV R0,$$QIOW+Q.IOPL+2 MOV #MASK,$$QIOW+Q.IOPL MOV #5,$$QIOW+Q.IOLU MOV #IO.WVB,$$QIOW+Q.IOFN DIR$ #$$QIOW RTS PC ; ; MASK: .ASCII <15><12>/PASCAL RUN-TIME ERROR NUMBER: / ASCBUF: .ASCII / / MASKL=.-MASK .EVEN ; .PAGE .SBTTL FILES11 INTERFACE DATA ; ; ; RSX-11D INTERFACE DATA AREAS ; GMCR: GMCR$ ; ; FDBUSE AND FDBPTR MUST ALWAYS APPEAR IN ORDER FDBUSE: .WORD 0,0,0,0,0 ;FDB USAGE INDICATORS FDBPTR: .WORD FDB001,FDB002,FDB003,FDB004,FDB006 FDB001: FDBDF$ FDAT$A R.VAR FDRC$A ,FCBREC,1 FDOP$A 1,FDSBK,FCBDFB,FO.WRT FDBF$A 32.,,1 FDB002: FDBDF$ FDAT$A R.VAR FDRC$A ,FCBREC,1 FDOP$A 2,FDSBK,FCBDFB,FO.WRT FDBF$A 32.,,1 FDB003: FDBDF$ FDAT$A R.VAR FDRC$A ,FCBREC,1 FDOP$A 3,FDSBK,FCBDFB,FO.WRT FDBF$A 32.,,1 FDB004: FDBDF$ FDAT$A R.VAR FDRC$A ,FCBREC,1 FDOP$A 4,FDSBK,FCBDFB,FO.WRT FDBF$A 32.,,1 FDB006: FDBDF$ FDAT$A R.VAR FDRC$A ,FCBREC,1 FDOP$A 6,FDSBK,FCBDFB,FO.WRT FDBF$A 32.,,1 FCBREC: .WORD 0 FATTR: .WORD 0 FCBDFB: NMBLK$ PASCAL,TMP,,SY,0 FDSBK: .WORD 0,0 .WORD 0,0 .WORD 0,0 ; FSRSZ$ 5 .END