; 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 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 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 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 dot dol IF smode NE #0 call bcom1 ;redraw screen FI pop adr2 ;PRINTF #temp 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 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 # , 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 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 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