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 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+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+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...