*      
* NED -- SPED II
*
* A text editor lacking the total lameness of SPED.
* Designed for use with Muse (or Blahtune if you like).
*
* SLJ 5/9/98
*

         DSK '@0:ned'

         REL
         PUT 'diskio.ext.s'

CHROUT   = $FFD2
GETIN    = $FFE4
PLOT     = $FFF0
STOP     = $FFE1

TEXTP    = $61            ;Compiler pointer to text
CODEP    = $63            ;Compiled code destination
COMPILER EXT
*CLIP EXT  ;Now CLIP is at $E000
FRETOP   EXT

ACC      = $69

BLNSW    = $CC
BLNCT    = $CD
BLNON    = $CF

POINT    = $FD
TEMP     = $FF

MAXBUF   = 240            ;Maximum number of chars in buffer

*-------------------------------
         DO 0
         JMP NEDINIT

DEBUG    STA TMPA
         STX TMPX
         STY TMPY
         JSR GETCHAR
         JSR CHROUT
         LDA TMPA
         LDX TMPX
         LDY TMPY
         RTS
TMPA     DFB 0
TMPX     DFB 0
TMPY     DFB 0

MEMTOP   DA $A000
CLIPBUF  ENT
         DA $FFFF
         FIN
*-------------------------------

CLIPBUF  = $E000
CLIPSIZE DA $FFFF

TEXT     ENT
         DW $6000         ;Start of text
TEXTEND  ENT
         DW $6001         ;end of text

CURADR   DW $6000         ;Address of current line
ROW1     DW $6000         ;Address of line on row 1

CURLINE  DW 0             ;current text row
CURPOS   DFB 0            ;current position within the row

NEDINIT  ENT
* LDA #$40
* STA TEXT+1
* STA TEXTEND+1
         LDA TEXT
* STA TEXT
         STA CURADR
         STA ROW1
* CLC
* ADC #1
* STA TEXTEND
         LDA TEXT+1
         STA CURADR+1
         STA ROW1+1
* ADC #00
* STA TEXTEND+1
         LDA TEXTEND+1
         STA POINT+1
         LDA TEXTEND
         STA POINT
         LDA #13          ;End of line
         LDY #00
         STA (POINT),Y
         DEY
         DEC POINT+1
         STA (POINT),Y
         LDA #$FF
         STA TEMPROW      ;For clipping text
         LDX #00
         STX CURLINE
         STX CURLINE+1
         STX CURPOS
         LDY #00
         JSR PLOPXY

NED      LDA #12
         STA $D020
         LDA #6
         STA $D021
         LDA #1
         STA COLOR
         JSR REDRAW
NED2     JSR LINE2BUF

NEDIT    JSR STATBAR
         LDA #1
         STA COLOR
         JSR GETCHAR
         LDY $CB
         CPY #63          ;R/S pressed?
         BNE :CONT
         JMP EXIT2
:CONT    JSR ISCTRL       ;CTRL chars
         BNE :C1
         JSR PROCCTRL
         CLC
         JSR BUF2TEXT
         JMP NED
:C1      JSR ISFUNC       ;Function keys
         BNE :C2
         JSR PROCFUNC
         JMP NED
:C2      JSR ISEDIT       ;An editing command?
         BNE :NORMAL
         JSR PROCEDIT
         BCS NEDIT
         JSR BUF2TEXT     ;Carry clear
         JMP NED

:NORMAL  CMP #29          ;crsr rt
         BEQ :RT
         CMP #17
         BEQ :DN
         CMP #145
         BEQ :UP
         CMP #157
         BEQ :LF
         CMP #141
         BEQ :SHCR
         CMP #13
         BNE :CHAR
         JMP :CR

:CHAR    STA MODBUF
         LDY CURPOS
         STA BUFFER,Y
         JSR CHAROUT
:ADV     INC CURPOS
         LDA CURPOS
         CMP #MAXBUF      ;No more than MAXBUF chars
         BCS :OFLOW
         LDA COLUMN
         CMP #40          ;Past column 39, so redraw
         BCC NEDIT        ;screen

         LDX #00
:NEWSCR  STX COLUMN
         CLC
         JSR BUF2TEXT
:NEWJMP  JMP NED
:OFLOW   DEC CURPOS       ;Overflowed past MAXBUF
         DEC COLUMN
:JNEDIT  JMP NEDIT

:RT      INC COLUMN
         BNE :ADV

:LF      LDY CURPOS
         BEQ :JNEDIT
         DEC CURPOS
         DEC COLUMN
         BPL :JNEDIT
         LDX #39
         BNE :NEWSCR

:UP      CLC
         JSR BUF2TEXT
         JSR PREVLINE     ;Go to previous line
         BCS :JMPN2       ;At beginning of file
         JSR P2CURLN      ;Set curadr
         JSR DECCUR
         DEC ROW
         BPL :JMPN2
         INC ROW
         JSR P2ROW1       ;Set row1
         JSR SCREENDN     ;Move screen down
         JSR RELINE       ;Print row1
         JMP NED2

:DN      CLC
         BCC :CR2

:SHCR    LDX #$FF         ;Shifted-CR -- insert new line
:SHLOOP  LDA BUFFER-1,X
         STA BUFFER,X
         DEX
         BNE :SHLOOP
         STX COLUMN
         STX CURPOS
         LDA #13
         STA BUFFER
         STA MODBUF
         CLC
         JSR BUF2TEXT
         JMP NED

:CR      LDA #00
         STA COLUMN
         STA CURPOS
         SEC              ;Insert an extra CR
:CR2     PHP
         JSR BUF2TEXT
         JSR NEXTSET      ;Go to next line
         BCS :CRJMP       ;At EOF
         JSR P2CURLN      ;Set curadr
         JSR INCCUR
         INC ROW
         LDA ROW
         CMP #24
         BCC :CRJMP
         PLP
         DEC ROW
         JSR SETROW1
         JSR NEXTLINE
         JSR P2ROW1       ;Update row1
         JSR SCREENUP     ;Much faster
         JSR RELINE
:JMPN2   JMP NED2         ;Don't redraw for crsr dn
:CRJMP   PLP
         BCC :JMPN2
         JMP NED

INCCUR   INC CURLINE
         BNE :C1
         INC CURLINE+1
:C1      RTS

DECCUR   LDA CURLINE
         SEC
         SBC #1
         STA CURLINE
         LDA CURLINE+1
         SBC #00
         STA CURLINE+1
         ORA CURLINE      ;Set flags
         RTS

*
* Check for editing command
*
ISEDIT   
         CMP #20          ;del
         BEQ :RTS
         CMP #148         ;ins
         BEQ :RTS
         CMP #19          ;home
         BEQ :RTS
         CMP #147         ;clear
:RTS     RTS

PROCEDIT 
         STA MODBUF
         CMP #147
         BEQ :CLR
         CMP #20
         BEQ :DEL
         CMP #148
         BEQ :INS
         JMP HOME

:CLR     JSR SAVEPOS
         JSR REALLY
         CMP #'y'
         BNE :NOPE
         PLA
         PLA
         LDA TEXT
         CLC
         ADC #1
         STA TEXTEND
         LDA TEXT+1
         ADC #00
         STA TEXTEND+1
         JMP NEDINIT
:NOPE    JSR GETPOS
         SEC
         RTS

:INS     LDY #MAXBUF      ;insert
:LOOP    LDA BUFFER-1,Y
         STA BUFFER,Y
         DEY
         CPY CURPOS
         BNE :LOOP
         LDA #32
         STA BUFFER,Y
         BNE DRAWBUFF

:DEL     LDY CURPOS
         BEQ DRAWBUFF
         DEC CURPOS
         DEY
         DEC COLUMN
         BPL :LOOP2
         LDA #39          ;Back up a screen
         STA COLUMN
:LOOP2   LDA BUFFER+1,Y
         STA BUFFER,Y
         INY
         CPY #MAXBUF-1
         BCC :LOOP2
         LDA #32
         STA BUFFER+1,Y

* Draw from buffer

DRAWBUFF JSR SAVEPOS
         LDX ROW
         LDY #00
         JSR PLOPXY       ;Set screen row/column

         LDX SAVECOL      ;Find position in buffer
         LDY CURPOS
:LOOP    DEY
         DEX
         BPL :LOOP
         INY

PRBUFF                    ;Print from buffer
         LDX #39
:LOOP    LDA BUFFER,Y
         JSR CHAROUT
         INY
         DEX
         BNE :LOOP
         LDX BUFFER,Y
         INY
:LOOP2   LDA BUFFER,Y     ;Print slash?
         CMP #32
         BNE :SLASH
         INY
         CPY #MAXBUF
         BCC :LOOP2
         TXA              ;No extra chars
         DFB $2C
:SLASH   LDA #'/'
         JSR CHAROUT      ;Print last char
         JSR GETPOS
         SEC
         RTS

* HOME (Also used by load)

HOME     CLC
         JSR BUF2TEXT
HOME2    LDA #00
         STA ROW
         STA COLUMN
         STA CURPOS
         STA CURLINE
         STA CURLINE+1
HOME3    LDA TEXT
         STA POINT
         LDA TEXT+1
         STA POINT+1
         JSR P2CURLN
         JSR P2ROW1
         CLC              ;Redraw
         RTS

* Prompt for y/n response

REALLY   LDX #24
         LDY #00
         JSR PLOPXY
         LDA #13
         STA COLOR
         JSR PLOPSTR
         TXT '>>> really?',00
         JSR SPACE
         LDX #24
         STX ROW
         LDY #11
         STY COLUMN
         JMP GETCHAR

*
* Check for CTRL-char
*
ISCTRL   PHA
         LDA $028D
         AND #4
         TAX
         PLA
         CPX #4
         RTS

EXIT     PLA
         PLA
EXIT2    CLC
         JMP BUF2TEXT     ;See-ya!

PROCCTRL 
         CMP #7           ;g
         BEQ :GOTO
         CMP #3           ;c
         BEQ :CLIP
         CMP #24          ;x
         BEQ :CLIP
         CMP #16
         BEQ :PASTE
         CMP #4           ;ctrl-d
         BEQ :DELETE
         CMP #2           ;ctrl-b
         BEQ :BEGLN
         CMP #14          ;ctrl-n
         BEQ :ENDLN
         CMP #1           ;ctrl-a
         BEQ :ZAP
         CMP #10          ;ctrl-j
         BEQ :LF
         CMP #11          ;ctrl-k
         BEQ :RT
         CMP #13          ;ctrl-m
         BEQ :DN
         CMP #9           ;ctrl-i
         BEQ :UP
         CMP #26          ;ctrl-z
         BEQ :COMPILE
         LDA $CB
         CMP #57          ;ctrl-_
         BEQ EXIT
         RTS

:COMPILE JMP COMPILE
:CLIP    JMP CLIPTXT
:PASTE   JMP PASTE
:GOTO    JMP GOTO
:UP      JMP :UP2         ;lame

:BEGLN   LDA #00          ;Beginning of line
         STA CURPOS
         STA COLUMN
         RTS

:ENDLN   LDY #MAXBUF      ;Move to end of line
:LOOP3   LDA BUFFER-1,Y
         CMP #32
         BNE :DONE3
         DEY
         BNE :LOOP3
:DONE3   STY CURPOS
         TYA
         SEC
:LOOP3B  SBC #40
         BCS :LOOP3B
         ADC #40
         STA COLUMN
         RTS

:ZAP     STA MODBUF
         LDY CURPOS
         JMP FILLBUF

:DELETE  CLC
         JSR BUF2TEXT
         JSR SETBLOCK
         LDA POINT
         STA BLDEST
         LDA POINT+1
         STA BLDEST+1
         JMP SETMOVE

:RT      LDA CURPOS
         CLC
         ADC #40
         CMP #MAXBUF
         BCC :STA
         RTS
:LF      LDA CURPOS
         SEC
         SBC #40
         BCC :RTS
:STA     STA CURPOS
:RTS     RTS

:DN      CLC
         JSR BUF2TEXT
         JSR SETCURLN
         LDX #00
:L2A     JSR NEXTSET
         BCS :ATEND
         JSR P2CURLN
         INX
         CPX #24
         BNE :L2A
:ATEND   TXA              ;This lets us move to the bottom
         BEQ :RTS
         CLC              ;if less than 24 lines left.
         ADC CURLINE
         STA CURLINE
         BCC :C2A
         INC CURLINE+1
:C2A     JSR SETROW1
         CPX #24
         BEQ :L2B
         TXA              ;Only a partial move
         CLC
         ADC ROW          ;Did we move off the screen?
         STA ROW
         CMP #23
         BCC :RTS         ;If not, then punt
         SBC #23
         TAX
         LDA #23
         STA ROW
:L2B     JSR NEXTLINE     ;Otherwise, update row1
         DEX
         BNE :L2B
         JMP P2ROW1

:UP2     CLC
         JSR BUF2TEXT
         LDA CURLINE      ;Already on first screen?
         SEC
         SBC #24
         TAX
         LDA CURLINE+1
         SBC #00
         BCC :ZERO
         BNE :C1A         ;If near first screen, need to
         CPX #24          ;update ROW
         BCS :C1A
         STX ROW
:C1A     STA CURLINE+1
         STX CURLINE
         LDA #24
         STA TEMP
         JSR SETROW1
:L1A     JSR PREV2
         DEC TEMP
         BNE :L1A
         JSR P2ROW1
         LDA #24
         STA TEMP
         JSR SETCURLN
:L1B     JSR PREV2
         DEC TEMP
         BNE :L1B
         JMP P2CURLN

:ZERO    LDX #00          ;Move to top of screen
         STX ROW
         STX CURLINE
         STX CURLINE+1
         JMP HOME3

* Compile to $E000

COMPILE  CLC
         JSR BUF2TEXT
         LDA #$FF         ;Compiles into clipboard area
         STA CLIPSIZE+1

         LDA TEXTEND
         STA POINT
         LDA TEXTEND+1
         STA POINT+1

         LDA TEXT
         STA TEXTP
         LDA TEXT+1
         STA TEXTP+1
         LDA #$E0
         STA CODEP+1
         LDA #00
         STA CODEP
         TAY
         STA (POINT),Y    ;Text ends with a 00
         JSR STROUT
         DFB 147,5,13,13,00 ;Clear, white, lcase

         JSR COMPILER
         JSR WAITKEY      ;Press a key to continue...
         LDA TEXTEND
         STA POINT
         LDA TEXTEND+1
         STA POINT+1
         LDY #00
         LDA #13
         STA (POINT),Y
         JMP GETPOS

* Goto line

GOTO     CLC
         JSR BUF2TEXT
         JSR SAVEPOS
         LDX #24
         LDY #00
         JSR PLOPXY
         LDA #13
         STA COLOR
         JSR PLOPSTR
         TXT '>>> goto line:',00
         JSR SPACE
         LDX #24
         LDY #14
         CLC
         JSR PLOT
         LDX #5
         JSR INPUT
         BEQ :ABORT
         LDA #<STRBUF
         LDX #>STRBUF
         LDY #10
         JSR ASCTONUM
         BCS :ABORT

         JSR HOME2        ;Reset row1, etc.
:LOOP    LDA ACC          ;Line number, low byte
         BNE :DEC
         LDA ACC+1
         BEQ :DONE
         DEC ACC+1
:DEC     DEC ACC
         JSR NEXTSET
         BCS :DONE
         JSR P2CURLN
         JSR INCCUR
         JMP :LOOP

:DONE    JSR SETCURLN
         LDX #00
:LOOP2   JSR PREV2
         BCS :DONE2
         INX
         CPX #12          ;Center at row 12
         BNE :LOOP2
:DONE2   STX ROW
         JMP P2ROW1

:ABORT   JMP GETPOS

* Cut/copy text

TEMPROW  DFB $FF          ;Starting screen row
CUTROW   DFB 00           ;Original row/col for CUT
CUTCOL   DFB 00
CURTEMP  DW 00
CLIPSTRT DW 00            ;Starting address for clip
CLIPLINE DW 00
OLDROW1  DW 00

CLIPTXT  CLC
         JSR BUF2TEXT
         LDA ROW
         STA TEMPROW
         STA CUTROW
         LDA COLUMN
         STA CUTCOL
         LDA CURADR
         STA CLIPSTRT
         LDA CURADR+1
         STA CLIPSTRT+1
         LDA CURLINE
         STA CLIPLINE
         LDA CURLINE+1
         STA CLIPLINE+1
         LDA ROW1
         STA OLDROW1
         LDA ROW1+1
         STA OLDROW1+1

         JSR SAVEPOS
         LDX #24
         LDY #00
         JSR PLOPXY
         JSR REVON
         LDA #10
         STA COLOR
         JSR PLOPSTR
         TXT '>>> clip text >>>',00
         JSR REVOFF
         JSR SPACE
         JSR GETPOS
         LDA #1
         STA COLOR

         LDA #00
         STA CURTEMP
         STA CURTEMP+1
         JSR REVLINE

:WAIT    JSR GETIN
         BEQ :WAIT
         JSR ISCTRL
         BEQ :CLIP
         CMP #17          ;crsr dn
         BEQ :DN
         CMP #145         ;crsr up
         BNE :EXIT        ;cancel on anything else

:UP      JSR REVLINE

         LDX ROW
         BEQ :EXIT

         LDA CURTEMP
         BNE :C1
         DEC CURTEMP+1
         BMI :EXIT
:C1      DEC CURTEMP
         DEX
         LDY COLUMN
         JSR PLOPXY
         JSR PREVLINE
         JSR P2CURLN
         JSR DECCUR
         JMP :WAIT

:DN      JSR NEXTSET
         BCS :EXIT
         JSR P2CURLN
         JSR INCCUR
         INC CURTEMP
         BNE :C2
         INC CURTEMP+1
:C2      LDX ROW
         CPX #23
         BEQ :NEWSCR
         INX
         LDY COLUMN
         JSR PLOPXY
         JSR REVLINE
         JMP :WAIT

:NEWSCR  JSR SETROW1
         JSR NEXTLINE
         JSR P2ROW1
         JSR SCREENUP     ;Move screen up
         JSR RELINE
         LDA TEMPROW
         BEQ :WAIT
         DEC TEMPROW
         JMP :WAIT

:EXIT    LDA #$FF
         STA TEMPROW
         STA CLIPSIZE+1
         RTS

:CLIP    LDX #$FF
         STX TEMPROW
         CMP #3           ;copy
         BEQ COPY
         CMP #24          ;cut
         BNE :EXIT

CUT      JSR COPY
         JSR SETBLOCK

         LDA CLIPSTRT
         STA BLDEST
         STA CURADR
         LDA CLIPSTRT+1
         STA BLDEST+1
         STA CURADR+1
         LDA CLIPLINE
         STA CURLINE
         LDA CLIPLINE+1
         STA CURLINE+1
         LDA OLDROW1
         STA ROW1
         LDA OLDROW1+1
         STA ROW1+1
         JSR SETMOVE
         LDA CUTROW
         STA ROW
         LDA CUTCOL
         STA COLUMN
         JMP SAVEPOS

* Copy text to clipboard

COPY     LDA CLIPSTRT
         STA BLSTART
         LDA CLIPSTRT+1
         STA BLSTART+1
         JSR NEXTSET
         LDA POINT
         TAX              ;end-start = num bytes
         SEC
         SBC BLSTART
         STA POINT        ;temp
         LDA POINT+1
         TAY
         SBC BLSTART+1
         STA POINT+1
         TXA              ;Need to use nextline-1
         BNE :C1          ;as move boundary
         DEY
:C1      DEX
         STX BLEND
         STY BLEND+1

         LDA #<CLIPBUF
         STA BLDEST
         LDA #>CLIPBUF
         STA BLDEST+1
         LDA BLEND
         SEC
         SBC BLSTART
         STA CLIPSIZE
         LDA BLEND+1
         SBC BLSTART+1
         STA CLIPSIZE+1
         JMP BLMOVE

* Paste from clipboard

PASTE    CLC
         JSR BUF2TEXT
         LDA CLIPSIZE+1
         CMP #$FF
         BEQ :EXIT
         JSR SETCURLN
         JSR SETBL2
         LDA CLIPSIZE     ;Number of bytes
         SEC              ;+1
         ADC POINT        ;set to curadr
         STA BLDEST
         LDA CLIPSIZE+1
         ADC POINT+1
         STA BLDEST+1
         JSR SETMOVE      ;Move the text

         LDA #<CLIPBUF
         STA BLSTART
         CLC
         ADC CLIPSIZE
         STA BLEND
         LDA #>CLIPBUF
         STA BLSTART+1
         ADC CLIPSIZE+1
         STA BLEND+1

         LDA CURADR
         STA BLDEST
         LDA CURADR+1
         STA BLDEST+1
         SEI
         LDA $01
         PHA
         AND #$FC         ;Switch out ROM
         STA $01          ;since clipbuf = $E000
         JSR BLMOVE
         PLA
         STA $01
         CLI
:EXIT    RTS

* Reverse a line on the screen

REVLINE  LDY #39
:LOOP    LDA (SCREENP),Y
         EOR #$80
         STA (SCREENP),Y
         DEY
         BPL :LOOP
         RTS

*
* Move entire screen up one line
*
SCREENUP JSR SAVEPOS
         LDX #00
         STX ROW
:LOOP1   LDX #40
         STX TEMP
         LDY #00
         LDX ROW
         CPX #23
         BEQ :DONE
         JSR PLOPXY       ;set SCREENP
         LDY #40
         LDX #00
:LOOP2   LDA (SCREENP),Y
         STA (SCREENP,X)
         INC SCREENP
         BNE :C1
         INC SCREENP+1
:C1      DEC TEMP
         BPL :LOOP2
         INC ROW
         BNE :LOOP1
:DONE    JMP GETPOS

*
* Move entire screen down one line
*
SCREENDN JSR SAVEPOS
         LDX #22
         STX ROW
:LOOP1   LDX #40
         STX TEMP
         LDY #00
         LDX ROW
         JSR PLOPXY       ;set SCREENP
         LDY #40
         LDX #00
:LOOP2   LDA (SCREENP,X)
         STA (SCREENP),Y
         INC SCREENP
         BNE :C1
         INC SCREENP+1
:C1      DEC TEMP
         BNE :LOOP2
         DEC ROW
         BPL :LOOP1
         JMP GETPOS

*
* Check for Function keys
*
ISFUNC   CMP #$88         ;F7
         RTS

PROCFUNC 
         CLC
         JSR BUF2TEXT
         JSR SAVEPOS

:DISKIO  LDA #$FF         ;diskio
         STA LOADID+1     ;no ID check
         LDA TEXT
         STA LOADADDR
         STA SAVESTRT
         LDA TEXT+1
         STA LOADADDR+1
         STA SAVESTRT+1
         LDA TEXTEND
         STA SAVEEND
         LDA TEXTEND+1
         STA SAVEEND+1
         LDA #00
         STA SAVEFLAG     ;Enable save
         LDA #>:STRING
         LDX #<:STRING
         JSR DISKIO
         LDA NEWDATA
         BNE :NEW
         JMP GETPOS
:NEW     LDA $AE
         STA TEXTEND
         LDA $AF
         STA TEXTEND+1
         LDY #00
         LDA #13          ;Ending CR
         STA ($AE),Y
         JMP HOME2

:STRING  DFB 147,153,18   ;clear, lt. green, rvs
         TXT '         load/save text file            '
         DFB 13,13,146,00

*
* Set row/col, blink cursor, and get a key
*
GETCHAR  
         LDA COLOR
         STA $0286        ;Same blink color
         STA $0287
         LDX ROW
         LDY COLUMN
         CLC
         JSR PLOT
         LDX #1
         STX BLNCT
         LDA #00
         STA BLNSW
:W       LDX BLNON        ;Wait for at least one blink
         BNE :W

:READ    JSR STOP
         BEQ :OUT
         JSR GETIN
         BEQ :READ
:OUT     LDX #1
         STX BLNCT
:WAIT    LDX BLNON
         BEQ :WAIT
         INC BLNSW
         RTS


*
* Copy the current line into the edit buffer
*
LINE2BUF 
         LDA CURADR
         STA POINT
         LDA CURADR+1
         STA POINT+1
         LDY #00
         STY MODBUF
:LOOP    LDA (POINT),Y
         CMP #13
         BEQ FILLBUF
         STA BUFFER,Y
         INY
         CPY #MAXBUF
         BNE :LOOP
         LDA #32
         BNE LASTFILL

FILLBUF  LDA #32
:L2      STA BUFFER,Y
         INY
         CPY #MAXBUF
         BCC :L2
LASTFILL LDY MAXBUF
         STA BUFFER,Y
         RTS

*
* Copy from buffer into main text
*
* Carry set means add another CR (insert additional line)
*
MODBUF   DFB 00

BUF2TEXT 
         ROR TEMP
         BMI :MOD
         LDA MODBUF
         BEQ :EXIT
:MOD     LDA #00
         STA MODBUF
         JSR SETBLOCK

         LDY #MAXBUF      ;Find buffer length+1
:LOOP1   LDA BUFFER-1,Y
         CMP #32
         BNE :DONE1
         DEY
         BNE :LOOP1
                          ;+1 for a CR
:DONE1   LDA #13
         STA BUFFER,Y
         LDX TEMP         ;Add another CR?
         BPL :SKIP
         INY
         STA BUFFER,Y
:SKIP    SEC              ;+1 to move past last char
         TYA
         PHA
         ADC POINT
         STA BLDEST       ;Points to last char+1
         LDA POINT+1
         ADC #00
         STA BLDEST+1

         JSR SETMOVE

         PLA
         TAY              ;Finally, copy from buffer
:LOOP2   LDA BUFFER,Y
         STA (POINT),Y
         DEY
         CPY #$FF
         BNE :LOOP2
:EXIT    RTS

*
* Set up the block move
*
SETBLOCK 
         JSR NEXTSET
SETBL2   LDA POINT        ;Set up the block move
         STA BLSTART
         LDA POINT+1
         STA BLSTART+1
         LDA TEXTEND
         STA BLEND
         LDA TEXTEND+1
         STA BLEND+1
         JMP SETCURLN     ;Set POINT

*
* Set new end of text and move block.
*
SETMOVE  
         LDA TEXTEND      ;New end of text = eof+dest-start
         CLC
         ADC BLDEST
         TAX
         LDA TEXTEND+1
         ADC BLDEST+1
         STA TEXTEND+1
         TXA
         SEC
         SBC BLSTART
         STA TEXTEND
         LDA TEXTEND+1
         SBC BLSTART+1
         STA TEXTEND+1

         JMP BLMOVE       ;Move it, buster!

*
* Save current row and column
*
SAVEROW  DFB 00
SAVECOL  DFB 00

SAVEPOS  
         LDA ROW
         STA SAVEROW
         LDA COLUMN
         STA SAVECOL
         RTS
GETPOS   
         LDY SAVECOL
         LDX SAVEROW
         JMP PLOPXY

*
* Draw the screen
*
COL0OFF  DFB 00

REDRAW   
         JSR SAVEPOS
         JSR SETROW1
         JSR GETOFF

         LDX #00
:LOOP    STX TEMP
         LDY #00
         JSR PLOPXY       ;Set screen row/column
         JSR FINDPOS      ;Find position in line
         JSR PRLINE       ;Print line
         JSR NEXTLINE     ;Advance to next line
         LDX TEMP
         INX
         CPX #24
         BNE :LOOP
         JMP GETPOS

*
* Calculate screen offset
*
GETOFF   LDA #00
         STA TEMP
         LDA #$FF         ;Find screen col 0 offset in line
         CLC              ;i.e. 40*int(curpos/40)
:L1      ADC #40
         CMP CURPOS
         BCC :L1
         SBC #39
         STA COL0OFF
         RTS

*
* Redraw a single line
*
RELINE   JSR SETCURLN
         JSR SAVEPOS
         JSR GETOFF

         LDX ROW
         LDY #00
         JSR PLOPXY       ;Set screen row/column
         JSR FINDPOS      ;Find position in line
         JSR PRLINE       ;Print line
         JMP GETPOS

*
* Print status bar
*

STATBAR  
         JSR SAVEPOS
         LDX #24
         LDY #00
         JSR PLOPXY
         LDA #13
         STA COLOR
         JSR PNAME        ;Buffer name
         JSR PLOPSTR
         TXT ' line ',00
         LDA CURLINE
         LDX CURLINE+1
         LDY #10
         JSR PLOPNUM
         JSR PLOPSTR
         TXT ' col ',00
         LDA CURPOS
         LDX #00
         LDY #10
         JSR PLOPNUM
         JSR SPACE
         JMP GETPOS

PNAME    RTS

*
* Find position in line.  Specifically, find address
* of starting row in line.
*
* On exit, .Y = offset
*
FINDPOS  
         JSR LINELEN
         CPY COL0OFF
         BCC :RTS
         LDY COL0OFF
:RTS     RTS

* Find length of current line
* C clear indicates line > 256 chars

LINELEN  
         LDY #00
:LOOP    LDA (POINT),Y
         CMP #13
         BEQ :RTS
         INY
         CPY #MAXBUF
         BNE :LOOP
         CLC
:RTS     RTS

*
* Print line -- .Y contains line offset.
* When end of line is reached, spaces fill out the screen
*
PRLINE   
         LDX TEMPROW
         BMI :NOREV       ;Reverse line if clipped
         LDX ROW
         CPX TEMPROW
         BCC :NOREV
         JSR REVON
:NOREV   
         LDX #39
:LOOP    LDA (POINT),Y
         CMP #13
         BEQ SPACE
         JSR CHAROUT
         DEX
         BEQ SLASH
         INY
         BNE :LOOP

* Fill rest of screen line with char

SLASH    LDA #'/'
         DFB $2C
SPACE    LDA #' '
         LDX COLUMN
:LOOP    CPX #40
         BCS :RTS
         STX COLUMN
         JSR CHAROUT      ;Kerplop is faster, but need
         INX              ;reversed spaces
         BNE :LOOP
:RTS     JMP REVOFF

*
* Copy current line to pointer
*
SETCURLN 
         LDA CURADR
         STA POINT
         LDA CURADR+1
         STA POINT+1
         RTS
*
* Copy row1 to pointer
*
SETROW1  
         LDA ROW1
         STA POINT
         LDA ROW1+1
         STA POINT+1
         RTS
*
* Copy pointer to row1
*
P2ROW1   
         LDA POINT
         STA ROW1
         LDA POINT+1
         STA ROW1+1
         RTS
*
* Copy pointer to curadr
*
P2CURLN  
         LDA POINT
         STA CURADR
         LDA POINT+1
         STA CURADR+1
         RTS

*
* Advance.  Lines longer than MAXBUF get chopped+split!
*
* Carry set means at EOF
*
NEXTSET  
         JSR SETCURLN
NEXTLINE JSR ATEOF
         BCS :RTS
         JSR LINELEN
         BCS :CONT
         LDA #13          ;Split line if > MAXBUF
         STA (POINT),Y
:CONT    TYA
         SEC              ;Skip ending CR
         ADC POINT
         STA POINT
         BCC :RTS
         INC POINT+1
         JMP ATEOF
:RTS     RTS

*
* Back up.
*
* Carry set means already at start of file
*
PREVLINE 
         JSR SETCURLN
PREV2    JSR ATSTART
         BCS :RTS
         LDA POINT        ;Move past ending CR
         BNE :C1
         DEC POINT+1
:C1      DEC POINT

         LDY #00
:LOOP    JSR ATSTART
         BCS :CLC
         LDA POINT
         BNE :C2
         DEC POINT+1
:C2      DEC POINT
         LDA (POINT),Y
         CMP #13
         BNE :LOOP
         INC POINT        ;Move past CR
         BNE :CLC
         INC POINT+1
:CLC     CLC
:RTS     RTS

*
* Check if at end of file
*
ATEOF    
         LDA POINT
         CMP TEXTEND
         LDA POINT+1
         SBC TEXTEND+1
         RTS
*
* Check if at start of file
*
ATSTART  
         LDA TEXT
         CMP POINT
         LDA TEXT+1
         SBC POINT+1
         RTS

BUFFER   DS MAXBUF+2

