gno/bin/gsh/edit.asm

1956 lines
32 KiB
NASM

**************************************************************************
*
* The GNO Shell Project
*
* Developed by:
* Jawaid Bazyar
* Tim Meekins
*
**************************************************************************
*
* EDIT.ASM
* By Tim Meekins
*
* The GNO/Shell command-line editor
*
**************************************************************************
keep o/edit
mcopy m/edit.mac
RAW gequ $20
CRMOD gequ $10
ECHO gequ $08
CBREAK gequ $02
TANDEM gequ $01
OAMAP gequ 0001 /* map OA-key to some sequence */
OA2META gequ 0002 /* map OA-key to meta-key */
OA2HIBIT gequ 0004 /* map OA-key to key|0x80 */
VT100ARROW gequ 0008 /* map arrows to vt100 arrows */
TIOCGETP gequ $40067408
TIOCSETP gequ $80067409
TIOCGETK gequ $40027414
TIOCSETK gequ $80027413
TIOCGLTC gequ $40067474
TIOCSLTC gequ $80067475
cmdbuflen gequ 1024
; editor key commands
undefined_char gequ 0 ;<- DO NOT CHANGE THIS DEFINITION
raw_char gequ 1 ;<- DO NOT CHANGE THIS DEFINITION
map_char gequ 2
backward_char gequ 3
forward_char gequ 4
up_history gequ 5
down_history gequ 6
beginning_of_line gequ 7
end_of_line gequ 8
complete_word gequ 9
newline_char gequ 10
clear_screen gequ 11
redisplay gequ 12
kill_whole_line gequ 13
lead_in gequ 14
backward_delete_char gequ 15
backward_word gequ 16
forward_word gequ 17
list_choices gequ 18
kill_end_of_line gequ 19
toggle_cursor gequ 20
delete_char gequ 21
**************************************************************************
*
* get a command line from the user
*
**************************************************************************
GetCmdLine START
using global
using HistoryData
using pdata
using keybinddata
using termdata
using vardata
stz signalled
stz cmdlen
stz cmdloc
stz currenthist
stz currenthist+2
ioctl (#1,#TIOCGETP,#oldsgtty)
ioctl (#1,#TIOCGETP,#newsgtty)
lda #CBREAK+CRMOD
sta sg_flags
ioctl (#1,#TIOCSETP,#newsgtty)
ioctl (#1,#TIOCGETK,#oldttyk)
ioctl (#1,#TIOCSETK,#newttyk)
ioctl (#1,#TIOCGLTC,#oldltc)
ioctl (#1,#TIOCGLTC,#newltc)
short m
lda #-1
sta newltc+1
long m
ioctl (#1,#TIOCSLTC,#newltc)
cmdloop lda #keybindtab
sta 0
lda #^keybindtab
sta 2
nextchar jsr cursoron
jsr flush
jsr getchar
sta 4
ldx signalled
beq nextchar2
jsr cmdsig
; bra cmdloop
nextchar2 jsr cursoroff
lda 4
cmp #-1
beq eof
cmp #4 ;CTL-D
bne findcmd
eof ldx cmdlen
bne findcmd
lda varignore
bne findcmd
jsr cursoron
ioctl (#1,#TIOCSETP,#oldsgtty)
ioctl (#1,#TIOCSETK,#oldttyk)
ioctl (#1,#TIOCSLTC,#oldltc)
sec
rts
findcmd asl a
sta addidx+1
asl a
addidx adc #0
tay
lda [0],y ;get the type of key this is
asl a
tax
jsr (keytab,x)
jmp cmdloop
keytab dc i'beep' ;undefined-char
dc i'cmdraw' ;raw-char
dc i'cmdloop' ;map-char
dc i'cmdleft' ;backward-char
dc i'cmdright' ;forward-char
dc i'PrevHistory' ;up-history
dc i'NextHistory' ;down-history
dc i'cmdbegin' ;beginning-of-line
dc i'cmdend' ;end-of-line
dc i'dotab' ;complete-word
dc i'cmdnewline' ;newline
dc i'cmdclearscrn' ;clear-screen
dc i'cmdredraw' ;redisplay
dc i'cmdclrline' ;kill-whole-line
dc i'cmdleadin' ;lead-in
dc i'cmdbackdel' ;backward-delete-char
dc i'cmdleftword' ;backward-word
dc i'cmdrightword' ;forward-word
dc i'cmdmatch' ;list-choices
dc i'cmdclreol' ;kill-end-of-line
dc i'cmdcursor' ;toggle-cursor
dc i'cmddelchar' ;delete-char
;-------------------------------------------------------------------------
;
; it's multiple character command
;
;-------------------------------------------------------------------------
cmdleadin pla ;kill return address
iny
iny
lda [0],y
tax
iny
iny
lda [0],y
sta 0+2
stx 0
jmp nextchar
;-------------------------------------------------------------------------
;
; Insert or overwrite an alphanum character
;
;-------------------------------------------------------------------------
cmdraw lda cmdlen
cmp #cmdbuflen
bcc cmIns0
jmp beep
cmIns0 lda insertflag
beq cmOver ;Do overstrike mode
short a
ldy cmdlen
cmIns1 cpy cmdloc
beq cmins2
bcc cmIns2
lda cmdline-1,y
sta cmdline,y
dey
bra cmIns1
cmIns2 long a
inc cmdlen
;
; Place character in string and output
;
cmOver lda 4
ldy cmdloc ;Do overstrike mode
short a
sta cmdline,y
long a
iny
sty cmdloc
jsr putchar
ldy cmdloc
cpy cmdlen
bcc cmdov2
beq cmdov2
sty cmdlen
;
; Redraw shifted text
;
cmdov2 lda insertflag
cmp #0
bne cmdov2a
rts
cmdov2a ldx #0
cmdov3 if2 @y,eq,cmdlen,cmdov4
lda cmdline,y
iny
inx
phx
phy
jsr putchar
ply
plx
bra cmdov3
cmdov4 jmp moveleft
;-------------------------------------------------------------------------
;
; If the shell is interrupted during an edit
;
;-------------------------------------------------------------------------
cmdsig stz signalled
jmp cmdredraw
;-------------------------------------------------------------------------
;
; end of command...newline
;
;-------------------------------------------------------------------------
cmdnewline pla ;pull off return address
sec
lda cmdlen
sbc cmdlen
tax
jsr moveright
ldx cmdlen ;strip trailing space
beq retdone
fix dex
lda cmdline,x
and #$FF
if2 @a,eq,#' ',fix
fix0 inx
stx cmdlen
stz cmdline,x ;terminate string
txy
beq retdone
ph4 #cmdline
jsl InsertHistory
retdone ioctl (#1,#TIOCSETP,#oldsgtty)
ioctl (#1,#TIOCSETK,#oldttyk)
ioctl (#1,#TIOCSLTC,#oldltc)
clc
rts
;-------------------------------------------------------------------------
;
; moved character to the left
;
;-------------------------------------------------------------------------
cmdleft lda cmdloc
bne ctl0a
jmp beep
ctl0a dec a
sta cmdloc
ldx #1
jmp moveleft
;-------------------------------------------------------------------------
;
; move character to the right
;
;-------------------------------------------------------------------------
cmdright ldy cmdloc
if2 @y,ne,cmdlen,ctl1a
jmp beep
ctl1a lda cmdline,y
jsr putchar
inc cmdloc
rts
;-------------------------------------------------------------------------
;
; show matching files
;
;-------------------------------------------------------------------------
cmdmatch lda cmdlen
beq dontdomatch
jsr domatcher
jmp cmdredraw
dontdomatch rts
;-------------------------------------------------------------------------
;
; Clear entire input line
;
;-------------------------------------------------------------------------
cmdclrline ldx cmdloc
jsr moveleft
stz cmdloc ;fall through to cmdclreol
;-------------------------------------------------------------------------
;
; Clear to end of line
;
;-------------------------------------------------------------------------
cmdclreol lda cdcap
ora cdcap
beq ctl4a0
tputs (cdcap,#1,#outc)
bra ctl4g
ctl4a0 sub2 cmdlen,cmdloc,@a
inc a
tax
tay
phx
ctl4a phy
lda #' '
jsr putchar
ply
dey
bne ctl4a
plx
jsr moveleft
ctl4g lda cmdloc
sta cmdlen
rts
;-------------------------------------------------------------------------
;
; redraw command-line
;
;-------------------------------------------------------------------------
cmdredraw jsr newline
redraw2 jsl WritePrompt
ldx cmdlen
stz cmdline,x
ldx #^cmdline
lda #cmdline
jsr puts
sec
lda cmdlen
sbc cmdloc
tax
jmp moveleft
;-------------------------------------------------------------------------
;
; clear screen
;
;-------------------------------------------------------------------------
cmdclearscrn jsr clearscrn
bra redraw2
;-------------------------------------------------------------------------
;
; Insert toggle
;
;-------------------------------------------------------------------------
cmdcursor eor2 insertflag,#1,insertflag
rts
;-------------------------------------------------------------------------
;
; delete character to left
;
;-------------------------------------------------------------------------
cmdbackdel lda cmdloc
bne ctldel2
jmp beep
ctldel2 dec a
sta cmdloc
ldx #1
jsr moveleft ;fall through to cmddelchar
;-------------------------------------------------------------------------
;
; Delete character under cursor
;
;-------------------------------------------------------------------------
cmddelchar ldy cmdloc
if2 @y,ne,cmdlen,cmdoa2a
rts
cmdoa2a short a
cmdoa2aa if2 @y,eq,cmdlen,cmdoa2b
lda cmdline+1,y
sta cmdline,y
iny
bra cmdoa2aa
cmdoa2b lda #' '
sta cmdline-1,y
sta cmdline,y
long a
ldy cmdloc
ldx #0
cmdoa2c if2 @y,eq,cmdlen,cmdoa2e
bcs cmdoa2d
cmdoa2e lda cmdline,y
iny
inx
phx
phy
jsr putchar
ply
plx
bra cmdoa2c
cmdoa2d jsr moveleft
dec cmdlen
rts
;-------------------------------------------------------------------------
;
; Jump to beginning of line
;
;-------------------------------------------------------------------------
cmdbegin ldx cmdloc
stz cmdloc
jmp moveleft
;-------------------------------------------------------------------------
;
; Jump to end of line
;
;-------------------------------------------------------------------------
cmdend if2 cmdloc,eq,cmdlen,cmdoa4a
ldx #1
jsr moveright
inc cmdloc
bra cmdend
cmdoa4a rts
;-------------------------------------------------------------------------
;
; Left one word
;
;-------------------------------------------------------------------------
cmdleftword lda cmdloc
bne cmdoa5a
jsr beep
cmdoa5z rts
cmdoa5a dec a
sta cmdloc
cmdoa5b ldx #1
jsr moveleft
ldy cmdloc
beq cmdoa5z
lda cmdline,y
and #$FF
cmp #' '
bne cmdoa5c
dec cmdloc
bra cmdoa5b
cmdoa5c ldy cmdloc
beq cmdoa5z
lda cmdline-1,y
and #$FF
cmp #' '
beq cmdoa5z
dec cmdloc
ldx #1
jsr moveleft
bra cmdoa5c
;-------------------------------------------------------------------------
;
; Move one word to the right
;
;-------------------------------------------------------------------------
cmdrightword if2 cmdloc,ne,cmdlen,cmdoa6a
jsr beep
cmdoa6z rts
cmdoa6a inc a
sta cmdloc
cmdoa6b ldx #1
jsr moveright
ldy cmdloc
if2 @y,eq,cmdlen,cmdoa6z
lda cmdline,y
and #$FF
cmp #' '
beq cmdoa6c
inc cmdloc
bra cmdoa6b
cmdoa6c ldy cmdloc
if2 @y,eq,cmdlen,cmdoa6z
lda cmdline,y
and #$FF
cmp #' '
bne cmdoa6z
inc cmdloc
ldx #1
jsr moveright
bra cmdoa6c
oldsgtty dc i1'0'
dc i1'0'
dc i1'0'
dc i1'0'
dc i2'0'
newsgtty dc i1'0'
dc i1'0'
dc i1'0'
dc i1'0'
sg_flags dc i2'0'
oldttyk dc i2'0'
newttyk dc i2'OAMAP+OA2META+VT100ARROW'
oldltc ds 6
newltc ds 6
END
;=========================================================================
;
; ^D file matcher
;
;=========================================================================
domatcher START
using global
jsr wordmatch
lda nummatch
bne m1
jmp beep
;
; move to end of command-line
;
m1 sec
lda cmdlen
sbc cmdloc
tax
jsr moveright
jsr newline
;
; start displaying each match
;
lda #0
m4 pha
asl a
asl a
tay
lda matchbuf,y
ldx matchbuf+2,y
jsr puts
lda #' '
jsr putchar
pla
inc a
cmp nummatch
bne m4
jsr newline
jmp clearword
END
;=========================================================================
;
; command line expansion
;
;=========================================================================
dotab START
using global
p equ 0
jsr wordmatch
lda nummatch
bne t1
meepmeep jmp beep
;
; only one! trivial case!
;
t1 dec a
bne t2
t1b mv4 matchbuf,p
ldy wordlen
t1a lda [p],y
and #$FF
jeq completed
sta oldchar
phy
jsr insertcmd
ply
iny
bra t1a
;
; one at a time
;
t2 jsr dofignore
lda nummatch
beq meepmeep
dec a
beq t1b
mv4 matchbuf,p
lda char
sta oldchar
ldy wordlen
lda [p],y
and #$FF
sta char2
jsr tolower
sta char
lda #0
t3 pha
asl a
asl a
tay
lda matchbuf,y
sta p
lda matchbuf+2,y
sta p+2
ldy wordlen
lda [p],y
and #$FF
jsr tolower
cmp char
bne honk
pla
inc a
cmp nummatch
bne t3
lda char2
beq completed
jsr insertcmd
inc wordlen
bra t2
honk pla
jsr beep
bra donetab
completed lda cmdloc
cmp cmdlen
bne donetab
lda oldchar
and #$FF
cmp #':'
beq donetab
cmp #'/'
beq donetab
lda #' '
jsr insertcmd
donetab jmp clearword
char ds 2
char2 ds 2
oldchar ds 2
END
;=========================================================================
;
; remove any entries matching $fignore
;
;=========================================================================
dofignore START
using global
var equ 0
word equ var+4
wordnum equ word+4
wordlen equ wordnum+2
varpos equ wordlen+2
newpos equ varpos+2
wordpos equ newpos+2
jsl alloc256
sta varparms+4
stx varparms+6
phx
pha
Read_Variable varparms
jsr p2cstr
sta var
stx var+2
phx
pha
jsr lowercstr
lda varparms+4
ldx varparms+6
jsl free256
lda [var]
and #$FF
jeq done
lda #0
sta wordnum
bigloop asl a
asl a
tax
lda matchbuf,x
sta word
tay
lda matchbuf+2,x
sta word+2
pha
phy
jsr cstrlen
sta wordlen
stz newpos
figmatch lda newpos
sta varpos
ldy varpos
eatspace lda [var],y
and #$FF
beq bignext
cmp #' '
bne yummy
iny
bra eatspace
yummy sty varpos
ldx #0
eatstuff lda [var],y
and #$FF
beq gotstuff
cmp #' '
beq gotstuff
inx
iny
bra eatstuff
gotstuff sty newpos
cpx wordlen
beq hgf
bcs figmatch
hgf phx
sec
lda wordlen
sbc 1,s
sta wordpos
plx
chk ldy wordpos
lda [word],y
and #$FF
beq deleteit
ldy varpos
jsr tolower
eor [var],y
and #$FF
bne figmatch
inc varpos
inc wordpos
bra chk
deleteit lda wordnum
jsr removeword
bignext inc wordnum
lda wordnum
cmp nummatch
bcc bigloop
done pei (var+2)
pei (var)
jsl nullfree
rts
varparms dc a4'fignore'
ds 4
fignore str 'fignore'
END
;=========================================================================
;
; insert a character into the command-line
;
;=========================================================================
insertcmd START
using global
sta tmp
short a
ldy cmdlen
cmIns1 cpy cmdloc
beq cmins2
bcc cmIns2
lda cmdline-1,y
sta cmdline,y
dey
bra cmIns1
cmIns2 long a
inc cmdlen
;
; Place character in string and output
;
cmOver lda tmp
ldy cmdloc ;Do overstrike mode
short a
sta cmdline,y
long a
iny
sty cmdloc
jsr putchar
ldy cmdloc
cpy cmdlen
bcc cmdov2
beq cmdov2
sty cmdlen
;
; Redraw shifted text
;
cmdov2 ldx #0
cmdov3 if2 @y,eq,cmdlen,cmdov5
lda cmdline,y
iny
inx
phx
phy
jsr putchar
ply
plx
bra cmdov3
cmdov5 jmp moveleft
tmp ds 2
END
;=========================================================================
;
; remove an entry from the word matcher table
;
;=========================================================================
removeword START
using global
pha
asl a
asl a
pha
tax
lda matchbuf+2,x
pha
lda matchbuf,x
pha
jsl nullfree
plx
ply
loop cpy nummatch
beq done
lda matchbuf+4,x
sta matchbuf,x
lda matchbuf+6,x
sta matchbuf+2,x
inx
inx
inx
inx
iny
bra loop
done dec nummatch
rts
END
;=========================================================================
;
; clear the word matcher table
;
;=========================================================================
clearword START
using global
lda #0
loop pha
asl a
asl a
tay
lda matchbuf,y
ldx matchbuf+2,y
phx
pha
jsl nullfree
pla
inc a
cmp nummatch
bne loop
stz nummatch
rts
END
;=========================================================================
;
; word matcher for command-line expansion
;
;=========================================================================
wordmatch START
using global
using hashdata
using BuiltInData
lda #'/'
sta sepstyle
ldx #0 ;for left counter
ldy cmdloc
beq atstart
lda cmdline,y ;if current char is space then
and #$FF ;char to left must be non-space
cmp #' '
bne findstart2
lda cmdline-1,y
and #$FF
cmp #' '
bne findstart
jmp beep
;
; move backwards to find start of word to expand
;
findstart inx
dey
beq atstart
findstart2 lda cmdline-1,y
and #$FF
cmp #';'
beq atstart
cmp #'|'
beq atstart
cmp #'&'
beq atstart
cmp #' '
bne findstart
;
; isolate the word
;
atstart sty startpos
stx dir+1
ldx #0
isolate cpy cmdlen
beq gotiso
lda cmdline,y
and #$FF
cmp #' '
beq gotiso
cmp #';'
beq gotiso
cmp #'|'
beq gotiso
cmp #'&'
beq gotiso
sta wordbuf,x
iny
inx
bra isolate
gotiso lda #0
sta wordbuf,x
stx wordlen
sty cmdloc
txa
sec
dir sbc #0
beq nomove
tax
jsr moveright
nomove anop
;
; start finding matches
;
stz nummatch
;
; see if it's a command or an argument, hopefully this is nice and
; accurate...it should serve its purpose well at least.
;
lda #1
sta cmdflag ;first, assume it's a command
ldy startpos
beq gotflag
dey
beq gotflag
flagskip lda cmdline,y
and #$FF
cmp #' '
bne chkflag
dey
bpl flagskip
bra gotflag
chkflag cmp #';'
beq gotflag
cmp #'|'
beq gotflag
cmp #'&'
beq gotflag
stz cmdflag
gotflag anop
;
; check if the first character is '$', if so, match for variables ONLY
;
lda wordbuf
and #$FF
cmp #'$'
jne filem
ld2 1,varParm+8
varloop Read_Indexed varParm
lda buffer
and #$FF
jeq vardone
dec a
cmp wordlen ;if shorter than word skip
jcc nextvar
ldx #1
varscan lda wordbuf,x
and #$FF
beq goodvar
jsr tolower
eor buffer,x
and #$FF
jne nextvar
inx
bra varscan
goodvar stz sepstyle
lda varval
and #$FF
tay
ldx #1
gv00 dey
bmi gv02
lda varval,x
and #$FF
cmp #':'
beq gv00b
cmp #'/'
bne gv00a
gv00b sta sepstyle
gv00a inx
bra gv00
gv02 lda varval ;check if it really is a directory
and #$FF
sta varval-1
ld4 varval-1,GFName
GetFileInfo GFParm
lda GFType
cmp #$0F
beq gv02a
stz sepstyle
gv02a lda nummatch
asl a
asl a
pha
lda buffer
and #$FF
inc a
inc a
inc a
pea 0
pha
jsl ~NEW
sta 0
stx 0+2
ply
sta matchbuf,y
txa
sta matchbuf+2,y
inc nummatch
lda #'$'
sta [0]
lda buffer
and #$FF
tax
ldy #1
gv01 lda buffer,y
sta [0],y
iny
dex
bne gv01
lda sepstyle
sta [0],y
nextvar inc varParm+8
jmp varloop
vardone rts
;
; next lets match by file names
; we'll start by moving our wordbuf to a pascal string
;
filem lda #1
sta iwparm+4
short a
lda wordlen
inc a
sta wordpbuf
long a
ldy wordlen
lda #'*'
sta wordbuf,y
ldx #0
short a
dey
findsep lda wordbuf,y
cmp #':'
beq gotsep
cmp #'/'
beq gotsep
cmp #'['
beq gotglob
cmp #'?'
beq gotglob
cmp #'='
beq gotglob
cmp #'"'
beq gotglob
cmp #"'"
beq gotglob
cmp #'*'
bne nextsep
cpy #0 ;allow boot prefix */
bne gotglob
lda wordbuf+1
cmp sepstyle
bne gotglob
bra nextsep
gotglob long a
jmp beep
longa off
gotsep sta sepstyle
inx
nextsep dey
bpl findsep
long a
cpx #0
beq initit
dec iwparm+4
initit Init_Wildcard iwparm
filematch Next_Wildcard nwparm
lda buffer
and #$FF
jeq filemdone
cmp wordlen
beq filematch
lda nummatch
asl a
asl a
pha
ph4 #buffer
jsr p2cstr
ply
phx ;for c2gsstr
pha
sta matchbuf,y
txa
sta matchbuf+2,y
jsr c2gsstr
phx ;for nullfree
pha
sta GFName
stx GFName+2
sta 4
stx 6
GetFileInfo GFParm
jsl nullfree
lda cmdflag
beq fm01
lda GFType
cmp #$0F
beq isdir
cmp #$B5
beq notdir
cmp #$B3
beq notdir
cmp #$B0
bne filematch
lda GFAux
cmp #6
bne filematch
lda GFAux+2
bne filematch
bra notdir
fm01 lda GFType
cmp #$0F
bne notdir
isdir lda nummatch
asl a
asl a
tax
phx
lda matchbuf,x
sta 0
lda matchbuf+2,x
sta 2
lda buffer
and #$FF
inc a
inc a
pea 0
pha
jsl ~NEW
ply
sta 8
stx 10
pei (2)
pei (0)
phx
pha
sta matchbuf,y
txa
sta matchbuf+2,y
jsr copycstr
pei (2)
pei (0)
jsl nullfree
lda buffer
and #$FF
tay
lda sepstyle
sta [8],y
notdir anop
inc nummatch
jmp filematch
filemdone anop
lda cmdflag ;if it's not a command, we're done
jeq done
;
; let's now look at the hashed files
;
p equ 0
q equ 4
ldy wordlen ;remove '*' from above
lda #0
sta wordbuf,y
lda hash_table
ora hash_table+2
beq endhash
mv4 hash_table,p
lda hash_numexe
beq endhash
ldy #0
ldx t_size
beq endhash
;
; loop through every hashed file and add it the string vector
;
hashloop lda [p],y
sta q
iny
iny
lda [p],y
sta q+2
iny
iny
ora q
beq nexthash
inc q
inc q
phy
phx
pei (q+2)
pei (q)
jsr cstrlen
cmp wordlen
bcc nexthash0
tax
ldy #0
hl lda wordbuf,y
and #$FF
beq hl0
jsr tolower
eor [q],y
and #$FF
bne nexthash0
iny
bra hl
hl0 inx
lda nummatch
asl a
asl a
pha
pea 0
phx
jsl ~NEW
ply
pei (q+2)
pei (q)
phx
pha
sta matchbuf,y
txa
sta matchbuf+2,y
inc nummatch
jsr copycstr
nexthash0 plx
ply
nexthash dex
bne hashloop
endhash anop
;
; add built-ins to the list
;
ld4 builtintbl,p
bilup lda [p]
ldy #2
ora [p],y
beq bidone
lda [p]
sta q
lda [p],y
sta q+2
pei (q+2)
pei (q)
jsr cstrlen
cmp wordlen
bcc binext
tax
ldy #0
bl lda wordbuf,y
and #$FF
beq bl0
eor [q],y
and #$FF
bne binext
iny
bra bl
bl0 inx
lda nummatch
asl a
asl a
pha
pea 0
phx
jsl ~NEW
ply
pei (q+2)
pei (q)
phx
pha
sta matchbuf,y
txa
sta matchbuf+2,y
inc nummatch
jsr copycstr
binext add2 p,#10,p
bra bilup
bidone anop
done rts
startpos ds 2
cmdflag ds 2
iwparm dc i4'wordpbuf'
dc i2'1'
nwparm dc i4'buffer'
GFParm dc i2'4'
GFName dc i4'0'
dc i2'0'
GFType dc i2'0'
GFAux dc i4'0'
varParm dc i4'buffer'
dc i4'varval'
dc i2'0'
ds 1 ;<- don't futz with me!!
varval ds 256
sepstyle ds 2
END
**************************************************************************
*
* key bindings data
*
**************************************************************************
keybinddata DATA
keybindtab dc i2'undefined_char',i4'0' ;^@
dc i2'beginning_of_line',i4'0' ;^A
dc i2'backward_char',i4'0' ;^B
dc i2'undefined_char',i4'0' ;^C
dc i2'list_choices',i4'0' ;^D
dc i2'end_of_line',i4'0' ;^E
dc i2'forward_char',i4'0' ;^F
dc i2'undefined_char',i4'0' ;^G
dc i2'backward_delete_char',i4'0' ;^H
dc i2'complete_word',i4'0' ;^I
dc i2'newline_char',i4'0' ;^J
dc i2'undefined_char',i4'0' ;^K
dc i2'clear_screen',i4'0' ;^L
dc i2'newline_char',i4'0' ;^M
dc i2'down_history',i4'0' ;^N
dc i2'undefined_char',i4'0' ;^O
dc i2'up_history',i4'0' ;^P
dc i2'undefined_char',i4'0' ;^Q
dc i2'redisplay',i4'0' ;^R
dc i2'undefined_char',i4'0' ;^S
dc i2'undefined_char',i4'0' ;^T
dc i2'kill_whole_line',i4'0' ;^U
dc i2'undefined_char',i4'0' ;^V
dc i2'undefined_char',i4'0' ;^W
dc i2'kill_whole_line',i4'0' ;^X
dc i2'kill_end_of_line',i4'0' ;^Y
dc i2'undefined_char',i4'0' ;^Z
dc i2'lead_in',i4'defescmap' ;^[
dc i2'undefined_char',i4'0' ;^\
dc i2'undefined_char',i4'0' ;^]
dc i2'undefined_char',i4'0' ;^^
dc i2'undefined_char',i4'0' ;^_
dc 95i2'raw_char,0,0' ;' ' .. '~'
dc i2'backward_delete_char',i4'0' ;^? (DEL)
defescmap dc 4i2'undefined_char,0,0' ;^@ .. ^C
dc i2'list_choices',i4'0' ;^D
dc 3i2'undefined_char,0,0' ;^E .. ^G
dc i2'backward_word',i4'0' ;^H
dc i2'complete_word',i4'0' ;^I
dc 2i2'undefined_char,0,0' ;^J, ^K
dc i2'clear_screen',i4'0' ;^L
dc i2'undefined_char,0,0' ;^M
dc i2'undefined_char,0,0' ;^N
dc i2'undefined_char,0,0' ;^O
dc i2'undefined_char,0,0' ;^P
dc i2'undefined_char,0,0' ;^Q
dc i2'undefined_char,0,0' ;^R
dc i2'undefined_char,0,0' ;^S
dc i2'undefined_char,0,0' ;^T
dc i2'forward_word,0,0' ;^U
dc i2'undefined_char,0,0' ;^W
dc i2'undefined_char,0,0' ;^X
dc i2'undefined_char,0,0' ;^X
dc i2'undefined_char,0,0' ;^Y
dc i2'undefined_char,0,0' ;^Z
dc i2'complete_word',i4'0' ;^[
dc 16i2'undefined_char,0,0' ;^\ .. +
dc i2'beginning_of_line',i4'0' ; ,
dc i2'undefined_char,0,0' ;
dc i2'end_of_line',i4'0' ; .
dc 19i2'undefined_char,0,0' ; .+1 .. A
dc i2'backward_word',i4'0' ;B
dc 3i2'undefined_char,0,0' ;C ... E
dc i2'forward_word',i4'0' ;F
dc 8i2'undefined_char,0,0' ;G ... N
dc i2'lead_in',i4'vt100key' ;O
dc 18i2'undefined_char,0,0' ;P ... a
dc i2'backward_word',i4'0' ;b
dc 2i2'undefined_char,0,0' ;c ... d
dc i2'toggle_cursor',i4'0' ;e
dc i2'forward_word',i4'0' ;f
dc 25i2'undefined_char,0,0' ;g ... ^?
vt100key dc 65i2'undefined_char,0,0' ;^@ ... @
dc i2'up_history',i4'0' ;A
dc i2'down_history',i4'0' ;B
dc i2'forward_char',i4'0' ;C
dc i2'backward_char',i4'0' ;D
dc 59i2'undefined_char,0,0' ;E ... ^?
END
**************************************************************************
*
* bind a key to a function
*
**************************************************************************
bindkeyfunc START
using keybinddata
p equ 0
tbl equ p+4
len equ tbl+4
space equ len+2
subroutine (4:keystr,2:function),space
lda keystr
ora keystr+2
jeq done
pei (keystr+2)
pei (keystr)
jsr cstrlen
sta len
ld4 keybindtab,tbl
loop lda len
jeq done
dec a
beq putit ;last char in string
lda [keystr]
and #$FF
asl a
sta addb+1
asl a
clc
addb adc #0
tay
lda [tbl],y
cmp #lead_in
beq next
phy
ph4 #128*6
jsl ~NEW
sta p
stx p+2
ldy #128*6-2
lda #0
zap sta [0],y
dey
dey
bpl zap
ply
lda #lead_in
sta [tbl],y
iny
iny
lda p
sta [tbl],y
iny
iny
lda p+2
sta [tbl],y
mv4 p,tbl
dec len
add4 keystr,#1,keystr
bra loop
next iny
iny
lda [tbl],y
tax
iny
iny
lda [tbl],y
sta tbl+2
stx tbl
dec len
add4 keystr,#1,keystr
jmp loop
putit lda [keystr]
and #$FF
asl a
sta adda+1
asl a
clc
adda adc #0
tay
lda function
sta [tbl],y
iny
iny
lda #0
sta [tbl],y
iny
iny
sta [tbl],y
done return
END
**************************************************************************
*
* BINDKEY: builtin command
* syntax: bindkey [-l] function string
*
* bind a keystring to an editor function.
*
**************************************************************************
bindkey START
str equ 0
func equ str+4
arg equ func+2
space equ arg+4
subroutine (4:argv,2:argc),space
lda argc
dec a
bne ok
showusage ldx #^usage
lda #usage
jsr errputs
jmp exit
ok dec argc
add2 argv,#4,argv
lda [argv]
sta arg
ldy #2
lda [argv],y
sta arg+2
lda [arg]
and #$FF
cmp #'-'
bne startbind
ldy #1
lda [arg],y
cmp #'l'
beq list
bra showusage
list ldx #^liststr
lda #liststr
jsr puts
jmp exit
startbind lda argc
dec a
jeq showusage
dec a
jne showusage
ldy #0
findloop phy
lda nametbl,y
ora nametbl+2,y
beq nofind
lda nametbl+2,y
pha
lda nametbl,y
pha
pei (arg+2)
pei (arg)
jsr cmpcstr
beq foundit
pla
add2 @a,#4,@y
bra findloop
nofind pla
ldx arg+2
lda arg
jsr errputs
ldx #^errstr
lda #errstr
jsr errputs
lda #-1
jmp exit
foundit pla
lsr a
tax
lda functbl,x
sta func
add2 argv,#4,argv
lda [argv]
sta arg
ldy #2
lda [argv],y
sta arg+2
pei (arg+2)
pei (arg)
jsr cstrlen
inc a
inc a
pea 0
pha
jsl ~NEW
sta str
stx str+2
pei (arg+2)
pei (arg)
phx
pha
jsl decode
pei (str+2)
pei (str)
pei (func)
jsl bindkeyfunc
pei (str+2)
pei (str)
jsl nullfree
exit return
usage dc c'Usage: bindkey [-l] function string',h'0d00'
errstr dc c': undefined function',h'0d00'
liststr dc c' backward-char - move cursor left',h'0d'
dc c' backward-delete-char - delete character to left',h'0d'
dc c' backward-word - move cursor left one word',h'0d'
dc c' beginning-of-line - move cursor to beginning of line',h'0d'
dc c' clear-screen - clear screen and redraw prompt',h'0d'
dc c' complete-word - perform filename completion',h'0d'
dc c' delete-char - delete character under cursor',h'0d'
dc c' down-history - replace command line with next history',h'0d'
dc c' end-of-line - move cursor to end of line',h'0d'
dc c' forward-char - move cursor to the right',h'0d'
dc c' forward-word - move cursor one word to the right',h'0d'
dc c' kill-end-of-line - delete line from cursor to end of line',h'0d'
dc c' kill-whole-line - delete the entire command line',h'0d'
dc c' list-choices - list file completion matches',h'0d'
dc c' newline - finished editing, accept command line',h'0d'
dc c' raw-char - character as-is',h'0d'
dc c' redisplay - redisplay the command line',h'0d'
dc c' toggle-cursor - toggle between insert and overwrite cursor',h'0d'
dc c' undefined-char - this key does nothing',h'0d'
dc c' up-history - replace command line with previous history',h'0d'
dc h'00'
nametbl dc i4'func1,func2,func3,func4,func5,func6,func7,func8'
dc i4'func9,func10,func11,func12,func13,func14,func15'
dc i4'func16,func17,func18,func19,func20,0'
func1 dc c'backward-char',h'00'
func2 dc c'backward-delete-char',h'00'
func3 dc c'backward-word',h'00'
func4 dc c'beginning-of-line',h'00'
func5 dc c'clear-screen',h'00'
func6 dc c'complete-word',h'00'
func7 dc c'delete-char',h'00'
func8 dc c'down-history',h'00'
func9 dc c'end-of-line',h'00'
func10 dc c'forward-char',h'00'
func11 dc c'forward-word',h'00'
func12 dc c'kill-end-of-line',h'00'
func13 dc c'kill-whole-line',h'00'
func14 dc c'list-choices',h'00'
func15 dc c'newline',h'00'
func16 dc c'raw-char',h'00'
func17 dc c'redisplay',h'00'
func18 dc c'toggle-cursor',h'00'
func19 dc c'undefined-char',h'00'
func20 dc c'up-history',h'00'
functbl dc i'backward_char'
dc i'backward_delete_char'
dc i'backward_word'
dc i'beginning_of_line'
dc i'clear_screen'
dc i'complete_word'
dc i'delete_char'
dc i'down_history'
dc i'end_of_line'
dc i'forward_char'
dc i'forward_word'
dc i'kill_end_of_line'
dc i'kill_whole_line'
dc i'list_choices'
dc i'newline_char'
dc i'raw_char'
dc i'redisplay'
dc i'toggle_cursor'
dc i'undefined_char'
dc i'up_history'
END
**************************************************************************
*
* decode does the grung work to decode the
* string escapes.
*
**************************************************************************
decode START
ch equ 1
space equ ch+2
cp equ space+3
str equ cp+4
end equ str+4
; subroutine (4:str,4:cp),space
tsc
sec
sbc #space-1
tcs
phd
tcd
ldy #0
loop lda [str],y
and #$FF
jeq breakloop
iny
cmp #'^'
bne caseslash
lda [str],y
and #$1F
iny
bra casebreak0
caseslash cmp #'\'
bne casebreak0
lda [str],y
and #$FF
sta ch
iny
ldx #0
nextc lda dp1,x
and #$FF
beq nextslash
cmp ch
beq gotslash
inx
bra nextc
gotslash lda dp2,x
and #$FF
bra casebreak0
nextslash lda ch
cmp #'0'
bcc casebreak0
cmp #'9'+1
bcs casebreak0
sec
sbc #'0'
sta ch
ldx #2
numloop asl ch
asl ch
asl ch
lda [str],y
and #$FF
sec
sbc #'0'
clc
adc ch
sta ch
iny
dex
beq casebreak0
lda [str],y
and #$FF
cmp #'0'
bcc casebreak
cmp #'9'+1
bcc numloop
casebreak lda ch
casebreak0 sta [cp]
inc cp
jne loop
inc cp+2
jmp loop
breakloop lda #0
sta [cp]
lda space+1
sta end-2
lda space
sta end-3
pld
tsc
clc
adc #end-4
tcs
rtl
dp1 dc c'E^\:nrtbf',h'00'
dp2 dc h'1b',c'^\:',h'0a0d09080c'
END