diff --git a/src/sysen2/xgp.31 b/src/sysen2/xgp.31 new file mode 100644 index 00000000..f2ec9fa1 --- /dev/null +++ b/src/sysen2/xgp.31 @@ -0,0 +1,2128 @@ +.TITLE XGP SUPPORT PACKAGE + +%ABSADR==1 + +;XGP SUPPORT PACKAGE + +;PHYSICAL CHARACTERISTICS OF XGP +;EACH SCAN LINE IS: (ALL IN DECIMAL) +; 1700 BITS +; 108 PDP-11 WORDS +; 54 PDP-10 WORDS +;IN OCTAL THAT IS: +; 330 PDP-11 BYTES +;IT TAKES 7.75 MILLISECONDS TO PRINT ONE SCAN LINE + +IMWDSZ=108. ;NUMBER OF WORDS OF IMAGE LINE BITS +IMSLSZ==*2 ;IMAGE MODE SCAN LINE SIZE (BYTES) + ;INCLUDES BUFFER HEADERS AND INITIAL IMAGE MODE WORD +NBITS==IMWDSZ*20 ;NUMBER OF BITS IN A SCAN LINE + +; REGISTER DEFINITIONS + +R0=%0 ; R0 - R3 -- WORK REGS +R1=R0+1 +R2=R1+1 +R3=R2+1 +R4=R3+1 ;USUALLY CONTAINS FONT INDEX +R5=R4+1 ;USUALLY CONTAINS #MQ +SP=%6 ; STACK POINTER +PC=%7 ; PROGRAM COUNTER + +.XCREF R0,R1,R2,R3,R4,R5,SP,PC + +;CORE ALLOCATOR SPECS +CORSIZ==140000-200 ;ROOM FOR CARPET BPT ROUTINE +INUSE==1 ; MARKS CORE BLOCK IN USE +NEBISH==20 ; BYTES WE'RE WILLING TO WASTE IN BLOCK + +MAXFNT==20 ; MAXIMUM # ALLOWABLE FONTS +LAMBDA==-10.*60. ; PDP10 TIME OUT CONSTANT +CF==18. ;CONFETTI SIZE IN HALF SECONDS +NSLBFS==36. ;NUMBER OF SCAN LINE BUFFERS +NCLKQS==12. ;MAX NUMBER OF QUEUED CUT REQUESTS + +;INTERRUPT VECTORS + +BPTV==14 +IOTV==20 +POWRFV==24 + +ACCTCT==0 ;OFFSET OF COUNT ENTRY IN ACCT (USUALLY NOT SHOWN) +ACCTWD==2 ;OFFSET OF WORD OFFSET IN SCAN LINE +ACCTBT==4 ;OFFSET OF BIT OFFSET IN SCAN LINE +ACCTNW==5 ;OFFSET OF NUMBER OF WORDS IN THIS CHAR +ACCTPT==6 ;OFFSET OF POINTER TO FONT ENTRY + + ; I/O DEVICE ADDRESSES + +XCR=172100 ; XEROX CONTROL REGISTER +XSR=172104 ; XEROX STATUS REGISTER +MAR=172102 ; XGP MEMORY ADDRESS REGISTER +XCUT=172106 ;REGISTER TO HACK CUTS ONLY, FCUTI=4 + +DIV=177300 ; EAE MAGIC LOCATIONS +AC=177302 +MQ=177304 +MUL=177306 +SC=177310 +SR=177311 +NOR=177312 +LSH=177314 +ASH=177316 +LKS=177546 ; LINE CLOCK STATUS +PS=177776 ; PROCESSOR STATUS + +; XGP STATUS BITS + +FOS==100000 ; (15) OVERSCAN +FSYN==40000 ; (14) SYNC ERROR +FOR==20000 ; (13) DMA OVERRUN +FNXM==10000 ; (12) NXM +FRDYC==4000 ; (11) DEV RDY CHANGED +FBCB==2000 ; (10) BAD CONTROL BYTE IN CHAR MODE +RDMASK==274 ; MASK FOR PRINTER STATUS BITS (EXCLUDES PAPER SPEED) +FRDY==100 ; (6) DEVICE READY (INCLUDES "PAPER UP TO SPEED") +FACT==1 ; (0) ACTIVE + +; XGP CONTROL BITS + +FERR==100000 ; (15) ERROR +FMOT==2000 ; (10) MOTION +FDONE==200 ; (7) DONE +FDIE==100 ; (6) DONE INTERUPT ENABLE +FCUTI==4 ;(2) CUT PAPER NOW! +FCUT==2 ; (1) CUT PAPER +FGO==1 ; (0) GO + + LNKV=124 ; POINTS TO CHANNEL HEADER AREA + + +;MACRO TO ALIGN . ON R0 PDP-10 WORD + +.MACRO TENWRD +.XLIST +ZZZ==.&3 +.IF NE ZZZ +.=.+4-ZZZ +.ENDC +.LIST +.ENDM + +.MACRO PUSH R0 +.XLIST + MOV R0,-(SP) +.LIST +.ENDM + +.MACRO POP R0 +.XLIST + MOV (SP)+,R0 +.LIST +.ENDM + + +.MACRO REPT1 CT,ARG +.XLIST +.REPT CT + ARG +.ENDR +.LIST +.ENDM + +.MACRO REPT2 CT,ARG1,ARG2 +.XLIST +.REPT CT + ARG1 + ARG2 +.ENDR +.LIST +.ENDM + +.MACRO REPT3 CT,ARG1,ARG2,ARG3 +.XLIST +.REPT CT + ARG1 + ARG2 + ARG3 +.ENDR +.LIST +.ENDM + +.=4 +REPT2 77,.+2,IOT +.=BPTV + 0 + 0 +.=124 + 0 + 0 + ; MAIN LOOP FOR STARTUP + +.=400 ; START ADDRESS + BR START + + +;COMMUNICATION AREA WITH THE PDP10 + +ABORTF: 0 ;FLAG SET WHEN THE 11 IS ABORTING, RESET BY PDP10 WHEN IT NOTICES +XGPE: 0 ;ERROR FLAGS FROM THE XGP. POSSIBLE CAUSES OF ABORTS IF NOT READY +ERRADR: 0 ;ADDRESS OF CALLS TO ERROR, WHICH CAUSES AN ABORT +TENWRD +XGPIMP: .=.+20 ;RING BUFFER POINTERS FOR IMAGE OUTPUT FROM SYSTEM + ;POINTER TO NEXT BUFFER IN RING + ;USE FLAG 0 => EMPTY + ;POINTER TO 4000 BYTE BUFFER + ;UNUSED + +TENWRD +KSTLOD: .=.+4 ;-1 WHILE LOADING KST, 0=>KST LOADED, POSITIVE=># CHARACTERS NOT LOADED +FULFLG: .=.+ ;NUMBER OF CHARS IN EACH FONT NOT LOADED + +NORUG: HALT +START: RESET ; CLEAR THE UNIBUS + CLR PS ; SET PRIORITY LEVEL 0 + MOV #STK,SP ; SETUP THE STACK + CLR R0 + MOV #340,R1 ; SET LEVEL 7 + CLR (R0)+ ; END OF LIST PTR + CLR (R0)+ + MOV #ERR1,(R0)+ ; SETUP ERROR TRAP VECTOR + MOV R1,(R0)+ + MOV #ERR2,(R0)+ ; SETUP RESERVED INSTR. TRAP + MOV R1,(R0)+ + MOV #POWRF,POWRFV ; SETUP POWER FAILURE TRAP + MOV #IOTBRK,IOTV ;SET UP BAD TRAP CATCHER + MOV R1,22 + TST BPTV ;IS CARPET THERE + BNE START1 + MOV #NORUG,BPTV + MOV R1,BPTV+2 +START1: MOV R1,@#62 + MOV #XGPDON,@#370 ; SETUP XGP TRAP + MOV R1,@#372 + MOV #<6_5>,R1 ; SET REST ON LEVEL 6 + MOV #CLKBRK,@#100 ; LINE CLOCK + MOV R1,@#102 + CLR TICKS ; START CLOCK + MOV #100,LKS + MOV #1,TICKS1 + JSR PC,FRECLR ; INITIALIZE FREE STORAGE + +;RESTART FOR ABORTS, ERRORS + +ST4: CLR XGPIMP ;CLEAR POINTER TO MAKE SYSTEM UNHAPPY ABOUT + ;PUTTING STUFF INTO BUFFERS NOW + JSR PC,TENIOR ; RESET 10-11 COMMUNICATION CHANNELS + BIS #100000,CIHDR ; OPEN COMMAND INPUT + +; PDP10 - PDP11 COMMUNICATION + +PDP10: INC IDLE + JSR PC,LNKI ; GET COMMAND CHARACTER + ASL R0 ; MAKE IT R0 WORD PTR. + CMP R0,#DSPL ; IS DISPATCH LEGAL? + BHIS PDP10 ; NO - IGNORE IT. + CLR IDLE + JMP @DSP(R0) ; DISPATCH + +DSP: LKSET ; (1) SPECIFY CHARACTER SET + MIXED ; (5) MIXED (TEXT & VECTORS) MODE + IMAGE ; (6) IMAGE MODE + TEST +DSPL==.-DSP ; DISPATCH TABLE LENGTH + TEST: JSR PC,FRECLR + JSR PC,XGPRDY ;TEST XGP HAPPINESS + JSR PC,SLBSU ;SETUP XGP BUFFERS + CLR R5 +TEST3: JSR PC,SLB + MOV R0,SLBO + ADD #4,R0 + MOV #1000,(R0)+ + CLR R2 + DEC R5 + BLE TEST1 +TEST2: MOV BIT100(R2),(R0)+ + TST (R2)+ + CMP R2,#IMWDSZ*2 + BLT TEST2 + MOV #1,@SLBO + BR TEST3 + +TEST1: MOV #-1,(R0)+ + TST (R2)+ + CMP R2,#IMWDSZ*2 + BLT TEST1 + MOV #100.,R5 + MOV #1,@SLBO + BR TEST3 + +BIT100: +.REPT 17. + 1 ;WORD WITH BIT + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 20 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 400 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 10000 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +.ENDR + + IMAGE: MOV #1,AUTCUT + JSR PC,XGPRDY ;XGP HAPPY? + JSR PC,FRECLR ;CLEAR OUT ALL FREE STORAGE AND FONT INFO + MOV #SLB1,XGPIMP+4 ;POINTER TO FIRST BUFFER + MOV #SLB1+10000,XGPIMP+4+8 ;POINTER TO SECOND BUFFER + CLR XGPIMP+2 ;CLEAR USE FLAG FOR FIRST BUFFER + CLR XGPIMP+2+8 ;CLEAR USE FLAG FOR SECOND BUFFER + MOV #XGPIMP,XGPIMP+8 ;SETUP BACK POINTER IN BUFFER CHAIN + MOV #XGPIMP+8,XGPIMP ;SETUP POINTER TO SECOND BUFFER (ALLOW SYSTEM TO START) + MOV #XGPIMP,IMBP ;SETUP INITIAL BUFFER POINTER + MOV #XGPIMP+8,IMOBP ;POINTER TO BUFFER IN USE + MOV #SLB1+20000,R0 ;FIRST FREE LOCATION FOR SCAN LINE BUFFERS + MOV R0,SBNP ;SAVE AS POINTER TO FIRST BUFFER + MOV R0,SLBINI ;FIRST PI LEVEL BUFFER +IM2: CLR (R0)+ ;CLEAR USE FLAG + MOV R1,R2 ;SAVE POINTER 2 BACK + MOV R0,R1 ;SAVE BACK POINTER + ADD #IMSLSZ-2,R0 ;INCREMENT TO NEXT BUFFER LOCATION + CMP R0,#CORSIZ ;OVERLOWED CORE? + BHIS IM1 ;YES, DONE + MOV R0,(R1) ;SAVE POINTER IN OLD BUFFER + BR IM2 ;BACK FOR MORE BUFFERS + +;REGISTER USE: R2 COUNT OF WORDS IN THIS SCAN LINE +; R3 POINTER INTO THE SCAN LINE +; R4 POINTER INTO THE 10 BUFFER +; R5 COUNT OF FREE WORDS IN THE 10 BUFFER + +IM1: MOV #SLB1+20000,(R2) ;BACK POINTER AT LAST BUFFER LOCATION + CLR XGPST ;NOT STARTED + CLR XGPFIN ;NOT FINISHED + CLR R5 ;ZERO INITIAL BUFFER WORD COUNT +IM3: JSR PC,SLB ;GET A SCAN LINE BUFFER + MOV R0,IMSLP ;SAVE POINTER TO SCAN LINE + MOV R0,R3 ;SCAN LINE POINTER + JSR PC,GETWD ;GET COUNT OF WORDS IN THIS LINE + DEC R0 ;FLUSH THIS ONE + BLE IMDONE ;BETTER BE AT LEAST 2 + CMP R0,#IMWDSZ ;REST HAD BETTER FIT INTO A SCAN LINE BUFFER + BGT IMDONE ;OR ELSE FLUSH + MOV R0,R2 ;COUNT OF WORDS TO GET FOR THIS LINE + DEC R2 ;ONE LESS 10 WORD + JSR PC,GETWD ;LINE NUMBER/CUT/EOF + TST R0 ;ZERO NESS + BEQ IMDONE ;HE LOSES + CMP #100000,R0 ;EOF? + BEQ IMDONE ;YUP + MOV R0,IMLPOS ;LINE POSITION AND CUT FLAG + BIC #100000,R0 ;CLEAR OUT CUT FLAG + CMP R0,#200.*36. ;LESS THAN A YARD OF PAPER! + BHIS IMDONE ;HE LOSES! + ADD #4,R3 ;SKIP OVER LINE # AND BUFFER POINTER IN SCAN LINE +IM4: DEC R5 ;ONE LESS WORD IN THE 10 BUFFER + BLT IM5 ;REFILL NEEDED FOR 10 BUFFER + MOV (R4)+,(R3)+ ;TRANSFER THE WORD INTO SCAN LINE + DEC R2 ;ONE LESS WORD IN THIS SCAN LINE + BGT IM4 ;BACK FOR MORE + MOV IMLPOS,@IMSLP ;CLOBBER SCAN LINE POSITION IN + BR IM3 ;NEW SCAN LINE + +IM5: JSR PC,GWRF1 ;REFILL BUFFERS, SETUP R5 AND R4 + BR IM4 ;TRY AGAIN + +GETWD: DEC R5 + BLT GWRF ;REFILL + MOV (R4)+,R0 ;GET WORD FROM 10 BUFFER + RTS PC + +GWRF: JSR PC,GWRF1 ;REFILL BUFFER + BR GETWD ;BACK TO TRY AGAIN + +GWRF1: MOV IMOBP,R0 ;PICK UP OLD POINTER + CLR 2(R0) ;FREE UP THE BUFFER + MOV IMBP,R0 ;PICK UP 10 BUFFER HEADER POINTER + MOV #-60.*60.,TIMER +GWRF3: TST 2(R0) ;10 FILLED BUFFER YET? + BNE GWRF2 ;YUP READY + TST TIMER ;TIMED OUT YET? + BLT GWRF3 ;NOT YET + JMP ABORT ;YES, HE LOSES + +GWRF2: MOV #4000,R5 ;COUNT SETUP AS 1K 10 WORDS + MOV 4(R0),R4 ;PICKUP POINTER TO BUFFER BEGINNING + MOV R0,IMOBP ;OLD BUFFER + MOV (R0),IMBP ;RING THE BUFFER POINTER + RTS PC + +IMDONE: CLR XGPIMP ;RESET BUFFER POINTER, DISABLE PDP-10 CLOBBERS + MOV #100000,(R3) ;SEND EOF TO INTERRUPT LEVEL + JSR PC,XGPWT ;WAIT FOR XGP TO BE DONE + JSR PC,FRECLR + JMP PDP10 + + LKSET: JSR PC,CMDI ;CONTROL CODE + PUSH R0 ;SAVE FOR LATER + JSR PC,LNKI ;FONT # + CMP R0,#MAXFNT ;LEGAL FONT #? + BLO LK1 ;YUP + CLR R0 ;DEFINE FONT 0 INSTEAD +LK1: MOV R0,R4 ;R4 HAS FONT INDEX + ASL R4 ;CONVERT TO WORD QUANTITY + JSR PC,CLRKST ;CLEAR OUT OLD CHAR SET IN THIS FONT + CLR FULFLG(R4) ;CLEAR COUNT OF CHARS IGNORED DUE TO NO MEMORY + MOV #-1,KSTLOD ;SET FLAG FOR PDP-10 + POP R3 ;CONTROL CODE + BEQ LKX ;THATS ALL WE WANT TO DO + JSR PC,WRDI ;HEIGHT + MOV R0,HEIGHT(R4) + JSR PC,WRDI ;BASE + MOV R0,BASE(R4) + MOV #400,R0 ;GET FONT DISPATCH TABLE + JSR PC,GETBLK + MOV R0,FNTBLS(R4) + BEQ LK10 ;BRANCH IF NO CORE + MOV #200,R1 +LK1A: CLR (R0)+ ;CLEAR OUT THE TABLE + DEC R1 + BGT LK1A +LK10: JSR PC,LNKI ;CHAR CODE + TSTB R0 + BLT LKX ;SIGN OF CHAR SET=> END OF CHARS FOR THIS FONT + ASL R0 ;WORD POINTER + MOV FNTBLS(R4),CHRIDX ;OFFSET INTO FONT TABLE + BEQ LK10A ;IF ZERO THEN DISPATCH TABLE DOES NOT EXIST + ADD R0,CHRIDX +LK10A: JSR PC,LNKI ; "BEFORE" CHARACTER ADJUST + NEG R0 ;SUBTRACTS FROM COLUMN POSITION + MOV R0,LBADJ + JSR PC,WRDI ;"AFTER" CHARACTER ADJUST + MOV R0,LAADJ + JSR PC,WRDI ;BITS PER ROW + BEQ NULCHR ;ZERO BITS WIDE => NULL + ADD #17,R0 ;MAKE IT ROUND UP + MOV R0,MQ + MOV #20,DIV ;FIND OUT NUMBER OF WORDS + MOV MQ,LWDSPR ;STASH IT AWAY + CLR SKIPS ;NUMBER TOP ROWS ALL ZERO TO BE SKIPPED + CLR BROWS ;HEIGHT(FONT)-SKIPS + CLR BOTZR ;CLEAR NUMBER OF BOTTOM ROWS BLANK + MOV HEIGHT(R4),NROWS + CLR LKOVRF ;BUFFER HAS OVERFLOWED FLAG +LK5: MOV #SLB1,R5 ;POINTER TO TEMPORARY TABLE AREA +LK2: DEC NROWS ;ROWS LEFT IN THIS CHAR + BLT LK8 ;NONE LEFT + CLR ROWNZ ;COUNT OF NON ZERO WORDS IN THIS ROW + MOV LWDSPR,R2 ;LOOP COUNT FOR FETCHING WORDS +LK3: DEC R2 + BLT LK4 ;FINISHED WITH THIS ROW + CMP #BITSNK-4,R5 + BLOS LKBFUL ;BUFFER FULL? + JSR PC,CMDI ;GET BYTE OF FONT DESCR. + MOVB R0,(R5)+ ;STASH IN TEMP LOC + JSR PC,CMDI ;NEXT BYTE + MOVB R0,(R5)+ + TST -2(R5) ;IS THIS ENTRY ZERO? + BEQ LK3 ;YES, MAYBE RESET TEMP POINTER, + INC ROWNZ ;COUNT OF NON ZERO ROWS + BR LK3 ;LOOP FOR MORE + +LKBFUL: JSR PC,WRDI ;BUFFER IS FULL, JUST GOBBLE TWO WORDS + INC LKOVRF ;FLAG A BUFFER OVERFLOW + BR LK3 + +LKX: MOV FULFLG(R4),KSTLOD ;SET FLAG FOR PDP-10 + JMP PDP10 + +LK4: TST BROWS ;GOT ANY NON ZERO ROWS YET? + BNE LK13 ;YUP, CANT HACK + TST ROWNZ ;THIS ROW ZERO? + BNE LK6 ;NOPE, CANT HACK + INC SKIPS ;SKIP OVER THIS ROW (DONT STORE IT) + BR LK5 ;BACKUP R5 TO BEG, START OVER + +LK6: INC BROWS ;COUNT OF NON ZERO ROWS SO FAR + BR LK2 + +LK13: TST ROWNZ ;THIS ROW ZERO? + BNE LK11 ;NO + INC BOTZR ;YES, MAYBE ON THE BOTTOM + BR LK2 ;BACK FOR ANOTHER ROW + +LK11: CLR BOTZR ;NON ZERO ROW, ZERO COUNT OF BOTTOM ZERO ROWS + BR LK2 ;BACK FOR ANOTHER ROW + +NULCHR: MOV CHRIDX,R1 + BEQ FONTFL ;BRANCH IF DISPATCH TABLE DOES NOT EXIST + MOV #4,R0 ;BLOCK FOR ADJUSTS ONLY + JSR PC,GETBLK ;GET ENUF FOR THIS CHAR + BEQ FONTFL ;BRANCH IF NONE + MOV R0,(R1) + MOVB LBADJ,(R0)+ ;SAVE BEFORE CHAR ADJUST + CLRB (R0)+ ;CLEAR WORDS/ROW FOR THIS CHAR + MOV LAADJ,(R0)+ ;SAVE AFTER CHARACTER ADJUST + BR LK10 + +FONTFL: INC FULFLG(R4) ;COUNT OF OVERFLOWED CHARACTERS + BR LK10 ;NEXT CHARACTER + +LK8: TST BROWS ;ANY BLACKNESS AT ALL? + BEQ NULCHR ;NOPE, NOT WORTH STORING THIS CHAR + TST LKOVRF ;DID BUFFER OVERFLOW? + BNE FONTFL + MOV CHRIDX,R1 ;RESTORE CHAR INDEX + BEQ FONTFL ;BRACH IF FONT DISPATCH DOES NOT EXIST + MOV LWDSPR,MQ ;WORDS/ROW + MOV BOTZR,MUL ;TIMES NUMBER OF ZERO BOTTOM ROWS + SUB MQ,R5 ;FLUSH ROW + SUB MQ,R5 ;TWICE BECAUSE ITS WORDS! + SUB #SLB1,R5 ;NUMBER OF WORDS IT TOOK TO STORE FONT + MOV R5,R0 ;SETUP FOR CORE ALLOC CALL + ASR R5 ;CONVERT TO COUNT + ADD #8,R0 ;ALLOW ROOM FOR SKIPS AND HEIGHT + JSR PC,GETBLK ;CALL CORE ALLOC + BEQ FONTFL ;BRANCH IF NO CORE FOUND + MOV R0,(R1) ;STORE POINTER TO FONT ENTRY + MOVB LBADJ,(R0)+ ;SAVE BEFORE ADJUST FOR THIS CHAR + MOVB LWDSPR,(R0)+ ;SAVE WORDS/ROW FOR THIS CHAR + MOV LAADJ,(R0)+ ;SAVE AFTER CHARACTER ADJUST + MOV SKIPS,(R0)+ ;STASH BLANK TOP SCAN LINES SKIPPED + MOV HEIGHT(R4),R2 ;HEIGHT OF FONT + SUB SKIPS,R2 ;SUB SCAN LINES SKIPPED AT TOP + SUB BOTZR,R2 ;SUBTRACT OFF NUMBER OF BOTTOM ZERO ROWS FROM HEIGHT + NEG R2 ;SL1 WANTS HEIGHT NEGATIVE + MOV R2,(R0)+ ;STASH REMAINING HEIGHT + MOV #SLB1,R1 ;ORIGIN OF STORED CHAR +LK9: MOV (R1)+,(R0)+ ;STASH AWAY ACTUAL BLACK BITS + DEC R5 ;COUNT OF NUMBER TO STASH + BGT LK9 ;NOT DONE + JMP LK10 ;BACK FOR ANOTHER CHARACTER + ;CLEAR CHARACTER SET +CLRKST: MOV FNTBLS(R4),R3 ;GET CHAR INDEX FOR 0 CHAR THIS FONT + BEQ RTSPC ;BRANCH IF FONT DISPATCH DOES NOT EXIST + PUSH #200 ;SETUP LOOP COUNT +CLRKS1: MOV (R3),R0 ;POINTER TO FONT DEF + BEQ CLRKS2 ;NO CHAR THERE + JSR PC,RETBLK ;RETURN MEMORY +CLRKS2: CLR (R3)+ ;INCREMENT POINTER + DEC (SP) ;COUNT RAN OUT? + BGT CLRKS1 ;NO + TST (SP)+ ; POP STACK + MOV FNTBLS(R4),R0 + CLR FNTBLS(R4) ;RETURN FONT DISPATCH TO FREE STORAGE + JMP RETBLK + ; 10-11 COMMUNICATION ROUTINES + + +; LNKI - GET R0 BYTE FROM PDP10 + +LNKI: JSR PC,CMDI + BIC #177400,R0 +RTSPC: RTS PC + +;HERE FOR FULL WORD INPUT FROM PDP-10 + +WRDI: JSR PC,CMDI + PUSH R0 + JSR PC,CMDI + MOVB R0,1(SP) + POP R0 + RTS PC + +;HERE FOR EMPTY COMMAND BUFFER + +CMDI1: MOV CIBUF,R0 ;POINTS TO THIS BUFFER + MOV #-1,(R0)+ ;MARK AS FREE + MOV (R0),R0 ;NEXT BUFFER ON RING +CMDI1A: MOV #LAMBDA,TIMER +CMDI2: TST DBSW + BNE CMDI4 + TST TIMER + BGT CMDI3 ;TIME OUT EXIT +CMDI4: TST CIHDR ;TEST FOR ARBITRARY CLOSE BY 10 + BLT .+4 + BPT ;HE DID IT! + MOV (R0),CICNT + BLE CMDI2 ;WAIT FOR BUFFER TO FILL + MOV R0,CIBUF + CLR (R0) ;MARK BUFFER AS BUSY + ADD #BHDRL,R0 ;FIRST AVAILABLE BYTE OF BUFFER + MOV R0,CINXT + +;HERE TO GET BYTE FROM COMMAND BUFFER +; RETURNS BYTE IN R0 + +CMDI: DEC CICNT + BLT CMDI1 ;BUFFER EMPTY + MOVB @CINXT,R0 + INC CINXT + RTS PC + +;HERE WHEN TEN TIMES OUT WAITING FOR COMMAND INPUT + +CMDI3: TST IDLE + BNE CMDI1A + JMP TIMOUT + + ;HERE TO RESET ALL I/O CHANNELS TO 10 + +TENIOR: MOV #LNKV,R0 + CLR (R0)+ ;POINTS TO CHANNEL HEADER AREA + CLR (R0)+ ;# CHANNELS + CLR (R0)+ ;POINTS TO BUFFER AREA + CLR (R0)+ ;SIZE OF BUFFER AREA + MOV #CIHDR,R2 ;ORIGIN OF CHANNEL HEADER AREA + MOV #ACTCHN,R3 ;CHANNEL COUNT +TENIO1: JSR PC,CLOS10 ;CLOSE THAT CHANNEL + DEC R3 + BGT TENIO1 + MOV #LNKV,R0 ;SET CHANNEL HEADER POINTER + MOV #CIHDR,(R0)+ + MOV #ACTCHN,(R0)+ + MOV #BUFORG,(R0)+ + MOV #BUFFRL,(R0)+ + RTS PC + +;HERE TO ZAP BUFFER RING + +ZAPRNG: PUSH R0 +ZAP1: MOV R1,(R0)+ ;THAT WITH WHICH TO ZAP + MOV (R0),R0 ;NEXT ON RG + CMP R0,(SP) ;CHECK FOR WRAP AROUND + BNE ZAP1 + POP R0 + CLR (R0) ;MAKE BUFFER WE ARE POINTING AT BUSY + RTS PC + +;HERE TO INSURE ALL BUFFERS IN DATA RING ARE FULL + +FILL: MOV DIBUF,R0 + MOV 2(R0),R0 ;RING PAST THE BUSY BUFFER + MOV #LAMBDA*4,TIMER ;BE MORE FORGIVING HERE +FILL1: TST DBSW + BNE FILL4 + TST TIMER + BGT FILL3 +FILL4: TST DIHDR + BGE FILL2 ;TEN CLOSED CHANNEL + TST (R0) ;THE TEN WILL GET HERE SOONER OR LADTER + BLE FILL1 + MOV 2(R0),R0 ;NEXT ON RING + CMP R0,DIBUF + BNE FILL1 +FILL2: RTS PC ;END OF RING + +FILL3: JMP TIMOUT + +;CLOSE 10 CHANNEL + +CLOS10: CLR (R2)+ ;CLOSE CHANNEL + MOV #-1,R1 ;MARK ALL BUFFERS AS FREE + MOV (R2)+,R0 ;BUFFER RING + JSR PC,ZAPRNG ;SHOULD BE ENOUGH IF THE 10 IS CLEVER + JSR PC,ZAPRNG ;BUT WE'RE PARANOID + CLR (R2)+ ;POINTS INTO BUFFER + CLR (R2)+ ;COUNT + RTS PC + ;DYNAMIC STORAGE ALLOCATOR ROUTINES + +GETBLK: PUSH R1 + PUSH R2 + JSR PC,EVENUP ;INSURE AN EVEN # OF BYTES + TST R0 ;REASONABLE REQUEST? + BNE GTB1 ;YUP + JSR PC,ERROR ;LOSEY LOSEY +GTB1: ADD #BHDRL,R0 ;ADD IN HEADER LENGTH + MOV ROVER,R1 + BNE GETBL1 + MOV @AVAIL,R1 + MOV R1,ROVER +GETBL1: MOV (R1),R2 ;NEXT BLOCK + CMP R0,-2(R1) + BLOS GETBL2 ;FOUND R0 WINNER + CMP R2,AVAIL + BEQ GETBL3 ;END OF CHAIN + MOV R2,R1 + BR GETBL1 + +;HERE IF WINNER FOUND + +GETBL2: MOV R2,ROVER + SUB R0,-2(R1) ;SIZE OF THIS BLOCK NOW + CMP -2(R1),#NEBISH + BLO GETB21 + MOV R1,R2 ;BREAK INTO TWO BLOCKS + ADD -2(R1),R2 ;ORIGIN OF NEW BLOCK + MOV -2(R1),-4(R2) ;SIZE INTO TOP OF OLD BLOCK +GETBL4: MOV R0,R1 ;LENGTH OF NEW BLOCK + BIS #INUSE,R0 ;MARKS BLOCK IN USE + MOV R0,-2(R2) ;MARKER INTO BLOCK + MOV R2,R0 ;RETURN POINTER TO CALLER + ADD R1,R2 ;ORIGIN OF NEXT BLOCK + MOV #INUSE,-4(R2) ;MARK LAST WORD OF NEW BLOCK + POP R2 + POP R1 + TST R0 ;RETURN IN CONDITION CODES ALSO + RTS PC + +;HERE TO GIVE CALLER ENTIRE BLOCK + +GETB21: JSR PC,UNLINK ;TAKE BLOCK OUT OF FREE LIST + ADD -2(R1),R0 ;SIZE OF BLOCK + MOV R1,R2 ;NEW BLOCK + BR GETBL4 + +;HERE ON END OF FREE LIST + +GETBL3: TST ROVER + BNE GTBL5 + POP R2 + POP R1 + CLR R0 ;INDICATE MEMORY FULL BY 0 RETURN + RTS PC + +GTBL5: CLR ROVER + MOV @AVAIL,R1 + BR GETBL1 + ;TAKES BLOCK IN R1 AND PATCHES IT OUT OF FREE STORAGE LIST + +UNLINK: MOV (R1),R2 + MOV R2,@2(R1) ;PATCH FORWARD POINTER INTO PRECEEDING BLOCK + MOV 2(R1),2(R2) ;PATCH BACK POINTER INTO NEXT BLOCK + CMP ROVER,R1 + BNE .+6 + MOV R2,ROVER ;DON'R1 LET ROVER POINT TO NON-EXISTENT BLOCK + RTS PC + +;HERE TO RETURN R0 BLOCK TO FREE STORAGE + +RETBLK: MOV R0,OLDBLK ;SAVE FOR DEBUGGING + CMP R0,#FS+2 + BHIS .+4 + HALT ;CAN'R1 TAKE THAT ONE BACK + MOV -2(R0),R1 ;SIZE + BIT #INUSE,R1 + BNE .+4 + HALT ;CAN'R1 FREE R0 BLOCK WHICH ISN'R1 IN USE + BIC #INUSE,R1 + BIT #INUSE,-4(R0) ;IS BLOCK BELOW RESERVED + BNE RETBL1 ;YES, CHECK LOWER BOUND + SUB -4(R0),R0 ;POINTS TO ENLARGED BLOCK + ADD R1,-2(R0) ;NEW SIZE + MOV R0,R1 + ADD -2(R0),R1 ;POINTS TO BLOCK ABOVE + MOV -2(R0),-4(R1) ;PUT MARKER AT TOP OF BLOCK + BIT #INUSE,-2(R1) + BNE RTSPC2 ;BLOCK ABOVE RESERVED, GOOD BYE + ADD -2(R1),-2(R0) ;NEW SIZE OF MOBY BIG BLOCK + JSR PC,UNLINK ;TAKE THIS BLOCK OUT OF FREE LIST + MOV R0,R1 ;MARK TOP OF ENLARGED BLOCK + ADD -2(R0),R1 ;POINTS TO NEXT BLOCK + MOV -2(R0),-4(R1) ;MARK TOP OF BLOCK WITH SIZE + RTS PC + ;BLOCK BELOW RESERVED, CHECK ABOVE + +RETBL1: MOV R1,-2(R0) ;MARK THIS BLOCK AS FREE + ADD R0,R1 ;POINTS TO NEXT BLOCK + MOV -2(R0),-4(R1) ;MARKER INTO TOP OF BLOCK + BIT #INUSE,-2(R1) + BNE LINK ;BR IF BLOCK ABOVE RESERVED, PATCH THIS ONE BACK IN + JSR PC,UNLINK ;TAKE BLOCK ABOVE OUT OF FREE STORAGE + ADD -2(R1),-2(R0) ;NEW SIZE + MOV R0,R1 + ADD -2(R0),R1 ;POINTS TO NEXT BLOCK + MOV -2(R0),-4(R1) ;MARK TOP OF BLOCK +LINK: ;PATCH THIS IN AT AVAIL + CMP ROVER,R0 + BNE .+6 + CLR ROVER + MOV AVAIL,R1 ;PREVIOUS BLOCK + MOV (R1),R2 ;NEXT BLOCK + MOV R0,(R1) ;FWD PNTR IN PREV BLK + MOV R2,(R0) ;FWD PNTR IN THI BLK + MOV R1,2(R0) ;BACK PNTR IN THIS BLK + MOV R0,2(R2) ;BACK PNTR IN NEXT BLK +RTSPC2: RTS PC + +EVENUP: BIT #1,R0 + BEQ RTSPC2 + INC R0 + RTS PC + + ;HERE TO INITIALZE FREE STORAGE VARIABLES + +FRECLR: MOV #CORSIZ,MEMTOP + MOV MEMTOP,R1 + MOV #-1,-(R1) ;EVERYTHING ABOVE FREE STORAGE RESERVED + MOV R1,MEMTOP ;SET UP FREE STORAGE + MOV #FAKEBL+2,R1 + MOV R1,AVAIL + MOV R1,ROVER + MOV #FS+2,R2 ;SET UP FAKE BLOCK + CLR -2(R1) ;SIZE 0 + MOV R2,(R1) ;FAKEBL FD PNTR + MOV R2,2(R1) ;BACK PNTR + MOV #-1,4(R1) ;LOOKS TAKEN FROM ABOVE + MOV R1,(R2) ;FD PNTR IN FS + MOV R1,2(R2) ;BACK PNTR IN FS + MOV MEMTOP,R0 + SUB #FS,R0 ;SIZE OF FREE STORAGE (LEAVE 1 WD FOR -1) + MOV R0,-(R2) + +;CLEAR THE KSET POINTERS INTO FREE STORAGE + + MOV #FNTBLS,R0 ;CLEAR FONT DISPATCH TABLE + MOV #MAXFNT,R1 +FRECL1: CLR (R0)+ + DEC R1 + BGT FRECL1 + RTS PC + ; ERROR HANDLING + +; POWER FAIL PROCEDURE + +POWRF: MOV SP,@#0 + MOV #POWRU,@#24 + CLR XCR + HALT +POWRU: JMP START + +; NON-XGP TRAPS + +; ERROR HANDLING + +ERROR: MOV (SP),ERRADR + CLR XCR ;STOP THE XGP + BPT ;GOES TO EITHER NORUG OR CARPET + JMP START + +IOTBRK: JSR PC,ERROR + +ERR1: JSR PC,ERROR + +ERR2: JSR PC,ERROR + PARAM: MOV #PLDO,R1 ;ORIGIN OF TABLE OF WORDS TO BE CLOBBERED + JSR PC,LNKI + MOV R0,R2 ;WORD COUNT +P2: DEC R2 ;DONE? + BLT P1 + JSR PC,WRDI + CMP R1,#PLDF ;OVERFLOW TABLE OF WORDS TO INITIALIZE? + BHIS P2 ;YES + MOV R0,@(R1)+ ;STASH THE WORD AWAY + BR P2 + +P1: MOV BOTMAR,R0 + ADD TOPMAR,R0 + CMP R0,LPAGE ;PAGE LENGTH BETTER BE BIGGER THAN TOPMAR+BOTMAR + BHIS PARMER ;LOSE! + MOV LPAGE,R0 ;PAGE LENGTH + SUB BOTMAR,R0 ;BOTTOM MARGIN IN SCAN LINES + MOV R0,BOTMAR ;WE WANT BOTMAR TO BE DISTANCE FROM TOP OF PAGE + RTS PC ;RETURN + +PARMER: JMP ABORT + +PLDO: VSP ;VERTICAL INTER BASELINE SPACING + LFTMAR ;LEFT MARGIN + TOPMAR ;TOP MARGIN + BOTMAR ;BOTTOM MARGIN (SCAN LINES FROM THE TOP OF THE PAGE) + LPAGE ;LENGTH OF PAGE (BETWEEN CUTS) IN SCAN LINES + PAGEN ;PAGE NUMBER + AUTCUT ;0=> DONT CUT THE PAPER + VLPFLG ;0=> NORMAL NON ZERO=> PAGES TERMINATED ONLY WITH FF +PLDF:: + SLBSU: MOV #SLB1,R0 ;SETUP SCAN LINE BUFFER POINTERS + MOV R0,SBNP ;SETUP INITIAL SCAN LINE BUFF POINTER + MOV R0,SLBINI ;FIRST PI LEVELBUFFER +SLSU2: CLR (R0)+ ;CLEAR OUT USED FLAG + MOV R1,R2 ;SAVE PAST 2 POINTERS + MOV R0,R1 + ADD #IMSLSZ-2,R0 ;SIZE OF BUFFER + CMP R0,#SLBND ;EXCEEDED ALLOCATION? + BHIS SLSU1 ;YUP, FINISHED + MOV R0,(R1) ;CHAINED BUFFER POINTER + BR SLSU2 + +SLSU1: MOV #SLB1,(R2) ;COMPLETE THE RING OF BUFFERS + CLR XGPST ;XGP NOT STARTED + CLR XGPFIN ;AND NOT FINISHED + RTS PC + +MIXED: JSR PC,XGPRDY ;TEST XGP HAPPINESS + MOV #100000,DIHDR ;OPEN DATA INPUT + JSR PC,SLBSU ;SETUP SCAN LINE BUFFERS + MOV #GCHARN,GCHARD ;SETUP INITIAL DISPATCH FOR CHAR GETTING LOOP + CLR EOFF ;CLEAR END OF FILE FLAG + CLR FONT ;START OUT WITH FONT 0 + CLR PPN ;ZERO PAPER PAGE NUMBER + CLR HEADRF ;NO HEADER INITIALLY + JSR PC,PARAM ;GET MARGINS,VSP,ETC. + JSR PC,FILL ;FILL TEXT LINE BUFFERS +PAGE: CLR FFF ;CLEAR FORM FEED FLAG ON THIS LINE + CLR OLLOW ;CLEAR DESCEND OF PREV LINE + CLR BSLC ;CLEAR BLACK SCAN LINE COUNT + JSR PC,VECTRS ;RESET VECTORS FOR NEW PAGE + CLR TVPOS ;TOP OF PAGE IS SCAN LINE ZERO + MOV TOPMAR,RVSP ;PRETEND PREVIOUS LINE HAD SPACING OF TOPMAR + TST HEADRF ;HAVE WE GOT A HEADER LINE + BEQ TLINE ;YES + MOV GCHARD,HGCHAR ;SAVE OLD SOURCE OF CHARACTERS + MOV #HDRS,GCHARD ;SETUP SOURCE FROM HEADER LINE + MOV HCNT,HCNT1 ;SETUP COUNT OF CHARS IN HEADER LINE + MOV #HBUF,HPTR ;SETUP POINTER TO HEADER CHRACTER LINES + MOV FONT,HSFONT ;SAVE FONT PREVIOUS TO HEADER. + CLR FONT ;RESET HEADER FONT TO FONT ZERO. +TLINE: TST FFF ;SHOULD I FORM FEED AFTER THIS LAST LINE? + BNE EPAGE ;YES + MOV RVSP,OVSP ;SAVE OLD LINE'S VERTICAL SPACE COMMAND + JSR PC,LSETUP ;MAIN LOOP FOR TEXT LINE PROCESSING + TST QFF ;QUICK FORM FEED FLAG? (NO OTHER STUFF ON THE LINE) + BNE EPAGE + TST LFF ;QUICK LINE FEED? + BNE LFQ ;YES, DO IT QUICKLY + MOV SKPCNT,R0 ;DOES THIS LINE HAVE ITS OWN IDEA OF HOW MANY + ;LINES TO SKIP BEFORE IT? + BNE TL3 ;SKIP AROUND COMPUTATION OF # OF LINES TO SKIP + MOV OVSP,R0 ;GET LAST LINE'S VSP PARAMETER + SUB OLLOW,R0 ;AMOUNT PREV LINE DESCENDED + SUB BASEL,R0 ;SUBTRACT UPPER PART OF THIS LINE + BLE TL1 ;LOSE, DESCEND+ASCEND > VSP, HE LOSES + MOV R0,SKPCNT ;COUNT OF LINES TO SKIP BETWEEN TEXT LINES +TL3: ADD TVPOS,R0 ;TEST FOR OVERFLOW OF BOTTOM MARGIN + TST VLPFLG ;VARIABLE LENGTH PAGE FLAG + BNE TL3A + CMP R0,BOTMAR + BGE NPAGE ;OVERFLOW +TL3A: JSR PC,VECTCK ;SETUP LINES WITH VECTORS +TL2: MOV CHRRCT,R0 + MOV R0,OLLOW ;SAVE DESCEND OF THIS LINE + SUB BASEL,OLLOW ;FOR NEXT LINE SPACING + ADD TVPOS,R0 + TST VLPFLG ;VARIABLE LENGTH PAGE FLAG + BNE TL2A + CMP R0,BOTMAR + BGE NPAGE ;THIS GUY JUST MADE A TEXT LINE RUN OFF THE + ;END OF THE PAGE +TL2A: CLR NPF ;CLEAR FLAG INDICATING LAST LINE CAUSED PAGE SKIP + TST LFF ;QUICK LINE FEED? + BNE LFQ ;YES + ADD CHRRCT,BSLC ;NO, ADD CHRRCT TO BLACK LINE COUNT +SLINE: DEC CHRRCT ;COUNT # SCAN LINES IN THIS TEXT LINE + BLT TLINE ;GET A NEW TEXT LINE + INC TVPOS ;NEXT LINE + JSR PC,SLB ;MAIN S.L. LOOP, GET A S.L. BUFFER + JSR PC,SLBC ;CLEAR IT OUT + MOV R0,SLBO ;SETUP POINTERS TO S.L. ORIGIN + JSR PC,VECT ;SETUP VECTORS ON THIS LINE + MOV #MQ,R5 ;POINTER TO MQ IN R5 + MOV #ACCT,R2 ;POINTER TO CHAR TABLE FOR LINE IN R2 + JMP SL1 ;OFF TO THE MAIN LOOP FOR CHAR PROCESSING + +LFQ: ADD OVSP,RVSP ;EXPAND VERTICAL SPACING OF PREVIOUS LINE + ;LEAVE OLLOW SAME + BR TLINE ;NEXT TEXT LINE + +TL1: CLR SKPCNT ;SETUP ZERO LINES TO SKIP + BR TL2 ;NO VECTORS PROCESSED, JUMP TO PAGE CHECK + +NPAGE: TST NPF ;DID THIS PREVIOUS LINE CAUSE A PAGE SKIP ALSO? + BNE EPAGE ;YES, FORGET THAT LOSING LINE + INC NPF ;SET LAST LINE PRODUCED A PAGE OVERFLOW + JSR PC,TLBACK + INC PPN ;AOS PRINTING PAGE NUMBER (RESET FF TIME) +EPAGE: TST BSLC ;NEW PAGE, HAVE WE PUT ANYTHING ON THE OLD ONE? + BEQ BLANK ;NOPE, DONT FEED THE FORM +EP1: MOV LPAGE,SKPCNT + SUB TVPOS,SKPCNT + JSR PC,VECTCK ;CHECK TO END OF PAGE FOR MORE VECTORS + JSR PC,SLB ;BUFFER FOR FORM FEED + MOV TVPOS,R1 ;LOC TO CUT PAPER + BIS #100000,R1 ;SET SIGN BIT FOR PAPER CUT + MOV R1,(R0) ;CLOBBER INTO SCAN BUFFER COUNT + TST EOFF ;END OF FILE? + BEQ PAGEA ;NEW PAGE STUFF + JSR PC,SLB + MOV #100000,(R0) ;SEND EOF TO INTERRUPT LEVEL STUFF + JSR PC,XGPWT ;WAIT FOR INT. LEVEL TO PROCESS IT + JMP PDP10 ;BACK FOR ANOTHER COMMAND FROM THE 10 + +PAGEA: JMP PAGE + +BLANK: TST EOFF ;AT END OF FILE? + BNE EP1 ;YES, FORM FEED ANYWAY + CLR FFF ;RESET FORM FEED INDICATION + JMP PAGE ;AND CONTINUE PROCESSING TEXT + +TLBACK: CLR EOFF ;RESET EOF UNTIL IT IS PROCESSED AGAIN + CLR FFF ;LIKEWISE FFF + mov blfont,font ;restore font in effect at beginning of old line + MOV #TLRD,GCHARD ;MAKE GCHAR READ STORED TEXT LINE + MOV TLCNT,TLCNT1 ;SETUP COUNT OF NUMBER OF CHARS IN LAST TEXT LINE + RTS PC + ;VECTCK IS CALLED WHEN THE TEXT PROCESSOR IS ABOUT TO +;SKIP OVER LINES BEFORE CREATING ANY SCAN LINE +;BUFFERS. IT IS UP TO VECTCK TO CHECK IF ANY VECTORS +;CROSS THESE SCAN LINES AND IF NECESSARY TO PRODUCE SCAN +;LINE BUFFERS FOR THEM. IN ANY CASE, IT INCREMENTS +;TVPOS. IT MUST SET BSLC FOR ANY LINES IT PRODUCES. + +VECTCK: ADD SKPCNT,TVPOS + RTS PC + +;VECT GETS CALLED JUST AFTER THE TEXT LINE PROCESSOR PRODUCES +;A NEW SCAN LINE. IT MUST DECIDE IF ANY VECTORS CROSS THIS LINE +;AND INSERT THEM INTO THE SCAN LINE BUFFER. + +VECT: RTS PC + +;VECTRS GETS CALLED AT THE BEGINNING OF EACH PAGE TO RESET THE VECTOR +;DATA BASE, SINCE VECTORS ARE NOT ALLOWED TO CROSS PAGE BOUNDARIES. + +VECTRS: RTS PC + +;ADVECT ADDS A VECTOR TO THE VECTOR DATABASE DESCRIPTION OF THE +;VECTOR IS IN X0,Y0,VN,XF,XS,XI + +ADVECT: RTS PC + SLB: MOV SBNP,R0 ;R0 GETS ADR OF NEW BUFF + TST (R0) ;FREE? + BNE WAITR ;NO +SLBA: MOV 2(R0),SBNP ;SETUP NEW POINTER + RTS PC + +SLBC: ADD #4,R0 ;SKIP OVER HEADER + MOV #1000,(R0)+ ;IMAGE MODE XGP LINE + MOV R0,R1 + REPT1 IMWDSZ,CLR (R1)+ ;LOTS OF CLEARS + RTS PC + +WAITR: TST XGPST ;HAS XGP BEEN STARTED? + BNE WAIT1 ;YES + JSR PC,XGPSTR ;NOPE, BUT WE WILL +WAIT1: TST (R0) ;REALLY SIT AND WAIT + BNE WAIT1 + BR SLBA + +XGPSTR: PUSH R1 + PUSH R2 +XGPST1: INC XGPST + MOV #FMOT,XCR + MOV #-2*60.,TIMER +STXGP1: WAIT + TST TIMER + BLT STXGP1 + BIT XSR,#FRDY + BEQ XGPST1 + MOV MKTOCT,R1 + MOV R1,R2 + TST TICKS1 + BNE STX1 + MOV TICKS,R2 +STX1: JSR PC,CUTCLK ;R1 HAS # OF TICKS BEFORE IT CUTS THIS STUFF + SUB #30*CF,R1 + BLT STX2 + SUB #30*CF,R2 + BGE STX1 +STX2: MOV SLBINI,SBPI ;SETUP INT LEVEL POINTERTO BUFFS + CLR VPOS ;CLEAR OUT INT LEVEL VERTICAL POSITION + MOV #ITEMP,OBUF ;SETUP BACK BUFFER POINTER TO POINT + ;TO HARMLESS JUNK + CLR XGPE ;ZERO ERROR CONDITIONS + MOV #FMOT,XCR ;START IT UP + MOV #BNULL,MAR ;WITH A NULL INITIAL BUFFER + MOV #FDIE+FGO+FMOT,XCR ;ENABLE INTERRUPTS, AND GO + POP R2 + POP R1 + RTS PC + +XGPWT: TST XGPST ;HAVE WE STARTED THE XGP? + BNE XWT1 ;YES + JSR PC,XGPSTR ;NO, START IT UP (THIS ONLY HAPPENS ON SHORT FILES +XWT1: TST XGPFIN ;XGP FINISHED? + BEQ XWT1 ;NO, WAIT MORE + CLR XGPFIN ;RESET DONE FLAG + CLR XGPST ;NO LONGER STARTED + CLR TICKS ;RESET TIMER + CLR TICKS1 +XRDYX: RTS PC + +XGPRDY: BIT #RDMASK,XSR + BEQ XRDYX ;EVERYTHING OK +ABORT: BIS XSR,XGPE ;ERROR FLAGS INTO XGPE + CLR XGPIMP ;PREVENT 10 FROM CLOBBERING BUFFERS + CLR XCR ;STOP XGP + INC ABORTF ;SIGNAL 10 WE HAVE ABORTED +AB1: TST ABORTF ;10 RESPONDED? + BNE AB1 ;NOPE, CONTINUE WAITING + JMP START ;FINALLY RESTART + SL1: INC (R2)+ ;COUNT + BLT SL2 ;<0, PRINT THIS CHAR + BGT FIDDLE ;>0 SKIP OVER THIS CHAR + MOV #77777,-2(R2) ;SET MAX POS #, SO WE SKIP FROM NOW ON +SL2: MOV (R2)+,R0 ;WORD OFFSET FROM ORIGIN + MOVB (R2)+,R4 ;BIT OFFSET FROM ORIGIN + ADD #0,R0 ;OFFSET WITH S.L. ORIGIN +SLBO==.-2 ;CLOBBERED AT SLINE + MOVB (R2)+,R1 ;WIDTH OF THIS CHAR IN WORDS + MOV (R2),R3 ;PTR TO FONT BITS +SL3: MOV (R3)+,(R5) ;BITS TO MQ + CLR -(R5) ;CLEAR BITS SHIFTED IN + MOV R4,LSH ;BITPOS INTO SHIFT COUNT + BIS MQ,(R0)+ ;BITS TO CORE + BIS (R5)+,(R0) ;BITS TO CORE + DEC R1 + BGT SL3 + MOV R3,(R2)+ ;UPDATE FONT POINTER + BR SL1 + +FIDDLE: DEC -(R2) ;RESTORE COUNT + BEQ EOL ;ZERO COUNT => END OF LINE + DEC (R2) ;DEC SKIP COUNT + BGT FIDL1 ;SKIP MORE + MOV ACCTPT(R2),R3 ;COUNT WAS ONE, SETUP CHAR TO START NEXT PASS + TST (R3)+ ;INC R3, SKIP OVER SKIP COUNT + MOV (R3)+,(R2) ;-HEIGHT => LINE BUFF + MOV R3,ACCTPT(R2) ;PTR TO FIRST LINE OF FONT DEF. +FIDL1: ADD #10,R2 ;SKIP OVER REST OF ACCT ENTRY + BR SL1 ;TRY AGAIN + +EOL: MOV SLBO,R0 ;ADR OF OLD S.L. BUFF + MOV TVPOS,-6(R0) ;STASH "IN USE" VERTICAL POSITION FIELD + JMP SLINE ;NEW SCAN LINE + + GCHAR: JMP @GCHARD ;DISPATCH TO APPROPRIATE ROUTINE + +GREFIL: JSR PC,GRF ;GET NEW TEXT LINE BUFFER +GCHARN: DEC DICNT ;COUNT DOWN CHARS LEFT IN BUFFER + BLT GREFIL ;NONE LEFT + MOVB @DINXT,R0 ;GET CHAR + INC DINXT ;COUNT POINTER UP + MOVB R0,@TLP ;SAVE CHAR IN LINE BUFFER + BLT GEOF ;END OF FILE CHARACTER + INC TLP ;TEXT LINE POINTER + INC TLCNT ;COUNT OF NUMBER OF CHARS IN LAST TEXT LINE + CMP TLP,#TLBND ;OVERFLOW? + BHIS TLOV ;YES +GCH1: BIC #177600,R0 ;CLEAR EXCEPT 177 BITS, SETUP CONDITION CODE + RTS PC + +GRF: MOV DIBUF,R0 ;POINTER TO OLD BUFFER + MOV #-1,(R0)+ ;INDICATE OLD BUFFER FREE + MOV (R0),R0 ;PICK UP RING POINTER TO NEW BUFFER +GRF1: MOV (R0),DICNT ;COUNT OF BYTES IN THIS BUFFER + BLE TWAIT ;WAIT FOR A TEXT BUFFER (UGH) + MOV R0,DIBUF ;STASH POINTER TO CURRENT BUFFER HEADER + CLR (R0) ;INDICATE BUSY + ADD #BHDRL,R0 ;SKIP OVER BUFFER HEADER + MOV R0,DINXT ;USE AS POINTER TO FIRST CHAR IN BUFFER + RTS PC + +TLOV: MOV #TLEND,TLP ;OVERFLOW LOCATION FOR TLBUF + BR GCH1 ;BACK TO FEED CHAR AT M.P. + +TLRD: MOVB @TLP,R0 ;GET CHAR OUT OF BUFFER + BLT GEOF ;EOF + INC TLP ;BUMP POINTER + DEC TLCNT1 ;RUN OUT OF CHARS? + BEQ TLRD1 ;YES + CMP TLP,#TLEND ;OR REACHED END OF BUFFER? + BHIS TLRD1 ;YES +TLRD2: BIC #177600,R0 ;FLUSH LH + RTS PC + +TLRD1: MOV #GCHARN,GCHARD ;SETUP NORMAL TEXT INPUT + BR TLRD2 ;RETURN LAST CHAR + +GEOF1: TST (SP)+ ;POP PC OFF STACK +GEOF: TST (SP)+ ;POP PC OFF STACK + JMP CHEOF ;TRAP TO EOF ROUTINE AT LINE LEVEL + +TWAIT: MOV #LAMBDA,TIMER ;SETUP TIMER + TST DIHDR ;TEST FOR CHANNEL CLOSED + BGE GEOF1 ;10 CLOSED CHNL ON US +TW1: TST (R0) ;READY YET? + BGT GRF1 ;YES, GO TO IT + TST TIMER ;TIMER TIMED OUT? + BLT TW1 ;NOPE, CHECK SOME MORE + TST DBSW ;DEBUGGING? + BNE TW1 ;YES, BE PATIENT +TIMOUT: JMP ABORT ;ABORT THIS ABORTION + +PNUM: MOV @PNPT,R0 ;PICK UP CHAR OF PAGE NUMBER + BEQ PNUM1 + INC PNPT + INC PNPT ;INCREMENT TO NEXT WORD IN PNBUFF + BIC #177600,R0 + RTS PC + +PNUM1: MOV PGCHAR,GCHARD ;RESTORE OLD SOURCE OF CHARACTERS + BR GCHAR ;GO USE IT + +HDRS: DEC HCNT1 ;COUNT OF HEADER LINE OUT? + BLT HDRS1 ;YUP + MOVB @HPTR,R0 ;PICK UP CHARACTER + INC HPTR ;BUMP POINTER + BIC #177600,R0 ;CLEAR LEFT HALF + RTS PC + +HDRS1: MOV HGCHAR,GCHARD ;SETUP OLD SOURCE OF CHARACTERS + mov hsfont,font ;restore text font after header line + BR GCHAR ;AND GO USE IT. + ;MAIN LINE SETUP, PROCESSES TEXT STRING +;INTO ACCT TABLE + +LSETUP: MOV #TLBUF,TLP ;RESET TEXT LINE BUFFER POINTER + CLR TLCNT ;CLEAR COUNT OF CHARS ON THIS LINE + CLR SEPER ;CLEAR OUT INTER-CHAR SPACING + CLR SKPCNT ;RESET LINES FIRM IDEA OF WHERE IT SHOULD GO + CLR SKSL ;RESET # LINES SKIP PRIOR TO CHARS OF THIS KSET + MOV FONT,R4 ;FONT INDEX INTO R4 + mov r4,blfont ;save font at line beginning in case of backup + MOV VSP,RVSP ;SETUP DEFAULT SPACING AFTER THIS LINE + MOV HEIGHT(R4),CHRRCT ;SETUP INITIAL CHAR HEIGHT + MOV BASE(R4),BASEL ;SETUP INITIAL BASE LINE + MOV #ACCT,R2 ;INDEX TO ACCT TABLE IN R2 + MOV LFTMAR,BITPOS ;SET LEFT MARGIN + MOV LFTMAR,STUBIT ;SET START OF UNDERLINE DEFAULT +CH1: CMP R4,#2*MAXFNT + BLO 1$ + BPT +1$: JSR PC,GCHAR ;MAIN CHAR PROC. LOOP + ASL R0 ;WORD QUANTITY + MOV R0,R1 + TST (R1)+ ;MAKE 177 => 0 + BIC #177400,R1 ;CLEAR OUT OVERFLOW BIT + CMP R1,#34 ;<15+1>_1 + BLE CTBLD ;DISPATCH ON CHARS 177, AND 0-15 +CH2: MOV FNTBLS(R4),R1 ;FONT OFFSET + CHAR CODE + BEQ CH1 ;BRANCH IF FONT DISPATCH DOES NOT EXIST + ADD R1,R0 + MOV (R0),R0 + beq ch1 ;null char table entry + MOVB (R0)+,R1 ;PICK UP "BEFORE" POSITION ADJUST + NEG R1 + ADD BITPOS,R1 ;ADD IN CURRENT POSITION + BLT CH4 ;CHAR BEFORE BEG OF LINE + MOV R1,MQ ;SAVE AWAY INITIAL POSITION OF THIS CHAR + MOV #20,DIV ;DIVIDE IT BY 20 + MOV R1,BITPOS ;BITPOS IS A GOOD TEMP + MOV 1(R0),R1 ;GET "AFTER" CHAR ADJ + ADD BITPOS,R1 ;ADD IN POSITION + ADD SEPER,R1 ;ADD IN INTER CHAR SEPERATION + MOV R1,BITPOS + MOV MQ,R3 ;# WDS OFFSET FROM BEG OF S.L. + ASL R3 ;CONVERT TO WD ADR + MOVB (R0)+,R1 ;GET NUMBER OF WORDS PER ROW + MOVB R1,ACCTNW(R2) ;SAVE IN ACCT TABLE FOR SCAN LINE SCAN + BEQ CH1 ;NO WORDS, NUL CHARACTER + tst (r0)+ + ASL R1 ;WORD QUANTITY + ADD R3,R1 ;WORD OFFSET AT END OF SCAN FOR THIS CHAR + CMP R1,#IMWDSZ*2 ;OVER THE END? + BHIS CH1 ;YES, IGNORE + MOV R3,ACCTWD(R2) ;SAVE WORD OFFSET FROM BEG OF S.L. + MOVB AC,ACCTBT(R2) ;BIT OFFSET + MOV (R0),R3 ;TOP LINE OFFSET + ADD SKSL,R3 ;OFFSET OF TOP LINE DUE TO FONT SWITCHING, SUPERSCRIPT + BNE CH3 ;ZERO OFFSET, SETUP POINTERS AND HEIGHT FOR FIRST PASS + MOV 2(R0),(R2) ;LOAD -HEIGHT INTO ACCT TABLE + ADD #4,R0 ;SKIP OVER SKIPS,HEIGHT + MOV R0,ACCTPT(R2) ;POINTER TO FONT TABLE + ADD #10,R2 ;INDEX TO NEXT ACCT ENTRY + CMP R2,#ACCTMX ;OVERFLOW OF ACCT TABLE? + BLO CH1 ;NO, CONTINUE +ACCTOV: CLR (R2)+ ;INSERT END TEST IN ACCT + CLR (R2)+ + CLR (R2)+ + CLR (R2)+ + MOV #BITSNK,R2 ;SETUP R2 TO R0 BIT SINK + BR CH1 + +CH3: MOV R3,(R2) ;SKIP COUNT INTO ACCT + MOV R0,ACCTPT(R2) ;POINTER TO FONT TABLE + ADD #10,R2 ;INDEX TO NEXT ACCT ENTRY + CMP R2,#ACCTMX + BLO CH1 + BR ACCTOV + +CH4: MOV 1(R0),R1 ;AFTER CHAR ADJUST + ADD SEPER,R1 ;INTER CHAR SPACING + ADD R1,BITPOS ;FIDDLE BIT POSITION + BR CH1 ;BACK FOR MORE CHARS + CTBLD: JMP @CTBL(R1) + +CTBL: CHESC ;177 + CH1 ;0, IGNORE + CH2 ;1 NORM + CH2 + CH2 + CH2 + CH2 + CH2 + CH2 + CHBS ;10 BACKSPACE + CHTB ;11 TAB + CHLF ;12 + CH2 ;13 NORM + CHFF ;14 FEED THOSE FORMS + CHCR ;15 RETURN THOSE CARRIAGES + +CHESC: JSR PC,GCHAR + ASL R0 ;WORD QUAN + MOV R0,R1 + TST (R1)+ ;177 => 0 + BIC #177400,R1 ;CLEAR OVERFLOW BIT + CMP R1,#34 + BGT CH2 + JMP @CHTB1(R1) + +CHTB1: CH2 ;177, NORM + CH2 ;0, NORM + ESC1 ;XGP ESCAPE 1 + ESC2 ;XGP ESCAPE 2 + ESC3 ;XGP ESCAPE 3 + ESC4 ;XGP ESCAPE 4 + CH1 ;5 + CH1 ;6 + CH1 ;7 + CH2 ;10 (BACKSPACE) NORM + CH2 ;11 (TAB) NORM + CH2 ;12 (LF) NORM + CH1 ;13 IGNORE + CH2 ;14 NORM (FF) + CH2 ;15 (CR) NORM + +CHBS: MOV FNTBLS(R4),R1 + BEQ CH1A ;BRANCH IF FONT DISPATCH DOES NOT EXIST + ADD #40*2,R1 ;CODE FOR SPACE + MOV (R1),R1 ;CHARACTER DEFINITION + beq ch1a ;no space character in this font + MOVB (R1),R0 ;BEGINING ADJUST FOR SPACE + MOV 2(R1),R1 ;FINAL ADJUST FOR SPACE + SUB R0,R1 ;DIFFERENCE + ADD SEPER,R1 + SUB R1,BITPOS ;BACK UP + BGE CH1A + CLR BITPOS ;CHECK END OF LINE +CH1A: JMP CH1 + + CHTB: MOV FNTBLS,R1 ;USE WIDTH OF SPACE OF FONT 0 FOR TABBING CALCULATION + BEQ CHTAB1 ;FONT DISPATCH EXIST? + ADD #40*2,R1 ;CODE FOR SPACE + MOV (R1),R1 ;PICK UP CHARACTER DEF + BEQ CHTAB1 ;SPACE EXIST? + MOVB (R1),R0 ;WIDTH OF SPACE, CURRENT FONT + mov 2(R1),R1 ;after adjust + SUB R0,R1 ;AFTER ADJUST - BEFORE ADJUST +CHTB0: ADD SEPER,R1 ;ADD IN INTER CHAR SPACING + ADD R1,BITPOS ;SPACE AT LEAST 1 SPACE WORTH + ASL R1 + ASL R1 + ASL R1 + MOV BITPOS,MQ + SUB LFTMAR,MQ ;TABS TAB 8 FROM THE LEFT MARGIN! + MOV R1,DIV + TST AC + BEQ CH1A + SUB AC,R1 + ADD R1,BITPOS ;ADD REMAINDER OF BITPOS/<8*SPACEWIDTH> TO BITPOS + BR CH1A ;IGNORE OTHERWISE + +CHTAB1: MOV #20,R1 ;FONT 0 SPACE DOES NOT EXIST, DREAM UP A SPACE WIDTH + BR CHTB0 + +CHCR: MOV LFTMAR,BITPOS + BR CH1A + +CHEOF: INC EOFF ;END OF FILE, SIMULATE FORM FEED +CHFF: INC PAGEN ;NEW PAGE, INC PAGE NUMBER + CLR PPN ;FORM FEED, CLR GENERATED DECIMAL PAGE # + INC FFF ;CAUSE FORM FEED AFTER THIS LINE +CHLF: CMP R2,#ACCT ;ANY CHARACTERS PUT OUT ON THIS LINE? + BEQ CHLFQ ;NOPE, DO A QUICK LINE FEED + CLR QFF ;QUICK FORM FEED FLAG (NO OTHER CHARS ON LINE) + CLR LFF ;DONT DO ONE + CLR (R2)+ ;LINE FEED, SETUP END CONDITION IN ACCT, + CLR (R2)+ + CLR (R2)+ + CLR (R2)+ + RTS PC ;AND RETURN TO HACK THE SCAN LINES + +CHLFQ: MOV FFF,QFF ;SETUP QUICK FORM FEED FLAG IF NEEDED + INC LFF ;QUICK LINE FEED FLAG + RTS PC ;RETURN + ESC1: JSR PC,GCHAR ;GET ESCAPE CODE + CMP R0,#20 ;<20? + BLT FONTSW ;YES, ITS A FONT SWITCH + SUB #40,R0 ;NO OTHER ESCAPES TILL 40 + BLT CH1B ;IGNORE OTHERS + CMP R0,#ESC1TL/2 + BHIS CH1B ;IGNORE ILLEGAL CODES + ASL R0 ;GET WORD ADR + JMP @ESC1T(R0) ;DISPATCH + +ESC1T: COLSEL ;40 XGP COLUMN SELECT + UNDER ;41 ! UNDERLINE + LINSPC ;42 " VARIABLE LENGTH LINE FEED + BALADJ ;43 # ABSOLUTE BASE LINE ADJUST + PPAPN ;44 $ PRINT PAPER PAGE NUMBER + AHEAD ;45 % GOBBLE AND PRINT HEADER LINE + STUND ;46 & START UNDERLINE + STPUND ;47 ' STOP UNDERLINE + SEPERS ;50 ( SET INTER-CHAR SPACING + STPUNV ;51 ) VARIABLE NUMBER OF SCAN LINE STOP UNDERLINE + RBLADJ ;52 * RELATIVE BASE LINE ADJUST + RBLUSC ;53 + RELATIVE BASE LINE UNDERLINE +ESC1TL==.-ESC1T + +PPAPN: MOV GCHARD,PGCHAR ;SAVE OLD SOURCE OF CHARACTERS + MOV #PNUM,GCHARD ;SETUP SOURCE OF PAGE NUMBER ROUTINE + PUSH R0 + MOV #PNBUFF,R0 + MOV R0,PNPT ;POINTER TO BEG OF PAGE NUMBER + MOV PAGEN,MQ ;DECIMAL PRINT INTO (R0) + JSR PC,DECPN1 + MOV PPN,MQ + BEQ PPAPN1 ;IF ZERO, DONT PRINT . OR NUMBER + MOV #'.,(R0)+ + JSR PC,DECPN1 +PPAPN1: CLR (R0)+ ;END TEST IS ZERO WORD + POP R0 + BR CH1B + +AHEAD: INC HEADRF ;SET HEADER EXISTS FLAG + JSR PC,GCHAR ;GET COUNT OF NUMBER OF BYTES + MOV R0,HCNT ;SAVE COUNT + MOV R0,HCNT1 ;SAVE IN TEMPORARY COUNT + MOV #HBUF,HPTR ;SETUP POINTER TO HEADER BUFFER +HD1: DEC HCNT1 ;RUN OUT OF BYTES? + BLT CH1B ;YES + JSR PC,GCHAR ;GET NEXT CHAR FOR HEADER LINE + MOVB R0,@HPTR ;SAVE IN HEADER BUFFER + INC HPTR ;BUMP HEADER POINTER + BR HD1 ;BACK FOR NEXT BYTE OF HEADER + + +DECPN1: MOV #10.,DIV + MOV AC,-(SP) + ADD #'0,(SP) + TST MQ + BEQ DECPN2 + CLR AC + JSR PC,DECPN1 +DECPN2: POP (R0)+ + RTS PC + FONTSW: CMP R0,#MAXFNT ;> MAX FONT #? + BGE CH1B ;YES + ASL R0 ;CONVERT TO WORD ADDRESS + MOV R0,R4 ;SETUP R4 CORRECTLY + MOV R4,FONT ;SAVE AWAY FOR INTER-LINE RESTORATION + CMP R2,#ACCT ;WRITTEN ANY CHARS YET ON THIS LINE? + BEQ FONT1 ;NO, JUST CLOBBER CHRRCT AND BASEL + MOV BASE(R4),R0 ;PICK UP NEW BASE + CMP R0,BASEL ;COMPARE WITH OLD BASE LINE + BLE FONTSM ;SMALLER FONT, SET SKSL + SUB BASEL,R0 ;GET # LINES WE NEED TO PUSH THIS LINE + JSR PC,PUSHL ;DOWN BY +FONT2: MOV HEIGHT(R4),R0 ;HEIGHT OF NEW FONT + ADD SKSL,R0 ;PLUS LINES SKIPPED BEFORE IT + CMP R0,CHRRCT ;HAD BETTER BE LESS THAN CHRRCT + BLE CH1B ;OK + MOV R0,CHRRCT ;MAKE IT SO +CH1B: JMP CH1 + +FONTSM: MOV BASEL,SKSL + SUB R0,SKSL ;SKIPS=BASEL-BASE(FONT) + BR FONT2 ;CHECK DECSENDING DIRECTION + +FONT1: MOV BASE(R4),BASEL ;NO CHARS YET, JUST CLOBBER BASEL, CHRRCT,SKSL + MOV HEIGHT(R4),CHRRCT + CLR SKSL + BR CH1B + +;ABSOLUTE BASE LINE ADJUST + +BALADJ: JSR PC,GCHAR ;GET AMOUNT + ASL R0 + MOV R0,TEMP + MOVB TEMP,R0 + ASR R0 + MOV BASEL,R1 ;BASE LINE + SUB BASE(R4),R1 ;SKIPS FOR THIS FONT (UNADJUSTED) + SUB R0,R1 ;NEW SKIP COUNT + BLT SUPER ;NEGATIVE, WE WENT OFF THE TOP +BALAD1: MOV R1,SKSL ;OK, SETUP SKIP COUNT + BR FONT2 ;AND CHECK WE DONT RUN OUT OF SCAN LINES AT BOTTOM + +SUPER: NEG R1 ;COUNT OF LINES TO PUSH DOWN + MOV R1,R0 + JSR PC,PUSHL ;PUSH IT + BR FONT2 ;CHECK FOR DESCENDING CHARS + +;RELATIVE BASE LINE ADJUST + +RBLADJ: JSR PC,GCHAR + ASL R0 ;CHARACTER IS 7-BIT SIGNED INTEGER + MOV R0,TEMP + MOVB TEMP,R0 ;USE SIGN EXTEND FEATURE OF MOVB TO ACCUMULATOR + ASR R0 + SUB R0,SKSL + MOV SKSL,R1 + BPL FONT2 + BR SUPER + PUSHL: CLR SKSL ;IT MUST BE 0 OR WE WOULDNT BE HERE + ADD R0,BASEL ;CLOBBER BASEL DOWN SOME + ADD R0,CHRRCT ;AND EXPAND CHRRCT + MOV R2,R2PL + MOV R3,R3PL + MOV #ACCT,R2 ;POINTER TO SKIP/COUNT FIELD +PUSH1: CMP R2,R2PL ;TEST DONE WITH LINE SO FAR + BHIS PX + MOV (R2),R3 ;GET SKIP/HEIGHT + BLT PUSH3 ;HEIGHT WAS SETUP + BEQ SPAZ ;THIS SHOULDNT HAPPEN + ADD R0,R3 ;ADD SKIP COUNT TO CHAR + MOV R3,(R2) ;PUT IT BACK +PUSH2: ADD #8,R2 ;NEXT ENTRY IN ACCT + BR PUSH1 + +PUSH3: MOV R0,(R2) ;SKIP COUNT WAS REALLY 0, CLOBBER IN THE NEW ONE + SUB #4,ACCTPT(R2) ;BACKUP THE FONT POINTER + BR PUSH2 + +SPAZ: JSR PC,ERROR + +PX: MOV R2PL,R2 ;RESTORE R2 + MOV R3PL,R3 ;RESTORE R3 + RTS PC + COLSEL: JSR PC,GCHAR ;GOBBLE HI ORDER BYTE + SWAB R0 + ASR R0 ;ITS ONLY 7 BITS + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 ;OR IN THE LOW ORDER BYTES + MOV R0,BITPOS ;JUMP AWAY TO THE NEW LINE POS + BR CH1C + +STUND: MOV BITPOS,STUBIT ;SAVE AWAY SPOT TO START UNDERLINING +CH1C: JMP CH1 + +STPUND: MOV #1,ULCNT ;ONE LINE OF UNDERLINEAGE + BR STPUN1 + +STPUNV: JSR PC,GCHAR ;MULTIPLE UNDERLINE COMMAND + MOV R0,ULCNT ;VARIABLE NUMBER OF UNDERLINE LINES +STPUN1: MOV STUBIT,OSTBT ;SAVE OLD START UNDERLINE + JSR PC,GCHAR + MOV R0,ULSL ;SCAN LINE TO UNDERLINE ON + MOV BITPOS,STPL ;LENTH OF UNDERLINE + SUB SEPER,STPL ;SUBTRACT INTER CHARACTER SPACING + SUB STUBIT,STPL + BGE STPUN2 ;ABS VALUE + NEG STPL ;WIN FOR STOPPING BEFORE YOU START + MOV BITPOS,STUBIT +STPUN2: MOV ULSL,SVULSL ;SAVE ULSL IN CASE WE LOOP BACK FOR MORE THAN ONE UNDERLINE + BR UNDERL + +;RELATIVE BASELINE UNDERSCORE, SAME AS UNSER, BUT ADDS THE ADJUSTED BASELINE +RBLUSC: JSR PC,UNDER1 ;GET PARAMETERS + MOV ULSL,R0 ;GET THE UNDERLINE LINE + BIT #100,R0 ;POSITIVE OR NEGATIVE? + BNE RBLUS1 ;NEGATIVE, MAKE IT FULL WORD + BIC #177600,R0 ;CLEAR OUT ANY STRAY BITS +RBLUS2: SUB BASEL,R0 ;TURN IT INTO BASELINE ADJUSTED FROB + ADD SKSL,R0 + ADD BASE(R4),R0 ;ADJUST BASELINE + MOV R0,ULSL ;AND THIS IS THE LINE TO UNDER LINE ON + BR UND2 +RBLUS1: BIS #177600,R0 ;TURN IT NEGATIVE + BR RBLUS2 + +UND1: BIS #177600,R0 ;SET TO NEGATIVE NUMBER + BR UND2 ;BRANCH BACK + +UND3: NEG R0 ;MAKE R0 POSITIVE COUNT OF LINES TO PUSH DOWN + ADD R0,SKSL + PUSH SKSL ;SAVE SKIP COUNT, WE ARE NOT REALLY CHANGING FONTS + JSR PC,PUSHL ;SHOVE IT + POP SKSL ;RESTORE SKIP COUNT + CLR R0 ;UNDERLINE ON SCAN LINE ZERO + BR UND4 +UNDER1: MOV STUBIT,OSTBT ;SAVE START OF UNDERLINE + JSR PC,GCHAR + MOV R0,ULSL + JSR PC,GCHAR + SWAB R0 + ASR R0 + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + MOV R0,STPL + MOV BITPOS,STUBIT + MOV #1,ULCNT ;ONE UNDERLINE ONLY + MOV ULSL,SVULSL ;SAVE AWAY ULSL (NOT REALLY NECESSARY, BUT... + RTS PC + +UNDER: JSR PC,UNDER1 +UNDERL: MOV STUBIT,R0 + CMP R0,#NBITS ;STARTING PAST END OF LINE? + BHIS CH1C ;YES, TOTALLY IGNORE + ADD STPL,R0 ;ENDING LOCATION + CMP R0,#NBITS ;ENDING OFF END OF LINE? + BLO UND5 ;NO, DO IT + MOV #NBITS,STPL + SUB STUBIT,STPL +UND5: MOV ULSL,R0 ;PICK UP CHAR FOR SCAN LINE NUMBER + BIT #100,R0 ;POSITIVE OR NEGATIVE? + BNE UND1 ;NEGATIVE, MAKE IT FULL WORD + BIC #177600,R0 ;CLEAR OUT ANY STRAY BITS +UND2: TST STPL + BEQ CH1D + ADD BASEL,R0 ;RELATIVE TO BASELINE + ADD ULOFF,R0 ;PLUS KLUDGY OFFSET TO MAKE TJ6 HAPPY + BLT UND3 + CMP R0,CHRRCT + BLT UND4 ;OK, WITHIN EXISTING LINE + MOV R0,CHRRCT ;EXPAND LINE ENOUGH FOR THIS UNDERLINE + INC CHRRCT +UND4: MOV R0,ULSL ;SETUP SCAN LINE NUMBER TO WIN ON + MOV R4,ULR4 ;SAVE FONT POINTER + MOV STUBIT,MQ + MOV #20,DIV + MOV MQ,R0 + ASL R0 + MOV R0,ACCTWD(R2) + MOVB AC,ACCTBT(R2) + MOV STPL,MQ + MOV #20,DIV ;GET # WORDS OF UNDERLINEAGE + MOV MQ,R0 + MOV AC,R1 + BIC #177600,R0 ;PARANOIA, CLEAR OUT ENUF BITS TO MAKE BYTE POS + BEQ UL1 ;NO WORDS, MAYBE SOME BITS + MOV #ONES,R4 + MOV ULSL,R3 + BNE UL2 ;SETUP HEIGHT ON FIRST LINE + ADD #4,R4 ;SETUP POINTER TO FONT BITS + DEC R3 ;0=> -1 WHICH IS HEIGHT OF UNDERLINE +UL2: MOV R3,(R2) ;SETUP SCAN LINE NUMBER + MOVB R0,ACCTNW(R2) ;SETUP # WORDS OF ONES + MOV R4,ACCTPT(R2) ;POINTER TO ONES + ADD #10,R2 ;INDEX TO NEXT ACCT ENTRY + TST R1 + BEQ UL5 ;NO STRAY BITS, EXIT + CMP R2,#ACCTMX ;OVERFLOW ACCT? + BHIS ACTOVU + ADD STPL,STUBIT ;FINAL POSITION + SUB R1,STUBIT ;FINAL POSITION AFTER END OF WHOLE WORDS + MOV STUBIT,MQ ;CONVERT TO WORD+BIT OFFSET INTO S.L. + MOV #20,DIV + MOV MQ,R0 + ASL R0 + MOV R0,ACCTWD(R2) + MOVB AC,ACCTBT(R2) +UL1: MOV R1,R4 ;PICK UP CHAR OF N BITS OF ONES + ASL R4 ;CONVERT TO WORD ADDRESS + ADD R1,R4 ;3 WDS/ENTRY IN CHAR TABLE + ASL R4 + ADD #ULTBL,R4 ;ORIGIN OF TABLE OF "CHARS" WITH BITS ON + MOV ULSL,R3 + BNE UL3 + DEC R3 ;0 => -1 (HEIGHT) + ADD #4,R4 ;SKIP OVER SKIPS,HEIGHT +UL3: MOV R3,(R2) ;COUNT FIELD + MOVB #1,ACCTNW(R2) ;ONE WORD ONLY + MOV R4,ACCTPT(R2) + ADD #10,R2 ;INDEX TO NEXT ACCT ENTRY +UL5: MOV ULR4,R4 + MOV OSTBT,STUBIT ;RESTORE START OF UNDERLINE + CMP R2,#ACCTMX ;OVER FLOW ACCT? + BLO UL6 +ACTOVU: MOV ULR4,R4 + JMP ACCTOV + +SEPERS: JSR PC,GCHAR ;GET INTER CHAR SPACING + MOV R0,SEPER +CH1D: JMP CH1 + +UL6: DEC ULCNT ;MORE LINES? + BLE CH1D ;NOPE, DONE + INC SVULSL ;NEXT LOWER SCAN LINE + MOV SVULSL,ULSL + JMP UNDERL ;BACK FOR MORE, FANS + +LINSPC: JSR PC,GCHAR ;GET SPACING AFTER THIS LINE + MOV R0,RVSP + JMP CHLF ;GO LINE FEED + +ESC2: JSR PC,GCHAR ;GET RELATIVE COLUMN SELECT + CMP R0,#100 ;POS OR NEG? + BGE SUBCOL ;NEG, SUBTRACT + ADD R0,BITPOS ;ADD IT IN + BR CH1D + +SUBCOL: BIS #177700,R0 ;MAKE IT NEGATIVE # + ADD R0,BITPOS ;ADD IT IN + BGE CH1D ;IF POS, RETURN + CLR BITPOS ;OTHERWISE, CLEAR IT TO ZERO + BR CH1D + +ESC3: JSR PC,GCHAR ;GET VERTICAL POSITION FOR THIS LINE + SWAB R0 + ASR R0 ;7 BITS ONLY + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + CMP R0,TVPOS ;POS HAD BETTER BE AFTER THIS + ;CURRENT LINE POSITION, OR HE LOSES + BLE CH1D + SUB TVPOS,R0 ;FIND DIFFERENCE + MOV R0,SKPCNT ;CAUSE THAT MANY SKIPS BEFORE THIS LINE + BR CH1D + + ESC4: JSR PC,GCHAR + SWAB R0 + ASR R0 + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + MOV R0,Y0 + JSR PC,GCHAR + SWAB R0 + ASR R0 + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + MOV R0,X0 + JSR PC,GCHAR + SWAB R0 + ASR R0 + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + MOV R0,R1 + ASR R0 + ASR R0 + CLR DXS + BIT #4000,R0 + BEQ DXSC + INC DXS +DXSC: BIC #4000,R0 + MOV R0,DXI + BIC #177774,R1 + SWAB R1 + ASR R1 + MOV R1,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + MOV R0,DXF + JSR PC,GCHAR + SWAB R0 + ASR R0 + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + MOV R0,VN + JSR PC,GCHAR + SWAB R0 + ASR R0 + MOV R0,TEMP + JSR PC,GCHAR + BIS TEMP,R0 + MOV R0,VW + JSR PC,ADVECT ;ADD VECTOR TO THE DATA BASE + JMP CH1 + XGPDON: PUSH R0 + TST XCR + BLT XGPERR ;SIGN BIT OF XCR IS ERROR FLAG +XGPD1: MOV SBPI,R0 ;POINTER TO INTERRUPT SCAN LINE BUFFERS + CLR @OBUF ;INDICATE OLD BUFFER NOW EMPTY + MOV R0,OBUF ;SAVE POINTER TO NEW BUFFER + INC VPOS ;INC INTERRUPT COUNT + TST (R0) ;EMPTY? + BLE EMPTY ;YES, OR CUT + CMP (R0)+,VPOS ;REACHED PLACE FOR THIS LINE YET? + BLT XGPMIS ;BIT THE BAG, TRY TO RECOVER BEST AS POSS + BGT NULLIN ;NOPE, SEND R0 NULL LINE +XGPC: MOV (R0)+,SBPI ;ADVANCE POINTER + MOV R0,MAR ;SETUP POINTER TO SCAN LIEN +XGPX: MOV #FDIE+FGO+FMOT,XCR ;STARTER UP + POP R0 + RTI + +XGPERR: MOV XSR,R0 + BIS R0,XGPE + BIT #FRDYC,R0 ;READY CHANGED? + BEQ XGPD1 ;NOPE, IGNORE ERROR + BIT #FRDY,R0 ;READY UP? + BNE XGPD1 ;READY REALLY STILL UP ANYWAY + JMP ABORT ;WE REALLY JUST LOST READINESS + +XGPMIS: MOV -2(R0),VPOS ;PRETEND WE DIDNT LOSE THIS LINE + BR XGPC ;CONTINUE (FORGE AHEAD) + + +EMPTY: BLT CUTR ;NEGATIVE, CUT OR EOF +NULLIN: MOV #BNULL,MAR ;SETUP NULL LINE + MOV #ITEMP,OBUF ;JUNK LOCATION TO BE CLEARED ON NULL LINE + BR XGPX + +CUTR: MOV (R0)+,ITEMP + BIC #100000,ITEMP + BEQ EOFI ;END OF FILE IF CUT AT PAGE LOC 0 + CMP ITEMP,VPOS ;REACHED CUT PAGE LOCATION? + BGT NULLIN ;NOPE, WAIT WITH BLANK LINES + CLR VPOS ;JUST CUT, RESET INTERRUPT POSITION + PUSH R1 + MOV MKTOCT,R1 + JSR PC,CUTCLK ;CUT WHEN THIS LINE GETS TO CUTTER + POP R1 + MOV (R0),SBPI ;ADVANCE BUFFER POINTER + BR XGPD1 ;GET NEXT BUFFER ON NEW PAGE + +EOFI: CLR XCR ;STOP THE WORLD + INC XGPFIN ;SET DONE FLAG + POP R0 + RTI + CLKBRK: INC TICKS + BVC CLKB1 + INC TICKS1 +CLKB1: INC TIMER + PUSH R0 + MOV #CLKQS,R0 +CLKB3: TST (R0)+ + BEQ CLKB2A + DEC -(R0) + BNE CLKB2 + MOV #FCUTI,XCUT ;ACTIVATE CUTTER BAR +CLKB2: TST (R0)+ +CLKB2A: CMP R0,#CLKQS+<2*NCLKQS> + BLO CLKB3 +CUTX: POP R0 + RTI + +;HERE TO QUEUE CUT REQUEST +;R1 HAS # 60THS BEFORE CUT HAPPENS + +CUTCLK: TST AUTCUT ;ARE WE SUPPOSED TO CUT? + BEQ CUTX1 ;NO + PUSH R0 + MOV #CLKQS,R0 ;LOOP LOOKING FOR IDLE CLOCK QUEUE BLOCK +CUT1: TST (R0)+ ;FREE? + BEQ CUT2 ;YES + CMP R0,#CLKQS+<2*NCLKQS> ;END TEST + BLO CUT1 ;LOOP +CUTX1A: POP R0 +CUTX1: RTS PC + +CUT2: MOV R1,-(R0) + BR CUTX1A + + +IDLE: 0 ;0 => NOT WAITING FOR MAIN PDP10 COMMAND +ITEMP: 0 ;TEMPORARY AT INTERRUPT LEVEL (XGP) +TEMP: 0 ;MAIN PROG TEMP + +lbadj: 0 ;temp for before adjust in loading fonts +laadj: 0 ;temp for after adjust in loading fonts +lwdspr: 0 ;temp for words/row in loading fonts +LKOVRF: 0 ;BUFFER OVERFLOW WHILE LOADING CHARACER FLAG +FONT: 0 ;INDEX TO CURRENT FONT, FOR INTERLINE HACKING + ;SINCE THIS IS IN R4 DURING LINE SCAN +blfont: 0 ;storage for font at beginning + ;of this line for use in backup after page length exceeded +hsfont: 0 ;storage for font before header line + ;started, used to restore after header over +SKPCNT: 0 ;SKIPPED LINE COUNT BETWEEN TEXT LINES (# TOTALLY BLANK LINES) +BASEL: 0 ;NUMBER OF SCAN LINES DOWN THE BASE LINE FOR THIS TEXT LINE IS +CHRRCT: 0 ;TOTAL NUMBER OF SCAN LINES WITH BLACKNESS ON IN THIS + ;TEXT LINE +SKSL: 0 ;NUMBER OF SCAN LINES SKIPPED BEFORE OUTPUTTING CHARACTERS + ;IN THE CURRENT FONT. NON ZERO ONLY AFTER FONT SWITCH + ;OR UPWARDS THEN DOWNWARDS BALADJ +BITPOS: 0 ;BIT POSITION WE ARE ABOUT TO OUTPUT THE + ;NEXT CHARACTER INTO +TVPOS: 0 ;MAIN PROGRAM IDEA OF VERTICAL PAGE POSITION +VPOS: 0 ;INT LEVEL VERT PAGE POSITION + +SEPER: 0 ;INTER CHARACTER SPACING (RESET AT END OF LINE) + +OSTBT: 0 ;SAVED STUBIT FOR WITHIN UNDERLINE ROUTINE +STUBIT: 0 ;SAVED LOCATION FROM "START OF UNDERLINE" +ULSL: 0 ;SCAN LINE WE ARE UNDERLINNG ON +SVULSL: 0 ;PLACE TO SAVE ULSL DURING MULTIPLE UNDERLINES +STPL: 0 ;LENGTH IN BITS OF AN UNDERLINE COMMAND +ULCNT: 0 ;COUNT OF NUMBER REMAINING UNDERLINES IN MULTIPLE UNDERLINE MODE +AUTCUT: 0 ;0=> NO CUTTING ON THIS FILE +VSP: 0 ;DEFAULT INTERLINE SPACING (BASE LINE TO BASE LINE) +RVSP: 0 ;REAL VSP FOR THIS LINE (CHANGED BY VARIABLE LF) +OVSP: 0 ;SAVE RVSP FROM THE PREVIOUS LINE (USED TO + ;CALCULATE SKPCNT) +OLLOW: 0 ;AMOUNT THE PREVIOUS TEXT LINE DESCENDED BELOW ITS BASE LINE + ;USED TO CALCULATE SKPCNT +EOFF: 0 ;END OF FILE FLAG (SET BY GCHAR)(EXAMINED NEAR TLINE) +BSLC: 0 ;COUNT OF BLACK SCAN LINES THIS PAGE + ;USED TO IGNORE TOTALLY BLANK PAGES +QFF: 0 ;QUICK FORM FEED FLAG CAUSES NO ATTEMPT + ;TO BE MADE TO PRINT THIS STUFF SINCE ITS BLANK ANYWAY +LFF: 0 ;SET IF THIS TEXT LINE HAS NO PRINTING CHARS + ;CAUSES THE TLINE STUFF TO SKIP OVER THE LINES IN QUESTION +GCHARD: 0 ;DISPATCH FOR SOURCE OF TEXT CHARACTERS +TLCNT: 0 ;COUNT OF CHARS ON THIS LINE SO FAR +TLCNT1: 0 ;TEMPORARY COUNT USED IN TLRD BECAUSE TLCNT IS CLOBBERED AT LSETUP +TLP: 0 ;POINTER TO BYTE WHERE NEXT CHAR IN TEXT LINE + ;WILL BE BUFFERED IN CASE OF RESCAN AT BOTTOM OF PAGE +TLBUF: .=.+1000 ;BYTE BUFFER TO STORE LAST TEXT LINE +TLBND==.-2 ;LIMIT OF TEXT LINE BUFFER +TLEND: 0 ;EXTRA LOCATION FOR OVERFLOW OF TLBUF + +PGCHAR: 0 ;SAVED GCHARD WHILE IN PNUM INPUT ROUTINE +PAGEN: 0 ;PAGE NUMBER WE ARE ON (INC AT FF ONLY) +PPN: 0 ;NUMBER OF PAGES GENERATED (IE WITHOUT FORM FEEDS IN THE TEXT) +PNPT: 0 ;POINTER TO PNBUFF DURING PAGE NUMBER PRINTING +PNBUFF: .=.+30 ;BUFFER FOR PAGE NUMBER +HEADRF: 0 ;FLAG INDICATING PRESENCE OF R0 TEXT LINE HEADER +HGCHAR: 0 ;SAVED GCHARD WHILE IN HEADER LINE +HCNT: 0 ;COUNT OF BYTES IN HEADER LINE +HCNT1: 0 ;TEMP COUNT OF BYTES IN HEADER LINE WHILE IN HDRS +HPTR: 0 ;POINTER TO HEADER LINE BUFFER +HBUF: .=.+200 ;BUFFER FOR HEADER LINE (MAX 200 SINCE BYTE COUNT <177) +NPF: 0 ;FLAG INDICATING THAT LAST TEXT LINE CAUSED AN OVERFLOW FORM FEED +FFF: 0 ;FEED FORMS AFTER THIS LINE (SET BY R0 FF IN TEXT LINE) + +VLPFLG: 0 ;FLAG NON ZERO FOR VARIABLE LENGTH PAGES, TERMINATED ONLY BY FF +BOTMAR: 0 ;BOTTOM MARGIN, SCAN LINES FROM TOP +TOPMAR: 0 +LFTMAR: 0 +LPAGE: 0 ;LENGTH OF PAGE IN SCAN LINES + +XGPST: 0 ;XGP STARTED FLAG +XGPFIN: 0 ;XGP INTERRUPT LEVEL FINISHED + +SLBINI: 0 ;POINTER TO FIRST PI LEVEL BUFFER +SBNP: 0 ;POINTER TO MAIN PROG S.L. BUFFERS +SBPI: 0 ;INTERRUPT POINTER TO S.L BUFFERS +OBUF: 0 ;POINTER TO OLD INT LEVEL S.L. BUFFER USED TO SET EMPTY FLAG + +MKTOCT: 4020 ;MAGIC DISTANCE IN 60THS SEC FROM DRUM EXPOSURE TO PAPER CUTTER +CLKQS: .=.+ ;SPACE FOR NCLKQS CUT MARKS +TICKS: 0 ;LOW ORDER TIMER +TICKS1: 0 ;HIGH ORDER OF TIMER +TIMER: 0 ;SHORT TERM TIMER REGISTER + +R3PL: 0 ;SAVED R3 IN PUSHL +R2PL: 0 ;SAVED R2 IN PUSHL +ULR4: 0 ;SAVED R4 IN UNDERLINE CODE + +Y0: 0 ;Y0 OF VECTOR +X0: 0 ;X0 OF VECTOR +DXS: 0 ;SIGN OF DELTA X +DXI: 0 ;INTEGER PART OF X +DXF: 0 ;FRACTION OF DX +VN: 0 ;NUMBER OF SCAN LINES ACTIVE FOR +VW: 0 ;X WIDTH OF THE VECTOR + +CHRIDX: 0 ;TEMP IN LKSET FOR INDEX INTO CHAR TABLE +SKIPS: 0 ;COUNT OF BLANK SCAN LINES AT TOP OF CHAR +BROWS: 0 ;COUNT OF BLACK ROWS OF CHAR IN LKSET +NROWS: 0 ;TEMP FOR REMAINING HEIGHT OF CHAR IN LKSET +BOTZR: 0 ;COUNT OF ZERO LINES AT THE BOTTOM OF THIS CHARACTER BEING LOADED +ROWNZ: 0 ;COUNT OF NON ZERO WORDS IN THIS ROW OF CHAR + +FSPTR: 0 ;FREE STORAGE POINTER +ULOFF: 3 ;DOWNWARDS OFFSET OF UNDERLINES TO APOLOGIZE TO TJ6 +DBSW: 0 ;DEBUGGING SWITCH OR NOT + +ONES: 0 ;SKIPS + -1 ;NEGATIVE OF HEIGHT + REPT1 IMWDSZ,-1 ;LOTS OF ONES + +ULTBL: REPT3 20,0,-1,<<1_<.RPCNT+1>>-1> + +BNULL: .BYTE 2,0,0,1 ;NULL SCAN LINE + +HEIGHT: REPT1 MAXFNT,0 +BASE: REPT1 MAXFNT,0 +FNTBLS: REPT1 MAXFNT,0 + +IMBP: 0 ;POINTER TO NEXT PDP-10 BUFFER RING ENTRY +IMOBP: 0 ;POINTER TO CURRENT/OLD PDP-10 BUFFER RING ENTRY +IMSLP: 0 ;POINTER TO CURRENT SCAN LINE BEGINNING +IMLPOS: 0 ;SAVED LINE POSITION FOR THIS LINE + + .=.+100 ;STACK +STK: 0 + +PAT: PATCH: + .BLKW 100 +PATCHE: -1 + ;10-11 CHANNEL HEADER AREA +; 11-10 COMMUNICATIONS BUFFER SIZES +ACTCHN==3 ;ACTIVE CHANNELS + +;(CI) COMMAND INPUT CHANNEL DESCRIPTION + +CINBUF==2 ; NUMBER OF BUFFERS +CIBFL==100 ; SIZE OF BUFFER + +;(CO) COMMAND OUTPUT CHANNEL DESCRIPTION + +CONBUF==0 +COBFL==0 + +;(DI) DATA INPUT CHANNEL DESCRIPTION + +DINBUF==10 +DIBFL==300 + +;CHANNEL HEADER AREA + +.MACRO CHHDR CI +.IIF EQ CI'NBUF,CI'BF0==0 +TENWRD +CI'HDR: 0 ; STATUS BITS + ; 15 1=>CHANNEL OPEN +CI'BUF: CI'BF0 ; BUFFER RING POINTER (BUFFER BEING HACKED BY 11) +CI'NXT: 0 ; NEXT AVAILABLE BYTE +CI'CNT: 0 ; # BYTES IN BUFFER +.ENDM + +;LEAVE CONTIGUOUS AND IN THIS ORDER + +.IRP R0, +.XLIST +CHHDR R0 +.LIST +.ENDM + +.MACRO FOO1 R0,B +R0'BF'B: -1 +.ENDM + +.MACRO FOO2 R0,B + R0'BF'B +.ENDM + +;CHANNEL BUFFERS + +BHDRL==6 ; SIZE OF BUFFER HEADER AREA + +.MACRO BFRING R0,NUM,SIZE +.IF NE NUM +TENWRD +R0'BF0: -1 ; BYTE COUNT(.LT.=>FREE, .EQ.=>BUSY, .GT.=>COUNT) + R0'BF1 ; POINTS TO NEXT BUFFER ON RING + SIZE ; BUFFER SIZE IN BYTES +.=.+SIZE + +.IFL NUM-2 +.ERROR LESS THAN TWO BUFFERS SPECIFIED +.ENDC + +.IFGE NUM-2 +.REPT NUM-2 +TENWRD +FOO1 R0,\<.RPCNT+1> +FOO2 R0,\<.RPCNT+2> +SIZE +.=.+SIZE +.ENDR + +TENWRD +FOO1 R0,\ +FOO2 R0,0 +SIZE +.=.+SIZE +TENWRD +.ENDC +.ENDC +.ENDM + +BUFORG==. +.IRP R0, +.XLIST +BFRING R0,R0'NBUF,R0'BFL +.LIST +.ENDM +BUFFRL==.-BUFORG + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; LEAVE CONTIGOUS AND IN THIS ORDER SEE LK3 FOR THE REASON +TENWRD +SLB1: .=.+ ;SPACE FOR SCAN LINE BUFFERS + ;POINTER STRUCTURE SETUP AT MX1 + ;AREA USED IN LKSET FOR TEMP STORAGE +SLBND: ;BOUNDARY OF SCAN LINE BUFFER AREA +ACCT: .=.+2200;MAX OF 128 ENTRIES (PRINTING CHARS/LINE) +BITSNK: .=.+20 ;AREA FOR OVERFLOW OF ACCT TO BE SUNK INTO +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;FORMAT OF ACCT TABLE ENTRIES +;FOUR WORDS PER INK PRODUCING CHARACTER +;WD0/ IF POS, SKIP THIS NUMBER OF ROWS BEFORE STARTING +; IF NEG, THIS IS AN ASCENDING NUMBER OF ROWS LEFT IN THIS ENTRY +; IF ZERO, END OF LINE +;WD1/ WORD OFFSET INTO SCAN LINE BUFFER +;WD2/ (LOW BYTE) BIT OFFSET INTO SCAN LINE BUFFER (<17) +; (HIGH BYTE) WIDTH IN WORDS OF ROW +;WD3/ POINTER TO EITHER +; (1) HEADER OF FONT ENTRY IF WD2 RH POS +;OR (2) POINTER INTO FONT ENTRY +;INCREMENTED TO POINT TO NEW WORDS AS OLD ONES USED UP + +ACCTMX==.-20 ;LIMIT TEST FOR ACCT OVERFLOW + +;FORMAT FOR CHARACTER FONT TABLE: +;WD0 OF FONT TABLE: WDS/ROW,,BEFORE ADJUST +;WD1 AFTER CHARACTER ADJUST (FULL WORD) +;WD2 SKIP COUNT BEFORE USEFUL BITS +;WD3 NEGATIVE OF HEIGHT (NOT COUNTING SKIPPED LINES) +;WD4 ON START OF FONT BITS + +;FREE STORAGE VARIABLES + +MEMTOP: 0 ;FIRST NXM +AVAIL: 0 ;POINTS TO FIRST FREE BLOCK +ROVER: 0 ;POINTS TO HEAD OF SEARCH LIST +OLDBLK: 0 + +;FAKE BLOCK + +FAKEBL: 0 + FS+2 + FAKEBL+2 + -1 + +;FREE STORAGE + +FS=. ;FREE STORAGE STARTS HERE + + .END START