.TITLE TIOEIO E COMMANDS, ETC. .SBTTL E COMMANDS, ETC. ; LAST EDIT ON 13-MAR-80 BY MARK BRAMHALL .IDENT /V36/ .MCALL .CLOSE, .CSISPC,.DSTAT, .ENTER, .GTIM, .LOOKUP,.PURGE, .RENAME ;+ ; TIME - GET TIME. ; ; CALL TIME ; ; R0 = TIME (SECONDS PAST MIDNIGHT /2) ;- ORG TECOIO TIME:: SAVREG ;SAVE ALL REGISTERS MOV #CSIBUF,R1 ;POINT TO A RESULT BUCKET (3 WORDS USED) CLR (R1)+ ;HIGHEST WORD IS ALWAYS ZERO .GTIM #AREA,R1 ;FETCH THE TIME MOV #TIMDIV,R2 ;POINT TO THE HERTZ DIVISORS CLR R0 ;START TIME (MINUTES PAST MIDNIGHT /2) AT ZERO MOV #32767./2+1,R3 ;SET INITIAL RESULT BUMPER (REALLY 65536./4) BR 20$ ; AND ENTER DIVISION LOOP 10$: ;CLC ;C=0 FROM 'BCC' BELOW ROR R4 ;DIVIDE DIVISOR BY 2 BCC 30$ ;NO CARRY OUT, KEEP USING THIS DIVISOR TST (R1)+ ;ELSE SHIFT TO LOW ORDER WORD MOV #512.,R3 ; AND START A NEW RESULT BUMPER 20$: MOV (R2)+,R4 ;GET THE NEXT DIVISOR 30$: ADD R3,R0 ;ADD TO RESULTANT TIME SUB R4,(R1) ; AND DO A TRIAL SUBTRACTION SBC -2(R1) ; DOUBLE WORD STYLE BHIS 30$ ;KEEP GOING... ADD R4,(R1) ;UNDERFLOW, CORRECT DIVIDEND ADC -2(R1) ; DOUBLE WORD STYLE SUB R3,R0 ;CORRECT RESULT ALSO ASR R3 ;DIVIDE RESULT BUMPER BY 2 BCC 10$ ;STILL BUMPING, KEEP GOING... MOV R0,R0OFF(SP) ;ELSE MOVE FINAL RESULT TO SAVED R0 RETURN ; AND EXIT .SBTTL PROCESS A NON-NULL FILE SPECIFICATION .ENABL LSB 10$: CMPB -(R0),#SPACE ;IS CHARACTER A JUNK CHARACTER? BLOS 20$ ;YES, IGNORE IT... CMPB (R0),#', ;PERFORM CHEAP SYNTAX CHECK BEQ 70$ ;BRANCH IF IMBEDDED COMMA IN STRING CMPB (R0),#'= ;ALSO CHECK FOR A=A OR A= OR =A BEQ 70$ ;BRANCH IF IMBEDDED EQUAL SIGN CMPB (R0)+,#'< ;LASTLY ALTERNATE EQUALS BEQ 70$ ;BRANCH IF ERROR NONNUL: CMP R0,#CSIBUF+CSISIZ-1 ;IS STRING TOO LONG? BHIS 70$ ;BRANCH IF TOO LONG 20$: MOVB (R4)+,(R0) ;ELSE MOVE A CHARACTER BICB #^C<177>,(R0)+ ; AND TRIM IT UP BNE 10$ ;NOT THE END TSTB (R1) ;IS THIS THE NULL FILENAME? BEQ 70$ ;ERROR IF SO CALL 90$ ;IS IT "EI" OR "ER"? BEQ 50$ ;YES CLRB (R0) ;KEEP STRING .ASCIZ MOVB #'=,-(R0) ; THEN SET "=" FOR A= OR A=A TST R2 ;IS IT "EB"? BGT 50$ ;NO, IT'S "EW" MOV R1,R4 ;YES, IT'S "EB", GET POINTER TO FILENAME 30$: INC R0 ;ADVANCE THE STORE LOCATION CMP R0,#CSIBUF+CSISIZ ;IS STRING TOO LONG? BHIS 70$ ;BRANCH IF TOO LONG MOVB (R4)+,(R0) ;ELSE (RE-)MOVE A STRING BYTE CMPB (R0),#'= ;ARE WE DONE (MOVED THE "=")? BEQ 40$ ;YES CMPB (R0),#'[ ;SHOUD WE QUIT EARLY (LENGTH SPECIFIED)? BNE 30$ ;NOPE, LOOP... 40$: CLRB (R0) ;TERMINATE THE A=A FORMAT 50$: MOV #DEFNUL,R0 ;GUESS AT NOT "EI" (NO DEFAULTS) CMP R2,#'I-'R ;GOOD GUESS? BNE 60$ ;YES MOV #DEFTEC,R0 ;NO, IT'S "EI" (DEFAULT TO '.TEC') 60$: .CSISPC R1,R0,R1 ;DO THE CSI CALL BCS 70$ ;ERROR IN NAME TST (SP)+ ;NO SWITCHES ARE VALID! BEQ 80$ ;IT'S O.K. 70$: ERR IFN,<"Illegal file name"> 80$: ADD #10,R1 ;GO TO END OF OUTPUT FILE SPECIFICATION MOV #DOOPEN,-(SP) ; AND SET A RETURN ADDRESS 90$: TST R2 ;IS IT "ER"? BEQ 100$ ;YES, EXIT Z=1 CMP R2,#'I-'R ;NO, IS IT "EI"? 100$: RETURN ;EXIT Z=1 FOR BOTH "EI" AND "ER" .DSABL LSB .SBTTL OPEN FILES (EB, EI, ER, EW), SWITCH INPUT/OUTPUT ;+ ; OPEN - OPEN FILES. ; ; R2 = 'B-'R FOR "EB" ; 'I-'R FOR "EI" ; 'R-'R FOR "ER" ; 'W-'R FOR "EW" ; ; CALL OPEN ;- .ENABL LSB OPEN:: SAVREG ;SAVE ALL REGISTERS MOV #CSIBUF,R0 ;POINT TO STRING DESTINATION MOV R0,R1 ; AND MAKE A COPY MOV FILBUF(R5),R4 ;GET POINTER TO FILENAME BUFFER TSTB (R4) ;IS IT THE NULL FILENAME? BNE NONNUL ;NON-NULL, MUST BE A REAL OPEN MOV #INPNOR+SZ,R3 ;GUESS AT SWITCH TO NORMAL INPUT TST R2 ;WHAT KIND OF SWITCH IS IT? BEQ 10$ ;NORMAL INPUT SWITCH (ER$) BGT 20$ ;NORMAL OUTPUT SWITCH (EW$) CMP R2,#'I-'R ;WHAT IS IT REALLY? BNE NONNUL ;NOT INDIRECT... CALLRX INDCL0 ;CLOSE OF INDIRECT COMMAND FILE (EI$) ;+ ; INPSAV - SWITCH TO SECONDARY INPUT. ; ; CALL INPSAV ;- INPSAV::SAVREG ;SAVE ALL REGISTERS MOV #INPALT+SZ,R3 ;WE'RE SWITCHING TO SECONDARY INPUT 10$: ADD R5,R3 ;MAKE POINTTER ABSOLUTE MOV R3,INPNTR(R5) ;DO THE INPUT SWITCH CLR EOFLAG(R5) ;SAY NOT AT END-OF-FILE BR SETNAM ;GO SET NAME, ETC. ;+ ; OUTSAV - SWITCH TO SECONDARY OUTPUT. ; ; CALL OUTSAV ;- OUTSAV::SAVREG ;SAVE ALL REGISTERS MOV #OUPALT+SZ,R3 ;WE'RE SWITCHING TO SECONDARY OUTPUT BR 30$ ;SO GO DO IT 20$: MOV #OUPNOR+SZ,R3 ;WE'RE SWITCHING TO NORMAL OUTPUT 30$: ADD R5,R3 ;MAKE POINTTER ABSOLUTE MOV R3,OUPNTR(R5) ;DO THE OUTPUT SWITCH .CALLR SETNAM ;GO SET NAME, ETC. & EXIT .DSABL LSB .SBTTL SET FILE NAME ;+ ; SETNAM - SET FILENAME, ETC. ; ; R3 -> I/O PARAMETER BLOCK @ SZ ; ; CALL SETNAM ; ; R0 = UNDEFINED ; R1 = UNDEFINED ; R4 = UNDEFINED ;- .ENABL LSB SETNAM: MOV FILBUF(R5),R4 ;GET FILENAME BUFFER POINTER TST (R3) ;IS THE FILE OPEN(SZ<>0)? BEQ 20$ ;NOPE ADD #FN-SZ,R3 ;YEP, INDEX TO DEV:FILANM.TYP MOV (R3)+,R0 ;GET DEVICE NAME BEQ 10$ ;NONE CALL 40$ ;ONE, OUTPUT IT MOVB #':,(R4)+ ; THEN A ":" 10$: CALL 30$ ;OUTPUT FILENAME MOV (R3)+,R0 ;GET FILE TYPE BEQ 20$ ;NONE MOVB #'.,(R4)+ ;ONE, OUTPUT A "." CALL 40$ ; THEN THE FILE TYPE 20$: CLRB (R4) ;END FILE NAME WITH A NULL RETURN ; AND EXIT 30$: MOV PC,-(SP) ;DO THE BELOW TWICE MOV (R3)+,R0 ;GET A RAD50 WORD 40$: CALL 50$,R3,50*50 ;DO THE FIRST CHARACTER CALL 50$,R3,50 ;DO THE SECOND CHARACTER CALL 50$,R3,1 ;DO THE THIRD CHARACTER RETURN ;EXIT 50$: CLR R1 ;CLEAR A RESULT BUCKET 60$: INC R1 ;INCREMENT THE RESULT SUB (R3),R0 ; AND DO A TRIAL SUBTRACTION BHIS 60$ ;KEEP GOING... ADD (R3)+,R0 ;ELSE CORRECT FOR THE UNDERFLOW DEC R1 ; AND CORRECT THE RESULT BEQ 80$ ;ZERO, DO NOTHING ADD #'A-1,R1 ;GUESS AT ALPHABETIC (1-32) CMP R1,#'Z ;GOOD GUESS? BLOS 70$ ;YES ADD #'0-36-<'A-1>,R1 ;NO, NUMERIC (36-47) (33, 34, 35 ARE UNUSED) 70$: MOVB R1,(R4)+ ;OUTPUT THE CHARACTER 80$: RETURN R3 ;EXIT .DSABL LSB .SBTTL DO THE REAL OPENING .ENABL LSB 10$: CALL SETNAM ;SET THE NAME OF THE OPEN OUTPUT FILE ERR OFO,<"Output file already open"> DOOPEN: BNE 20$ ;IT'S "EB" OR "EW" TST R2 ;IT'S "EI" OR "ER", BUT WHICH IS IT? BEQ 30$ ;IT'S REALLY "ER" CLR INDIR(R5) ;IT'S "EI", CLEAR ACTIVE INDIRECT INDICATION MOV #CMDPRM+SZ,R3 ;GET THE I/O PARAMETER BLOCK POINTER ADD R5,R3 ; AND MAKE IT ABSOLUTE BR 40$ ; THEN GO OPEN IT 20$: MOV OUPNTR(R5),R3 ;IT'S "EB" OR "EW", GET OUTPUT FILE POINTER TST (R3) ;IS AN OUTPUT FILE ALREADY OPEN? BNE 10$ ;YES, THAT'S AN ERROR TST R2 ;IS IT "EB"? BGT 50$ ;NOPE, IT'S "EW" 30$: MOV INPNTR(R5),R3 ;GET INPUT FILE POINTER CLR EOFLAG(R5) ;NOT AT END-OF-FILE YET 40$: ADD #3*5*2,R1 ;SHIFT TO INPUT FILE SPECIFICATION LOCATION CALL OPNSET ; THEN SET UP FOR AN OPEN .LOOKUP #AREA,CH-FN(R3),R1 ;TRY TO FIND THAT FILE BCS OPNERR ;SOME ERROR CALL OPNDNE ;FINISH UP OPEN, ALLOCATE BUFFER, SET FILENAME CMP R2,#'I-'R ;WHAT KIND OF OPEN WAS THIS? BEQ 70$ ;IT'S "EI" BGT 80$ ;IT'S "ER" MOV #CSIBUF+10,R1 ;IT'S "EB", SET CORRECT FILE SPECIFICATION PTR 50$: MOV OUPNTR(R5),R3 ;GET OUTPUT FILE I/O PARAMETER BLOCK POINTER CALL OPNSET ; THEN SET UP FOR AN OPEN TST R2 ;IS IT "EW"? BLE 100$ ;IT'S "EB" TST AREA ;IT'S "EW", NON-FILE STRUCTURED? BPL 110$ ;YEP, NO SUPERSEDE CHECK CMP 6(R1),(PC)+ ;IS IT A TEMPORARY FILE? .RAD50 /TMP/ BEQ 110$ ;YEP, NO SUPERSEDE CHECK .LOOKUP #AREA,CH-FN(R3),R1 ;DOES THE FILE EXIST? BCS 60$ ;NOPE MOV #90$,-(SP) ;YEP, TELL THE USER WHEN WE'RE ALL DONE 60$: .PURGE CH-FN(R3) ;ENSURE CHANNEL IS PURGED AGAIN BR 110$ ; AND GO DO THE FILE ENTER 70$: TST (R3)+ ;INDIRECT'S WANT POINTER TO "CC" .ASSUME CC EQ SZ+2 MOV R3,INDIR(R5) ;SET THE OPEN INDIRECT INDICATION 80$: RETURN ;EXIT 90$: CALLX NOCCO ;WE'VE STARTED A SUPERSEDE, TELL THE USER PRINTS <"%Superseding existing file"> 100$: BISB #DOEB,FG-FN(R3) ;SET THE "EB" FLAG FOR "EB" 110$: .ENTER #AREA,CH-FN(R3),R1,CSIBUF+10 ;DO THE FILE ENTER W/LENGTH BCS CREERR ;SOME ERROR .CALLR OPNDNE ;FINISH UP OPEN, ALLOCATE BUFFER, SET FILENAME .DSABL LSB .SBTTL FINISH UP AN OPEN, ALLOCATE AN I/O BUFFER, SET FILENAME ;+ ; OPNDNE - FINISH UP AN OPEN, ALLOCATE AN I/O BUFFER, SET FILENAME. ; ; R0 = (MAXIMUM) FILE SIZE OR 0 IF NON-FILE STRUCTURED ; R3 -> I/O PARAMETER BLOCK @ FN ; ; CALL OPNDNE ; ; R0 = UNDEFINED ; R1 = UNDEFINED ; R3 -> I/O PARAMETER BLOCK @ SZ ; R4 = UNDEFINED ;- .ENABL LSB OPNDNE: ADD #SZ-FN,R3 ;RE-INDEX TO SZ IN I/O PARAMETER BLOCK MOV R0,(R3) ; AND STORE THE (MAXIMUM) FILE SIZE BNE 10$ ;NON-ZERO SIZE SPECIFIED COM (R3) ;ELSE DEFAULT TO 65535. 10$: MOV QZ(R5),R1 ;GET Q-REGS IN USE ADD #512.,R1 ; AND ADD IN AN I/O BUFFER SIZE CALLX SIZEQR ;ASK FOR THE MEMORY BCC 20$ ;FAILED... SUB #512.,QMAX(R5) ;GOT IT, TAKE IT AWAY ALREADY MOV QRSTOR(R5),R0 ;GET START OF Q-REGS ADD QMAX(R5),R0 ; AND FIND IT'S END ADD CURFRE(R5),R0 ; THEN END OF TECO'S SPACE MOV R0,RP-SZ(R3) ;SET THAT AS THE I/O BUFFER ADDRESS CALL SETNAM ;GO SET THE FILENAME, ETC. RTSPC: RETURN ;EXIT 20$: MOV #$E$MEM,-(SP) ;SET RETURN FOR "MEMORY OVERFLOW" ERROR BR PURGE ;GO PURGE AWAY THE FILE & EXIT .DSABL LSB .SBTTL LOOKUP/ENTER ERROR HANDLING ;+ ; OPNERR - A .LOOKUP FAILED. ; ; JMP OPNERR ;- .ENABL LSB OPNERR: CMPB @#ERRBYT,#-3 ;IS IT REALLY FILE NOT FOUND? BEQ DIOERR ;NOPE, DIRECTORY I/O ERROR 10$: ERR FNF,<"File not found"> ;+ ; CRERRR - A .ENTER FAILED. ; ; R2 < 0 => "EB" ; > 0 => "EW" ; ; JMP CREERR ;- CREERR: TST R2 ;IS THE FAILURE FROM "EW"? BLE 20$ ;NOPE, IT'S FROM "EB", ALWAYS A REAL ERROR TST NFLG(R5) ;FROM "EW", WILL WE BE RETURNING A VALUE? BMI 10$ ;YES, ALWAYS SAY "FNF" (WILL RETURN A 0) 20$: CMPB @#ERRBYT,#-3 ;WHAT KIND OF ERROR ON ENTER? BEQ DIOERR ;DIRECTORY I/O ERROR ERR NRO,<"No room for output"> .DSABL LSB .SBTTL KILL OUTPUT FILE ;+ ; KILFIL - KILL CURRENT OUTPUT FILE. ; ; CALL KILFIL ;- KILFIL::SAVREG ;SAVE ALL REGISTERS MOV OUPNTR(R5),R3 ;GET OUTPUT FILE POINTER TST (R3) ;ANYTHING THERE(SZ<>0)? BEQ RTSPC ;NOPE .CALLR PURGE ;YEP, GO PURGE THE CHANNEL & EXIT ;+ ; PURGE - PURGE A CHANNEL. ; ; R3 -> I/O PARAMETER BLOCK @ SZ ; ; CALL PURGE ; ; R0 = UNDEFINED ; R4 = UNDEFINED ;- PURGE:: ADD #RP-SZ,R3 ;INDEX TO RP MOV (R3),R4 ;SAVE POINTER TO I/O BUFFER CLR (R3) ; THEN CLEAR IT CLR -(R3) ;CLEAR THE BLOCK NUMBER .ASSUME BK EQ RP-2 TST -(R3) ;NOW BACK TO CH .ASSUME CH EQ BK-2 .PURGE (R3) ;PURGE THE CHANNEL CLR -(R3) ;CLEAR CURRENT POINTER .ASSUME CP EQ CH-2 CLR -(R3) ;CLEAR CURRENT COUNT .ASSUME CC EQ CP-2 CLR -(R3) ;CLEAR SZ .ASSUME SZ EQ CC-2 CLR FG-SZ(R3) ;CLEAR NC/FG .ASSUME NC EQ FG+1 TST R4 ;WAS THERE AN I/O BUFFER? BEQ RTSPC ;NOPE MOV #512.,R0 ;YEP, SET BUFFER'S SIZE CALLRX BUFDAL ;GO DEALLOCATE & EXIT .DSABL LSB .SBTTL CLOSE FILES ;+ ; CLSFIL - CLOSE INPUT & OUTPUT FILES. ; ; CALL CLSFIL ;- .ENABL LSB CLSFIL::SAVREG ;SAVE ALL REGISTERS CLR EOFLAG(R5) ;NEVER AT END-OF-FILE IF CLOSED MOV INPNTR(R5),R3 ;GET INPUT FILE POINTER (->SZ) TST (R3) ;ANYTHING THERE(SZ=0)? BEQ 10$ ;NOPE CALL PURGE ;YEP, GO FREE UP THE CHANNEL BR 10$ ;GO CLOSE THE OUTPUT FILE ;+ ; CLSOUT - CLOSE OUTPUT FILE. ; ; CALL CLSOUT ;- CLSOUT::SAVREG ;SAVE ALL REGISTERS 10$: MOV OUPNTR(R5),R3 ;GET OUTPUT FILE POINTER (->SZ) TST (R3)+ ;ANYTHING THERE(SZ=0)? BEQ RTSPC ;NOPE MOV #512.,R1 ;SET COUNT TO FORCE A BLOCK WRITE .ASSUME CC EQ SZ+2 20$: CLR R2 ;SET UP A NULL CALLX PUTBYT ; AND OUTPUT IT DEC R1 ;LOOP BNE 20$ ; UNTIL DONE... TST -(R3) ;INDEX TO SZ AGAIN TSTB FG-SZ(R3) ;WERE WE IN EB? BPL 30$ ;IF NOT, JUST CLOSE OUTPUT .ASSUME DOEB EQ 200 .PURGE #14. ;ENSURE THE RENAME CHANNEL IS FREE MOV #CSIBUF+<4*2*2>,R1 ;GET END POINTER FOR RENAMING MOV R1,R0 ;SAVE POINTER FOR WORK AREA (2 WORDS USED) MOV (PC)+,-(R1) ;NEW FILE TYPE IS .BAK .RAD50 /BAK/ TST -(R3) ;INDEX TO FILE DATA .ASSUME FN+6 EQ SZ-2 MOV -(R3),-(R1) ;SET FILENAME SECOND PART MOV -(R3),-(R1) ; AND FIRST PART MOV -(R3),-(R1) ;SET DEVICE ADD #10,R3 ;RE-INDEX TO FILE DATA AGAIN MOV -(R3),-(R1) ;SET FILE TYPE MOV -(R3),-(R1) ;SET FILENAME SECOND PART MOV -(R3),-(R1) ; AND FIRST PART MOV -(R3),-(R1) ;SET DEVICE ADD #SZ-FN,R3 ;RE-INDEX TO SZ .RENAME R0,#14.,R1 ;DO THE RENAMING 30$: .CLOSE CH-SZ(R3) ;CLOSE THE FILE BCC PURGE ; THEN GO PURGE THE CHANNEL DIOERR: ERR DIO,<"Directory I/O error"> .DSABL LSB .SBTTL SET UP FOR OPEN ;+ ; OPNSET - SET UP FOR OPEN. ; ; R1 -> JUST BEYOND DEV:FILNAM.TYP (4 RAD50 WORDS) ; R3 -> I/O PARAMETER BLOCK @ SZ ; ; CALL OPNSET ; ; R0 = UNDEFINED ; R1 -> DEV:FILNAM.TYP (4 RAD50 WORDS) ; R3 -> I/O PARAMETER BLOCK @ FN ; R4 = UNDEFINED ; AREA = HANDLER FLAG WORD ;- .ENABL LSB OPNSET: CALL PURGE ;ENSURE CHANNEL IS PURGED MOV -(R1),-(R3) ;LOAD FILE TYPE MOV -(R1),-(R3) ; AND SECOND PART OF FILENAME MOV -(R1),-(R3) ; AND FIRST PART OF FILENAME MOV -(R1),-(R3) ; AND, FINALLY, THE DEVICE .ASSUME FN EQ SZ-10 MOV #AREA,R4 ;POINT TO SOME SCRATCH SPACE .DSTAT R4,R1 ;GET INFORMATION ABOUT DEVICE BCS 20$ ;BRANCH IF BAD DEVICE NAME TST 4(R4) ;IS HANDLER ALREADY LOADED? BNE 10$ ;YES, SIMPLY EXIT CALLX FETCH ;NO, GO FETCH THE DEVICE HANDLER BCS 30$ ;WHOOPS, SOME ERROR FETCHING THE HANLDER 10$: RETURN ;EXIT 20$: ERR DEV,<"Invalid device"> 30$: ERR FET,<"Handler fetch error"> .DSABL LSB .SBTTL DATA AREAS ORG TIOTXT .EVEN DEFNUL: .WORD 0,0,0,0 ;NO DEFAULTS FOR FILE TYPES DEFTEC: .RAD50 /TECTECTECTEC/ ;DEFAULT "EI" TO '.TEC' .PSECT CSIBUF,RW,D,LCL,REL,CON ORG CSIBUF CSIBUF: .BLKW 5 ;1ST OUTPUT FILE SPEC AREA: .BLKW 5 ;2ND OUTPUT FILE SPEC, MONITOR CALL WORD AREA .BLKW 5 ;3RD OUTPUT FILE SPEC .BLKW 4 ;1ST INPUT FILE SPEC .BLKW 4 ;2ND INPUT FILE SPEC .BLKW 4 ;3RD INPUT FILE SPEC .BLKW 4 ;4TH INPUT FILE SPEC .BLKW 4 ;5TH INPUT FILE SPEC .BLKW 4 ;6TH INPUT FILE SPEC CSISIZ = .-CSIBUF ;SIZE OF CSI BUFFER .END