; move comments over 1 tab	C/;/	;/
; move back 1 tab        	C/	;/;/
; find leading spaces and convert to tabs	4y5y6y
; get 24 leading	1,$c/^                        /			/4p
;      16        	1,$c/^                /		/5p
;       8         	1,$c/^        /	/6p
;
        $MACRO push this
        mov #@1,-(sp)
        $ENDM 
;
        $MACRO pop that
        mov (sp)+,#@1
        $ENDM 
;
        $MACRO save all registers
        jsr pc,saval
        $ENDM 
/
        PROGRAM Ed      ;Fill and justify routines
        mutask=1 
        .psect edi13
         
        .enabl lc
        .enabl ama
        .nlist sym
         
        .if df mutask
        .MACRO pure
        .psect pur,ro
        .ENDM 
         
        .MACRO impure
        .psect ipur,rw
        .ENDM 
        .iff 
        .MACRO pure
        .ENDM 
         
        .MACRO impure
        .ENDM 
        .endc 
         
         
        .globl nfill    ;Handle the Nf command (fill text)
        .globl hspace   ;character used as a forced space
        .globl fparms   ;5 word parm list, for display
        impure 
         
         
; - - -	 macro library calls
        .mcall dir$,callr
; - - -	 system	macros
; - - -	 local data and	symbols
;  temp:   .blkb   200.    ;temp for debugging
wordb:  .blkb     80.   ;buffer for storing a word
        ewordb=.-1      ;end of buffer
         
i:      .word           ;index
         
fparms: 				;global pointer to parm list
left:   .word 5         ;left margin
right:  .word 70.       ;right margin
indent: .word 0.        ;indent on paragraph
spaces: .word 1.        ;single, double, ...
justfg: .word 1.        ;justify flag 1=yes, 0=no
         
nlines: .word 0         ;input to spacing routine, # of lines to output
nwords: .word 0         ;word in line counter
ip:     .word           ;pointer into wordb
op:     .word           ;pointer into lbuf3 (output buffer)
nullb:  .word 0         ;this is a null word that ip initially points to
outw:   .word 0         ;out width
wwid:   .word 0         ;width of current word
         
addr:   .word           ;current addr on input
peekc:  .word           ;look ahead char
gflag:  .word           ;get char flag
adloc:  .word           ;location we are adding after
         
         
str1:   .asciz/--/ 
        .even 
         
        nl=12 
        cr=15 
        space=40 
        backspace=10            ;
        hspace=2                ;hard space, not delimeter character
        tab=11 
        comma=54 
        pure 
nfill:    
        IF zero = dot
            mov #4,r1
            jmp error
        FI 
         
         
        mov #-1,peekc
        mov #nullb,ip           ;initialize
         
	IF adr2 = #0            ;default to DOT AND allow line zero
;            mov zero,adr1
;            add #2,adr1
;            mov dol,adr2
	     mov dot,adr1
             mov dot,adr2
        FI 
        call getparms
         
        IF adr1 = zero          ;address zero is used to just set
            IF adr1 = adr2        ;the parmeters (say, from a macro)
                clr adr2           ;clear for sfacts so it dont shade
                call sfacts        ;display new parms and
                rts pc             ;return
            ELSE 
                mov #4,r1          ;but if multiple addresses and 1
                jmp error          ;of 'em is zero = bad address
            FI 
        FI 
;PRINTF #temp <dot=%o dol=%o adr1=%o adr2=%o zero=%o> dot dol adr1 adr2 zero
        mov adr1,padr1
        mov adr2,padr2
        mov adr2,adloc          ;add text after here
        mov adr1,addr           ;initialize address to get lines from
        mov #lbuf3,op           ;init
        call resetm             ;reset margins
        call brake1             ;do part of break that don't flush
        DO FOREVER
            call getwd
            BREAK IF CS
            IFB wordb = #0
                call brake
            ELSE 
                call putwd
            FI 
        OD 
        call flsh
;PRINTF #temp <b: adr1=%o adr2=%o adloc=%o dot=%o> adr1 adr2 adloc  dot
        LET addr = adloc - adr2 + adr1 - #2
        push padr1
        push padr2
        call delete
        pop padr2
        pop padr1
        mov addr,dot
;PRINTF #temp <a: adr1=%o adr2=%o adloc=%o dot=%o> adr1 adr2 adloc  dot
        IF dot HI dol
            mov dol,dot          ;but not beyond end
        FI 
         
        IF dot LOS zero
            LET dot = zero + #2
        FI 
        push adr2
        mov dot,adr2             ;for bcom1
;PRINTF #temp <zero=%o dot=%o dol=%o> zero dot dol
         
        IF smode NE #0
            call bcom1            ;redraw screen
        FI 
        pop adr2
;PRINTF #temp <padr1=%o padr2=%o  adr1=%o adr2=%o> padr1 padr2 adr1 adr2
        IF padr1 = adr1  AND padr2 = adr2
            mov dot,padr2        ;readjust tag range to new size of block
        FI 
         
        rts pc
         
putwd:    
        save 
        call size                       ;r0=len, r1=width
        mov r0,r3                       ;copy length into r3
        mov r1,wwid                     ;save width of word
         
;;        PRINTF #TEMP <len=%d,wid=%d [%s]> r0,r1,#wordb
         
        LET r2 = op + r3                ;max buffer calc
        LET r4 = wwid + outw            ;total width of buf + new word
        IF r2 HIS #lbuf3+lbs-3  OR r4  GT  right ;no room, or width exceeded
            call spread                  ;only justify if asked to.
            call outlin
        FI 
         
        add wwid,outw                   ;accumulate width of line
        inc outw                        ;add one for spacing
        inc nwords                      ;count words
        mov #wordb,r1                   ;start of buffer
        LOOP for r2 = #1 TO r3          ;its r3 chars long
            movb (r1)+,@op               ;copy onto end of line
            inc op                       ;inc pointer
        NEXT r2                         ;
        movb #space,@op                 ;add space at end
        inc op                          ;of line
         
        rts pc
spread:  
        save 
        IF nwords GT #0
            dec op                       ;clear last space at end
            dec outw                     ;and lessen width by one
        FI 
         
        movb #nl,@op                    ;add newline at end
        inc op                          ;next
        clrb @op                        ;add null at end also
         
        LET r0 = right - outw           ;extra spaces to be doled out
        LET r1 = op - #lbuf3-2          ;current output index
        push r0
        push r1
;	PRINTF #TEMP <					    spread (%d wds) (%d extra) (%d ptr)> nwords,r0,r1
        pop r1
        pop r0
        mov nwords,r2                   ;
        IF justfg NE #0
            call fillit                  ;pass r0,r1,r2 and lbuf3
        FI 
        rts pc
flsh:      
;       TTY <							flsh called>
         
        movb #nl,@op                    ;add nl and null at end
        inc op
        clrb @op
        call outlin                     ;and output what we gots so far.
         
        rts pc
outlin:  
        call outln1
        LET nlines = spaces - #1        ;add nlines of blank lines
        call spacing
        mov #lbuf3,op
        call resetm
        rts pc
outln1:  
        save 
;	PRINTF #TEMP <					    oline  %d width  %d words> outw,nwords
;	TTY  <{1   -5   -10  -15  -20  -25  -30  -35  -40  -45 9>
;	PRINTF #TEMP <{%s}> #lbuf3
        call adline
        rts pc
resetm:  
        save 
        clr outw
        clr nwords                      ;init for next time
        mov #lbuf3,r0
        LOOP for r1 = #2 TO left        ;additional spaces on front
            movb #hspace,(r0)+           ;these are hard spaces
            inc outw
        NEXT r1
        mov r0,op
        rts pc
brake:   
         
;       TTY <							brake called>
        call flsh
        mov spaces,nlines
        call spacing
        mov #lbuf3,op
        call resetm
brake1:  
        save 
        LOOP FOR r3 = #1 TO indent
            movb #hspace,@op
            inc op
            inc outw
        NEXT r3
        rts pc
spacing: 
        save 
        mov (pc)+,@(pc)+        ;mov #<nl,0> , lbuf3
        .byte nl,0
        .word lbuf3
        LOOP FOR r3 = #1 TO nlines
            call outln1
        NEXT r3
        rts pc
getwd:    
        save 
        mov #wordb,r0
         
        DO FOREVER                      ;Skip all leading junk
            call getch                   ;get a character
            IF CS                        ;end of range
                rts pc
            FI 
                 
            IF r0  = #nl    OR    r0 = #space    OR    r0 = #tab
            ELSE 
                BREAK                     ;if its not any of above
            FI                           ;then we've skipped all garbage
        OD                              ;and have a word
         
        IF r0 = #0                      ;check if a null line
            clrb wordb                   ;and indicate in word buffer
            clc                          ;not end of range
            rts pc                       ;but done for now
        FI 
         
        mov r0,peekc                    ;else put back the char
         
        mov #wordb,r1                   ;addr of output
        DO FOREVER
            call getch                   ;get a char
            IF CS
                rts pc
            FI 
            IF r0  = #nl    OR    r0 = #space    OR    r0 = #tab
                clrb (r1)                 ;these are terminators and were
                BREAK                     ;done now (asciz the word)
            FI 
            movb r0,(r1)+                ;else put the char into the word buf
            IF r1 HIS #ewordb-1          ;test for too large
                clrb (r1)                 ;and truncate it here
                BREAK                     ;and call it done
            FI 
        OD 
         
        rts pc
         
getch:    
         
        clr gflag                       ;
        IF peekc NE #-1                 ;look ahead character
            mov peekc,r0                 ;there is one
            mov #-1,peekc                ;so return it and clear it
            clc                          ;not end of range
            rts pc                       ;
        FI 
         
getch1:  
        movb @ip,r0                     ;get next char in buf
        inc ip                          ;update to next
         
        IF r0 NE #0                     ;if it is 0 then we need new line
            clc                          ;else everything is ok to return
            rts pc                       ;
        FI 
         
        call nline                      ;get next line
        IF CS                           ;cs means no more lines
            rts pc                       ;so return with end of range status
        FI 
         
        clr gflag
        mov #lbuf1,r1                   ;input buffer
        mov #lbuf2,r2                   ;needs to be copied here
        mov r2,ip                       ;also init pointer the beginning
        DO FOREVER
            movb (r1)+,(r2)              ;mov input to output
            IF NE                        ;till done
                IFB (r2) NE #space AND (r2) NE #tab  AND (r2) NE #nl
                    inc gflag              ;indicate not an essentially blank line
                FI 
            ELSE 
                BREAK                     ;done on null
            FI 
            inc r2                       ;else to next output location
        OD 
         
        IF gflag = #0                   ;was it a null line
            clr r0                       ;yes, so send back a null
            rts pc
        ELSE 
            br getch1                    ;no so go get first char in line
        FI 
         
nline:    
;	PRINTF #temp <nline: addr=%o adr1=%o adr2=%o dol=%o> addr adr1 adr2 dol
         
        IF addr HI adr2
            sec 
        ELSE 
            mov @addr,r0
            call getlin
            add #2,addr
            clc 
        FI 
        rts pc
         
size:    
        LEN #wordb
         
        clr r1                          ;clear width count
        mov #wordb-1,r4                 ;
        add r0,r4                       ;last char in word
         
        LOOP for r2 = #wordb THRU r4
            SELECT case (r2) of
            CASEB #nl
                BREAK                  ;don't count
                 
            CASEB #backspace
                dec r1                 ;backspace = -1
                BREAK 
                 
            DEFAULT 
                inc r1                 ;else +1
            ESAC 
        NEXT r2
        rts pc
         
         
getparms:  
        call getc
        IF r0 = #'.
            call getlpm                  ;use line to get parameters
            rts pc
        ELSE 
            mov r0,peek
        FI 
         
         
        LOOP for i = #left TO #justfg STEP #2
10$:        call getc
            IF r0 = #space
                br 10$
            FI 
            BREAK IF r0 = #nl
            IF r0 NE #comma         ; testing for ,, type entry
                call getnum          ; which means leave parm alone
                mov r1,@i
                call getc            ;get the terminator
                IF r0 = #nl
                    mov r0,peek        ;put it back only if a nl
                FI 
            FI 
        NEXT i
         
; PRINTF #temp <L=%d R=%d in=%d sp=%d j=%d> left right indent spaces justfg
        rts pc
         
         
         
adline: 				;add line in lbuf3 to file
        save 
        clrb lbuf3+lbs-1
        mov #lbuf3,r0
        mov #lbuf1,r1
         
5$:      
        movb (r0)+,r2
        IFB r2 = #hspace
            mov #space,r2
        FI 
        movb r2,(r1)+
        bne 5$
         
        mov adloc,r5
        mov #10$,r4
        call append
        add #2,adloc
        rts pc
         
         
         
10$:    mov #20$,r4
        clc 
        rts pc
         
20$:    sec 
        rts pc
         
getlpm:  
         
        call getc
        IF r0 NE #nl
            mov #2,r1
            jmp error
        FI 
         
        IF adr1 = zero
            mov @dot,r0
        ELSE 
            mov @adr1,r0
        FI 
         
        call getline
        call expand
        call findend
        LET r1 = r0 - #text
         
        mov #text,r0
        DO FOREVER
            BREAK IF r0 HIS #etext
            BREAK IFB (r0) NE  #space
            inc r0
        OD 
         
        sub #text,r0
        inc r0
        IF r0 GT #140.  OR  r1  LE #0   OR r1 LT r0
            mov #2,r1
            jmp error
        ELSE 
            mov r0,left
            mov r1,right
        FI 
         
; PRINTF #temp <--L=%d R=%d in=%d sp=%d j=%d> left right indent spaces justfg
        rts pc
         
         
        .end 
