.TITLE CSETU .IDENT /X01/ ; ; PDP-11 C RUNTIME ; SETU ; ; VERSION X01 ; ; DAVID G. CONROY 26-OCT-77 ; .GLOBL EXIT .GLOBL $GETC .GLOBL $PUTC .GLOBL $PROF .GLOBL STDIN .GLOBL STDOUT .GLOBL EOF .GLOBL NL .MCALL GMCR$, EXIT$S, QIOW$, NMBLK$ .MCALL FDBDF$, FDOP$A, FDAT$A, CSI$ .MCALL CALL, RETURN, CSI$1, CSI$2 .MCALL CLOSE$, OPEN$A, OPEN$W, OPEN$R .MCALL DIR$, GET$S, PUT$S, FSRSZ$ CSI$ FSRSZ$ 3 ; EQUIVALENCES EOF = -1 NL = 12 MAXARG = 20. ;SIZE OF ARGV CMDLNG = 80. ;SIZE OF BUFFER IN GMCR$ BUFLNG = 80. ;SIZE OF BUFFERS TILUN = 1 ;TI: LUN SILUN = 2 ;STANDARD INPUT LUN SOLUN = 3 ;STANDARD OUTPUT LUN ALT = 33 ;ASCII ALTMODE CR = 15 ;ASCII RETURN BL = 40 ;ASCII BLANK ; GLOBAL DATA $PROF: .WORD RTS ;POINTS AT AN RTS PC ARGC: .WORD 0 ;ARGUMENT COUNT. ARGV: .BLKW MAXARG ;ARGUMENT VECTOR. STDIN: FDBDF$ ;STANDARD INPUT FDB FDOP$A SILUN,CSIBK+C.DSDS,DFNB STDOUT: FDBDF$ ;STANDARD OUTPUT FDB FDAT$A R.VAR,FD.CR FDOP$A SOLUN,CSIBK+C.DSDS,DFNB DFNB: NMBLK$ ,,,SY ;DEFAULT NAME BLOCK CSIBK: .BLKB C.SIZE ;CSI WORK BLOCK .EVEN ; LOCAL DATA AFLAG: .WORD 0 ;APPEND FLAG INFILE: .WORD TI ;STANDARD INPUT FILENAME OTFILE: .WORD TI ;STANDARD OUTPUT FILENAME IOSTAT: .BLKW 2 ;I/O STATUS RETURN ; DIRECTIVE BLOCKS GMCR: GMCR$ ;GET MCR COMMAND LINE OUT: QIOW$ IO.WLB,TILUN,1,,,,<0,0,BL> TP: QIOW$ IO.WLB,TILUN,1,,,, TR: QIOW$ IO.RLB,TILUN,1,,IOSTAT,, ; STUFF FOR PUTCHA AND GETCHA PPTR: .WORD PBUF ;PUTCHAR POINTER GPTR: .BLKW 1 ;GETCHAR POINTER GCNT: .WORD 0 ;GETCHAR COUNT PBUF: .BLKB BUFLNG ;PUTCHAR BUFFER GBUF: .BLKB BUFLNG+1 ;GETCHAR BUFFER ; ASCII THINGS TI: .ASCIZ "TI:" ;DEFAULT STDIN AND STDOUT PROMPT: .ASCIZ "GMCR:" ;GET COMMAND LINE MSG02: .ASCIZ "SYNTAX ERROR" MSG03: .ASCIZ ": NOT FOUND" MSG04: .ASCIZ ": CANNOT CREATE" .EVEN ;+ ; ** SETU - ENTRY FROM RSX ; ; THIS ROUTINE CHOPS UP THE COMMAND LINE, OPENS THE STANDARD FILES ; AND CALLS THE PROGRAM AT 'MAIN' WITH ARGC AND ARGV ;- SETU: DIR$ #GMCR ;GET MCR COMMAND LINE BCC 20$ ;OK 10$: DIR$ #TP ;PROMPT FOR THE LINE DIR$ #TR ;READ IT BACK CMP IOSTAT,#IS.CR ;WAS THE STATUS OK BNE 10$ ;NO, LOOP MOV IOSTAT+2,R0 ;PUT THE NEWLINE MOVB #CR,GMCR+G.MCRB(R0) ;ON THE END 20$: MOV #GMCR+G.MCRB,R0 ;GET POINTER TO COMMAND LINE CALL CHOP ;CHOP IT UP BCC 30$ ;IF THERE IS AN ERROR MOV #MSG02,R0 ;ITS BR 100$ ;FATAL 30$: MOV INFILE,R0 ;OPEN STANDARD INPUT CALL MDSPT BCS 40$ ;BAD FILE NAME OPEN$R #STDIN BCC 50$ 40$: MOV #MSG03,R0 ;CANNOT OPEN FILE MOV INFILE,R1 BR 90$ 50$: MOV OTFILE,R0 ;OPEN STANDARD OUTPUT CALL MDSPT BCS 70$ ;BAD FILE NAME TST AFLAG ;IS IT OPEN FOR APPEND ">>" BEQ 60$ ;BR IF NOT OPEN$A #STDOUT BCC 80$ CMPB F.ERR(R0),#IE.NSF ;IF THE FILE IS NONEXISTANT BNE 70$ ;APPEND IS JUST WRITE 60$: OPEN$W #STDOUT BCC 80$ 70$: MOV #MSG04,R0 ;CANNOT CREATE MOV OTFILE,R1 BR 90$ 80$: MOV #ARGV,-(SP) ;CALL USER'S MAIN MOV ARGC,-(SP) CALL MAIN CMP (SP)+,(SP)+ BR EXIT ;THEN GO AWAY 90$: CALL FMSG ;FILE ERROR BR EXIT 100$: CALL MSG ;OTHER ERROR ;+ ; ** EXIT - EXIT ROUTINE ; ; THIS ROUTINE IS THE NORMAL TERMINATION OF A C PROGRAMME ; IT IS EITHER JUMPED TO BY THE SETU (IF MAIN RETURNS) OR IT ; MAY BE CALLED BY THE USER VIA EXIT(); ;- EXIT: CALL @$PROF ;DO PROFILE CALL CLOSE$ #STDIN ;CLOSE STANDARD INPUT CLOSE$ #STDOUT ;CLOSE STANDARD OUTPUT EXIT$S ;EXIT ;+ ; ** FMSG -- WRITE MESSAGE FOR FILE ACCESSES, ETC. ; ; INPUTS: ; R0=POINTER TO ASCIZ MESSAGE ; R1=POINTER TO ASCIZ FILE NAME ;- FMSG: MOV R0,-(SP) ;SAVE MESSAGE TEXT MOV R1,R0 ;FILE NAME MOV #'$,OUT+Q.IOPL+4;CHANGE SLEW TO 'PROMPT' AND CALL MSG ;PUT OUT FILE NAME MOV (SP)+,R0 ;GET MESSAGE MOV #'+,OUT+Q.IOPL+4;PUT IN OVERPRINT SLEW CALL MSG ;PUT OUT MESSAGE (AND A NEWLINE) MOV #BL,OUT+Q.IOPL+4;PUT BACK NORMAL SLEW RTS: RETURN ;+ ; ** MSG -- WRITE MESSAGE ; ; INPUTS: ; R0=POINTER TO ASCIZ MESSAGE ;- MSG: MOV R0,OUT+Q.IOPL ;BUFFER ADDRESS 10$: TSTB (R0)+ ;COMPUTE LENGTH BNE 10$ ;OF DEC R0 ;THE SUB OUT+Q.IOPL,R0 ;MESSAGE MOV R0,OUT+Q.IOPL+2 ;SAVE IN THE QIOW$ DIR$ #OUT ;FIRE IT OFF, AND MOV OUT+Q.IOPL,R0 ;RECOVER ORIGINAL R0 RETURN ;RETURN ;+ ; CHOP -- CHOP UP COMMAND LINE ; ; INPUTS: ; R0=POINTER TO STRING ; ; OUTPUTS: ; ARGC, ARGV, INFILE, OTFILE, AFLAG SET UP ; R0=JUNK ; R1=JUNK ; R2=JUNK ; R3=JUNK ;- CHOP: MOV #ARGV,R1 ;R1 IS OUTPUT WORKING POINTER 10$: CLR R3 ;NEW FIELD, CLEAR QUOTE FLAG 15$: MOVB (R0)+,R2 ;SKIP OVER LEADING BLANKS CMPB R2,#BL BEQ 15$ CMPB R2,#CR ;STOP SCAN ON RETURN BEQ 120$ CMPB R2,#ALT ;OR ALTMODE BEQ 120$ CMPB R2,#'' ;QUOTED ARGUMENT? BEQ 20$ ;YES CMPB R2,#'" ;BOTH KINDS WORK BNE 30$ ;NOT QUOTED ARGUMENT 20$: MOV R2,R3 ;SAVE DELIMITER CMP R1,#ARGV+<2*MAXARG> ;WILL ANOTHER FIT? BHIS 110$ ;NO MOV R0,(R1)+ ;YES, SAVE POINTER INC ARGC ;COUNT UP AN ARGUMENT BR 70$ ;GO COLLECT 30$: CMPB R2,#'< ;REDIRECT STANDARD INPUT? BNE 40$ ;NO MOV R0,INFILE ;YES, SAVE POINTER TO STRING BR 70$ ;GO COLLECT NAME 40$: CMPB R2,#'> ;REDIRECT STANDARD OUTPUT BNE 60$ ;BR IF NOT CMPB (R0),R2 ;IS IT ">>" FOR APPEND? BNE 50$ ;NO INC R0 ;YES, SKIP THE SECOND ">" INC AFLAG ;SET APPENDING FLAG 50$: MOV R0,OTFILE ;SAVE THE FILE NAME AND BR 70$ ;GO COLLECT THE FIELD 60$: CMP R1,#ARGV+<2*MAXARG> ;WILL ANOTHER ARGUMENT FIT? BHIS 110$ ;BR IF NOT MOV R0,(R1) ;SAVE DEC (R1)+ ;POINTER AND INC ARGC ;COUNT UP AN ARGUMENT 70$: MOVB (R0)+,R2 ;COLLECT A FIELD CMPB R2,#CR ;STOP ON RETURN BEQ 90$ CMPB R2,#ALT ;AND ALTMODE BEQ 90$ TST R3 ;QUOTED ARGUMENT? BNE 80$ ;BR IF YES CMPB R2,#BL ;IF NOT QUOTED, STOP ON BLANK BEQ 90$ BR 70$ ;KEEP COLLECTING 80$: CMP R2,R3 ;IS IT THE RIGHT KIND OF QUOTE BNE 70$ ;NO, KEEP COLLECTING 90$: CLRB -1(R0) ;MAKE ARGUMENT ASCIZ CMPB R2,#CR ;QUIT ON CR FIELD BEQ 100$ CMPB R2,#ALT ;OR ALTMODE FIELD BNE 10$ 100$: TST R3 ;STILL IN A QUOTED FIELD BEQ 120$ ;NO, OK 110$: SEC ;YES, ERROR RETURN ;RETURN TO CALLER 120$: CLC ;GOOD RETURN RETURN ;TO CALLER ;+ ; ** MDSPT -- MAKE A DSPT IN THE CSI BLOCK ; ; INPUTS: ; R0=POINTER TO ASCIZ NAME ;- MDSPT: MOV R0,CSIBK+C.CMLD+2 ;POINTER 10$: TSTB (R0)+ ;GET LENGTH BNE 10$ DEC R0 SUB CSIBK+C.CMLD+2,R0 MOV R0,CSIBK+C.CMLD;PUT IN THE CSI BLOCK CSI$1 #CSIBK ;SYNTAX CHECK BCS 20$ ;ERROR CSI$2 ,OUTPUT ;MAKE NAME 20$: RETURN ;DONE ;+ ; ** PUTCHA - PUT A CHARACTER ONTO THE STANDARD OUTPUT ; ; C CALLABLE ;- $PUTC: CMPB R0,#NL ;NEWLINE BEQ 10$ MOVB R0,@PPTR ;PUT IN BUFFER INC PPTR BR 20$ ;RETURN CHARACTER 10$: SUB #PBUF,PPTR ;COMPUTE BUFFER LENGTH PUT$S #STDOUT,#PBUF,PPTR MOV #PBUF,PPTR ;WIND BACK POINTER MOVB #12,R0 ;RETURN NEWLINE 20$: RETURN ;+ ; ** GETCHA - GET CHARACTER FROM STANDARD INPUT ; ; C CALLABLE ; RETURNS -1 ON EOF OR ERROR ;- $GETC: DEC GCNT ;IS THERE ANY STUFF BPL 20$ ;YES GET$S #STDIN,#GBUF,#BUFLNG BCC 10$ ;GOT CHARACTERS MOV #EOF,R0 BR 30$ 10$: MOV F.NRBD(R0),R0 ;PUT NL ON THE END MOVB #12,GBUF(R0) MOV R0,GCNT MOV #GBUF,GPTR 20$: MOVB @GPTR,R0 INC GPTR 30$: RETURN .END SETU