Mercurial > hg > Members > kono > nitros9-code
view level1/cmds/minted.asm @ 2954:43588191b624
rules.mak: Generate assembly listings if LISTDIR is defined
This is useful for debugging.
author | Tormod Volden <debian.tormod@gmail.com> |
---|---|
date | Sat, 08 Feb 2014 02:12:13 +0100 |
parents | 41a6f70d842d |
children |
line wrap: on
line source
* * MinTED Minimalist Text Editor for OS-9 6809 * * * This is freeware and open source. Use it as you wish. * 2013 Luis Antoniosi * nam MinTED ttl MinTED for OS-9 6809 ; 2013 Luis Antoniosi ifp1 use defsfile endc tylg set Prgrm+Objct atrv set ReEnt+rev rev set $03 edition set 1 mod eom,name,tylg,atrv,start,size org 0 undo_item struct previous rmb 2 next rmb 2 scrline rmb 2 cx rmb 1 cy rmb 1 key rmb 1 topstr rmb 2 endstruct org 0 sgn_code rmb 1 cx rmb 1 cy rmb 1 tcx rmb 1 key rmb 1 edited rmb 1 width rmb 2 height rmb 2 cntlin rmb 2 curstr rmb 2 ; temp cur str curptr rmb 2 ; temp cur ptr topstr rmb 2 ; top screen current string topptr rmb 2 ; top screen string pointer topscr rmb 2 ; curlen rmb 2 ; current string len curmsiz rmb 2 ; current malloc size gotocmd rmb 3 ; cursor locate cmd malsize rmb 2 remsize rmb 2 delstr rmb 2 renderall rmb 1 currows rmb 1 strlen rmb 2 prevchar rmb 1 curchar rmb 1 strptr rmb 2 ; first string pointer scrline rmb 2 ; current top screen line curline rmb 2 ; current cursor screen line scrlines rmb 2 ; total screen lines undoptr rmb 2 ; undo first item undoflag rmb 1 ; termcap rmb 1 ; terminal capabilities himem rmb 2 ; application high memory bufsize rmb 2 ; buffer size scrbuf rmb 2 ; screen buffer addr scrsize rmb 2 ; screen buffer size membuf rmb 2 ; memory buffer addr memsize rmb 2 ; memory buffer size memstart rmb 2 ; memory start chunck oldecho rmb 1 ; original term echo3 oldalf rmb 1 ; original term auto line-feed filepath rmb 1 ; file path number argc rmb 2 ; number of args optbuf rmb 32 ; SS/GS OPT buffer filename rmb 256 ; filename readbuf rmb 256 ; read buffer args rmb 256 ; 128 max args VAR_SIZE equ . ; work variables size STACK_SIZE equ 256 ; reserved stack size IFEQ Level-1 buffer rmb (20*1024-VAR_SIZE) ELSE buffer rmb (54*1024-VAR_SIZE) ENDC size equ . stdin equ 0 stdout equ 1 stderr equ 2 K$Shift equ $10 K$Up equ $0c K$Down equ $0a K$Left equ $08 K$Right equ $09 K$ShiftUp equ $1c K$ShiftDown equ $1a K$ShiftLeft equ $18 K$ShiftRight equ $19 K$CtrlUp equ $13 K$CtrlDown equ $12 K$CtrlLeft equ $10 K$CtrlRight equ $11 K$CtrlK equ $0b K$CtrlD equ $04 K$CtrlW equ $17 K$CtrlR equ $12 K$CtrlS equ $13 K$CtrlO equ $0f K$CtrlG equ $07 K$CtrlU equ $15 VDG_CAP equ $00 ; vdg defaul terminal WIN_CAP equ $01 ; window capabilities (Level 2) name fcs /MinTED/ fcb edition errPNNF fcn "Path Name not found" errMF fcn "Memory full" errRF fcn "Error reading file" errWF fcn "Error writing file" errBreak fcn " - press break" msgConfirm fcn "Exit without saving (y/n)?" msgSave fcn "Save file (y/n)?" msgRename fcn "Rename/Save as: " msgSaving fcn "Saving " msgLineNo fcn "Go to line: " msgHelp fcc "Minted: Minimalist Text Editor" fcb $0a,$0d fcb $0a,$0d fcc "Hot keys:" fcb $0a,$0d fcb $0a,$0d fcc "Ctrl+S = Save file" fcb $0a,$0d fcc "Ctrl+R = Rename file" fcb $0a,$0d fcc "Ctrl+K = Delete line" fcb $0a,$0d fcc "Ctrl+D = Duplicate line" fcb $0a,$0d fcc "Ctrl+O = Online help" fcb $0a,$0d fcc "Ctrl+E = Exit" fcb $0a,$0d fcc "Ctrl+G = Go to line" fcb $0a,$0d fcc "Ctrl+U = Undo" fcb $0a,$0d fcc "Cursor Keys = Move cursor" fcb $0a,$0d fcc "Shift+Left = Delete left" fcb $0a,$0d fcc "Shift+Right = Delete right" fcb $0a,$0d fcc "Shift+Up = Page up" fcb $0a,$0d fcc "Shift+Down = Page down" fcb $0a,$0d fcc "Ctrl+Left = Go to line begin" fcb $0a,$0d fcn "Ctrl+Right = Go to line end" brkpnt rts start lbsr _getargs lbsr _init lbsr _open tst <filepath beq @skip lbsr _read lbsr _close @skip lbsr _cntlines lbsr _renderall lbsr _navigate lbsr _cls lbsr _curon @end lbra _exit _getargs clr argc,u clr argc+1,u leay args,u @pre tstb ; check arg string beq @noargs decb lda ,x+ cmpa #13 ; linefeed ? beq @endargs cmpa #32 ; space delimiter ? beq @pre leax -1,x stx ,y++ leax 1,x inc argc+1,u ; inc arg count @arg tstb beq @endargs ; has ended ? decb lda ,x+ cmpa #13 ; linefeed ? beq @endargs cmpa #32 ; space delimiter ? bne @arg @endline leax -1,x clr ,x+ ; set null termination bra @pre @endargs clr -1,x @noargs rts _icept stb sgn_code,u rti _init clr sgn_code,u leax _icept,pcr os9 F$Icpt lbcs _abort lda #stdin ldb #SS.Opt leax optbuf,u os9 I$GetStt lda (PD.EKO-PD.OPT),x sta oldecho,u clr (PD.EKO-PD.OPT),x lda (PD.ALF-PD.OPT),x sta oldalf,u clr (PD.ALF-PD.OPT),x lda #stdin ldb #SS.Opt leax optbuf,u os9 I$SetStt lda #1 ldb #SS.ScSiz os9 I$GetStt ; get screen dimensions lbcs _abort stx width,u sty height,u lda width+1,u ldb height+1,u mul std scrsize,u ; compute screen size leax buffer,u stx scrbuf,u leax d,x stx membuf,u ; compute memory buffer dec height+1,u ; ldd #0 os9 F$Mem ; get memory boundaries lbcs _abort leay -STACK_SIZE,y sty himem,u subd #VAR_SIZE subd #STACK_SIZE subd scrsize,u std bufsize,u ; compute buffer size lbsr _meminit ; init memory manager lbsr _strinit lda #VDG_CAP sta termcap,u lda #1 ldb #SS.ScTyp os9 I$GetStt ; get screen dimensions lbcs @nonwin lda #WIN_CAP sta termcap,u @nonwin rts _deinit pshs a,b,x,y,cc leax optbuf,u lda oldecho,u sta (PD.EKO-PD.OPT),x lda oldalf,u sta (PD.ALF-PD.OPT),x lda #stdin ldb #SS.Opt os9 I$SetStt lbsr _curon puls a,b,x,y,cc,pc curoff fcb $05,$20 curon fcb $05,$21 clrlin fcb $0b cls fcb $0c home fcb $01 insline fcb $1f,$30 delline fcb $1f,$31 _clrlin pshs a,b,x,y lda #stdout leax clrlin,pcr ldy #1 os9 I$Write ; turn off cursor lbcs _abort puls a,b,x,y,pc _curon pshs a,b,x,y lda #stdout leax curon,pcr ldy #2 os9 I$Write ; turn off cursor lbcs _abort puls a,b,x,y,pc _curoff pshs a,b,x,y lda #stdout leax curoff,pcr ldy #2 os9 I$Write ; turn off cursor lbcs _abort puls a,b,x,y,pc _cls pshs a,b,x,y lda #stdout leax cls,pcr ldy #1 os9 I$Write ; turn off cursor lbcs _abort puls a,b,x,y,pc _home pshs a,b,x,y lda #stdout leax home,pcr ldy #1 os9 I$Write ; turn off cursor lbcs _abort puls a,b,x,y,pc _insline tst termcap bne @l2 clr <renderall com <renderall rts @l2 pshs a,b,x,y lda #stdout leax insline,pcr ldy #2 os9 I$Write ; turn off cursor lbcs _abort puls a,b,x,y,pc _delline tst termcap bne @l2 clr <renderall com <renderall rts @l2 pshs a,b,x,y lda #stdout leax delline,pcr ldy #2 os9 I$Write ; turn off cursor lbcs _abort puls a,b,x,y,pc _exit lbsr _deinit ldd #0 os9 F$Exit _abort lbsr _deinit clra os9 F$Exit _error leax errPNNF,pcr cmpb #E$PNNF beq @print leax errMF,pcr cmpb #E$MemFul beq @print leax errRF,pcr cmpb #E$Read beq @print leax errWF,pcr cmpb #E$Write beq @print lbra _abort @print lbsr _cls clra ldb <height+1 lbsr _gotoxy lbsr _strlen tfr d,y lda #stdout os9 I$Write leax errBreak,pcr lbsr _strlen tfr d,y lda #stdout os9 I$Write clr <sgn_code @loop ldb <sgn_code cmpb #S$Abort bne @loop clr <sgn_code lbsr _renderall rts _help lbsr _curoff lbsr _cls leax msgHelp,pcr lbsr _strlen tfr d,y lda #stdout os9 I$Write clr <sgn_code @loop lda #stdin ldy #1 leax key,u os9 I$Read ldb <sgn_code cmpb #S$Abort bne @loop clr <sgn_code lbsr _renderall rts _meminit ldx <membuf stx <memstart clr ,x+ clr ,x rts ; x address ; d new size ; return x: new block address _mrealloc pshs a,b,y leax -2,x ; get memory header addd #2 ; add header size std <malsize ; store new size ldd ,x ; get current size anda #~$80 cmpd <malsize ; compare new size lbeq @end ; return if the same bcc @split ; new size smaller, then split leay d,x ldy ,y cmpy #0 beq @endchain ; end of chain ? tfr x,y ldx <malsize leax -2,x ; adjust header size lbsr _malloc ; otherwise make new allocation bcs @fail subd #2 pshs u,x,y leau 2,y ; old chunk data tfr d,y @loop lda ,u+ sta ,x+ leay -1,y bne @loop ; transfer data to new chunk puls u,x,y exg x,y leax 2,x lbsr _mfree exg x,y clra lbra @ret ; return new address @split ldd ,x anda #~$80 leay d,x ; get next chunk ldd ,y * cmpd #0 ; is the end of the chain ? beq @endchain ldd ,x anda #~$80 subd <malsize cmpd #8 ; worth spliting it ? bmi @end std <remsize ldd <malsize leay d,x ora #$80 std ,x ; set new size ldd <remsize ; restore remaining size std ,y ; set new chunk clra ; clear carry bra @end @endchain ldd <malsize leay d,x leay 2,y cmpy <himem bcc @outmem leay -2,y ora #$80 std ,x clr ,y+ clr ,y bra @end @fail tfr y,x @outmem comb leax 2,x puls a,b,y,pc @end clrb leax 2,x @ret puls a,b,y,pc _malloc pshs a,b,y tfr x,y @try lbsr __malloc bcs @memful puls a,b,y,pc @memful ldd <undoptr beq @error lbsr _undo_del tfr y,x bra @try @error comb puls a,b,y,pc ; x block size ; return x: block address __malloc pshs a,b,y leax 2,x stx <malsize ldx <memstart ldd ,x @checkused bita #$80 beq @computesiz @nextchunk ldd ,x anda #~$80 leax d,x ldd ,x bra @checkused @computesiz cmpd #0 beq @endchain subd <malsize bmi @nextchunk cmpd #8 ; space for a small chunk ? bpl @split ldd ,x ora #$80 sta ,x bra @found @split std <remsize ; remain size ldd <malsize leay d,x ora #$80 std ,x ldd <remsize std ,y bra @found @endchain ldd <malsize leay d,x leay 2,y cmpy <himem bcc @outmem leay -2,y clr ,y+ clr ,y ora #$80 std ,x bra @found @outmem ldx #0 comb bra @end @found leax 2,x clra @end puls a,b,y,pc ; mfree ; x address _mfree pshs a,b,x,y leax -2,x ldd ,x anda #~$80 std ,x leay d,x ldd ,y bita #$80 bne @end addd ,x std ,x ; coalesce ajacent chunks @end puls a,b,x,y,pc ; memcpy ; x tgt ; y src ; d size _memcpy pshs a,b,x,y @loop pshs a lda ,y+ sta ,x+ puls a subd #1 bne @loop puls a,b,x,y,pc ; Strings manager ; Each string lies on a malloc chunk allocation and has a 4 byte header for: ; ; Prev str addr | Next str addr ; ; The maximum string size is inferred from the malloc struct. ; The current string size is the null character on it. _strinit ldd #0 std <strptr ; clears struct rts ; append string to the end of the chain ; x string size ; y previous string ptr ; return x : str ptr _strapp pshs a,b,y leax 5,x cmpy #0 beq @first @next ldd 2,y cmpd #0 beq @last tfr d,y bra @next @last lbsr _malloc bcs @fail stx 2,y sty ,x clr 2,x clr 3,x clr 4,x clr 5,x puls a,b,y,pc @first lbsr _malloc bcs @fail ldd #0 std ,x std 2,x std 4,x stx <strptr puls a,b,y,pc @fail comb ldx #0 puls a,b,y,pc ; dettach the string ; x string ptr _strdet pshs a,b,y ldy ,x ; previous ldd 2,x ; next cmpy #0 beq @first std 2,y ; previous->next = next exg d,y cmpy #0 beq @free std ,y ; next->previous = previous @free puls a,b,y,pc @first std <strptr ; strptr = next exg d,y cmpy #0 beq @free std ,y ; next->previous = 0 bra @free ; delete the string ; x string ptr _strdel pshs a,b,y ldy ,x ; previous ldd 2,x ; next cmpy #0 beq @first std 2,y ; previous->next = next exg d,y cmpy #0 beq @free std ,y ; next->previous = previous @free lbsr _mfree puls a,b,y,pc @first std <strptr ; strptr = next exg d,y cmpy #0 beq @free std ,y ; next->previous = 0 bra @free ; resize string ; x str ptr ; d new size ; return x new str _strres pshs a,b,y addd #5 lbsr _mrealloc bcs @error ldy ,x ; previous beq @first stx 2,y ; previous->next = this @next ldy 2,x ; next beq @last stx ,y ; next->previous = this @last puls a,b,y,pc @first stx <strptr bra @next @error puls a,b,y,pc ; strlen ; x str first char ; return d string len _strlen pshs x ldd #0 @isnull tst ,x+ beq @null addd #1 bra @isnull @null puls x,pc ; memcpy ; x tgt ; y src _strcpy pshs a,x,y @loop lda ,y+ sta ,x+ bne @loop puls a,x,y,pc _strrows pshs x,y ldy #1 @wrap ldb <width+1 @isnull lda ,x+ beq @null cmpa #$0d beq @null decb bne @isnull leay 1,y bra @wrap @null tfr y,d puls x,y,pc ; insert string of x size ; y previous string ptr ; return new x pointer _strins pshs a,b,y leax 5,x lbsr _malloc lbcs @error ldd #0 std ,x std 2,x std 4,x sty ,x ldd 2,y stx 2,y std 2,x beq @last tfr d,y stx ,y @last lda #1 sta 4,x @error puls y,a,b,pc _reset pshs a,b,x,y ldd #0 lbsr _meminit ; init memory manager lbsr _strinit std <curline std <scrlines std <undoptr std <cx clr <tcx clr <renderall clr <undoflag ldd #1 std <scrline clr filename,u clr <filepath clr <edited puls a,b,x,y,pc _open pshs a,b,x,y lbsr _reset ldd argc,u cmpd #0 beq @empty leax filename,u ldy args,u ; file name lbsr _strcpy lda #READ. os9 I$Open bcs @error sta <filepath clra puls a,b,x,y,pc @error lbsr _error @empty comb puls a,b,x,y,pc _close pshs a,b,x,y lda <filepath beq @end os9 I$Close clr <filepath @end puls a,b,x,y,pc @backspace pshs a,b ldd <strlen beq @end subd #1 std <strlen ldx <curstr leax 5,x leax d,x clr ,x @end puls a,b,pc _appchar cmpa #$09 beq @tab cmpa #$08 beq @backspace cmpa #$0d beq __appchar cmpa #$20 bcc __appchar rts @tab _tab set 0 _stack set 1 pshs a,b leas -_stack,s ldb <strlen+1 decb andb #$03 stb _tab,s ldb #4 subb _tab,s lda #32 @loop bsr __appchar decb bne @loop @skip leas _stack,s puls a,b,pc ; append character to current string ; x string ; a char __appchar pshs a,b,x ldx <curstr ldd -2,x anda #~$80 subd #7 cmpd <strlen bgt @append addd #32 lbsr _strres bcs @error stx <curstr std <curlen @append leax 5,x ldd <strlen leax d,x addd #1 std <strlen lda ,s sta <prevchar clrb std -1,x @error puls a,b,x,pc _read pshs a,b,x,y ldy #0 sty <curstr clr <prevchar @read lda <filepath,u ldb #SS.EOF os9 I$GetStt lbcs @eof ldy #256 leax readbuf,u os9 I$Read lbcs @error cmpy #0 lbeq @eof tfr y,d leay readbuf,u ; y = readbuf @nextlin ldx #256 stx <curlen pshs y ldy <curstr lbsr _strapp ; append new line puls y lbcs @outmem stx <curstr ; save current string leax -2,x stx <memstart ldx #1 stx <strlen @loop lda ,y+ cmpa #$0a ; ignore NL beq @checkcr cmpa #$0d beq @newline @continue lbsr _appchar @skip decb bne @loop lda <filepath ldb #SS.EOF os9 I$GetStt bcs @eof ldy #256 leax readbuf,u os9 I$Read bcs @error cmpy #0 lbeq @eof tfr y,d leay readbuf,u ; y = readbuf bra @loop @backspace @newline lbsr _appchar sta <prevchar pshs b ldx <curstr ldd <strlen lbsr _strres ; resize trailing string puls b decb bne @nextlin lbra @read @checkcr sta <curchar lda <prevchar cmpa #$0d beq @skip lda #$0d bra @newline @eof ldx <curstr ldd <strlen addd #1 lbsr _strres ; resize trailing string ldx <membuf stx <memstart puls a,b,x,y,pc @outmem ldb #E$MemFul @error lbsr _error puls a,b,x,y,pc _cntlines pshs a,b,x,y ldx #0 stx <scrlines ldy <strptr cmpy #0 beq @last @next pshs y leay 5,y clr <cntlin @wrap ldx <scrlines leax 1,x stx <scrlines inc <cntlin ldx width,u @count ldb ,y+ beq @endline cmpb #$0d beq @endline leax -1,x beq @wrap bra @count @endline puls y lda <cntlin sta 4,y ldd 2,y cmpd #0 beq @last tfr d,y bra @next @last ldd <scrlines bne @end ldy #0 ; insert empty line ldx #16 lbsr _strapp lda #1 sta 4,x @end puls a,b,x,y,pc _rename pshs a,b,x,y @repeat clra ldb <height+1 decb lbsr _gotoxy lbsr _clrlin ldb <height+1 lbsr _gotoxy lbsr _clrlin leax msgRename,pcr lbsr _strlen tfr d,y lda #stdout os9 I$Write leax optbuf,u clr (PD.EKO-PD.OPT),x com (PD.EKO-PD.OPT),x lda #stdin ldb #SS.Opt os9 I$SetStt clr <sgn_code leax readbuf,u ldy #128 lda #stdin os9 I$ReadLn ldb <sgn_code cmpb #S$Abort beq @abort cmpy #0 beq @repeat cmpy #1 beq @repeat tfr y,d leax filename,u leay readbuf,u clr d,y lbsr _memcpy @end leax optbuf,u clr (PD.EKO-PD.OPT),x lda #stdin ldb #SS.Opt os9 I$SetStt lbsr _renderall clr <sgn_code puls a,b,x,y,pc @abort leax optbuf,u clr (PD.EKO-PD.OPT),x lda #stdin ldb #SS.Opt os9 I$SetStt lbsr _renderall clr <sgn_code comb puls a,b,x,y,pc _confirm pshs a,b,x,y clra ldb <height+1 decb lbsr _gotoxy lbsr _clrlin ldb <height+1 lbsr _gotoxy lbsr _clrlin lbsr _strlen tfr d,y lda #stdout os9 I$Write lda #stdin ldy #1 leax key,u os9 I$Read ldb <sgn_code cmpb #S$Abort beq @cancel lda <key cmpa #'Y beq @exit cmpa #'y beq @exit @cancel lbsr _renderall clr <sgn_code puls a,b,x,y,pc @exit clr <sgn_code comb puls a,b,x,y,pc _save pshs a,b,x,y leax msgSave,pcr lbsr _confirm lbcc @end tst filename,u bne @renamed lbsr _rename lbcs @end @renamed clra ldb <height+1 decb lbsr _gotoxy lbsr _clrlin ldb <height+1 lbsr _gotoxy lbsr _clrlin leax msgSaving,pcr lbsr _strlen tfr d,y lda #stdout os9 I$Write leax filename,u os9 I$Delete ; deletes previous file lda #WRITE. ldb #%00011011 leax filename,u os9 I$Create bcs @error sta <filepath ldy <strptr beq @close @next pshs y leax 5,y lbsr _strlen tfr d,y lda <filepath os9 I$Write lbcs @error puls y ldy 2,y bne @next @close lbsr _close clr <edited @end lbsr _renderall puls a,b,x,y,pc @error pshs b lbsr _close puls b lbsr _error puls a,b,x,y,pc _gotolin pshs a,b,x,y @repeat clra ldb <height+1 decb lbsr _gotoxy lbsr _clrlin ldb <height+1 lbsr _gotoxy lbsr _clrlin leax msgLineNo,pcr lbsr _strlen tfr d,y lda #stdout os9 I$Write leax optbuf,u clr (PD.EKO-PD.OPT),x com (PD.EKO-PD.OPT),x lda #stdin ldb #SS.Opt os9 I$SetStt clr <sgn_code leax readbuf,u ldy #128 lda #stdin os9 I$ReadLn ldb <sgn_code cmpb #S$Abort beq @abort cmpy #0 ; no input ? beq @repeat cmpy #1 beq @repeat ; only enter ? ldd #0 std <curline leax readbuf,u leay -1,y @loop lda <curline ldb #10 mul stb <curline lda <curline+1 ldb #10 mul clr <curline+1 addd <curline std <curline clra ldb ,x+ subb #'0 cmpb #10 lbcc @repeat addd <curline std <curline leay -1,y bne @loop ldd <curline beq @abort cmpd <scrlines beq @go bcc @abort @go std <scrline clr <cx clr <cy @end leax optbuf,u clr (PD.EKO-PD.OPT),x lda #stdin ldb #SS.Opt os9 I$SetStt lbsr _renderall clr <sgn_code puls a,b,x,y,pc @abort leax optbuf,u clr (PD.EKO-PD.OPT),x lda #stdin ldb #SS.Opt os9 I$SetStt lbsr _renderall clr <sgn_code comb puls a,b,x,y,pc ; a start row ; b end row _scrdraw pshs a,b,x,y _col set 0 _row set 2 _curstr set 4 _scrstart set 6 _stack set 8 leas -_stack,s pshs a,b ldx <scrbuf ldb <width+1 mul leax d,x ldb 1,s subb ,s lda <width+1 mul tfr d,y lda #32 @cls sta ,x+ ; clear buffer leay -1,y bne @cls puls d tfr d,y ldb <width+1 mul ldx <scrbuf leax d,x stx _scrstart,s tfr y,d ldx <scrline leax a,x lbsr _gotoline ; find top screen ptrs sta _row,s subb _row,s stb _row,s ldb <width+1 stb _col,s ldx <topstr stx _curstr,s ldx <topptr ldy _scrstart,s @cont lda ,x+ beq @nextstr cmpa #$0d beq @nextstr sta ,y+ dec _col,s beq @nextlin bra @cont @nextlin dec _row,s beq @end ldb <width+1 stb _col,s lda <height+1 inca suba _row,s mul ldy <scrbuf leay d,y bra @cont @nextstr ldx _curstr,s ldx 2,x beq @end stx _curstr,s leax 5,x bra @nextlin @end leas _stack,s puls a,b,x,y,pc ; render screen ; a start row ; b end row _render pshs a,b,x,y ldx <scrbuf ldb <width+1 mul leax d,x lda 1,s suba ,s ldb <width+1 mul tfr d,y lda 1,s cmpa <height+1 bcs @cont leay -1,y @cont lda #stdout os9 I$Write lbcs _abort puls a,b,x,y,pc _renderdown pshs a,b tst termcap beq @renderall tst <renderall bne @renderall lbsr _curoff lbsr _home lbsr _delline ldd <height decb lbsr _gotoxy tfr b,a incb incb lbsr _scrdraw lbsr _render puls a,b,pc @renderall lbsr _renderall puls a,b,pc _renderall pshs a,b clr <renderall lbsr _curoff lbsr _home ldd <height incb lbsr _scrdraw ldd <scrlines cmpd <height bcs @draw ldd <height @draw incb lbsr _render lbsr _clrlin puls a,b,pc _renderup pshs a,b tst termcap beq @renderall tst <renderall bne @renderall lbsr _curoff lbsr _home lbsr _insline ldd #$0001 lbsr _scrdraw lbsr _render puls a,b,pc @renderall lbsr _renderall puls a,b,pc ; find top string ptr for the current scrline ; x scr line _gotoline pshs a,b,x,y stx <cntlin ldx #0 ldy <strptr cmpy #0 beq @end ldd #0 @next addb 4,y adca #0 cmpd <cntlin bcc @found leay 2,y ldy ,y beq @last bra @next @found subb 4,y sbca #0 addd #1 tfr d,x ldd <cntlin stx <cntlin subd <cntlin leax 5,y @wrap lda <width+1 mul leax d,x bra @end @last leax 5,y @end stx <topptr sty <topstr puls a,b,x,y,pc ; goto cursor ; a = col ; b = row _gotoxy pshs a,b,x,y leax gotocmd,u addd #$2020 std 1,x lda #$02 sta ,x lda #stdout ldy #3 os9 I$Write puls a,b,x,y,pc ; set cursor position and text _setpos pshs a,b,x,y clra ldb <cy addd <scrline tfr d,x lbsr _gotoline clra ldb <cx cmpb #-1 @rcheck beq @lcheck tfr d,y ldx <topptr lbsr _strlen std <strlen leax d,x lda -1,x cmpa #$0d bne @notenter ldd <strlen subd #1 std <strlen @notenter ldd <strlen ldx <topptr cmpy <strlen lbcs @wrapdown cmpy <width bcc @wrapdown stb <cx puls a,b,x,y,pc @lcheck clr <cx ldx <topstr leax 5,x cmpx <topptr bne @wrapup clra ldb <cy addd <scrline cmpd #1 lbeq @lreset clra subd #1 tfr d,x lbsr _gotoline ldx <topptr lbsr _strlen decb stb <cx stb <tcx lbsr _up puls a,b,x,y lbra _setpos @lreset clr <cx clr <tcx puls a,b,x,y,pc @wrapup ldb <width+1 decb stb <cx stb <tcx lbsr _up puls a,b,x,y lbra _setpos @wrapdown cmpy <width lbcs @end clr <cx clr <tcx lbsr _down puls a,b,x,y lbra _setpos @end puls a,b,x,y,pc _navigate pshs a,b,x,y _input @input lbsr _setpos @locate ldd <cx lbsr _gotoxy lbsr _curon lda #stdin ldy #1 leax key,u os9 I$Read ldb <sgn_code cmpb #S$Abort lbeq @end _redo lda <key @up cmpa #K$Up bne @down lbsr _up lbra @input @down cmpa #K$Down bne @pageup lbsr _down lbra @input @pageup cmpa #K$Shift|K$Up bne @pagedown lbsr _pageup lbra @input @pagedown cmpa #K$Shift|K$Down bne @right lbsr _pagedown lbra @input @right cmpa #K$Right bne @left lbsr _right lbra @input @left cmpa #K$Left bne @backspace lbsr _left lbra @input @backspace cmpa #K$ShiftLeft bne @delete lbsr _backspace lbra @input @delete cmpa #K$ShiftRight bne @enter ldd <cx pshs a,b lbsr _right lbsr _setpos puls a,b cmpd <cx lbeq @input lbsr _backspace lbra @input @enter cmpa #$0d bne @char lbsr _splitline lbra @input @char cmpa #$20 blo @ctrl_r lbsr _inschar lbra @input @ctrl_r cmpa #K$CtrlR bne @ctrl_s lbsr _rename lbra @input @ctrl_s cmpa #K$CtrlS bne @ctrl_o lbsr _save lbra @input @ctrl_o cmpa #K$CtrlO bne @ctrl_k lbsr _help lbra @input @ctrl_k cmpa #K$CtrlK bne @ctrl_d lbsr _killine lbra @input @ctrl_d cmpa #K$CtrlD bne @ctrl_g lbsr _dupline lbra @input @ctrl_g cmpa #K$CtrlG bne @ctrl_u lbsr _gotolin lbra @input @ctrl_u cmpa #K$CtrlU bne @ctrl_left lbra _undo_undo @ctrl_left cmpa #K$CtrlLeft bne @ctrl_right lbsr _dohome lbra @input @ctrl_right cmpa #K$CtrlRight bne @continue lbsr _doend lbra @input @continue lbra @input @end lda #stdin ldy #1 leax key,u os9 I$Read tst <edited beq @return clr <sgn_code leax msgConfirm,pcr lbsr _confirm lbcc @input @return puls a,b,x,y,pc _execute _left clra ldb <cx decb stb <cx stb <tcx lbra @end _right clra ldb <cx tfr d,y ldx <topptr lbsr _strlen std <strlen beq @notenter leax d,x lda -1,x cmpa #$0d bne @notenter ldd <strlen subd #1 std <strlen @notenter ldd <strlen ldx <topptr cmpy <strlen lbcc _linedown tfr y,d incb stb <cx stb <tcx lbra @end _linedown clra ldb <cy incb addd <scrline tfr d,y cmpy <scrlines lbhi @end clr <cx clr <tcx lbra _down _pagedown ldd <scrline addd <height cmpd <scrlines lbpl @end std <scrline ldd <scrlines subd <height bcs _top addd #1 cmpd <scrline bcs _bottom lbsr _renderall lbra @end _pageup ldd <scrline subd <height bcs _top std <scrline lbsr _renderall lbra @end _top ldd #1 std <scrline lbsr _renderall lbra @end _down ldb <tcx stb <cx clra ldb <cy addd <scrline cmpd <scrlines lbpl @end clra ldb <cy incb cmpb <height+1 bgt _godown stb <cy lbra @end _bottom ldd <scrlines subd <height std <scrline lbsr _renderall lbra @end _godown clra ldb <cy addd <scrline cmpd <scrlines lbpl @end ldd scrline,u addd #1 std scrline,u lbsr _renderdown lbra @end _up ldb <tcx stb <cx lda <cy deca bmi _goup sta <cy ldd <scrline addd <cy lbra @end _goup ldd <scrline subd #1 lbeq @end std <scrline lbsr _renderup lbra @end _backspace lbsr __backspace lbra @end @end rts __backspace pshs a,b,x,y clr <edited com <edited ldx <topptr lbeq @end lbsr _strrows std <cntlin ldx <topptr ldb <cx beq @isjoin decb stb <cx stb <tcx leax b,x @domove lda ,x lbsr _undo_push @move lda 1,x sta ,x+ bne @move lbra @count @isjoin ldy <topstr leay 5,y cmpy <topptr beq @joinline lda <cx deca sta <cx sta <tcx leax -1,x bra @domove @joinline ldx <topstr leax 5,x lbsr _strlen std <malsize ldd <scrline addb <cy adca #0 cmpd #1 lbeq @end clr <renderall com <renderall tst <cy bne @ntop ldd <scrline subd #1 std <scrline inc <cy lbsr _setpos @ntop ldx <topptr ldy <topstr stx <delstr ldd <scrline dec <cy addb <cy adca #0 tfr d,x lbsr _gotoline ldx <topptr lbsr _strlen decb stb <cx stb <tcx ldx <topstr leax 5,x lbsr _strlen addd <malsize addd #2 ldx <topstr lbsr _strres lbcs @error stx <curstr leax 5,x lbsr _strlen std <strlen leax d,x clr -1,x ; remove car ret ldx <delstr lda #$0d lbsr _undo_push @jmove lda ,x+ beq @endjoin lbsr __appchar lbcs @error bra @jmove @endjoin ldd <scrline addb <cy adca #0 tfr d,x lbsr _gotoline ldx <topstr tfr y,x lbsr _strdel ldd #0 std <cntlin @count ldx <topptr lbsr _strrows cmpd <cntlin beq @render ldx <topstr leax 5,x lbsr _strrows stb -1,x clra ldb <cy cmpb <height+1 bcc @btm incb @btm lbsr _gotoxy lda <cy beq @top deca ldb <height+1 incb lbsr __cntlines lbsr _renderdel bra @end @render lda <cy beq @top deca inc <cntlin+1 @top tfr a,b addb <cntlin+1 lbsr __cntlines lbsr _renderdel @end puls a,b,x,y,pc @error ldb #E$MemFul lbsr _error lbsr __cntlines puls a,b,x,y,pc _renderdel pshs a,b tst <renderall bne @renderall cmpa <height+1 blo @aLower lda <height+1 deca @aLower cmpb <height+1 bls @bLower ldb <height+1 incb @bLower lbsr _curoff pshs a,b tfr a,b clra lbsr _gotoxy ldd <height incb lbsr _scrdraw puls a,b lbsr _render puls a,b,pc @renderall lbsr _renderall puls a,b,pc __cntlines pshs a,b,x,y ldd <height addd #2 std <cntlin ldx #0 stx <scrlines ldy <strptr cmpy #0 beq @last @next leax 5,y ldd <scrlines addd #2 subd <scrline bcs @nonvis cmpd <cntlin bhi @nonvis lbsr _strrows clra stb 4,y @nonvis clra ldb 4,y addd <scrlines std <scrlines ldy 2,y bne @next @last puls a,b,x,y,pc _killine lda #K$CtrlD lbsr _undo_push clr <edited com <edited ldx <topstr ldd 2,x beq @last lbsr _strdet bra @end @last ldd ,x beq @first lbsr _strdet ldy ,x lbsr _up bra @end @first leax 5,x ldd #$0d00 std ,x lda #1 sta -1,x @end lbsr __cntlines ldd <scrline addb <cy adca #0 cmpd <scrlines bcs @update beq @update ldd <scrlines subd <scrline cmpd <height bcc @reset stb <cy bra @update @reset ldd <scrlines std <scrline clr <cy @update lda #0 ldb <height+1 incb lbsr _renderdel rts _dupline lda #K$CtrlK lbsr _undo_push clr <edited com <edited ldx <topstr leax 5,x lbsr _strlen tfr d,x leax 1,x ldy <topstr lbsr _strins lbcs @error lda 4,y sta 4,x leay 5,y leax 5,x @loop lda ,y+ sta ,x+ bne @loop lbsr __cntlines lbsr _down lda #0 ldb <height+1 incb lbsr _renderdel rts @error ldb #E$MemFul lbsr _error lbsr __cntlines rts _splitline lda #K$ShiftRight lbsr _undo_push clr <edited com <edited ldx <topptr ldb <cx leax b,x lbsr _strlen addb #16 std <malsize tfr d,x ldy <topstr lbsr _strins lbcs @error ldb <cx ldy <topptr leay b,y leax 5,x pshs y @move lda ,y+ beq @endloop sta ,x+ bra @move @endloop puls y ldd #$0d00 std ,y clr ,x lbsr __cntlines lda <cy pshs a lbsr _down clr <cx clr <tcx lbsr _setpos ldd <scrlines cmpd <height bcc @tobtm puls a bra @draw @tobtm puls a ldb <height+1 @draw incb lbsr _renderdel rts @error ldb #E$MemFul lbsr _error @count lbsr __cntlines rts _inschar lda #K$ShiftRight lbsr _undo_push lda <key clr <edited com <edited sta <curchar ldx <topstr leax 5,x lbsr _strrows stb <currows lbsr _strlen std <strlen ldd -7,x anda #~$80 subd #2 ; malloc header std <malsize subd #6 ; str header + null char lbcs @error subd <strlen lbcs @error beq @expand bra @insert @expand ldx <topstr ldd <malsize addd #10 ; lbsr _strres lbcs @error clra ldb <cy addd <scrline tfr d,x lbsr _gotoline @insert ldx <topptr ldb <cx leax b,x tfr x,y clrb @goend incb lda ,y+ bne @goend @move lda ,-y sta 1,y decb bne @move lda <curchar sta ,x lbsr __cntlines lbsr _right ldx <topstr leax 5,x lbsr _strrows cmpb <currows beq @renderdel clr <renderall com <renderall @renderdel ldx <topptr lbsr _strrows lda <cy addb <cy lbsr _renderdel rts @error ldb #E$MemFul lbsr _error rts _dohome ldd <topptr subd <topstr addd #5 @loop subd <width beq @same bcs @same pshs a,b lbsr _up puls a,b bra @loop @same clr <cx clr <tcx lbsr _setpos lbsr _renderall rts _doend lbsr brkpnt ldx <topptr lbsr _strlen @loop subd <width beq @same bcs @same pshs a,b lbsr _down puls a,b bra @loop @same addd <width decb stb <cx stb <tcx lbsr _setpos lbsr _renderall rts _undo_push tst <undoflag lbne @skip pshs a,b,x,y,u ldx <undoptr beq @first @loop ldy 2,x beq @last tfr y,x bra @loop @last tfr x,y ldx #sizeof{undo_item} lbsr _malloc lbcs @error stx 2,y sty ,x clr 2,x clr 3,x bra @set @first ldx #sizeof{undo_item} lbsr _malloc lbcs @error stx <undoptr ldy #0 sty ,x sty 2,x @set sta undo_item.key,x ldd <cx std undo_item.cx,x ldd <topstr std undo_item.topstr,x ldd <scrline std undo_item.scrline,x puls a,b,x,y,u,pc @error ldb #E$MemFul lbsr _error puls a,b,x,y,u,pc @skip clr <undoflag rts _undo_pop ldx <undoptr beq @end @next ldd 2,x beq @last tfr d,x bra @next @last ldd #0 ldy ,x beq @first std 2,y bra @pop @first std <undoptr @pop lbsr _mfree @end rts _undo_del pshs a,b,x,y ldx <undoptr cmpx #0 beq @end ldd #0 std <undoptr lbsr _mfree ldy 2,x beq @last ldd #0 std ,y sty <undoptr @last lda undo_item.key,x cmpa #K$CtrlD bne @end ldx undo_item.topstr,x lbsr _mfree @end puls a,b,x,y,pc _undo_undo lbsr _undo_pop cmpx #0 beq @end lda undo_item.key,x cmpa #K$CtrlD bne @dokey clr undo_item.key,x ldd undo_item.cx,x std <cx ldd undo_item.scrline,x std <scrline addb <cy adca #0 exg d,x lbsr _gotoline exg d,x ldx undo_item.topstr,x ldd ,x beq @first ldd 2,x beq @last ldy <topstr ldy ,y ldd 2,y std 2,x this->next = prev->next sty ,x this->prev = prev stx 2,y prev->next = this ldy 2,x stx ,y next->prev = this @refr clr <renderall com <renderall lbsr __cntlines exg x,d lbsr _setpos lbsr _renderall @end lbra _input @last ldy <strptr @next ldd 2,y beq @found tfr d,y bra @next @found stx 2,y sty ,x bra @refr @first ldy <strptr sty 2,x stx ,y stx <strptr bra @refr @dokey clr <renderall com <renderall ldd undo_item.cx,x std <cx ldd undo_item.scrline,x std <scrline exg x,d lbsr _setpos exg x,d lda undo_item.key,x sta <key clr <undoflag com <undoflag lbra _redo emod eom equ * end