 
*  ED1/EDIT1                  May / 05 / 95
 
*  Flags/Data in temporary flag area
*-----------------------------------
*  Available before clear entry
 
       RORG >0                Force start
 
SCLR   EQU  $                 Start of CMDxit clear block
OVRL   BSS  2                 >2000
CMDRT  BSS  2                 >2002
MARKER BSS  2                 >2004
UPCASE BSS  2                 >2006
DESSAV BSS  2                 >2008
MFLAG  BSS  2                 >200A
GOLF   BSS  2                 >200C
SWSF   BSS  2                 >200E
 
REFRSH BSS  2                 >2010
VRFY   BSS  2                 >2012
HLPSCR BSS  2                 >2014
PROMPT BSS  2                 >2016
 
LINTBL BSS  24*2              >2018
ERRLIN EQU  LINTBL+4
LINT34 EQU  LINTBL+34
LINT36 EQU  LINTBL+36
LINT40 EQU  LINTBL+40
LINADR BSS  2                 >2048
LINEND BSS  2                 >204A
VIEWSC BSS  2                 >204C
HARDF  BSS  2
CHGNAM BSS  2
 
*------------------
SCLRND EQU  $                 Running clear block length
*------------------
 
ICHRF  BSS  2                 >204E
 
LASTCR BSS  2                 >2050
CTLMDE BSS  2                 >2052
WDWRAP BSS  2                 >2054
LINENO BSS  2                 >2056
LSTKEY BSS  1                 >2058
       BSS  1
BUFADR BSS  2                 >205A
LOADS  BSS  2                 >205C
RLINE  BSS  2                 >205E
 
WLINE  BSS  2                 >2060
NCHAR  BSS  2                 >2062
LINF   BSS  2                 >2064
TOPPAR BSS  2                 >2066
WTOP   BSS  7*2               >2068
 
SCNLEN BSS  2             |   >2076
TOPSCN BSS  2             |   >2078
CRFLAG BSS  2                 >207A
SREGS  BSS  7*2               >207C
SREGS2 EQU  SREGS+2
 
NUM1   BSS  2             |   >208A     Keep
NUM2   BSS  2             |   >208C     in
NUM3   BSS  2             |   >208E     this
NUMCHK BSS  2             |   >2090     order
 
SAVER0 BSS  2                 >2092
ENDLIN BSS  2                 >2094
DELAST BSS  2                 >2096
DELAY  BSS  2                 >2098
SBFOC  BSS  2                 >209A
NOINTR BSS  2                 >209C
ERFLAG BSS  2                 >209E
 
LEVEL1 BSS  2                 >20A0
RSTRL  BSS  2                 Replace String length
STRL   BSS  1                 String length
STRL1  BSS  1                 String length as byte
DELIM  BSS  1                 Delimiter for parse
DBLNK  BSS  1                 End col for FS
ELINE  BSS  2                 Line count
STRING BSS  2                 Pointer to find string
RSTRNG BSS  2                 Pointer to replacing string
RSFLAG BSS  2                 Flag for 3 delimiters
 
CNT    BSS  2                 Count for string cmds
COLNUM BSS  2                 EoF/Col check flag for parse
WPMODE BSS  2
ASPARS BSS  2
WDPROC BSS  2
MKSAV1 BSS  2                 Temp save for R1
MKSAV3 BSS  2                 Temp save for R3
MESGAD BSS  2
 
       BSS  2                 Spare
IORNM  BSS  6                 Total 6
PARBLK EQU  $                 Marks end of initial clear >20C8
 
*-----------------------------------------------*
*  Initial block cleared on entry : >C8 = 100w  *
*-----------------------------------------------*
 
       RORG >0                Start here at >2000 when loaded
 
*  Entry code and parameter block
*--------------------------------
*  10 w
 
       B    @HIBUF
LDIMM  BYTE >0                SETO => halt for choice screen
LDTYPB BYTE >0                0-2   0-USA 1-Allch 2-EuWr
LNGTYP BYTE >0                0-7   ++ CHAR@1, F8TX@1
HELPLD BYTE >1                0 -> no help else load help
PALNTS BYTE >80               NTSC/PAL at entry
PLNTEX BYTE >00               Exit
PCENTY BYTE >00               Printer control - entry length
PCEXT  BYTE >00               Exit codes length
ERAMF  DATA >FF01             See ERAMF byte choices
HDPGET BYTE >0                Hard path directory source flag
       BYTE >0                Hard path length
TABSPC BYTE >0
       BYTE >0
LDVN#  DATA '52'              Version #
 
*  ERAMF byte choices, W/P  MSByte, P/E LSByte
*  >0000  no ERAM  64 Kb single buffer only
*  >FF  ERAM present - 128 Kb single buffer
*  >01  ERAM present - dual 64 Kb buffers
 
*  Printer codes, 24 bytes each
*------------------------------
*  24 w
 
PCEDAT BYTE >00,>00,>00,>00,>00,>00,>00,>00
       BYTE >00,>00,>00,>00,>00,>00,>00,>00
       BYTE >00,>00,>00,>00,>00,>00,>00,>00
 
PCXDAT BYTE >00,>00,>00,>00,>00,>00,>00,>00
       BYTE >00,>00,>00,>00,>00,>00,>00,>00
       BYTE >00,>00,>00,>00,>00,>00,>00,>00
 
*  Hard path name data
*---------------------
*  24 w
 
DISNAM TEXT 'DSK5. '
HDPNAM TEXT 'DSK2.           '
       TEXT '                '
       TEXT '          '
       EVEN
 
*  Eurochar PAB Data
*-------------------
*  13 w
 
PABCHD DATA >0500,>1000-6,0,>900
       BYTE 0
PABCHN BYTE >0F
       TEXT 'WDS1.FWB.'
CHRFLD TEXT 'CHAR@1'
CHRFLL EQU  $-2
CHRHIB EQU  $-1
       EVEN
 
*  EuroText PAB Data
*-------------------
*  13 w
 
PABFWD DATA >0500,CATBF,0,>500
       BYTE 0
PABFWN BYTE >0F
       TEXT 'WDS1.FWB.'
FWTFLD TEXT 'F8TX@E'
FWTFLL EQU  $-2
       EVEN
 
*  Help file PAB Data
*--------------------
*  9 w
 
       BYTE 0
PABHLN BYTE >0F
       TEXT 'WDS1.FWB.'
HLPFLD TEXT 'HELP8P'
HLPFLL EQU  $-1
       EVEN
 
*--------------------
*  Resume data block
*--------------------
 
       RORG PARBLK
 
*  Margin/Window data
 
SWCH10 EQU  $                 Flag for 80/40 switch
SWCH12 EQU  $+2
SWCH14 EQU  $+4
WLIN   BYTE >00               With line #s
       BYTE >06
       BYTE >06
WNLIN  BYTE >06               Without
       BYTE >06
       BYTE  06
       EVEN
 
SWCH15 EQU  $                 Flag for 80/40 switch
SWIDTH DATA >4F               Width - 1
SSNLEN DATA 24          |     Keep
STPLEN DATA 24          |     Order
RMGIN  DATA 8                 Bell inset at Rmrg
EUROWR DATA >0                All-Chars flag - OFF as default
TABTYP DATA >0                Tabline type -- 0->USA
RMAFLA DATA >0                Right margin adjust flag
MLINT  DATA >0                Clipboard occupancy
VWLCNT DATA >0                # files in <V>iew list
 
*  Command table pointers
 
CCTABL DATA COMVE             Pointer in VDP
CATBL  EQU  64                Offset to 2nd block
CBTBL  EQU  90                Offset to <fctn> table
 
*  Load/Save alternatives
 
LDADRS DATA LOAD01,LDTP01
SVADRS DATA SAVE01,SDTP01
 
*  Cursor data
 
OCSR   BYTE 8,>3C,>24,>24,>24,>24,>24,>24,>3C
WCSR   BYTE 8,>70,>70,>70,>70,>70,>70,>70,>70
CCSR   BYTE 8,>00,>00,>00,>00,>00,>00,>00,>7C
MASK10 BYTE >10
       EVEN
 
*  Color & VReg data
 
COLCH  DATA >0                Main color index
       DATA >0087             VR #7
BCOLC  DATA >0                Secondary color index
       DATA >008C             VR #12
TWCOLS DATA >0,>0,>0,>0,>0    Roon for FW's 10
TWCOLT EQU  $                 End marker
V9SAV  DATA >8089             For NTSC/PAL, IL toggles  VR #9
 
*  Sound and timing data
 
H80    EQU  $
SNDATA BYTE >80,>20,>90,>9F
MBSDAT BYTE >80,>08,>92,>9F   Margin bell sound data
FLRATE DATA >0003             Cursor flash
 
*  Vowel substitution table
 
VWLTAB BYTE 'A',>80,'E',>84,'I',>88,'O',>8C,'U',>90
       BYTE 'a',>94,'e',>98,'i',>9C,'o',>A0,'u',>A4
 
*  Fixed byte data list
 
WILDC  BYTE '*'               Wildcard byte for FS/RS
SLASH  BYTE '/'               Terminators
BLANK  BYTE ' '
COMMA  BYTE ','
LPAREN BYTE '('
RPAREN BYTE ')'
QUOTE  BYTE >27               Single quote
PERIOD BYTE '.'
HYPHEN BYTE '-'
EXCLAM BYTE '!'
QUESTN BYTE '?'
ANTI20 BYTE >DF               Bit 2 mask
EOT    EQU  $
CR     BYTE >0D               <cr>
FORMF  BYTE >0C               <pa>
BKTAB  BYTE >94               Back tab keycode
FIVE   BYTE >05               Key unit
B8E    BYTE >8E               VR 14 VWTR byte
B0F    BYTE >0F               <f-9> <escape>
CTRLC  BYTE >83               <c-C> <escape>
H40    BYTE >40
H39    BYTE >39
CSR    BYTE >1E
UDLINE BYTE >1F               Underline
CMARKR BYTE >7F               Column marker
B06    BYTE >06               Cursor timing
BFF    BYTE >FF
B7F    EQU  CMARKR
B03    BYTE >03               To fake up delete
       EVEN
 
SQUOTE EQU  QUOTE
TENM2  EQU  $-2               Legalized REF for offset start
WONE   EQU  $                 Word data
ONE    EQU  $+1               Byte data
TEN    DATA 1                 Powers of 10 list
TENS   DATA 10
HUNDRA DATA 100,1000,10000
 
*---------------------------
*  Command line entry table
*--------------------------
*  Order must match MESG
 
CMDTBL EQU  $
       DATA 'SF',0,SV         Save File
CMDTE  EQU  $-CMDTBL          Length of each entry
       DATA 'LF',0,LF         Load File
       DATA 'PF',0,PF         Print File
       DATA 'LT',0,TL         Load Temp
       DATA 'ST',0,TS         Save Temp
       DATA 'DP',0,DP         SDir print device
       DATA 'SD',0,SD         Show Directory
P      DATA 'P ',MPGPT,PG     Purge
ECOMD  EQU  $+4               Pointer for single file re-write
       DATA 'E ',0,EDRNT      Edit Ring (single - CMDXIT)
       DATA 'F ',MODFP,COMSTA Files
       DATA 'L ',MODLP,COMSTA Lines
       DATA 'SH',MODSP,COMSTA SearcH
TT     DATA 'T ',0,MTCI       Tabs
       DATA 'Q ',MQEPT,QF     Quit
       DATA 'QQ',0,EXCHEK     Immediate quit
       DATA 'FS',0,FS         Find String
       DATA 'RS',0,RS         Replace String
       DATA 'M ',MMLPT,ML     Move
       DATA 'C ',MCLPT,CL     Copy
       DATA 'S ',MSLPT,SL     Show
       DATA 'D ',MDLPT,DL     Delete
       DATA 'MK',EMLPT,EML    MarK line
       DATA 'CO',0,STBUF      Copy to CP buffer
       DATA 'PA',0,RTBUF      Paste to edit file
       DATA 'H ',0,HELPS      Help screen
       DATA 'V ',0,VIEWS      View paste buffer
       DATA 'HD',0,HDP        Hard path name
       DATA 'WC',0,WDCENT     Wildcard char
CMDTND EQU   $
 
*  Response table
*-----------------
 
CRSTAB EQU  $
Y      BYTE 'Y'               Yes
N      BYTE 'N'               No
TE     BYTE 'E'               Exit
A      BYTE 'A'               All
S      BYTE 'S'               Stop
TI     BYTE 'I'               Indent
L      BYTE 'L'               Left
R      BYTE 'R'               Right
       EVEN
 
 
*  Main loop, Start, Screen, Scwrit
*  Comdkey, Entkey, Scroll, Dwnar, Newpar, Inschr, Split
*  Indent, Page, Wordw, Cmode
 
*---------------------*
*   Main screen loop  *
*---------------------*
 
START  EQU  $
       BL   @CLRTMP           Clear temp line buffer
       MOV  R1,R8             Get line address - copy Cline
       S    R3,R8             Remove screen line Sbias
       MPY  @D86,R8           Offset in line buffer to R9
       AI   R9,CPUSCN         Construct pointer into text buffer
CPUADR EQU  $-2               Data word for screen buffer start
       BL   @RESTLB           Construct line end/start pointers
STAR10 MOV  @EOF,R11          Refresh EoF comparison
       JNE  STAR20
       BL   @PURGE
       JMP  STAR10
STAR20 DEC  R11               Back off to give EoF - 1
       MOV  R11,@EOFM1        Reset EOFM1
       BL   @BUMPC            Adjust cursor and windows
 
*   Screen handler routine
*-------------------------
 
SCREEN EQU  $
       MOV  @EOFONS,R6        Does file fill screen ?
       JEQ  NOTONS            Yes
       LI   R12,EOFLIN        EoF data line pointer
       A    *R7,R12           Adjust for window
       MOV  R12,*R6           Write into table
NOTONS ABS  @REFRSH           Refresh forbidden ?
       JNE  SCWRIT            Yes
H07    EQU  $                 Cheap byte data >07
       ABS  @OVRL             Overlay in ?
       JNE  SCWRIT            Yes - also do not disturb
 
*  Update CPU Screen buffer from text buffer
*-------------------------------------------
 
       CLR  @ICHRF            Cancel Insert mode
       MOV  @EOFONS,R6        EoF on screen ?
       JEQ  SCRN05            Don't bother
       CLR  *R6               Clear pointer
       CLR  @EOFONS           Reset flag
SCRN05 MOV  @SCNLEN,R6        Yes, get screen length
       MOV  R3,@LINENO        Sbias on first line number
       MOV  @TOPSCN,@BUFADR   Set up first cpu address
SCBFIL BL   @GETL20           Get next line
       JMP  EOFILL            Not there, probably EOF
       DEC  R6                Count line
       JGT  SCBFIL            Any left ?
       JMP  SCWRIT            Go write it
 
*  Complete buffer for End of File on screen
 
EOFILL EQU  $
       MOV  @LINENO,R9        Eof line number
       DEC  R9                Back off 1
       S    R3,R9             Relative screen line number
       LI   R12,EOFLIN        Point to EoF line
       A    *R7,R12           Window adjust
       SLA  R9,1              Index by words
       AI   R9,LINTBL         Point into special line table
       MOV  @SSNLEN,R8        Get Default Screen length
       S    @SCNLEN,R8        Should be zero unless command mode.
       SLA  R8,1              Otherwise should be 2 now
       A    R8,R9             If 2, add 4 to table address
       MOV  R12,*R9           Write in EoF line pointer
       MOV  R9,@EOFONS        Address of EoF message entry
       MOV  @BUFADR,R9        End of CPU buffer
       LI   R8,CPUSND         Blank rest of cpu buffer
EOFILM MOV  @DSPACE,*R9+      Get blank from PAD - will be even
       C    R9,R8             All done ?
       JL   EOFILM            Not yet
 
*  Write up video screen from CPU screen buffer
*-----------------------------------------------
*  Following code assumes in-line routine in PAD
 
SCWRIT EQU  $
       LI   R8,CPUSCN->56     Start of CPU screen buffer area
       MOVB *R4,R5            Save char under cursor
       MOVB @CSR,*R4          Replace with cursor char code
       A    *R7,R8            Allow for window
       MOV  @STPLEN,R6        Get Screen Length
       CLR  R9                Start of screen table
SCWR05 BL   @SETWDA           Write VDP address 0
       LI   R12,LINTBL        Special vdp write table
       LI   R14,VDPWD         Set up for in-line VDP writes
SCWR10 AI   R8,86             Advance to next line in cpu buffer.
D86    EQU  $-2               Screen buffer line length
B86    EQU  $-1               Byte data
SCWR20 LI   R9,4              4 blocks of 20 per line
SWCH20 EQU  $-2               Need 2 for 40 col
       MOV  *R12+,R10         Special screen message?
       JNE  SCWR50            Yes - use this
 
*  Write out a line using speedup code in PAD
 
       MOV  R8,R10            No, output from CPU buffer
SCWR50 BL   @FASTVW           Go to code in PAD
       DEC  R6                Line count
       JGT  SCWR10            Repeat till done
 
*  Do pointer on bottom line
*-------------------------------------------------------------
*  Go to COMAND on first pass, replacing with next instruction
 
CMARK  EQU  $
RWBRN  B    @FIRST            Goes off via COMAND
*      MOV  @LASTCR,R9        Replaces previous on first pass
       BL   @SETWDA           Set up last marker position
       MOVB @DSPACE,@VDPWD    Clear previous marker
       MOV  R2,R9             Get column pointer
       AI   R9,>820-6         Convert to baseline marker
       MOV  R9,@LASTCR        Save pos'n for erasure
       BL   @SETWDA           Set for write
       MOVB @CMARKR,@VDPWD    Little arrowhead marker
 
*  Get key-stroke
*----------------
 
       SETO @REFRSH           Disable refresh of cpu buffer
       MOV  R1,R8             Calculate VDP address of cursor
       S    R3,R8             # lines on screen
       LI   R12,>50           Reset for 40-col mode
SWCH30 EQU  $-2               Switch pointer
       MPY  R12,R8            Beginning of line offset
       A    R2,R9             Add cursor column
       S    *R7,R9            Adjust for current window
       MOVB @KEYRT,@LSTKEY    Save last key as left behind
       MOVB R5,*R4            Char to buffer
       MOVB R5,R0             Set up cursor flash in R0
       SWPB R0                Reverse bytes
       MOVB @CSR,R0           Cursor as other byte
       BL   @FLACSR           Flash cursor, wait for key
       BL   @MRCHEK           Margin bell
       MOV  @PROMPT,R11       Special return for prompting
       JEQ  KYEVAL            None - evaluate key return
       RT                     GO there
 
*  Process key return
*---------------------
 
KYEVAL EQU  $
       MOVB @KEYRT,R10        Fetch key-stroke
       JLT  CONTKY            Key greater than >8000
       CI   R10,>1F00         Key less than >1F00
       JLT  COMDKY            Function key then
BRINS  B    @NEWCHR           Character key (>20 - >7F)
 
*  Command key table lookup
*--------------------------
 
COMDKY EQU  $
       LI   R6,CBTBL          Command key (Function key)
COMD10 SRL  R10,7             Calculate address into key table
       MOV  @CCTABL,R9        VDP address of table
       A    R6,R9             Select sub-table
       A    R10,R9            Index into sub-table
       BL   @SETRDA           Set for read
       MOVB @VDPRD,R6         First byte
       SWPB R6                For next
       MOVB @VDPRD,R6         Read LSB
       SWPB R6                Make word address
COMD15 LI   R11,START         Set up return address
       CLR  R0                Clear error register
       CLR  @ICHRF            Clear insert character flag.
       B    *R6               Go
 
CONTKY CLR  R6                Control key offset to CTBL = 0
       AI   R10,->8000
       CI   R10,>2000         Out of range?
       JLT  COMD10            No
       LI   R6,CATBL          Check for control 0,1,...7
       AI   R10,->3000        Key between >9F, >B0
       JLT  BST2              Yes, ignore
       CI   R10,>E00          No, key between >B0,>BD
       JLT  COMD10            Yes, good key
BST2   B    @START            No, forget about it
 
*  ENTER LINE Processor
*----------------------
 
ENTKEY EQU  $
       CLR  @TOPPAR           Reset top of para flag
       MOV  @CMDRT,R6         Command mode?
       JEQ  ENTR02            No
       B    *R6               Yes, go to command processor.
 
ENTR02 C    R1,@EOFM1         Cline at end of file ?
       JLT  ENTR05            No
       MOV  @WDWRAP,@CRFLAG   Wordwrap flag determines if <cr> entered
       JNE  NEWP01            Yes - go to last line check
       JMP  ENTR10            No
 
ENTR05 ABS  @CRFLAG           Word wrap mode?
       JNE  NEWPAR            Yes
ENTR10 CLR  R2                Home cursor on line
       BL   @UPDATE           Update the line
       C    R1,@EOFM1         Past end of file ?
       JHE  ENTR20            At or past end
       ABS  @CRFLAG           Word wrap mode?
       JEQ  SCRL01            No, go check scroll
 
ENTR15 MOV  @SCRL01+2,@AUTXIT+2 Establish return
       B    @AUTO60           Go into word-wrap insert routine
 
ENTR20 MOV  @EOF,@LINENO      Force insert at end
       BL   @INSL10           Insert line into buffer
 
*   Scroll subroutine
*--------------------
 
SCRL01 LI   R11,START         Fake up return for scroll
SCROLL INC  R1                Point to next line
H81    EQU  $-1               Cheap data byte
SCRL03 MOV  R1,R8             Go to next line
       S    R3,R8             Remove start of screen bias
       C    R1,@EOFM1         At end of file ?
       JLT  SCRL04            Not yet
       MOV  @EOFM1,R1         Replace Cline with (end of file  - 1)
       INC  R8                Next line
SCRL04 C    R8,@STPLEN        Next line on screen?
       JLT  SCRL07            Yes - return directly
       INC  R3                Push start of screen along a line
       CLR  @REFRSH           Force refresh of cpu buffer
SCRL07 RT
 
*  Cursor down arrow
*-------------------
 
DWNAR  EQU  $
       BL   @UPDT10           Refresh line in buffer
       JMP  SCRL01            Go scroll
 
*  Don't split last line with <enter>
*------------------------------------
 
NEWP01 MOV  R4,R8             Copy current cursor address
       MOV  R8,R9             Copy for search start
       S    R2,R9             R9 <- start of line
       AI   R9,86             R9 <- end of line
NEWP03 CB   *R8+,@DSPACE      Found nonblank after cursor?
       JNE  NEWP05            Yes, do not split
       C    R8,R9             End of line?
       JNE  NEWP03            No, continue checking
       JMP  NEWPAR            Yes, all blanks after cursor
 
NEWP05 MOV  R9,R4             Fake out no split
       JMP  NEWP20            Force split to end of line
 
*  Indent and/or New paragraph
*-----------------------------
 
INDENT EQU  $
       MOV  @WDWRAP,@CRFLAG   Word-wrap mode ?
       JEQ  BST2              No - back to start
NEWPAR SETO @NCHAR            Ensure Edit buffer gets updated
       LI   R9,TEMPM6         Temp buffer allowing for line #
       A    R2,R9             Point into buffer
       CB   *R4,@CR           Is it a CR ?
       JEQ  NEWP10            Yes
       MOVB *R4,*R9+          No - put in temp buffer
NEWP10 MOVB @CR,*R4+          Move data to next line, split.
NEWP20 MOV  R4,R8             Copy Cursdr
       MOV  @INDT,R2          Start at indent
       MOV  R2,@LMRG          Temp left margin for split
       SETO @GOLF             Use to flag <enter> key for insert
       JMP  SPLIT
 
*  Insert blank line ( or split line )
*---------------------------------------
*  Set insert mode only, if not wordwrap
 
INSCHR MOV  @WDWRAP,@CRFLAG   Word wrap mode?
       JNE  INSC45            No
INSC40 SETO @ICHRF            Not word wrap so set flag
       RT
 
INSC45 SETO @SWSF             Effectively save Wd-wrap state
INSCH1 CLR  @TOPPAR           Not a new para
INSC05 CLR  @GOLF             Yes, split line
       MOV  R4,R8             Copy cursor address in buffer
       LI   R9,TEMPM6         Temporary
       A    R2,R9             R9 -> DADDR in tempbf
SPLIT  MOV  @LINEND,R6        Current line CPU end
INSC10 C    R8,R6             End of line?
       JH   INSC20            Yes, exit
       MOVB *R8+,*R9+         Move rest of line to tempbf
       JMP  INSC10            Repeat
INSC20 BL   @CTOEOL           Clear to end of line
       BL   @UPDATE           Update split line
       BL   @INSL50           Insert next split line
       ABS  @GOLF             Check flag setting for enter
       JNE  SCRL01            Enter key, scroll
INSC30 DEC  R1                Not enter key
       JMP  SCRL01            Scroll screen
 
*  Insert a blank line ahead of present line
*------------------------------------------
*  New page char insert
 
INSERT BL   @UPDATE           Last (blanked) line to buffer
       JMP  INSERU            Collect line and scroll screen
PAGE   BL   @UPDATE           Last line to buffer
       LI   R9,TEMPM6         Use temp buffer
       A    @LMRG,R9          Over to left margin
       MOVB @FORMF,*R9+       Write in <new page>
       MOVB @EOT,*R9+         Write a <cr>
INSERU BL   @INSLIN           Place in text buffer
       JMP  INSC30
 
*  Previous line-start align and insert new line
*-----------------------------------------------
 
PRETTY EQU  $
       BL   @UPDT10           Current line to text buffer
       BL   @CHKBLM           ENTRY writes in
       MOV  R8,R2             Use first non-blank position
       INC  R1                Next line - blank line re-entry
       JMP  INSERU            Go insert blank and set cursor on it
 
*  Release to full margins
*-------------------------
 
MRREL  EQU  $
       SETO @GOLF             Allow outside margins
MRREM  MOV  @DSIX,@LMRG       Full left margin
       MOV  @D85,@RMRG        Full right margin
       RT
 
*  Set/toggle  mode flags
*------------------------
 
WORDW  EQU  $                 31 w ----
       SETO R10               Flag <ctl-0> entry
       SETO @CTLMDE           Fake up to be changed
       JMP  CTKL10
CMODE  CLR  R10               Flag <ctl-U> entry
CTKL10 LI   R8,CCSR           Underline cursor data
       MOV  @WPMODE,R9        Fetch flag pointer
       ABS  @CTLMDE           Check control char mode ( +1 or 0 )
       DEC  @CTLMDE           Toggle it ( 0 or -1 )
       JNE  CTKL30            Go set underline cursor
       ABS  *R9               Normalize flag
       A    R10,*R9           Toggle it
       JEQ  CTKL20            Flag off - hollow cursor
       MOV  @WDPROC,@CRFLAG   Copy to CR
       LI   R8,WCSR           Wrap (or Asm) cursor
       JMP  CTKL30
 
CTKL20 LI   R8,OCSR           Hollow cursor
CTKL30 BL   @VSTRV            Write in current cursor shape
       DATA VCSRP             Pattern table address
CTKL40 B    @START            Back to start
 
 
*  Insert, Get, Update lines
*  Clr2EoL, ClrTmp, ClrRep
*  Newchar, Rollup, Rolldown
*  Up, Cdnar, Oops, Duplic, Freeze
*  Delete, Move, Copy lines
 
*  Insert line into text buffer
*------------------------------
 
INSLIN EQU  $
       MOV  R1,@LINENO        Cline becomes insert pointer
INSL10 MOV  @TADR,@BUFADR     Inserts new line (Tmpbuf)
INSL20 BLWP @INSTLN           Call buffer manager
       CLR  @REFRSH           Insure CPU buffer gets updated
       INC  @EOFM1            Bump end of file pointer
INSL30 RT
 
INSL50 MOV  R1,@LINENO        Insert line below current line
       INC  @LINENO           Advance line pointer for insert
       JMP  INSL10
 
*  Get lines from text buffer
*--------------------------------------------
*  Called from  SCBFIL, FINDNB, REFR10, FSSUB
 
GETLC  EQU  $
       MOV  R1,@LINENO        Use Cline as line pointer
GETL10 MOV  @LINADR,@BUFADR   Text buffer to put it
GETL20 BLWP @GETLN            BufMgr service
       MOV  R0,R0             Check for error return
       JNE  GETL30            Something is wrong
       INCT R11               Step over error return
GETL30 RT
 
*  UPDATE line in Text Buffer
*--------------------------------------
*  Simple update intercepted in ASMode
*  Warning - line contents altered in ASMode
 
UPDT10 CLR  @TOPPAR           Normal line
       CLR  @CRFLAG           No <cr>'s
UPDATE ABS  @NCHAR            Should this line be updated?
       JEQ  GETL30            No new chars have been entered
UPDA05 C    R1,@EOFM1         Is the line # legit ?
       JGT  GETL30            Line past end of file !
       MOV  R1,@LINENO        Yes - current line for update
UPDA10 MOV  @LINADR,@BUFADR   Use screen buffer as source
       A    @DSIX,@BUFADR     Push past line #
       MOV  R11,R14           Save return
       ABS  @ASPARS           Check if in ASMODE
       JEQ  ASMCEX            No - update directly
       LI   R15,'* '          Load comparison bytes
       MOV  @BUFADR,R8        Point to current line buffer
       CB   *R8,R15           Comment line ?
       JEQ  ASMCEX            Yup - no further action
       SWPB R15               Blank for byte comparisons
       MOV  R8,R9             Copy pointer
       AI   R9,LLL            Point to end of line
 
*  Do label field
 
LABEL  C    R8,R9             End of line ?
       JHE  ASMCEX            Yes
       CB   *R8,R15           Blank ?
       JEQ  GAP01             Yes - go scan for next field
       BL   @CNVLC8           UPCASE it
       INC  R8                Next char
       JMP  LABEL             Go look at it
 
*  Cross gap to Opcode field and check for illegal chars
 
GAP01  C    R8,R9             End of line ?
       JHE  ASMCEX            Quit
       CB   *R8+,R15          Blank ?
       JEQ  GAP01             Yes
       DEC  R8                Back off to char
OPCODF C    R8,R9             End of line ?
       JHE  ASMCEX            Yes
       CB   *R8,R15           Blank ?
       JEQ  GAP02             Yes
       BL   @CNVLC8           UPCASE
       CB   *R8,@UCA          Lower ASCII limit "A" ?
       JL   ASMERR            Bad char
       CB   *R8+,@UCZ         Upper ASCII limit "Z" ?
       JH   ASMERR            Bad char
       JMP  OPCODF            Check next
 
*  Search for Operand field and convert
 
GAP02  C    R8,R9             End of line ?
       JHE  ASMCEX            Quit
       CB   *R8+,R15          Blank ?
       JEQ  GAP02             Yes
       DEC  R8                Back off to char
       CLR  R10               Quote counter
       CLR  R13               DQuote flag
       CB   *R8,@DQUOTE       Does it start with a normal quote
       JNE  OPRND
       SETO R13               Flag a double quote -- in COPY
OPRND  C    R8,R9             End of line ?
       JHE  OPND30            Yes
       CB   *R8,@SQUOTE       "'" ?
       JNE  OPND10
       DEC  R10               Toggle quote indicator
OPND10 ABS  R10               Check if even or odd # of quotes
       JNE  OPND20
       CB   *R8,R15           Blank ?
       JEQ  OPND30
       BL   @CNVLC8           UPCASE
       CB   *R8,@PERIOD       "." for "," is common typo
       JNE  OPND20            None of that
       MOV  R13,R13           Could it be COPY filename ?
       JEQ  ASMERR            No way
OPND20 INC  R8                Next char
       JMP  OPRND             Do it again
 
*  Check quotes on way out
 
OPND30 ABS R10                Uneven # of quotes
       JNE ASMERR             Sound the alarm
       MOV R13,R13            Did it start with " '
       JEQ ASMCEX             No
       CB  @-1(R8),@DQUOTE    Finish " to match ?
       JNE ASMERR             No
ASMCEX BLWP @UPDTLN           Update edit buffer
       B    *R14              Return
ASMERR BL   @HONK             Show displeasure
       JMP  ASMCEX            Don't do next to make more obvious still
 
*  Clear to end of line key
*--------------------------
 
CTOEOL EQU  $
       MOV  @LINEND,R6        Current end of line
       MOV  R4,R9             Copy Curadr
CTOE10 C    R9,R6             To end yet ?
       JH   GETL30            Yes
       MOVB @DSPACE,*R9+      Fill with blank
       JMP  CTOE10            Check if done
 
*  Clear temporary buffer
*-----------------------
 
CLRTMP LI   R14,TMPBUF         Clear temporary buffer
TADR   EQU  $-2                Use as pointer
MFILL  LI   R6,80              Line text length
CLRT10 MOVB @DSPACE,*R14+      Blank buffer for insert line
       DEC  R6                 Count off
       JGT  CLRT10             Not done
       RT
 
*  Clear replace buffer
*----------------------
 
BKREPB LI   R14,REPBUF        Blank replace buffer
BKRE10 LI   R6,160            May blank too much, but ok since it
       JMP  CLRT10            is the last buffer.
 
*  Fake up special chars
*-----------------------
 
CHR0A  MOVB @EOT,@KEYRT       Fake up CR
       JMP  NEWC01
CHR0C  MOVB @FORMF,@KEYRT     Fake up PA
       JMP  NEWC01
 
*  Eurowriter vowel modifier
*---------------------------
 
VOWEL  EQU  $
       LI   R6,VWLTAB         Point to substitution table
       LI   R0,>14            Length of table
VWL10  CB   *R4,*R6           Is it this vowel ?
       JEQ  VWSUBS            Yes
       INCT R6                No - try the next
       DECT R0                Count off
       JGT  VWL10             Do the next
       JMP  BST10             Not a vowel - resume main loop
 
*  Do the substitution in range  >80 - >A7
 
VWSUBS MOV  *R6,R6            Fetch the table entry
       SLA  R6,8              Bring up other byte
       SLA  R10,7             Key decode pointer
       AI   R10,>F800         -8 reduces to 0-3 in MSB
       AB   R10,R6            Add to base substitution
       MOVB R6,@KEYRT         Fake into the key return
 
*  Process normal key entry
*--------------------------
 
NEWCHR EQU  $
       LI   R11,KEYRT         Byte saver
       ABS  @CTLMDE           Special char mode ?
       JEQ  NHIBIT            No
       SB   @H40,*R11         Convert to standard control key
       SZCB @H80,*R11
NHIBIT MOVB @CMARKR,R6        Check current mode byte
       JGT  NEWC01            Normal mode
       SOCB @H80,*R11         Set high bit
       CB   @BFF,*R11         Check - used in encoding
       JNE  NEWC01            No
       MOVB @DSPACE,*R11      Replace by blank
NEWC01 CB   @B7F,*R11         <f-V> key
       JNE  NOBKDL            No
       C    R2,@LMRG          Treat as a back delete
       JLE  BST10             Do not pass left margin
       DEC  R2                Cursor left
       DEC  R4                Buffer pointer left
       MOVB @B03,*R11         Fake up char delete
       B    @KYEVAL           Redo key check
 
NOBKDL SETO @NCHAR            Flag for update of Edit buffer
       SETO @REFRSH           Flag to stop update of CPU buffer
       MOVB @KEYRT,R5         Fetch key
H83    EQU  $-2               Cheap data byte
       MOV  @CMDRT,R6         Special command return
       JEQ  SETEDF            No - has to be command mode
       SETO @CHGNAM           Show name edited
       JMP  NEWC02            Again
 
SETEDF SETO @CHNGED           Edited flag for recall/quit
       ABS  @WDWRAP           Word wrap mode?
       JNE  NEWC50            Yes
 
*  Normal (and CMD) mode
 
NEWC02 ABS  @ICHRF            No, insert char mode?
       JEQ  NEWC10            No
       MOV  @LINADR,R9        Yes, move next characters
       A    @RMRG,R9          End of line at RMRG
       MOV  R4,R6             Curadr -> end of move
       MOV  R9,R8             Copy
NEWC03 DEC  R8                Previous char
NEWC05 C    R8,R6             R6 -> cursor
       JLT  NEWC10            Done?
       MOVB *R8,*R9           No - shuffle it along
       DEC  R9                Back off target
       JMP  NEWC03            Back off source too on loop
 
*  Now insert character at cursor position
 
NEWC10 MOVB R5,*R4            Put new char in line buffer
NEWC15 INC  R2                Move cursor right
       JMP  BST05             Adjust cursor
 
*  Wordwrap insert mode
 
NEWC50 CB   *R4,@EOT          Overstriking a cr?
       JNE  NEWC52            No
       MOV  R2,R8             Copy cursor position on line
       INC  R8                Next
       C    R8,@RMRG          Would it be past right margin ?
       JHE  NEWC52            Yes
       MOVB *R4,@1(R4)        Put cr out anyway.
NEWC52 C    R2,@RMRG          Room for one more character?
       JLT  NEWC10            No, leave room
NEWC24 BL   @AUTOIN           Wrap word and insert line
       JMP  NEWC15            Put new char in buffer
 
*  Rollup - add screen length to Sbias
*-------------------------------------
 
CMRLUP EQU  $
       DECT R3                Command screen shorter
       JMP  RLUP05            Skip buffer update
 
ROLLUP EQU  $
       BL   @UPDATE           Update line buffer if needed
RLUP05 CLR  @REFRSH           Allow refresh
       MOV  R1,R8             Working copy of Cline
       A    @STPLEN,R3        Push Sbias along - check later
       A    @STPLEN,R8        Change current line by screen length
       C    R8,@EOF           Past EoF ?
       JHE  RLUP10            Yes
       MOV  R8,R1             No, use new Cline
       JMP  BSTART            Exit now
 
RLUP10 C    R3,@EOF           Check Sbias in file
       JLT  RLUP20            That's OK
       MOV  @EOF,R3           EOF to Sbias
       DEC  R3                Show last line at top
RLUP20 MOV  R3,R1             Use new Sbias
 
*  Common scroll finish
 
BSTART CLR  @CRFLAG           Don't put cr's in.
       CLR  @TOPPAR           Not top of paragraph
       CLR  @SWSF             Get out of insert mode
BST05  MOV  @CMDRT,R11        Check special return
       JEQ  BST10             None - main loop
BSTT10 MOV  R3,R1             Sbias -> Cline
       INC  R1
BST10  B    @START
 
*  Rolldown -  subtract screen length from Sbias
*-----------------------------------------------
 
CMRLDN EQU  $
       INCT R3                Command screen shorter
       JMP  RDWN05            Skip buffer update
 
ROLDWN EQU  $
       BL   @UPDATE           Update current line if needed
RDWN05 CLR  @REFRSH           Allow screen buffer refresh
       MOV  R1,R8             Copy Cline
       S    @STPLEN,R8        Back up one screen
       JLT  RDWN10            Off screen?
       MOV  R8,R1             No - use new Cline
       S    @STPLEN,R3        Back one screen length in file also
       JLT  RDWN20            Off screen!
       JMP  BSTART            No
 
RDWN10 CLR  R1                Cursor to top of screen
RDWN20 CLR  R3                First line in file - Sbias = 0
       JMP  BSTART
 
*  Delete line key  (PREDEL for blank lines only)
*------------------------------------------------
 
PREDEL EQU  $
       MOV  R11,R14           Save return
       BL   @CHKBLM           ENTRY writes in
       B    *R14              Ignore if non-blank
 
DELLIN EQU  $
       LI   R9,SDLBUV         Point to save delete buffer
       LI   R8,6              Allow for line #
       A    @LINADR,R8        Get past line # in buffer
       BL   @VMBWL            Write to VDP storage
       DATA LLL               Whole line
       CLR  @REFRSH           Force update of screen
DELLN1 MOV  R1,@LINENO        Cline to line pointer
       BLWP @DELTLN           Delete current line
       CLR  @DELAST           Reset DELete last line flag
       C    R1,@EOF           Past EoF ?
       JLT  BST10             No - exit directly
       SETO @DELAST           Set DELete last line flag
       MOV  R1,R1             Any lines left ?
       JNE  UPAR05            Scroll screen up
       JMP  BST10             No - exit directly
 
*  Up arrow key
*--------------
 
UPAR   EQU  $
       BL   @UPDT10           Update CLINE
UPAR05 DEC  R1                Go to previous line
       C    R1,R3             Cline,Sbias
       JLT  UPAR20            Off screen
UPAR10 JMP  BST10             B @START
 
*  Repaint
 
UPAR20 MOV  R3,R3             First line?
       JNE  UPAR30            No
UPAR25 CLR  R1                Yes, don't scroll
UPAR30 MOV  R1,R3             Scroll up
       JLT  UPAR25            Cline < 0 error
RFSTAT CLR  @REFRSH           Force screen refresh
JBST10 JMP  BST10             To main loop
 
*  Up/Down Arrow for command mode
*--------------------------------
 
CUPAR  EQU  $
       MOV  R3,R3             Check Sbias
       JEQ  BST10             Must be start anyway
       DEC  R3                Back a line towards start
CUPR10 CLR  @REFRSH           Force screen buffer refresh
       JMP  BSTT10
 
CDNAR  EQU  $
       C    R3,@EOFM1         Check Sbias
       JHE  BST10             No more to go
       INC  R3                Next line to top of screen
       JMP  CUPR10            Go write  new screen
 
*  Go to Marker
*--------------
 
GO2MRK EQU  $
       MOV  R1,@MKSAV1        Save current cursor line
       MOV  R3,@MKSAV3        Save current screen bias
       MOV  @MKTBL,R3         Get marker
GO2MRJ BL   @UPDT10           Update buffer
       MOV  R3,R1             Force top of screen
GO2STT JMP  RFSTAT            Force screen refresh
 
GO2ORG EQU  $
       BL   @UPDT10           Update buffer with current line
       MOV  @MKSAV1,R1        Write in saved cursor line
       MOV  @MKSAV3,R3        Write in saved top of screen
       JMP  RFSTAT
 
*   Oops Key
*-----------
 
OOPS   EQU  $
       CLR  @REFRSH           Re-initializes current line anyhow
       CB   @LSTKEY,@H07      Was it a <fctn-3> ?
       JEQ  OOPS10            Undo it then
       RT                     NO action then
 
OOPS10 ABS  @DELAST           Deleted last line?
       JEQ  OOPS20            No
       INC  R1                Yes, insert after last line
OOPS20 BL   @MOVE             Retrieve deleted line from VDP
       DATA SDLBUV
       DATA TMPBUF,LLL
       BL   @INSLIN           Insert line back in text buffer
       JMP  JBST10            Restart
 
*  Duplicate line key
*--------------------
 
DUPLIC EQU  $
       MOV  R1,@LINENO        Duplicate previous line
       JEQ  DUPLID            Line = 0?
       DEC  @LINENO           No, Back up to previous line
       MOV  @LINADR,@BUFADR   Read line from edit buffer
       BLWP @GETLN
DUPLID RT
 
*  Freeze lower half screen
*--------------------------
 
FREEZE EQU  $
       LI   R8,STPLEN         Byte saver
       C    *R8,@-2(R8)       Has temp length been set ?
       JHE  FRZ10             No - change to line after cursor
       MOV  *R8,R0            Copy current value
       MOV  @-2(R8),*R8       Restore nominal value SSNLEN
       CLR  R8                For alternate color table clearance
       JMP  FRZ30
 
FRZ10  MOV  R1,R0             Copy current Cline
       INC  R0                Advance to next
       S    R3,R0             Remove Sbias for line count
       MOV  R0,*R8            Rewrite temp screen length
       SETO R8                For setting alternate color table
FRZ30  BLWP @SHOFRZ           Vector switched for 40/80
FRZ99  RT
 
 
*---------------------------------------------*
*    COPY, MOVE  Lines  (DELETE after COMAND) *
*---------------------------------------------*
*  Move Lines
*------------
 
ML     EQU  $
       BL   @LINUMS           Collect 3 numbers from command line
       LI   R11,MKTBL         Byte saver
       MOV  R13,R14           Copy block size
       A    R12,R13           Restore "to"
       C    R9,*R11           All safely above ?
       JH   ML30              Yes
       C    R6,*R11           All below ?
       JL   ML30              Yes
       C    R12,*R11          Target below ?
       JL   ML10              Yes
       C    R13,*R11          Above then - check "to"
       JHE  ML30              Go subtract block
       JMP  ML40              Can't decide
 
ML10   C    R15,*R11          Below - check "from"
       JLE  ML40              Can't decide
       NEG  R14               Push marker along after insertion
ML30   S    R14,*R11          Pull marker after excision
       JMP  ML50
 
ML40   CLR  *R11              Cancel marker
ML50   BL   @MVLINS           Shuffle line table around
       B    @CMDXIT           All done
 
*  Copy Lines
*-------------------------------------------------------------
*  R12 has "after" from LINUM, R15 "start", R13 M/C block size
*  R9,R8,R6 increasing - either from-to-after or after-from-to
 
CL     EQU  $
       BL   @LINUMS           Command line #s
       C    R12,@MKTBL        "After" line #
       JHE  CL30              Copy zone safely above
       A    R13,@MKTBL        Adjust by block length
CL30   MOV  R12,R9            Copy "to" as
       MOV  @EOF,R8           Current EoF as mid pointer
       BLWP @CPBLOC           Copy the block
       MOV  @EOF,R6           New EoF as extreme pointer
       JMP  ML50              Now shift this block into place
 
*------------------------------------
*  NextScn, DelChr, LastPar, NextPar
*  Endfil, HomeCsr, GoTo1, Go2End
*  FindNB, FindCR, Refrmt
*------------------------------------
 
*  Next Screen across
*--------------------
*  <ctrl-5> key
 
NXTSCN EQU  $
       MOV  *R7,R8            Current window
       S    R8,R2             Relative cursor
       C    *R7+,*R7+         Tricky +4 to next entry
       MOV  *R7,*R7           Terminator ?
       JLT  NXTS10            Yes - reset
NXTS05 A    *R7,R2            Copy to Cursor
       RT
 
NXTS10 LI   R7,WTOP           Reset to start of table
       JMP  NXTS05
 
*  Delete character
*------------------
 
DELCHR EQU  $
       CLR  @ICHRF            Cancel insert mode
       SETO @NCHAR            Insure line gets updated
       MOV  R4,R9             Copy current Curadr
       MOV  R4,R8             Again
       INC  R8                Point to next byte
DELC10 C    R8,@LINEND        Stop at end of line
       JH   DELC20            There !
       MOVB *R8+,*R9+         Shuffle back one
       JMP  DELC10            Repeat
DELC20 MOVB @DSPACE,*R9       Blank last character on line
       RT
 
*  End/Home cursor to File / Page  <c-J/H/L>
*-------------------------------------------
 
ENDFIL EQU  $
       MOV  @EOF,R3           To end of file
       S    @STPLEN,R3        Make sure last page is filled
       JGT  HOMCSR            Yes
HOMFIL EQU  $
       CLR  R3                Start of buffer
HOMCSR BL   @UPDT10           Current line to buffer
       MOV  R3,R1             Sbias -> Cline
       CLR  R2                Cursor to start of line
       JMP  LAST90            Force refresh on way
 
*  Go to start of line <ctrl-V> without line update or refresh
 
GOTO1  CLR  R2                Cursor to left
       RT
 
*  Go to end of line   <ctrl-Z>
 
GO2END EQU  $
       MOV  @RMRG,R8          Only as far as right margin
GTE10  MOV  @LINADR,R9        Line start pointer
       A    R8,R9             Construct line buffer pointer
       CB   *R9,@DSPACE       Work back to non-space
       JNE  GTE20             Found
       DEC  R8                Back up
       JNE  GTE10             Not done yet
GTE20  MOV  R8,R2             Use as cursor
       INC  R2                Past the last
       RT
 
*  Find last paragraph
*---------------------
 
LASTP  EQU  $
       BL   @UPDATE           Update current line
       MOV  @DECLIN,R14       DEC Cline for FINDCR
       MOV  R1,R15            Save current line #
LAST10 MOV  R1,R1             Check if at start of file
       JEQ  NEXT99            Out of range
       DEC  R1                Previous line - search for para
       BL   @FINDCR           Find carriage return
       BL   @FINDNB           Was it on a blank line ?
       JMP  LAST10            Yup - try again
       MOV  R1,R1             Something there - end of last para
       JEQ  LAST35            Can't back up any more
 
*  Common routine for finding last/next <cr>
 
DECLIN DEC  R1                Start searching back in this para
LAST25 BL   @FINDCR           Find carriage return
LAST30 C    R1,@EOFM1         End of file for next para search
       JGT  NEXT99            Out of range
INCLIN INC  R1                Bump to next line
       BL   @FINDNB           Find first non blank
       JMP  LAST30            Line is blank, go to next
 
*  Paragraph found
 
LAST35 DEC  R4                Adjust pointer
       MOV  R4,R2             Copy buffer pointer
       S    R8,R2             Convert to line pointer
LANX40 SETO @TOPPAR           Top of paragraph flag
LAST40 MOV  R1,R3             Cline -> Sbias => Top of screen
LAST90 B    @RFSTAT           Includes screen refresh
 
*  Search error exits
 
NEXT99 MOV  R15,R1            Did not find next/last <cr>
       BL   @HONK             Sound error and restore line pointer
       JMP  LAST40
 
*  Find next paragraph
*---------------------
 
NEXTP  EQU  $
       BL   @UPDATE           Update current line
       MOV  @INCLIN,R14       INC Cline operation
       MOV  R1,R15            Save current line #
       JMP  LAST25            Go FINDCR, then FINDNB until done.
 
*  Search subroutines
*-------------------------------------
*  Find <cr>, or initial '*' in ASMode
*  Uses R6,R8, needs R1,R14
 
FINDCR EQU  $                 Find next <cr>, or last <cr>
       MOV  R11,R6            Save return
FNCR10 BL   @GETLC            Fetch line from buffer
       JMP  NEXT99            Catches EoF
       MOV  @LINADR,R8        Set up pointer for search
       A    @DSIX,R8          Step past line #
       MOV  @WPMODE,R11       Check editor mode
       CI   R11,WDWRAP        Is it W/P ?
       JEQ  FNCR40            Yes - go to <cr> check
 
*  Program comment line check
 
       CB   *R8,@ASTRIX       Assembly comment line ?
       JEQ  FNCREX            Yes
       CB   *R8+,@SLASH       c-99 comment delimiter ?
       JNE  FNCR50            No
       CB   *R8,@ASTRIX       /* ?
       JEQ  FNCREX            Yes
 
*  <cr> check for paragraph
 
FNCR40 CB   *R8+,@EOT         Is it a <cr> ?
       JEQ  FNCREX            Whoopee
       C    R8,@LINEND        Line done ?
       JL   FNCR40            Not yet
FNCR50 X    R14               Do direction set
       MOV  R1,R1             Check for start
       JEQ  NEXT99            No more
       JMP  FNCR10            Back for next
FNCREX B    *R6
 
*  Find non-blank within margins
*-------------------------------
*  No allowance for ASMode
 
FINDNB EQU  $
       MOV  R11,R6            Save return
       MOV  @LINADR,R4        Get next line
       A    @LMRG,R4          Move to left margin
       BL   @GETLC            Fetch next line from text buffer
       JMP  NEXT99            EoF
FNDN10 CB   *R4+,@DSPACE      Scan for first non-blank
       JGT  FNDN20            Not a blank
       C    R4,@LINEND        End of line?
       JLT  FNDN10            No
       B    *R6               Return without step-over
FNDN20 INCT R6                Step over next
       B    *R6
 
*  Check for blank line between margins
*--------------------------------------
 
CHKBLM EQU  $
       MOV  @LMRG,R8          Start at left margin
CHBL10 MOV  @LINADR,R9        Current line buffer
       A    R8,R9             Index into line
       CB   *R9,@DSPACE       Search for non-blank
       JNE  CHBL20            Found
       INC  R8                Next char
       C    R8,@RMRG          Stop at right margin
       JL   CHBL10            Loop on it
       INCT R11               Step over for blank line
CHBL20 B    *R11              Non-blank line - direct return
 
*  Reformat --  also used by replace string
*----------------------------------------------
*  Right margin adjust - W/P and word-wrap only
*  All entries clear RMA flag on exit
 
RMADJ  EQU  $
       SETO @RMAFLA           Flag Right margin adjust
       JMP  RJ05
REFRMT EQU  $
       CLR  @RMAFLA           Cover non-wordwrap
RJ05   ABS  @WDWRAP           Wordwrap mode ?
       JNE  REFR05            Yes
 
*  If not wordwrap do insert of next line at cursor
 
       MOV  R11,R14           Save return
       MOV  R4,R9             Save Curadr buffer pointer
       MOV  R1,@LINENO        Current line
       INC  @LINENO           Point to next
RJ10   LI   R8,SQSBUF         Use squish as temp buffer
       MOV  R8,@BUFADR        Set as pointer
       BL   @GETL20           Fetch from text buffer
       B    *R14              EoF exit
       LI   R8,SQSBUF+6       Start of copied line
       LI   R13,SQSBUF+85     End of copied line
 
*  Trim and test the next line
 
RJ20   C    R8,R13            All checked ?
       JH   RJ10              Blank - try next
       CB   *R8+,@DSPACE      Space ?
       JEQ  RJ20              Yes
       DEC  R8                Back to first non-blank
RJ30   CB   *R13,@DSPACE      At other end - blank ?
       JEQ  RJ35              Yes
       CB   *R13,@EOT         <cr> ?
       JNE  RJ40              Must be a genuine entry
RJ35   DEC  R13               Try char before
       JMP  RJ20              Use line check to bail out
 
*  Set up insert procedure
 
RJ40   S    R8,R13            First n/b
       INC  R13               # chars to insert
       MOV  @LINEND,R0        End of cline
       MOV  R0,R6             Make copy
       S    R4,R6
       INC  R6                Max # chars to replace on cline
       C    R13,R6            How many to move ?
       JGT  RJ70              Will overrun cline - no insert
 
*  Move as insert
 
       MOV  R0,R15            Copy end pointer
       S    R13,R15           Slide alonhg from here
RJ50   MOVB *R15,*R0          Move char
       DEC  R15               Back one from end
       DEC  R0                Back towards cursor
       C    R15,R4            Done ?
       JHE  RJ50              No
RJ60   MOVB *R8+,*R9+         At least 1 to  move
       DEC  R13               Count off
       JGT  RJ60              More ?
       B    *R14              Yes
 
*  Move overwrites whole line
 
RJ70   MOVB *R8+,*R9+         Always 1 to move
       C    R9,R0             End of line ?
       JL   RJ70              Not yet
       B    *R14              Exit
 
*  Word-wrapping reformat to end of paragraph
 
REFR05 MOV  R11,R14           Save return
       BL   @UPDATE           Update current line in text buffer
       MOV  R1,@RLINE         Save line pointer as read pointer
       CLR  @RSTRNG           No replace string involved
       BL   @GETDAT           Get next line from text buffer
       B    *R14              EoF exit - no work to do
       LI   R14,START         Set re-entry for this path
 
*  Entry from REPLCE string to reformat or drop through
 
RENTRY EQU  $
       MOV  R14,@REFXIT+2     Set up return from either entry
       CLR  @GOLF             Clamp margins
       CLR  @MFLAG            No marker yet
       CLR  @CRFLAG           Get out of wrap mode
       MOV  R9,R12            Preserve R9 from GETDAT over SAVEWS
       BL   @RESTAB           Restore margins
       BL   @SAVEWS           Save current screen pointers
       MOV  R12,R9            Restore R9 pointer
       MOV  R1,@WLINE         Current line as next to write
       INC  R1                Update Cline to next
       MOV  R1,@RLINE         Next line to read
 
*  Initialize pointers on current line
 
       MOV  R2,R8             Copy current cursor offset
       ABS  @SWSF             Insert mode or replace string?
       JNE  REFR10            Yes, ref from current cursor
       MOV  @DSIX,R2          No, reformat entire line.
       MOV  @INDT,R8          Set up for top of paragraph.
       ABS  @TOPPAR           Top of paragraph?
       JNE  REFR20            Yes
       MOV  @LMRG,R8          No, adjust margin.
       JMP  REFR20
 
*  Reformat from current cursor
 
REFR10 CLR  @SWSF             Done with flag now
       MOV  @WLINE,@LINENO    This is the next line
       MOV  @TPM6A,@BUFADR    To temp buffer
       BL   @GETL20           Fetch it from text buffer
       JMP  REFXIT            Must be at end of buffer
       LI   R14,TEMPM6        Start of TMP buffer
TPM6A  EQU  $-2
       MOV  R14,@DESSAV       Copy TMPline buffer start
       A    @LMRG,@DESSAV     Adjust to left margin for destination
       A    R8,R14            Current cursor as offset
       LI   R6,86             Buffer length
       S    R8,R6             Remaining # of bytes to blank
       BL   @CLRT10           Blank TMPBF to end from cursor
 
*  Reformat from start of line or continue
 
REFR20 MOV  R2,R4             Cursor pointer on line
       AI   R4,REPBM6         Make pointer into REP buffer
       LI   R14,TEMPM6        Destination pointer
       MOV  R14,R10           Copy start
       A    @RMRG,R10         Construct end pointer
       A    R8,R14            Start as offset already set up
       DEC  R14               Back off to previous byte
 
*  Get next word
 
GETNWD EQU  $
       CLR  R0                Start counter
       MOV  R4,R13            Copy cursor pointer into REPBuf
GETN10 C    R13,@MARKER       Check cursor against Marker
       JNE  GETN12            Not at marker
       SETO @MFLAG            Flag on Marker
GETN12 C    R13,R9            End of line in REPBuf yet ?
       JL   GETN20            No - go on with what we have
       BL   @GETDAT           Yes, get a new line and reset
       JMP  GETN35            No more data, end of file
GETN20 CB   *R13+,@DSPACE     Scan for non blank character
       JEQ  GETN10            Another blank
       DEC  R13               Back off to first non-space
       MOV  R13,R4            Copy
       CB   *R13,@EOT         Was it a <cr> ?
       JNE  GETN40            No
       INC  R14               Next position for target
GETN30 MOVB *R13,*R14         Put the <cr> in new record
       JMP  PUTN10            Go deal with the line
GETN35 LI   R13,EOT           Fake source as <cr> for EoF
       JMP  PUTN10            Done with line
 
*  Get next word from following line
*-----------------------------------
 
GETN40 C    R13,@MARKER       Reached marker now ?
       JNE  GETN42            Not at marker
       SETO @MFLAG            Set flag
GETN42 C    R13,R9
       JHE  GETN45
       CB   *R13,@DSPACE      Scan for end of word
       JEQ  GETN50            Found it
       CB   *R13+,@EOT        Check for end of text char
       JNE  GETN40            Found it
       JMP  GETN50
 
GETN45 CB   *R13,@DSPACE      Last character a blank?
       JEQ  GETN50            Yes
       INC  R13               No, INC R13 before calc room
GETN50 MOV  R13,R15           ROOM
       S    R4,R15
 
*  Fetch next word
 
PUTNWD MOV  R10,R12           Copy destination end pointer
       S    R14,R12           R12 - DESPTR = Room left
       C    R15,R12           Room for next word?
       JLT  PUTN20            Yes
       C    R14,@DESSAV       Special case of first long word.
       JEQ  PUTN20
 
*  Done with line
*----------------
 
PUTN10 EQU  $                 Out of room so:
       MOV  @WLINE,@LINENO    Flag this line
       ABS  @RMAFLA           Do a RMA ?
       JEQ  PUTN15            No
       BL   @RMGAD            Do the adjust
PUTN15 BL   @INSL10           Insert into text buffer
       INC  @RLINE            One done -source
       INC  @WLINE            One done - target
       BL   @CLRTMP           Clear temp buffer
       BL   @INITMP           Init L(R14)/R(R10) margins in TMP
       DEC  R14               Allow for the blank bump
       MOV  R14,@DESSAV       Preserve start pointer
       CB   *R13,@EOT         Was *R13 <cr> - end of para ?
       JNE  PUTN20            No - that's not all
 
*  Delete original text block after reformat and exit
 
REFR50 EQU  $
       BL   @RESTWS           Restore workspace registers
       BL   @BUMPC            Set up cursor and window
       MOV  @RLINE,R12        Has become start of reformatted block
       MOV  @WLINE,R15        End line of block
       MOV  R15,R14           Save for marker reset
       S    R15,R12           Length of delete block
       BL   @DLLSUB           Delete original block
REFR99 CLR  @RMAFLA           Cancel any right margin adjust
REFXIT B    @>0               All done now
 
*  Construct rest of TMP buffer contents
 
PUTN20 EQU  $
       INC  R14               Allow 1 blank between words
PUTN30 MOVB *R4+,*R14+        Move word to temp buffer
       DEC  R15               Less ROOM
       JGT  PUTN30
       ABS  @MFLAG            Marker flag set ?
       JEQ  PUTN35            No
       MOV  @WLINE,@SREGS     Hit marker, save cline
       MOV  @WLINE,@SREGS+4   Make sbias=cline
       MOV  R4,R6
       S    @MARKER,R6        Count # past marker.
       MOV  R14,R2            Desptr -> new cursor
       S    @TPM6A,R2         Adjust for buffer offset
       S    R6,R2             R6 < ROOM always!!!!
       MOV  R2,@SREGS+2       Update stored Cursor
       CLR  @MFLAG            Reset it now
PUTN35 MOV  R4,R13
       DEC  R13
       CB   *R13,@PERIOD      Full stop ?
       JNE  PUTN33            No - nothing special
       CB   @2(R13),@DSPACE
       JNE  PUTN33
       INC  R14               DESPTR
PUTN33 CB   *R13,@EOT         End of text marker?
       JEQ  PUTN10            Yes, update line, exit
       B    @GETNWD           No, get next word.
 
*  Set up data for Replace buffer
 
GETDAT EQU  $
       CLR  @MARKER           Set marker to start
       MOV  @RADR,R13         Start of REPbuf
       MOV  R13,R9            Copy start
       AI   R9,79             Construct end pointer
       MOV  R13,R4            Copy start pointer
       MOV  @RPM6A,@BUFADR    Start of REPbuf as fetch target
       MOV  @RLINE,@LINENO    Line # for TBuf fetch
       BLWP @GETLN            Get line from Text buffer
       MOV  R0,R0             End of file?
       JNE  GETD10            Yes
       INC  @RLINE            No, count this line
       INCT R11               Step over error return
GETD10 RT
 
*  Adjust right margin before sending back to text buffer
*--------------------------------------------------------
*  Line is in TMPBUF --  expand out to right margin
*  Build table of word gap start pointers
*  LMA already done by Reformat - indent implicit only
*  Preserve R1,R4,R9,R13,R15
 
RMGAD  EQU  $
       MOV  R11,@RMGD99+2     Establish return
       MOV  @DSPACE,R0        Byte saver
       BL   @INITMP           R14 - Lmrg, R10 - Rmrg
       MOV  R10,R12           Working copy of RM
RMGD05 C    R14,R12           Safety check
       JHE  RMGD99            Something has gone very wrong
       CB   *R14+,R0          Maybe there was top of par indent
       JEQ  RMGD05            Still a blank
       DEC  R14               Back off to first non-blank
 
*  Do not RMA last line (end with <cr>) of a paragraph
 
RMGD10 C    R12,R14           This check should not be necessary
       JL   RMGD99            Too far
       CB   *R12,@EOT         <cr> at end ?
       JEQ  RMGD99            Yes - avoid RMA
       CB   *R12,R0           Space ?
       JNE  RMGD20            No - exit pointing to end of last word
       DEC  R12               Previous - R12 is now new REnd
       JMP  RMGD10
 
*  Find # of spaces after last word  & # of gaps between words
 
RMGD20 S    R12,R10           # blanks after last word
       JEQ  RMGD99            No work to do
       LI   R5,BYTVBF         Use as temporary pointer area
       CLR  *R5+              Mark start with a null
       MOV  R5,R3             Copy pointer to first gap start
       CLR  R6                Initialize gap counter
       CLR  R7                Initialize punctuation counter
       MOV  R14,R8            Disposable copy of start pointer
RMGD30 C    R8,R12            At end already marked ?
       JHE  RMGD50            Yes
       INC  R8                Must start with non-blank
       CB   *R8,R0            Blank ?
       JNE  RMGD30            Same word
       INC  R6                Count a gap then
       BL   @CHKPUN           Check for a punctuation mark
       JMP  RMGD35            No
       INC  R7                Count it then
RMGD35 MOV  R8,*R5+           Put on list anyway - recheck later
RMGD40 INC  R8                Next byte
       CB   *R8,R0            Last is guaranteed non-blank
       JEQ  RMGD40            Same gap
       JMP  RMGD30            Look for next word
 
*  Move words towards end
 
RMGD50 CLR  *R5               Mark table end
       MOV  R6,R6             Only a single word ?
       JEQ  RMGD99            Yes - no adjust possible
RMGD55 LI   R5,BYTVBF         Start list at begin flag
RMGD60 INCT R5                Next entry
       MOV  *R5,R8            Fetch entry of each first blank
       JEQ  RMGD70            All done
       MOV  R7,R7             Any punctuation breaks ?
       JEQ  RMGD60            No - do by words only
       BL   @CHKPUN           Recheck if punctuation
       JMP  RMGD60            No - try next
       BL   @SHUFFL           Shuffle along
       JEQ  RMGD99            All done (after DEC R0)?
       JGT  RMGD60            No
 
*  Work backwards expanding gaps - alternate to near start
 
RMGD70 DECT R5                Back up an entry
       MOV  *R5,R8            Fetch entry
       JEQ  RMGD60            Null starter - work the punctuation again
       BL   @SHUFFL           Move along and adjust pointers
       JEQ  RMGD99            None left
       MOV  R5,R2             Save current
       MOV  R3,R5             Replace with starter
       MOV  *R5,R8            Has this gotten to end
       JEQ  RMGD75            Yes - do not use
       BL   @SHUFFL           Do the shuffle
       JEQ  RMGD99            All done
       INCT R3                Go to next
RMGD75 MOV  R2,R5             Restore pointer
       JMP  RMGD70            Resume loop
RMGD99 B    @>AAAA            Easy ID for binary search
 
*  Initialize TMP buffer pointers
 
INITMP EQU  $
       LI   R10,TEMPM6        TMP buffer start
       MOV  R10,R14           Copy buffer start
       A    @RMRG,R10         Set to right margin
       A    @LMRG,R14         Advance to left margin
       RT
 
*  Check end of word for punctuation
 
CHKPUN EQU  $
       DEC  R8                Back up to last char
       CB   *R8,@PERIOD       Was it the end of a sentence ?
       JEQ  CHKP10
       CB   *R8,@COMMA        Comma ?
       JEQ  CHKP10
       CB   *R8,@QUESTN       Question mark ?
       JEQ  CHKP10
       CB   *R8,@EXCLAM       Exclamation mark ?
       JEQ  CHKP10
       CB   *R8,@HYPHEN       Hyphen ?
       JEQ  CHKP10
       CB   *R8,@RPAREN       Right bracket?
       JNE  CHKP20
CHKP10 INCT R11               None of the above - step over counter
CHKP20 INC  R8                Restore pointer
       RT
 
*  Move along one byte from R8 to end
*-------------------------------------
*  Update pointers after shuffle start
 
SHUFFL EQU  $
       MOV  R5,R14            Copy current table pointer
SHFF10 INCT R14               Go to next
       MOV  *R14,*R14         Check for terminator
       JEQ  SHFF20            All done
       INC  *R14              Update for shift to come
       JMP  SHFF10            Next
 
SHFF20 MOV  R12,R14           Last char pointer
SHFF30 MOVB *R14+,*R14        Move to the next
       DECT R14               Back to previous
       C    R14,R8            At start of this move
       JHE  SHFF30            Not yet
       INC  R12               Update end of last word
       DEC  R10               Tick off one of spaces to adjust
       RT
 
*----------------------------------------------------------------
 
