File TECO.P1

Directory of image this file is from
This file as a plain text file

;TECO11 FOR THE PDP11-05 STAND ALONE SYSTEM
;
;WRITTEN BY DEVON B. WORRELL
;SYSTEM DEVLOPMENT
;NEWPORT-MESA UNIFIED SCHOOL DISTRICT
;JANUARY 25, 1975

;REGISTER DEFINITIONS OCP=%5 INBUF=%4 CKLST=%2 SP=%6 PC=%7 PS=177776 SR=%3 R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 R6=%6 R7=%7 ;SYSTEM DEFINTIONS TPS=177564 TKS=177560 TKB=177562 TPB=177566 PPB=177566 PPS=177554 PRB=177552 PRS=177550 $PRINT=IOT ;INTERUPT VECTORS .=4 .+2 ;TIMOUT ERRORS HALT ;HALT ON A TIMOUT(MODIFIED IN INIT) .=20 XIOT ;PRINT INTERUPT VECTOR 240 ;SYSTEM INTERUPT LEVEL=5 .=60 KBDX ;KEYBOARD INTERUPT VECTOR 240 ;SYSTEM INERUPT LEVEL=5 XTTY ;TTY INTERUPT VECTPOR 240 ;SYSTEM INTERUPT LEVEL=5
;TECO FOR THE PDP11-05 STAND ALONE SYSTEM ; ;WRITTEN BY DEVON B. WORRELL ;SYSTEM DEVLOPMENT ;NEWPORT MESA UNIFIED SCHOOL DISTRICT ;JANUARY 25, 1975 ;MAIN PROGRAM SECTION ;TECO INIT, ENTERED AT THE BEGGING OF THE EDITING PASS ;ALL REGISTERS, SYMBOL TABLES, CORE SIZE.. ARE ;INITILIZED AT THIS POINT .=400 ;BYPASS ALL SYSTEM INTERUPT VECTORS ENTRY: RESET ;RESET ALL THE DEVICES ON THE UNIBUS MOV #SA,SP ;SET UP THE SYSTEM STACK POINTER MOV #FND,@#4 ;SET TIMOUT ERRORS TO TRAP TO CORMAX ROUTINE CLR R0 ;SET REGISTER 0 TO THE BEGINING OF CORE CORMAX: TST (R0)+ ;TEST THE NEXT WORD IN CORE BR CORMAX ;CONTINUE UNTIL TIMOUT OCCURS FND: MOV R0,INBUF ;SET INPUT BUFFER POINTER TO ;THE LAST WORD OF CORE SUB #1002,INBUF ;DONT WIPE OUT THE SYSTEM LOADERS ADD #4,SP ;BUMP PS PAST INTERUPT VECTOR MOV INBUF,BUFBG ;SAVE BEGGING ADDRESS OF THE BUFFER MOV #RINGB,OCP ;SET UP RING BUFFER FOR PRINTING MOV #154,R0 ;SET UP COUNT FOR Q-REG SYMBOL TABLE ZERO MOV #QSYM,R1 ;SET UP POINTER TO THE Q-REQ SYMBOL TABLE ZLP: CLR (R1)+ ;ZERO A WORD IN THE TABLE DEC R0 ;DECREMENT COUNTER BNE ZLP ;IF NOT=0 CONTINUE ZEROING MOV #TEXTB,CP ;SET . MOV #TEXTB,EOT ;& END OF TEXT BUFFER POINTER BIOC: CLR SR ;RESET STATUES TO NORMAL $PRINT ;PRINT <CRLF>*, AND WAIT FOR A RESPONCE .BYTE 15 .BYTE 12 .BYTE 52 .BYTE 0 .EVEN MOV #100,@#TPS ;SET TELEPRINTER TO INTERUPT ON READY MOV #100,@#TKS ;SET KEYBOARD TO INERUPT ON DONE MOV #PNTH,TYP30 ;INITIAL SETTING TO TYPE NOT PUNCH CLR @#PS ;LET INTERUPTS HAPPEN CIRCL: WAIT ;WAIT FOR AN INTERUPT BR CIRCL ;INTERUPTS GOT ME GOING IN CIRCLES
;HERE LIE THE SPECIAL CHARECTER HANDELING ROUTINES ;THERE HERE BECAUSE BR CAN ONLY ACCOMIDATE DISTANCES OF 128 WORDS ;AND THE MAIN INTERUPT HANDLER IS BELOW BUFBG: .WORD 0 ;BEGINING OF INPUT BUFFER CP: .WORD 0 ;CURRENT POINTER "." EOT: .WORD 0 ;END OF THE TEXT BUFFER ENDCS: .WORD 0 ;WHILE EXECUTING = END 2ND INPUT BUFFER XG: BIT #CNTLG,SR ;LAST CHR A CONTROL G? BNE CRNCH ;YES KILL BUFFER BIS #CNTLG,SR ;NO, SO SET BIT IN SR MOVB (INBUF)+,R2 ;MOV CONTROL G IN TO R2 FOR ECHO BR PMS1 ;ECHO THE CHAR IN REGISTER 2 CRNCH: MOV BUFBG,INBUF ;RESET BUFFER POINTER MOV #SA,SP ;RESTORE SP TO THE BEGGINING MOV #BASE,OCP ;CLEAR OUT THE FIFO BR BIOC ;GO PRINT A CRLF*, AND WAIT XALT: BIT #ALT,SR ;LAST CHAR AN ALTMODE? BNE CEXEC ;YES, GO AND EXECUTE THE COMMAND STRING BIS #ALT,SR ;NO, SO SET THE BIT IN THE SR BR PMS ;AND BACK TO MAIN STREEM CEXEC: JMP EXECUT ;START ER UP XO: CMP #EXEC,SR ;ARE WE CURRENTLY RUNNING? BNE PMS ;NO, DONT TURN OFF PRINTING INC SR ;COMPLEMENT BIT 0 BIC #2,SR ;CLEAR THE OVERFLOW BIT #CNTLO,SR ;COMMING OUT OF A CONTROL O OUTPUT HOLD? BEQ KRES ;YES RESTART THE TTY MOV #BASE,OCP ;NO, CLEAR THE FIFO BR PMS ;EXIT BACK TO THE MAIN STREAM XS: BIS #CNTLS,SR ;SET CONTROL S FLAG IN THE SR INC INBUF ;DROP CONTROL S FROM THE BUFFER BR CHRR ;RETURN WITH NO ECHO
XQ: BIC #CNTLS,SR ;CLEAR OUT THE CONTROL S FLAG KRES: MOV (SP)+,R2 ;RESTOR REGISTER 2 INC INBUF ;DROP CONTROL Q FROM THE BUFFER BR XTTY ;AND START THE TTY MOVING AGAIN XU: JSR R0,BGL ;SCAN BACKWARDS TO THE BEGGING CMP BUFBG,INBUF ;IS THIS THE BEGINING BEQ CRNCH ;YES, GO PRINT THE <CRLF>* $PRINT ;PRINT ^U<CRLF> .BYTE 25,15,12,0 BR CHRR ;RETURN WITHOUT AN ECHO XRET: MOVB @INBUF,R2 ;STORE BOTH <CR> & <LF> MOVB #12,-(INBUF) BR PMS1 ;RETURN AND ECHO THE <CR>
ALT=100000 ;ALTMODE ENCOUNTERED BIT EXEC=40000 ;EXECUTION IN PROGRESS CNTLS=400 ;CONTROL S ENCOUNTERED CNTLG=200 ;CONTROL G FLAG CNTLO=1 ;CONTROL O IN EFFICT RUBM=4 ;RUBOUT BIT IN SR SLASH=134 ;SLASH CHAR XRUB: INC INBUF ;BYPASS STORED RUBOUT CMP BUFBG,INBUF ;NOW AT THE BEGGINNG OF THE BUFFER? BEQ XRUBEX ;YES, DONT RUBOUT ANYTHING BIT #RUBM,SR ;LAST CHAR A RUBOUT? BNE RUBNS ;YES DONT PRINT A SLASH MOV #SLASH,R2 ;SET UPRINT, MOVE CHAR TO R2 JSR R0,PNT ;PRINT OPENING \ BIS #RUBM,SR ;AND SET RUBOUT BIT IN SR RUBNS: MOVB (INBUF)+,R2 ;ECHO CHAR TO BE RUBBED OUT BR PMS ;RETURN XRUBEX: BIT #RUBM,SR ;WAS THE LAST CHAR A RUBOUT? BEQ BDRB ;NO, JUST PRINT A <CRLF> MOV #SLASH,R2 ;MOVE CHAR TO PRINT INTO R2 JSR R0,PNT ;PRINT THE CLOSING SLASH BDRB: $PRINT ;PRINT A <CRLF> .BYTE 15,12,0 ;CR,LF .EVEN BR CHRR ;RETURN WITH NO ECHO
;THE FOLLOWING ROUTINES ARE THE MAINLINE OF THE ;INTERUPT HANDELING. ALL KEYBOARD, AND TTY INTERUPTS ;WILL COME TO EITHER XTTY, XKBD, AND DEPART FROM THERE XTTY: CMP OCP,#BASE ;ARE THE POINTERS THE SAME? BEQ XTTYEX ;YES, THERE IS NOTHING LEFT TO PRINT JSR R0,XCHRO ;ECHO CHAR XTTYEX: RTI ;RETURN FROM THE INTERUPT KBDX: BIT #EXEC,SR ;ARE WE CURRENTLY EXECUTING? BNE KBDEX ;YES, ONLY SPECIAL CONTROL CHARS ARE CHECKED MOV #TLIS,CKLST ;SET UP THE TABLE SEARCH K2: MOVB @#TKB,-(INBUF) ;MOVE THE CHAR INTO THE INPUT BUFFER MOV R2,-(SP) ;SAVE REGISTER 2 CMP #177,@INBUF ;THIS CHAR A RUBOUT? BEQ XRUB ;IF SO, CALL RUBOUT HANDLER BIT #RUBM,SR ;WAS THE LAST CHAR A RUBOUT? BEQ KXL MOV #SLASH,R2 ;YES, PRINT CLOSING \ JSR R0,PNT BIC #RUBM,SR ;AND CLEAR RUBOUT FLAG KXL: CMPB (INBUF),(CKLST)+ ;ARE THE CHARS THE SAME? BEQ KXGT ;YES, GO AND EXECUTE THE ROUTINE TSTB (CKLST) ;IS THIS THE END OF THE TABLE? BNE KXL ;NO, CONTINUE LOOKING PMS0: BIC #ALT+CNTLG+RUBM,SR ;CLEAR ALTMODE & CONTROL G FLAGS PMS: MOVB @INBUF,R2 ;PUT THE CHAR INTO REGISTER 2 PMS1: JSR R0,PNT ;CALL THE ECHO ROUTINE WITH CHAR IN R2 CHRR: BIT #EXEC,SR ;ARE WE CURRENTLY EXECUTING? BEQ KBX ;NO, BYPASS RESTORE MOV INBUF,ENDCS ;RESTORE END OF INPUT BUFFER MOV (SP)+,INBUF ;RETURN INBUF TO VALUE AT INTERUPT KBX: MOV (SP)+,R2 ;RESTORE R2 RTI ;RETURN FROM THE INTERUPT KBDEX: MOV #T2,CKLST ;SETUP PARTIAL SEARCH WHILE EXECUTING MOV INBUF,-(SP) ;SAVE CURRENT INPUF POINTER MOV ENDCS,INBUF ;SET END OF INPUT BUFFER AS BUFFER POINTER BR K2 ;EXECUTE AS NORMAL PNT: BIT #CNTLO,SR ;CONTROL O FLAG SET? BNE NPCN ;YES, DONT PRINT THE CHAR CMP #RINGB+144,OCP ;HAS THE FIFO OVERFLOWED?? BEQ NPCN ;YES, DONT DO ANY THING WITH THIS CHAR MOV OCP,-(SP) ;PUSH OCP INTO THE STACK XBMP: MOV OCP,-(SP) ;SAVE CURRENT POSITON MOVB -(OCP),@(SP)+ ;SLIDE CHAR UP ONE CMP OCP,#BASE ;AT THE BOTTEM OF THE STACK? BHI XBMP ;NO, CONTINUE SLIDING MOVB R2,@#BASE ;ADD NEW CHAR ONTO THE STACK(FIFO) MOV (SP)+,OCP ;RESTORE OCP TO ITS ORIGINAL STATE INC OCP ;INCREMENT TO INCLUDE THE NEW CHAR TSTB @#TPS ;WAS THE PRINTER IN USE? BPL NPCN ;YES, IT'ILL HANDLE IT SELF JSR R0,XCHRO ;GO AND START THE ECHOING NPCN: RTS R0 ;RETURN FROM THE ECHO ROUTINE KXGT: SUB #TLIS+1,CKLST ;CREATE BYTE OFFSET INTO THE TABLE ;POINTER AT ENTRY WILL BE 1 PAST MATCH ROL CKLST ;MAKE IT A WORD OFFSET ADD #TDIS,CKLST ;ADD IN THE BASE OF THE DISPATCH TABLE JMP @(CKLST)+ ;CALL THE SOBORDINATE ROUTINE
;THIS ROUTINE ECHOS THE CHAR IN THE FIFO ;IF ^S MODE NO ECHO IS PERFORMED ;ALL CONTROL CHARS ARE CONVERTED TO ^CHAR UPARO=136 XCHRO: MOV R1,-(SP) ;SAVE REGISTER 1 BIT #CNTLS,SR ;ARE WE CURRENTLY IN CONTROL S MODE? BNE CEX ;YES, DON'T ECHO THE CHAR CMPB #37,-(OCP) ;IS THIS CHAR A CONTROL CHAR? BLO ECHOC ;NO, JUST PLAIN PRINT THE CHAR MOV #TSC,R1 ;SET UP TABLE SEARCH SCCL: CMPB @OCP,(R1)+ ;FOUND A MATCH? BEQ SCCSR ;YES, EXECUTE THE PROPER ROUTINE TSTB @R1 ;NO, IS THIS THE END OF THE TABLE? BNE SCCL ;NO, CHECK THE NEXT CHAR MOVB #UPARO,@#TPB ;ECHO THE ^ BISB #100,(OCP)+ ;MAKE THE CHAR A NORMAL CHAR, AND ;RENSTATE IT TO THE FIFO TO BE ECHOED LATER CEX: MOV (SP)+,R1 ;RESTORE R1 RTS R0 ;RETURN FROM ECHO CALL SCCSR: SUB #TSC+1,R1 ;CREATE BYTE OFFSET INTO TABLE ROL R1 ;MAKE IT A WORD OFFSET ADD #TSCD,R1 ;ADD BASE OF DISPATCH TABLE JMP @(R1)+ ;CALL THE SPECIFIED ROUTINE ECHOC: MOVB @OCP,@#TPB ;NORMAL ECHO, PRINT THE NEXT CHAR INC LPOS ;ACCOUNT FOR THE PRINTED CHAR BR CEX ;RESTORE R1, AND RETURN TSC: .BYTE 11 ;TAB .BYTE 12 ;LF .BYTE 13 ;VT .BYTE 14 ;FORM .BYTE 15 ;CR .BYTE 33 ;ALT .BYTE 0 ;TABLE TERMINATER .EVEN TSCD: CTAB CLF CVT CFF CCR CALT
;OUTPUT SPECIAL CHAR PROCCESSING ROUTINES ;CTAB MANAGE SOFTWARE TAB STOPS CTAB: MOV R0,-(SP) ;SAVE REGISTER 0 MOV (PC)+,R0 ;SET UP LINE POS FOR TAB CALC LPOS: .WORD 0 BIS #177770,R0 ;R0&7-10 MOV R2,-(SP) ;SAVE REGISTER 2 MOV #40,R2 ;CHAR FOR PNT TO PRINT PTAB: JSR R0,PNT ;PRINT THE SPACE INC R0 ;DONE WITH BLOCK? BNE PTAB ;NO, CONTINUE PRINTING MOV (SP)+,R2 ;RESTORE REGISTER 2 MOV (SP)+,R0 ;RESTORE REGISTER 0 BR CEX ;RESTORE REGISTER 3, AND RETURN ;LINE FEED CLF: MOVB @OCP,@#TPB ;PRINT THE LF BR CEX ;EXIT ;VERTICAL TAB, AND CARRAGE RETURN CCR: CVT: JSR R0,CRLF ;PRINT A <CRLF> BR CEX ;EXIT ;FORM FEED CFF: MOV #10,-(SP) ;SET UP A COUNTER ON THE STACK JSR R0,CRLF ;PRINT A <CRLF> CFFL: JSR R0,AELF ;PRINT ONLY THE <LF> DEC @SP ;PRINTED 10 LINES YET? BNE CFFL ;NO, CONTINUE PRINTING LF'S TST (SP)+ ;YES, RID STACK OF TEMP COUNTER BR CEX ;EXIT ;ALTMODE CALT: MOVB #44,@OCP ;CONVERT ALTMODE TO A $ BR ECHOC ;ECHO THE $ UNSTEAD OF THE <ALT> ;PRINT CARRAGE RETURN LINE FEED CRLF: MOVB @OCP,@#TPB ;PRINT THE CR AELF: MOVB #12,(OCP)+ ;PRINT ONLY THE <LF> CLR LPOS ;RESTORE LINE POS TO 0 RTS R0 ;EXIT
;SIMULATE JSR R0,XPNT FROM THE $PRINT CALL XIOT: TST (SP)+ ;BUMP PS TP POINT TO INTERUPT PS MOV @SP,@#PS ;RESTORE PS TO BEFORE CALL MOV R0,@SP ;PUSH R0 INTO THE STACK MOV -(SP),R0 ;SET UP RETURN ADDRESS IN R0 ;FALL THRU TO PRINT ROUTINE MOV SR,@SP ;PUSH SR INTO THE STACK, TO BE CHECKED LATER XPNT: TSTB @R0 ;IS THIS THE END OF THE STRING? BEQ XPEX ;YES, GOBACK FROM WHERE WE CAME FROM MOVB (R0)+,R2 ;MOV THE CHAR TO PRINT INTO REGISTER 2 JSR R0,PNT ;CALL THE ECHO ROUTINE&PRINT CHAR IN R2 BR XPNT ;GO AND PRINT ANOTHER CHAR XPEX: ROR R0 ;CREATE WORD ADDRESS TO RETURN TO INC R0 ;ADD 2 TO THE REGISTER CLC ;CLEAR THE CARRY BIT ROL R0 ;RESTORE THE REGISTER RTS R0 ;RETURN FROM CALL TLIS: .BYTE 177 ;RUBOUT .BYTE 7 ;CONTROL G .BYTE 33 ;ALT T2: .BYTE 17 ;CONTROL O .BYTE 23 ;CONTROL S .BYTE 21 ;CONTROL Q .BYTE 25 ;CONTROL U .BYTE 15 ;<CR> .BYTE 0 ;TABLE TERMINATOR .EVEN TDIS: XRUB XG XALT XO XS XQ XU XRET
;HERE IS THE MEAT OF TECO ;THE COMMAND HANDLER. THIS ROUTINE DETURMINES ;THE PROPER ROTINE TO CALL IN THE PROPER ;ORDER EXECUT: BIS #EXEC,SR ;SET STATUS (EXECUTE) BIT CLR @#PS ;ALLOW KBD, TTY, ... TO INTERUPT CLRB @INBUF ;MAKE LAST ALT A 0 MOV INBUF,@SP ;SAVE THE END OF INPUT BUFFER MOV INBUF,ENDCS ;& IN A SECOND AREA FOR INTERUPTS MOV BUFBG,INBUF ;MOV BUFFER POINTER TO THE BEGGING $PRINT ;PRINT $<CRLF> TO SHOW WE DOING SOMTHING .BYTE 33,15,12,0 COM: MOV #ARG,R1 ;SET UP ARG STACK ADDRESS CLR (R1)+ ;RESET ARGUMENT STACK CLR (R1)+ ARGCOM: MOV #CTA,R0 ;SET UP COMMAND TABLE SEARCH CMPB #57,-(INBUF) ;CHECK FOR A NUMERIC OPPERAND BHI COM0A ;ITS NOT ONE CMPB #72,@INBUF ;CHECK FOR OVER NOW BHI COMCAL ;GOT ONE, INPUT THE NUMBER COM0A: CMPB (R0)+,@INBUF ;COMPARE COMMAND WITH ENTRY BEQ COMCAL ;FOUND A MATCH BLO COM0A ;ALLREADY BYPASSED COMMAND? $PRINT ;YES, GIVE HIM AN ERROR .ASCII \?CMDERR\ .BYTE 0 .EVEN JMP CRNCH ;RESET EVERYTHING AND PRINT <CRLF>* COMCAL: SUB #CTA,R0 ;CREATE OFFSET ASL R0 ;MAKE IT A WORD OFFSET ADD #COMDIS,R0 ;ADD BASE OF DISPATCH TABLE JSR R0,@(R0)+ ;CALL THE COMMAND HANDLER BR COM ;PROCESS NEXT COMMAND
ARG: .WORD 0,0 ;ARGUMENT STACK, MAX=2 ;NOW FOR SOME GARBAGE; THE COMMAND TABLES ;COMMAD TABLE CTA: .BYTE 0,11,12,15,33,43,46,52,53,54 .BYTE 55,56,75,101,102,103,104,105,106,110 .BYTE 111,112,113,114,116,120,122,123,124 .BYTE 126,131,132 ;AND THE DISPATCH TABLE COMDIS: .WORD C.NUM,C.COMP,C.TAB,C.LF,C.CR,C.ALT .WORD C.OR,C.AND,C.MULT,C.ADD,C.COMMA .WORD C.SUB,C.CURNT,C.EQU,C.APEND,C.BEGIN .WORD C.CHAR,C.DEL,C.EXTEND,C.FUNCT,C.HOLE,C.INSERT .WORD C.JMP,C.KILL,C.LINE,C.NSRCH,C.PAGE,C.REVRS .WORD C.SEARCH,C.TYPE,C.VERFY,C.YANK,C.ZEND
C.DEL: HALT C.EXTEND: HALT C.FUNCT: HALT C.KILL: HALT C.LINE: HALT C.NSRCH: HALT C.SEARCH: HALT C.VERFY: HALT
;MAIN-LINE SUBROUTINES USED THROUGH OUT TECO ;OCTAL TO DECIMAL CONVERSION & ZERO SUPPRESS PRINT
PRTNUM: MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;SAVE NUMBER TO PRINT MOV #DECT,R1 ;ADDRESS OF OUTPUT BUFFER CLR DECNEG ;CLEAR THE NEGITIVE FLAG TST R2 ;IS THE NUMBER - BPL DEC01 NEG R2 ;YES, SO MAKE IT POSITIVE INC DECNEG ;SET THE NEGITIVE FLAG DEC01: CLR R0 ;RESET DIVISION COUNTER BR DEC00A ;BYPASS INITIAL INC DEC00: INC R0 ;BUMP DIVIDEND DEC00A: SUB #12,R2 ;DIVISION BY REPITIVE SUBTRACTION BPL DEC00 ;DONE? ADD #60+12,R2 ;YES, RESTORE NUMBER AND CHANGE TO ASCII MOVB R2,-(R1) ;STORE IT IN THE BUFFER MOV R0,R2 ;USE REMINDER AS NEW NUMBER BNE DEC01 ;IF ITS NON ZERO CONTINUE TST DECNEG ;WAS THIS NUMBER NEGITIVE BEQ DEC02 MOVB #55,-(R1) ;YES, PRINT A - ALSO DEC02: MOVB @R1,R2 ;SUBROUTINE PRINTS CHAR IN R2 JSR R0,PNTH ;PRINT IT TSTB (R1)+ ;DONE? BPL DEC02 MOV (SP)+,R1 ;RESTORE R1 MOV (SP)+,R0 ;SAME FOR R0 RTS R0 ;RETURN .BYTE 0,0,0,0,0 DECT: .BYTE 240 .EVEN DECNEG: .WORD 0
;INPUT BUFFER SCAN ROUTINES BGL: CMP BUFBG,INBUF ;ARE WE AT THE BEGGING? BEQ BGLX ;IF SO EXIT CMPB #12,(INBUF)+ ;BEGGING OF A LINE? BNE BGL CMCX: DEC INBUF ;YES, MOVE POINTER TO FIRST CHAR BGLX: RTS 0 ;RETURN PNTH: CMP #BASE+62,OCP ;FIFO HALF FULL? BLO PNTH ;IF SO WAIT FOR IT TO EMPTY JSR R0,PNT ;NO, PRINT THE CHAR IN R2 RTS R0 ;RETURN
;INSERT COMMAND C.TAB: INC INBUF ;INCLUDE <TAB> IN INSERT C.INSERT: MOV INBUF,-(SP) ;SAVE CURRENT INPUT BUFFER POINTER CIN0A: CMPB #33,-(INBUF) ;SCAN FOR THE CLOSING <ALT> BNE CIN0A CIN0: SUB @SP,INBUF ;CREATE LENGHT OF INSERT STRING COM INBUF ;MAKE LENGTH POSITIVE & DONT INCLUDE <ALT> MOV EOT,R1 ;SET UP SLIDE MOV R1,R2 ADD INBUF,R2 ;ADD INSERT LENGTH TO EOT CMP R2,ENDCS ;IS THE NEW EOT OVERLAPING INPUT BUFFER? BLO CIN0B $PRINT ;YES, BUFFER FULL ERROR .ASCII \?BFRFUL\ .BYTE 0 .EVEN JMP CRNCH CIN0B: MOV R2,EOT ;STORE NEW EOT CIN1: CMP CP,R1 ;DONE WITH SLIDE? BEQ CIN1A MOVB -(R1),-(R2) ;NO, SLIDE CHAR UP BR CIN1 CIN1A: ADD INBUF,CP ;RESTORE . TO PROPER POSITION MOV (SP)+,INBUF ;& INBUF CIN2: MOVB -(INBUF),(R1)+ ;MOVE FROM INPUT BUF TO TEXT BUF CMP R1,R2 ;DONE WITH INSERT? BNE CIN2 C.LF: C.CR: C.ALT: RTS R0 ;---- EXIT ----
;ARGUMENT SUBROUTINES C.NUM: INC INBUF ;BACK UP POINTER C.ZEND: C.BEGIN: C.CURNT: C.ADD: JSR R0,ARGTGN ;INPUT A NUMBER C.NUM0: ADD R2,@R1 ;ADD THE NUMBER ONTO THE STACK ARGRET: TST (SP)+ ;BUMP R0 OFF THE STACK JMP ARGCOM ;RETURN WITHOUT DISTROYING THE STACK C.SUB: JSR R0,ARGTGN ;INPUT A NUMBER SUB R2,@R1 ;SUBTRACK THE NUMBER FROM THE STACK BR ARGRET ;RETURN C.COMP: TST (SP)+ ;BUMP RO OFF THE STACK JMP CRNCH ;ALL DONE WITH COMMAND EXECUTION ARGTGN: JSR R0,NUM ;INPUT A NUMBER FROM THE BUFFER ARGTST: CMP #ARG+4,R1 ;FIRST TIME? BNE ARGT0 ARGT1: TST -(R1) ;YES, BUMP PTR TO FIRST ENTRY ARGT0: RTS R0 ;RETURN C.AND: C.OR: JSR R0,ARGTGN ;INPUT A NUMBER BIS R2,@R1 ;DO THE OR BR ARGRET ;RETURN C.EQU: JSR R0,ARGTST ;MAKE SURE WE HAVE AN ENTRY MOV @R1,R2 ;SET UP FOR THE NUMOUT JMP PRTNUM ;PRINT THE NUMBER, AND RETURN TO COM C.HOLE: MOV #ARG+2,R1 ;SET UP FOR A DUBBLE ENTRY CLR @R1 ;B MOV EOT,R2 ;SET UP FOR TRUE Z CALC SUB #TEXTB,R2 ;TRUE Z MOV R2,-(R1) ;ADD IT TO THE STACK BR ARGRET
C.COMMA: CMP #ARG+2,R1 ;CAN WE PUT ANOTHRE ENTRY ON THE STACK? BNE CMA0 $PRINT ;STACK OVERFLOW ERROR .ASCII \?STKERR\ .BYTE 0 .EVEN JMP CRNCH CMA0: TST -(R1) ;BUMP POINTER TO NEXT ENTRY BR ARGRET ;RETURN C.MULT: JSR R0,ARGTGN ;GET A NUMBER MOV @R1,R0 ;SAVE NUMBER TO BE * CLR @R1 ;RESET ANSWER MLT0: TST R2 ;ALL DONE? BEQ ARGRET ADD R0,@R1 ;MULT BY REPITIVE ADDITION DEC R2 ;DECREMENT COUNTER BR MLT0 NUM: CMPB #56,-(INBUF) ;"." COMMAND? BEQ NUM01 CMPB #102,@INBUF ;"B" COMMAND BEQ NUM02 CMPB #132,@INBUF ;"Z" COMMAND? INC INBUF ;INITIAL STARTING POINT CLR R2 ;NUMBER TO BUILT IN R2 NUM1: CMPB #57,-(INBUF) ;IS THIS CHARA DIGIT? BHI NUM2A CMPB #72,@INBUF BHI NUM3 NUM2A: INC INBUF ;BUMP POINTER TO PREIVOUS CHAR CMPB #55,@INBUF ;WAS IT A - ? BNE NUM2B INC R2 ;YES, ASUME A -1 NUM2B: RTS R0 NUM3: ASL R2 ;MULTIPLY NUMBER BY 12 ASL R2 ADD R2,R2 ADD R2,R2 ADD @INBUF,R2 ;AND ADD IN NEW DIGIT SUB #60,R2 ;TAKE INTO ACCOUNT ASCII DIGIT BR NUM1 ;GET ANOTHER DIGIT NUM01: MOV CP,R2 ;"." COMMAND MOVE CURRENT POINTER TO ARG R NUM01A: SUB #TEXTB,R2 ;MAKE IT RELITIVE RTS R0 NUM02: CLR R2 ;"B" COMMAND, SET ARG R TO 0 RTS R0 NUM03: MOV EOT,R2 ;"Z" COMMAND MOVE END OF TEXT TO ARG R BR NUM01A ;MAKE IT RELITIVE & EXIT
;TYPE - PUNCH COMBINATION C.TYPE: MOV #TEXTB,R2 ;GLOBAL OF BEGINING OF BUFFER CMP #ARG+2,R1 ;HOW MANY ARGUMENTS ARE THERE? BEQ TYP001 ;IF EQUAL 1 ARG BHI TYP002 ;IF HIGH 2 ARGUMENT INC -(R1) ;NO ARGUMENT, DEFALT =1 ARG VALUE 1 TYP001: TST @R1 ;IS IT A 0T? BEQ TYP01B ;IF 0, YES BMI TYP01A ;IF - USE REVERS SCAN TYP01C: TYP010: JSR R0,TSKPL ;SKIP A LINE DEC @R1 ;SKIPED ENOUGH LINES? BNE TYP010 MOV (SP),@R1 ;STORE CP INTO ARG STACK MOV CP,-(SP) ;STORE TO POINTER BR TYP100 ;PRINT FROM ABS RANGE TYP01B: INC CP ;0T DONT SKIP PAST THIS LINE IF AT THE BEGINNING TYP01A: DEC @R1 ;SET COUNT TO ONE MORE THAN NEEDED TYP0B0: JSR R0,TSKPLR ;SKIP BACKWARDS 1 LINE INC @R1 ;BUMP COUNT BNE TYP0B0 MOV CP,@R1 ;PUT CP ONTO THE ARG STACK MOV (SP),-(R1) ;AND THE TO POINTER BR TYP100 ;PRINT FROM THE ABS ARG STACK TYP002: ADD R2,(R1) ;ADD ON THE BASE OF THE TEXT BUFFER ADD R2,2(R1) ;ADD ON THE BASE TO SECOND ARG CMP EOT,(R1) ;ARGUMENT OUT OF RANGE? BLO TYP20
TYP100: CMP (R1)+,(R1) ;FIRST ARG LARGER? BLO TYP20 ;IF SO ERROR MOV R0,-(SP) ;SAVE R0 MOV @R1,R0 ;POINTER TO START PRINTING FROM CMP R2,R0 ;SECOND ARG OUT OF RANGE? BHI TYP20 ;IF SO ERROR TYP10A: MOVB (R0)+,R2 ;MOVE NEXT CHAR TO PRINT TO R2 JSR R0,@(PC)+ ;CALL EITHER PRINT OR PUNCH ROUTINE TYP30: PNTH ;INITIALY SET TO PRINT CMP -2(R1),R0 ;ARE THE POINTER THE SAME BNE TYP10A ;IF NOT CONTINUE PRINTING, PUNCHING MOV (SP)+,R0 ;RESTORE R0 MOV (SP)+,CP ;AND CP RTS R0 ;EXIT TYP20: $PRINT ;----- ERROR ----- .ASCII \?ARGERR\ .BYTE 0 .EVEN JMP CRNCH ;RESTART
;PUNCH ROUTINE, MODIFIES TYPE SPCHR: .WORD 0 BFOR: .WORD 0 ;FORM NOT ENCOUNTERD ON READ C.PAGE: CLR SPCHR ;SET CHAR TO PRINT AT END OF PUNCH CMP #ARG+4,R1 ;NO ARGUMENTS? BNE PAGE0 MOV #14,SPCHR ;YES, SET TO PRINT A <FORM> PAGE0: MOV #PAGE1,TYP30 ;SET PRINT ROUTINE TO PUNCH JSR R0,C.TYPE ;GO DO IT MOV SPCHR,R2 ;PRINT THE EXTRA CHAR TST BFOR ;WAS A <FORM> ENCOUNTERD ON READ IN? BEQ PAGE3 CLR R2 ;NO, SO DONT PUNCH A <FORM> PAGE3: JSR R0,PAGE1 ;PUNCH THE CHAR MOV #PNTH,TYP30 ;RESET THE CALL BACK TO PRINT RTS R0 PAGE1: BIT #100200,@#PPS ;PUNCH BUSY BEQ PAGE1 BMI PAGE01 ;DONE, WAS THERE AN ERROR MOV R2,@#PPB ;NO ERROR, PUNCH CHAR RTS R0 ;AND EXIT PAGE01: $PRINT ;PUNCH ERROR .ASCII \?PCHERR\ .BYTE 0 .EVEN JMP CRNCH ;RESTART ;LINE SKIP ROUTINES TSKPL: MOV R0,-(SP) ;SAVE R0 MOV CP,R0 ;SET UP SCAN SKP0: CMP EOT,R0 ;AT THE END OF THE TEXT BUFFER? BEQ SKP01 CMPB (R0)+,#12 ;FOUND THE <LF>? BNE SKP0 MOV R0,CP ;YES, SAVE NEW CP SKP01: MOV (SP)+,R0 ;RESTORE RO RTS R0 ;AND EXIT TSKPLR: MOV R0,-(SP) ;SAVE R0 MOV CP,R0 ;SET UP SCAN DEC R0 ;IF AT THE BEGGING OF A LINE BYPASS IT SKPR0: CMP #TEXTB,R0 ;AT THE BEGGING OF THE BUFFER? BEQ SKP01 ;IF SO RESTORE R0, EXIT CMPB -(R0),#12 ;AT THE BEGGING OF THE LINE? BNE SKPR0 ;IF NOT CONTING SCANNING BR SKP01 ;YEP, RESTORE R0, EXIT
;READER COMMANDS: YANK, AND APPEND C.YANK: MOV #TEXTB,EOT ;RESET BUFFER POINTERS MOV #TEXTB,CP C.APEND: CLR BFOR ;RESET <FORM> FOUND FLAG MOV R0,-(SP) ;SAVE R0 MOV EOT,R0 ;GLOBAL TO THE TEXT POINTER APND10: JSR R0,RDR ;READ A CHAR OFF THE READER MOV R0,R1 ;CHECK FOR BUFFER NEAR FULL CMP R2,#12 ;FOUND THE END OF A LINE? BNE APND0 ADD #144,R1 ;YES, STILL MORE THAN 100 CHARS LEFT? APND20: SUB ENDCS,R1 ;HOW FAR FROM THE END BPL APND55 CMP #14,R2 ;THIS CHAR A <FORM>? BEQ APND50 MOV R2,(R0)+ ;ADD THE CHAR TO THE BUFFER BR APND10 ;KEEP TRUCKING APND0: ADD #24,R1 ;STOP WHEN WITHIN 20 OF THE END BR APND20 APND55: INC BFOR ;NO <FORM> FOUND, SET FLAG APND50: DEC ARG+2 ;COUNTER SATISIFIED? BPL APND10 MOV R0,EOT ;SET UP NEW END OF TEXT POINTER MOV (SP)+,R0 ;RESTORE R0 RTS R0 ;READER ROUTINE RDR: INC @#PRS ;SET READER ENABLE RDR0: TST @#PRS ;TEST FOR ERROR BMI RDR30 TSTB @#PRS ;TEST FOR COMPLEATION BPL RDR0 MOV @#PRB,R2 ;DONE, READ THE CHAR RTS R0 RDR30: $PRINT ;READER ERROR .ASCII \?RDRERR\ .BYTE 0 .EVEN JMP CRNCH ;EXIT
;CHARECTER MANIPULATION ROUTINES C.JMP: CMP #ARG+4,R1 ;ANY ARG SPECIFIED? BNE JMP00 CLR -(R1) ;NO, SO DEFAULT IS 0J JMP00: ADD #TEXTB,(R1) ;MAKE IT ABSOLUTE JMP33: CMP #TEXTB,(R1) ;IS IT BELOW THE BEGGING OF THE BUFFER? BLOS JMP01 JMP02: $PRINT ;ATTEMPTED TO MOVE POINTER OFF PAGE .ASCII \?POP\ .BYTE 0 .EVEN JMP CRNCH ;EXIT JMP01: CMP (R1),ENDCS ;PAST THE END OF THE BUFFER BHIS JMP02 MOV (R1),CP ;SAVE THE NEW CURRENT POINTER RTS R0 ;RETURN C.REVRS: JSR R0,CKARG ;SET DEFUALT ARG IF NEED BE SUB CP,(R1) ;SET ABS POSITION TO JMP TO BR JMP33 ;AND DO IT C.CHAR: JSR R0,CKARG ;SET DEFUALT ARG IF NEED BE CHAR0: ADD CP,(R1) ;SET ABS POSITION TO JMP TO BR JMP33 ;AND DO A JMP CKARG: CMP #ARG+4,R1 ;IS THERE AN ARGUMENT? BNE CHAR0 INC -(R1) ;NO, DEFUALT IS 1 RTS R0
;FREE AREA FROM HERE DOWN ;USED TO CONTAIN THE SYSTEM STACK, RING BUFFER, INPUT BUFFER ;Q-REGISTER SYMBOL TABLE, AND STORAGE AREA, AND ;THE TEXT BUFFER RINGB: BASE: .WORD 0 ;FIFO BUFFER 100 BYTES .=.+144 ;SYSTEM STACK AREA 50 WORDS .=.+144 SA: .WORD 0 QSYM: ;Q-REGISTER SYMBOL TABLE 108 WORDS .=154+154+. TEXTB: .WORD 0 ;TEXT BUFFER EXTINDING UPWARD .END ;THAT'S ALL FOLKS



Feel free to contact me, David Gesswein djg@pdp8online.com with any questions, comments on the web site, or if you have related equipment, documentation, software etc. you are willing to part with.  I am interested in anything PDP-8 related, computers, peripherals used with them, DEC or third party, or documentation. 

PDP-8 Home Page   PDP-8 Site Map   PDP-8 Site Search