1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-23 02:48:48 +00:00
2018-07-18 16:46:29 +02:00

2131 lines
54 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

.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==<IMWDSZ+3>*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
.EXPUNGE ASH,DIV,MUL
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: .=.+<MAXFNT*2> ;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 <SKPCNT> 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: .=.+<NCLKQS*2> ;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,<CI,CO,DI>
.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,\<NUM-1>
FOO2 R0,0
SIZE
.=.+SIZE
TENWRD
.ENDC
.ENDC
.ENDM
BUFORG==.
.IRP R0,<CI,CO,DI>
.XLIST
BFRING R0,R0'NBUF,R0'BFL
.LIST
.ENDM
BUFFRL==.-BUFORG
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LEAVE CONTIGOUS AND IN THIS ORDER SEE LK3 FOR THE REASON
TENWRD
SLB1: .=.+<IMSLSZ*NSLBFS> ;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