ߋtv ?B-NO BOOT ON VOLUME K@w p@w w&׭ ׭ w f& fwW#w f   @ @w$ v @& 7   BLOCK@ t IS BAD  -̂@ &   # D@ jw 7 $7 & & B g wD ѕ Rì    s ` h] LJ 1  T s-"w Uq kQNKjkQe'}kQ :dHkQ zH!v kQkQ sH:kQP }kQ&Uq Uq Uq% Uq' }؁'}'}('}P'Jw_kQ!EK QK !8EK Uq%Tq UqJkQUqJkQUqJkQUqJkQUqJkQUqJkQUqJkQTUqJkQTUqJkQT9v #tv *%v *vLDv *xev *jLpv*&#v *y%v *Udv* .BYTE 4 .ENDM .RENAME ; .MACRO .CLOSE .CHANNEL CALL .IO .BYTE ^O<.CHANNEL> .BYTE 7 .ENDM .CLOSE ; .MACRO .PRINT .MESADDR .IF NB .MESADDR MOV .MESADDR,R0 .ENDC ;.IF NB .MSADDR CALLO .PRNT .ENDM .PRINT ; .MACRO .TTYOUT .CHAR .IF NB .CHAR MOVB .CHAR,R0 .ENDC ;.IF NB .CHAR CALLO .TTOUT .ENDM .TTYOUT ; .MACRO .RCTRLO CLR TTOCLO(R5) .ENDM .RCTRLO ; .SBTTL INPUT MODE PROCESSING ; ;TURN ON INPUT MODE ;MAIN PROCESSING LOOP FOR INPUT MODE ; INPUTS: ;REQUEST TERMINAL INPUT CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE TSTB SWITCH(R5) ;BLOCK MODE IN EFFECT? BPL 5$ ;NO: NO SWEAT THEN PUSH CP(R5) ;MAKE SURE WE CAN GET A GOOD SUB PP(R5),(SP) ; LINE IN THEN. CMP (SP)+,#LINELN+4 BHI 5$ ;OK: LINE WILL FIT CALL 2$ ;NO: TELL USER OF PROBLEM BR EDITSS ;REENTER EDIT MODE 5$: CALLO TYPEIN CMPB 2(R0),#12 ;FIRST CHAR = LF, VT, OR CR? BLT 1$ ;NO CMPB 2(R0),#15 ;COULD STILL BE BGT 1$ ;NO CLR (R0) ;YES: NULL LINE SINCE IT DOESN'T REALLY ; EXIST ANYMORE. BR EDITSS ;TURN ON EDIT MODE 1$: CALLO OUTPUT ;WRITE OUT LINE PUSH #3$ ;SETUP A RETURN ADDRESS AT 2$ CALL BUFCHK ;CHECK BUFFER > 7/8 FULL BR 2$ ;TELL USER IT'S TOO BIG RETURN ;CONTINUE (RETURN = BR 3$) 2$: .PRINT #NFULL ;TELL USER RETURN ;RETURN TO CALLER 3$: MOV CURREN(R5),R0 ;TRANSFER LINE FROM CMD AREA TO CURRENT LINE MOVR #CMD,R1 MOV (R1),R2 ;GET BYTE COUNT MOV (R1)+,(R0)+ ;MOVE BYTE COUNT FIRST 4$: MOVB (R1)+,(R0)+ ;NOW TRANSFER LINE DEC R2 ;ALL DONE? BGT 4$ ;NO: CONTINUE BR INPUTS ;CONTINUE ; .SBTTL EDIT MODE PROCESSING ; OVLY2: ;ROUTINE TO FORCE OVERLAY #2 IN RETURN ;RETURN TO CALLER ; ;TURN ON EDIT MODE ; EDITS: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE MOV STACK(R5),SP ;RESET STACK POINTER BIT #100,SWITCH(R5) ;DOES COMMAND ALREADY EXIST? BEQ EDITSS ;NO MOV ENDCM(R5),R0 ;YES: GET NEXT COMMAND THEN BIC #100,SWITCH(R5) ;CLEAR LINE CONCATENATION ID BR EDITS4 EDITSS: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE BIT #20,SW2(R5) ;WAS A MACRO BEING PROCESSED? BEQ REDIT ;NO DEC MACARG(R5) ;YES: DECREMENT MACRO REPEAT COUNT BLE REDIT ;ALL DONE: GET NEXT COMMAND BIT #20000,SW2(R5) ;EOB DETECTED IN MACRO? BEQ 1$ ;NO: CONTINUE BIT #40000,SW2(R5) ;CAN WE CONTINUE OR WILL WE END UP IN ; A POSSIBLE LOOP? BEQ REDIT ;NO: CLEAR STATUS BITS AND ASK FOR NEW ; COMMAND. BIC #40000,SW2(R5) ;CLEAR FLAG FOR NEW OPERATION 1$: MOV CURMAC(R5),R0 ;REDO MACRO BR EDITS4 REDIT: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE .RCTRLO ;RESET ^O FLAG TO ALLOW FUTURE TYPEOUTS .TTYOUT #'* ;TYPE AN (*) BIC #100,SWITCH(R5) ;DISABLE LINE CONCATENATION ID BIC #62220,SW2(R5) ;DISABLE MACRO AND PASTE-LC MODE CLR NARG(R5) ;NUMERIC ARG IS UNDEFINED NOW CLR MACARG(R5) ;MACRO ARG IS ALSO UNDEFINED ; ;MAIN PROCESSING LOOP FOR EDIT MODE ; CLR QUIT(R5) ;NOTHING GOING ON RIGHT NOW MOV CMD(R5),TEMP1(R5) ;SAVE 1ST 6 CHARS IN CMD BUFFER IN MOV CMD+2(R5),TEMP2(R5) ; CASE A "/" AS TYPED. MOV CMD+4(R5),TEMP3(R5) CALLO TYPEIN ;REQUEST TERMINAL INPUT .RCTRLO ;IN CASE IT SLIPPED THROUGH ABOVE TST (R0)+ ;POINTS TO FIRST GOOD CHARACTER CMPB (R0),#'/ ;1ST CHARACTER A "/"? BNE EDITS4 ;NO: TREAT AS NORMAL COMMAND CMP -(R0),#3 ;YES: BYTE COUNT MUST BE 3 THEN BNE ILLCD ;NO: ILLEGAL COMMAND THEN MOV TEMP1(R5),(R0)+ ;RESTORE ORIGINAL COMMAND MOV TEMP2(R5),(R0)+ MOV TEMP3(R5),(R0) TST -(R0) ;BACK PTR BY 2 TO POINT TO FIRST GOOD ; CHARACTER IN OLD COMMAND. EDITS4: BIC #2004,SW2(R5) ;DISABLE READ/WRITE OPERATIONS ; AND IMMEDIATE MACROS. MOV R0,OLDCWD(R5) ;SAVE LOCATION OF OLD CWD MOV R0,R1 ;FIND LINE TERMINATOR TO SEE IF THIS 3$: CMPB (R1)+,CATEN(R5) ; IS A CONCATENATED LINE STRING. BEQ EDITS2 CMPB -1(R1),#12 ;LF ONLY TERMINATES BNE 3$ EDITS0: MOV R1,ENDCM(R5) ;SAVE EOL OR BOL IF ANOTHER COMMAND ; EXISTS. CMPB (R0),#15 ;FIRST CHAR = C/R, LF, OR VT? BNE 1$ ;NO JMP INPUTS ;CR: TURN ON INPUT MODE 1$: CMPB (R0),#13 BEQ VTCHAR ;VT: DO AN NP-1 CMPB (R0),#12 BEQ LFCHAR ;LF: DO AN NP+1 CMPB (R0),#11 BNE 3$ CLR TEMP3(R5) ;TAB: ASSUME ITS AN INSERT COMMAND MOV R0,CWDS(R5) JMP INSERT 3$: CMPB (R0),#100 ;IF 1ST CHAR IS LESS THAN 100(8) BGT 8$ ; THEN AN INVALID COMMAND WAS GIVEN CMPB (R0),#'% ; UNLESS A NUMERIC PRECEEDS IT. BEQ 8$ CMPB (R0),#'< ;IMMEDIATE MACROS ARE ALSO LEGAL BEQ 8$ CMPB (R0),#'* ;ASTERISK MEANS 77777(8) BEQ 8$ CMPB (R0),#60 BLT ILLCD CMPB (R0),#71 BGT ILLCD 8$: MOV R0,CWDS(R5) ;WHERE COMMAND IS BIS #10,SW2(R5) ;IF 1ST CHAR IS A NUMERIC, PROCESS IT JSR R1,GETNUM ; FIRST. MOV R1,NUMBER(R5) ;SAVE ARGUMENT MOV R2,TEMP3(R5) ;R2 CONTAINS "0" IF NO ARG WAS GIVEN BPL 2$ JMP ILLNUM ;NEGATIVE COUNT IS ILLEGAL 2$: .IF NDF NOMAC CMPB @CWDS(R5),#'< ;IF FIRST CHAR OF CONTROL WORD BNE 10$ ; IS AN IMMEDIATE MACRO, PROCESS JMP IMEDMC ; IT IMMEDIATELY. .ENDC 10$: CALLO GETCOM ;GET CONTROL WORD CLR R0 ;CLEAR TABLE ENTRY COUNTER MOV #EDITCM,ARG2(R5) ;TABLE OF CONTROL WORDS MOVR #CWD,ARG1(R5) ;USER'S CONTROL WORD NEXTCM: JSR R0,SCAN ;SCAN FOR MATCH BR .+4 ;NO MATCH BR ENDS1 ;END OF STRING 1 (CONSIDER THIS MATCHED) MOV ARG2(R5),R1 ;END OF STRING 2 (NO POSSIBLE MATCH) 1$: CMPB (R1)+,#15 ;FIND START OF NEXT STRING BNE 1$ MOV R1,ARG2(R5) ;START OF NEW STRING POINTER INC R0 CMP R0,#SIZEVT ;END OF TABLE? BNE NEXTCM ;NO: CONTINUE ILLCD: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE MOV #MSG7,R0 ;TYPE "ILL CMD" BR EDIT4 ILLNUM: JMP PRT0 ;NEG COMMAND REPEAT COUNT IS ILLEGAL. ENDS1: ASL R0 ;COMPUTE DISPATCH ADDRESS INC QUIT(R5) ;INDICATE SOME PROCESSING IS GOING ON JMP @EDITVT(R0) ;CALL REQUESTED ROUTINE EDITS2: BIS #100,SWITCH(R5) ;SET LINE CONCATENATION ID CALL TESTCR ;LINE CANNOT BE TERMINATED FOLLOWING ; THE CATENATING CHARACTER. JMP 1$ ;YES: ILLEGAL CONSTRUCTION BR EDITS0 1$: MOV #SYNTAX,R0 ;PRINT SYNTAX ERROR EDIT4: .PRINT JMP REDIT ; ;QUICKIE CHARACTERS LF AND VT - AND - OVERLAY #2 HANDLER ; VTCHAR: PUSH #-1 ;SIMULATE AN NP-1 COMMAND .PRINT #MSG3 ;TYPE A CR-LF FIRST BR LF1 LFCHAR: PUSH #1 ;SIMULATE AN NP+1 COMMAND .TTYOUT #15 ;TYPE A CR FIRST LF1: BIS #1,SW2(R5) POP R1 INC QUIT(R5) ;INDICATE SOME PROCESSING IS GOING ON JMP NEXT8 ; ; OVERLAY #2 DEFINER ROUTINE DEFINES OVERLAY #2 SO WHEN AN ; RTS PC IS EXECUTED IN NON-OVERLAYED CODE, THE RIGHT OVERLAY ; IS BROUGHT IN. ; SETOV2: MOVB #1,OVLYSW(R5) ;SHOW OVERLAY #2 ACTIVE RETURN ;RETURN TO CALLER ; .SBTTL PRINT, LIST, AND TYPE COMMANDS ; ;PRINT N LINES FROM EDIT FILE ; PRINT: BICB #20,SWITCH(R5) ;CLEAR LIST ID JSR R1,GETNUM ;GET ARGUMENT (RETURNED IN R1) MOV R1,TEMP4(R5) ;SAVE TEMP MOV R1,NUMBER(R5) ;SAVE ARGUMENT BPL PRT3 ;ARGUMENT MUST BE (+) PRT0: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE .PRINT #MSG10 ;ILLEGAL NUMERIC ARGUMENT JMP REDIT PRT3: MOV CURREN(R5),R0 ;ANY CHARS IN THIS LINE. TSTB (R0) BEQ 1$ ;IGNORE IF ZERO CALLO TYPE ;TYPE OUT LINE 1$: DEC NUMBER(R5) ;ALL LINES PRINTED BNE PRT2 ;MORE TO DO RCMD: JMP EDITS ;TYPE A (*) PRT2: CALLO OUTPUT ;WRITE OUT CURRENT LINE CALLO INPUT ;INPUT A NEW LINE JMP 5$ ;END OF FILE RETURN TST QUIT(R5) ;SOME ONE WANT TO STOP PREMATURELY? BEQ RCMD1 ;YES: TERMINATE FUNCTION BR PRT3 ;TYPE OUT NEW LINE 5$: BITB #20,SWITCH(R5) ;LIST OR REGULAR MODE? BNE 6$ ;LIST BIT #400,SW2(R5) ;TYPE COMMAND ACTIVE? BEQ 7$ ;NO BIC #421,SW2(R5) ;DISABLE MACRO PROCESSING AND THE BIC #100,SWITCH(R5) ; TYPE COMMAND. MOV NUMBER(R5),R1 ;MOVE BACK TO ORIGINAL LINE SUB TEMP4(R5),R1 INC R1 BEQ RCMD ;FORGET IT IF WE'RE AT THE BOTTOM ; AND THAT'S WHERE WE STARTED. BR NEXT8 ;RETURN TO OLD CURRENT LINE NOW 7$: JMP EOF ;REGULAR: PRINT "EOF" 6$: JMP TOP ;CLEAR LIST REQUEST AND TOP AGAIN RCMD1: BIC #20,SW2(R5) ;DISABLE MACRO PROCESSING BR RCMD ;TERMINATE FUNCTON ; ; ;LIST ENTIRE BLOCK BUFFER ; LIST: BISB #20,SWITCH(R5) ;INDICATE A LIST "TOP" IS REQUESTED AND MOV #77777,NUMBER(R5) ; THEN USE "PRINT" TO LIST THE BLOCK BR PRT3 ; BUFFER. ; ;SERVICE A TYPE REQUEST ; TYPLIN: JSR R1,GETNUM ;GET ARG (RETURNED IN R0) BMI PRT0 ;NEG # IS ILLEGAL TSTB SWITCH(R5) ;ARE WE IN BLOCK MODE? BPL ILLMOD ;NO: ILLEGAL THEN MOV R1,NARG(R5) ;SAVE MACRO ARG. CALL TESTCC ;MAKE SURE THE STANDARD CC CHAR HAS ; BEEN DEFINED, AND IF ; NOT, DEFINE IT. BIS #400,SW2(R5) ;INDICATE TYPE COMMAND ACTIVE MOV #TYPMAC,R0 ;ADDRESS OF TYPE MACRO COMMAND JMP EXECMC ;SET MACRO MODE IN PROGRESS AND ; EXECUTE MACRO. ; .SBTTL DELETE, DP, NEXT, AND NP COMMANDS ; ;DELETE N LINES ; DELETE: BIC #1,SW2(R5) BR DELET1 ; ;DELETE N LINES AND PRINT CURRENT LINE WHEN DONE ; DELETP: BIS #1,SW2(R5) DELET1: CLR R0 BR NEXT3 ; ;MOVE POINTER DOWN N LINES ; NEXT: BIC #1,SW2(R5) ;DON'T PRINT LINE WHEN FOUND NEXT7: MOV PC,R0 ;DELETE/NEXT SWITCH NEXT3: JSR R1,GETNUM ;GET ARGUMENT (RETURNED IN R1) NEXT8: MOV R1,NUMBER(R5) ;SAVE ARGUMENT BMI NEXT4 ;IF NEG, BLOCK MODE MUST BE IN EFFECT 2$: TST R0 ;DELETE/NEXT? BNE 1$ ;NEXT CLR .CURRN(R5) ;NULL OUT LINE LENGTH 1$: CALLO OUTPUT ;OUTPUT CURRENT LINE CALLO INPUT ;INPUT NEW LINE JMP EOF ;EOF RETURN TST QUIT(R5) ;PREMATURE TERMINATE DESIRED? BEQ RCMD1 ;YES DEC NUMBER(R5) ;ALL DONE? BNE 2$ ;MORE LINES TO DO NEXT0: BIT #1,SW2(R5) ;PRINT OUT THIS LINE? BEQ RCMD ;NO: RETURN TO MAIN PROCESSING LOOP JMP FND2 NEXT4: TSTB SWITCH(R5) ;BLOCK MODE MUST BE IN EFFECT BMI NEXT5 ;OK ILLMOD: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE .PRINT #ILLOFF ;ILL MODE JMP REDIT NEXT5: MOV #-2,R1 ;ASSUME CURRENT LINE EXISTS AND AFTER TSTB .CURRN(R5) ; WE WRITE IT OUT WE HAVE TO BACK BNE 1$ ; UP 2 LINES. INC R1 ;NO: ONLY BACK UP ONE LINE THEN 1$: CALLO OUTPUT ;MAKE SURE CURRENT LINE GETS INSERTED ; IN BUFFER BEFORE DELETING OR ; MOVING. CALL MOVE ;BACK UP BUFFER POINTER BY TWO TO NORM- ; ALIZE OPERATIONS. BR BOBED ;BEGINNING OF BUFFER REACHED CALLO INPUT ;READ IN PREVIOUS LINE NOW. (LINE -1) JMP EOF TST R0 ;DELETE/NEXT? BNE 6$ ;NEXT CLR .CURRN(R5) ;DELETE: NULL OUT CURRENT LINE CALLO INPUT ;GET NEXT LINE IN THEN JMP EOF CALLO OUTPUT ;THIS JUST SWITCHES BUFFERS. NO LINE ; ACTUALLY GETS OUTPUT. 6$: INC NUMBER(R5) ;ALL DONE? BLT NEXT5 ;NO: DO ANOTHER BR NEXT0 BOBED: BIT #20,SW2(R5) ;CURRENTLY IN MACRO MODE? BNE NEXT0 ;YES MOV #MSG12-2,R0 ;PRINT "BOB" AND RETURN BR EOF1 ; ;SERVICE NP REQUEST ; NP: BIS #1,SW2(R5) ;SET NP REQUEST BR NEXT7 ;USE REGULAR NEXT ROUTINE NOW. ; .SBTTL PAGE-FIND AND PAGE-LOCATE COMMANDS ; ;SERVICE A PFIND COMMAND ; PFIND: JSR PC,PFL ;DO A PAGE FIND NOW .WORD FIND1 ;WHERE TO GO ; ;SERVICE PLOCATE COMMAND ; PLOCAT: JSR PC,PFL ;DO A PAGE LOCATE NOW .WORD LOCAT1 ;WHERE TO GO ; ; PFL: BIS #100,SW2(R5) ;INDICATE A PAGE FIND/LOCATE IS REQUESTED TSTB SWITCH(R5) ;MUST BE IN BLOCK MODE BMI 1$ ;OK JMP ILLMOD ;ILLEGAL BLOCK MODE 1$: CLR TEMP5(R5) ;INDICATE NO NEW PAGES READ IN YET MOV @(SP)+,PC ;GO TO REQUESTED ROUTINE (FIND/LOCATE) PFL1: JSR R0,WRITES ;RENEW TO NEXT PAGE JSR R0,READS BR FND3 ;EOF RETURN BIS #40000,SW2(R5) ;INDICATE THAT A NEW PAGE IS IN MOV SP,TEMP5(R5) ;REMEMBER THAT A RENEW WAS DONE RETURN ;RETURN .SBTTL FIND COMMAND ; ;FIND A LINE ; FIND: BIC #100,SW2(R5) ;CLEAR PAGE FIND REQUEST FIND1: CALLO OUTPUT ;OUTPUT CURRENT LINE CALLO INPUT ;GET NEW LINE AND OUTPUT LAST JMP 1$ ;EOF RETURN TST QUIT(R5) ;PREMATURE TERMINATE DESIRED? BEQ FND5 ;YES MOV CURREN(R5),ARG2(R5) ;SETUP STRING POINTER MOV CWDS(R5),ARG1(R5) ADD #2,ARG2(R5) JSR R0,SCAN BR FIND1 ;NOT FOUND BR FND4 ;END OF LINE FOR STRING 1 BR FIND1 ;LOOK AT NEXT LINE 1$: BIT #100,SW2(R5) ;WAS THIS A PAGE FIND REQUEST? BEQ EOF ;NO: TYPE EOF/EOB CALL PFL1 ;RENEW TO NEXT PAGE BR FIND1 ;CONTINUE LOOKING THIS PAGE EOF: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE TSTB SWITCH(R5) ;BLOCK MODE IN EFFECT? BMI EOF2 ;YES: TYPE "EOB" MOV #MSG13-2,R0 ;TYPE "EOF" BIC #20,SW2(R5) ;DISABLE MACRO PROCESSING BR EOF1 EOF2: CALLO TOPS ;TOP BLOCK BUFFER BIT #220,SW2(R5) ;IS PASTE, LC, OR MACRO ACTIVE? BNE FND3 ;DON'T PRINT EOB IF SO MOV #MSG11-2,R0 ;"EOB" EOF1: CALLO TYPE FND3: JMP EDITS ;RETURN TO MAIN PROCESSING LOOP FND5: JMP RCMD1 ;DISABLE MACRO PROCESSING AND RETURN FND4: DEC NUMBER(R5) ;FOUND THE NTH OCCURRENCE OF THIS ; STRING? BGT FIND1 ;NO: LOOK AGAIN FND1: BIT #100,SW2(R5) ;PF OR PL REQUESTED? BEQ 1$ ;NO TST TEMP5(R5) ;ANY NEW PAGES READ IN? BEQ 1$ ;NO CALL PLINES ;YES: PRINT BUFFER SIZE IF NECESSARY 1$: BITB #2,SWITCH(R5) ;PRINT FOUND LINE? BEQ FND3 ;NO FND2: MOV CURREN(R5),R0 ;TYPE FOUND LINE BR EOF1 .SBTTL LOCATE COMMAND ; ;LOCATE A LINE ; LOCATE: BIC #100,SW2(R5) ;CLEAR PAGE LOCATE REQUEST LOCAT1: CALLO OUTPUT ;OUTPUT CURRENT LINE CALLO INPUT ;GET NEW LINE AND OUTPUT LAST JMP 4$ ;EOF RETURN TST QUIT(R5) ;PREMATURE TERMINATE DESIRED? BEQ FND5 ;YES MOV CURREN(R5),ARG2(R5) ;SETUP STRING POINTER MOV CWDS(R5),ARG1(R5) ADD #2,ARG2(R5) 1$: JSR R0,SCAN ;CALL STRING COMPARER BR 2$ ;NOT FOUND THIS TRY BR 3$ ;FOUND BR LOCAT1 ;NOT FOUND ANYWHERE IN THIS LINE 4$: BIT #100,SW2(R5) ;WAS THIS A PAGE LOCATE REQUEST? BEQ EOF ;NO CALL PFL1 ;LOOK AT NEXT PAGE BR LOCAT1 ;CONTINUE 2$: INC ARG2(R5) ;START AT NEXT CHARACTER IN LINE BR 1$ 3$: DEC NUMBER(R5) ;FOUND THE NTH OCCURRENCE OF THIS ; STRING? BGT 2$ ;NO: LOOK AGAIN BR FND1 ;YES: PRINT LINE IF IN VERIFY MODE .SBTTL INSERT, RETYPE, ADD, AND AP COMMANDS ; ;INSERT A LINE AFTER THE CURRENT LINE IN "LAST" ; INSERT: MOV CWDS(R5),R1 ;GET POINTER TO ARGUMENT CALL TESTCR ;ANY ARG. OR IS USER REQUESTING INPUT? JMP INPUTS ;INPUT REQUEST: SWITCH TO INPUT MODE CALLO OUTPUT ;WRITE OUT CURRENT LINE .DSABL LSB ; ; ;REPLACE CURRENT LINE WITH COMMAND LINE ; RETYPE: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE MOV CURREN(R5),R0 ;NULL CURRENT LINE CLR (R0) ; ;ADD SOME DATA TO THE CURRENT LINE ; ADDIT: BIC #400,SW2(R5) ;INDICATE AN "ADD" COMMAND IS IN USE ADD1: MOV CWDS(R5),R1 ;ADDRESS OF STRING TO CONCATENATE CALL TESTCR ;NULL STRING? 2$: JMP 9$ ;PRINT OUT LINE IF NECESSARY 10$: MOV CURREN(R5),R0 ;ADDRESS OF BASE STRING MOV R0,TEMP1(R5) TST (R0)+ ;ACCOUNT FOR HEADER TST @TEMP1(R5) ;BASE STRING NULL? BEQ 4$ ;YES 3$: CMPB (R0)+,#14 ;LOOK THRU LINE TILL C/R OR FF BEQ 5$ CMPB -1(R0),#15 BNE 3$ DEC R0 SUB #2,@TEMP1(R5) ;SUBTRACT C/R FROM BYTE COUNT 5$: CMP @TEMP1(R5),#82. ;MAKE SURE THERE IS ENOUGH ROOM BLT 4$ ;OK MOVB #15,(R0)+ ;END LINE WITH A C/R MOVB #12,(R0)+ JMP CH16 ;REPORT TO USER THAT LINE IS TOO LONG 4$: MOVB (R1),(R0)+ ;ADD ONE BYTE INC @TEMP1(R5) ;+1 TO BYTE COUNT CMPB (R1),CATEN(R5) ;END OF STRING? BNE 6$ ;NO MOVB #15,-1(R0) ;YES: SUBSTITUTE A C/R BR 7$ 6$: CMPB (R1),#14 ;END OF STRING? BEQ 8$ ;YES CMPB (R1)+,#15 ;END OF STRING? BNE 5$ ;NO: CONTINUE 7$: MOVB #12,(R0) ;ADD ONE LF INC @TEMP1(R5) ;+1 TO BYTE COUNT 8$: BIT #400,SW2(R5) ;PRINT OUT NEW LINE? BEQ 1$ ;NO: RETURN TO COMMAND LOOP JMP FND2 ;YES 1$: JMP EDITS ;RETURN TO COMMAND LOOP 9$: CMPB (R1),#14 ;WAS IT A FF? BEQ 10$ ;YES: INSERT IT THEN BR 8$ ;NO ; ;ADD SOME DATA TO CURRENT LINE AND PRINT IT OUT ; APPEND: BIS #400,SW2(R5) ;INDICATE AN "AP" COMMAND IN PROGRESS BR ADD1 ;PROCESS COMMAND NOW .SBTTL CHANGE, LC, AND PASTE COMMANDS ; ;REPLACE STRING 1 WITH STRING 2. ; CH0: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE .PRINT #MSG1 ;ILLEGAL COMMAND CONSTRUCTION BIC #20,SW2(R5) ;DISABLE MACRO PROCESSING JMP EDITS CHANGE: BIC #200,SW2(R5) ;INDICATE CHANGE ACTIVE MOV CURREN(R5),OARG(R5) ;BEGIN SEARCHING AT BEGINNING ADD #2,OARG(R5) ; OF LINE. CHANG: MOV CURREN(R5),R1 ;IF LINE DOESN'T EXIST, DON'T ALLOW TST (R1)+ ; A CHANGE TO OCCUR. CALL TESTCR JMP 25$ CMPB @OARG(R5),#14 BNE CH20 25$: TSTB SW2(R5) ;PASTE OR LC ACTIVE? BMI CH2 ;YES: JUST SKIP THE LINE THEN .NOL: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE .PRINT #NOLINE ;NO LINE(ERROR) JMP REDIT CH2: JMP CH17 CH20: CLR CDONE(R5) ;INDICATE NO CHANGES HAVE BEEN MADE ; YET. MOV CWDS(R5),R0 ;START ADDRESS OF STRING 1 MOVB (R0)+,QUOTE(R5) ;FIRST CHAR IS THE QUOTE MOV R0,ARG1(R5) ;START ADDRESS OF QUOTE STRING 24$: CMPB (R0),QUOTE(R5) ;QUOTE AGAIN? BEQ 19$ ;YES CMPB (R0),CATEN(R5) ;CATENATION CHAR? BEQ CH0 ;YES CMPB (R0)+,#15 ;C/R ENDS CHANGE REQUEST BEQ CH0 BR 24$ ;KEEP LOOKING 19$: INC R0 ;MOVE PAST QUOTE CHAR MOV R0,TEMP1(R5) ;START ADDRESS OF REPLACEMENT STRING 4$: CMPB (R0),#15 ;DELETE QUOTE OR C/R AT END OF BEQ 3$ ; STRING. CMPB (R0),QUOTE(R5) BEQ 3$ TSTB (R0)+ BR 4$ ;CONTINUE SEARCH 3$: SUB TEMP1(R5),R0 ;NBR. OF CHARS IN REPLACEMENT STRING MOV OARG(R5),ARG2(R5) ;SETUP SCAN POINTER. BEGIN EITHER ; AT BEGINNING OF LINE IF "CHANGE" ; OR AT END OF LAST REPLACEMENT ; IF "LC" OR "PASTE". 5$: JSR R0,SCANCH ;CALL STRING COMPARER BR 6$ ;NOT FOUND THIS TRY BR 7$ ;FOUND BR CH17 ;NOT FOUND ANYWHERE IN THIS LINE 6$: INC ARG2(R5) ;START AT NEXT CHAR IN NEW LINE BR 5$ 7$: MOV R2,R4 ;WAS SEARCH STRING NULL? SUB ARG2(R5),R4 BNE 23$ ;NO TSTB SW2(R5) ;IF PASTE OR LC WAS ACTIVE, WE BETTER BMI CH0 ; FORGET IT OR WE'LL END UP IN ; AN INFINITE LOOP. 23$: MOV R0,R1 ;SAVE TEMP. SUB R4,R0 ;COMPUTE DIFFERENCE IN STRING SIZES BGE CH11 MOV ARG2(R5),R2 ;REPLACEMENT STRING IS SMALLER THAN MOV TEMP1(R5),R3 ; ORIG. STRING. THEREFORE THE MAIN 9$: CMPB (R3),QUOTE(R5) ; STRING MUST BE SHORTENED. THE BEQ 8$ ; REPLACEMENT TEXT IS SUBSTITUTED CMPB (R3),CATEN(R5) ; FIRST. BEQ 8$ CMPB (R3),#15 BEQ 8$ MOVB (R3)+,(R2)+ BR 9$ 8$: MOV R2,OARG(R5) ;REMEMBER WHERE REPLACEMENT ; TEXT LEFT OFF. NEG R0 ;NOW CONTRACT MAIN STRING ADD R2,R0 10$: MOVB (R0)+,(R2) CMPB (R2)+,#12 ;END OF STRING? BNE 10$ ;NO: CONTINUE MOV R2,R4 SUB CURREN(R5),R4 SUB #2,R4 BR CH15 CH11: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE MOV ARG2(R5),R3 ;REPLACEMENT STRING IS LARGER THAN ORIG ; STRING. THEREFORE THE MAIN STRING 12$: CMPB (R3)+,#12 ; MUST BE EXPANDED. THE REPLACEMENT BNE 12$ ; TEXT IS SUBSTITUTED AFTER THE ; EXPANSION IS COMPLETED. MOV R3,R2 SUB ARG2(R5),R2 MOV R3,R4 ;MAKE SURE THE NEW STRING HAS ENOUGH ADD R0,R4 ; ROOM. DEC R4 ADD R3,R0 ;(ADD IN OFFSET USED DURING EXPANSION) SUB CURREN(R5),R4 SUB #2,R4 CMP R4,#LINELN BLT CH13 ;OK CH16: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE .PRINT #MSG8 ;TOO MANY CHARS IN LINE MOV CURREN(R5),R0 ;PRINTOUT OLD LINE ALSO TST (R0)+ BIC #20,SW2(R5) ;DISABLE MACRO MODE JMP EOF1 CH13: MOVB -(R3),-(R0) ;EXPAND STRING NOW DEC R2 ;ALL DONE? BGT CH13 ;NO: CONTINUE MOV ARG2(R5),R2 ;INSERT REPLACEMENT TEXT MOV TEMP1(R5),R3 INC R4 14$: CMPB (R3),QUOTE(R5) BEQ 25$ CMPB (R3),CATEN(R5) BEQ 25$ CMPB (R3),#15 BEQ 25$ MOVB (R3)+,(R2)+ BR 14$ 25$: MOV R2,OARG(R5) ;REMEMBER WHERE REPLACEMENT TEXT ; LEFT OFF. CH15: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE MOV CURREN(R5),R0 ;COMPUTE NEW HEADER WORD COUNT INC CDONE(R5) ;INDICATE A CHANGE WAS MADE TO THIS LINE MOV R4,(R0) TSTB SW2(R5) ;IF LC IS ACTIVE, DO THE CHANGE AGAIN BMI LC3 ;YES CH17: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE MOV CURREN(R5),R0 ;NO TSTB SW2(R5) ;LC ACTIVE? BMI LC1 ;YES TST CDONE(R5) ;ANY CHANGES MADE SO FAR? BNE 25$ ;YES .PRINT #ILLSTR ;TELL USER THAT NO MATCH WAS MADE BIC #20,SW2(R5) ;DISABLE MACRO MODE BR PLINE1 ;GET NEXT COMMAND 25$: DEC NUMBER(R5) ;NTH CHANGE MADE YET? BLE CH18 ;YES JMP CHANGE ;NO: DO NEXT THEN CH18: BIC #100,SW2(R5) ;PRINTOUT NEW LINE JMP FND1 ; ;PASTE/LC SERVICE ROUTINE ; PASTE: MOV #77777,NUMBER(R5) ;SET LC COUNT TO MAX LC: CLR PDONE(R5) ;CLEAR COUNTER FOR CHANGES MADE BIS #200,SW2(R5) ;INDICATE A PASTE OR LC IS ACTIVE MOV CURREN(R5),OARG(R5) ADD #2,OARG(R5) LC2: JMP CHANG ;PROCESS LC REQUEST FOR CURRENT ; LINE. LC1: TST PDONE(R5) ;WAS A CHANGE MADE? BEQ 4$ ;NO: LOOK AT NEXT LINE BITB #2,SWITCH(R5) ;PRINT LINE (VERIFY)? BEQ 4$ ;NO MOV CURREN(R5),R0 ;YES: TYPE IT OUT CALLO TYPE 4$: DEC NUMBER(R5) ;N LINES CHANGED? BLE PLINE1 ;YES: QUIT THEN CALLO OUTPUT ;OUTPUT CURRENT LINE CALLO INPUT ;GET A NEW LINE JMP EOF ;END OF FILE RETURN TST QUIT(R5) ;PREMATURE TERMINATE DESIRED? BNE LC ;NO: CONTINUE LC6: BIC #20,SW2(R5) ;DISABLE MACRO PROCESSING PLINE1: JMP EDITS LC3: ADD CDONE(R5),PDONE(R5) ;REMEMBER A CHANGE WAS MADE BR LC2 ;DO LINE AGAIN IN CASE THERE'S MORE ; TO CHANGE. .IF NDF NOMAC .SBTTL <...> COMMAND ; ; SERVICE THE <...> COMMAND ; IMEDMC: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE INC CWDS(R5) ;BUMP PAST "<" MOV R1,TEMP1(R5) ;SAVE R1 MOV #1,R1 ;RESULT ENDS UP IN MACRO 1 BIS #2000,SW2(R5) ;INDICATE AN IMMEDIATE MACRO ; IS IN PROGRESS. JMP MAC001 ;PROCESS MACRO NOW ; .SBTTL "M" COMMAND ; ;SERVICE AN "M" COMMAND ; MACRO: BICB #100,SWITCH(R5) ;DON'T ALLOW CONCATENATED MACROS TST MACARG(R5) ;ARE WE REPEATING A MACRO? BNE 4$ ;YES: DON'T DIDDLE WITH MACRO'S REPEAT ; COUNT THEN. MOV NUMBER(R5),MACARG(R5) ;SAVE NEW MACRO COUNT 4$: JSR R1,GETNUM ;GET ARGUMENT (RETURNED IN R1) BMI ILLN ;NEGATIVE NUMBER IS ILLEGAL CMPB R1,MAXMAC(R5) ;MACRO SLOT NUMBER LEGAL? BGT ILLN ;NO: ILLEGAL NUMBER GIVEN THEN MOVR #MACDEF-1,R0 ;MACRO DEFINED? ADD R1,R0 TSTB (R0) BMI 1$ ;YES .PRINT #MACERR ;TELL USER OF ERROR JMP REDIT 1$: MOVR #MACBUF-130.,R0 ;CALCULATE MACRO ADDRESS 2$: ADD #130.,R0 DEC R1 BGT 2$ JSR R1,GETNUM ;GET 2ND ARG IF ONE WAS GIVEN TST R2 ;IF R2=0, NO ARG WAS GIVEN BEQ 3$ MOV R1,R2 ;USE R1 VALUE 3$: MOV R2,NARG(R5) ;SAVE ARG SO COMMANDS MAY USE IT BIS #30,SW2(R5) ;SET MACRO MODE IN PROGRESS AND COMMAND ; MODE FOR NUMERICS PRECEEDING ; COMMANDS. MOV OLDCWD(R5),CURMAC(R5) ;SAVE START LOCATION OF MACRO COMMAND JMP EDITS4 ;R0 POINTS TO START OF MACRO. ; EXECUTE THE MACRO NOW. ILLN: JMP PRT0 .ENDC ;.IF NDF NOMAC .SBTTL EXIT, CLOSE AND BOTTOM (END) COMMANDS ; ;SERVICE AN EXIT REQUEST ; EXIT: TSTB FG ;ARE WE IN THE FOREGROUND? BNE 1$ ;YES JMP ILLCD ;OUCH: THIS GUYS TRYING TO TAKE ; THE SYSTEM TO NEVER NEVER LAND. 1$: BISB #200,SWITCH+1(R5) ;SET EXIT SWITCH TO EXIT AFTER THE BR CLOSEX ; CLOSE IS DONE. ; ;SERVICE A CLOSE REQUEST ; CLOSE: BICB #200,SWITCH+1(R5) ;INDICATE NO EXIT AFTER CLOSE CLOSEX: BISB #4,SWITCH(R5) ;INDICATE A COMPLETE CLOSE IS REQUESTED BR BOTT00 ; ;SERVICE BOTTOM(END) REQUEST ; BOTTOM: BICB #4,SWITCH(R5) ;INDICATE NO CLOSE IS REQUESTED BOTT00: BIC #40,SW2(R5) ;INITIALIZE PREVIOUS BLOCK-ON SWITCH BOTT0: CALLO OUTPUT ;OUTPUT CURRENT LINE CALLO INPUT ;INPUT A NEW LINE JMP 1$ ;EOF, LAST LINE ALREADY IN TST QUIT(R5) ;PREMATURE TERMINATE DESIRED? BNE BOTT0 ;NO: DO NEXT LINE JMP LC6 ;YES 1$: BITB #4,SWITCH(R5) ;CLOSE? BNE 2$ ;YES: CONTINUE BITB #2,SWITCH+1(R5) ;WAS THIS A BOTTOM REQUEST FOR A READ? BEQ 4$ BICB #6,SWITCH+1(R5) ;YES: CLEAR SWITCHES AND RETURN JMP READ0 4$: BIC #100,SW2(R5) ;TYPE OUT LAST LINE AND RETURN JMP FND1 2$: TSTB SWITCH(R5) ;BLOCK MODE IN EFFECT? BPL 3$ ;NO: CONTINUE JSR R0,WRITES ;WRITE OUT BLOCK BUFFER NOW BICB #200,SWITCH(R5) ;DISABLE BLOCK MODE AND BOTTOM AGAIN BIS #40,SW2(R5) ;REMEMBER THAT WE WERE IN BLOCK MODE BR BOTT0 3$: CALLO OUTPUT ;MAKE SURE LAST LINE HAS BEEN OUTPUT MOVR #OUTPTR,R2 ;PAD REST OF OUTPUT BLOCK WITH NULLS ; AND THEN WRITE IT OUT. MOV #1,CHAN(R5) CALLO COMOUT .CLOSE 1 ;CLOSE OUTPUT FILE .CLOSE 0 ;CLOSE INPUT FILE BIT #40,SW2(R5) ;WAS BLOCK MODE ON BEFORE? BEQ BOTT12 ;NO BISB #200,SWITCH(R5) ;TURN ON BLOCK MODE AGAIN BOTT12: BITB #1,SWITCH(R5) ;IF NO INPUT FILE WAS PRESENT, DON'T BNE 5$ ; TRY TO DIDDLE WITH IT. MOV INFIL+2(R5),BAKFIL+2(R5) ;RENAME FILE. SETUP FILE BLOCK FIRST MOV INFIL+4(R5),BAKFIL+4(R5) MOV INFIL+2(R5),FLTMP+2(R5) ;TRANSFER FILE NAME TO RENAME AREA MOV INFIL+4(R5),FLTMP+4(R5) MOV INFIL+6(R5),FLTMP+6(R5) .CKFIL #BAKFIL,BOTT01 ;NO ONE ELSE CAN USE THIS FILE NAME .RENAME 0,#FLTMP CLR FLTMP+2(R5) ;DISABLE FILE NAME BLOCK 5$: MOV CWDS(R5),R1 ;GET FILE NAME CALL TESTCR ;EXIST? JMP BOTT10 ;NO MOVR #INFIL+2,R4 ;PUT IT IN "INFIL" IN CASE THERE'S AN CALL GETNM ; AN ERROR. BR BOTT02 ;SYNTAX ERROR BR BOTT10 ;SUCESSFUL RETURN BOTT02: .PRINT #ILLNAM ;TELL USER OF ERROR BR BOTT10 ;USE ORIGINAL FILE NAME NOW ; BOTT01: .PRINT #OFILE ;TELL USER HIS EDITED FILE IS "EDIT0N.TMP" JMP START ; BOTT10: MOV TMPFIL+2(R5),BAKFIL+2(R5) ;NOW USE THIS NAME TO RENAME THE MOV TMPFIL+4(R5),BAKFIL+4(R5) ; TEMPORARY OUTPUT FILE. MOV TMPFIL+6(R5),BAKFIL+6(R5) MOV DEV(R5),INFIL(R5) ;ALWAYS USE DEFAULT DEVICE .CKFIL #INFIL,BOTT02 ;NO ONE ELSE CAN USE THIS FILE NAME .RENAME 0,#BAKFIL ;RENAME TEMP OUTPUT FILE NOW MOV BAK,BAKFIL+6(R5) ;RESET BACKUP FILE EXTENSION BITB #1,SWITCH+1(R5) ;REOPEN FILE (TOP DONE?) BNE BOTT9 ;YES TSTB SWITCH+1(R5) ;EXIT TO BACKGROUND? BPL 1$ ;NO TSTB FG ;ARE WE IN THE FGD? BEQ 2$ ;NO: ILLEGAL COMMAND THEN CALL DFBLK ;DISABLE FILE NAME BLOCKS .PRINT #EXITMG ;YES: TELL USER WE'RE EXITING CALLO TTWAIT ;WAIT FOR TTY TO FINISH JMP EXITBK 2$: .PRINT #NOXIT ;TELL USER THAT WE'RE NOT EXITING 1$: CALL DFBLK ;DISABLE FILE NAME BLOCKS JMP START ;COMPLETELY RESTART EDITOR BOTT9: BIC #410,SWITCH(R5) ;CLEAR TOP REQUEST AND INDICATE A ; TOP WAS MADE. CLR FSIZE(R5) ;SET FILE SIZE = 0 TO USE DEFAULT INPUT ; SIZE + 50 BLOCKS. .PRINT #REOPEN ;TELL USER WE'RE REOPENING HIS FILE JMP EDIT1 ;NOW REOPEN INPUT AND OUTPUT FILES ; ; DISABLE FILE NAME BLOCKS ; DFBLK: CLR INFIL+2(R5) CLR OUTFIL+2(R5) CLR BAKFIL+2(R5) CLR FLTMP+2(R5) RETURN ;RETURN TO CALLER ; .SBTTL ERASE COMMAND ; ;ERASE NEXT N PAGES ; ERASE: JSR R1,GETNUM ;GET ARGUMENT (RETURNED IN R1) BMI 3$ ;NEGATIVE ARGUMENT IS ILLEGAL MOV R1,NUMBER(R5) ;SAVE ARGUMENT 2$: CALLO ERASES ;ERASE CURRENT PAGE TSTB SWITCH(R5) ;ILLEGAL TO CONTINUE IF WE'RE IN BMI 4$ ; BLOCK OFF MODE AND N IS > 1. DEC NUMBER(R5) BLE LINE1 ;RETURN (ONLY ONE PAGE WAS REQUESTED) JMP ILLMOD ;ILLEGAL BLOCK COMMAND 4$: MOV PAGE(R5),PDONE(R5) ;SAVE PAGE NBR OF CURRENT PAGE DEC NUMBER(R5) ;MORE PAGES TO GO? BLE LINE1 ;NO: ALL DONE 1$: JSR R0,READS ;GET NEXT PAGE BR 5$ ;EOF FOUND CMP PAGE(R5),PDONE(R5) ;DID ENTIRE PAGE GET READ IN? BNE 2$ ;YES: ERASE IT THEN CALLO ERASES ;NO: ERASE WHAT WE DID GET IN AND GO BR 1$ ; GET REST OF IT. 3$: JMP PRT0 ;NEG. ARG. IS ILLEGAL 5$: CLR NUMBER(R5) ;NO MORE PAGES EXIST BR 2$ ;ERASE CURRENT PAGE NOW ; .SBTTL BLOCK COMMAND ; ;SERVICE A BLOCK ON/OFF MODE REQUEST ; BLOCK: CALL TSTPG ;TEST FOR PAGE MODE ALLOWED BR 2$ ;NO: DON'T ALLOW COMMAND THEN MOV SWITCH(R5),R2 ;REMEMBER PREVIOUS MODE MOV #200,R1 ;INDICATE BLOCK MODE BY A 200 CALLO ONOFF ;SET SWITCH ON/OFF NOW BIT R1,SWITCH(R5) ;DID SWITCH GET TURNED ON? BEQ 1$ ;NO: MAKE SURE WE WEREN'T IN BLOCK ON ; MODE WITH SOMETHING IN THE BUFFER. BIS #40000,SW2(R5) ;INDICATE THAT MACRO PROCESSING CAN ; CONTINUE. JSR R0,READS ;READ IN 1ST BLOCK NOP ;EOF CALL PLINES ;PRINT BUFFER SIZE IF NECESSARY BR LINE1 ;RETURN 1$: BIT R1,R2 ;WERE WE IN BLOCK MODE BEFORE? BEQ LINE1 ;NO: OK THEN. (NOTHING CHANGED) BIS #200,SWITCH(R5) ;DEFINE BLOCK MODE TO EMPTY BUFFER JSR R0,WRITES ;EMPTY BUFFER NOW 2$: BIC #200,SWITCH(R5) ;DISABLE BLOCK MODE LINE1: JMP EDITS ;RETURN .SBTTL TOP (BEGIN) COMMAND ; ;SERVICE TOP(BEGIN) REQUEST ; TOP: BICB #20,SWITCH(R5) ;INDICATE A REGULAR TOP IS REQUESTED TSTB SWITCH(R5) ;IN BLOCK MODE? BPL 3$ ;NO CALLO TOPS ;DO A TOP NOW BR TOP5 3$: BITB #10,SWITCH(R5) ;ARE WE ALREADY AT THE TOP? BEQ TOP5 ;YES: DON'T TOP AGAIN THEN BISB #1,SWITCH+1(R5) ;INDICATE A TOP IS REQUESTED JMP CLOSE ;CLOSE FILE AND THEN REOPEN IT TOP5: JMP EDITS ; .SBTTL OLDPAGE AND TOF MACRO COMMANDS ; ;SERVICE AN OLDPAGE REQUEST ; OLDPAG: JSR R1,GETNUM ;GET ARG (RETURNED IN R0) BMI PRT01 ;NEG. # IS ILLEGAL BR TOF1 ;EXECUTE MACRO NOW ; ;SERVICE A TOF REQUEST (TOP OF FILE) ; TOF: MOV #1,R1 ;TOF ALWAYS READS IN PAGE 1 TOF1: TSTB SWITCH(R5) ;MUST BE IN BLOCK ON MODE BPL TOF2 ;NO: ILLEGAL THEN MOV R1,NARG(R5) ;SAVE MACRO ARG. CALL TESTCC ;MAKE SURE THE STANDARD CONCATENATING ; CHARACTER HAS BEEN DEFINED. MOV #OLDMAC,R0 ;ADDRESS OF OLDPAGE MACRO COMMAND EXECMC: BIS #20,SW2(R5) ;SET MACRO MODE IN PROGRESS JMP EDITS4 ;EXECUTE MACRO NOW TOF2: JMP ILLMOD ;TELL USR OF ERROR ; ;ROUTINE TO TEST IF THE STANDARD CONCATENATING CHARACTER HAS ; BEEN DEFINED, AND IF NOT, DEFINE IT. ; TESTCC: CMPB CATEN(R5),#33 ;IS THE STANDARD CC CHAR DEFINED? BEQ 1$ ;YES .PRINT #CATENM ;TELL USER THAT ITS GETTING ; CHANGED BACK TO THE DEFAULT MOVB #33,CATEN(R5) ; VALUE. 1$: RETURN ;RETURN TO CALLER ; .SBTTL RENEW COMMAND ; ;SERVICE A RENEW REQUEST ; .ENABL LSB RENEW: JSR R1,GETNUM ;GET ARGUMENT (RETURNED IN R1) BPL RENEW1 ;ARG OK PRT01: JMP PRT0 ;NEGATIVE ARGUMENT IS ILLEGAL RENEW1: CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE PUSH R1 ;GET SET TO WRITE AND READ "N" TIMES BIS #40000,SW2(R5) ;INDICATE A RENEW WAS MADE TO ALLOW ; MACRO PROCESSING TO CONTINUE. JSR R0,WRITES ;WRITE OUT CURRENT BUFFER MOV PAGE(R5),NUMBER(R5) ;SAVE CURRENT PAGE # JSR R0,READS ;READ IN A NEW ONE BR 1$ ;EOF RETURN POP R1 ;RESTORE R1 DEC R1 ;ALL DONE? BLE 2$ ;YES: FOUND PAGE WE WERE LOOKING FOR CMP PAGE(R5),NUMBER(R5) ;DID PAGE # GET UPDATED. IF BNE RENEW1 ; NOT, ONLY A PARTIAL PAGE INC R1 ; WAS READ IN. BR RENEW1 2$: MOV PAGE(R5),R0 ;TELL USER WHAT PAGE THIS IS BITB #4,SWITCH+1(R5) ;IF PAGE WAS NOT TERMINATED WITH A FF, BNE 6$ ; INCREMENT PAGE COUNTER SO USER ; SEES THE CORRECT PAGE #. CMP R0,#1 ;EXCEPTION IS PAGE #1 BEQ 6$ INC R0 6$: MOVR #PAGECU,R1 CALL OCTDEC MOVR #PAGECU,R0 ;NULL LEADING ZEROS 4$: CMPB (R0)+,#60 BNE 3$ MOVB #40,-1(R0) BR 4$ 3$: CMPB #40,PAGECU+4(R5) ;IF ENTIRE NUMBER IS NUL, BNE 5$ ; INSERT A ZERO. MOVB #60,PAGECU+4(R5) 5$: MOVR #CPAGE,R0 .PRINT BITB #4,SWITCH+1(R5) ;PRINT NBR OF LINES READ IN BNE 7$ ; IF NOT TERMINATED BY A FF. CALL BUFCHK ;CHECK BUFFER > 7/8 FULL BR 9$ ;YES BR 8$ ;NO 9$: .PRINT #NFULL ;TELL USER THAT BUFFER IS GETTING FULL 8$: MOV SIZELS(R5),R0 ;TELL USER HOW MANY LINES WERE READ IN DEC R0 MOVR #SIZENB,R1 CALL OCTDEC MOVR #SIZEMG,R0 .PRINT 7$: BIT #2,SW2(R5) ;PAGE REQUESTED? BNE PAGE1 ;YES RENEW2: JMP TOP5 ;RETURN 1$: POP R1 ;RESTORE R1; EOF MEANS LAST PAGE BR 2$ ; IS IN. .DSABL LSB ; .SBTTL PAGE COMMAND ; ;SERVICE PAGE REQUEST ; PAGEC: JSR R1,GETNUM ;GET ARGUMENT (RETURNED IN R1) BMI PRT00 ;ILLEGAL PAGE # CALL TSTPG ;TEST FOR PAGE MODE ALLOWED BR 1$ ;NO: IGNORE COMMAND THEN BIS #2,SW2(R5) ;INDICATE A PAGE OPERATION IS ; GOING ON. BISB #200,SWITCH(R5) ;MAKE SURE WE'RE IN BLOCK ON MODE SUB PAGE(R5),R1 ;CALCULATE # OF PAGES FROM HERE BEQ PAGE1 ;WE'RE ALREADY HERE BGT RENEW1 ;USE RENEW NOW TO GET THE DESIRED ; PAGE. .PRINT #ILLPAG ;CAN'T GET TO THIS PAGE, WE'VE ALREADY ; PASSED IT UP. TELL USER TO BIC #20,SW2(R5) ; FORGET REQUEST. BR RENEW2 ;(PREVIOUS INSTR DISABLED MACRO MODE) 1$: JMP EDITS PAGE1: CALLO TOPS ;TOP THE BLOCK BUFFER BIC #2,SW2(R5) ;CLEAR PAGE REQUEST NOW JSR R1,GETNUM ;DO AN NP REQUEST NOW IF IT WAS BMI PRT00 ; SPECIFIED. TST R2 ;IF NONE WAS GIVEN, IGNORE THIS BEQ RENEW2 BIS #1,SW2(R5) ;SET NP REQUEST MOV R2,R0 ;FOR NEXT COMMAND JMP NEXT8 PRT00: JMP PRT0 ; ;TEST FOR PAGE MODE ALLOWED ; TSTPG: TSTB NOPAGE ;PAGE MODE ALLOWED? BEQ 1$ ;YES CALL SETOV2 ;SHOW OVERLAY #2 ACTIVE .PRINT #NOPG ;NO: TELL USER RETURN ;USE ERROR RETURN 1$: ADD #2,(SP) ;SHOW PAGE MODE ALLOWED RETURN .SBTTL READ COMMAND ; ;READ A PAGE FROM INPUT DEVICE INTO BLOCK BUFFER ; READ: JSR R1,GETNUM ;GET ARGUMENT (RETURNED IN R1) BMI PRT00 ;NEGATIVE ARG IS ILLEGAL MOV R1,NUMBER(R5) ;SAVE ARG 1$: JSR R0,READS ;CALL "READ" SUBROUTINE BR 2$ ;EOF ENDS READ DEC NUMBER(R5) ;ALL DONE? BGT 1$ ;NO: GET ANOTHER PAGE IN 2$: BITB #4,SWITCH+1(R5) ;PRINT NBR OF LINES READ IN BNE 3$ ; IF NOT TERMINATED BY A FF. CALL BUFCHK ;CHECK BUFFER > 7/8 FULL BR 5$ ;YES BR 4$ ;NO: PRINT NUMBER OF LINES READ IN 5$: .PRINT #NFULL ;TELL USER THAT BUFFER IS GETTING FULL 4$: MOV SIZELS(R5),R0 ;TELL USER HOW MANY LINES WERE READ IN MOVR #SIZENB,R1 CALL OCTDEC MOVR #SIZEMG,R0 .PRINT 3$: BR RCMDM ;RETURN ; ;READ SUBROUTINE USED BY "READ" AND "RENEW" ; READS: JSR R0,RWON ;MAKE SURE BLOCK ON MODE IS ON BICB #4,SWITCH+1(R5) ;CLEAR FF FOUND ID BISB #2,SWITCH+1(R5) ;INDICATE A BOTTOM IS NEEDED BIS #1000,SW2(R5) ;USED TO TEST FOR EOF WHEN NO LINES ; WERE READ IN. JMP BOTTOM READ3: BIS #4,SW2(R5) ;READ LINE FROM FILE, NOT BLOCK BUFFER ; (BIT IS CLEARED BY "INPUT") CALLO INPUT ;GET A LINE FROM ONE OF THE WORK BUFFERS. JMP READ1 ;EOF RETURN BIC #1000,SW2(R5) ;REMEMBER THAT A LINE WAS READ IN ; FOR THIS PAGE. READ0: CALLO OUTPUT ;INSERT CURRENT LINE INTO BUFFER CALL BUFCHK ;CHECK BUFFER > 7/8 FULL BR READ7 ;YES: TELL USER IF THIS IS THE PAGE ; HE'S LOOKING FOR. PUSH CP(R5) ;SEE IF WE CAN FIT A COMPLETE LINE IN SUB PP(R5),(SP) CMP (SP)+,#LINELN+4 BLOS READ7 ;NO: THAT'S IT THEN TST QUIT(R5) ;PREMATURE TERMINATE DESIRED? BEQ WRITE7 ;YES BITB #4,SWITCH+1(R5) ;PAGE IN? BEQ READ2 ;NO: CONTINUE READ6: INC PAGE(R5) ;INCREMENT PAGE COUNTER READ5: TST (R0)+ ;NON EOF RETURN READ4: CALLO TOPS ;DO A TOP NOW RTS R0 ;RETURN READ1: BIT #1000,SW2(R5) ;ANY LINES READ IN FOR THIS PAGE? BEQ READ6 ;YES: DON'T REPORT EOF YET PUSH R0 ;SAVE R0 .PRINT #MSG13 ;PRINT "EOF" POP R0 ;RESTORE R0 BIC #20,SW2(R5) ;DISABLE MACRO MODE BR READ4 ;TOP BUFFER AND RETURN ON EOF READ2: INC SIZELS(R5) ;N LINES IN YET? CMP SIZELS(R5),SIZEBF(R5) BLE READ3 ;NO: CONTINUE BR READ5 ;DO A TOP NOW READ7: BIT #1000,SW2(R5) ;ANY LINES READ IN? BNE READ5 ;NO: DON'T INCREMENT LINE COUNTER THEN INC SIZELS(R5) ;+1 TO LINE COUNTER BR READ5 ; PLINES: CMP SIZELS(R5),SIZEBF(R5) ;PRINT # OF LINES READ IN IF NOT BLE 1$ ; TERMINATED BY A FF. BITB #4,SWITCH+1(R5) BNE 1$ TSTB SWITCH(R5) BPL 1$ PUSH R0 ;SAVE R0 MOV SIZEBF(R5),R0 ;TELL USER THAT "N" LINES WERE READ IN MOVR #SIZENB,R1 CALL OCTDEC MOVR #SIZEMG,R0 .PRINT POP R0 ;RESTORE R0 1$: RETURN ;RETURN TO CALLER ; .SBTTL WRITE COMMAND ; ;WRITE N LINES FROM BLOCK BUFFER TO OUTPUT DEVICE ; WRITE: JSR R0,WRITES ;CALL "WRITE" SUBROUTINE BR RCMDM ;RETURN WRITE7: TST (SP)+ ;UPDATE STACK JMP RCMD1 RCMDM: JMP EDITS ; ;WRITE SUBROUTINE USED BY "WRITE" AND "RENEW" ; WRITES: JSR R0,RWON ;MAKE SURE BLOCK ON MODE IS ONE CALLO OUTPUT ;INSERT CURRENT LINE INTO BUFFER (NOT ; A DESTRUCTIVE BUFFER WRITE). CALLO TOPS ;DO A TOP FIRST 6$: CALLO INPUT ;GET ANOTHER LINE FROM BLOCK BUFFER JMP 5$ ;END OF BUFFER BIS #4,SW2(R5) CALLO OUTPUT ;OUTPUT LINE TO THE OUTPUT DEVICE. TST QUIT(R5) ;PREMATURE TERMINATE DESIRED? BEQ WRITE7 ;YES BR 6$ ;CONTINUE 5$: BIS #4,SW2(R5) CALLO OUTPUT ;MAKE SURE THE LAST LINE GETS OUT CALLO TOPS ;DO A TOP NOW RTS R0 ;RETURN ; ;READ/WRITE BLOCK MODE TEST ROUTINE ; RWON: TSTB SWITCH(R5) ;MUST BE IN BLOCK MODE BMI RW1 ;OK CMP (SP)+,(SP)+ ;UPDATE STACK JMP ILLMOD ;ILLEGAL BLOCK COMMAND RW1: CLR SIZELS(R5) ;CLEAR PAGE-IN INDICATOR RTS R0 ;RETURN ; .SBTTL END OF PROGRAM STATEMENT ; ; ENDP: ;END OF REMOTE-11 MOV #ENDP,R2 ;RETURN ADDRESS OF ENDP TO INITIALIZATION RETURN ; CODE. ; .END .SBTTL LETVEC V01-003 .TITLE LETVEC V01-003 EDIT=003. ; ; ; PDP-11 RT-11 MULTI-USER LINE TEXT EDITOR VECTOR MODULE ; ; PROGRAM NAME: LETVEC ; ; VERSION LEVEL V01-003 ; ; PATCH LEVEL A ; ; AUTHOR: RICHARD HULLY ; ; DATE: FEB., 1974 ; ; ; COPYRIGHT (C) 1974, 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO ; CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED ; AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ; DEC ASSUMES NO RESPONSIBILITY FOR ANY ERRORS THAT ; MAY APPEAR IN THIS DOCUMENT. ; ; THIS SOFTWARE IS FURNISHED TO PURCHASER UNDER A ; LICENSE FOR USE ON A SINGLE COMPUTER SYSTEM AND ; CAN BE COPIED (WITH INCLUSION OF DEC'S COPYRIGHT ; NOTICE) ONLY FOR USE IN SUCH SYSTEM, EXCEPT AS MAY ; OTHERWISE BE PROVIDED IN WRITING BY DEC. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE ; OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT ; WHICH IS NOT SUPPLIED BY DEC. ; ;--- TTYDEF - MACRO TO DEFINE TTY. ; ; TTYDEF ,,, ; .MACRO TTYDEF SLOT,DEVICE,VECTOR,SATVEC TTVEC'SLOT' = 'VECTOR' TKS'SLOT' = 'DEVICE' TKB'SLOT' = 'DEVICE'+2 TPS'SLOT' = 'DEVICE'+4 TPB'SLOT' = 'DEVICE'+6 DLVEC'SLOT' = 'SATVEC' .GLOBL TTVEC'SLOT',TKS'SLOT',TKB'SLOT',TPS'SLOT',TPB'SLOT' .GLOBL DLVEC'SLOT' .ENDM TTYDEF NOSAT = 0 ;NO SATELLITE CONNECTED ON THIS PORT ; ; ; DEINE TTY1-TTY8 ; TTYDEF 1,177560,60,NOSAT ; TTYDEF 2,175610,400,400 ; TTYDEF 3,175600,410,400 ; TTYDEF 4,175570,420,200 ; TTYDEF 5,175560,430,NOSAT ; TTYDEF 6,175550,440,NOSAT ; TTYDEF 7,175540,450,NOSAT ; TTYDEF 8,175530,460,NOSAT ; .END .TITLE FLET VERSION 01 ; ; PROGRAM TO RETURN TO FOREGROUND EDITOR "LETTER" ; ; WRITTEN BY: RICK HULLY ; ; DATE: DECEMBER 1974 ; ; COPYRIGHT (C) 1974, 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO ; CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED ; AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ; DEC ASSUMES NO RESPONSIBILITY FOR ANY ERRORS THAT ; MAY APPEAR IN THIS DOCUMENT. ; ; THIS SOFTWARE IS FURNISHED TO PURCHASER UNDER A ; LICENSE FOR USE ON A SINGLE COMPUTER SYSTEM AND ; CAN BE COPIED (WITH INCLUSION OF DEC'S COPYRIGHT ; NOTICE) ONLY FOR USE IN SUCH SYSTEM, EXCEPT AS MAY ; OTHERWISE BE PROVIDED IN WRITING BY DEC. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE ; OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT ; WHICH IS NOT SUPPLIED BY DEC. R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 PS=-2 .MCALL ..V2..,.SDATW,.SPND ..V2.. ; ; FLET: .SDATW #AREA,#MESSAG,#1 ;TELL FGD ("LETTER") TO START UP ; THIS USER. 1$: .SPND ;NOTHING ELSE TO DO EXCEPT WAIT FOR BR 1$ ; NEXT USER TO ATTACH AND TYPE ^C. ; AREA: .BLKW 10. MESSAG: .ASCII /GO/ .EVEN ; .END FLET ; PARAMETER FILE FOR REMOTE ASSEMBLY ; ; EMPTY FILE ASSUMES NUSERS=2 ; AND NO CONDITIONALS ARE DEFINED .(R$R E@R. `U@@  1l > 7 7  7 p  2v 2w  x "F T 7j   E@A N  0 n A u "  , є , > X:  v פ"  T7' (   Lw ~  CU@ d h   LE@  w~ "   HnU@7! 7jĝ  E@ l dF   < 7 (6  L    [```t I rXe7 7B :n  n : | D w $\& .  f) b Z JE@w\A 8 4 U@ w   f Eo& T 7O      ! 7P dEB7W  B 7 W  u $ W`< W"W` rv ׀` ` Bv $ e  ev 0E =% % Aa ` e/  2 bs  W A`E   0&, 9̕0 ̕0   & :+5   W 5s E@ E@ ׭* &|E  @EU  T7 N   w  E@ 7  7    D  7eU@ OX e7:7:v׭$     : 6D8 .E@n Dw 5  g SEND ECHOSENDECHODDCMP$UPPESEND&ECHOEXITJDDCMP0UPPERCg LOWERC ENTIRE TEST COMPLETETOTAL # BYTES TRANSMITTED = REMOTE-11 HOST/SATELLITE BYTE TRANSMISSION TEST PROGRAM *** INTERRUPT VECTOR AND UNIBUS ADDRESS SETUP *** SPECIFY IN-HOST VECTOR AND UNIBUS ADDRESSES FOR EXISTING TERMINALS TERMINAL 1 VECTOR ADDRESS = UNIBUS ADDRESS = BEGIN ECHO TEST (TYPE CONTROL-C TO TERMINATE)ECHO TEST TERMINATEDSEND TEST TERMINATEDSPECIFY TEST DESIRED (SEND, ECHO OR DDCMP): INPUT LINE TOO LONG -- PLEASE RETYPE DOWN-LINE LOADING OF TERMINAL COMPLETE BEGINNING TRANSMISSION OF DDCMP MESSAGESPATTERN DESIRED: COUNT: TERMINAL #: ^U ^C255 MESSAGES TRANSMITTED. TEST COMPLETE.TIME-OUT ERROR. TERMINAL #8 NOT RESPONDING.UNABLE TO SEND FURTHER DDCMP MESSAGES. PLEASE RE-BOOT TERMINAL AND TRY AGAIN.MESSAGE # NOT ACCEPTED....RETRANSMITTED.QRSTUVWXYZabcdefghijklmnopqrstuvwxyz?ABCDEFGHIJKLMNOPQRSTABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:/@!"#$%&'()-=][__*+?><^SE@pE@te"ߋtv DDCMP MIRROR-TEST PROGRAM LOADED SUCCESSFULLY $ DDCMP MIRROR-TEST PROGRAM LOADED SUCCESSFULLY $T˫Sū  Tq.}N Tq Tq, zdY F;Tq* zd; SN\( S; pS;@ }.p S\P,T˫SF; vR^*pS;ppjX *SS;  T˫SF;xn.S5 Tq TqvժT,Rvժ  }F; >*vժ S۪ ;S .NTq  Sժ5k,Tq .NLIST TTM .TITLE V2BMAC .SBTTL V001 ; ; MTPS AND MFPS MACROS FOR VERSION 2B ; ; PROGRAM NAME: V2BMAC ; ; VERSION LEVEL: V001 ; ; AUTHOR: HARRY E. KELLER ; ; DATE: 29-OCT-75 ; ; COPYRIGHT (C) 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU- ; SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY OTHER ; COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE ; TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO ; AGREES TO THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE ; SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIBILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; ; THESE MACROS ARE PROVIDED IN V2C ; HOWEVER, SINCE THEY ARE NOT AVAILABLE IN V2B, ; THIS MODULE MUST BE INCLUDED WHEN ASSEMBLING ; RTSIM UNDER V2B ; .MACRO MTPS .ADD MOV .ADD,-(6.) MOV #.+6.,-(6.) RTI .ENDM .MACRO MFPS .ADD .WORD ^O106746 ;MFPS -(6.) MOV (SP)+,.ADD .ENDM .NLIST TTM .TITLE RT-11 SIMULATOR FOR REMOTE-11 .SBTTL RTSIM V01L ; ; REMOTE OBJECT TIME SYSTEM ; ; PROGRAM NAME: RTSIM ; ; VERSION LEVEL: V0001L ; ; AUTHOR: HJ/RRB/RH/HK ; ; DATE: 18-DEC-75 ; ; COPYRIGHT (C) 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU- ; SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY OTHER ; COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE ; TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO ; AGREES TO THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE ; SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIBILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 .SBTTL VECTOR AREA DEFS ; ;THE RTSIM FOR REMOTE CAN BE ASSEMBLED WITH ;A NUMBER OF PARAMETERS TO CHANGE ITS ;FUNCTIONALITY AND SIZE ; ;IF IT IS BEING ASSEMBLED UNDER RT-11/V02B ;AND NOLSI IS NOT DEFINED, THEN V2BMAC.MAC ;MUST BE INCLUDED IN THE ASSEMBLY TO PREVENT ;ASSEMBLY ERRORS AND GUARANTEE LSI-11 ;SUPPORT ; ;THE FOLLOWING PARAMETERS ARE AVAILABLE: ; NODST--.DSTATUS BECOMES UNSUPPORTED ; NOCSI--.CSISPC BECOMES UNSUPPORTED ; NOLSI--LSI-11 FEATURES ARE ELIMINATED ; NORMON--RMON MODULE IS ELIMINATED ; MTRAP--TRAPS WILL OUTPUT MSG ?M-TRAP AT 4 (OR 10) ; .GLOBL VTVEC VTVEC = 320 VT11PC = 172000 .ASECT .=0 JMP @#RTSIM ;0 FOR GETTING STARTED ;2 USED TRAP4: .IF NDF MTRAP .+2 ;4 TIME-OUT ERROR .IFF MTRAP0 .ENDC HALT ;6 TRAP10: .IF NDF MTRAP .-2 ;10 ILLEGAL INSTRUCTION .IFF MTRAP0 .ENDC +1 ;12 CARRY SET .+2 ;14 BREAKPOINT HALT ;16 .+2 ;20 IOT HALT ;22 .+2 ;24 POWER FAIL HALT ;26 EMTER ;30 EMT HANDLER ADDRESS 0 ;32 PS .+2 ;34 TRAP HALT ;36 0 ;40 START ADDRESS OF JOB SET BY OTI .LIMIT ;42,44 INITIAL VALUE OF SP, LOW LIMIT .=.-2 JSW: 0 ;44 JSW .LIMIT ;46,50 MAKE 50 CONTAIN HIGH ADDRESS .=.-4 0 ;46 USR LOAD ADDRESS .=.+2 0 ;52 EMT ERROR CODE ;54 HIGH USABLE CORE ADDRESS - ;FILLED IN BY $XK MODULE .=.+2 0 ;56 FILL CHAR AND COUNT TTYIN ;60 TTY INPUT VECTOR 000 ;62 PS TTYOUT ;64 TTY OUTPUT VECTOR 000 ;66 PS .=100 LKINT ;100 CLOCK INTERRUPT ROUTINE 341 ;102 PR7 WITH CARRY SET .=244 FPPERR ;244 FIS, FPP EXCEPTION TRAP 0 ;246 PS .=VTVEC+10 0 ; VT11 SHIFT OUT VECTOR 0 .SBTTL PROCESS EMT ; .CSECT $RTSIM ; EMTER: MOV R1,-(SP) ;SAVE REGS MOV 2(SP),R1 ;GET PC OF TROUBLE MAKER MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) MOV R0,-(SP) TST (PC)+ ;IS THIS THE FIRST TIME EMT? INIT: .WORD 0 ;FLAG BNE 1$ ;NO MOV @#54,R5 ;YES: INIT TERMINAL MOV #100,@310(R5) MOV #101,@304(R5) MOV SP,INIT ;SET FLAG FOR NOT 1ST TIME 1$: CLR V2 ;ASSUME V1 EMTS MOV -(R1),R1 ;GET EMT INSTRUCTION BIC #EMT,R1 ;REMOVE EMT OPCODE MOV R1,R2 ;COPY REQUEST CODE BIC #177417,R2 ;STRIP OFF CHANNEL BEQ DELJMP ;DELETE CMP #240,R2 ;240 IS A WAIT BEQ NOPS2 ;WHICH IS A NOP TO US CMP R2,#20 ;LOOKUP? BEQ LOKJMP ;YES CMP R2,#40 ;ENTER? BEQ ENTJMP ;YES CMP R2,#200 ;READ? BEQ REDJMP ;YES CMP R2,#220 ;WRITE? BEQ WRIJMP ;YES CMP R2,#160 ;CLOSE? BEQ CLOJMP ;YES SUB #340,R1 ;340 IS LOWEST EMT CODE EMULATED BLT UNSJMP ;LESS THAN 340 IS ERROR CMP #375-340,R1 ;375 IS SPECIAL CASE FOR V2 BEQ EMT375 ;IF 375 GO PROCESS SUBCODE CMP #374-340,R1 ;374 IS ALSO SPECIAL CASE BEQ EMT374 CMP #357-340,R1 ;357 IS HIGHEST CODE HANDLED BLO UNSJMP ;BRANCH IF UNSUPPORTED ASL R1 ;GET WORD INDEX JMP @DISPAT(R1) ;JUMP TO APPROPRIATE ROUTINE DELJMP: JMP DELETE LOKJMP: JMP LOOKUP ENTJMP: JMP ENTER REDJMP: JMP READ WRIJMP: JMP WRITE CLOJMP: JMP CLOSE UNSJMP: JMP UNSUPT DISPAT: .WORD TTYINR ;340 .TTYIN,.TTINR .WORD TTOUTR ;341 .TTYOUT,.TTOUTR .WORD DSTATS ;342 .DSTATUS .WORD NOP1 ;343 .FETCH .WORD UNSJMP ;344 .CSIGEN .WORD CSISPC ;345 .CSISPC .WORD NOP ;346 .LOCK .WORD NOP ;347 .UNLOCK .WORD EXIT ;350 .EXIT .WORD PRINT ;351 .PRINT .WORD SRESET ;352 .SRESET .WORD NOP1 ;353 .QSET .WORD SETTOP ;354 .SETTOP .WORD RCTRLO ;355 .RCTRLO .WORD UNSJMP ;356 .WORD EXIT ;357 HARD RESET (=EXIT) $HRDWR: .WORD 0 FPPERR: CMP $HRDWR,#8. ;DOES FP-11B EXIST? BLO FPPEXT ;NOPE - IT'S FIS STST -(SP) ;ELSE STORE FPU STATUS FPPEXT: JMP @(PC)+ ;JUMP TO INTERRUPT SERVICE FPPSET: .WORD 246 ;HALT IF .SFPA NOT DONE EMT374: MOVB R0,R1 BIC #-20,R1 ;CHANNEL SWAB R0 ;FOR CODE BIC #-400,R0 ;LEAVE IT ONLY ASL R0 SUB #22,R0 ;MAX CODE ALLOWED BGT UNSJMP JMP @DIS374+22(R0) ;EXECUTE EMT DIS374: .WORD NOP ;0 .WAIT .WORD NOP ;1 .SPND .WORD NOP ;2 .RSUM .WORD PURGE ;3 .PURGE .WORD NOP ;4 .SERR .WORD NOP ;5 .HERR .WORD CLOSE ;6 .CLOSE .WORD NOP ;7 .TLOCK .WORD UNSJMP ;10 .CHAIN .WORD NOP ;11 .MWAIT PURGE: JSR PC,CKCHAN BR NOPS2 BR NOPS2 CLRB (R3) ;CHANNEL INACTIVE BR NOPS2 SRESET: CLR CHAN ;PURGE ALL CHANNELS ON SOFT RESET CLR CHAN+2 BR NOPS2 .ENABL LSB EMT375: CMP @R0,#33*400 ;R0 -> ARG BLOCK; IS IT .CNTXSW? BGT UNSJMP ;NO: UNSUPPORTED FUNCTION CMP @R0,#30*400 ;.SFPA ? BGT NOPS2 ;LEGAL ONE TO IGNORE? BNE 1$ ;NO - GO CHECK FOR .GTJB AND .TRPSET MOV 2(R0),FPPSET ;SET FLOATING POINT EXCEPTION ADDRESS NOPS2: JMP NOP LKCSR=177546 LKIV=100 GTIM: MOV @#54,R1 ;GET RMON ADDRESS ADD #322,R1 ;POINT TO TIME WORDS MOV 2(R0),R0 ;GET JOB PARAMETER BLOCK ADDRESS MOV (R1),(R0)+ MOV -(R1),(R0) BR NOPS2 LKINT: MOV R0,-(SP) MOV @#54,R0 ;GET RMON ADDR ADC 320(R0) ;BUMP CLOCK WORD ADC 322(R0) MOV (SP)+,R0 RTI 1$: MOV R0,V2 ;ASSUME V2 EMT'S FOR NOW ADD #4,V2 CMP (R0),#21*400 ;.GTIM? BEQ GTIM ;YES CMP (R0),#3*400 ;.TRPSET, LOOKUP, DELETE, OR ENTER? BGT 2$ ;BRANCH IF NO BEQ 3$ ;.TRPSET MOVB (R0)+,R1 ;NO: GET CHANNEL NBR TSTB (R0) ;LOOKUP, DELETE OR ENTER? BEQ 4$ ;DELETE CLR R2 CMPB (R0)+,#1 ;LOOKUP? BEQ 7$ ;YES MOV #20,R2 ;NO: MUST BE ENTER THEN 7$: MOV R0,V2 ;USE V2 EMT NOW MOV 2(R0),AREA+510. ;SAVE FILE SIZE IF NECESSARY MOV (R0),R0 ;GET ADDESS OF DEVICE BLOCK JMP DELOEN ;PROCESS REQUEST NOW 4$: MOV #-20,R2 ;DELETE TSTB (R0)+ ;BUMP R0 BR 7$ 3$: TST (R0)+ ;POINT TO ARGUMENTS MOV @R0,TRAP4 ;SET TRAP MOV @R0,TRAP10 ; 4 AND 10 JMP NOP UNSJ: JMP UNSUPT 2$: CMPB 1(R0),#6 ;.RENAME, .REOPEN, OR .SAVESTATUS? BLE UNSJ ;YES: NOT SUPPORTED MOVB (R0),R1 ;GET CHANNEL NBR CMPB 1(R0),#7 ;CLOSE? BNE 5$ ;NO JMP CLOSE ;YES: PROCESS IT 5$: CMPB 1(R0),#10 ;READ? BNE 6$ ;NO: TRY FOR WRITE THEN CMP #1,10(R0) ;READC? BLO UNSJ ;YES: NOT ALLOWED MOV 2(R0),R0 ;GET RELATIVE BLOCK NBR JMP READ ;PROCESS READ 6$: CMPB 1(R0),#11 ;WRITE? BNE 8$ ;NO CMP #1,10(R0) ;WRITC? BLO UNSJ ;YES: NOT ALLOWED MOV 2(R0),R0 ;GET RELATIVE BLOCK NBR JMP WRITE ;PROCESS WRITE 8$: CMP #14*400,(R0) BEQ BRNOP CMP (R0),#15*400 ;.CDFN? BEQ UNSJ ;YES: NOT SUPPORTED CMP #20*400,(R0)+ ;.GTJB ? BNE BRNOP ;IF NOT, IT'S A NOP MOV @R0,R0 ;R0 -> 8-WORD PARM BLOCK CLR (R0)+ ;JOB # = 0 (BACKGROUND) MOV @#50,(R0)+ ;HIGH LIMIT SET BY .SETTOP CLR (R0)+ ;LOW LIMIT IS ZERO ON BARE MACHINE BR BRNOP ;IGNORE CHANNEL AREA INFO (UNUSED BY F4) ARG1=20 ;FIRST PASSED ARG ON STACK ARG2=22 ;2ND .DSABL LSB ; RCTRLO: CLR CTRLOF ;TURN ON TTY OUTPUT BRNOP: BR NOP3 .SBTTL .SETTOP,.DSTATUS,MTRAP,.EXIT SETTOP: MOV @#54,R1 ;GET RMON ADDR CMP R1,R0 ;IF REQUESTORS ADDRESS IS LOWER, USE IT BHI 3$ MOV R1,R0 3$: TST -(R0) ;RETURN TOP=TOP-2 MOV R0,@#50 ;SET SETTOP ADDRRESS FOR OTI MOV R0,(SP) ;NOW RETURN R0 CORRECTLY NOP3: JMP NOP .IFDF NODST DSTATS: JMP UNSUPT ;NOT SUPPORTED .IFF DSTATS: CLRB @#52 ;PRESET ERROR RETURN CMP (PC)+,(R0) ;ONLY GOOD IF TTY, LP, DT, DX, ;SY, RK, OR DK .RAD50 /TT / BNE TRYPP ;MIGHT BE PP MOV #4,R2 ;TTY MOV #TTOUTR,R3 ;POSSIBLE ENTRY POINT DS1: MOV ARG1(SP),R1 ;ADDR TO RETURN INFO TO MOV R2,(R1)+ ;FLAG CLR (R1)+ ;SIZE MOV R3,(R1)+ ;POSSIBLE ENTRY POINT CLR @R1 ;DIRECTORY SIZE WORD JMP NOP1 ;SUCESSFUL RETURN WITH 1 ARG ON STACK TRYPP: CMP (PC)+,(R0) ;IS IT PP? .RAD50 /PP / BNE TRYPR ;NO: TRY PR MOV #20010,R2 ;FLAG AS WRITE ONLY, PP BR DS2 TRYPR: CMP (PC)+,(R0) ;IS IT PR? .RAD50 /PR / BNE TRYLP ;NO: TRY LP MOV #40007,R2 ;FLAG AS READ ONLY, PR BR DS2 TRYLP: CMP (PC)+,(R0) ;IS IT LP? .RAD50 /LP / BNE TRYSY ;NO: ONLY DIRECTORIED DEVS LEFT MOV #20003,R2 ;NON FILE, WRITE ONLY, LP DS2: MOV #-2,R3 ;USE I/O PAGE MEMORY FOR ENTRY POINT TO ; HANDLER. I.E., DON'T ALLOW IT. BR DS1 TRYSY: MOV #100000,R2 ;ASSUME DT, DX, SY, RK, OR DK NOW JSR R5,CKDEV ;SY? .RAD50 /SY / BLE DS2 ;YES: OK THEN JSR R5,CKDEV ;DK? .RAD50 /DK / BLE DS2 ;YES JSR R5,CKDEV ;RK? .RAD50 /RK / BLE DS2 INC R2 ;FLAG AS DECTAPE JSR R5,CKDEV .RAD50 /DT / BLE DS2 ADD #21,R2 ;FLAG AS FLOPPY JSR R5,CKDEV .RAD50 /DX / BLE DS2 JMP BADRT1 ;NONE: ERROR THEN ; ; CHECK DEVICE TO SEE IF IT'S LEGAL ; BLE SUCCEEDS IF IT IS ; ARGUMENT IS RAD50 DEV NAME ; CKDEV: MOV (R0),R4 SUB (R5)+,R4 BEQ GOODEV SUB (PC)+,R4 .RAD50 / 0/ BLT BADDEV CMP R4,#7 BLE GOODEV BADDEV: CCC ;INDICATE BAD RETURN GOODEV: RTS R5 ;RETURN .ENDC ;.IFDF NODST REMARG: MOV SP,R2 ;PUSH REGS AND PS DOWN OVER AN ARG ADD #ARG1+2,R2 ;POINT R2 TO ARG1, REMEMBERING RET ADDR MOV R2,R3 ;POINT R3 TO AFTER ARG TST (R3)+ MOV #9.,R4 ;PUSH 9 WORDS DOWN, INCLUDING RET ADDR 1$: MOV -(R2),-(R3) ;PUSH WORD DOWN DEC R4 ;COUNT BNE 1$ ;DO'EM ALL TST (SP)+ ;GET EXTRA WORD OFF TOP OF STACK RESRET: RTS PC ;RETURN .IFDF MTRAP MTRAP0: BCS 1$ ;FROM 10 MOV #"4 ,TRAPA BR 2$ 1$: MOV #"10,TRAPA 2$: MOV #TRAPM,R5 MOV #5,R0 ;5 CHARS IN PC MOV #ADDR+5,R1 ;WILL GO HERE 3$: MOV (SP),R2 ;GET PC BIC #-10,R2 ;LO OCTAL DIGIT ADD #60,R2 ;TO ASCII MOVB R2,-(R1) ;INTO MSG CCC ROR (SP) ;TO NEXT DIGIT ROR (SP) ROR (SP) DEC R0 ;COUNT DOWN BGT 3$ ;MORE TO GO BR MSGOUT ;SEND OUT MSG .ENDC ;IFDF MTRAP EXIT: MOV #STOP,R5 ;OUTPUT A STOP MESSAGE BR MSGOUT ;SEND MESSAGE UNSUPT: MOV #NEEDRT,R5 ;OUTPUT THE BAD NEWS MSGOUT: CLRB @#$CRLF ;CLEAR CR/LF FLAG JSR PC,OSTRNG ;SEND THE MESSAGE MOV @#54,R0 ;RMON ADDRESS MOV 310(R0),R1 ;TPS 1$: BITB #100,(R1) ;WAIT TILL TELEPRINTER IS DONE BNE 1$ RESET MOV @#$START,R1 TST 302(R0) ;SCROLLER HERE? BEQ 2$ ;NO JMP 6(R1) ;YES: DO SEC MODE PROG LOAD 2$: JMP (R1) ;DO ENTER TERMINAL MODE .SBTTL .PRINT,.TTOUTR $START=164 PRINT: MOV R0,R5 ;SAVE ADDR OF STRING IN R5 JSR PC,OSTRNG ;OUTPUT STRING POINTED TO BY R5 BR NOP2 ;RETURN $CRLF = 151 ONE$: TSTB @#$CRLF ;TEST IF LF IS TO ATTACHED TO CR BEQ 1$ ;YES 2$: JSR PC,OUTCHR ;NO: USE DIFFERENT OUTPUT ROUTINE THEN BCS 2$ ;WAIT FOR BUFFER TO EMPTY IF FULL BR OSTRNG 1$: JSR PC,TTIOUT ;OUTPUT CHARACTER AND APPEND LF IF CR IS ; CHARACTER TO BE OUTPUT. OSTRNG: MOVB (R5)+,R0 ;GET NEXT BYTE BGT ONE$ ;GO PUT OUT THE CHARACTER BMI RESRET ;RETURN 1$: MOVB #15,R0 ;SET UP TO DO THE C.R. JMP TTIOUT ;OUTPUT THE C.R. TTOUTR: JSR PC,OUTCHR ;OUTPUT THE CHARACTER IN R0 BCS BADRET ;RING BUFFER FULL NOP2: JMP NOP ;LEAVE ;DDCMP ERROR PROCESSOR DERROR: MOV R1,-(SP) ;SAVE SECONDARY ERROR CODE MOV R0,-(SP) ;SAVE ERROR CODE MOV #2,R2 ;LOOP THRU TWICE MOV #D1,R1 ;ADDRESS OF RESULT 1$: BIC #177707,R0 ;GET HIGH DIGIT ASR R0 ;PUT IN BITS 2, 1, AND 0 ASR R0 ASR R0 ADD #60,R0 MOVB R0,(R1)+ ;PUT INTO MESSAGE BIC #177770,(SP) ;NOW THE 2ND DIGIT ADD #60,(SP) MOVB (SP)+,(R1)+ MOV (SP),R0 ;GET 2ND NUMBER INC R1 ;BUMP PAST "," DEC R2 ;2ND PROCESSED YET? BGT 1$ ;NO: DO IT THEN MOV #DERR,R5 ;PRINT FATAL MESSAGE NOW BR MSGOUT NEEDRT: .ASCIZ /****** A REQUESTED OPERATION NEEDS RT-11/<15> STOP: .ASCIZ <15><12><12><12>/****** STOP/<15> DERR: .ASCII /****** DDCMP ERROR / D1: .BYTE 0,0,', D2: .BYTE 0,0,15,12,0 .IFDF MTRAP TRAPM: .ASCII /?M-TRAP FROM / .EVEN TRAPA: .WORD 0 .BYTE 12,15 ADDR: .BLKB 5 .BYTE 15,12,0 .ENDC ;.IFDF MTRAP .EVEN BADRT1: JSR PC,REMARG ;REMOVE A WORD FROM BOTTOM OF STACK BADRET: BIS #1,16(SP) ;SET CALLERS CARRY BR SKIP NOP1: JSR PC,REMARG ;GET RID OF WORD ON STACK AT BOOTOM ;CLEANS OF UNWANTED ARGS ON STACK NOP: BIC #1,16(SP) ;CLEAR CALLERS CARRY SKIP: MOV (SP)+,R0 MOV (SP)+,R5 ;RESTORE REGS MOV (SP)+,R4 MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 RTI ;RETURN .SBTTL .DELETE,.LOOKUP,.ENTER $SENDDC=162 .ENABL LSB DELETE: LOOKUP: ENTER: SUB #20,R2 ;SAVE EMT CODE (0=LOOKUP, 20 = ENTER) DELOEN: MOV R2,-(SP) ;SAVE ON STACK MOV #AREA,R4 ;GET PTR TO WORK AREA MOV #18.,(R4)+ ;SETUP BYTE COUNT OF LINE MOV #200+6*400+20,(R4)+ ;FILE ACCESS CODE + CHANNEL ID + ; DAP CODE. BIC #177760,R1 ;GET CHANNEL NBR FROM EMT CLRB @#52 ;ASSUME CHANNEL IN USE ERROR JSR PC,CKCHAN ;SEE IF CHANNEL IS ALREADY IN USE BR CERR0 ;YES: SHOW ERROR THEN BR CERR2 ;NO: BUT TABLE IS FULL TST (SP) ;DELETE? BMI 6$ ;YES: DON'T ASSIGN CHANNEL THEN BISB #200,(R3) ;OK: ASSIGN CHANNEL NOW 6$: MOVB R1,(R4)+ ;SAVE RT CHANNEL NBR IN MESSAGE AREA MOVB #10.,(R4)+ ;ASSUME LOOKUP TST (SP) ;WAS IT? BEQ 1$ ;YES BPL 7$ ;NO: ENTER MOVB #4,-1(R4) ;DELETE (4 WILL GET CHANGED TO TO 5 AT ; NEXT INSTRUCTION. 7$: INCB -1(R4) ;NO: MAKE CODE FOR ENTER THEN 1$: JSR PC,UNPACK ;GET DEVICE NAME AND ; CONVERT RAD50 TO ASCII AND STORE. MOVB #':,(R4)+ ;INSERT ":" AFTER DEVICE NAME JSR PC,UNPACK ;NOW FILE NAME JSR PC,UNPACK MOVB #'.,(R4)+ ;INSERT A PERIOD TO SEPARATE FILE NAME ; AND EXTENSION. JSR PC,UNPACK ;NOW DO EXTENSION TST (SP) ;ENTER? BLE 2$ ;NO TST V2 ;YES: V2 EMT? BNE 11$ ;YES MOV ARG1+2(SP),AREA+510. ;NO: GET FILE SIZE FROM CALL 11$: TST AREA+510. ;AREA DEFINED? (V2 VALUE GETS HERE AT EMT ; DECODE TIME). BEQ 2$ ;NO MOVB #'[,(R4)+ ;INSERT SIZE IN FILE SPEC MOV #DECTAB,R2 ;GET TABLE OF OCTAL TO DECIMAL VALUES 13$: MOVB #60,(R4) ;INIT TO ZERO 12$: SUB (R2),AREA+510. ;REMOVE A POWER OF TEN BLT 14$ ;ALL DONE FOR THIS DIGIT INCB (R4) ;MORE TO GO, COUNT IT BR 12$ 14$: ADD (R2)+,AREA+510. ;RESET UNDERFLOW INC R4 ;BUMP TO NEXT POSITION INC AREA ;+1 TO CHAR COUNT IN MESSAGE TST (R2) ;ALL DONE? BNE 13$ ;NO: CONTINUE MOVB #'],(R4)+ ;YES: INSERT CLOSING ] ADD #2,AREA ;ACCOUNT FOR [] IN BYTE COUNT OF MESSAGE 2$: JSR PC,SEND ;SEND MESSAGE OUT TST (SP) ;ENTER, DELETE, OR LOOKUP? BGT 3$ ;ENTER: LOOK FOR "READY FOR INPUT" ; MESSAGE. CMP R1,#10 ;ERROR RETURNED? BEQ 15$ ;YES CMP R1,#2 ;LOOKUP OR DELETE: LOOK FOR STATUS MESSAGE BNE ERR0 ;NO: FATAL ERROR THEN TST (SP) ;LOOKUP OR DELETE? BPL 8$ ;LOOKUP CMPB 1(R0),#1 ;DELETE: LOOK FOR STATUS COMPLETE BEQ NOPS ;YES BR 9$ ;NO: ERROR 15$: CMPB 1(R0),#33. ;FILE NOT FOUND? BEQ 9$ ;YES: SET ERROR BR ERR0 ;NO: UNEXPECTED MESSAGE RETURNED 8$: CMPB 1(R0),#2 ;ACCESS ACK? BEQ NOPS ;YES: ALL DONE 9$: INC @#52 ;NO: FILE NOT FOUND, SHOW ERROR TO ; USER THEN. TST (SP)+ ;CLEAN UP STACK 4$: JMP BADRET 3$: CMPB #4,R1 ;"ACKNOWLEDGE REQUEST" MESSAGE? BNE ERR0 ;NO: FATAL ERROR THEN TST (SP)+ ;CLEAN UP STACK TST V2 ;V2 EMT? BNE 16$ ;YES: NOTHING TO CLEAN UP ON STACK REMOV1: JSR PC,REMARG ;REMOVE ARG FROM STACK BR 16$ NOPS: TST (SP)+ ;CLEAN UP STACK 16$: JMP NOP ;RETURN ERR0: CLR R0 ;SHOW FATAL DDCMP ERROR (UNEXPECTED BR DERR1 ; MESSAGE RETURNED). CERR0: TST (SP)+ ;CLEAN UP STACK (CHANNEL IN USE ERROR) BLE 4$ ;LOOKUP OR DELETE DONE TST V2 ;V2 EMT? BNE 4$ ;YES JSR PC,REMARG ;NO: REMOVE ARG FROM STACK THEN BR 4$ CERR2: MOVB #2,R0 ;CHANNEL TABLE FULL ERROR CLR R1 BR DERR1 .DSABL LSB .SBTTL SEND .ENABL LSB ; SEND: MOV #8.,-(SP) ;ALLOW UP TO 8 RETRIES ON CRC ERRORS 1$: MOV #AREA,R5 ;NOW SEND OUT MESSAGE CLR R2 ;NO COMPLETION ROUTINE JSR PC,@$SENDDC MOV @#$SENDDC,R0 ;CALC ADDR OF RECDDC SUB #62,R0 MOV #-9.,R4 ;SET UP CALL TO RECDDC CLR R3 CLR R2 ;WITHOUT COMPL ROUTINE JSR PC,(R0) MOV @#154,R0 ;GET BUFFER POINTER TST -4(R0) ;MESSAGE IN? BEQ .-4 ;NO: WAIT TILL IT IS THEN BMI 2$ ;ERROR: RESEND MESSAGE CMP (R0)+,(R0)+ ;SEE WHAT KIND OF MESSAGE RETURNED CMPB (R0)+,#20 ;MUST BE DAP MESSAGE BNE ERR4 ;NO: FATAL ERROR MOVB (R0)+,R1 ;GET OPERATOR CODE BPL ERR3 ;ILLEGAL WITHOUT CHANNEL ID (FATAL ERROR) BIC #177600,R1 ;REMOVE GARBAGE TST (SP)+ ;CLEAN UP STACK RTS PC ;RETURN TO CALLER ; 2$: DEC (SP) ;CRC ERROR, REQUEST MESSAGE AGAIN BGT 1$ ;MORE TRIES TO GO (8 MAX ALLOWED) MOV #1,R0 ;FATAL NOW, RECEIVED MESSAGED IN ERROR 3$: CLR R1 DERR1: JMP DERROR ; MORE THAN 8 CONSECUTIVE TIMES. ERR3: MOV #3,R0 ;MSG W/O CHAN NBR IS ILLEGAL BR 3$ ERR4: MOV R0,R1 ;MSG NOT DAP MOV #4,R0 BR DERR1 .DSABL LSB .SBTTL .READ,.READW ; .ENABL LSB READ: MOV #AREA,R4 ;REQUEST INPUT MOV #8.,(R4)+ ;BYTE COUNT OF MESSAGE MOV #200+4*400+20,(R4)+ ;FILE ACCESS CODE + CHANNEL ID + DAP ; CODE. BIC #177760,R1 ;GET CHANNEL NBR FROM EMT MOVB #2,@#52 ;ASSUME CHANNEL NOT OPEN IF ERROR OCCURS JSR PC,CKCHAN ;CHECK IF CHANNEL HAS BEEN ASSIGNED BR 8$ ;CHANNEL IS ASSIGNED AND OK BR READ6 ;ERROR BR READ6 ;ERROR 8$: MOVB R1,(R4)+ ;SAVE IN MESSAGE MOV R1,-(SP) ;ALSO SAVE FOR LATER TEST MOVB #2,(R4)+ ;REQUEST RECORD MOVB R0,(R4)+ ;INSERT BLOCK NBR DESIRED SWAB R0 MOVB R0,(R4)+ CLR (R4)+ ;(M.S. OF BLOCK NBR.) 1$: JSR PC,SEND ;SEND AND WAIT MOV (SP)+,R2 ;PICK UP CHANNEL NUMBER CLRB @#52 ;ASSUME EOF ERROR IF ERROR OCCURS CMPB R1,#1 ;DID WE GET INPUT? BNE 3$ ;NO: COULD BE EOF CMPB (R0)+,R2 ;IS CHANNEL OK? BNE READ7 ;NO: ERROR ADD #4,R0 MOV #512.,R2 ;TRANSFER 512 BYTES TST V2 ;V2 EMT? BNE 5$ ;YES: GET DATA BUFFER ADDRESS FROM ; DESCRIPTOR BLOCK. MOV ARG1(SP),R1 ;WHERE DATA WILL BE PUT 2$: MOVB (R0)+,(R1)+ ;TRANSFER DATA TO USER DEC R2 BGT 2$ TST V2 ;V2 EMT? BNE NOPS1 ;YES: STACK OK SO EXIT IMMEDIATELY BR WRIDNE ;REMOVE ARGS AND EXIT 3$: CMPB R1,#2 ;STATUS BLOCK RETURNED? BNE READ7 ;NO: UNEXPECTED MESSAGE RETURNED CLRB @#52 ;SHOW EOF AS THE ERROR READ6: TST V2 ;V2 EMT? BNE 4$ ;YES: LEAVE STACK ALONE AND REPORT ERROR JSR PC,REMARG ;REMOVE ARGS AND SET CALLERS CARRY JSR PC,REMARG ; INDICATING FAILURE. JMP BADRT1 4$: JMP BADRET ;RETURN SHOWING ERROR IN CARRY BIT 5$: MOV @V2,R1 ;GET BUFFER ADDRESS BR 2$ READ7: CLR R0 ;UNEXPECTED MESSAGE RETURNED ; JMP DERROR .DSABL LSB .SBTTL .WRITE,.WRITW .ENABL LSB ; WRITE: MOV #AREA,R4 ;GET PTR TO WORK AREA MOV #512.+7,(R4)+ ;SETUP BYTE COUNT MOV #200+1*400+20,(R4)+ ;FILE ACCESS CODE + CHANNEL ID + DAP ; CODE. BIC #177760,R1 ;GET CHANNEL NBR FROM EMT MOVB #2,@#52 ;ASSUME CHANNEL NOT OPEN IF ERROR OCCURS JSR PC,CKCHAN ;CHECK IF CHANNEL HAS BEEN ASSIGNED AND OK BR 5$ ;OK BR READ6 ;ERROR BR READ6 ;ERROR 5$: MOVB R1,(R4)+ ;INSERT IN MESSAGE MOVB R0,(R4)+ ;INSERT BLOCK NBR DESIRED SWAB R0 MOVB R0,(R4)+ CLRB (R4)+ ;(M.S. OF BLOCK NBR.) CLRB (R4)+ MOV #512.,R0 ;NOW MOVE 512 BYTES TO WORK AREA TST V2 ;V2 EMT? BNE 3$ ;YES MOV ARG1(SP),R2 ;WHERE DATA IS 1$: MOVB (R2)+,(R4)+ DEC R0 BGT 1$ MOV R1,-(SP) ;SAVE CHANNEL # FOR LATER TEST JSR PC,SEND ;SEND OUT LINE MOV (SP)+,R2 ;PICK UP CHANNEL NUMBER FROM BEFORE CMPB #4,R1 ;DID HE GET LINE OK? BNE READ7 ;NO: UNEXPECTED MESSAGE RETURNED CMPB (R0)+,R2 ;IS CHANNEL NUMBER OK? BNE READ7 ;NO TST V2 ;V2 EMT? BNE NOPS1 ;YES: EXIT WITHOUT DIDDLING STACK WRIDNE: JSR PC,REMARG ;REMOVE 3 ARGS FROM STACK JSR PC,REMARG JMP REMOV1 3$: MOV @V2,R2 ;GET DATA BUFFER ADDRESS BR 1$ ; .DSABL LSB ; .SBTTL .CLOSE .ENABL LSB CLOSE: MOV #AREA,R4 ;REQUEST FILE CLOSE MOV #4,(R4)+ ;BYTE COUNT OF MESSAGE MOV #200+2*400+20,(R4)+ ;FILE ACCESS CODE + CHANNEL ID + DAP ; CODE. BIC #177760,R1 ;GET CHANNEL NBR FROM EMT JSR PC,CKCHAN ;CHECK IF CHANNEL IS IN USE BR 1$ ;YES: CLOSE IT THEN BR NOPS1 ;NO: IGNORE THEN BR NOPS1 ;NO: IGNORE THEN 1$: CLRB (R3) ;CLOSE CHANNEL MOVB R1,(R4)+ ;INSERT IN MESSAGE MOVB #1,(R4) ;SHOW EOF JSR PC,SEND ;SEND AND WAIT CMP R1,#2 ;ACK MESSAGE? BNE 2$ ;NO: UNEXPECTED MESSAGE CMPB 1(R0),#1 ;ACK? BNE 2$ ;NO: UNEXPECTED MESSAGE NOPS1: JMP NOP ;EXIT 2$: JMP READ7 ;SHOW UNEXPECTED MESSAGE ERROR .DSABL LSB .SBTTL .CSISPC ; ; DONE CODE IS FIRST ; .IFDF NOCSI CSISPC: JMP UNSUPT ;NOT SUPPORTED .IFF CSIDN: CLR ARG2+2(SP) ;SHOW NO SWITCHES WERE SPECIFIED JSR PC,REMARG ;REMOVE ARGS AND EXIT JSR PC,REMARG JMP NOP1 ; CSISPC: CLR INOUT ;SHOW WE'RE DOING OUT SPECS MOV ARG2+2(SP),R4 ;GET POINTER TO OUTPUT AREA MOV ARG1(SP),R0 ;GET POINTER TO ASCIZ STRING 1$: CMPB (R0),#'= ;LOOK FOR = IN STRING BEQ 2$ ;FOUND IT: NORMAL STRING CMPB (R0)+,#40 ;ANY CTRL CHAR TERMINATES STRING BGE 1$ ;KEEP LOOKING MOV #3,INOUT ;NO =: SO INPUT ONLY MOV #15.,R1 ;ZERO OUT OUT SPECS 3$: CLR (R4)+ DEC R1 BGT 3$ 2$: MOV ARG1(SP),R0 ;RESET R0 BR CSISP3 CSISP1: TST (R4)+ CSISP3: MOV R0,ARG1(SP) ;RESET POINTER TO CURRENT STRING INC INOUT ;FILE SPEC COUNT CMP INOUT,#9. BGT CSIDN ;DONE MOV R4,R1 ;OUTPUT AREA PTR BNE 4$ ;NOT TERMINAL MOV (PC)+,(R1)+ ;USE TT: .RAD50 /TT / MOV #38.,R0 ;FILL REMAINDER WITH 0 3$: CLR (R1)+ DEC R0 BGT 3$ BR CSIDN 4$: CLR (R1) ;INIT RAD50 AREA MOV #3,R2 ;MAX 3 CHARS DEV NAME 1$: MOVB (R0)+,R3 ;GET NEXT CHAR BEQ DEFDEV ;NULL BEFORE : MEANS DEFAULT CMPB #':,R3 ;COLON? BEQ 2$ ;YES DEC R2 ;COUNT DOWN BMI DEFDEV ;4 CHARS NOT ALLOWED BR 5$ ;NEXT CHAR 2$: DEC R2 ;HAVE COLON--IS WORD FILLED? BMI FILENA ;YES CLR R3 ;NO-USE NULL AS FILLER DEC R0 ;BACKUP POINTER 5$: JSR PC,RAD50 ;PUT NEXT CHAR (R3) INTO OUTPUT AREA BR 1$ DEFDEV: MOV (PC)+,(R1) ;USE "SY" FOR DEVICE .RAD50 /SY / MOV ARG1(SP),R0 ;RESET FOR FILENAME SEARCH .ENABL LSB FILENA: TST (R1)+ ;POINT TO NEXT WORD CLR (R1) ;INIT RAD50 WORK AREA MOV #6.,R2 ;ALLOW MAX OF 6 CHARS FOR FILE NAME 4$: MOVB (R0)+,R3 ;END OF STRING? BEQ 1$ ;YES: FILL WITH NULLS CMPB R3,#'[ ;SQUARE BRACKETS? BEQ 9$ ;YES CMPB R3,#', ;COMMA? BEQ 9$ ;YES CMPB R3,#'= ;EQUALS? BEQ 9$ ;YES CMPB R3,#'. ;PERIOD? BNE 2$ ;NO: USE CHAR AS IS THEN 9$: CLR R3 ;MAP INTO NULL NOW 1$: DEC R0 ;BACKUP POINTER 2$: JSR PC,RAD50 ;CONVERT TO RAD50 AND STORE CMP R2,#4 ;HAVE WE PROCESSED EXACTLY 3 CHARACTERS? BNE 3$ ;NO TST (R1)+ ;YES: USE 2ND WORD NOW CLR (R1) 3$: DEC R2 ;ALL DONE? BGT 4$ ;NO TST (R1)+ CLR (R1) MOV #3,R2 ;NOW DO EXTENSION IF IT EXISTS CMPB (R0)+,#'. BEQ 5$ ;YES MOV @ARG2(SP),(R1) ;USE DEFAULT EXTENSION DEC R0 BR 6$ ; CSISP2: MOVB -1(R0),R3 ;NULL TERMINATOR? BEQ 8$ ;YES CMPB R3,#'= ;WAS TERMINATOR A =? BNE CSISP1 ;NO CMP INOUT,#3 ;WAS THIS 1ST OR 2ND OUT SPEC? BGT CSISP1 ;NO 8$: DEC R0 ;YES: INSURE THAT UNUSED FIELDS ARE NULL BR CSISP1 ; 5$: MOVB (R0)+,R3 ;DO EXTENSION NOW BEQ 11$ ;NULL IS END OF LINE CMPB R3,#'[ ;SQUARE BRACKETS? BEQ 10$ ;YES CMPB R3,', ;COMMA? BEQ 10$ ;YES CMPB R3,'= ;EQUALS? BEQ 10$ ;YES CMPB R3,#15 ;CR? BNE 7$ ;NO 10$: CLR R3 ;FILL WITH NULLS IF THATS IT 11$: DEC R0 7$: JSR PC,RAD50 ;CONVERT TO RAD50 DEC R2 ;ALL DONE? BGT 5$ ;NO: CONTINUE 6$: MOV R1,R4 ;REMEMBER WHERE WE ARE CMP INOUT,#3 ;PROCESSING IN OR OUT SPECS? BGT CSISP1 ;INPUT TST (R1)+ ;OUTPUT: GET SIZE SPEC ADD #2,ARG2(SP) ;BUMP DEFAULT EXT PTR CLR (R1) ;SHOW THAT NO SPACE WAS REQUESTED MOV R1,R4 MOVB (R0)+,R3 CMPB R3,#'[ ;WAS SPACE REQUESTED? BNE CSISP2 ;NO 12$: MOVB (R0)+,R3 ;YES: GET CHAR BEQ CSISP2 ;THAT'S IT CMPB R3,#'] ;CLOSING BRACKET? BEQ CSISP2 ;YES CMPB R3,#15 ;CR? BEQ CSISP2 ;YES SUB #60,R3 ;NO: CONVERT TO OCTAL DIGIT BLT CSISP2 ;ILLEGAL DIGIT, QUIT THEN CMPB R3,#7 ;CHECK HIGH END BGT CSISP2 ;OUT OF BOUNDS, QUIT TST (R1)+ ;MULTIPLY PREVIOUS NBR BY 8. CCC ROL (R1) ROL (R1) ROL (R1) ADD R3,(R1) ;ADD IN NEW DIGIT BR 12$ ;DO NEXT DIGIT INOUT: .WORD 0 .ENDC ;.IFDF NOCSI .DSABL LSB ; .SBTTL UNPACK ; ; UNPACK RAD50 TO ASCII ; ; CALLING SEQUENCE: ; ; (R0) ;NAME - .RAD50/XXX/ ; MOV AREA,R4 ;WHERE TO PUT RESULT ; JSR PC,UNPACK ; UNPACK: MOV (R0)+,R3 ;GET RAD50 WORD MOV R0,-(SP) ;SAVE R0 CLR R0 2$: SUB #3100,R3 BLO 3$ INC R0 BR 2$ 3$: ADD #3100,R3 ;RESTORE UNDERFLOW CMP R0,#36 ;DIGIT? BLT 6$ ;NO ADD #22-100,R0 ;YES: CONVERT TO ASCII DIGIT THEN 6$: TST R0 ;IF ZERO, SUBSTITUTE A NULL BEQ .+6 ADD #100,R0 ;MAKE IT ASCII MOVB R0,(R4)+ ;SAVE 1ST CHAR IN OUTPUT AREA CLR R0 ;NOW DO 2ND AND 3RD 4$: SUB #50,R3 ;DIVIDE BY 50 BMI 5$ INC R0 BR 4$ 5$: ADD #50,R3 ;RESTORE UNDERFLOW CMP R0,#36 ;DIGIT? BLT 7$ ;NO ADD #22-100,R0 ;YES: CONVERT TO ASCII DIGIT THEN 7$: TST R3 BEQ 8$ ;IF ZERO, SUBSTITUTE A NULL ADD #100,R3 ;CONVERT TO ASCII CMP R3,#136 ;DIGIT? BLT 8$ ;NO ADD #22-100,R3 ;YES: CONVERT TO ASCII DIGIT THEN 8$: TST R0 ;IF 2ND CHAR IS ZERO, CONVERT IT TO A BEQ .+6 ; NULL. ADD #100,R0 MOVB R0,(R4)+ ;SAVE 2ND CHAR MOVB R3,(R4)+ ;SAVE 3RD CHAR MOV (SP)+,R0 ;RESTORE R0 RTS PC ;RETURN ; .SBTTL RAD50 ; ; CONVERT CHAR IN R3 TO RAD50 AND MULTIPLY PREVIOUS CHARS BY 50(8) ; RAD50: ASL (R1) ;*2 ASL (R1) ;*4 ASL (R1) ;*8 MOV (R1),-(SP) ;SAVE TEMP ASL (R1) ;*16 ASL (R1) ;*32 ADD (SP)+,(R1) ;*40(10) = *50(8) BIC #300,R3 ;CONVERT CHAR TO RAD50 BEQ 1$ ;NULL CHAR CMP R3,#71 ;WAS IT LEGAL? BGT 1$ ;NO: CONVERT TO NULL CMP R3,#60 ;COULD BE A DIGIT BGE 2$ ;YES CMP R3,#32 ;WAS IT A LETTER? BLE 3$ ;YES; CHAR OK AS IS THEN 1$: CLR R3 ;CONVERT CHAR TO A NULL BR 3$ 2$: SUB #60-36,R3 ;CONVERT NBRS FROM 60-71 TO 36-47 3$: ADD R3,(R1) ;ADD CHAR TO ACCUMULATED RESULT RTS PC ;RETURN ; .SBTTL CKCHAN ; ; CHECK CHANNEL NBR ; CKCHAN: MOV #CHAN,R3 ;POINT TO CHANNEL NBR TABLE MOV R2,-(SP) ;SAVE R2 AND R4 MOV R4,-(SP) MOV #4,-(SP) ;SCAN ONLY 4 CHANNELS 1$: MOVB (R3)+,R2 ;RT-11 CHANNEL ASSIGNED? BPL 2$ ;NO: LOOK AT NEXT ENTRY BIC #177600,R2 ;YES: REMOVE GARBAGE AND TEST FOR MATCH CMPB R2,R1 ;MATCH? BEQ 7$ ;YES: USE "MATCH RETURN" 2$: DEC (SP) ;NO: LOOK AT NEXT USER BGT 1$ ;MORE: CONTINUE MOV #4,(SP) ;NO MATCH: LOOK FOR 1ST EMPTY SLOT THEN MOV #CHAN,R3 3$: TSTB (R3)+ ;CHANNEL ASSIGNED? BPL 4$ ;NO: RETURN THIS TO USER THEN DEC (SP) ;LOOK AT NEXT USER BGT 3$ ;MORE: CONTINUE BR 6$ ;ALL CHANNELS IN USE AND NO MATCH ON ; REQUESTED CHANNEL. 4$: MOVB R1,-1(R3) ;SET CHANNEL NBR IN TABLE BUT DON'T ; DEFINE IT JUST YET. 5$: ADD #2,6(SP) ;BUMP RETURN 6$: ADD #2,6(SP) ;BUMP RETURN 7$: TST (SP)+ ;CLEAN UP STACK MOV (SP)+,R4 ;RESTORE R4 AND R2 MOV (SP)+,R2 DEC R3 ;POINT R3 TO RIGHT SLOT MOV R3,R1 ;CONVERT CHANNEL NBR TO RT-11 CHANNEL SUB #CHAN,R1 RTS PC ;RETURN TO CALLER ; .SBTTL TTY INPUT INTERRUPT HANDLER .ENABL LSB TTYIN: MOV R1,-(SP) ;SAVE THE REGISTERS MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) MOV R0,-(SP) MOV @#54,R0 ;RMON ADDRESS MOV 306(R0),R0 ;TKB MOVB (R0),R0 ;GET INPUT CHAR BIC #177600,R0 ;GET RID OF PARITY BEQ HERE ;IGNORE NULLS CMP R0,#141 ;BE KIND AND CAPITALIZE ALL CHARS BLT 1$ ;BRANCH IF CHAR LOWER THAN LOWERS CMP R0,#172 ;CHECK UPPER RANGE OF LOWER CASE BGT 1$ ;BRANCH IF CHAR GREATER THAN LOWERS SUB #40,R0 ;MAPPING FUNCTION TO UPPER CASE 1$: MOV #IEMPT,R3 ;INIT IN POINTER MOV #SPEC,R1 ;GET ADDRESS OF SEARCH LIST 2$: MOVB (R1)+,R2 ;GET OFFSET OF ROUTINE BEQ NORMAL ;0 MEANS END OF LIST CMPB (R1)+,R0 ;IS THIS A MAGIC CHARACTER BNE 2$ ;LOOP THROUGH THE LIST BIC #177400,R2 ;REMOVE GARBAGE JMP HERE(R2) ;GO TO HANDLER 3$: MOV #IBUF,-(R3) ;RESET TO BEGINNING OF BUFFER NORMAL: TSTB @(R3)+ ;SEE IF NEXT SLOT EMPTY BEQ 5$ ;BRANCH IF IT IS BMI 3$ ;HIT END OF RING, RESET POINTER MOV #7,R0 ;SET BELL CHAR BR OUTIT ;LET'EM KNOW RING FULL T5: TST (R3)+ 5$: MOVB R0,@-(R3) ;PUT CHAR INTO BUFFER INC CCOUNT ;COUNT CHARACTER TST RUBFLG ;SEE IF WE'RE IN A RUBOUT SEQUENCE BEQ 4$ ;BRANCH IF NOT JSR PC,TBSLSH ;HIT'EM WITH A \ MOVB @0(R3),R0 ;RESTORE THE CHAR 4$: INC @R3 ;BUMP THE RING POINTER TMODE: BIT #10000,@#JSW ;TTY SPECIAL MODE? BNE HERE1 ;YES: SKIP ECHO THEN OUTIT: JSR PC,TTIOUT ;OUTPUT THE CHAR IN R0 HERE: JMP SKIP ;RETURN FROM INTERUPT HERE1: CMPB #15,R0 ;CR? BNE HERE ;NO SUB #3,R0 ;YES: MAP INTO LF AND INSERT INTO BUFFER BR NORMAL .DSABL LSB ALT: BIT #10000,@#JSW ;SPECIAL TTY MODE? BNE NORMAL ;YES: DON'T DO CONVERSION THEN MOV #33,R0 ;MAKE ALL ALTMODES LOOK ALIKE BR NORMAL CR: BIT #10000,@#JSW ;SPECIAL TTY MODE? BNE NORMAL ;YES: SKIP LINE COUNTING INC LINCNT ;A FULL LINE HAS BEEN COLLECTED BR NORMAL ;PUT IT IN INPUT BUFFER CTRLS: MOV SP,STOPO ;SET ^S FLAG BR HERE ;EXIT CTRLQ: CLR STOPO ;CLEAR ^S STATE MOV @#54,R0 ;RMON ADDRESS CLR @310(R0) ;CLEAR STATUS SO RESET WILL CAUSE INT MOV #100,(R0) ;RESET INTERRUPT FLAG BR HERE ;EXIT CTRLO: COM CTRLOF ;INVERT CONTROL O FLAG BR OUTIT RUBOUT: BIT #10000,@#JSW ;TTY SPECIAL MODE? BNE T5 ;YES: LET USER HANDLE IT JSR PC,BACKUP ;BACKUP UP A CHAR IF POSSIBLE BEQ CRLF ;BRANCH IF NOT TST RUBFLG ;ARE WE IN A RUBOUT SEQUENCE? BNE 1$ ;BRANCH IF YES JSR PC,TBSLSH ;OUTPUT A \ 1$: MOVB R4,R0 ;R4 CONTAINS REMOVED CHAR BR OUTIT ;ECHO IT CTRLU: BIT #10000,@#JSW ;TTY SPECIAL MODE? BNE T5 ;YES: LET USER HANDLE IT JSR PC,TTIOUT ;SEND THE ^U 1$: JSR PC,BACKUP ;BACKUP A CHAR BNE 1$ ;GET BACK TO BEGINING OF LINE CRLF: TST (PC)+ ;TEST RUBFLG RUBFLG: .WORD 0 ;INITIAL VALUE OF RUBFLG BEQ 1$ ;BRANCH IF NOT IN RUBOUT SEQUENCE JSR PC,TBSLSH ;OUTPUT A \ 1$: MOVB #15,R0 ;SET UP TO SEND A C.R. BR TMODE ;SEND IT CTRLC: JSR PC,TTIOUT ;ECHO ZEE ^C JMP EXIT ;PERFORM AN EXIT .ENABL LSB TTYINR: BIT #10000,@#JSW ;TTY SPECIAL MODE? BNE 5$ ;YES TST (PC)+ ;NO: SEE IF A LINE IS READY LINCNT: .WORD 0 ;NUMBER OF AVAILABLE LINES BEQ 4$ ;NO CHARS AVAILABLE YET MOV #ICR,R3 ;GET ADDR OF INTERSECTING POINTERS TST (R3)+ ;DID WE JUST GIVE BACK A C.R.? BEQ 1$ ;BRANCH IF NOT CLR -(R3) ;RESET C.R. FLAG DEC LINCNT ;REDUCE NUMBER OF FULL LINES MOV #12,R0 ;SET UP TO RETURN A L.F. BR 3$ ;RETURN IT 2$: MOV #IBUF,-(R3) ;RESET RING POINTER 1$: MOVB @(R3)+,R0 ;GET A CHAR OUT OF RING BUFFER BMI 2$ ;WE'RE WRAPPING AROUND CLRB @-(R3) ;EMPTIFY POSITION INC @R3 ;BUMP POINTER CMPB #15,R0 ;SEE IF LINE TERMINATOR BNE 3$ ;BRANCH IF NOT BIT #10000,@#JSW ;TTY SPECIAL MODE? BNE 3$ ;YES INC -(R3) ;SET C.R. FLAG 3$: MOV R0,@SP ;RETURN CHAR IN R0 JMP NOP ;GIVE SUCESSFUL RETURN 4$: JMP BADRET 5$: MOV #ICR+2,R3 ;SETUP BUFFER DESCRIPTOR POINTER TST CCOUNT ;ANY CHARACTERS TO GET? BEQ 4$ ;NO DEC CCOUNT ;YES: GET ONE BR 1$ .DSABL LSB WRAPA: MOV #IBUFEND,@R3 ;RESET RING POINTER TO END BACKUP: MOV @R3,R2 ;GET ADDRESS OF NEXT SLOT MOVB -(R2),R4 ;GET CHAR INTO R4 BMI WRAPA ;BACKED INTO BEGINING OF BUFFER BEQ 1$ ;NOTHING IN BUFFER CMPB #15,R0 ;DID WE BACK INTO A C.R. BEQ 1$ ;BRANCH IF SO CLRB @R2 ;REMOVE CHAR FROM BUFFER DEC @R3 ;MOVE EMPTY BACK 1 1$: RTS PC ;RETURN TBSLSH: COM RUBFLG ;INVERT RUBFLG MOVB #'\,R0 ;SET UP \ ;SEND IT AND RETURN TTIOUT: MOV R0,-(SP) ;SAVE CHAR TO SEND 1$: JSR PC,OUTCHR ;INSERT IT INTO OUTPUT RING BCS 1$ ;WAIT UNTIL IT FITS SUB #3,R0 ;CHECK FOR A C.R. CMP #12,R0 ;ARE WE TO SEND A L.F. BEQ 1$ ;YES: SEND IT THEN MOV (SP)+,R0 ;RESTORE ORIGINAL CHAR RTS PC ;RETURN .SBTTL TTY OUTPUT INTERRUPT HANDLER ; TTYOUT: MOV R1,-(SP) ;SAVE THE REGISTERS MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) MOV R5,-(SP) MOV R0,-(SP) MOV @#54,R3 ;RMON ADDRESS MOV 310(R3),R4 ;TPS MOV 312(R3),R3 ;TPB TST (PC)+ ;SEE IF ^S IS IN EFFECT STOPO: .WORD 0 ;0 MEANS NO BNE SKIP1 ;BRANCH IF IT IS MOV #OCNT,R5 ;GET ADDRESS OF INTERESTING OUTPUT INFO NOTYPE: TST (R5)+ ;SEE IF ANY CHARS LEFT IN RING BNE 2$ ;BRANCH IF SOME LEFT CLR (R4) ;CLEAR INT SO NEW CHAR CAN CAUSE ONE BR SKIP1 ;LEAVE 2$: MOVB @(R5)+,R0 ;GET NEXT CHAR BPL 1$ ;A REAL CHAR MOV #OBUF,-(R5) ;RESET RING POINTER WHEN WE HIT END BR 2$ ;TRY AGAIN 1$: INC -(R5) ;BUMP POINTER DEC -(R5) ;DECREMENT CHAR COUNT TST (PC)+ ;SEE IF CONTROL O ON CTRLOF: .WORD 0 ;0 MEANS TYPE BNE NOTYPE ;BRANCH TO CLEAR OUT RING BUFFER MOVB R0,(R3) ;STICK NEW CHARACTER INTO TTY OUTPUT SKIP1: JMP SKIP ;RETURN .ENABL LSB OUTCHR: MOV #OCNT,R1 ;GET ADDRESS OF OUTPUT POINTERS CMP #,@R1 ;SEE IF BUUFER FULL? BLO NOTRDY ;C IS SET IF BRANCH OCCURS(BUFFER FULL) BIC #177600,R0 ;GETRID OF PARITY MOV R0,-(SP) ;SAVE THE CHAR BEQ 1$ ;OUTPUT NULLS AS IS CMPB #33,R0 ;CHECK TYPE OF CHAR BEQ 2$ ;BRANCH IF ALTMODE BLT 6$ ;CHAR IS REGULAR 1 SPACE TYPE CMP #7,R0 ;IS IT BELL? BEQ 1$ ;OUTPUT AS IS CMP #15,R0 ;IS IT C.R. BEQ 3$ ;BRANCH IF SO BLT 4$ ;BRANCH TO OUTPUT AS CONTROL CHAR CMP #11,R0 ;IS IT A TAB? BEQ 5$ ;BRANCH IF TAB BLT 1$ ;BRANCH TO OUTPUT AS IS(L.F.,V.T.,F.F.) 4$: MOV #'^,R0 ;OUTPUT CHAR AS ^CHAR+100 JSR PC,TTIOUT ;SEND IT MOV @SP,R0 ;GET ORGINAL ADD #100,R0 ;MAKE IT PRINTABLE JSR PC,TTIOUT ;GO OUTPUT IT BR 7$ ;GO TO SUCCESS CODE 2$: MOV #'$,R0 ;OUTPUT ALTMODE AS $ 6$: INC (PC)+ ;BUMP COLUMN COUNTER TABCNT: .WORD 0 ;COLUMN POINTER BR 1$ ;GO OUTPUT IT 3$: CLR TABCNT ;RESET TO BEGINING OF LINE BR 1$ ;OUTPUT THE CHAR 5$: MOV #40,R0 ;CONVERT TABS TO BLANKS JSR PC,TTIOUT ;OUTPUT A BLANK BIC #177770,TABCNT ;SEE IF AT TAB STOP? BNE 5$ ;BRANCH IF NOT BR 7$ ;GO THROUGH SUCCESS EXIT CODE 8$: MOV #OBUF,(R1)+ ;RESET START OF RING POINTER 1$: TSTB @-(R1) ;SEE IF WE HIT END OF RING BMI 8$ ;BRANCH TO RESET IT MOVB R0,@(R1)+ ;PUT CHAR INTO RING INC @R1 ;BUMP THE COUNT INC -(R1) ;BUMP CURRENT POINTER MOV @#54,R2 ;RMON ADDRESS MOV #100,@310(R2) ;POKE INTERRUPT IN CASE I IGNORED ONE CMPB @#56,R0 ;CHECK FILL CHAR BNE 7$ ;NOT IT MOVB @#57,R2 ;SET UP FILL COUNT CLR R0 ;SET UP TO SEND NULLS 9$: JSR PC,TTIOUT ;OUTPUT THE NULL DEC R2 ;DID WE OUTPUT THE REQUIRED NUMBER? BGT 9$ ;NO: OUTPUT ANOTHER 7$: MOV (SP)+,R0 ;RESTORE THE ORIGINAL CHAR CLC ;SIGNIFY SUCCESS NOTRDY: RTS PC ;RETURN .DSABL LSB .SBTTL BUFFERS,POINTERS,TABLES ; ;INPUT RING BUFFER AND POINTERS .BYTE 255. IBUF: .REPT 80. .BYTE 0 .ENDR IBUFEN: .BYTE 255. IEMPT: .WORD IBUF ICR: .WORD 0 ;FLAG TO DETERMINE IF C.R. LAST CHAR ICUR: .WORD IBUF V2: .WORD 0 ;V2 EMT FLAG CCOUNT: .WORD 0 ;CHARACTER COUNT DURING SPECIAL TTY ; MODE. ;ACTIVE CHANNEL NUMBER TABLE (POSITIVE INDICATES CHANNEL NOT ACTIVE) CHAN: .BYTE 0 ;RT-11 CHANNEL 0 .BYTE 0 ;RT-11 CHANNEL 1 .BYTE 0 ;RT-11 CHANNEL 2 .BYTE 0 ;RT-11 CHANNEL 3 ; OCTAL TO DECIMAL TABLE ; DECTAB: 10000. 1000. 100. 10. 1. 0 SPEC: .BYTE CTRLC-HERE,'C&77 .BYTE CTRLO-HERE,'O&77 .BYTE CTRLS-HERE,'S&77 .BYTE CTRLQ-HERE,'Q&77 .BYTE CTRLU-HERE,'U&77 .BYTE ALT-HERE,175 .BYTE ALT-HERE,176 .BYTE RUBOUT-HERE,177 .BYTE CR-HERE,15 .BYTE 0 ;THE OUTPUT RING BUFFER AND POINTERS OBUF: .REPT 80. ;SIZE OF OUTPUT RING RING BUFFER .BYTE 0 ;ALL THE ELEMENTS HAVE TO BE + .ENDR OBUFEN: .BYTE 255. ;END OF RING SIGNIFIER OEMPT: .WORD OBUF ;EMPTY POSITION POINTER OCNT: .WORD 0 ;CURRENT NUMBER OF CHARS IN BUFFER OCUR: .WORD OBUF ;CURRENT CHARACTER POINTER AREA: 0 ;WORK AREA FOR DDCMP COMMUNICATIONS ; (BYTE COUNT). 0 ;DAP CODE + OPERATOR .BYTE 0,0 ;CHANNEL NBR AND REQUEST TYPE .BYTE 0,0,0,': ;DEVICE NAME .BYTE 0,0,0 ;FILE NAME .BYTE 0,0,0 .BYTE '. ;PERIOD .BYTE 0,0,0 ;FILE NAME EXTENSION .EVEN .SBTTL ONCE-ONLY CODE ; ;ONCE ONLY CODE ; .ENABL LSB .RAD50 /RTSIM / RTSIM: MOV (SP),@#2 ;DON'T RESTART HERE MOV (SP)+,@#40 ;START ADDRESS FROM BOOT TST (SP)+ ;GET RID OF EXTRA STACK ENTRY MOV (SP)+,@#54 ;TOP OF MEMORY FROM BOOT CMP @#$START,#160000;HARDWARE BOOT? BLO 1$ ;NO MOV @#54,R2 ;YES: USE SIZER LIMIT BR 2$ 1$: MOV @#164,R2 ;USE LOW END OF BOOT SUB #1000,R2 2$: MOV R2,@#54 ;FIX LIMIT MOV #7$,@#4 ;CHECK FOR VT11 TST @#VT11PC BIS #4,300+RMON ;FIX CONFIG WORD IF IT'S THERE MOV @#VTVEC+10,R0 ;CHECK FOR SCROLLER PRESENT CMP (PC)+,-(R0) ;IF R0 IS ILLEGAL ADDR, .RAD50 /OLL/ ;CODE FALLS THRU TO 7$ BNE 8$ ;IF NOT SCROLL, TO 8$ CMP (PC)+,-(R0) .RAD50 /SCR/ BNE 8$ MOV -(R0),R1 MOV R1,302+RMON ;SCROLLER IS HERE: SHOW IT IN RMON MOV R1,310+RMON ;AND MAKE TPS=SCROL TST (R1)+ MOV R1,312+RMON ;AND TPB=SCROL+2 JSR PC,@-(R0) ;CALL SCROLLER INIT CODE BR 8$ ;WHICH WILL ADJUST @#54 7$: CMP (SP)+,(SP)+ 8$: MOV @#54,R2 ;GET NEW UPPER MEMORY LIMIT MOV #RMON,R0 ;GET SIZE OF RMON MOV #RMNEND,R1 CMP R1,R2 ;ROOM? BHI OVRCOR ;NO: GIVE ERROR MSG SUB R0,R1 ;LENGTH OF RMON SUB R1,R2 ;MAKE ROOM FOR RMON MOV R2,@#54 ;ADJUST HI MEM LIMIT MOV R2,-(SP) ;REMEMBER RELOCATION OFFSET SUB R0,(SP) ASR R1 ;MAKE A WORD COUNT 4$: MOV (R0)+,(R2)+ DEC R1 BGT 4$ MOV @#54,R2 ;POINT R2 TO RMON MOV @#50,R1 ;HI LIMIT OF JOB 15$: CLR (R1)+ ;ZERO MEMORY CMP R1,R2 BLO 15$ ADD (SP)+,324(R2) ;FOR SYNCH MOV #5$,@#4 ;CHECK FOR CLOCK CLR @#6 BIS #100,@#LKCSR ;TRY TO ENABLE IT BIS #100000,300(R2) ;FIX CONFIG WORD IF CLOCK OK BR 3$ 5$: CMP (SP)+,(SP)+ 3$: .IFNDF NOLSI MOV #9$,@#4 ;CHECK FOR LSI TST @#-2 ;LSI IF NO PSW BR 10$ ;NOT AN LSI 9$: CMP (SP)+,(SP)+ BIS #4000,300(R2) ;LSI BIT IS BIT 11 10$: .ENDC MOV #6$,@#10 ;SET UP RESERVED INSTR TRAP CLR $HRDWR ;ASSUME NO FPP 170001 ;TRY A FPP INSTR MOV #8.,$HRDWR ;IT WORKED BIS #100,300(R2) ;FIX CONFIG WORD TO SAY SO BR 11$ 6$: CMP (SP)+,(SP)+ .IFDF MTRAP 11$: MOV #MTRAP0,@#4 MOV #MTRAP0,@#10 .IFF 11$: MOV #6,@#4 MOV #12,@#10 .ENDC ;.IFDF MTRAP MOV @#40,PC ;START UP USER PROGRAM ; OVRCOR: MOV #OVRMSG,R5 JMP MSGOUT OVRMSG: .ASCIZ /?OVR COR?/ .EVEN .DSABL LSB .SBTTL RMON ; ; THIS MODULE PROVIDES THE FEATURES OF RMON ; NECESSARY TO SIMULATE AN RT-11 ENVIRONMENT ; IN A SATELLITE COMPUTER UNDER REMOTE-11 ; IT WILL BE RELOCATED TO HIGH MEMORY BY RTSIM ; WHEN THE PROGRAM IS LOADED. THEREFORE, IT ; MUST BE WRITTEN IN POSITION INDEPENDENT CODE (PIC) RMON: .IFNDF NORMON INTEN: MOV R4,-(SP) ;SAVE R4 .IFNDF NOLSI MOV @#54,R4 ;RMON ADDR BIT #4000,300(R4) ;IS THIS AN LSI-11? BEQ 1$ ;NO MFPS R4 ;GET PSW BIC (R5)+,R4 MTPS R4 ;FIX IT BR 2$ .ENDC ;.IFNDF NOLSI 1$: BIC (R5)+,@#-2 ;FIX PRIORITY 2$: JSR PC,(R5) ;GO TO USER ROUTINE MOV (SP)+,R4 ;RESTORE REGS MOV (SP)+,R5 RTI ; SYNCH: CMP (R5)+,(SP)+ ;GET READY TO RETURN MOV R0,-(SP) ;SAVE R0 AND R1 MOV R1,-(SP) MOV 6(R4),R0 ;FOURTH WORD OF SYNCH BLOCK JSR PC,(R5) ;TO USER ROUTINE MOV (SP)+,R1 ;RESTORE REGS MOV (SP)+,R0 RTS PC ; .IFNDF NOLSI MFPS: MOV (SP),-(SP) ;MAKE ROOM ON STACK MOV @#54,-(SP) ;RMON ADDR ADD #300,(SP) ;CONFIG WORD OFFSET BIT #4000,(SP)+ ;IS THIS AN LSI-11? BNE 1$ ;YES MOV @#-2,2(SP) RTS PC 1$: MFPS 2(SP) RTS PC .ENDC ;.IFNDF NOLSI ; .=RMON+262 .WORD 12.*40+11.*40+3 ;262 DATE=DEC-11-1975 .WORD 0 ;264 FILLER .WORD 0 ;266 USR SWAP AREA .WORD 0 ;270 FILLER .WORD 0 ;272 FILLER .BYTE 0 ;274 FILLER .BYTE 0 ;275 SYS DEVICE .BYTE 2 ;276 VERSION .BYTE 'B ;277 UPDATE .WORD 200 ;300 CONFIG WORD (USR IS RESIDENT) .WORD 0 ;302 SCROLL ADDRESS (NONE PRESENT) .WORD 177560 ;304 TERMINAL BUS ADDRESSES .WORD 177562 ;306 .WORD 177564 ;310 .WORD 177566 ;312 .WORD -2 ;314 LARGEST FILE .WORD 0 ;316 FILLER .WORD 0,0 ;320 TIME .WORD SYNCH ;324 MUST BE RESET BY RTSIM WHEN ; IT IS RELOCATED!!! .=RMON+354 .WORD VTVEC ;354 VT11 VECTOR ADDR .IFNDF NOLSI .WORD 0 ;356 FILLER RTI ;360 MTPS ENTRY BR MFPS ;362 MFPS ENTRY .ENDC ;.IFNDF NOLSI .ENDC ;.IFNDF NORMON RMNEND=. ; .IIF GT RTSIM+512.-9.-. .=RTSIM+512.-9. ;512. BYTE BUFFER .END .NLIST TTM .TITLE DDCMP "REMOTE" BOOTSTRAP PROGRAM .SBTTL REMOTE.001 ; ; PDP-11 REMOTE PROCESSOR BOOTSTRAP PROGRAM ; ; PROGRAM NAME: REMOTE ; ; VERSION LEVEL: X0001 ; ; AUTHOR: RICK HULLY/HK ; ; DATE: 11 DECEMBER 1975 ; ; ; COPYRIGHT (C) 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU- ; SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY OTHER ; COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE ; TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO ; AGREES TO THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE ; SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIBILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; .SBTTL EQUATES ; ; GENERAL REGISTER ASSIGNMENTS ; R0 = %0 R1 = %1 R2 = %2 R3 = %3 R4 = %4 R5 = %5 SP = %6 PC = %7 ; ; OTHER EQUATES ; PSW = 177776 ;PROCESSOR STATUS WORD SW = 177570 ;SWITCH REGISTER RETURN = 207 ;RTS PC DLE = 220 ;DEL CHARACTER SYN = 377 ;SYNC CHARACTER (ASYNC) POLY = 120001 ;CRC-16 POLYNOMINAL DLECRC = 66000 ;CRC VALUE OF "DLE" ALONE SYNDLE = 110377 ;SYN AND DLE CHARACTERS SYNSYN = -1 ;SYN AND SYN CHARACTERS ; ; ; CONSOLE TERMINAL EQUATES ; KBCSR = 177560 KBBUF = KBCSR+2 TTCSR = KBCSR+4 TTBUF = KBCSR+6 ; ; DL11-E COMMUNICATIONS EQUATES ; DLICSR = 175610 DLIBUF = DLICSR+2 DLOCSR = DLICSR+4 DLOBUF = DLICSR+6 .IF NDF DLVEC .IF NDF REV11 DLVEC = 400 .IFF DLVEC = 370 .ENDC ;REV11 .ENDC ;DLVEC ; .IIF DF M9301, .ENABL ABS,AMA ; .IIF DF M9301, .=165000 ; .IIF DF REV11, .ENABL ABS ; .IIF DF REV11, .=172000 ;FOR BLAST PROGRAM ; ; CONSOLE AND COMMUNICATIONS BUFFERS ; ; CONSOLE TERMINAL BUFFER HAS 122 BYTES OF BUFFER WITH 6 ; BYTES OF DESCRIPTOR. ; COMMUNICATIONS BUFFER HAS 377 BYTES OF BUFFER WITH 7 ; BYTES OF DESCRIPTOR. ; ; TTIN = 150 ;CONSOLE TERMINAL BUFFER DESCRIPTOR ; BLOCK POINTER. COMM = TTIN+2 ;COMMUNICATIONS TERMINAL BUFFER ; DESCRIPTOR BLOCK POINTER. ; BFIDES = TTIN+4 ;DDCMP BUFFER (INPUT) DESCRIPTOR BLOCK ; ADDRESS. BFODES = TTIN+6 ;DDCMP BUFFER (OUTPUT) DESCRIPTOR BLOCK ; ADDRESS. ; RECNUM = TTIN+10 ;RECORD NBR DURING DDCMP PROGRAM LOADS $SENDDC = TTIN+12 ;ADDRESS OF "SENDDC" ROUTINE $START = TTIN+14 ;ADDRESS OF "BOOTSTRAP RESTART" ; ; TTY AND COMM BUFFER DESCRIPTION ; ; -4 OUTPUT POINTER ; -2 INPUT POINTER ; 0 BYTE COUNT ; +2 LAST CHAR (COMM ONLY) ; +3 ^S FLAG (COMM ONLY) ; ; PAGE1 = . ;THIS MUST BE BEGINNING OF PAGE ONE .SBTTL DDCMP DESCRIPTOR BLOCKS ; ; DDCMP INPUT BUFFER DESCRIPTOR BLOCK ; ; WORD CONTENTS ; ; -6 COMPLETION ROUTINE ADDRESS ; -4 COMPLETION FLAG ; -2 CRC VALUE DURING INPUT ; 0 BUFFER POINTER ; +2 BYTE COUNT OF INPUT ; +4 BUFFER STARTS HERE ; ; ; DDCMP OUTPUT BUFFER DESCRIPTOR BLOCK ; ; WORD CONTENTS ; ; -6 COMPLETION ROUTINE ADDRESS ; -4 COMPLETION FLAG ; -2 CRC BEFORE OUTPUT ; 0 BUFFER POINTER ; +2 BYTE COUNT OF OUTPUT ; +4 BUFFER STARTS HERE ; ; .SBTTL MACROS ; .MACRO PUSH,ARG MOV ARG,-(SP) .ENDM PUSH ; .MACRO POP,ARG MOV (SP)+,ARG .ENDM POP ; .MACRO CALL,SUBROUTINE JSR PC,SUBROUTINE .ENDM CALL ; .MACRO MOVR,X,Y .IF DF REV11 MOV X-5000,Y .IFF MOV X,Y .ENDC .ENDM MOVR ; .MACRO JMPR,X .IF DF REV11 JMP X-5000 .IFF JMP X .ENDC .ENDM JMPR ; .MACRO CALLR,SUBR .IF DF REV11 CALL SUBR-5000 .IFF CALL SUBR .ENDC .ENDM CALLR ; .SBTTL RECEIVE DDCMP MESSAGE .ENABL LSB ; ; CALLING SEQUENCE: ; MOV #-9.,R4 ; CLR R3 ; MOV #COMPL,R2 ; CALL RECDDC ; WHERE COMPL IS THE ADDRESS OF A COMPLETION ROUTINE ; 0 IF NONE ; RECDDC: MOV R2,-(SP) ;SAVE FOR LATER MOV @#BFIDES,R0 ;SETUP DESCRIPTOR BLOCK TO RECEIVE DDCMP MOV R0,R2 ; MESSAGE. CMP (R2)+,(R2)+ ;R2=R2+4 MOV R2,(R0) ;RESET BUFFER POINTER TO BEGINNING ; OF BUFFER. MOV R4,-(R2) ;SETUP BYTE COUNT OF LINE MOV R3,-(R0) ;INITIALIZE CRC (EITHER CRC OF DLE OR ; ZERO). CLR -(R0) ;INITIALIZE COMPLETION FLAG TO ZERO MOV (SP)+,-(R0) ;COMPLETION ROUTINE (0 IF NONE) BIS #100,@#DLICSR ;ENABLE INTERRUPTS AND WAIT FOR MSG TST (R0)+ ;COMPLETION ROUTINE? BNE 2$ ;YES: BUMP R0 AND RETURN 1$: ROL (R0) ;MESSAGE IN? 0=NO, 1=YES, -1=ERROR BEQ 1$ ;NO: CONTINUE WAITING THEN BCS 4$ ;ERROR 2$: TST (R2)+ ;R2 POINTS TO DATA SUB 4(R0),R2 ;R2 = LENGTH OF BUFFER IN BYTES NEG R2 BLE 4$ ;MUST BE >0, USER MUST HANDLE 0 LENGTH CLC ;GOOD RETURN 4$: RETURN .DSABL LSB .SBTTL SEND DDCMP MESSAGE ; ; CALLING SEQUENCE: ; MOV #COMPL,R2 ; MOV #MSG,R5 ; CALL SENDDC ; WHERE "MSG" HAS THE FOLLOWING FORMAT ; BYTES 0 AND 1 HAVE NBR OF BYTES IN MESSAGE ; BYTE 2 HAS OSOP CODE ; BYTES 3 THRU N HAVE THE DATA (IF ANY) ; ; COMPL IS THE ADDRESS OF A COMPLETION ROUTINE ; 0 IF NONE ; SENDDC: MOV R2,-(SP) ;HOLD ONTO COMPL RTN ADDR MOV @#BFODES,R2 ;GET MESSAGE ADDRESS MOV R2,R0 MOV #11.,(R2)+ ;BEGIN WITH STANDARD 11 BYTE HEADER MOV R2,-(R0) ;SETUP REST OF DESCRIPTOR BLOCK ; (BUFFER START ADDRESS). MOV R0,R3 ;POINTER NEEDED FOR CRC CALCULATIONS (R0) MOV #DLECRC,-(R3) ;INIT CRC WITH DLE CRC VALUE CLR -(R3) ;INIT COMPLETION FLAG CLR -(R3) ;NO COMPLETION ROUTINE NEEDED MOV #SYNSYN,(R2)+ ;NOW PLUG IN HEADER MOV #SYNDLE,(R2)+ ;NOW PLUG IN HEADER MOV (R5),R4 ;GET BYTE COUNT OF LINE BIS #100000,R4 ;SET S (SELECT LINK FLAG) BIT CALL @#STORE2 ;STORE IN BUFFER AND COMPUTE CRC ON IT CLR R4 ;STORE 2 FILLER BYTES IN BUFFER CALL @#STORE2 ; AND COMPUTE CRC ON THEM. INC R4 ;STORE THE STATION ADDRESS (ALWAYS "1") CALL @#STORE1 ; AND COMPUTE CRC ON IT. CALL SENDMS MOV R0,R2 ;SETUP BUFFER TO SEND OUT DATA PORTION TST (R2)+ ; OF MESSAGE NOW. MOV #2,(R2) ;INIT BYTE COUNT OF 2 FOR CRC CHARS ADD (R5),(R2)+ ;ADD IN BYTE COUNT OF LINE MOV R2,(R0) ;INIT BUFFER START ADDRESS MOV R0,R3 ;KEEP R0 POINTING HERE CLR -(R3) ;INIT CRC VALUE CLR -(R3) ;INIT COMPLETION FLAG MOV (SP)+,-(R3) ;COMPLETION ROUTINE (0 IF NONE) MOV (R5)+,R3 ;GET BYTE COUNT OF LINE AGAIN 2$: MOVB (R5)+,R4 ;GET NEXT BYTE, STORE IN BUFFER AND CALL @#STORE1 ; CALCULATE CRC ON IT. DEC R3 ;ALL DONE? BGT 2$ ;NO: CONTINUE SENDMS: TST -(R0) MOVB (R0)+,(R2)+ ;STORE CALCULATED CRC ALSO MOVB (R0)+,(R2) BIS #100,@#DLOCSR ;ENABLE INTERRUPTS AND SEND MESSAGE OUT TST -6(R0) ;COMPLETION RTN REQUEST? BNE 3$ ;YES 1$: TST -4(R0) ;NO: WAIT TIL DONE BEQ 1$ 3$: RETURN ; .SBTTL DL11 COMMUNICATIONS INPUT INTERRUPT PROCESOR .ENABL LSB ; CI.INT: PUSH R0 ;SAVE SOME REGISTERS PUSH R1 MOV @#BFIDES,R0 ;GET BUFFER DESCRIPTOR WORD MOVB @#DLIBUF,R1 ;READ IN BYTE MOVB R1,@(R0)+ ;SAVE IT CMP (R0),#-9. ;BYTE CURRENTLY SHOWING THAT NOTHING HAS ; BEEN READ IN SO FAR? BGT 1$ ;NO: SEE IF DLE HAS BEEN READ IN CMPB R1,#SYN ;YES: SYNC BYTE? BNE CMEXIT ;NO: JUST IGNORE THE BYTE THEN BR 5$ ;YES: COUNT BYTE THEN 1$: CMP (R0),#-8. ;"DLE" READ IN YET? BNE 2$ ;YES: GOOD BYTE READ IN SO LETS SAVE IT CMPB R1,#SYN ;IS THIS BYTE A SYNC? BEQ CMEXIT ;YES: IGNORE LEADING SYNC'S TST -(R0) ;POINT AT BUFFER ADDRESS CMPB R1,#DLE ;MUST BE A "DLE" OR MESSAGE IS NOT ; IN SYNC. BEQ 3$ ;YES: CALCULATE CRC ON THIS BYTE MOV R0,R1 ;SAVE FOR A MOMENT TST (R0)+ ;R0=R0+2 MOV #-9.,(R0)+ ;RESET BUFFER COUNT AND POINTER MOV R0,(R1) CLR -(R1) ;RESET CRC VALUE BR CMEXIT ; 2$: INC -(R0) ;INCREMENT BUFFER POINTER 3$: CALL CRC ;CALCULATE CRC FOR THIS BYTE TST (R0)+ 4$: TST (R0) ;HEADER OR DATA SECTION? BPL 6$ ;DATA ; ; HEADER BLOCK PROCESSING ; 5$: INC (R0) ;INCREMENT HEADER BYTE COUNT BMI CMEXIT ;MORE BYTES TO GO YET TST -4(R0) ;HEADER IS COMPLETELY IN, TEST CRC BNE CMFAIL ;ERROR: SET ERROR FLAG AND CALL ; COMPLETION ROUTINE. MOV 2(R0),(R0) ;GET BYTE COUNT FOR DATA FIELD BIC #140000,(R0) ;MASK OFF S AND F BITS ADD #2,(R0)+ ;GET CRC OF DATA FIELD ALSO MOV R0,-4(R0) ;RESET BUFFER POINTER TO BEGINNING OF ; BUFFER. CMP -(R0),#521. ;BYTE COUNT > 521. BYTES? BGT CMFAIL ;YES: ERROR THEN. SET ERROR FLAG AND ; CALL COMPLETION ROUTINE. CMEXIT: POP R1 ;RESTORE R1 POP R0 ;RESTORE R0 RTI ;RETURN TO INTERRUPT PROGRAM ; ; ; DATA BLOCK PROCESSING ; 6$: DEC (R0) ;DECREMENT DATA FIELD BYTE COUNT BGT CMEXIT ;MORE BYTES TO GO TST -4(R0) ;ALL BYTES IN, CHECK CRC BEQ CMSUC1 ;OK, SET SUCCESS FLAG AND GO TO ; COMPLETION ROUTINE. ; CMFAIL: MOV #-1,R1 ;SET FAILURE FLAG AND CALL COMPLETION ; ROUTINE. ; CMSUCC: CMP -(R0),-(R0) ;R0=R0-4 MOV R1,-(R0) ;SET SUCCESS/FAILURE FLAG BIC #100,@#DLICSR ;TURN OFF INPUT INTERRUPTS TST -(R0) ;COMPLETION ROUTINE EXIT? BEQ CMEXIT ;NO: JUST EXIT THEN POP R1 ;RESTORE R1 PUSH (R0)+ ;COMPLETION ROUTINE ADDRESS CMP (R0)+,(R0)+ RTSPC: RETURN ;CALLER MUST RETURN VIA RTI ; AND MUST RESTORE R0 .DSABL LSB ; .SBTTL DL-11E COMMUNICATIONS OUTPUT INTERRUPT ROUTINE ; CO.INT: PUSH R0 ;SAVE SOME REGISTERS PUSH R1 MOV @#BFODES,R0 ;GET ADDRESS OF BUFFER DESCRIPTOR TST (R0) ;ANYTHING TO OUTPUT? BEQ 1$ ;NO: CLEAR INTERRUPT AND CALL ; COMPLETION ROUTINE IF ANY. DEC (R0) ;DECREMENT BYTE COUNT MOVB @-(R0),@#DLOBUF ;GET NEXT BYTE FROM BUFFER AND SEND ; IT OUT. INC (R0) ;BUMP BUFFER POINTER BR CMEXIT ;RESTORE REGISTERS AND EXIT ; 1$: CLR @#DLOCSR ;TURN OFF OUTPUT INTERRUPTS CMSUC1: MOV #1,R1 ;SHOW SUCCESSFUL COMPLETION AND BR CMSUCC ; CALL COMPLETION ROUTINE. ; .SBTTL BEGIN DDCMP I/O .ENABL LSB ENTDDC: MOV #-7,R4 ;ASSUME 7 BYTES LEFT IN HEADER MOV #DLECRC,R3 ;CURRENT CRC VALUE OF DLE ALONE DDCMP: CLR R2 ;NO COMPLETION ROUTINE CALL RECDDC ;GET MSG ;ON RETURN--- ;R0 POINTS TO BFIDES ;R2 CONTAINS BYTE COUNT ;CARRY IS SET IF AN ERROR OCCURRED MOV R0,R5 ;FOR LATER USE BCS 10$ ;ERROR ADD #8.,R0 ;POINT TO BUFFER SUB #14,R2 ;ASSUME PROGRAM LOAD WITH TRANS ADDR MOVB (R0)+,R1 ;GET OSOP CODE DESIRED CMPB R1,#22 ;ENTER TTY MODE? BNE 1$ ;NO MOV #ENTTY-1,R5 MOV #4,R2 ;READY TO REENTER JMP @#RESTRT ;REENTER 1$: MOVB (R0)+,@#RECNUM ;SAVE RECORD NBR DESIRED MOV (R0)+,R3 ;GET LOAD ADDRESS TST (R0)+ ;IGNORE MOST SIGNIFICANT 16 BITS ASL R1 ;R1=0 FOR TRAN WITH ADDR AND 4 WITHOUT ADD R1,R2 ;R2 NOW HAS REAL SIZE OF DATA BMI 10$ ;ILLEGAL, MUST HAVE SHORT BUFFER 2$: DEC R2 BMI 3$ ;TRANSFER COMPLETE MOVB (R0)+,(R3)+ ;TRANSFER PROGRAM SEGMENT BR 2$ ;KEEP ON TRUCKIN 3$: TST R1 ;TRANSFER ADDRESS INCLUDED? BEQ 6$ ;YES: PROCESS IT INC @#RECNUM ;BUILD "REQUEST PROGRAM LOAD" MESSAGE 10$: ADD #55.,R5 ;ADJUST PREVIOUSLY SAVED BFIDES MOVB @#RECNUM,(R5) ;RECORD NBR DESIRED MOVB #12,-(R5) ;OSOP CODE MOV #2,-(R5) ;BYTE COUNT SEND2M: CLR R2 ;NO COMPLETION ROUTINE CALL SENDDC ;SEND IT OUT MOV #-9.,R4 ;GET NEXT DDCMP MESSAGE CLR R3 BR DDCMP 6$: MOV #DLVEC,R3 ;RESET VECTOR AREA IN CASE USER WANTED IT MOV #170,R4 MOV (R4)+,(R3)+ MOV (R4)+,(R3)+ MOV (R4)+,(R3)+ MOV (R4),(R3) ;NOW ASSEMBLE THE ADDRESS MOVB (R0)+,-(SP) ;LOW ORDER BYTE MOVB (R0),1(SP) ;HIGH ORDER BYTE ROR (SP) ;ILLEGAL TRANSFER ADDRESS? BCS HLT ;YES: HALT THEN ROL (SP) ;ANY TRANSFER ADDRESS AT ALL? BEQ HLT ;NO: SO HALT MOV @#2,R3 ;LOOK FOR RTSIM LOAD BEQ RTSPC ;EVADE TRAP CATCHER TRAP CMP -(R3),(PC)+ .RAD50 /IM / BNE RTSPC ;NOT HERE CMP -(R3),(PC)+ ;DOUBLE CHECK .RAD50 /RTS/ BNE RTSPC ;FAILS CLR PC ;START UP RTSIM THROUGH LOC 0 .DSABL LSB .SBTTL DDCMP MESSAGES ; ; FORMAT: 16 BIT COUNT OF DATA FIELD + 1 BYTE FOR OSOP ; OSOP CODE (1 BYTE) ; N BYTES OF DATA ; ; REQUEST FOR SECONDARY PROGRAM LOAD ; HLT: HALT ;FLAG TO TELL US THIS IS REQ2M REQ2M: .BYTE 4,0,10,4;1,0 ; ; ENTER TTY MODE ; ENTTY: .BYTE 1,0,22,0 ; ; .IIF GT .-PAGE1-1000, .ERROR 1 ;PART 1 GREATER THAN 256. BYTES ; .SBTTL BOOT STARTUP CODE ; .IIF DF M9301, .=173000 .IIF NDF M9301, .=PAGE1+1000 ; PAGE2 = . ;MUST BE AT BEGINNING OF PAGE TWO ; START: MOVR #ENTTY-1,R5 ;SETUP MESSAGE (POINT AT FLAG = NON-ZERO) BR START1 SECSTR: MOVR #REQ2M-1,R5 ;SECONDARY MODE PROG LOAD (FLAG = ZERO) ;TEST WILL BUMP TO REAL LOCATION START1: MOV #$START,R0 MOV #START,(R0) BR START2 .IIF NE .-PAGE2-24, .ERROR 2 ;NEXT LOC MUST BE 24 .WORD 173776 ;POWER FAIL RESTART @ 173024 START2: RESET MOVR #SENDDC,-(R0) MOV #DLVEC,R2 ;SETUP INTERRUPT VECTORS FOR MOV #170,R4 ; COMMUNICATIONS INTERFACE. MOV #340,R3 MOVR #CI.INT,(R2) MOV (R2)+,(R4)+ MOV R3,(R2)+ MOV R3,(R4)+ MOVR #CO.INT,(R2) MOV (R2)+,(R4)+ MOV R3,(R2)+ MOV R3,(R4) MOV (PC),SP ;BEGIN MEMORY SIZER @ 5002 CLR R2 CLR (R2)+ ;JUMPS TO 0 HALT MOV PC,(R2)+ ;USED TO TEST FOR RTSIM LATER RESTRT: MOV #RTII,(R2)+ ;RETURN FOR BUS ERROR CLR (R2) MOV (SP),(SP)+ ;THIS INSTRUCTION TESTS FOR R/W MEMORY BR .-2 ;AND KEEP GOING UNTIL IT TRAPS RTII: MOV #6,-(R2) ;RESET BUS ERROR TRAP TO A HALT MOV SP,R0 SUB #195.+31.*2,R0 ;ALLOCATE COMM BUFFER AND STACK AREA MOV #BFIDES,R1 MOV R1,R3 MOV R0,-(R1) ;R1->COMM SUB #66.*2,R0 ;NOW ALLOCATE TTY BUFFER MOV R0,-(R1) ;R1->TTIN MOV R0,(R0) ;SETUP BUFFER MOV R0,(SP) ;REMEMBER WHERE TOP OF CORE IS ADD (R2),(R0) ;BUFFER START ADDRESS (OUTPUT) ;SETUP DDCMP BUFFER ADDRESSES(INPUT) MOV (R0),(R3)+ ;OLD R3->BFIDES MOV (R0),(R3) ;NOW THE OUTPUT (->BFODES) ADD #2,(R3)+ CLR (R3)+ ;FOR DDCMP USE LATER TSTB (R5)+ ;SEC'Y MODE REQ? (ALSO POINT TO MSG NOW) BNE 1$ ;NO JMPR SEND2M ;YES: DON'T ALLOW REF TO TTY REGS 1$: CLR R2 ;NO COMPLETION ROUTINE CALLR SENDDC MOV @#TTIN,R0 ;SETUP TTY BUFFERS MOV R0,(R0) ADD #6,(R0) MOV (R0)+,(R0)+ ;BUFFER START ADDRESS (INPUT) MOV @#COMM,R2 ;SETUP COMM BUFFER MOV R2,(R2) ;BUFFER START ADDRESS (OUTPUT) ADD #10,(R2) MOV (R2)+,(R2)+ ;BUFFER START ADDRESS (INPUT) CLR (R2)+ ;BUFFER IS INITIALLY EMPTY CLR (R2) ;CLEAR ^S FLAG MOV -(R2),(R0) ;CLEAR TTY BYTE COUNT ; AND POINT R2 TO COMM ; CLR -(SP) ;CLEAR INTERNAL ^S FLAG BOOT1: TSTB @#KBCSR ;ANY TTY INPUT? BPL BOOT2 ;NO: CHECK COMM INPUT THEN MOVB @#KBBUF,R1 ;GET CHARACTER BIC #177600,R1 ;RID GARBAGE BOOT3: CMP (R0),#66.*2-6 ;ROOM FOR CHARACTER? BHIS BOOT2 ;NO: IGNORE CHARACTER THEN CMPB R1,#23 ;USER TYPE ^S? BNE 1$ ;NO MOVB R1,(SP) ;YES: JUST STOP OUTPUT ON THIS BR BOOT2 ; SIDE THEN. 1$: CMPB R1,#21 ;USER TYPE ^Q? BEQ 2$ ;YES INC (R0) ;NO: +1 TO CHARACTER COUNT MOVB R1,@-(R0) ;SAVE CHARACTER IN BUFFER BR BOOT10 ;BUMP BUFFER POINTER 2$: CLRB (SP) ;FREE UP OUTPUT ON REMOTE SIDE ; BOOT2: MOV #DLOCSR,R5 MOV #DLOBUF,R3 MOV R2,R4 ADD #3,R4 ;R4->^S TSTB @#DLICSR ;ANY COMM INPUT? BPL 5$ ;NO: CHECK TTY OUTPUT THEN MOVB @#DLIBUF,R1 ;GET CHARACTER CMPB #DLE,R1 ;DLE CHARACTER? BNE 3$ ;NO CMPB 2(R2),#SYN ;WAS LAST CHARACTER AN "SYN"? BNE 3$ ;NO JMPR @#ENTDDC ;YES: ENTER DDCMP MODE 3$: TSTB (R4) ;^S SENT? BNE 4$ ;YES: DON'T BOTHER ABOUT SENDING ; ANOTHER THEN. CMP (R2),#386.*3/4 ;BUFFER > 3/4 FULL? BLO 4$ ;NO TSTB (R5) ;SEND ^S TO HOST COMPUTER (R5->DLOCSR) BPL .-2 MOVB #23,(R3) ;(R3->DLOBUF) MOVB R1,(R4) ;REMEMBER THAT A ^S WAS SENT 4$: INC (R2) ;+1 TO CHARACTER COUNT MOVB R1,@-(R2) ;SAVE CHARACTER IN BUFFER MOVB R1,-(R4) ;SAVE LAST CHARACTER RECEIVED BR 6$ ;BUMP BUFFER POINTER ; 5$: TSTB @#TTCSR ;OUTPUT DEVICE READY FOR OUTPUT? BPL BOOT8 ;NO: WAIT TILL LATER THEN TSTB (R4) ;^S ACTIVE? BEQ 9$ ;NO CMP (R2),#386.*1/4 ;BUFFER EMPTIED LESS THAN 1/4? BHIS 9$ ;NO CLRB (R4) ;YES: CLEAR ^S FLAG TSTB (R5) ;OUTPUT READY? (R4->DLOCSR) BPL .-2 ;NO: WAIT FOR IT MOVB #21,(R3) ;PUT A ^Q IN OUTPUT BUFFER TO FREE IT 9$: TST (R2) ;ANY OUTPUT? BEQ BOOT8 ;NO TSTB (SP) ;INTERNAL ^S ACTIVE? BNE BOOT8 ;YES: WAIT TILL ITS FREED UP THEN DEC (R2) ;DECREMENT CHARACTER COUNT CMP -(R2),-(R2) ;R2=R2-4 MOVB @(R2),@#TTBUF ;SEND CHARACTER 6$: INC (R2) ;BUMP POINTER MOV @#COMM,R1 ;TEST END OF BUFFER ADD #195.*2-1,R1 CMP (R2),R1 ;END OF BUFFER? BLOS 7$ ;NO SUB #195.*2-8.,(R2) ;YES: RESET TO BEGINNING OF BUFFER 7$: MOV @#COMM,R2 ;RESET BUFFER DESCRIPTOR POINTER CMP (R2)+,(R2)+ ;R2=R2+4 ; BOOT8: TSTB (R5) ;COMM OUTPUT READY? (R5->DLOCSR) BPL BOOT1 ;NO: CHECK AGAIN LATER TST (R0) ;ANY OUTPUT? BEQ BOOT1 ;NO DEC (R0) ;DECREMENT CHARACTER COUNT CMP -(R0),-(R0) ;R0=R0-4 MOVB @(R0)+,(R3) ;OUTPUT NEXT CHARACTER (R3->DLOBUF) CMPB @-(R0),#17 ;^O SENT? BNE BOOT10 ;NO MOV -(R2),-(R2) ;YES: NULL OUT RESET OF BUFFER CMP (R2)+,(R2)+ ;PUT R2 BACK CLR (R2) ;SHOW NO CHARACTERS IN BUFFER BOOT10: INC (R0) ;BUMP BUFFER POINTER MOV @#TTIN,R1 ;TEST END OF BUFFER ADD #66.*2-1,R1 CMP (R0),R1 ;END OF BUFFER? BLOS BOOT11 ;NO SUB #65.*2-6,(R0) ;YES: RESET TO BEGINNING OF BUFFER BOOT11: MOV @#TTIN,R0 ;RESET BUFFER DESCRIPTOR POINTER CMP (R0)+,(R0)+ ;R0=R0+4 BR BOOT1 ;LOOK FOR TTY INPUT NOW ; .SBTTL STORE AND CALC CRC ; ; ROUTINE TO STORE AND CALCULATE CRC ; CALLING SEQUENCE: ; MOV #BYTE,R4 ;FOR 1 BYTE ; CALL STORE1 ; (OR) ; MOV #WORD,R4 ;FOR 2 BYTES ; CALL STORE2 ; ; R0 MUST POINT TO CRC VALUE +2 ; R2 MUST POINT TO THE CURRENT BUFFER POSITION WHERE BYTE WILL BE STORED ; STORE2: MOV R4,R1 ;MAKE COPY OF ORIGINAL SWAB R4 ;SETUP 2ND BYTE FOR LATER REFERENCE CALL STORE ;STORE 1ST BYTE AND COMPUTE CRC ON IT ; STORE1: MOVB R4,R1 ;NOW DO 2ND BYTE (OR 1ST IF "STORE1") STORE: MOVB R1,(R2)+ ;STORE BYTE IN BUFFER ;NOW CALCULATE CRC .SBTTL CRC CALCULATOR ; ; ROUTINE TO CALCULATE CRC-16 POLYNOMINAL ; ; CALLING SEQUENCE: ; ; MOV #BUFFER DESCRIPTOR,R0 ; MOVB BYTE,R1 ; CALL CRC ; CRC: PUSH #8. ;BYTE LENGTH IS 8 BITS CRCLOP: CLC ;INITIALIZE CARRY BIT ROR -2(R0) ;SHIFT OLD PARTIAL ROR R1 ;SHIFT BYTE BVC 1$ ;XOR POLYNOMINAL ; PUSH #POLY ;POLYNOMINAL TO SACK BIC -(R0),(SP) ;NOT PARTIAL AND POLYNOMINAL BIC #POLY,(R0) ;NOT POLYNOMINAL AND PARTIAL BIS (SP)+,(R0)+ ;POLYNOMINAL XOR PARTIAL ; 1$: DEC (SP) ;DECREMENT BIT COUNT BGT CRCLOP ;MORE BITS TO GO TST (SP)+ ;CLEAN UP STACK RETURN ;RETURN TO CALLER ; .SBTTL DEVICE BOOTSTRAP ;DEVICE BOOTSTRAP ; .BLKW 2 ;FILLER RX: MOV #100247,R2 1$: MOV #177170,R1 BITB R2,(R1) BEQ .-2 MOVB #7,R3 MOV R1,R0 MOV R2,(R0)+ BR .+6 2$: MOV #1,(R0) ASR R3 BCS .+6 MOVB (PC)+,(R1) ;MOVB #23,(R1) 3$: MOVB (R0),(R3)+ BIT R2,(R1) BEQ .-2 BMI 1$ BCS 2$ TSTB (R1) BMI 3$ CLR R0 CMP #240,(R0) BNE 1$ CLR PC ; .IIF GT .-PAGE2-1000, .ERROR 1 ;PART 2 GREATER THAN 256. BYTES ; .END START $JOB/RT11 TTYIO .R MACRO *REMUSR=PARAM,REMUSR *REMCOM=PARAM,REMCOM *REMMSG=PARAM,REMMSG *REMDDC=PARAM,REMDDC *REMTTY=PARAM,REMTTY *REMEDC=PARAM,REMEDC *REMED1=PARAM,REMED1 *REMED2=PARAM,REMED2 *VECTOR=VECTOR .R LINK *REMB=VECTOR/C *REMUSR,REMCOM,REMMSG/C *REMDDC,REMEDC,REMTTY/C *REMED1,REMED2 $EOJ $JOB/RT11 TTYIO .R MACRO *REMUSR=PARAM,REMUSR *REMCOM=PARAM,REMCOM *REMMSG=PARAM,REMMSG *REMDDC=PARAM,REMDDC *REMTTY=PARAM,REMTTY *REMEDC=PARAM,REMEDC *REMED1=PARAM,REMED1 *REMED2=PARAM,REMED2 *VECTOR=VECTOR .R LINK *REMBO=VECTOR/C *REMUSR,REMCOM,REMMSG/C *REMDDC,REMEDC,REMTTY/C *REMED1/O:1/C *REMED2/O:1 $EOJ $JOB/RT11 TTYIO .R MACRO *REMUSR=PARAM,REMUSR *REMCOM=PARAM,REMCOM *REMMSG=PARAM,REMMSG *REMDDC=PARAM,REMDDC *REMTTY=PARAM,REMTTY *REMEDC=PARAM,REMEDC *REMED1=PARAM,REMED1 *REMED2=PARAM,REMED2 *VECTOR=VECTOR .R LINK *REMF=VECTOR/R/C *REMUSR,REMCOM,REMMSG/C *REMDDC,REMEDC,REMTTY/C *REMED1,REMED2 $EOJ $JOB/RT11 TTYIO .R MACRO *REMUSR=PARAM,REMUSR *REMCOM=PARAM,REMCOM *REMMSG=PARAM,REMMSG *REMDDC=PARAM,REMDDC *REMTTY=PARAM,REMTTY *REMEDC=PARAM,REMEDC *REMED1=PARAM,REMED1 *REMED2=PARAM,REMED2 *VECTOR=VECTOR .R LINK *REMFO=VECTOR/R/C *REMUSR,REMCOM,REMMSG/C *REMDDC,REMEDC,REMTTY/C *REMED1/O:1/C *REMED2/O:1 $EOJ C F4 TEST1 TYPE 100 100 FORMAT(' FORTRAN PROGRAM WORKS') TYPE 200 200 FORMAT(' TYPE A CR TO STOP') ACCEPT 300,I 300 FORMAT(I1) STOP END C F4 TEST2 C TRY TO READ AND WRITE TO DISK--UNFORMATTED SEQUENTIAL DIMENSION A(100),B(100) TYPE 1000 1000 FORMAT (' BEGIN TEST') DO 10 I=1,100 10 A(I)=I WRITE (1,ERR=50)A REWIND 1 READ (1,ERR=60)B DO 20 I=1,100 IF (A(I).NE.B(I)) TYPE 100,A(I),B(I) 100 FORMAT (' WRITE AND READ UNEQUAL',2F10.0) 20 CONTINUE TYPE 200 200 FORMAT (' TEST COMPLETE') GOTO 70 50 TYPE 300 300 FORMAT (' I/O ERROR WRITING') GOTO 70 60 TYPE 400 400 FORMAT (' I/O ERROR READING') 70 TYPE 500 500 FORMAT (' TYPE TO STOP') ACCEPT 600,I 600 FORMAT(I1) STOP END C F4 TEST3 C SEE IF WE CAN GET THE DATE DIMENSION A(3) DATA A/' ',' ',' '/ CALL DATE(A) TYPE 100,A 100 FORMAT (1X,3A4) TYPE 200 200 FORMAT (' TYPE TO STOP') ACCEPT 300,I 300 FORMAT (I1) STOP END C F4 TEST4 C UNFORMATED DIRECT ACCESS I/O DIMENSION A(100),B(100) DEFINE FILE 1(4,256,U,IO) TYPE 100 100 FORMAT (' BEGIN TEST') DO 10 I=1,100 10 A(I)=I WRITE(1'1,ERR=50) (A(I),I=1,10) WRITE(1'4,ERR=50) (A(I),I=11,20) READ(1'1,ERR=60) (B(I),I=1,10) READ(1'4,ERR=60) (B(I),I=11,20) DO 20 I=1,20 IF (A(I).NE.B(I)) TYPE 200,A(I),B(I) 200 FORMAT (' UNEQUAL WRITE AND READ',2F10.0) 20 CONTINUE TYPE 300 300 FORMAT (' TEST COMPLETE') GOTO 70 50 TYPE 400 400 FORMAT(' I/O ERROR WRITING') GOTO 70 60 TYPE 500 500 FORMAT(' I/O ERROR READING') 70 TYPE 600 600 FORMAT (' TYPE TO STOP') ACCEPT 700,I 700 FORMAT (I1) STOP END .NLIST TTM,CND .TITLE SATELLITE SCROLLER FOR REMOTE-11 .IFDF RTSIM .SBTTL V001 (RTSIM) .IFF .SBTTL V001 (STAND-ALONE) .ENDC ; ; SATELLITE SCROLLER ; ; PROGRAM NAME: SCROL ; ; VERSION LEVEL: X0001J ; ; AUTHOR: HARRY E. KELLER ; (TAKEN FROM GT40 SCROLLER, COURTESY OF JACK BURNESS) ; ; DATE: 10 NOVEMBER 1975 ; ; COPYRIGHT (C) 1975 ; ; DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLU- ; SION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY OTHER ; COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE ; TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO ; AGREES TO THESE LICENSE TERMS. TITLE TO AND OWNERSHIP OF THE ; SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC. ; ; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS ; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; .SBTTL EQUATES ;SCROLLER FOR REMOTE-11 .IFDF RTSIM ;TO BE LINKED WITH RTSIM TO PROVIDE ;SCROLLING DURING EXECUTION OF PROGRAMS ;IN THE SIMULATED RT-11 ENVIRONMENT .IFF ;TO BE LOADED WHEN BOOTING A VT-11 BASED ;SATELLITE BY STARTING AT THE REQUEST ;SECONDARY MODE PROGRAM LOAD ADDRESS .ENDC ; .MCALL .REGDEF .REGDEF ; ;IMPORTANT ADDRESSES ; VTVEC=320 VT11PC=172000 VT11SR=VT11PC+2 DLICSR=175610 DLIBUF=DLICSR+2 DLOCSR=DLIBUF+2 DLOBUF=DLOCSR+2 KBCSR=177560 KBBUF=KBCSR+2 DLVEC=400 ; ;BOOT COMMUNICATION AREA ; .IFNDF RTSIM BFODES=156 $SENDDC=162 .ENDC $START=164 ; ;SPECIAL CHARACTERS ; CRLF=5015 ;CARRIAGE RETURN-LINE FEED DLE=220 SYN=377 ; ;VT11 INSTRUCTIONS ; DISJMP=160000 ;DISPLAY JUMP DISTOP=173000 ;DISPLAY STOP ; ;CONSTANTS ; NUMLIN=32. ; .SBTTL INITIALIZATION .IFDF RTSIM .ASECT .=VTVEC+10 .WORD VTBUSE,200 .CSECT SCROL START: MOV @#54,R1 ;GET HIGH MEMORY ADDRESS .IFF START: MOV @#164,R1 ;BOOT RESTART ADDRESS CMP R1,#160000 ;IS IT IN I/O PAGE? BLO 1$ ;NO MOV (SP),R1 ;YES: GET THE TOP OF MEMORY BR 2$ 1$: SUB #1000,R1 ;ADJUST FOR OFFSET 2$: MOV R1,R0 ;IT WON'T HURT TO ZERO MEMORY 3$: CLR -(R0) CMP R0,#END ;BUT DON'T WIPE OUT PROGRAM BHI 3$ .ENDC ;IFDF RTSIM MOV R1,R2 ;SET UP SCROL BUFFER TOP CMP -(R2),-(R2) ;R2=R2-4 MOV R2,JMPBEG SUB #12,R2 MOV R2,BUFHI SUB #2*NUMLIN-4,R2 MOV R2,JMPADD SUB #3000-NUMLIN*2,R2 .IFDF RTSIM MOV R2,@#54 ;RESET UPPER MEMORY BOUND .ENDC MOV R2,BUFLOW MOV #BUFEND,R0 ;READY TO PUT IN END OF BUFFER 4$: MOV -(R0),-(R1) ;MOVE IT BNE 4$ ;UNTIL WE HIT A ZERO MOV R1,R0 MOV R0,POINTR SUB #2*NUMLIN,R0 ;WHERE CRLFS WILL GO 5$: MOV #CRLF,(R0)+ ;PUT THEM IN CMP R0,R1 BLO 5$ .IFNDF RTSIM MOV #VTBUSE,@#VTVEC+10;SET UP TO CATCH VT11 TIME OUT MOV #200,@#VTVEC+12 ;PR4 .ENDC ;IFNDF RTSIM MOV #HEADER,@#VT11PC;START UP VT11 .IFDF RTSIM RTS PC .IFF MOV @#$START,R0 ;BOOT START ADDRESS TST (R0)+ ;GET #ENTTY INTO R5 MOV (R0),R5 INC R5 CLR R2 ;COMPLETION ROUTINE JSR PC,@$SENDDC ;CALL SENDDC MOV @#BFODES,R1 TST -6(R1) BEQ .-4 ;WAIT UNTIL I/O IS DONE BR DLINP ;DO I/O .ENDC .SBTTL ENTER DDCMP MODE ;ENTER DDCMP MODE ; ENTDDC: MOV @#164,R0 ;ADDRESS OF START OF BOOT ADD #370,R0 ;ADDRESS OF ENTDDC MOV (R0),-(SP) ;PUT ENTDDC ADDRESS ON STK MOV @#170,@#DLVEC ;RESET INTERRUPT MOV #STOPD,JMPBEG ;CLEAR SCREEN RTS PC .IFNDF RTSIM .SBTTL DL INPUT AND TTY I/O HANDLER ;DL AND TTY CODE ; DLINP: TSTB @#DLICSR ;ANYTHING HERE? BPL 2$ ;NO MOVB @#DLIBUF,R0 ;GET CHAR CMPB #DLE,R0 ;DLE CHAR? BNE 1$ ;NO CMPB LAST,#SYN ;WAS LAST CHAR A SYN? BEQ ENTDDC ;YES: GO ENTER DDCMP MODE 1$: MOVB R0,LAST ;SAVE LAST CHAR RECEIVED JSR PC,SCROLL ;SCROLL IT 2$: TSTB @#KBCSR ;WAIT FOR KEYBOARD RESPONSE BPL DLINP ;OR COMM LINE INPUT MOV @#KBBUF,R1 ;SOMETHING WAS TYPED BIC #-200,R1 ;RID GARBAGE 3$: TSTB @#DLOCSR ;SEND IT OUT BPL 3$ MOVB R1,@#DLOBUF BR DLINP .ENDC .SBTTL SCROLLING PART OF CODE ; ;DO SCROLLING ; SCROLL: CMP R0,#177 ;CHAR OUT OF RANGE? BGE RETURN CMP R0,#40 ;IS IT A PRINTING CHAR? BGE NORMAL ;YES MOV R0,R1 SUB #7,R1 ;MAKE A BELL=0 CMP R1,#7 ;TEST BHIS RETURN ASL R1 ADD R1,PC BR BELL ;7=BELL BR NORMAL ;10=BACKSPACE BR TAB ;11=TAB BR LF ;12=LINE FEED (LF) BR VT ;13=VERTICAL TAB (VT) BR FF ;14=FORM FEED (FF) ;15=CARRIAGE RETURN (CR) CR: MOV #-1,TABCNT ;RESET TAB POSITION ON CR NORMAL: JSR PC,INSERT ;INSERT CHAR IN BUFFER INC TABCNT BR RETURN TAB: MOV #40,R0 JSR PC,INSERT ;INSERT BLANKS INC TABCNT ;UNTIL TABCNT IS BIT #7,TABCNT ;A MULTIPLE OF 8 BNE TAB BR RETURN VT: MOVB (PC),R1 ;PUTS A 5 INTO R1 BR FFLOOP BELL: CLR @#VT11SR ;ANY MOVE RINGS BELL BR RETURN FF: MOV #NUMLIN,R1 FFLOOP: MOV #12,R0 ;LINE FEED JSR PC,LFSUB DEC R1 BGT FFLOOP BR RETURN LF: MOV #RETURN,-(SP) ;CALL LFSUB AND RETURN TO RETURN LFSUB: MOV JMPBEG,R2 ;POINT TO 1ST CHAR ON SCREEN MOV 2(R2),R3 LFLOOP: CMPB (R3)+,R0 ;LOOK FOR LINE FEED BEQ LFOUND ;GOT IT CMP R3,BUFHI ;AT END OF BUFFER? BLO LFLOOP ;NO: KEEP AT IT MOV BUFLOW,R3 ;AT TOP, RESET TO BOTTOM BR LFLOOP LFOUND: INC R3 ;AT A LINE FEED NOW BIC #1,R3 ;SET DISJMP TO 1ST CHAR PAST LF MOV R3,2(R2) JSR PC,INSERT CLR R0 INSERT: MOV POINTR,R3 MOVB R0,(R3)+ ;PUT CHAR IN BIT #1,R3 ;NEXT CHAR POSITION EVEN OR ODD BNE INSRTX ;ODD: NOPROBLEMS CMP R3,BUFHI ;EVEN: AT END? BLO INSRTL ;NO: MAKE ROOM FOR ANOTHER WORD MOV R3,R2 ;YES: RESET POINTER MOV BUFLOW,R3 ; TO BEGINNING OF BUFFER JSR PC,INSRTL ;PUT IT IN CLR (R2)+ CLR (R2) INSRTX: MOV R3,POINTR ;SAVE POINTER RTS PC ; INSRTL: CMP (R3)+,(R3)+ ;BYPASS THE DISJMP MOV #HEADER,(R3) ;PUT IN A NEW ONE MOV #DISJMP,-(R3) CLR -(R3) ;NEW SPACE AVAILABLE BR INSRTX ; RETURN: RTS PC .SBTTL STORAGE, ETC. .IFDF RTSIM .WORD START ;RTSIM WILL START US HERE .WORD SCROL ;FOR RTSIM LINK UP TO VTHDLR .RAD50 /SCROLL/ ;SO RTSIM WILL KNOW WE'RE HERE .ENDC VTBUSE: .IFDF RTSIM BIT #100,SCROL ;PSEUDO-INT ENABLED? BEQ 2$ ;NO MOV R0,-(SP) ;SAVE R0 MOVB SCROL+2,R0 ;CHAR? BEQ 1$ ;NO MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) CLR SCROL+2 ;FOR NEXT TIME JSR PC,SCROLL ;SCROLL THIS CHAR MOV (SP)+,R3 MOV (SP)+,R2 MOV (SP)+,R1 1$: MOV (SP)+,R0 MOV #200,-(SP) ;FAKE INTERRUPT MOV @#64,-(SP) ;WILL GO TO TTYOUT 2$: .ENDC ;.IFDF RTSIM MOV #DPURET,@#VT11PC;RESTART VT11 RTI ; .WORD 0 .WORD DISJMP .WORD HEADER .WORD DISJMP BUFLOW: .WORD 0 .WORD DISJMP JMPADD: .WORD 0 BUFEND: ; HEADER: .IFDF RTSIM .WORD DISJMP .WORD SCROL+6 RTHEAD: .ENDC ;IFDF RTSIM .WORD 103334 ;ENABLE CHAR MODE, BLINKING .BYTE 177,17 ;A BLINKING BOX--RUBOUT .IFDF RTSIM .BYTE 16,77 ;FORCE A SHIFT OUT INTERRUPT .ENDC DPURET: .BYTE 17,17 .WORD 116124 ;GO TO POINT MODE .WORD 171340 ;LOAD STATUS REGISTER .WORD 0,1352 ;POINT TO UPPER LEFT .WORD 103324 ;BACK TO CHAR MODE .WORD DISJMP JMPBEG: .WORD 0 STOPD: .WORD DISTOP ; BUFHI: .WORD 0 TABCNT: .WORD 0 POINTR: .WORD 0 LAST: .WORD 0 .IFDF RTSIM SCROL: .WORD 0 ;PSEUDO-CSR .WORD 0 ;PSEUDO-BUF .WORD NUMLIN .WORD DISJMP .WORD RTHEAD .IFF END=. .ENDC ;IFDF RTSIM ; .END START  "&*.26:>BFJNRVZ^bfjnrvz~  D tn &\Z*@0 LbC @ ( _BV  !dprtvhjlnfLN862401"(*&'  f CdCdW 27 v7 7 7 @A?P6?00?P$?0 ?P? x: 2HD7 7 7 0?P0P 0?P Hd  07P07 ?P0 +X ? nCGCGCGLCG?N?`?P?0 jC X‹X_  2? h F  ? ? /?  7 7 =bw  hdXRdhL F .40$M$ - 7 ] U@U@E % E@E@%Eb^Z-HO  @-8_ 0 (7 & ^X-_  ? RPHF5>5,"|dLH>645, x 6? %6e : |~z?te `X/T~Av h`dERH5@/<6&5/  /z| C Vd$@M B5/"|5t-n /dTXNJE: X 02B   !"#$%&'()*!d+,-./0123456789:;<=>?@@?>=<;:9876543210/.-,+*)('&%$#"!  dB ,%Ee@EeVEeEeEeEg7,Ee,UU%UU0,0,1,p,1,p,%7-7-UU'UUtd> 'UUp7Lf-bUUT7LJ-FE'UUEUU -7UU7UU0  0  p  p      d     0 %0 %p  p      eHB!'%'%''G UU;d E%UUG'UU bnh d  _ %UU  %  ' %/%/%''O UUE%UUOTddX-\> (B0  o% e %o'?   %UU  %  '? % t  ^ .%9.7N%`dE'UU9N%UUץUU001p1p7 ׭ 7 ׭ U𕪪קUUקUU 7d ׭ U 7̰ ׭ ŪקUT UUN ׭J 0ߋ0'0'0ߋpߋpߋߋ'ߋߋߋ+dr0'0'p'p'% קקߥߧߕ߭H ߗ߭6 '_%U_%U %d  ' ߕ%ׯ     ߭n d t ߭\ N UUŪR ߥUU" 2 ߭* ?$ ߋ ߥUU ߥ ק?ߥ%ߋ }d.9P7ΰJDŪקU7&7*7('9ΰ%UUU    .x7u%.Sf.X7U%.F.8wd5%.N&.w%.O-- b ^ -V?*LLw H7 D7 @7 <7 8w 4w 0w , -   R%E777www -777wwdw -`\ w:@ < %2((m"-    7 >7 >w 6 6-.0w $ 7 7 w  w7 7 w w7 e%  x x_H ߥ.dH  7 7 -  w%@0w?  %?   H? %%PU@%v lhVRT Hd%U< %%UUDF5@@> xEe jj  5xj w . "V V" _H_  = A)E``zxjh7fh hZXV TFD0 @.,*d&$ d7 V5Vw vt7 7  nhw dM`m^^ \-VePLmBB7 @7 > <m*( $j?b X5@~ 5v - 7 _ (7 &f&fzRb&?b?Z?X zUU YUUt 7 ) eDz '"5h:_ ?_ __ _ _ _  %$b%(%,%0%4     ( "+ $. &1 (4 *7   ` @  Ȫ⨞||−\[h<;Hz(n@ _H "&*.26:>BFJNRVZ^bfjnrvz&*@d2 xvt7 *8(,  / '/#(  "'"t7 00*b  X77 .w *@( t-5  5 w" w\5 B . ^B |5t5j &5@X @"5 Hw84*(<8 @  / /!:,FOR SCOPE-CLEAR HALT SW.-SET SCOPE SW.-CONTINUE,@RESET SCOPE SW. ANYTIME TO RETURN TO PROGRAM.,7 7 dN @8hbw ^MZmXX V-PeJFm<<7 :7 8 6m$" ? 8qEQ( UU(/SET MEMORY ADDRESS LIMITS VIA SWITCH REGISTER@SET LOWER LIMIT IN SW-REG AND PRESS CONTINUE@SET UPPER LIMIT IN SW-REG AND PRESS CONTINUE@UNDEFINED LIMITS WILL BE SET TO 2050-17470@LIMITS BELOW THIS RANGE WILL BE DEFAULTED/d "&*.26:>BFJNRVZ^bfjnrvz~ "&*.26:>BFJNRVZ^^bfjnrvz~M&bR*@:6pf&f&l=  _6 POWER FAILED   0 Nd5U5@xN_5xߗx5x  5xD  `!`  "( &e&  ֥ D ߋtv   C  C Ԝ  x5 x; b ~z X H B dH@      @     @     fQPPP%@   B  ĕa    B     5*f BFHd-  &f&f  J J J      J  J     KLˌ ˊ #dLL̊ ̊ˊ̋ ˌK% e    $ % U  d     %!@  Udb bU%RҊ"Ջҋ$    +    + \  l \     j4d -ڌj]  (w w  7 7     w tf% g7 w~d w7ywl7_wSF:/ w e Z         : : z z d|  z   zz::zzz `   00 P@D @D  cdD P C  `$ e! % %%ĵUD%UЄ  $ # K b"2L  RB" L bK be d8 % B" Jʌ ͊ J  PJJʋ %D$#"JJJ͒JKJ ̢K͢   ̊̒dW)X" M DU 8TEU ( R d  㕀Ԥ@ (e) B " Ue :&j fJm & ( # # $ $ܕ%(%++++5 \  %UU_drM< ,l 2@l r <r ,, UUUt (( #(  / oOdR_/ 7 :ǡ1`NjG "e'Ƿg)- Me Z  (00 00    ccce ;;|%z=   gd` J DZ [+¿?eU@ e H  e[B     B % d $  eB k   B w g B  BaJ '    c! aB aNd  @ c! $#  Bc   $ g @  g@@ @  Jg e5dl e Z x ߋ    ׭   e^e<e #ߥ  d\Y6 _@(e6  a  QP@%ߋ%e@Lgdߥeߵ 7 Hg, g  ? z}?? p j & e v U0 0 P @ e&Εeƕ # %   c %!d(!e &eP %  e Z 5@t4644ߟ0vߋt t t  xߟv  @BU@f&ߵ"ߕ4ߋt4 @ 7\4@ `  & 5@tߋx8 0U@t 7,zw0 Lr  Rn5R5@tߋt ߋx B" _ LOW LIMIT?HIGH LIMIT? THIS TEST INVALID FOR 11/40-11/45 PLEASE RUN DCQKC DZQKC DONE1LLTq( 7"w* 0[NOT ENOUGH SWAP AREA AVAILABLE] * zhzzTING MOVE ? MOV #BOARD+42.,R1 ;ADDRESS OF ACTIVE BOARD MOV #IOBORD,R2 ;ADDRESS OF IO BOARD MOV #78.,R3 ;NUMBER OF ACTIVE SQUARES 10$: MOV (R1)+,(R2)+ ;COPY CURRENT BOARD DEC R3 BNE 10$ RTS PC ; INPUT A POSITION COMPEQ: CALL COMRE ;FIRST RESET EVERYTHING CLR CHRONE ;GET MOVE NUMBER CALL GETNUM MOV R0,MOVE ;IN CASE ITS IMPORTANT TO THE POSITION 7&.2XwRO PIECE SUM MOV #BOARD+182.,R4 ;START WITH BLACK'S BACK RANK 10$: CALL FLUSH ;FIND THE END OF THE LINE MOV #8.,R2 ;8. SQUARES IN A RANK 15$: CALL GETC ;GET A CHAR MOV R0,R3 ;SAVE IT IN CASE ITS A PIECE COLOR SUB #71,R0 ;IS IT A NUMBER ? ADD #11,R0 BCC 30$ ;NO, MUST BE A PIECE BEQ 60$ ;ZERO IS ILLEGAL CMP R0,R2 ;ENOUGH SPACE LEFT ? BGT 60$ ;NO, ERROR 20$: CLR (R4)+ ;CLEAR THE SPACES DEC R2 DEC R0 ;DECREMENT THE COUNTS BN G DP D    EW 04eNB`C wN RJ 173 t vBpUX$ *wlING MISSING ? BEQ 50$ ;YES, BAD TST BKING ;CHECK BOTH BEQ 50$ .IF NE,BOOKOP MOV #-1,BOOK ;KILL BOOK .ENDC RTS PC ;OK, DONE 30$: CALL INPIEC ;GET THE PIECE VALUE MOV VALUE(R1),R0 ;GET PIECE VALUE CMP R3,#'W ;IS IT WHITE ? BEQ 40$ ;YES, JUST STORE IT CMP R3,#'B ;BLACK ? BNE INERRzz zzzzv@zρ$[PAGE][00000 LINES READ IN]4ptrv 013:::;AND INCREMENT PIECE COUNT DEC R2 ;REDUCE COUNT BR 25$ ;SEE IF END OF RANK 50$: CALL COMRE ;KING MISSING, RESET BOARD 60$: BRND GIVE ERROR MESSAGINPUT A MOVE 7 CLR IOMDW ;CLEAR MDW FOR INPUT MOVE CLR IOTO ;AND THE TO ADDRESS CLR IOFROM ;AND THE FROM ADDRESS CLR CAPIEC ; eNB`C wN  RJ 173 BwECE MOVING MOV R1,IOPIEC ;SAVE IT ; LOOK FOR MOVE OPERATION 10$: CALL GETC ;GET THE OPERATOR CHARACTER CMP R0,#'- ;SIMPLE MOVE ? BEQ 30$ ;YES CMP R0,#'* ;CAPTURE ? BEQ 20$ ;YES CMP R0,#'X ;CAPTURE ? BEQ 20$ ;YES CMP R0,#'# ;ENPASSANT CAPTURE ? BEQ 15$ ;YES, TREAT SPECIALLY ; FROM SQUARE DESIGNATION CMP R0,#'/ ;FROM SQUARE DESIGNATOR ? BNE INERR ;NO, BAD INPUT TST IOFROM ;PREVIOUS FROM SQUARE ? BNE INERR ;YES, TWO IS BAD CALL INSQAR ;OK, GET THE FROM SQUARE MOV R1,IOFROM ;AND SAVE IT BR 10$ ;GO BACff ; ENPASSANT CAPTURES 15$: MOV #ENPASS+CAPTUR,IOMDW ;MDW FOR ENPASSANT CAPTURE BR CHKLGL ;GO SEE IF LEGAL ; NORMAL CAPTURES 20$: BIS #CAPTUR,IOMDW ;SET CAPTURE BIT CALL INPIEC ;GET PIECE TO BE CAPTURED MOV R1,CAPIEC ; TO SQUARE DESIGNATION CALL GETC ;GET POSSIBLE TO SQUARE DESIGNATOR CMP R0,#'/ ;SLASH PRECEEDS SQUARE NAME BNE 40$ ;NO 30$: CALL INSQAR ;GET TO SQUARE MOV R1,IOTO ;SAVE IT CALL GETC ;POSSIBLE PAWN PROMOTION ? ; PAWN PROMOTIONS 40$: CMP R0,#'= BNE CHKLGLxxT CHECK FOR ILLEGAL MOVES CALL INPIEC ;GET NEW PIECE INDEX MOV PROMDW(R1),R1 ;GET MDW OF PROMOTION BEQ INERR ;P=P AND P=K ARE ILLEGAL BIS R1,IOMDW ;ADD SPECIAL MOVE BITS TO MDW BR CHKLGL ;SEE IF MOVE IS LEGAL INERR: .PRINT #ERROR ;SOMETHING WRONG WITH THE INPUT SEC ;SIGNAL ERROR RTS PC ; CASTLING MOVES INCA: CLR CHRONE ;FORGET THE FIRST TWO CHARACTERS MOV IOWK,R1 ;ASSUME WHITE INPUTTING MOVES MOV #KING,IOPIEC ;A KING IS THE MOVING PIECE TST IOWHO ;WHO ACTUALLY IS ? BEQ ff zz zzzzv@zЁ$[PAGE][00000 LINES READ IN] 13OMDW ;SET BIT TO INDICATE O-O CALL GETC ;SEE IF THERE IS ANOTHER "O" CMP R0,#'O BNE 20$ ;NO, NOT QUEENS SIDE CASTLING SUB #1 UP TO ADDRESS MOVIOMDW ;AND M 7ITY CHKLGL: CLR R0 ;CLEAR MOVE FOUND ADDRESS 5$: MOV (R5)+,R1 ;MDW OF MOVE MOV (R5)+,R2 ;TO ADDRESS MOV (R5)+,R eNB`C wN RJ 17:3 BwSSUME A MATCH CMP R3,IOFROM ;SAME FROM ADDRESS ? BNE 5$ ;NO, TRY AGAIN 10$: TST IOTO ;TO ADDRESS GIVEN ? BEQ 20$ ;NO, ASSUME A MATCH CMP R2,IOTO ;SAME TO ADDRESS BNE 5$ ;NO, LOOK AGAIN 20$: CMPB IOBD(R3),IOPIEC ;IS IT THE CORRECT PIECE ? BNE 5$ ;NO CMPB IOBD(R2),CAPIEC ;DOES THE CAPTURED PIECE MATCH ? BNE 5$ ;NO MATCH BIC #77770,R1 ;COMPARE CAPTURE AND SPECIAL BITS CMP R1,IOMDW BNE 5$ ;DON'T MATCH ; CHECK FOR MOVE AMBIGUITY TST R0 ;ANY PREVIOUS MATCH ? BEQ 40$ ;NO, ITS OK SO FAR .PRINT #AMBIG ;AMBIGUOUS MOVE JJIGNAL ERROR RTS PC ;TRY AGAIN 40$: MOV R5,R0 ;SAVE MOVE STACK POINTER OF MATCHING MOVE BR 5$ ;MAKE SURE ITS UNIQUE ; MAKE THE MOVE IF LEGAL 50$: TST R0 ;ANY MATCH ? BNE 60$ ;YES, MOVE OK .PRINT #ILLMOV ;PRINT ILLEGAL MOVE SEC ;SIGNAL ERROR RTS PC 60$: MOV -(R0),IOFROM ;GET THE MATCHING MOVE PARAMETERS MOV -(R0),IOTO MOV -(R0),IOMDW .IF NE,THINKA CLR IKNEW ;CLEAR THE CORRECT GUESS SWITCH CMP IOFROM,THINKF ;COMPARE ACTUAL MOVE MADE BNE 65$ ;WITH MOVE THAT MACHINE GUESSED CM\\NKT ;AND IF EQUAL, SET THE I KNEW SWITCH BNE 65$ ;WHICH MEANS THAT IF THE MACHINE IS CMP IOMDW,THINKM ;FINISHED THINKING ABOUT A RESPONSE TO BNE 65$ ;THE GUESSED MOVE, IT CAN USE IT AND INC IKNEW ;APPARENTLY MAKE AN INSTANTANEOUS REPLY 65$: .ENDC CLC ;INDICATE SUCCESS RTS PC ; INPUT A SQUARE NAME INSQAR: CALL GETC ;GET FILE NAME MOV R0,R2 ;FIRST CHARACTER CALL GETC CMP R0,#101 ;IS SECOND CHAR A LETTER ? BGE 1$ ;YES MOVB R0,CHRONE+1 ;NO, PUT IT BACK MOV R2,R0 MOV #4JJzz zzzzv@zс$[PAGE][00000 LINES READ IN]  13 FILE NAME LIST BEQ 20$ ;GOT IT DEC R1 BPL 10$ ;KEEP LOOKING BR INERRL 20$: CALL GETC ;NOW GET THE RANK NUMBER SUB #71,R0,R0 ;IS IT 1 TO 8 z IS INPUTTING MO W&@. H  '&uDB@w0 DD .5>5  "ن,3) 6ŀ   ȋ HЕ Е  W @.=.e*D&@.&"'&uDB@w0 h ) R55    :   $ B ' 0%( w!w w w E5UX57*5X & >l bPeW!& bNB Е PH<& EXe F EX7UX7 5><@a Hoe 52%  $ % e, e& ȋp zɋFZ5Tz5Rnlual= l$@ "ua"E}VU@V5 @5 X =l l nAaW W@'DaW ZD5R5555WEVw ,$ oua uax+ 7AW u  $ w x+A HwI @   $ vwn2T>) Hue 042 $ $ :52 T2$  ,ePP"P P$B*< )& d& ^uDB"@ B<@a1 >"GO7B*J,r.wW W uef& ABa W W@ WZR wы u 5 4&@-u 4+* <+0"  5 2,/5X%  ) |%wDm%w@Z5X9E& e ` 5 4 EX "& / e0e %'d 5 j5 l5 n5 p5 rtRfW W W:B x t4jBaR W uW/W[W.  W u W.NpBaыj@a A?m@a v9p@a h2 W[ W uW] & e & N09Ee W/ WLW5@ef WA W0 W:   WZW9. e C` eUXEXAB B ~ dR . VRu: 6  T :RA:B65Xɋu3 W W u   $ W. W. W.W. eREMOTE V01-X003A[ILL CMD][SYNTAX ERROR]FILE: [WAITING...][NO BACKGROUND] [BACKGROUND REQUIRED!] [DEVICE ERROR][NO DEV][DEV NOT LOADED][SWAP ERROR][DIRECTORY ERROR][FILE DOES NOT EXIST][ILL STRING CONST][LINE DELETED][TOO MANY CHARS][ILL NUM][*EOB*][*BOB*][*EOF*][BUFFER EXCEEDED BY][NO FILE OPEN][CREATING NEW FILE] INPUT[EXIT][BACKUP FILE CANNOT BE EDITED BECAUSE FILENAME "XXXXXX.NEW"] [IS CURRENTLY IN USE. RENAME BACKUP FILE OR "XXXXXX.NEW"][NO MATCH][REOPENING FILE][SECONDARY FILE ALREADY OPEN][ILL NAME OR SECONDARY FILE NOT FOUND][SECONDARY FILE CURRENTLY SELECTED FOR INPUT][ILL FILE NAME GIVEN IN CLOSE OR EXIT] [FILE WAS NOT RENAMED][ALREADY PASSED THAT PAGE!][CONCATENATING CHAR CHANGED TO "$"][ILL "SAVE" FILE NAME][FILE AREA ALLOCATED EXCEEDED, ORIGINAL FILE STILL OK][ILL IN BLOCK ON MODE][ILL IN BLOCK OFF MODE][NO LINE OR NOT ENOUGH LINES IN BUFFER TO COMPLETE REQUEST][NOT ENOUGH ROOM ON DEVICE FOR FILE SIZE REQUESTED][BUFFER > 7/8 FULL][FILE NAME CURRENTLY IN USE BY SOMEONE ELSE][EDITED FILE IS NAMED "EDIT0N.TMP" WHERE "N" IS YOUR USER NUMBER][EDITED FILE IS IN "EDIT0N.TMP", RENAME IT IMMEDIATELY OR IT WILL BE DELETED][ILL CHAR][OTHERS STILL EDITING][USE "@EXIT"][NOT ENOUGH BUFFER ROOM FOR BLOCK-ON MODE][MACRO NUMERIC ARG UNDEFINED][MACRO UNDEFINED]_X 0BL OFFTPAG% OP%NN-% M1 ADD AP BEGIN BLOCK BOTTOM CHANGE CLOSE CLOSES CC DELETE DP DUPLICATE END ERAS ERASE EXIT FIND FILL FF INSERT KIL KILL LOCATE LC LIST M MACRO NEXT NP OVERLAY OUTPUT OPENS OLDPAGE PRINT PASTE PAGE PFIND PLOCATE RETYPE READ RENEW SEARCH SIZE SAVE SP SS TOP TOF TYPE UN UNSAVE VERIFY VERSION WRITE C\DfI"I*G|DG=9AA6*G@H GB>v6C@>`C(FAF$:A~B69J=IA"FJBBCKIj7::(>V>fIIA@8<9::L EXIT SEND RDVV BJ f&N$%e e+ee  >&T  e e! 8 2 , & W 5X ae$$ $ $u( e&@"5.ȋV5XV  @WBa0 p EX&  z@a5 EX t5 %  j c%  w.B"5XVu-&J0 &fB& z& WV#. WzBa5 0 eEXU X5VBa0V% Dw&8.ua.= .2   L  5 $uJ&  5 V f@ ~w ХOȥN ХF ХFu@VuPV $ w&DBa "& #e    EN`"% Lw7f2@$56+ W  W    565$u6&D&fC  e 4B&D$ Jf ~&5$ 7j D&D$$D$f  @5$e 7:7 2*&BP` Jf&fP c c      l@a&f     @W    Е Е ~ѕ 7P @  &  72 ~ 0 & 0&D 4#   & 0  Õ Õ .1 ,& @1 ~ EB%ꐊ " & |1@ & 1 `7  `7 v`7@"EwDa|E A1 )`(00}0~ ,V V V V $6< w*www5D5= U@ <  $\ # 4#  5UX5Õ$   w w75X ,} C  xu  lUX5 E@VEdXC  J נ  >5 5  נ Õ\ 5 7 4#e  `7  `7 `7D BA& 1 4#UX5 + W W$  }$W  qW$ 1  u(}$ ! I) $ = wv  f&f &e@7 ^uuu5 4 .-O@a +@a   % 0w\—* (% 0 @a +@a ߋ*݁u@a `+V@a L@a ZV @e25@ @a +@a @a ߋ*-( 0  w`5 @5 -5 U@VW& 0 W& 05 x5 ua5 z5 |TV Vwuwx% D0w>5  0z,w< 5w|u(wz 5 ( -wT w5wPuwN VwJ u:u8@"Aae  z, 8 -w Aa@"BeP  z,A z-w : ( dz, ^-w Tz, 55 F52w* u"eW w @535535 w u7w  +-D *  0 9 Ef e `   M u`u-uCCm"C-ăD( BB` BCCm"    !D"5EJu(BAa Bҕ ҕ B" z,A" uBaW A"u (Vw z, -wu"umwC0 Ba \-wzB"BmAa eJ  ҕ ҕ B"w B"w,I  Dw w 54  @4w 5 .w85@ .A wu5$ 05wDuA56@a@`ȕ@Bae  >#@Vҕ ҕ 5Xu4 ) 6UXE$Xw5Xw\5wLwNuwRVwB5RuHuR5 @wwu(A w Da 3 @ @@a ~+v@a ptUX@a r—*(%w-( 20Mt' &0wBarJ5 @au  b.u".Ba0 , ( z, -w EXBa -@a5  b. EX5 wvVw5uuRA @w Da ^@a 4+@a &UX@a (—*(%:%wwTBa   R~J@au  b. z,@"5.Ba0 : ha( 0t' z0w@aw5W&DaTRA —*(%& $0w@a +@a @a և WBa   R~Jw25W%  W@a b.0W5 W@a rb. hb. W5W W@a  vz, r j-w 5 X-w Nz, (5X%WUX B fCU@XVwz5 H7 7@U@XHE@X z, -w" .u"ue7#5@X  V%EX  -5X% j0wwP (5@X H V@"E@X Jz, D-w" u"ue7*  5@X   (A w z, 0@" EXA wr@"54 4   4W/4RЕ Е wpP 4u W W ȕ 45Xw wW UX P% D0EXwEXu"eA" wW X L' 0ww(5 F@535535  54 53Ћ@4u7m DXBC43ע Ҕ ` D"9 Cפ B` `D"! jt% 0@" EXw BC4 3ע Ҕ "@" FXL @"X& F f& 0EX7 (wdE@Xw(5 HUXu"ewL H V@" \j0 ( Pz, J-w EXwumFH n u4UXw@V u(wV&u#@a@`ȋ) 0w@ae w" BUXuww wՀWŀWVVE X zz, t-w w&VWWw*E@XwV 7ŀVU X $z,Ba0 - ( "5 XՀVVuuuuu@a +@a 5 A w(Da  & 0( 0wuuuuR@a \+@a jTWW4  >% &0 wU) 0 wEV5 @q& 0w5 5 5 5 w4u( -V (8w&uH (07^ u-H -w5 ( BV .u0V U@X7  B0UV7EVwVV >- VWwwwz#V u )UXww`WP' 0w4w6 fU@X7Zu(7jP u-( @W  Aa @a0  0@a \0W $a( B0@ Aa d@a &05Xwwj) RUXՀVA 4' 0EXwL -EXw( UXww c) 0ewu(7> (W Pa( n0@Aa @a T0q7$WWUXwUX ,-w<EX z, +f&N$%$ FW  -5X&% 0EX u-5X u-WV&@Aa @a 07  wDw7> bz, \- V-wUX Fz, UX 2z, ,-V%w5 L0$: BITB (R3),PINS(R0) ;IS PAWN PINNED IN ANY DIRECTION BUT THIS ONE ? BEQ PROMCK ;NO, CAPTURE IS OK NOCAP: RTS PC ;PINNED PAWN ; ENPASSANT CAPTURES ENPCHK: MOV -(R0),R3 ;GET VALUE OF POSSIBLE ENPASSANT CAPTURER ADD COLR,R3 ;IS IT MY PAWN ? CMP R3,#PAWN BNE 20$ ;NO, FORGET CAPTURE TST COLR ;WHICH COLOR ? BEQ 10$ ;WHITE, P  `acd12:;?@z}~ D E G H   #(* Y c f i o pt xz {~tz [dlwz} 5"7z,<VY`z̘Әژl™əЙ^qt  58BU}r F@G_b}!&<Akxz2 5 N V ` c i l t !!!%!.!3!=!E!H!d!g!!!!!!!!5"8"X"[""""#,#2#5#g#j######$$$$,$D$G$J$N$Q$\$_$r$$$$$$$,%6%9%G%a%d%m%%%%%%%%%%%&)&,&/&7&A&D&P&7z,<VY`z̘Әژl™əЙ^qt  58BU}D, FOCAL WILL ASSEMBLE AS A PAPER-TAPE ; VERSION. DEFAULT IS RT-11 VERSION. ; ; IF "$TRAP" IS DEFINED, INTERNAL CALLS WILL BE VIA ; A TRAP INSTRUCTION. THIS WILL TAKE LONGER, BUT CORE ; SIZE WILL BE REDUCED BY APPROXIMATELY 350 WORDS. ; ; IF "$SMALL" IS DEFINED, FOCAL-11 WILL ASSEMBLE MINUS ; THE FOLLOWING FEATURES: ; ; 1. ERROR INTERCEPTION ; ; 2. EXTENDED VIRTUAL FILES ; ; 3. FLN,FLOG,FEXP ARE NOT AVAILABLE ; ; 4. SCHEDULING BY EITHER TIME OR INTERRUPT ; ; 5. USE OF QUOTES IN LIBRARY COMMAND ; .GLOBL $DBL ;DOUBLE PRECISION SWITCH ; ;--- NOTE: THIS VARIABLE ($DBL) SHOULD NOT BE DEFINED IN THIS ; MODULE. IT IS A RUN-TIME DOUBLE PRECISION SWITCH. FOR THIS ; REASON, THIS VARIABLE SHOULD NEVER BE USED AS A BASIS ; FOR CONDITIONAL ASSEMBLY. ; .IFDF $PAPER .IFDF $SMALL .TITLE FOCAL - 4K PAPER-TAPE VERSION .IFF .TITLE FOCAL - 8K PAPER-TAPE VERSION .ENDC ; ;--- PAPER TAPE VERSION: .IFF .IFDF $SMALL .TITLE FOCAL - 8K RT-11 VERSION .IFF .TITLE FOCAL - 12K RT-11 VERSION .ENDC ; ;--- RT-11 VERSION .ENDC ; ; OPTIONS USED: .IIF DF,$PAPER,; $PAPER .IIF DF,$TRAP,; $TRAP .IIF DF,$SMALL,; $SMALL ; ; SUPPORTS: ; UP TO 28K CORE .IFDF $TRAP ; INTERNAL CALLS VIA TRAP INSTRUCTION .IFF ; INTERNAL CALLS VIA JSR INSTRUCTION .ENDC .IFNDF $SMALL ; EITHER SINGLE OR DOUBLE PRECISION PACKAGE ; (LINKAGE OPTION) .IFF ; SINGLE PRECISION ARITMETIC ONLY .ENDC .IFDF $RT11 ; DYNAMIC MEMORY ALLOCATION ; FULL LIBRARY CAPABILITIES ; VIRTUAL FILES ; UP TO 8 USER FILES ACCESSED AT ONE TIME .ENDC .IFNDF $SMALL ; FOCAL INTERRUPT SCHEDULING PROVIDED ; ASYNCHRONOUS TASK SCHEDULING BY TIME .ENDC ;DOCUMENTATION NOTES: ;DOUBLE QUOTE MARKS DENOTE TRAP-INSTRUCTION MODULES ;(X) MEANS THE CONTENT-OF-X. ;ASTERISKS DENOTE COMMAND MODULES. ;"C.R."MEANS "CARRIAGE RETURN". ;SINGLE QUOTE MARKS DENOTE A SUBROUTINE. .SBTTL ASSIGNMENTS OF REGISTERS ;AS USED GENERALLY TEMP=%0 ;SCRATCH AC=%1 ;ACCUMULATOR PTR=%2 ;VARIABLE POINTER AXOUT=%3 ;TEXT READER CHAR=%4 ;CHARACTER R5=%5 ;EXCEPTIONAL USE REGISTER AND RUBOUT PROTECTION R4=%4 R3=%3 R2=%2 R1=%1 R0=%0 ;TEMP REG USED BY RT-11 PATCH ROUTINES.. SP=%6 ;STACK POINTER PC=%7 ;PROGRAM COUNTER PDP-11 ONE=200 ;SWITCH ASSIGNMENTS ALL=1 NALPHA=20 ;0=TERMINATE ON ASCII CODES ;1=TERMINATE ON ;;C.R.ALSO CR=216 ;INTERNAL CODE CRLF=05015 ;FOR USE IN "PRINT2, CRLF" STATUS=177776 PSW=STATUS ;PDP-11 PEOPLE ARE FAMILIAR WITH THIS... .IFDF $RT11 .SBTTL RT-11 DEFINITIONS AND MACRO CALLS ; .MCALL .TTYIN,.TTYINR,.TTYOUT,.TTOUTR,.PRINT,..V2.. .MCALL .SRESET,.SETTOP,.RCTRLO,.HRESET,.DATE,.GTIM,.GTJB .MCALL .LOOKUP,.ENTER,.FETCH,.RELEASE,.DSTATUS,.CLOSE .MCALL .WRITW,.READW,.WAIT,.CSISPC,.EXIT,.TRPSET .MCALL .GTJB,.PROTEC,.SYNCH,.INTEN .MCALL .MFPS,.DEVICE ; ;--- FOLLOWING ARE MONITOR PARAMETER LOCATIONS FOR RT-11 ; .GLOBL RESTRT ;START ADDRESS .GLOBL STACKP ;STACK POINTER (INITIALLY 1000) .GLOBL JSW ;JOB STATUS WORD .GLOBL RESBIT ;RESTART BIT (SET=YES) .GLOBL TTYSPC ;TTY I/O MODE (SET=SPECIAL) .GLOBL IOHALT ;HALT ON I/O ERROR (SET=YES) .GLOBL USRADD ;ADDRESS FOR USR SWAPPING .GLOBL HICOR ;HIGH CORE ADDRESS .GLOBL EMTERR ;EMT ERROR CODE .GLOBL RMON ;RMON START ADDRESS .GLOBL FILCHR ;FILL CHARACTER .GLOBL FILCNT ;COUNT OF FILL CHARACTERS NEEDED (0=NONE) ; ;--- USRLD - RT-11 V2-01 OFFSET TO START OF NORMAL USR AREA. N.B. - IF ; A NEW VERSION OF RT-11 IS USED, THIS MAY HAVE TO CHANGE! ; .GLOBL USRLD ;OFFSET INTO THE MONITOR FOR USR SWAP ADDR ; .GLOBL RMCNFG ;OFFSET TO RMON CONFIGURATION WORD ; ;--- USE RT-11 VERSION 2 MACRO CALLS ; ..V2.. ;USE V2-01 .ENDC .SBTTL FOCAL-11 FLOATING POINT DEFINITIONS ; ;--- ALL FOCAL FLOATING POINT OPERATIONS ARE PRECEDED BY A FPMP ; TRAP CALL. THE FOCAL FLOATING POINT PACKAGE IS REENTRANT, AND ; ACCEPTS WORDS AFTER THE CALL AS INSTRUCTIONS TO BE ; INTERPRETED. RETURN IS TO THE FIRST WORD WHICH DOES NOT ; HAVE A BASE OF "EMT". NOTE: OUR "EMT" IS NOT THE SAME AS ; THE MACHINE'S, IT IS ACTUALLY AN ILLEGAL INSTRUCTION ; ;FLOATING POINT HANDLER FOR FOCAL-11 ;ARITHMETIC OPERATIONS ARE NUMBERED 0-7: ;THE ADDRESSING MODES ARE NUMBERED 0-7: EMT=007000 FGET=EMT+00 ;POSSIBLE ERRORS FADD=EMT+10 ;OVERFLOW FSUB=EMT+20 ;UNDERFLOW AND OVERFLOW FDIV=EMT+30 ;DIVIDE BY ZERO ERROR ;ALSO SIGNIFICANCE ERRORS FMUL=EMT+40 ;AS FDIV ABOVE FPOW=EMT+50 ;IF LOG AND EXP FUNCTIONS AVAILABLE, ; NO ERROR IS GIVEN OTHER THAN OVERFLOW ; AND UNDERFLOW. IF NOT AVAILABLE, ; THEN ONLY INTEGER PORTION OF POWER WILL ; BE USED. FPUT=EMT+60 ;NO ERRORS (WORD TRANSFER) FINT=EMT+71 ;OVERFLOW ERRORS FSGN=EMT+72 ;NO ERRORS FABS=EMT+73 ;NO ERRORS FNEG=EMT+74 ;NO ERRORS FLOAT=EMT+75 ;NO ERRORS FZER=EMT+77 ;NO ERRORS ; ;--- 100 TO 177 UNUSED ; FCODE=EMT+200 ;COMPUTED OPERATION IN AC ;--- 201 TO 377 UNUSED ; ;--- ADDRESSING MODES: CORRECT MODE IS TO BE ADDED TO THE CORRECT OPERATION ; I.E.: FPUT+INTO+STACK ;PLACE THE FLT. PT. ACCUM INTO THE STACK ; ; FADD+REL,FONE-. ;ADD ONE (RELATIVE ADDRESSING MODE) ; DIRECT=0 ;ABSOLUTE (FADD+DIRECT,ADDR) (NON-PIC) IPTR=1 ;@PTR XPTR=2 ;AUTO INDEX PTR BY APPROPRIATE VALUE. ; FOR SINGLE PRECISION PACKAGE, THIS IS ; TWO WORDS; IN DOUBLE PRECISION, FOUR. ; INDEX IS PERFORMED AFTER USE!!!!! INTO=3 ;STACK (USES FOUR WORDS ALREADY ALLOCATED) FROM=3 ;STACK " THROUGH=4 ;STACK HOLDS THE ADDRESS OF THE AREA IMMED=5 ;DATA FOLLOWS THE CALL (4 WORDS AT ALL TIMES) REL=6 ;RELATIVE (ADDR-.) FOLLOWS CALL ; STACK=0 ;PROVIDED FOR READABILITY ;"DIRECT" AND "INDEX" ARE FOLLOWED BY COMMA AND ADDRESS. ; ;--- TO DEFINE A CALL TO A ROUTINE, SPECIFY: ; ; DEFINE (CALL NAME),(ROUTINE NAME) ; ; .MACRO DEFINE .A,.Z .GLOBL '.A' .MACRO '.A' .B,.C .LIST MEB .WORD '.A' .IIF NB,<.B>, .WORD '.B' .IIF NB,<.C>, .WORD '.C' .NLIST MEB .ENDM '.A' .ENDM DEFINE ; ; DEFINE SORTJ,SORTB ;SORT AND BRANCH ON (CHAR) (TABLE VECTOR JUMP) DEFINE SORTC,SORTD ;SORT CHARACTER (TRANSLATE) DEFINE PRINTC,OUT ;PRINT CHAR-S DEFINE READC,CHIN ;READ DATA INTO CHAR AND PRINT IT-S DEFINE OUTCH,XOUT ;OUTPUT TO A DEVICE DEFINE INCH,XI33 ;INPUT FROM A DEVICE DEFINE GETC,GETX ;UNPACK A CHAR-S DEFINE PACKC,PACKX ;PACK A CHARACTER-S DEFINE TESTC,TESTX ;RETURNS ON (CHAR)= DEFINE GETLN,GETLNX ;UNPACK AND FORM A LINE NUMBER DEFINE FINDLN,FINDX ;SEARCH FOR A GIVEN LINE DEFINE PRNTLN,XPRNTL ;PRINT (LINENO) DEFINE COPYLN,COPYLX ;READ NEXT LINE NUMBER DEFINE START,STARTX ;RETURN TO COMMAND/INPUT MODE DEFINE SPNOR,SPNORX ;IGNORE SPACE-S DEFINE ERASEV,ERVX ;ERASE AND SET VARIABLES DEFINE ERASET,ERTX ;ERASE TEXT DEFINE PRINT2,PRIN2A ;PRINT 2 CHARACTERS DEFINE DIGTST,DIGTSA ;TEST FOR DIGIT OF INDICATED PLACE VALUE DEFINE PARTST,PARTSA ;CHECK FOR PARENTHESIS MATCH DEFINE GROOVY,GROVX ;COMPARE GROUP NUMBERS DEFINE SKPLPR,XTSTLP ;SKIP IF (CHAR) IS A LEFT PARNS. DEFINE SKPNON,SKPNOX ;SKIP IF NOT A NUMBER DEFINE TASK,TASKX ;DO FORMAT CONTROLS FOR *ASK*TYPE* DEFINE EVAL.X,EVALUX ;"PUSHJ EVAL-2" DEFINE FPMP,$FPMPX ;FPMP PRE-PROCESSOR DEFINE FREAD,$READ ;FLOATING POINT READ ROUTINE DEFINE FPRINT,$PRINT ;FLOATING POINT PRINT ROUTINE DEFINE ITOA,ITOAX ;INTEGER TO ASCII CONVERSION DEFINE OTOA,OTOAX ;OCTAL TO ASCII CONVERSION DEFINE BTOA,BTOAX ;BINARY TO ASCII CONVERSION DEFINE PATCH1,PATCH ;-- PATCH #1 DEFINE PATCH2,PATCHB ;-- PATCH #2 .IFDF $RT11 ;IF RT-11 VERSION, HANDLE DELETE DEFINE DELETE,DELIN ;DELETE ONE LINE ** PRI 7 CALL ** DEFINE GETHAN,$GETHN ;GET DEVICE HANDLER DEFINE RELHAN,$RELHN ;RELEASE HANDLER FROM CORE DEFINE DOEMT,$DOEMT ;EXECUTE A CONSTRUCTED EMT DEFINE GCHAN,$GCHAN ;CONSTRUCT A CANNEL ENTRY POINTER DEFINE DMPBLK,$DMPBL ;DUMP A BLOCK FROM A BUFFER DEFINE NXTBLK,$NXTBL ;GET A NEXT BLOCK FOR A BUFFER DEFINE CHKEOF,$CKEOF ;CHECK FOR EOF CONDITION DEFINE CLRM,$CLRM ;CLEAR MEMORY ALLOCATION TABLES DEFINE REQM,$REQM ;REQUEST MEMORY DEFINE SCNM,$SCNM ;SCAN MEMORY TABLES AND ADJUST SYMBOL TABLE .ENDC ERROR=104400 ;TRAP ;PUSHJ X=JSR PC,X .MACRO OPEN ;OPEN THE STACK 4 WORDS .LIST MEB SUB #10,SP ;BACK OFF .NLIST MEB .ENDM OPEN ; .MACRO CLOSE ;CLOSE THE HOLE .LIST MEB ADD #10,SP ;DO IT .NLIST MEB .ENDM CLOSE ; ;--- MACRO: PRINT - USED TO OUTPUT ASCII CHARACTERS. ; .MACRO PRINT A .LIST MEB .WORD 104400+'A' .NLIST MEB .ENDM PRINT POPJ=207 ;RTS PC .IF NDF,$SMALL .SBTTL INTREX - INTERRUPT NORMAL SEQUENCE AND EXECUTE ROUTINE ; ;--- INTREX - ROUTINE TO EXECUTE AN INTERRUPT ; ; INTERRUPTS ARE FAKED HERE IN RT-11 LAND DUE TO THE ; STUFFY WAY OF PROCESSING TRUE INTERRUPTS. IT SEEMS THAT ; INTERRUPTS ARE HANDLED AS A CO-ROUTINE AFTER A ".SYNCH" ; MONITOR REQUEST. THE ".SYNCH" IS REQUIRED IN ORDER TO PRODUCE ; A CONTEXT SWITCH FORCING THE CORRECT STACK AND FLOATING ; VECTORS FOR THE REQUESTED JOB. AFTER THIS, THE ONLY PERMISSABLE ; EXIT IS VIA A RTS PC, WHICH SAYS THAT NO ERRORS ARE ; TO BE POSSIBLE. ALSO, SINCE THE USR IS POSSIBLY SWAPPED ; INTO FOCAL, GENERAL REQUESTS MAY NO LONGER BE AVAILABLE... ; .GLOBL PROC2,INTCHN,INTPRI,WHIPV,LINENO,SWITCH,DO2 .GLOBL INTREX,ZAPINT,INTSW,PTR0,CLKT .IFDF $RT11 .GLOBL L.CSIT,RMCNFG .ENDC ; INTREX: MOV R5,-(SP) ;SAVE R5 .MFPS -(SP) ;SET THAT 5$: MOV #14.,R0 ;SET LIST MOV #340,-(SP) MOV #10$,-(SP) RTI 10$: MOV #-1,INTSW ;SET SWITCH FOR INTERRUPT IN PROGRESS 4$: MOV INTCHN(R0),R5 ;SCAN FROM PRI 7 TO PRI 0 BNE 1$ ;HANDLE IT DEC R0 DEC R0 ;COUNT BY TWOS BGT 4$ ;HANDLE IT BR 2$ ;FALSE ALARM 1$: MOV @R5,INTCHN(R0) ;SET LINK DOWN CLR @R5 ;FREE FOR NEXT REQUEST MOV 6(R5),LINENO ;SET LINE NUMBER MOVB INTPRI,9.(R5) ;SAVE OLD PRIORITY MOVB 8.(R5),INTPRI ;SET NEW ONE MOV @SP,-(SP) MOV #11$,-(SP) RTI 11$: MOV R5,-(SP) ;SAVE FOR LATER CLRB SWITCH ;SET FOR DO TSTB LINENO ;SEE IF A LINE OR GROUP BEQ 3$ ;GROUP... MOVB #200,SWITCH ;SET THE SWITCH 3$: MOV 12(R5),AC ;GET THE VALUE JSR PC,WHIPV ;POINT TO THE "&" VARIABLE OPEN ;SAVE IT FPMP FGET+IPTR ;GET IT .WORD FPUT+INTO+STACK ;SAVE IT .WORD FLOAT ;FLOAT THE NEW ONE .WORD FPUT+IPTR ;PLACE IT BACK JSR PC,DO2 ;DO THE SECTION JSR PC,WHIPV ;POINT TO "&" VARIABLE AGAIN FPMP FGET+FROM+STACK ;RECOVER VALUE .WORD FPUT+IPTR ;SET IT CLOSE ;REMOVE THE HOLE IN THE STACK ; ;--- DEQUEUE THE REQUEST ; MOV (SP)+,R0 ;GET THE PLACE BACK TST 2(R0) BNE 14$ CLR 6(R0) 14$: MOV #340,-(SP) MOV #12$,-(SP) RTI 12$: MOVB 9.(R0),INTPRI ;REINSTATE PRIORITY BLT 5$ MOVB INTPRI,R1 ;SEE WHAT WE WERE RETURNING TO MOV #14.,R0 ;GET MAX 6$: MOV INTCHN(R0),R5 ;SCAN TOP DOWN BNE 1$ ;HANDLE IT DEC R0 ;COUNT DEC R0 ;DITTO CMP R0,R1 BPL 6$ ;KEEP IT UP BR 7$ ; ; 2$: CLR INTSW ;RESET INTERRUPT SWITCH MOVB #-1,INTPRI ;SET NORMAL PRIORITY 7$: MOV #13$,-(SP) RTI 13$: MOV (SP)+,R5 ;POP THE STACK JMP PROC2 ;CONTINUE .SBTTL ZAPINT - DEQUEUE ALL INTERRUPT AND SCHEDULED ROUTINES. ; ;--- ZAPINT - ROUTINE TO FREE ALL INTERRUPT REQUESTS ; ZAPINT: MOV #14.,R0 ;WIPE OUT ALL 8 PRIORITIES 1$: CLR INTCHN(R0) ;RESET CHAINS DEC R0 ;COUNT DEC R0 ;BY TWO'S BPL 1$ ;KEEP IT UP CLR INTSW ;RESET SWITCH MOVB #-1,INTPRI ;RESET PRIORITY MOV #I.SLOT,R5 ;POINT AT THE SLOT TABLE 2$: ADD #4,R5 ;POINT TO THE LINK CLR (R5)+ ;WIPE IT OUT TST (R5) ;INTERRUPT CODE? BPL 3$ ;NO - SKIP MOV 2(R5),@(R5) ;SHUT DOWN THE DEVICE 3$: MOV #5,R0 ;GET NUMBER OF WORDS TO WIPE OUT 4$: CLR (R5)+ ;ZERO IT OUT DEC R0 ;KEEP IT UP BGT 4$ ;OVER AND OVER CMP R5,#E.SLOT ;THE END? BLO 2$ ;KEEP IT UP RTS PC ;RETURN ; .SBTTL $INTRP - INTERRUPT PROCESSOR ; ;--- THIS CODE IS RESPONSIBLE FOR THE HANDLING OF BOTH INTERRUPTS ; AND MARK-TIME REQUESTS. ON ENTRY, R5 HAS BEEN SAVED ON THE STACK, ; AND NOW POINTS TO THE LINK WORD IN OUR SCHEDULER SLOT. ; ; IF THE WORD FOLLOWING THIS IS NEGATIVE, IT HAS TO BE ; A DEVICE INTERRUPT. (NO NEGATIVE MARKTIME COUNTS ALLOWED!) ; ; THE ROUTINE THEN SETS THINGS UP ACCORDINGLY, AND MASSAGES ; FLAGS FOR FOCAL TO CHECK AT THE COMPLETION OF EACH ; PROGRAM COMMAND. PRIORITIES ARE HONORED SIMMILARLY TO THE ; HARDWARE CONVENTION. NOTE: ALL ROUTINES SCHEDULED RUN AT ; MACHINE PRIORITY 0!!!!!! ; ; .GLOBL $INTRP,I.SLOT,MAXTSK,E.SLOT ; .IFDF $PAPER .MACRO .INTEN .PRI .LIST MEB MOV #'.PRI'*40,@#PSW ;SET PRIORITY '.PRI' MOV R5,-(SP) ;SAVE R5 MOV R4,-(SP) ;AND R4 MOV #$RTI,-(SP) ;SET FOR RTI INSTRUCTION .NLIST MEB .ENDM .INTEN .ENDC ; $INTRP: MOV R5,PTR0 ;R0 SAVE AREA IN .SYNC TABLE TST 2(R5) ;IS THIS AN INTERRUPT OR A COMPLETION?? BPL $COMP ;THIS IS A COMPLETION MOV 4(R5),@2(R5) ;MASK OFF THE CSR MOV (SP)+,R5 ;RECOVER THE ORIGINAL R5 .INTEN 7 ;SET UP PRIORITY 7 ON SYSTEM STACK $IENTR: MOV PTR0,R4 ;GET POINTER TO THE ENTRY TST @R4 ;IN USE? BNE 6$ ;EXIT DUE TO PROBLEMS MOV R0,-(SP) ;SAVE R0 MOVB 8.(R4),R0 ;GET PRI ASL R0 ;*2 MOV #INTCHN,R5 ;POINT TO IT ADD R0,R5 ;OFFSET 2$: MOV @R5,R0 ;GET LINK BEQ 3$ ;HANDLE IT MOV R0,R5 ;PASS LINK BR 2$ ;KEEP IT UP ; 3$: MOV R4,@R5 ;SEND IT TST INTSW ;SEE IF RUNNING CMPB 8.(R4),INTPRI ;SEE IF IN A GOOD PRIORITY BLE 5$ ;YES - JUST WAIT ; 4$: MOV #1,INTSW ;SET INTERRUPT REQUEST ; 5$: MOV (SP)+,R0 ;RECOVER R0 6$: POPJ ;RETURN ; ; ;--- HANDLE MARKTIME REQUEST ; $COMP: TST 2(R5) ;COUNT EXHAUSTED? BLE 2$ ;YES - EXIT IMMEDIATELY DEC 2(R5) ;REDUCE COUNT BEQ 1$ ;PERFORM THIS ONE ONLY MOV TEMP,-(SP) MOV AC,-(SP) MOV PTR,-(SP) ;SAVE REGS MOV R5,TEMP ;POINT AT THE SCHEDULED ROUTINE SUB #4,TEMP ;POINT AT THE START MOV 4(R5),AC ;GET THE TIME TILL THE NEXT ONE JSR PC,$SCHED ;RE-SCHEDULE THE TASK MOV (SP)+,PTR ;RESTORE IT MOV (SP)+,AC MOV (SP)+,TEMP ;ALL REGS RESTORED ; 1$: MOV R4,-(SP) ;SAVE R4 .MFPS -(SP) ;SAVE PRI MOV #340,-(SP) MOV #3$,-(SP) RTI 3$: JSR PC,$IENTR ;FAKE AS IF AN RT-11 INTERRUPT MOV #4$,-(SP) RTI 4$: MOV (SP)+,R4 ;RESTORE REGISTERS MOV (SP)+,R5 ;R4 AND R5 POPJ ;GET OUT ; 2$: MOV (SP)+,R5 ;RESTORE REG 5 POPJ ;EXIT ; .IFDF $PAPER $RTI: MOV (SP)+,R4 ;RESTORE REGS R4 MOV (SP)+,R5 ; AND R5 RTI ;AND REALLY RETURN FROM THE INTERRUPT .ENDC .SBTTL $FINT - FOCAL INTERRUPT FUNCTION ; ; ;--- THE $FINT ROUTINE ACCEPTS A VARIABLE NUMBER OF PARAMETERS, ; AND, BASED UPON THIS NUMBER, EITHER CONNECTS A DEVICE VECTOR ; TO THE FOCAL SYSTEM, OR RELEASES ONE. ; ; X FINT(P1,P2,P3,P4,P5) ; ; THE PARAMETERS ARE: ; ; 1. THE VECTOR ADDRESS (MUST BE EVEN...) ; ; 2. THE LINE/GROUP NUMBER TO BE USED FOR THE ROUTINE ; ; 3. THE PRIORITY OF THE ROUTINE (0-7) ; ; 4. THE REGISTER ADDRESS WHICH CAN BE USED TO SHUT THE ; DEVICE DOWN. ; ; 5. THE MASK TO BE USED ON THE ABOVE MENTIONED REGISTER. ; ; .GLOBL $FINT,$LIST ; $FINT: FPMP FINT ;GET THE INTEGER VALUE OF THE VECTOR MOV AC,-(SP) ;SAVE IT GETC GETLN ;GET A LINE NUMBER MOV LINENO,AC ;SEE IF WE ARE SETTING ONE UP BNE 1$ ;SKIP IF WE ARE MOV (SP)+,TEMP ;GET THE VECTOR ADDRESS MOV @TEMP,AC ;POINT AT THE SLOT CMP AC,#I.SLOT ;SEE IF IT IS IN THE SLOT BLO INTRER ;HANDLE ERROR CMP AC,#E.SLOT ;IS IT IN THIS AREA? BHIS INTRER ;NO - ERROR MOV #INTRER,@TEMP ;SET ERROR CLR 12(AC) ;RESET THE ROUTINE MOV 6(AC),TEMP ;GET CSR REGISTER MOV 10(AC),@TEMP ;KILL INTERRUPTS ADD #4,AC ;OVER THE CALL TST @AC ;PENDING INTERRUPT? BEQ 4$ ;NO - EXIT MOV #INTCHN,TEMP ;LOOK THROUGH THE CHAIN BEQ 4$ ;STRAGGLER 2$: CMP @TEMP,AC ;SEE IF WE CHAN FIND THIS GUY BEQ 3$ ;YES - UNHOOK HIM MOV @TEMP,TEMP ;LINK THROUGH BNE 2$ ;KEEP IT UP BR 4$ ;NOT IN THE CHAIN 3$: MOV @AC,@TEMP ;CLOSE THE GAP 4$: CLR @AC ;RELEASE THE ENTRY POINT 6$: POPJ ;EXIT ; 1$: MOV AC,TEMP ;SAVE THE LINE NUMBER MOV (SP)+,AC ;GET THE VECTOR ADDRESS 8$: MOV #I.SLOT,PTR ;POINT AT THE SLOT TABLE MOV #MAXTSK,-(SP) ;SET COUNTER 7$: TST 12(PTR) ;SEE IF FREE BEQ 12$ ;YES - USE IT ADD #20,PTR ;INDEX DEC @SP ;COUNT IT OUT BGT 7$ ;KEEP GOING BR INTRER ;SET ERROR - SLOTS FUL 12$: MOV TEMP,@SP ;SET POINTER MOV AC,16(PTR) ;SET VECTOR ADDRESS .IFDF $RT11 MOV @#RMON,TEMP ;POINT AT RMON BIT #400,RMCNFG(TEMP) ;FOREGROUND PROGRAM RUNNING? BEQ 5$ ;NO - SKIP TEST .PROTEC #L.CSIT,AC ;PROTECT THE VECTOR BCS INTRER ;GIVE ERROR 5$: .ENDC MOV @SP,12(PTR) ;SET THE ROUTINE NUMBER MOV PTR,@SP ;SAVE THE PTR MOV PTR,(AC)+ ;SET THE VECTOR MOV #340,(AC) ;AND HIGH PRIORITY EVAL.X ;GET PRIORITY FPMP FINT ;AND MAKE IT AN INTEGER CMP AC,#7 ;SEE IF WITHIN RANGE BHI INTRER ;SET ERROR MOV (SP),PTR ;RECOVER THE POINTER MOV AC,14(PTR) ;SET IT EVAL.X ;GET THE DEVICE ADDRESS FPMP FINT ;GET IT MOV @SP,PTR ;RECOVER THE PTR MOV AC,6(PTR) ;SET IT INTO THE SLOT EVAL.X ;GET MASK FPMP FINT ;SET AS AN INTEGER MOV (SP)+,PTR ;GET IT FOR THE LAST TIME MOV AC,10(PTR) ;SET INTO THE TABLE DEVICE: MOV #I.SLOT,PTR ;GET THE INTERRUPT DEVICE TABLE 10$: MOV #$LIST+4,AC ;AND THE .DEVICE TABLE ADDR TST 6(PTR) ;IS THE ELEMENT A CSR ? BMI 11$ ;YES 13$: ADD #20,PTR ;POINT TO THE NEXT TABLE ENTRY CMP #E.SLOT,PTR ;ARE WE AT THE END OF THE TABLE ? BNE 10$ ;NO - KEEP GOING CLR (AC) ;WRITE AN EOF IN THE TABLE .DEVICE #$LIST ;AND LET RT-11 KNOW ABOUT IT POPJ ;EXIT 11$: MOV 6(PTR),(AC)+ ;PUT THE CSR INTO THE LIST CLR (AC)+ ;ALONG WITH A 0 TO DISABLE THE DEVICE BR 13$ ;AND CONTINUE ; INTRER: ERROR+201+39.+39. .SBTTL FQUE - SCHEDULE FUNCTION ; ;--- THIS IS THE FOCAL SCHEDULING ROUTINE. CALL SHOULD BE OF THE FORM: ; ; S ID=FQUE(COUNT,GROUP,TIME,DELAY,PRIORITY) ; ; WHERE: ; ; ID - THIS IS THE ID WHITH WHICH THE REQUEST CAN BE LATER ; CANCELLED. ; ; COUNT - THIS IS THE NUMBER OF TIMES THE ROUTINE IS TO BE SCHEDULED ; ; GROUP - THIS IS THE LINE/GROUP NUMBER ; ; TIME - THIS IS THE TIME (INTERVAL) IN SECONDS. ; ; DELAY - THIS IS THE TIME IN SECONDS UNTIL THE FIRST OCCURRANCE ; ; PRIORITY- THIS IS THE SOFTWARE PRIORITY LEVEL. (0-7) ; ;--- ALTERNATE FORM OF THE CALL: ; ; X FQUE(0,ID,GROUP) ; ; THIS WILL CAUSE A PREVIOUSLY SCHEDULED TASK IDENTIFIED BY ; "ID" AND VERIFIED BY "GROUP" TO BE CANCELLED. ; ; .GLOBL XFQUE ; XFQUE: FPMP FINT ;GET INTEGER PART TST AC ;SEE IF A CANCEL REQUEST BEQ FQ.CAN ;CANCEL THE QUEUE REQUEST ; MOV #I.SLOT,TEMP ;SCAN FOR AN OPEN SLOT 1$: TST 12(TEMP) ;FIND ONE WITH A CLEAR LINE/GROUP BEQ 2$ ;GOT IT.. ADD #20,TEMP ;SKIP OVER CMP TEMP,#E.SLOT ;THE END? BLO 1$ ;NO - KEEP IT UP 3$: ERROR+201+39.+39. ;ERROR IN QUEUE ; 2$: MOV TEMP,-(SP) ;SAVE IT MOV AC,6(TEMP) ;SET NUMBER OF TIMES GETC ;SKIP THE COMMA GETLN ;GET THE LINE NUMBER MOV @SP,TEMP ;GET POINTER MOV LINENO,12(TEMP) ;SET THE LINE/GROUP NUMBER EVAL.X ;GET THE TIME IN SECONDS FPMP FINT ;GET IT TST AC ;SEE IF ERROR BLE 3$ ;HANDLE IT MOV @SP,TEMP ;POINT MOV AC,10(TEMP) ;SET THE TIME (32,767 MAX SECONDS) MOV TEMP,16(TEMP) ;SET ID INTO SLOT FOR "&" EVAL.X ;GET THE DELAY VALUE FPMP FINT ;AS AN INTEGER MOV AC,-(SP) ;SAVE IT EVAL.X ;GET PRIORITY FPMP FINT ;SET IT MOV 2(SP),TEMP ;GET THE POINTER MOV AC,14(TEMP) ;SET IT AND CLEAR HIGH BYTE MOV TEMP,AC ;CONSTRUCT QUEUE ID FPMP FLOAT ;FLOAT THE NUMBER FOR THE USER MOV (SP)+,AC ;GET THE DELAY BGT 4$ ;HANDLE NORMALLY MOV (SP)+,TEMP ;GET ROUTINE ADDRESS JMP (TEMP) ;FAKE AN INTERRUPT FOR IT ; 4$: MOV (SP)+,TEMP ;GET ROUTINE ADDRESS ; AND DROP INTO SCHEDULER .SBTTL $SCHED - ROUTINE TO SCHEDULE A FUNCTION ; ;--- $SCHED - CO ROUTINE SCHEDULER ; ;INPUT R0-ROUTINE ADDRESS R1-TIME IN SECONDS ; .GLOBL PARAM ;USED TO ACCESS PARAM #11 ; $SCHED: MOV CHAR,-(SP) ;SAVE REG MOV TEMP,PTR ;SAVE CO-ROUTINE ADDRESS CLR TEMP ;SET TO 0 MOV AC,-(SP) ;SAVE *1 TSTB PARAM+11. ;IS TIME IN CLOCK TICKS? BNE 3$ ;YES - SKIP MULTIPLY BY CYCLES ASL AC ;*2 ROL TEMP ;*2 ASL AC ;*4 ROL TEMP ;*4 ADD @SP,AC ;*5 ADC TEMP .IF DF,$RT11 MOV @#RMON,CHAR ;GET RMON POINTER BIT #40,RMCNFG(CHAR) ;SEE IF 50 CYCLE .IFF .GLOBL CONFIG ;FOR PAPER TAPE CONFIGURATION BIT #40,CONFIG ;50 CYCLE CLOCK? .ENDC BNE 1$ ;YES - SKIP UPDATE TO *6 ADD @SP,AC ;SET INTO AC ADC TEMP ;MAKE IT *6 ; ;--- NOW MULTIPLY BY TEN ; 1$: ASL AC ;*2 ROL TEMP ;*2 MOV TEMP,@SP ;SAVE MOV AC,-(SP) ;DITTO ASL AC ;*4 ROL TEMP ;*4 ASL AC ;*8 ROL TEMP ;*8 ADD (SP)+,AC ;*2+*8=*10 ADC TEMP ;PASS CARRY ADD (SP)+,TEMP ;FINAL MOV AC,-(SP) ;SET UP FOR MARK-TIME 3$: MOV TEMP,-(SP) ;REQUEST MOV SP,AC ;POINT TO IT ; JSR PC,MRKT BCS 2$ ;HANDLE AN ERROR CMP (SP)+,(SP)+ ;POP THE STACK MOV (SP)+,CHAR ;GET REG BACK POPJ ;RETURN ; 2$: ERROR+201+39.+39. .SBTTL FQ.CAN - CANCEL SCHEDULED REQUEST ; ; FQ.CAN: EVAL.X ;GET FPMP FINT MOV AC,PTR ;POINT AT THE REQUEST GETC ;SKIP THE COMMA GETLN ;GET THE LINE NUMBER CMP LINENO,12(PTR) ;IS THEIS IT? BEQ 1$ ;YES - CONTINUE ERROR+201+39.+39. ;SET ERROR IN REQUEST 1$: CLR 6(PTR) ;SAY THAT IT IS OVER JSR PC,CMKT CLR 12(PTR) ;FREE THE SLOT RTS PC ;RETURN ; ; FQ.WRK: .BLKW 5 ;HANDLE IT .SBTTL MRKT - ROUTINE TO HANDLE MARK TIME REQUESTS ; ; .MACRO CHKSYS .A MOV @#RMON,TEMP BIT #1,RMCNFG(TEMP) BEQ '.A' .ENDM CHKSYS ; MRKT: .IFDF $RT11 CHKSYS 1$ .MCALL .MRKT .MRKT #FQ.WRK,AC,PTR,PTR RTS PC .ENDC ; ;--- PSEUDO MARK TIME QUEUE STRUCTURE ; ;$QUEUE:+----------------------+ ; : PTR TO FIRST ENTRY : ; +----------------------+ ; : PTR TO FREE LIST : ; +----------------------+ ; ; ; THIS STRUCTURE HEADER IS THE FIRST 2 WORDS OF THE $QUEUE ; AREA. THE REST OF THE AREA IS BLOCKED INTO 4 WORD ENTRIES ; WITH THE FOLLOWING FORMAT. ; ; ; +----------------------+ ; : LINK WORD (0=END) : ; +----------------------+ ; : POINTER TO ROUTINE : ; +----------------------+ ; : 2 WORD FIELD FOR : ; : THE TIME OF DAY : ; +----------------------+ ; ; ; 1$: MOV AC,-(SP) ;SAVE POINTER MOV #$QUEUE+2,AC ;SCAN FOR OPEN AREA MOV @AC,AC ;POINT TO THE FREE AREA BEQ 7$ ;OUT OF SLOTS - GENERATE ERROR MOV @AC,$QUEUE+2 ;CHAIN DOWN BR 3$ ;CONTINUE 7$: TST (SP)+ ;POP THE STACK SEC ;SET CARRY POPJ ;AND RETURN IF ALL FULL ; 3$: MOV PTR,2(AC) ;SET ROUTINE ADDRESS .IF DF,$RT11 .GTIM #FQ.WRK,#CLKT ;GET TIME OF DAY BCS 7$ ;EXIT WITH ERROR .ENDC MOV (SP)+,TEMP ;RECOVER TIME OF DAY MOV (TEMP)+,4(AC) ;PASS IT MOV (TEMP),TEMP ;GET LOW WORD ADD CLKT+2,TEMP ;GET THE SUM MOV TEMP,6(AC) ;SET INTO THE AREA ADC 4(AC) ;PASS THE CARRY ADD CLKT,4(AC) ;ADD THE HIGH WORD MOV #$QUEUE,TEMP ;GET THE QUEUE STRUCTURE MOV TEMP,-(SP) ;SAVE IT 4$: MOV @TEMP,TEMP ;GET THE TIME BEQ 6$ ;ADD IT CMP 4(TEMP),4(AC) ;SEE IF A PROBLEM BLO 5$ ;SKIP THIS BHI 6$ ;PASS IT CMP 6(TEMP),6(AC) ;LOOK AT LOW WORDS BLO 5$ 6$: MOV TEMP,@AC MOV (SP)+,TEMP MOV AC,@TEMP CLC ;FORCE A ZERO CARRY POPJ 5$: MOV TEMP,@SP ;SAVE IT BR 4$ ;RETURN ; ; ; .SBTTL CMKT - ROUTINE TO CANCEL ABOVE REQUEST ; ; CMKT: .IFDF $RT11 CHKSYS 1$ .MCALL .CMKT .CMKT #FQ.WRK,PTR RTS PC .ENDC 1$: MOV #$QUEUE,TEMP 2$: MOV @TEMP,AC ;GET QUEUE BEQ 3$ CMP 2(AC),PTR BEQ 4$ MOV AC,TEMP BR 2$ 4$: MOV @AC,@TEMP JSR PC,SETFRE ;SET (AC) INTO FREE AREA 3$: POPJ .SBTTL QUESET - ROUTINE TO SET UP THE QUEUE STRUCTURE ; ; .GLOBL QUESET ; QUESET: .IFDF $RT11 CHKSYS 1$ .MCALL .QSET .QSET #$QUEUE,#MAXTSK RTS PC .ENDC .GLOBL $QUEUE,MAXTSK 1$: MOV #$QUEUE,AC MOV #MAXTSK,TEMP INC TEMP ASL TEMP ASL TEMP ;NOW THE NUMBER OF WORDS TO BE CLEARED 2$: CLR (AC)+ DEC TEMP BGT 2$ ;CONTINUE MOV #$QUEUE+4,AC ;POINT TO THE START AREA MOV AC,TEMP ;SAVE IT MOV AC,-(TEMP) ;PLACE INTO THE FREE LIST MOV #MAXTSK-1,TEMP ;GET NUMBER 3$: ADD #10,AC ;POINT BEYOND MOV AC,-10(AC) ;CHAIN DOWN DEC TEMP ;COUNT OUT THE ELEMENTS BGT 3$ ;KEEP GOING CLR @AC ;JUST TO BE SAFE POPJ ;RETURN ; ; ;--- SETFRE - SET AREA POINTED TO BY AC INTO FREE LIST ; ; SETFRE: MOV #$QUEUE+2,TEMP ;POINT TO THE LIST 1$: TST @TEMP ;END? BEQ 2$ ;YES - PLACE IT HERE MOV @TEMP,TEMP ;CHAIN DOWN BR 1$ ;UNTIL FINISHED ; 2$: MOV AC,@TEMP ;PLACE IT IN THE CHAIN CLR @AC ;SET THE END POPJ ;RETURN .SBTTL QUECHK - ROUTINE TO CHECK ON TIME OUTS ; ; .GLOBL QUECHK ; QUECHK: TST INTSW ;CHECK FOR INTERRUPTS .IFDF $RT11 BGT 1$ ;HANDLE IF TRUE CHKSYS 2$ POPJ .IFF BEQ 2$ ;CHECK FOR MARK-TIME .ENDC 1$: TST (SP)+ ;POP THE STACK JMP INTREX ;EXECUTE INTERRUPT REQUEST 2$: TST $QUEUE BEQ 3$ ;NO ELEMENTS - EXIT .IF DF,$RT11 .GTIM #FQ.WRK,#CLKT BCS 5$ .ENDC MOV $QUEUE,AC ;CHECK THE FIRST ONE ONLY CMP 4(AC),CLKT ;SEE IF HIGH WORDS ARE THE SAME BLO 4$ ;EXIT BHI 3$ ;EXECUTE IT IMMEDIATELY CMP 6(AC),CLKT+2 ;SEE IF LOW ONES ALIKE BHI 3$ ;EXIT IF NOT TIME YET 4$: MOV @AC,$QUEUE ;PLACE IT BACK JSR PC,SETFRE ;WIPE OUT ENTRY JSR PC,@2(AC) ;HANDLE THE INTERRUPT BR 1$ ;EXECUTE IT 3$: POPJ ;EXIT 5$: ERROR+201+39.+39. .ENDC .IFDF $RT11 .SBTTL MOVES - SYMBOL TABLE SHUFFLE ROUTINE ; .GLOBL STARTV,AXIN,BOTTOM,TRUEND,MEMTAB,MEMSIZ .GLOBL IDENT,STARTX,HICORE,SWAPLC,BUFR .GLOBL MOVES,$CLRM,$SCNM,$REQM,$RELM ; ;--- THIS ROUTINE ALLOWS THE SYSTEM TO MOVE THE NEW SYMBOL TABLE ; STRUCTURE. THIS ALLOWS HANDLERS AND BUFFERS TO RESIDE ; IN HIGH CORE, NEXT TO THE MONITOR. ; ; THE SHUFFLE PARAMETER IS LOCATED IN "AC" AND IS OF A WORD ; OFFSET IN NATURE. THIS OFFSET IS SIGNED, AND THE AVAILABILITY ; OF FREE CORE WHERE THE TABLE IS GOING IS VERIFIED. ; PROTECTION FROM OVERLAYING THE TEXT AREA AND THE HARD ; TOP OF CORE (MONITOR LIMIT) ARE PROVIDED FOR. ; MOVES: ASL AC ;GET WORD VALUE BVS MOVERR ;VALUE TOO LARGE - KILL REQUEST .MFPS -(SP) MOV #340,-(SP) MOV #2$,-(SP) RTI 2$: MOV CHAR,-(SP) ;SAVE CHAR MOV AC,TEMP ;GET OFFSET VALUE BEQ MOVEX ;EXIT - NO OFFSET LEAVES IT THERE.. BPL MOVHI ;MOVE TO HIGH ADDRESS CORE ; ;--- SHUFFLE SYMBOL TABLE TO LOWER CORE ADDRESSES ; MOV STARTV,AC ;POINT TO CURRENT START ADD AC,TEMP ;POINT TO NEW START CMP TEMP,BUFR ;MAKE SURE WE DON'T INTERFERE WITH TEXT BLOS MOVERR ;WE ALMOST DID IT! CMP TEMP,AXIN ;SEE IF HERE EITHER BLOS MOVERR MOV TEMP,STARTV ;REFLECT THE MOTION MOV BOTTOM,CHAR ;SAVE LIMIT 1$: MOV (AC)+,(TEMP)+ ;MOVE IT CMP AC,CHAR ;BOTTOM YET? BLOS 1$ ;NO - KEEP MOVING IT TST -(TEMP) ;BACK UP THE POINTER MOV TEMP,BOTTOM ;SET NEW BOTTOM BR MOVEX ;RETURN TO THE USER ; ;--- MOVE THE TABLE TO HIGHER CORE ADDRESSES ; MOVHI: MOV BOTTOM,AC ;GET CURRENT BOTTOM OF THE TABLE ADD AC,TEMP ;GET NEW BOTTOM ADDRESS CMP TEMP,TRUEND ;SEE IF THE TRU END OF US? BHI MOVERR ;NO GO - ERROR CODE! MOV TEMP,BOTTOM ;THIS REFLECTS THE CHANGE... MOV (AC),(TEMP) ;COPY THE FIRST WORD MOV STARTV,CHAR ;SET THE LIMIT REGISTER BR 2$ ;ENTER THE LOOP 1$: MOV -(AC),-(TEMP) ;COPY THE TABLE ONE WORD AT A TIME 2$: CMP AC,CHAR ;LAST WORD COPIED? BHI 1$ ;NO - CONTINUE MOV TEMP,STARTV ;SET NEW VARIABLE START ADDRESS MOVEX: MOV (SP)+,CHAR ;RESTORE CHAR MOV #1$,-(SP) RTI 1$: RTS R5 ;RETURN TO THE CALLING ROUTINE MOVERR: ERROR+201+23.+23. ;SYMBOL TABLE SHUFFLE ERROR .SBTTL $CLRM - DMA MEMORY CLEAR ROUTINE ; ;--- $CLRM - THIS ROUTINE PROVIDES THE SYSTEM WITH A MEANS OF ; REMOVING ALLOCATED MEMORY WITHOUT BOTHERING TO FIGURE OUT ; THE ADDRESS OF THE MEMORY TO BE RELEASED. ; ; THIS IS HANDY FOR REMOVING ALL MEMORY ALLOCATED WITH A PARTICULAR IDENT ; FIELD. ; $CLRM: MOV #MEMTAB,TEMP ;POINT TO MEMORY ALLOCATION TABLE MOV #MEMSIZ,-(SP) ;STACK THE NUMBER OF BLOCKS TST IDENT ;A CLASS OPERATION (IE: ALL USER AREA) BMI CLRCLS ; ;--- HERE ONLY CLEAR OUT THE PARTICULAR GUY, OR ALL IF =0 ; 1$: TSTB IDENT ;SEE WHAT'S UP BEQ 2$ ;WIPE IT ALL OUT CMPB IDENT,(TEMP) ;SEE IF THIS IS THE ONE BNE 3$ ;NO - SKIP IT 2$: CLRB @TEMP ;WIPE OUT THE ENTRY 3$: INC TEMP ;INDEX DEC @SP ;COUNT OUT THE NUMBER OF ENTRIES BGT 1$ ;KEEP IT UP BR CLREX ;EXIT..... ; ;--- HERE CLEAR OUT A CLASS OF USERS ; CLRCLS: TSTB IDENT ;SEE IF SYSTEM OR USER CLASS BMI CLRSYS ;GET RID OF SYSTEM AREA 1$: TSTB (TEMP)+ ;SEE IFUSER SPACE BMI 2$ ;NO - SKIP IT CLRB -1(TEMP) ;YES - WIPE IT OUT 2$: DEC @SP BGT 1$ BR CLREX ;GET OUT ; CLRSYS: TSTB (TEMP)+ ;SEE IF SYSTEM BPL 1$ ;SKIP IF NOT... CLRB -1(TEMP) ;ELIMINATE IT 1$: DEC @SP BGT CLRSYS ; ;--- CLREX - EXIT FROM THE CLEAR ROUTINE ; CLREX: TST (SP)+ ;POP THE STACK ; ; DROP INTO THE $SCNM CODE ; .SBTTL $SCNM - ROUTINE TO KEEP SYMBOL TABLE PACKED IN HIGH CORE ; ;--- $SCNM - THIS ROUTINE SCANS THE MEMORY TABLE AND KEEPS THE SYSBOL TABLE ; AS FAR INTO HIGH ADDRESS MEMORY AS POSSIBLE ; .GLOBL PARAM ; $SCNM: MOV #MEMTAB,AC ;POINT TO THE TABLE MOV #MEMSIZ,TEMP ;GET THE LENGTH OF THE TABLE 1$: TSTB (AC)+ ;SEE IF FREE BNE 2$ ;ALL SET... EXIT DEC TEMP BGT 1$ ;LOOP ALL THE WAY BACK BR 4$ ;RESET MEMORY 2$: SUB #MEMTAB+1,AC ;GET OFFSET FROM THE END SUB #MEMSIZ,AC ;COMPLETE THE DIFFERENCE NEG AC ;MAKE IT POSITIVE SWAB AC ;QUICK * 256 ASL AC ;*2 FOR WORD COUNT -> BYTE COUNT NEG AC ;NOW MAKE IT NEGATIVE ADD TRUEND,AC ;GET THE END SUB BOTTOM,AC ;GET THE BYTE OFFSET BEQ 3$ ;YES - THEN ALL IS OK...EXIT... ASR AC ;DIVIDE BY 2 FOR WORD COUNT JSR R5,MOVES ;SHUFFL THE SYMBOLS 3$: RTS R5 ;RETURN TO THE CALLER ; ;--- HERE ALL OF REQM AREA IS FREE - PUSH SYMBOL TABLE WAY UP... ; ; FIRST SET UP "HICORE" PARAMETER ; 4$: .SETTOP #-2 ;TRY FOR MAX MOV @#HICOR,TEMP ;POINT TO TEMP AREA MOVB PARAM,AC ;GET PARAM 0: IF =0 - USE ALL AVAILABLE CORE ; =1 - USE AREA BELOW "USR" ONLY ; >=2 - USE AREA BELOW KMON ONLY ! BEQ 5$ ;SKIP OUT IF DONE MOV SWAPLC,TEMP ;GET USR LOAD ADDRESS DEC AC ;SEE IF 1 BEQ 5$ ;YES - SKIP OUT SUB #5000,TEMP ;BACK OFF SOME 5$: TST -(TEMP) ;POINT I FRONT OF SACRED AREA CMP TEMP,HICORE ;SEE IF WE SHOULD SETTOP NOW,... OR LATER BLOS 6$ ;BACK OFF SYMBOL TABLE FIRST!!! .SETTOP ;MAKE SURE USER AREA BEFORE WE MOVE!! 6$: MOV TEMP,HICORE ;MARK HIGH CORE ADDRESS MOV TEMP,TRUEND ;ALSO NEW TRUEND SUB BOTTOM,TEMP ;GET OFFSET ASR TEMP ;DIVIDE BY 2 FOR WORD OFFSET MOV TEMP,AC ;CORRECT FOR TABLE SHUFFL JSR R5,MOVES ;MOVE THE SYMBOL TABLE MOV HICORE,TEMP ;GE HIGH ADDRESS AGAIN .SETTOP ;DO IT AGAIN IN CASE... MOV #STARTX,@#USRADD ;SET FOR POSSIBLE SWAP CMP HICORE,SWAPLC ;SEE IF WE SET TOP LOW ENOUGH BHI 3$ ;EXIT CLR @#USRADD ;RESET FOR NORMAL MONITOR USR RESIDENT RTS R5 ;RETURN TO CALLING ROUTINE .SBTTL $REQM - REQUEST FOR MEMORY ROUTINE ; ;--- $REQM - THIS ROUTINE IS PROVIDED TO ALLOW THE SYSTEM TO REQUEST ; BLOCKS OF 256 WORD MEMORY. THE STACK CONTAINS THE NUMBER OF ; BLOCKS REQUIRED, AND RETURNS THE ADDRESS IF SUCCESSFUL. ; IF UNSUCCESSFUL, AN ERROR WILL RESULT. ; $REQM: MOV #MEMTAB,TEMP ;POINT AT THE END OF THE TABLE ADD #MEMSIZ,TEMP ;POINT AT THE END (COMPLETE) CLR AC ;SET COUNT TO ZERO 1$: TSTB -(TEMP) ;SCAN FROM HIGH TO LOW FOR FREE BLOCK BNE 4$ ;NOT FREE - RESET BLOCKS FOUND COUNT INC AC ;UPDATE THE NUMBER OF BLOCKS FOUND CMP AC,2(SP) ;HAVE WE FOUND ENOUGH FOR HIM? BLO 5$ ;NO - CHECK END OF TABLE AND RETURN ; ;--- WE HAVE FOUND ENOUGH MEMORY. AT LEAST ACCORDING TO THE TABLES! ; MOV TEMP,-(SP) ;SAVE THE POINTER TO THE TABLE ENTRY SUB #MEMTAB,TEMP ;GET DISTANCE FROM THE END SUB #MEMSIZ,TEMP ;COMPLETE THE DIFFERENCE NEG TEMP ;FOCE IT TO BE POSITIVE SWAB TEMP ;QUICK *256. ASL TEMP ;CONVERT WORDS -> BYTES NEG TEMP ;MAKE IT NEGATIVE AND BACK UP ADD TRUEND,TEMP ;GET TRUE ADDRESS-2 CMP TEMP,BOTTOM ;SHUFFL SYMBOL TABLE? BHI 2$ ;NO - SKIP IT MOV TEMP,-(SP) ;SAVE IT MOV TEMP,AC ;AND HOLD ANOTHER COPY SUB BOTTOM,AC ;GET ADJUSTMENT VALUE IN BYTES ASR AC ;NOW AS WORDS JSR R5,MOVES ;MOVE THE SYMBOL TABLE MOV (SP)+,TEMP ;RESTORE ORIGINAL VALUE 2$: MOV 4(SP),AC ;RECOVER ORIG # BLOCKS TST (TEMP)+ ;ADD 2 SINCE TRUEND POINTS AT LAST WORD MOV TEMP,4(SP) ;SET ADDRESS OF AREA MOV (SP)+,TEMP ;POINT AT MEMORY TABLE SLOT 3$: MOVB IDENT,(TEMP)+ ;MARK THE MEMORY OWNERSHIP DEC AC ;COUNT OUT THE NUMBER OF BLOCKS BGT 3$ ;KEEP IT UP RTS R5 ;RETURN TO CALLER ; 4$: CLR AC ; 5$: CMP TEMP,#MEMTAB BHI 1$ ERROR+201+24.+24. ;MEMORY ALLOCATION ERROR .SBTTL $RELM - RELEASE MEMORY ; ;--- $RELM - THIS ROUTINE IS USED TO RELEASE MEMORY ALLOCATED BY ; A REQM REQUEST. THE NUMBER OF BLOCKS RELEASED SHOULD BE PUSHED ; ONTO THE STACK, FOLLOWED BY THE ADDRESS OF THE FIRST WORD ; OF THE AREA ALLOCATED. ; $RELM: MOV (SP)+,PTR ;SAVE RETURN ADDRESS MOV (SP)+,TEMP ;GET ADDRESS MOV (SP)+,AC ;AND BLOCK COUNT MOV PTR,-(SP) ;REPLACE THE RETURN ADDRESS SUB TRUEND,TEMP ;GET OFFSET NEG TEMP ;MAKE IT POSITIVE ASR TEMP ;GET TO WORD OFFSET INCB TEMP ;SEE IF LOW ORDER IS ZERO BEQ 1$ ;YES - SKIP IT... ERROR+201+25.+25. ;INTERNAL MEMORY ERROR 1$: SWAB TEMP ;QUICK DIVIDE BY 256. COM TEMP ;USE TO BACK UP ADD #MEMTAB,TEMP ;POINT AT THE SLOT ADD #MEMSIZ,TEMP ;COMPLETE THE ADDITION 2$: CMPB (TEMP),IDENT ;SEE IF THIS IS CORRECT BEQ 3$ ;YES - OK TO REMOVE ERROR+201+26.+26. ;ILLEGAL RELM REQUEST 3$: CLRB (TEMP)+ ;REMOVE THE MEMORY DEC AC ;COUNT OUT THE BLOCKS BGT 2$ ;CONTINUE UNTIL ALL GONE JMP $SCNM ;SCAN MEMORY AND RETURN .ENDC .END .NLIST .IFNDF $PAPER $RT11=0 ;IF NOT PAPER TAPE VERSION, THEN MUST BE RT-11 .ENDC .LIST ; ; /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ ; \ / .IFDF $RT11 ; / F O C A L - R T - 1 1 \ .IFF ; / F O C A L - PAPER TAPE \ .ENDC ; \ / ; / \ .IFDF $PAPER ; \ DEC-11-LFOCB-A-LA / .IFF ; \ DEC-11-ORUMA-A-LA / .ENDC ; / \ ; \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ ; ; ********************************* ; * THIS IS PART IV OF THE * ; * FOCAL LISTINGS. FOCMAT IS THE * ; * MATH PACKAGE FOR FOCAL. ALL * ; * MATHEMATICAL OPERATIONS IN * ; * FOCAL ARE PERFORMED HERE. * ; * * ; * THERE ARE TWO VERSIONS OF * ; * THIS ROUTINE, ONE EACH FOR * ; * SINGLE AND DOUBLE PRECISION. * ; * * .IF EQ,$DBL ; * THIS IS THE SINGLE PRECISION * .IFF ; * THIS IS THE DOUBLE PRECISION * .ENDC ; * VERSION. * ; ********************************* ; ; ; ORIGINAL CODING PERFORMED: DECEMBER 8, 1972 ; BY: RICHARD MERRIL ; .IFDF $PAPER ; PAPER TAPE VERSION CODED: JUNE 9,1974 .IFF ; RT-11 VERSION CONVERTED ON: JUNE 9,1974 .ENDC ; BY: GEORGE S. KACZOWKA (HIAS) ; ; ; COPYRIGHT (C) 1974 BY DIGITAL EQUIPMENT CORPORATION ; MAYNARD, MASSACHUSETTS 01754 ; ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO ; CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED ; AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. ; DEC ASSUMES NO RESPONSIBILITY FOR ANY ERRORS THAT ; MAY APPEAR IN THIS DOCUMENT. ; ; THIS SOFTWARE IS FURNISHED TO PURCHASER UNDER A ; LICENSE FOR USE ON A SINGLE COMPUTER SYSTEM AND ; CAN BE COPIED (WITH INCLUSION OF DEC'S COPYRIGHT ; NOTICE) ONLY FOR USE IN SUCH SYSTEM, EXCEPT AS MAY ; OTHERWISE BE PROVIDED IN WRITING BY DEC. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE ; OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT ; WHICH IS NOT SUPPLIED BY DEC. ; ;--- IF "$PAPER" IS DEFINED, FOCAL WILL ASSEMBLE AS A PAPER-TAPE ; VERSION. DEFAULT IS RT-11 VERSION. ; ; IF "$TRAP" IS DEFINED, INTERNAL CALLS WILL BE VIA ; A TRAP INSTRUCTION. THIS WILL TAKE LONGER, BUT CORE ; SIZE WILL BE REDUCED BY APPROXIMATELY 350 WORDS. ; ; IF "$SMALL" IS DEFINED, FOCAL-11 WILL ASSEMBLE MINUS ; THE FOLLOWING FEATURES: ; ; 1. ERROR INTERCEPTION ; ; 2. EXTENDED VIRTUAL FILES ; ; 3. FLN,FLOG,FEXP ARE NOT AVAILABLE ; ; 4. SCHEDULING BY EITHER TIME OR INTERRUPT ; ; 5. USE OF QUOTES IN LIBRARY COMMAND ; .GLOBL $DBL ;DOUBLE PRECISION SWITCH ; ;--- NOTE: THIS VARIABLE ($DBL) SHOULD BE DEFINED IN THIS ; MODULE. ALL ASSEMBLY CONDITIONALS BASED ON THIS ; VARIABLE SHOULD BE IN THIS MODULE. ; .IFDF $PAPER .IFDF $SMALL .TITLE FOCMAT(SP) - 4K PAPER-TAPE .IFF .IFEQ $DBL .TITLE FOCMAT(SP) - 8K PAPER-TAPE .IFF .TITLE FOCMAT(DP) - 8K PAPER-TAPE .ENDC .ENDC ; ;--- PAPER TAPE VERSION: .IFF .IFDF $SMALL .IFEQ $DBL .TITLE FOCMAT(SP) - 8K RT-11 VERSION .IFF .TITLE FOCMAT(DP) - 8K RT-11 VERSION .ENDC .IFF .IFEQ $DBL .TITLE FOCMAT(SP) - 12K RT-11 VERSION .IFF .TITLE FOCMAT(DP) - 12K RT-11 VERSION .ENDC .ENDC ; ;--- RT-11 VERSION .ENDC ; ; OPTIONS USED: .IIF DF,$PAPER,; $PAPER .IIF DF,$TRAP,; $TRAP .IIF DF,$SMALL,; $SMALL ; ; SUPPORTS: ; UP TO 28K CORE .IFDF $TRAP ; INTERNAL CALLS VIA TRAP INSTRUCTION .IFF ; INTERNAL CALLS VIA JSR INSTRUCTION .ENDC .IFNDF $SMALL ; EITHER SINGLE OR DOUBLE PRECISION PACKAGE ; (LINKAGE OPTION) .IFF ; SINGLE PRECISION ARITMETIC ONLY .ENDC .IFDF $RT11 ; DYNAMIC MEMORY ALLOCATION ; FULL LIBRARY CAPABILITIES ; VIRTUAL FILES ; UP TO 8 USER FILES ACCESSED AT ONE TIME .ENDC .IFNDF $SMALL ; FOCAL INTERRUPT SCHEDULING PROVIDED ; ASYNCHRONOUS TASK SCHEDULING BY TIME .ENDC ;DOCUMENTATION NOTES: ;DOUBLE QUOTE MARKS DENOTE TRAP-INSTRUCTION MODULES ;(X) MEANS THE CONTENT-OF-X. ;ASTERISKS DENOTE COMMAND MODULES. ;"C.R."MEANS "CARRIAGE RETURN". ;SINGLE QUOTE MARKS DENOTE A SUBROUTINE. .SBTTL ASSIGNMENTS OF REGISTERS ;AS USED GENERALLY TEMP=%0 ;SCRATCH AC=%1 ;ACCUMULATOR PTR=%2 ;VARIABLE POINTER AXOUT=%3 ;TEXT READER CHAR=%4 ;CHARACTER R5=%5 ;EXCEPTIONAL USE REGISTER AND RUBOUT PROTECTION R4=%4 R3=%3 R2=%2 R1=%1 R0=%0 ;TEMP REG USED BY RT-11 PATCH ROUTINES.. SP=%6 ;STACK POINTER PC=%7 ;PROGRAM COUNTER PDP-11 ;AS USED BY OUTPUT CONVERSION P=TEMP ;PLACES BEFORE "." AC=AC ;TOTAL NO. OF DIGITS. E=PTR ;NO. OF INTEGER DIGITS F=AXOUT ;TOTAL NO. OF PLACES. CHAR=CHAR ;NO. OF DECIMAL POINTS R5=R5 ;SCRATCH ;AS USED BY MAIN FLOATING POINT TEMP=TEMP ;SCRATCH AC=AC ;INPUT EXP;MAY CONTAIN OP-CODES BH=PTR ;FLAC HORD;MAY CONTAIN ADDRESS BL=AXOUT ;FLAC LORD;MAY BE NEEDED BY FREAD AH=CHAR ;INPUT HORD;MAY BE NEEDED BY FREAD AL=R5 ;INPUT LORD ONE=200 ;SWITCH ASSIGNMENTS ALL=1 NALPHA=20 ;0=TERMINATE ON ASCII CODES ;1=TERMINATE ON ;;C.R.ALSO CR=216 ;INTERNAL CODE CRLF=05015 ;FOR USE IN "PRINT2, CRLF" .IFDF $PAPER ;PAPER-TAPE VERSION ONLY TKS=177560 ;TELETYPE KEYBOARD TPS=177564 ;TELETYPE PRINTER LPS=177514 ;LINE PRINTER PRS=177550 ;H.S. READER PPS=177554 ;H.S. PUNCH .IFF TKS=0 TPS=0 LPS=1 PRS=2 PPS=3 ;THESE VALUES INDICATE VECTOR ENTRY .ENDC STATUS=177776 PSW=STATUS ;PDP-11 PEOPLE ARE FAMILIAR WITH THIS... .SBTTL GLOBAL VARIABLES ; ; .GLOBL SORTJ,SORTC,PRINTC,READC,OUTCH,INCH,GETC,PACKC,TESTC .GLOBL GETLN,FINDLN,PRNTLN,COPYLN,START,SPNOR,ERASEV,ERASET .GLOBL PRINT2,DIGTST,PARTST,GROOVY,SKPLPR,SKPNON,TASK .GLOBL EVAL.X,FPMP,FINT,FREAD,FPRINT,PATCH1,PATCH2 .GLOBL FLAC,FSIN,FCOS,FEXP,FLOG,FLN,FSQT,XITR .IF DF,$RT11 .GLOBL $VGET,$VPUT,VIRTUL,V.NAME,L.CHAN,VINDEX,VCHAN .ENDC ; ;--- NOW FOR GLOBAL ADDRESSES ; .GLOBL $FPMPX ;FLOATING POINT CALL ENTRY ; ; ERROR=104400 ;ERROR TRAP CALL ; ; POPJ=207 ;RTS PC ; ; RETURN=134 ;JMP @(R4)+ (POLISH RETURN) ; ; MAXCOD=6*2 ;MAX FPMP OPERATION CODE ; ; NGCODE=201+37.+37. ;ILLEGAL FLOATING POINT CALL .SBTTL $FPMPX - FPMP TRAP CALL ENTRY POINT ; ;--- $FPMPX - FOCAL TRAP CALL TO INVOKE FPMP CALLS. ; ; FOCAL TRAPS LEAVE SYSTEM IN STATE AS IF JSR R5,$FPMPX ; WAS PERFORMED. AT ENTRY, SAVE ALL REGISTERS EXCEPT R5. ; ; DECODE WORD FOLLOWING CALL FOR CORRECT ADDRESSING MODE OF ; ARGUEMENT. AFTER ESTABLISHED, INDEX TO CORRECT ; FPMP DRIVER CODE TO PERFORM OPERATION. R0 WILL THEN ; POINT TO THE SOURCE OPERAND, AND R1 WILL CONTAIN ; AN INDEX OF VECTR2 WHICH WILL BE USED BY THE ; EXEC ROUTINE TO PERFORM THE MATH FUNCTION. ; ; CONTINUE THIS PROCEDURE UNTIL NEXT INSTRUCTION DOES NOT HAVE THE ; FLOATING POINT CODE OF 016 IN THE HIGH BYTE. (007000-007377) ; ; THEN RESTORE REGISTERS AND PERFORM A RTS R5 TO THE MAINLINE CODE. ; .GLOBL FSW ;FLOATING POINT ERROR SWITCH ;WHEN NOT ZERO, TRAPS ARE DECODED AS ;FLOATING POINT ERRORS. SEE RT-11 ;FORTRAN MANUAL FOR DETAILS OF ERRORS. ; $FPMPX: MOV R0,-(SP) ;SAVE REGISTERS R0-R3 MOV R1,-(SP) MOV R3,-(SP) MOV R2,-(SP) INCB FSW ;SET IN FLOATING POINT ; ;--- ENTRY POINT #2 - VERIFY FPMP CODE TO BE PERFORMED ; $FPMP2: CMPB 1(R5),#16 ;SPECIAL CODE? BNE $FPMPE ;NO - EXIT MOVB (R5)+,R0 ;GET THE CODE BPL 1$ ;SKIP IF WE ARE TO GEN CODE MOVB 4(SP),R0 ;GET CODE 1$: MOV R0,R1 ;AND ESTABLISH IT! INC R5 ;UPDATE THE POINTER BIC #-10,R0 ;SAVED IN R0 BIC R0,R1 ;REMOVE IT ASR R1 ;GET OTHER BITS SHIFTED DOWN ASR R1 ;FINISHED... CONSTRUCT DATA POINTER IN PTR ASL R0 ;MAKE A WORD INDEX CMP R1,#MAXCOD ;FPMP FUNCTION CALL? BLE $FEXEC ;NO - EXECUTE JSR PC,@VECTR3(R0) ;CALL ROUTINE BR $FPMP2 ;CONTINUE ; $FPMPE: DECB FSW ;RESET FLOATING POINT SWITCH MOV (SP)+,R2 MOV (SP)+,R3 ;RESTORE REGISTERS R3-R0 MOV (SP)+,R1 MOV (SP)+,R0 RTS R5 ;RETURN TO THE USER .SBTTL ADDRESS MODE DECODING TABLE ; ; ; $FEXEC: JMP @VECTOR(R0) ;GO TO IT! ; ;--- VECTOR TABLE FOR RETRIEVING THE DATA ; ; ;--- DIRECT MODE (0) - ADDRESS FOLLOWS CALL ; VECTOR: .WORD DIRECT ;DIRECT CALL ; ; ;--- IPTR MODE (1) - PTR POINTS TO THE DATA (WHAT WE WANT TO DO!) ; .WORD IPTR ;NULL ROUTINE ; ; ;--- XPTR MODE (2) - PTR POINTS TO DATA, THEN INDEX BY CORRECT AMOUNT ; .WORD XPTR ;SET UP INDEX ; ; ;--- STACK MODE (3) - STACK HAS DATA PUSHED ON IT ; .WORD STACK ;SET UP PTR TO POINT AT STACK ; ; ;--- ISTACK MODE (4) - STACK HOLDS THE POINTER TO THE DATA ; .WORD ISTACK ;LOAD UP PTR WITH THE POINTER ; ; ;--- IMMEDIATE MODE (5) - DATA FOLLOWS THE CALL (ALWAYS 4 WORDS) ; .WORD IMMED ;HANDLE THE CASE OF IMMEDIATE MODE ; ; ;--- RELATIVE MODE (6) - (PIC) - OFFSET FROM PC TO DATA FOLLOWS CODE ; .WORD RELTIV ;HANDLE RELATIVE OFFSET CASE ; ; ;--- ERROR CODE (7) - ILLEGAL ; .WORD CODERR .SBTTL ADDRESSING MODE PROCESSING ROUTINES ; ;--- ADDRESSING ROUTINES: ; ;(0) ; DIRECT: MOV (R5)+,R0 ;LOAD ADDRESS BR EXEC ;EXECUTE FPMP FUNCTION ; ;(1) ; IPTR: MOV (SP),R0 ;GET VALUE BR EXEC ;GO!!! ; ;(2) ; XPTR: MOV (SP),R0 ;RECOVER ORIGINAL VALUE .IF EQ,$DBL ADD #4,(SP) ;INDEX BY SINGLE LENGTH .IFF ADD #8.,4(SP) ;INDEX BY DOUBLE LENGTH .ENDC BR EXEC ;EXECUTE THE FUNCTION ; ;(3) ; STACK: MOV SP,R0 ;GET POSITION OF THE STACK ADD #12,R0 ;POINT AT STACK POSITION BEFORE CALL BR EXEC ;GO DO OUR THING! ; ;(4) ; ISTACK: MOV 12(SP),R0 ;POINT THROUGH STACK BR EXEC ;PERFORM FUNCTION ; ;(5) ; IMMED: MOV R5,R0 ;POINT AT THE LOCATION ADD #10,R5 ;POINT OVER 4 WORDS BR EXEC ;PERFORM THE FUNCTION ; ;(6) ; RELTIV: MOV R5,R0 ;GET WORD FOLLOWING ADD (R5)+,R0 ;ADD PC TO OFFSET BR EXEC ;DO IT ; ;(7) ; CODERR: CLRB FSW ;RESET ERROR SWITCH ERROR+NGCODE ;SEND ERROR (INTERNAL) .SBTTL FPMP OPERATION CODE DECODE TABLES ; ;--- EXEC - THIS SECTION INDEXES FOR CORRECT CODE ; EXEC: ; ;--- INDEX DOWN ON CODE IN R1 ; ; JSR R4,@VECTR2(R1) ;CALL ROUTINE IN POLISH MODE 1$: FLAC ;POINT TO FLAC FOR MEMORY OPERATIONS .+2 ;RETURN FROM POLISH MODE POWXIT: MOV (SP)+,R4 ;RESTORE R4 BR $FPMP2 ;CONTINUE TO CHECK ; ;--- FPMP OPERATION VECTOR TABLE ; VECTR2: .WORD MOV$AM ;GET IT INTO THE FLAC ; ; .IF EQ,$DBL .WORD ADF$AM ;SINGLE PRECISION ADD ; ; .WORD SUF$AM ;SINGLE PRECISION SUBTRACT ; ; .WORD DIF$AM ;SINGLE PRECISION DIVIDE ; ; .WORD MUF$AM ;SINGLE PRECISION MULTIPLY .IFF .WORD ADD$AM ;DOUBLE PRECISION ADD .WORD SUD$AM ;DOUBLE PRECISION SUBTRACT ; ; .WORD DID$AM ;DOUBLE PRECISION DIVIDE ; ; .WORD MUD$AM ;DOUBLE PRECISION MULTIPLY .ENDC ; ; .WORD FPOW ;RAISE THE FLAC TO THIS POWER ; ; .WORD MOV$MA ;PUT IT OUT OF THE FLAC ; ; ;--- T..T...T...T...THAT'S ALL FOLKS! ; ; .SBTTL OPERATION EXECUTION ROUTINES ; ; .IF EQ,$DBL ADF$AM: JSR R4,@(PC)+ ;ENTER POLISH .IFF ADD$AM: JSR R4,@(PC)+ ;ENTER POLISH .IFTF MOV$MS ;MOVE FROM MEMORY TO STACK FLAC ;FROM THE FLAC MOV$AS ;MOVE OPERAND TO STACK .IFT .GLOBL ADF$SS ADF$SS ;PERFORM THE ADDITION .IFF .GLOBL ADD$SS ADD$SS ;PERFORM THE ADDITION IN DOUBLE PRECISION .IFTF MOV$SM ;RESTORE THE FLAC ;FLOATING ACCUMULATOR BYEBYE ;EXIT FROM OUR POLISH AND RETURN ; ; .IFT SUF$AM: JSR R4,@(PC)+ ;ENTER POLISH .IFF SUD$AM: JSR R4,@(PC)+ ;CALL POLISH .IFTF MOV$MS ;MOVE FROM MEMORY TO STACK FLAC ;FROM THE FLAC MOV$AS ;MOVE OPERAND TO STACK .IFT .GLOBL SUF$SS SUF$SS ;PERFORM THE SUBTRACTION .IFF .GLOBL SUD$SS SUD$SS ;PERFORM THE SUBTRACTION IN DOUBLE PRECISION .IFTF MOV$SM ;RESTORE THE FLAC ;FLOATING ACCUMULATOR BYEBYE ;EXIT FROM OUR POLISH AND RETURN ; ; .IFT DIF$AM: JSR R4,@(PC)+ ;ENTER POLISH .IFF DID$AM: JSR R4,@(PC)+ .IFTF MOV$MS ;MOVE FROM MEMORY TO STACK FLAC ;FROM THE FLAC MOV$AS ;MOVE OPERAND TO STACK .IFT .GLOBL DIF$SS DIF$SS ;PERFORM THE DIVISION .IFF .GLOBL DID$SS DID$SS ;PERFORM THE DIVISION IN DOUBLE PRECISION .IFTF MOV$SM ;RESTORE THE FLAC ;FLOATING ACCUMULATOR BYEBYE ;EXIT FROM OUR POLISH AND RETURN ; ; .IFT MUF$AM: JSR R4,@(PC)+ ;ENTER POLISH .IFF MUD$AM: JSR R4,@(PC)+ ;ENTER POLISH .IFTF MOV$MS ;MOVE FROM MEMORY TO STACK FLAC ;FROM THE FLAC MOV$AS ;MOVE OPERAND TO STACK .IFT .GLOBL MUF$SS MUF$SS ;PERFORM THE MULTIPLICATION .IFF .GLOBL MUD$SS MUD$SS ;PERFORM THE MULTIPLICATION IN DOUBLE PRECISION .IFTF MOV$SM ;RESTORE THE FLAC ;FLOATING ACCUMULATOR BYEBYE ;EXIT FROM OUR POLISH AND RETURN ; ; .ENDC ; BYEBYE: MOV (SP)+,R4 ;RESTORE OLD POLISH PC TST (R4)+ ;POP THE WORD RETURN ;CONTINUE ALONG .SBTTL FPOW - SPECIAL ROUTINE TO RAISE TO THE POWER ; ; FPOW: JSR R4,$POLSH ;CHECK ON POWER FUNCTION POWCHK ;CALL IT NOLOG ;BRANCH TO NOLOG IF NO LOG OR EXP FUNCTION NEGFLC ;BRANCH TO NEGFLC IF FLAC IS NEGATIVE POSFLC: CALFLN ;RETURN HERE IS ALL IS OK .IF EQ,$DBL MUF$AM ;MULTIPLY .IFF MUD$AM ;DOUBLE PRECISION MULTIPLY .ENDC FLAC ;MUL THE FLAC CALEXP ;TAKE THE EXP POWXIT ;AND EXIT ; NEGFLC: CALABS ;GET ABS OF FLAC SAV$A ;SAVE R0 MOV$AS .IF EQ,$DBL .GLOBL $RI $RI ;GET INTEGER ON STACK .IFF .GLOBL $DI $DI ;MAKE AN INTEGER .ENDC GET$A ;GET R0 BACK CALFLN ;TAKE LOG .IF EQ,$DBL MUF$AM .IFF MUD$AM .ENDC FLAC CALEXP ;TAKE EXP OF IT CALFIX ;FIX IT UP POWXIT ;EXIT ; NOLOG: MOV$AS ;COPY TO THE STACK .IF EQ,$DBL $RI .IFF $DI .ENDC SETLP ;SET LOOP PARAMETER MOV$MS ;STACK FLAC ;THE FLAC SET$SA ;POINT R0 AT THE STACK SAV$A ;SAVE IT MOV$1M ;SET A ONE IN THE FLAC FLAC LOOP ;CHECK FOR LOOP 1$ ;KEEP IT UP POWXIT ;EXIT 1$: GET$A ;RESTORE R0 .IF EQ,$DBL MUF$AM .IFF MUD$AM .ENDC FLAC ;WITH THE FLAC LOOP ;LOOP BACK 1$ ;UNTIL COUNT IS EXHAUSTED POWXIT ;EXIT ; ; SAV$A: MOV R0,SAVER0 ;SAVE IT RETURN ; ; GET$A: MOV SAVER0,R0 ;RESTORE IT RETURN ; ; SAVER0: .WORD 0 ;SAVE AREA ; ; POWCHK AND POWXIT - ROUTINES IN POLISH FOR POWER CODE ; POWCHK: ;THIS ROUTINE IS TO DETERMINE HOW WE DO IT! TST @R0 ;IS THE POWER EQUAL TO ZERO? BEQ 3$ ;YES - ALWAYS RETURN A ONE... .IF EQ,$DBL ; .GLOBL ALOG,EXP ;LOG FUNCTIONS ; TST #ALOG ;IS IT DEFINED? BEQ 1$ ;NO - HANDLE THE EXIT TST #EXP ;IS THIS DEFINED TOO? BEQ 1$ ;NO - WE MUST USE OLD WAY .IFF ; .GLOBL DLOG,DEXP ;DOUBLE PRECISION LOG FUNCTIONS ; TST #DLOG ;LOG AVAILABLE? BEQ 1$ ;NO - REPETATIVE MULTIPLICATION TST #DEXP ;HOW ABOUT THE EXPONENTIAL FUNCTION? BEQ 1$ ;NO - USE SLOW METHOD. WE NEED BOTH .ENDC TST (R4)+ ;SKIP THE POINTER FOR NO LOG/EXP FUNCTION TST FLAC ;IS THE BASE NEGATIVE? BMI 2$ ;YES - THIS IS SPECIAL BEQ POWXIT ;IF ZERO,EXIT... TST (R4)+ ;SKIP POINTER RETURN ;RETURN TO POLISH ; 1$: TST @R0 ;IS THE OPERAND NEGATIVE? BMI ERR15 ;CAN'T DO IT.. 2$: MOV @R4,R4 ;PERFORM A POLISH JUMP (USUALLY BACKWARDS) RETURN ;CONTINUE AT NEW LOCATION ; 3$: MOV #FLAC,R1 ;POINT AT THE RESULT FIELD JSR PC,FSGN2 ;FORCE A +1 INTO THE FIELD BR POWXIT ;AND RETURN WITH THE PROPER RESULT ; ERR15: CLRB FSW ;RESET FLOATING POINT SWITCH ERROR+201+15.+15. ;SEND ERROR ; ; CALFIX - POWER FIX ROUTINE FOR THE NEGATICE FLAC CASE ; CALFIX: ROR (SP)+ ;SEE IF AN ODD NUMBER OF POWERS BCC 1$ ;SKIP IF EVEN BIS #100000,FLAC ;SET THE FLAC AS NEGATIVE 1$: RETURN ;POLISH RETURN .SBTTL POLISH UTILITY ROUTINES ; ; ;--- UTILITY POLISH ROUTINES ; ; MOVES... ; MOVE FROM MEMORY TO THE STACK ; ; MOV$MS: MOV (R4)+,R2 ;POINT AT THE MEMORY BR MOV$XS ;CONTINUE ; ; MOVE THE OPERAND TO THE STACK ; MOV$AS: MOV R0,R2 ;SET THE VALUE .IF EQ,$DBL MOV$XS: ADD #4,R2 ;POINT TO THE END .IFF MOV$XS: ADD #8.,R2 ;POINT AT THE END MOV -(R2),-(SP) ;STACK MOV -(R2),-(SP) .ENDC MOV -(R2),-(SP) ;PUSH THE VALUE ON THE STACK MOV -(R2),-(SP) RETURN ;RETURN ; ; SET THE OPERAND TO BE THE STACK (NON-POP STACK MODE) ; SET$SA: MOV SP,R0 ;POINT AT THE STACK POSITION RETURN ;RETURN ; ; MOVE OPERAND TO MEMORY ; MOV$AM: MOV (R4)+,R1 MOV R0,R2 ;SAVE IT ; ; GENERAL MOVE FROM R2 TO R1 ; MOV$: MOV (R2)+,(R1)+ MOV (R2)+,(R1)+ .IF NE,$DBL MOV (R2)+,(R1)+ ;CONTINUE MOV (R2)+,(R1)+ .ENDC RETURN ;RETURN ; ; MOVE MEMORY TO OPERAND ; MOV$MA: MOV (R4)+,R2 MOV R0,R1 ;SET POINTERS BR MOV$ ;MOVE IT AND EXIT ; ; CALL THE FABS FUNCTION ; CALABS: JSR PC,FABS ;GET ABS RETURN ;RETURN ; ; CALL THE EXPONENTIAL FUNCTION ; CALEXP: JSR PC,FEXP ;GET EXP FUNCTION RETURN ;RETURN ; ; CALL THE NATURAL LOGARITHM ROUTINE ; CALFLN: JSR PC,FLN ;CALL LOG FUNCTION RETURN ;CONTINUE ; ; SET UP FOR A REPEAT LOOP (COUNTER IS @R5 WHEN THROUGH) ; SETLP: MOV @SP,-(SP) ;OPEN SPACE BY COPYING VALUE TO BE COUNTED BMI ERR15 ;SEND ERROR IN CASE IT IS NEGATIVE MOV R5,2(SP) ;SAVE R5 MOV SP,R5 ;REMEMBER WHERE WE WERE ; THIS IS ALSO USED TO REINSTATE THE STACK ; WHEN WE ARE THROUGH RETURN ;CONTINUE ; ; EXECUTE THE LOOP CONTROL ROUTINE. WORD FOLLOWING CALL ; IS USED IF THE COUNTER IS GREATER THAN OR EQUAL TO ZERO. ; LOOP: DEC @R5 ;COUNT IT OUT BMI 1$ ;SKIP IF WE ARE TO EXIT MOV (R4)+,R4 ;POINT TO WHERE WE ARE GOING RETURN ;CONTINUE AT NEW LOCATION ; 1$: MOV R5,SP ;RESET THE STACK TST (SP)+ ;POP IT MOV (SP)+,R5 ;GET R5 BACK TST (R4)+ ;SKIP BRANCH LOCATION RETURN ;FALL THROUGH ; ; MOVE STACK TO MEMORY ; MOV$SM: MOV (R4)+,R2 MOV (SP)+,(R2)+ MOV (SP)+,(R2)+ .IF NE,$DBL MOV (SP)+,(R2)+ MOV (SP)+,(R2)+ .ENDC RETURN ;RETURN ; ; MOVE ONE TO MEMORY ; MOV$1M: MOV (R4)+,R1 ;POINT AT THE MEMORY JSR PC,FSGN2 ;FIX IT UP RETURN ;CONTINUE ; ; $POLSH - ROUTINE TO ENTER POLISH MODE SIMPLY ; $POLSH: TST (SP)+ ;POP THE STACK RETURN ;CONTINUE .SBTTL FUNCTION CODE (7X) TABLES ; ; VECTR3: .WORD FEXIT ;NORMALIZE IS A NOP ; ; .WORD FINT ;INTEGER ROUTINE ; ; .WORD FSGN ;GET SIGN FUNCTION ; ; .WORD FABS ;GET ABS FUNCTION ; ; .WORD FNEG ;NEGATE THE FLAC ; ; .WORD FLOAT ;FLOAT THE INTEGER (AC) ; ; .WORD FEXIT ;NOP FOR NOW ; ; .WORD FZER ;CLEAR THE FLAC ; ; ;-------------------------------- ; ; FINT: CMP FLAC,#^F-32768 ;SEE IF SPECIAL VALUE BNE 1$ ;NO - EXIT BIT #170000,FLAC+2 ;SEE IF CORRECT BNE 1$ ;NO...EXIT MOV #100000,R1 ;SET VALUE BR 2$ ;GET OUT 1$: JSR R4,MOV$MS ;LOAD FLAC AND ENTER POLISH MODE FLAC .IF EQ,$DBL .WORD $RI .IFF .WORD $DI .ENDC .WORD .+2 ;EXIT POLISH MOV (SP)+,R1 ;GET VALUE MOV (SP)+,R4 ;RESTORE R4 2$: MOV R1,6(SP) ;PLACE INTO THE RETURN LOC POPJ ;RETURN ; ; FSGN: MOV #FLAC,R1 ;POINT TO IT TST @R1 ;SET CONDITION CODES BGT FSGN2 ;HANDLE GREATER THAN BEQ FSGN1 ;HANDLE ZERO MOV #^F-1,(R1)+ ;SET IT BR FSGN3 ;SKIP FSGN1: CLR (R1)+ ;CLEAR IT BR FSGN3 ;SKIP FSGN2: MOV #^F1,(R1)+ ;SET FIRST WORD FSGN3: CLR (R1)+ ;ZAP SECOND WORD .IF NE,$DBL CLR (R1)+ CLR (R1)+ ;AND THE REST TOO .ENDC POPJ ;EXIT ; ; ; ABSOLUTE VALUE FUNCTION ; FABS: BIC #100000,FLAC ;RESET BIT ON FLAC FEXIT: POPJ ;RETURN ; ; FNEG: TST FLAC ;NEG? BEQ FEXIT ;-0=+0 !!! BMI FABS ;NEGATE BY ABS VAL BIS #100000,FLAC ;SET MINUS IF NOW POS POPJ ;RETURN ; ; FLOAT THE CONTENTS OF R1 INTO THE FLAC ; FLOAT: MOV 6(SP),R1 ;RECOVER ORIG MOV R4,-(SP) ;SAVE R4 MOV R1,-(SP) ;PLACE ONTO THE STACK JSR R4,$POLSH ;ENTER POLISH .IF EQ,$DBL .GLOBL $IR .WORD $IR .IFF .GLOBL $ID .WORD $ID .ENDC MOV$SM ;RESTORE IT FLAC .+2 ;EXIT POLISH MOV (SP)+,R4 ;GET IT BACK POPJ ;RETURN ; ; FZER: MOV #FLAC,R1 BR FSGN1 ;ZERO IT .SBTTL FOCAL FUNCTIONS ENTERED VIA A JSR PC,FXXXX ; ; ; FITR - GET INTEGER PART ; XITR: .IF EQ,$DBL .GLOBL AINT MOV #AINT,-(SP) ;STACK .IFF .GLOBL DINT MOV #DINT,-(SP) ;STACK IT .ENDC BR FUNCT ; ; FSQT - SQUARE ROOT FUNCTION ; FSQT: .IF EQ,$DBL .GLOBL SQRT MOV #SQRT,-(SP) .IFF .GLOBL DSQRT MOV #DSQRT,-(SP) .ENDC BR FUNCT ; ; FSIN - SINE FUNCTION ; FSIN: .IF EQ,$DBL .GLOBL SIN MOV #SIN,-(SP) .IFF .GLOBL DSIN MOV #DSIN,-(SP) .ENDC BR FUNCT ; ; FCOS - COSINE FUNCTION ; FCOS: .IF EQ,$DBL .GLOBL COS MOV #COS,-(SP) .IFF .GLOBL DCOS MOV #DCOS,-(SP) .ENDC BR FUNCT ; ; FLN - NATURAL LOGARITHM FUNCTION ; FLN: .IF EQ,$DBL .GLOBL ALOG MOV #ALOG,-(SP) .IFF .GLOBL DLOG MOV #DLOG,-(SP) .ENDC BR FUNCT ; ; FLOG - LOG BASE 10 ROUTINE ; FLOG: .IF EQ,$DBL .GLOBL ALOG10 MOV #ALOG10,-(SP) .IFF .GLOBL DLOG10 MOV #DLOG10,-(SP) .ENDC BR FUNCT ; ; FEXP - EXPONENTIAL FUNCTION ; FEXP: .IF EQ,$DBL .GLOBL EXP MOV #EXP,-(SP) .IFF .GLOBL DEXP MOV #DEXP,-(SP) .ENDC .IF NE,$DBL ; BR FUNCT ;ENTER FUNCTION CODE ; DINT: MOV #FLAC+8.,R0 ;POINT FOR $DINT MOV -(R0),-(SP) ;PLACE THE FLAC ON THE STACK MOV -(R0),-(SP) MOV -(R0),-(SP) MOV -(R0),-(SP) ;COMPLETE - NOW CALL $DINT JSR R4,$POLSH ;ENTER POLISH .GLOBL $DINT .WORD $DINT .WORD .+2 MOV (SP)+,R0 MOV (SP)+,R1 MOV (SP)+,R2 MOV (SP)+,R3 RTS PC ;RETURN LIKE A FORTRAN FUNCTION .ENDC .SBTTL GENERAL FUNCTION INTERFACE ; ; FUNCT: TST @SP ;ROUTINE HERE? BEQ 3$ ;NO - SEND ERROR MOV R0,-(SP) ;SAVE R0-R4 MOV R1,-(SP) ;SAVED MOV R2,-(SP) MOV R3,-(SP) MOV R4,-(SP) JSR R5,2$ ;CALL ROUTINE, SAVING R5 AND POINTING BR 1$ ;AT THIS ARGUEMENT LIST .WORD FLAC ;OPERAND IS IN THE FLAC 1$: MOV #FLAC,R4 ;POINT AT IT MOV R0,(R4)+ ;PASS THE RESULT MOV R1,(R4)+ ;CONTINUE .IF NE,$DBL ;IF DBL PRCSN MOV R2,(R4)+ ;THIRD WORD MOV R3,(R4)+ ;FINAL WORD .ENDC MOV (SP)+,R4 ;RESTORE THE MOV (SP)+,R3 MOV (SP)+,R2 ;REGISTERS SAVED MOV (SP)+,R1 MOV (SP)+,R0 ;ABOVE TST (SP)+ ;POP THE ROUTINE ADDRESS POPJ ;RETURN TO THE CALLER ; ; CALL TO DESIGNATED FUNCTION - R5 IS ALL SET UP ; 2$: INCB FSW ;SET FLOATING POINT JSR PC,@12.(SP) ;CALL THE ROUTINE DECB FSW ;RESET THE SWITCH RTS R5 ;REENTER THE CODE AND RESTORE R5 ; ; ERROR - ROUTINE NOT AVAILABLE ; 3$: CLRB FSW ;RESET FORTRAN SWITCH ERROR+201+2+2 ;ILLEGAL FUNCTION .IFDF $RT11 ;RT-11 VERSION .SBTTL $VGET/$VPUT - ROUTINE TO HANDLE A VARIABLE FROM A VIRTUAL FILE ; .GLOBL C.BUF,C.OFF,C.BLK,C.FIL,L.WRT ; .GLOBL GCHAN,DMPBLK,NXTBLK ; $VPUT: MOV #1,AC ;POINT TO TRANSFER TABLE BR $VGO ;DO IT ; $VGET: CLR AC ;POINT TO TRANSFER TABLE $VGO: MOV L.CHAN,-(SP) ;GET CHANNEL INTO THE STACK MOV VCHAN,L.CHAN ;LOOK UP VIRTUAL FILE CHANNEL GCHAN ;GET THE CHANNEL POINTER MOV R5,-(SP) ;SAVE R5 ALSO MOV TEMP,R5 ;HANG ONTO THE CHANNEL POINTER TSTB @R5 ;IS THE CHANNEL OPEN? BNE 1$ ;YES - CONTINUE ERROR+201+36.+36. ;INTERNAL VIRTUAL FILE ERROR 1$: MOVB 1(R5),TEMP ;GET FORMAT INFO ASL TEMP ;*2 FOR WORD OFFSET MOV #2$,-(SP) ;SET RETURN ADDRESS MOV AC,-(SP) ;IN/OUT SWITCH JMP @V.XFER(TEMP) ;GO DO IT 2$: MOV (SP)+,R5 ;RECOVER R5 MOV (SP)+,L.CHAN ;RESET CHANNEL MOV #VIRTUL,PTR ;SET PTR FOR VIRTUAL FILES POPJ ;RETURN ; V.XFER: V.DFLT ;USE DEFAULT OF SINGLE OR DOUBLE PRCSN V.DBL ;USE DOUBLE PRECISION V.SNG ;USE SINGLE PRECISION V.XTND ;USE EXTENDED 16 BIT INTEGER V.INT ;USE STANDARD SIGNED INTEGER V.BYTE ;USE STANDARD UNSIGNED INTEGER BYTE V.TEXT ;USE 7 BIT ASCII ; .SBTTL DEFAULT INPUT AND OUTPUT CONVERSION ; .MACRO FIND .A .LIST MEB MOV VINDEX,AC ;GET SUBSCRIPT MOV #'.A',TEMP ;SET '.A' OCTAL BYTES/ENTRY JSR PC,V.FIND ;LOOK UP THE ENTRY .NLIST MEB .ENDM FIND ; .IF NE,$DBL V.DFLT: FIND 10 ;GET THE INDEX ENTRY .IFF V.DFLT: FIND 4 .ENDC MOV #VIRTUL,AC ;POINT AT OUTPUT FIELD TST (SP)+ ;SEE IF WE ARE TO READ OR WRITE BNE 2$ ;WRITE MOV (PTR)+,(AC)+ MOV (PTR)+,(AC)+ .IF NE,$DBL MOV (PTR)+,(AC)+ MOV (PTR)+,(AC)+ .ENDC BR 3$ ;EXIT NOW 2$: MOV (AC)+,(PTR)+ MOV (AC)+,(PTR)+ ;COPY OUT .IF NE,$DBL MOV (AC)+,(PTR)+ MOV (AC)+,(PTR)+ .ENDC BIS #L.WRT,@R5 ;SET THE CORRECT BIT 3$: POPJ ;RETURN ; ; .IF NDF,$SMALL ;8K VERSION DOESN'T HAVE THIS .IF EQ,$DBL V.SNG=V.DFLT ; V.DBL: FIND 10 .IFF V.DBL=V.DFLT ; V.SNG: FIND 4 .IFTF MOV #VIRTUL,AC ;POINT AT THE AREA TST (SP)+ ;READ? BNE 1$ ;NO - SKIP MOV (PTR)+,(AC)+ ;READ THE VARIABLE MOV (PTR)+,(AC)+ ;DITTO .IFT TST @PTR ;SHOULD WE ROUND? BPL 2$ ;NO - EXIT INC -(AC) ;UPDATE IT ADC -(AC) ;PASS POSSIBLE CARRY .IFF CLR (AC)+ ;ZAP IT CLR (AC)+ ;AGAIN .IFTF BR 2$ ;EXIT ; 1$: MOV (AC)+,(PTR)+ ;COPY THE WORDS MOV (AC)+,(PTR)+ ;DITTO .IFT CLR (PTR)+ ;AND ZERO OTHERS CLR (PTR)+ .IFTF BIS #L.WRT,@R5 ;SET WRITTEN INTO 2$: POPJ ;RETURN .ENDC .ENDC .SBTTL V.FIND - ROUTINE TO LOCATE THE VIRT. FILE VARIABLE ; ; ;--- ON ENTRY: R0 CONTAINS THE NUMBER OF BYTES/ENTRY. THIS VALUE ; ** M U S T ** BE A POWER OF TWO!!!!!! (OR 1 WHICH IS 2^0) ; ; R1 HOLDS THE SUBSCRIPT VALUE (POSITIVE PLEASE!!!) ; ;--- ON EXIT, CORRECT BUFFER IS IN CORE, AND "PTR" POINTS TO THE ; FIRST BYTE OF THE ENTRY. ; V.FIND: MOV AC,PTR ;COPY THE SUBSCRIPT BIC #377,AC ;CLEAR LOW BYTE BIC AC,PTR ;REMAINDER SWAB AC ;FAST DIVIDE BY 256 ; 1$: CMP TEMP,#1 ;IS THIS THE END? BLOS 2$ ;YES - NOW AS A BYTE QUANTITY ROLB PTR ;A FANCY SHIFT ROL AC ;PLACE IT ROR TEMP ;UPDATE WHERE WE GO BCC 1$ ;CONTINUE IF A POWER OF TWO ERROR+201+36.+36. ;INTERNAL V. F. ERROR ; 2$: ROR AC ;RESTORE BYTES (512 BYTES/BLOCK) BCC 3$ ;SKIP IF ZERO BIS #400,PTR ;SET THE BYTE 3$: CMP AC,C.BLK(R5) ;ARE WE ON THE RIGHT BLOCK? BEQ 4$ ;YES - EXIT MOV VCHAN,TEMP ;CHECK OUT EXPONENT ASL TEMP ;*2 FOR WORDS ASL TEMP ;*4 (2 WORDS/ENTRY) .GLOBL V.NAME ADD #V.NAME,TEMP ;POINT TO THE ENTRY CMP AC,2(TEMP) ;SEE IF WITHIN THE MAX SIZE BHIS 5$ ;NO - SEND ERROR MOV R5,TEMP ;SET UP DMPBLK ;DUMP IT OUT MOV AC,C.BLK(R5) ;SET NEW ONE NXTBLK ;GET NEW BLOCK 4$: ADD C.BUF(R5),PTR ;POINT AT THE BUFFER MOV PTR,AC ;AC NOW POINTS TO THE FIRST ; BYTE OF THE ENTRY POPJ ;RETURN ; 5$: ERROR+201+19.+19. ;SUBSCRIPT OUT OF RANGE .SBTTL FLAC SAVE AND RESTORE ROUTINES ; $FSAVE: MOV (SP)+,AC ;SAVE RETURN ADDRESS MOV #FLAC,R0 ;POINT AT THE FLAC MOV (R0)+,-(SP) ;SAVE IT MOV (R0)+,-(SP) .IF NE,$DBL MOV (R0)+,-(SP) MOV (R0)+,-(SP) .ENDC MOV AC,PC ;SET RETURN ADDRESS ; $FREST: MOV (SP)+,AC .IF EQ,$DBL MOV #FLAC+4,R0 .IFF MOV #FLAC+8.,R0 .ENDC MOV (SP)+,-(R0) MOV (SP)+,-(R0) .IF NE,$DBL MOV (SP)+,-(R0) MOV (SP)+,-(R0) .ENDC MOV AC,PC ;RETURN .IF NDF,$SMALL .SBTTL ONE WORD INTEGER CONVERSION ROUTINES ; ; V.XTND: FIND 2 ;GET LOCATION TST (SP)+ ;INPUT? BEQ I.XTND JSR PC,$FSAVE ;SAVE THE FLAC JSR R5,$FPMPX ;ENTER FLT PT MODE 007000 ;FGET+DIRECT VIRTUL ;VIRTUL; 007073 ;FABS; 007020 ;FSUB+DIRECT V.MAX ;V.MAX; BR V.IGO ;CONTINUE ; V.INT: FIND 2 ;LOCATE THE VARIABLE TST (SP)+ ;INPUT? BEQ I.INT ;YES - GO TO IT JSR PC,$FSAVE ;SAVE FLAC JSR R5,$FPMPX ;ENTER FLT PT MODE 007000 ;FGET+DIRECT VIRTUL ;VIRTUL; V.IGO: JSR R5,$FPMPX ;RE-ENTER FLOATING POINT MODE 007071 ;FINT MOV AC,@PTR ;SET IT IN V.OUT: JSR PC,$FREST ;RESTORE THE FLAC BIS #L.WRT,@R5 ;SET WRITTEN INTO POPJ ;RETURN ; I.XTND: JSR PC,$FSAVE MOV @PTR,AC ;GET IT JSR R5,$FPMPX ;ENTER FLT PT MODE 007075 ;FLOAT; 007010 ;FADD+DIRECT V.MAX ;MAX NUMBER BR I.IGO ;CONTINUE ; I.INT: JSR PC,$FSAVE MOV @PTR,AC ;GET THE VARIABLE I.BGO: JSR R5,$FPMPX ;ENTER FLOATING POINT MODE 007075 ;FLOAT; I.IGO: JSR R5,$FPMPX ;ENTER FLOATING POINT AGAIN 007060 ;FPUT+DIRECT VIRTUL ;PLACE IN THE AREA JSR PC,$FREST ;RESTORE THE FLAC POPJ ;RETURN ; V.MAX: .FLT4 32768 .SBTTL BYTE TRANSFER CONVERSION ROUTINES ; V.BYTE: FIND 1 TST (SP)+ ;SEE IF INPUT OR OUTPUT BEQ I.BYTE ;HANDLE INPUT JSR PC,$FSAVE ;SAVE FLAC JSR R5,$FPMPX ;ENTER FLOATING POINT MODE 007071 ;FINT MOVB AC,@PTR ;SAVE IT BR V.OUT ;GET OUT ; I.BYTE: JSR PC,$FSAVE ;SAVE THE FLAC MOVB @PTR,AC ;GET IT BR I.BGO ;CONTINUE IT ; ; V.TEXT: FIND 1 TST (SP)+ ;IN OR OUT? BEQ I.TEXT ;HANDLE INPUT JSR PC,$FSAVE JSR R5,$FPMPX 007071 ;FINT BIC #177600,AC ;SET TEXT MOVB AC,@PTR ;PLACE INTO THE FILE BR V.OUT ;GET OUT ; I.TEXT: JSR PC,$FSAVE MOVB @PTR,AC BIC #177600,AC BR I.BGO .IFF V.SNG=V.DFLT V.DBL=V.DFLT V.XTND=V.DFLT V.INT=V.DFLT V.BYTE=V.DFLT V.TEXT=V.DFLT .ENDC .ENDC ; .END