P*      
* NED -- SPED II
*
* A text editor lacking the total lameness of SPED.
* Designed for use with Muse (or Blahtune if you like).
*
* This version is for use with El Cheapo Assembler.
*
* SLJ 12/27/98
*

         DSK '@0:ned'

         REL
         PUT 'diskio.ext.s'

ASSEND   = $9500          ;Highest point for text.

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

         DO 0
TEXTP    = $61            ;Compiler pointer to text
CODEP    = $63            ;Compiled code destination
         FIN

ASSERR   EXT
ASSLINE  EXT
BASIC    EXT
ASSEMBLE EXT
MONITOR  EXT
CODEFLAG EXT
*CLIP EXT  ;Now CLIP is at $E000

ACC      = $69

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

POINT    = $FD
TEMP     = $FF

MAXBUF   = 240            ;Maximum number of chars in buffer

CLIPBUF  = $E000
CLIPSIZE DA $FFFF

TEXT     ENT
         DW $0800         ;Start of text
TEXTEND  ENT
         DW $0801         ;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

QUOTE    DFB 00           ;Within quotes
EDITMODE DFB 00           ;Editing mode

EDITOR   ENT
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 #13          ;End of line
         JSR SETEND       ;.Y = 0
         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

HINED    
         LDA #14          ;lower case
         JSR CHROUT
         LDA #1
         STA $CF          ;Last blink

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
         BNE :CONT        ;R/S pressed?
         JSR SETTAB
         JMP NEDIT
: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 #157
         BEQ :LF
         CMP #145
         BEQ :UP
         CMP #17
         BNE :CONT1
         JMP :DN
:CONT1   CMP #141
         BNE :CONT2
         JMP :SHCR
:CONT2   CMP #13
         BNE :CHAR
         JMP :CR

:CHAR    STA MODBUF
         BIT EDITMODE
         BPL :NOINS
         JSR INSERT
         INC COLUMN
         BNE :ADV
:NOINS   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 :JNEDIT      ;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 RELINE
         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
         JMP :RELINE      ;Print row1 / current line

: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 RELINE       ;For crsr dn
         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
:RELINE  JSR RELINE
:JMPN2   JMP NED2         ;Don't redraw all 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

*
* SETTAB
*
*  column 0-8   label
*         9-12  opcode
*         13-21 arg
*         22-   comment
*
SETTAB   
         LDY CURPOS
         LDA $028D
         AND #1
         BNE :BACK
         CPY #9
         BCC :C9
         CPY #13
         BCC :C13
         CPY #22
         BCS :RTS
:C22     LDX #22
         DFB $2C
:C13     LDX #13
         DFB $2C
:C9      LDX #9
         DFB $2C
:C0      LDX #00
         STX CURPOS
         STX COLUMN
:RTS     RTS

:BACK    CPY #10
         BCC :C0
         CPY #14
         BCC :C9
         CPY #23
         BCC :C13
         BCS :C22

         DO 0
         STX TEMP
         LDA #160
:STA     STA BUFFER,Y
         LDA #32
         JSR CHAROUT
         INY
         CPY TEMP
         BCC :STA
         STY CURPOS
:RTS     RTS
         FIN

*
* 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

HOMELINE DA 01
HOMEPOS  DFB 00
HOMECOL  DFB 00

PROCEDIT 
         STA MODBUF
         CMP #147
         BEQ :CLR
         CMP #20
         BEQ :DEL
         CMP #148
         BEQ :INS
         LDA CURLINE
         ADC #1           ;C clear
         STA HOMELINE
         LDA CURLINE+1
         ADC #00
         STA HOMELINE+1
         LDA CURPOS
         STA HOMEPOS
         LDA COLUMN
         STA HOMECOL
         RTS
:DEL     JMP DELETE
:GOHOME  
         CLC
         JSR BUF2TEXT
         LDA HOMELINE
         STA ACC
         LDA HOMELINE+1
         STA ACC+1
         JSR SAVEPOS
         JSR GOTOLINE
         LDA HOMEPOS
         STA CURPOS
         LDA HOMECOL
         STA COLUMN
         CLC
         RTS

:CLR     LDA $028D
         AND #2
         BNE :GOHOME
         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     
         LDA $028D
         AND #2
         BEQ INS2
         LDA #$80
         EOR EDITMODE
         STA EDITMODE
         RTS
INSCHAR  DFB 32           ;Insert character

INS2     LDA #32
INSERT   STA INSCHAR
         LDY #MAXBUF      ;insert
:LOOP    LDA BUFFER-1,Y
         STA BUFFER,Y
         DEY
         CPY CURPOS
         BNE :LOOP
         LDA INSCHAR
         STA BUFFER,Y
         BNE DRAWBUFF
DELETE   
         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   LDA #13
         JSR SETBAR
         JSR PLOPSTR
         TXT '>>> really?',00
         JSR SPACE
         LDX #24
         LDY #11
REALLY2  STX ROW
         STY COLUMN
         JMP GETCHAR

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

EXIT     PLA
         PLA
EXIT2    JSR SAVEALL      ;See-ya!
         LDA #147
         JSR CHROUT
         JMP MONITOR

PROCCTRL 
         LDX $CB
         CPX #48          ;ctrl-\
         BEQ :DASH
         CPX #54          ;ctrl-^
         BEQ :STAR
         CPX #53          ;ctrl-=
         BEQ :EQU
         CPX #57          ;ctrl-_
         BEQ :BASIC
         CMP #7           ;g
         BEQ :GOTO
         CMP #3           ;c
         BEQ :CLIP
         CMP #24          ;x
         BEQ :CLIP
         CMP #16
         BEQ :PASTE
         CMP #4           ;ctrl-d
         BEQ :DEL
         CMP #2           ;ctrl-b
         BEQ :BEGLN
         CMP #14          ;ctrl-n
         BEQ :ENDLN
         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 :FORMAT
         CMP #1           ;ctrl-a
         BEQ :ZAP
         CMP #15          ;ctrl-o
         BEQ :OOPS
         CMP #12          ;ctrl-l
         BEQ :LAB
         CMP #6           ;ctrl-f
         BEQ :FIND
         RTS

:BASIC   PLA
         PLA
         JSR SAVEALL
         JMP BASIC
:RTS     RTS

:FORMAT  JMP FORMAT
:CLIP    JMP CLIPTXT
:PASTE   JMP PASTE
:GOTO    JMP GOTO
:UP      JMP GOUP
:DN      JMP GODN
:LF      JMP GOLF
:RT      JMP GORT         ;Klaatu
:DEL     JMP DELINE
:BEGLN   JMP BEGLN
:ENDLN   JMP ENDLN

:EQU     LDA #'='
         DFB $2C
:STAR    LDA #'*'
         DFB $2C
:DASH    LDA #'-'
         JMP BUFCOM

:LAB     LDA $028D
         AND #1
         BEQ :FL2
         JMP NLAB
:FL2     JMP FINDLAB
:FIND    LDA $CB          ;CTRL-f and CTRL-_ the same
         CMP #57
         BEQ :BASIC
         LDA $028D
         AND #$01
         BEQ :F2
         JMP NFIND
:F2      JMP FIND

:OOPS    JSR LINE2BUF
         JMP DRAWBUFF

:ZAP     STA MODBUF
         LDX CURPOS
         JMP FILLBUF

BEGLN    LDA $028D        ;Beginning of line
         AND #1
         BEQ :BEG2
         JMP HOME         ;First line
:BEG2    STA CURPOS
         STA COLUMN
:RTS     RTS

ENDLN    LDA $028D        ;Move to end of line
         AND #1
         BEQ :END2
         LDA #$FF
         STA ACC
         STA ACC+1
         JMP GOTOLINE
:END2    LDY #MAXBUF
: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

GORT     LDA CURPOS
         CLC
         ADC #40
         CMP #MAXBUF
         BCC GOLFSTA
         RTS
GOLF     LDA CURPOS
         SEC
         SBC #40
         BCC GOLFRTS
GOLFSTA  STA CURPOS
GOLFRTS  RTS

GODN     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 GOLFRTS
         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 GOLFRTS      ;If not, then punt
         SBC #23
         TAX
         LDA #23
         STA ROW
:L2B     JSR NEXTLINE     ;Otherwise, update row1
         DEX
         BNE :L2B
         JMP P2ROW1

GOUP     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

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

BUFCOM   PHA              ;Set comment
         LDA #'*'
         STA BUFFER
         STA MODBUF
         LDA #32
         LDX #MAXBUF
:L2      STA BUFFER,X
         DEX
         CPX #31
         BNE :L2
         PLA
:LOOP    STA BUFFER,X
         DEX
         BNE :LOOP
         JMP DRAWBUFF

FORMAT   JSR SAVEALL      ;Re-format all text
         JSR HOME3
:LOOP    JSR P2CURLN
         JSR LINE2BUF
         INC MODBUF
         INC $D020
         CLC
         JSR BUF2TEXT
         JSR NEXTSET
         BCC :LOOP
         JMP HOME2

* Save stuff to exit program

SAVEALL  
         LDA #$FF         ;Labels may extend into
         STA CLIPSIZE+1   ;clipboard area
SAVEALL2 
         CLC
         JSR BUF2TEXT
         LDA #00
         STA NEWFIND
         JMP SAVEPOS

* Restore stuff

RESTORE  ENT
         JSR GETPOS
         JMP HINED

* Compile to $010800

SETEND   
         LDY TEXTEND
         STY POINT
         LDY TEXTEND+1
         STY POINT+1
         LDY #00
         STA (POINT),Y    ;Text ends with a 00 or 13
         RTS
COMPILE  
         JSR SAVEALL
         DO 0
         LDA TEXT
         STA TEXTP
         LDA TEXT+1
         STA TEXTP+1
         LDA #$E0
         STA CODEP+1
         LDA #00
         STA CODEP
         FIN

         LDA #00          ;Text ends with 00
         JSR SETEND

         JSR STROUT
         DFB 147,5,13,13  ;Clear, white,
         TXT 'Assembling...',0d,00

         JSR ASSEMBLE
         JSR WAITKEY      ;Press a key to continue...
         LDA #13
         JSR SETEND
         LDA ASSERR
         BNE :GO
:JMP     JMP GETPOS
:GO      LDA ASSLINE
         STA ACC
         LDA ASSLINE+1
         STA ACC+1
         JMP GOTOLINE

* Goto line

GOTO     CLC
         JSR BUF2TEXT
         LDA #13          ;Color
         JSR SETBAR
         JSR PLOPSTR
         TXT '>>> goto line:',00
         JSR SPACE
         LDX #24
         LDY #14
         CLC
         JSR PLOT
         LDX #5
         JSR INPUT
         BEQ GOABORT
         LDA #<STRBUF
         LDX #>STRBUF
         LDY #10
         JSR ASCTONUM
         BCS GOABORT
         LDA ACC
         ORA ACC+1
         BEQ GOABORT
GOTOLINE 
         JSR HOME2        ;Reset row1, etc.

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

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

GOABORT  JMP GETPOS

* Find text/label

FINDLINE DA 00
FINDFLAG DFB 00
NEWFIND  DFB 00

NLAB     LDA #$80
         DFB $2C
NFIND    LDA #00
         LDX #00
         STX NEWFIND
         DFB $2C
FINDLAB  LDA #$80
         DFB $2C
FIND     LDA #00
         STA FINDFLAG
         CLC
         JSR BUF2TEXT
         LDA NEWFIND
         BNE :NEXT
         JSR SAVEPOS
         LDA CURLINE
         STA FINDLINE
         LDA CURLINE+1
         STA FINDLINE+1
         LDA #13
         JSR SETBAR
         JSR PLOPSTR
         TXT '>>> find:',00
         JSR SPACE
         LDX #24
         LDY #9
         CLC
         JSR PLOT
         LDX #30
         JSR INPUT
         BEQ GOABORT
         INC NEWFIND
         JSR HOME2
:FIND    JSR SETCURLN
:L2      LDY #00
         STY TEMP
:LOOP    LDY TEMP
         LDA (POINT),Y
         CMP #13
         BEQ :NEXT
         JSR COMPARE
         BCS :FOUND
         LDA FINDFLAG
         BMI :NEXT
         INC TEMP
         BNE :LOOP
:NEXT    JSR NEXTSET
         BCS :EOF
         JSR INCCUR
         JSR P2CURLN
         JMP :L2
:EOF     LDA #00
         STA NEWFIND      ;At EOF
         JSR GETPOS
         LDA FINDLINE
         STA ACC
         LDA FINDLINE+1
         STA ACC+1
         JMP GOTOLINE
:FOUND   JMP CENTER


COMPARE  
         LDX #00
:LOOP    LDA STRBUF,X
         BEQ :SEC         ;Gotcha
         CMP (POINT),Y
         BNE :CLC
:INY     INY
         INX
         BNE :LOOP
:SEC     SEC
         DFB $24
:CLC     CLC
         RTS


* 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

         LDA #10
         JSR SETBAR
         JSR REVON
         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
         BEQ :RTS
         CMP #133         ;F1 -- assemble
         BEQ :RTS
         CMP #137         ;F2 -- exit to monitor
:RTS     RTS

PROCFUNC 
         CMP #$88
         BEQ :DISKIO
         CMP #133
         BEQ :COMP
         JMP EXIT
:COMP    JMP COMPILE

:DISKIO  
         JSR SAVEALL2
         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

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

*
* Set row/col, blink cursor, and get a key
*
LASTKEY  DFB 00
GETCHAR  
         LDA COLOR
         STA $0286        ;Same blink color
         STA $0287
         LDX ROW
         LDY COLUMN
         CLC
         JSR PLOT
         LDA #1
         STA BLNCT
         LDX #00
         STX BLNSW
:W       LDX BLNON        ;Wait for at least one blink
         BNE :W
                          ;.A = 1
:READ    STA LASTKEY      ;Debouncing kludge
         JSR GETIN
         BEQ :READ
         LDX $CB          ;debounce
         CPX #63
         BNE :OUT
         LDA LASTKEY
         BNE :READ
:OUT     LDX #1
         STX BLNCT
:WAIT    LDX BLNON
         BEQ :WAIT
         INC BLNSW
         STA LASTKEY
         AND #$FF
         RTS


*
* Copy the current line into the edit buffer
*
LINE2BUF 
         LDA CURADR
         STA POINT
         LDA CURADR+1
         STA POINT+1
         LDX #00
         LDY #00
         STY MODBUF
         STY QUOTE

:LOOP    LDA (POINT),Y
         BEQ FILLBUF
         CMP #13
         BEQ FILLBUF
         CMP #34
         BEQ :QUOTE
         CMP #39
         BEQ :QUOTE
         CMP #';'
         BEQ :COM
         CMP #160         ;tab
         BEQ :TAB
         CMP #224
         BEQ :TAB2
:STA     STA BUFFER,X
         INX
:INY     INY
         CPX #MAXBUF
         BCC :LOOP
         BCS FILLBUF

:QUOTE   STA TEMP
         EOR QUOTE
         BEQ :STQ
         CMP TEMP
         BNE :LDT
:STQ     STA QUOTE
:LDT     LDA TEMP
         BNE :STA

:COM     STA TEMP
         LDA QUOTE
         BNE :LDT
         ORA #$FF
         BNE :STQ

:TAB     STA TEMP
         LDA QUOTE
         BNE :LDT
         LDA TEMP
         CPX #9
         BCC :C9
         CPX #13
         BCC :C13
:TAB2    LDA #22
         DFB $2C
:C9      LDA #9
         DFB $2C
:C13     LDA #13
         STA TEMP
         LDA #32
:L2      STA BUFFER,X
         INX
         CPX TEMP
         BCC :L2
         BCS :INY

FILLBUF  LDA #32
:L2      STA BUFFER,X
         INX
         CPX #MAXBUF
         BCC :L2
         STA BUFFER,X
         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

         JSR CRUNCH

* The Big Kludge
         DO 0
         LDY #MAXBUF      ;Find buffer length+1
:LOOP1   LDA BUFFER-1,Y
         CMP #32
         BNE :DONE1
         DEY
         BNE :LOOP1
         FIN
                          ;+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

*
* CRUNCH removes excess spaces within BUFFER
* On exit, spaces are removed, and .Y points to last
* character+1
*
* Currently, The Big Kludge is used to calculate the
* actual end of the line, above.
*
* Shift-spaces are used for tabs.
*
CRUNCH   
         LDX #00          ;Current position
         LDY #00          ;Destination position
         STX QUOTE

         LDA BUFFER,X     ;Label field
         CMP #'*'
         BEQ :REST
         CMP #';'
         BEQ :REST
         JSR :COPYSPC
         BCC :RTS
         INY

         LDA BUFFER,X     ;Opcode
         CMP #';'
         BEQ :COMMENT
         JSR :COPYSPC
         BCC :RTS
         INY

         LDA BUFFER,X     ;Arg
         CMP #';'
         BEQ :COMMENT
*-------------------------------
         DO 0
         CMP #34          ;quote
         BEQ :CQ
         CMP #39
         BNE :CS
:CQ      JSR :COPYQ
         BCC :RTS
         BCS :COM
         FIN
*-------------------------------
:CS      JSR :COPYSPC
         BCC :RTS
         INY

:COM     LDA BUFFER,X
         CMP #';'
         BNE :REST
:COMMENT LDA #224         ;Another space
         STA BUFFER-1,Y

:REST    LDA #$FF         ;Copy rest of line
         STA QUOTE

:COPYSPC                  ;Copy until a space/tab is found
:L1      LDA BUFFER,X
         INX
         ROL QUOTE
         ROR QUOTE
         BNE :INQUOTE     ;Keep going if within quotes
         CMP #224
         BEQ :NEXTCHR
         CMP #160
         BEQ :NEXTCHR
         CMP #32
         BEQ :NEXTCHR
:INQUOTE STA BUFFER,Y
         INY
         CMP #34          ;Check for quotes
         BEQ :QUOTE
         CMP #39
         BNE :CHECK

:QUOTE   BIT QUOTE        ;Toggle quote flag
         BEQ :STA
         EOR QUOTE
         BNE :STY
:STA     STA QUOTE

:CHECK   CMP #32          ;Remember last non-space
         BEQ :CPX
:STY     STY ACC+1        ;Store last non-space
:CPX     CPX #MAXBUF
         BCC :L1
         LDY ACC+1        ;Last non-space
         CLC
         RTS

:NEXTCHR                  ;Find next non-space
:C1      LDA BUFFER,X
         CMP #32
         BNE :RTS
         INX
         CPX #MAXBUF
         BCC :C1
         CLC
:RTS     LDA #160         ;INY is above
         STA BUFFER,Y
         RTS              ;C clear -> MAXBUF


*-------------------------------
         DO 0
:COPYQ   STA ACC          ;Copy until quote is found
:L2      LDA BUFFER,X
         STA BUFFER,Y
         INY
         CMP #32
         BEQ :INX
         STY ACC+1        ;Store last non-space char
:INX     INX
         CMP ACC
         BEQ :RTS2
         CPX #MAXBUF
         BCC :L2
         CLC              ;C clear -> MAXBUF
         LDY ACC+1
         RTS
         FIN
*-------------------------------

*
* 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 ACC+1
         TXA
         SEC
         SBC BLSTART
         TAX
         LDA ACC+1
         SBC BLSTART+1
         CMP #>ASSEND
         BCS :ERR
         STX TEXTEND
         STA TEXTEND+1

         JMP BLMOVE       ;Move it, buster!

:ERR     LDA #7
         JSR SETBAR
         JSR PLOPSTR
         TXT 'Out of memory!',00
         JSR SPACE
         LDX #24
         LDY #14
         JSR REALLY2
         JMP GETPOS

*
* 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
*
SETBAR   
         STA COLOR
         JSR SAVEPOS
         LDX #24
         LDY #00
         JMP PLOPXY

STATBAR  
         LDA #13
         JSR SETBAR
* JSR PNAME ;Buffer name
         JSR PLOPSTR
         TXT ' line ',00
         LDX CURLINE+1
         LDA CURLINE
         CLC
         ADC #1
         BCC :C1
         INX
:C1      
         LDY #10
         JSR PLOPNUM
         JSR PLOPSTR
         TXT ' col ',00
         LDA CURPOS
         LDX #00
         LDY #10
         JSR PLOPNUM
         LDA EDITMODE
         BPL :SPACE
         JSR PLOPSTR
         TXT ' (insert)',00
:SPACE   JSR SPACE
         JMP GETPOS


*
* 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 #00

:LOOP    LDA (POINT),Y
         CMP #13
         BEQ SPACE
         CMP #224
         BEQ :TAB2
         CMP #160
         BNE :NORMAL

         LDA #9           ;Handle tabs
         CPX #9
         BCC :C1
         LDA #13
         CPX #13
         BCC :C1
:TAB2    LDA #22
:C1      STA ACC
         LDA #32
:L1      JSR CHAROUT
         INX
         CPX ACC
         BCC :L1
         INY
         BNE :LOOP

:NORMAL  JSR CHAROUT
         INX
         CPX #39
         BCS 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 :JMP
         INC POINT+1
:JMP     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+4      ;Little extra padding...
