mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-08-23 00:28:59 +00:00
Fixed several mutual exclusion problems, including a particularly nasty one that would cause gsh to loop forever inside the memory manager. (You could identify this one by the "BRA (-23)" at the bottom of the infinite loop.) Fixed the string vector print routine to properly handle all numbers of entries in the hash table. Previously, it would always print duplicate entries if there were < 6 commands hashed, and would sometimes print duplicates (depending on previous contents of an internal table) for other numbers of commands. gsh would wait on background processes started from an exec file (executed, not sourced). Now the exec file does not wait on the process, but the background process is not associated with the parent shell after the exec file terminates. Made gsh globbing work more like csh: if none of the requested patterns are found, print "No match" and exit. At startup, if /etc/glogin, $HOME/glogin, or $HOME/gshrc does not exist, don't report a "file not found" error message. (PR#100)
2035 lines
35 KiB
NASM
2035 lines
35 KiB
NASM
**************************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
*
|
|
* $Id: edit.asm,v 1.10 1998/12/31 18:29:12 tribby Exp $
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* EDIT.ASM
|
|
* By Tim Meekins
|
|
* Modified by Dave Tribby for GNO 2.0.6
|
|
*
|
|
* The GNO/Shell command-line editor
|
|
*
|
|
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
|
|
* | | | | | |
|
|
* ^ ^ ^ ^ ^ ^
|
|
**************************************************************************
|
|
|
|
mcopy /obj/gno/bin/gsh/edit.mac
|
|
|
|
dummyedit start ; ends up in .root
|
|
end
|
|
|
|
setcom 60
|
|
|
|
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
|
|
|
|
WORDGS_SIZE gequ 256 Size of buffer for word search
|
|
|
|
**************************************************************************
|
|
*
|
|
* 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 If signal was received,
|
|
beq nextchar2
|
|
jsr cmdsig acknowledge it
|
|
bra cmdloop and continue reading.
|
|
|
|
nextchar2 jsr cursoroff
|
|
lda 4 Get results of getchar.
|
|
cmp #-1 EOF?
|
|
beq eof
|
|
cmp #4 CTL-D? (treated same as EOF)
|
|
beq eof
|
|
cmp #$FF00 Error?
|
|
bcc findcmd
|
|
and #$00FF
|
|
sta ErrError
|
|
ErrorGS Err yes--print error code.
|
|
bra reterr
|
|
;
|
|
; Parameter block for shell ErrorGS call (p 393 in ORCA/M manual)
|
|
;
|
|
Err dc i2'1' pCount
|
|
ErrError ds 2 Error number
|
|
|
|
eof ldx cmdlen
|
|
bne findcmd
|
|
lda varignore
|
|
bne findcmd
|
|
reterr 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+2
|
|
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 jsl 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
|
|
gsbuf equ wordpos+2
|
|
space equ gsbuf+4
|
|
|
|
subroutine (0:dummy),space
|
|
|
|
ph4 #fignore
|
|
jsl getenv
|
|
|
|
sta gsbuf If buffer wasn't allocated
|
|
stx gsbuf+2
|
|
ora gsbuf+2
|
|
jeq done return to caller.
|
|
|
|
clc
|
|
lda gsbuf Text begins after
|
|
adc #4 four bytes of
|
|
bcc storevar length words.
|
|
inx
|
|
storevar sta var Store pointer to
|
|
stx var+2 c-string in var.
|
|
phx Shift
|
|
pha to
|
|
jsr lowercstr lower case.
|
|
|
|
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
|
|
|
|
pei (gsbuf+2) Free memory allocated
|
|
pei (gsbuf) for the value of $FIGNORE.
|
|
jsl nullfree
|
|
|
|
done anop
|
|
|
|
return
|
|
|
|
fignore gsstr 'fignore' Env variable name
|
|
|
|
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 #'/' Default separator is "/".
|
|
sta sepstyle
|
|
|
|
ldx #0 Keep track of left moves in X-reg.
|
|
ldy cmdloc Y-reg = position on line.
|
|
beq atstart If 0, can't go any further.
|
|
lda cmdline,y If current
|
|
and #$FF character is
|
|
cmp #' ' space, and
|
|
bne findstart2 the one before
|
|
lda cmdline-1,y it is also a
|
|
and #$FF space,
|
|
cmp #' '
|
|
bne findstart
|
|
jmp beep beep at the user.
|
|
;
|
|
; Move backwards to find start of word to expand
|
|
;
|
|
findstart inx Count # of times we've moved left.
|
|
dey Decrement the buffer index.
|
|
beq atstart Done if all the way to start.
|
|
findstart2 lda cmdline-1,y Get the previous
|
|
and #$FF character.
|
|
cmp #';' Compare against shell
|
|
beq atstart characters that
|
|
cmp #'|' indicate a word break.
|
|
beq atstart
|
|
cmp #'&'
|
|
beq atstart
|
|
cmp #'>'
|
|
beq atstart
|
|
cmp #'<'
|
|
beq atstart
|
|
cmp #' '
|
|
bne findstart Stay in loop until one is found.
|
|
;
|
|
; Y-reg points to start, X-reg contains number of positions to cursor.
|
|
; Search forward to isolate the current word.
|
|
;
|
|
atstart sty startpos
|
|
stx dir+1 Ugh! Self-modifying code!!
|
|
ldx #0
|
|
|
|
isolate cpy cmdlen If at end of line,
|
|
beq gotiso cannot go any further.
|
|
lda cmdline,y Isolate the next character.
|
|
and #$FF Compare against shell
|
|
cmp #' ' characters that
|
|
beq gotiso indicate a word break.
|
|
cmp #';'
|
|
beq gotiso
|
|
cmp #'|'
|
|
beq gotiso
|
|
cmp #'&'
|
|
beq gotiso
|
|
cmp #'>'
|
|
beq gotiso
|
|
cmp #'<'
|
|
beq gotiso
|
|
sta wordgs_text,x Accumulate chars in comparison buffer.
|
|
iny Bump character index.
|
|
inx Bump number of chars in word.
|
|
cmp #WORDGS_SIZE-2 If we haven't filled the buffer,
|
|
bcc isolate keep accumulating characters.
|
|
jmp beep Otherwise, beep at the user.
|
|
;
|
|
; We've isolated the word in wordgs_text. X-reg = # of characters
|
|
; and Y-reg is the column number of the final character.
|
|
;
|
|
gotiso lda #0 Terminate string with
|
|
sta wordgs_text,x null byte.
|
|
stx wordlen Save length and
|
|
sty cmdloc position on input line.
|
|
txa
|
|
sec Subtract the number of
|
|
dir sbc #0-0 character to original cursor.
|
|
beq nomove
|
|
tax
|
|
jsr moveright Move cursor to end of word.
|
|
nomove anop
|
|
|
|
;
|
|
; Look for a match: either a command (if word is in first position),
|
|
; a filename in the current directory, or a variable name.
|
|
;
|
|
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 Assume it's a command (flag=1).
|
|
ldy startpos If starting position
|
|
beq gotflag is 0
|
|
dey or 1,
|
|
beq gotflag it's a command.
|
|
|
|
flagskip lda cmdline,y Keep fetching previous
|
|
and #$FF characters until
|
|
cmp #' ' a non-space is
|
|
bne chkflag found, or we run
|
|
dey back to the beginning.
|
|
bpl flagskip
|
|
bra gotflag
|
|
|
|
;
|
|
; We've got the first non-space character before the word in question.
|
|
; If it's a meta- character indicating the end of a command, this must
|
|
; be the beginning of a new command. Otherwise it's an argument.
|
|
;
|
|
chkflag cmp #';'
|
|
beq gotflag
|
|
cmp #'|'
|
|
beq gotflag
|
|
; NOTE: & can be a command terminator, but also part of >& or >>&
|
|
cmp #'&'
|
|
bne isarg Not "&"; must be an argument.
|
|
cpy #0 If at start of line (unusual for &!)
|
|
beq gotflag it must be a command.
|
|
lda cmdline-1,y Get character in front of "&".
|
|
cmp #'&>' Anything except '>'
|
|
bne gotflag means we've got a command.
|
|
|
|
isarg stz cmdflag Argument: cmdflag = 0.
|
|
|
|
;
|
|
; Now that we've established whether we're looking for a command or an
|
|
; argument, see if we're looking for a file name or a variable name
|
|
;
|
|
gotflag anop
|
|
lda wordgs_text
|
|
and #$FF
|
|
cmp #'$'
|
|
jne filem
|
|
|
|
;
|
|
; The first character is '$': match for variables ONLY
|
|
;
|
|
ld2 1,idxIndex
|
|
varloop ReadIndexedGS idxParm Get next variable name.
|
|
lda NameLen
|
|
beq vardone
|
|
cmp wordlen If shorter than word, skip
|
|
jcc nextvar
|
|
;
|
|
; Scan this variable name to see if it matches wordgs_text
|
|
;
|
|
ldx #1
|
|
varscan lda wordgs_text,x
|
|
and #$FF
|
|
beq goodvar Matches (up to current length)
|
|
jsr tolower
|
|
eor NameText-1,x
|
|
and #$FF
|
|
jne nextvar Name doesn't match word.
|
|
inx
|
|
bra varscan
|
|
;
|
|
; We have a match between the variable name and word being typed
|
|
;
|
|
goodvar stz sepstyle Don't use ":" or "/" separator.
|
|
|
|
gv02a anop
|
|
lda nummatch Get the number of matches.
|
|
asl a Multiply by 4 (size of address entry)
|
|
asl a
|
|
pha Hold offset on stack.
|
|
lda NameLen Get length of name,
|
|
inc a and add 3.
|
|
inc a
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW Request memory to hold name.
|
|
sta 0
|
|
stx 0+2
|
|
ply Get matchbuf offset from stack.
|
|
sta matchbuf,y Store allocated memory's
|
|
txa address in matchbuf array.
|
|
sta matchbuf+2,y
|
|
inc nummatch
|
|
|
|
lda #'$' First character = "$".
|
|
sta [0]
|
|
ldx NameLen Get length of name in X-Reg.
|
|
ldy #1 Use Y as offset into strings.
|
|
gv01 lda NameText-1,y Get next byte of name.
|
|
sta [0],y Store in allocated memory.
|
|
iny Bump the index.
|
|
dex Decrement the count
|
|
bne gv01 Keep copying until done.
|
|
lda sepstyle Store separator style at end.
|
|
sta [0],y
|
|
;
|
|
; Done with this variable. Check the next one.
|
|
;
|
|
nextvar inc idxIndex
|
|
jmp varloop
|
|
|
|
vardone rts Return from wordmatch
|
|
|
|
;
|
|
; Match by file name wildcard; start by moving
|
|
; wordgs_text + trailing "*" to a GS/OS string
|
|
;
|
|
filem lda #1
|
|
sta iwFlags
|
|
|
|
lda wordlen
|
|
inc a
|
|
sta wordgsbuf
|
|
ldy wordlen
|
|
lda #'*'
|
|
sta wordgs_text,y
|
|
|
|
ldx #0
|
|
short a
|
|
dey
|
|
findsep lda wordgs_text,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 wordgs_text+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 iwFlags
|
|
|
|
initit InitWildcardGS iwparm
|
|
|
|
filematch anop
|
|
NextWildcardGS nwparm
|
|
ldy NameLen Get length of name.
|
|
jeq filemdone If 0, there's no more to search.
|
|
cpy wordlen
|
|
beq filematch
|
|
|
|
lda #0 Store null byte at end of name,
|
|
sta NameText,y so it will act like a c-string.
|
|
|
|
lda nummatch Get the number of matches.
|
|
asl a Multiply by 4 (size of address entry)
|
|
asl a
|
|
pha Hold offset on stack.
|
|
iny Get length of name + 1
|
|
pea 0
|
|
phy
|
|
~NEW Request memory to hold name.
|
|
ply Get matchbuf offset from stack.
|
|
sta matchbuf,y Store allocated memory's
|
|
txa address in matchbuf array.
|
|
sta matchbuf+2,y
|
|
|
|
ph4 #NameText Copy string from
|
|
lda matchbuf+2,y name buffer into
|
|
pha matchbuf table entry.
|
|
lda matchbuf,y
|
|
pha
|
|
jsr copycstr
|
|
|
|
lda cmdflag Are we looking for a command?
|
|
beq fm01
|
|
lda nwType Yes: Get the file's type
|
|
cmp #$0F == $0F?
|
|
beq isdir it's a directory
|
|
cmp #$B5 == $B5?
|
|
beq notdir it's EXE (shell executable)
|
|
cmp #$B3 == $B3?
|
|
beq notdir it's S16 (GS/OS application)
|
|
cmp #$B0 == $B0?
|
|
bne filematch it's SRC (shell source code)
|
|
lda nwAux Get file's aux type
|
|
cmp #6 == $00000006?
|
|
bne filematch
|
|
lda nwAux+2
|
|
bne filematch No; try next wildcard.
|
|
bra notdir It's shell cmd file.
|
|
;
|
|
; Not looking for a command
|
|
;
|
|
fm01 lda nwType
|
|
cmp #$0F
|
|
bne notdir
|
|
;
|
|
; File type is $0F: it's a directory
|
|
;
|
|
isdir lda nummatch
|
|
asl a
|
|
asl a
|
|
tax
|
|
phx
|
|
lda matchbuf,x
|
|
sta 0
|
|
lda matchbuf+2,x
|
|
sta 2
|
|
lda NameLen Allocate NameLen+2 bytes of memory
|
|
inc a
|
|
inc a
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
ply
|
|
sta 8
|
|
stx 10
|
|
pei (2)
|
|
pei (0)
|
|
phx
|
|
pha
|
|
sta matchbuf,y
|
|
txa
|
|
sta matchbuf+2,y
|
|
jsr copycstr
|
|
pei (2) Free entry that was
|
|
pei (0) allocated in non-directory
|
|
jsl nullfree section of code.
|
|
ldy NameLen
|
|
lda sepstyle
|
|
sta [8],y
|
|
|
|
notdir anop
|
|
inc nummatch Bump the match count.
|
|
jmp filematch Try next wildcard.
|
|
|
|
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 Direct page
|
|
q equ 4 locations.
|
|
|
|
ldy wordlen ;remove '*' from above
|
|
lda #0
|
|
sta wordgs_text,y
|
|
|
|
lda hash_table
|
|
ora hash_table+2
|
|
beq eq_endhash
|
|
mv4 hash_table,p
|
|
lda hash_numexe
|
|
jeq endhash
|
|
ldy #0
|
|
ldx t_size
|
|
eq_endhash 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
|
|
incad q
|
|
incad q
|
|
phy
|
|
phx
|
|
pei (q+2)
|
|
pei (q)
|
|
jsr cstrlen
|
|
cmp wordlen
|
|
bcc nexthash0
|
|
tax
|
|
ldy #0
|
|
hl lda wordgs_text,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
|
|
~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 wordgs_text,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
|
|
~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 Return from wordmatch.
|
|
|
|
|
|
startpos ds 2
|
|
cmdflag ds 2
|
|
|
|
;
|
|
; GS/OS string holding match word + wildcard "*"
|
|
;
|
|
wordgsbuf ds 2
|
|
wordgs_text ds WORDGS_SIZE
|
|
|
|
;
|
|
; Parameter block for shell InitWildcardGS call (p 414 in ORCA/M manual)
|
|
;
|
|
iwparm dc i2'2' pCount
|
|
dc i4'wordgsbuf' pathname with wildcard
|
|
iwFlags dc i2'1' flags
|
|
|
|
;
|
|
; Parameter block for shell NextWildcardGS call (p 414 in ORCA/M manual)
|
|
;
|
|
nwparm dc i2'4' pCount
|
|
dc i4'NameBuf' pathName
|
|
dc i2'0' access
|
|
nwType dc i2'0' fileType
|
|
nwAux dc i4'0' auxType
|
|
|
|
;
|
|
; Parameter block for shell ReadIndexedGS call (p 421 in ORCA/M manual)
|
|
;
|
|
idxParm anop
|
|
dc i2'4' pCount
|
|
dc i4'NameBuf' Name (pointer to GS/OS result buf)
|
|
dc i4'ResultBuf' Value (pointer to GS/OS result buf)
|
|
idxIndex ds 2 Index number
|
|
ds 2 Export flag
|
|
;
|
|
; GS/OS result buffer to hold name: maximum size = 255 bytes
|
|
;
|
|
NameBuf dc i2'259' Total length of result buf.
|
|
NameLen ds 2 Name's length returned here.
|
|
NameText ds 255 Text goes here.
|
|
ds 2 Room for terminating null bytes.
|
|
;
|
|
; GS/OS result buffer for testing whether a variable is defined.
|
|
; It doesn't have enough room for > 1 byte to be returned, but we
|
|
; only need to get the length of the value.
|
|
;
|
|
ResultBuf dc i2'5' Only five bytes total.
|
|
ds 2 Value's length returned here.
|
|
ds 1 Only 1 byte for value.
|
|
|
|
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
|
|
jeq 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
|
|
~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
|
|
status equ arg+4
|
|
space equ status+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
stz status
|
|
|
|
lda argc
|
|
dec a
|
|
bne ok
|
|
showusage ldx #^usage
|
|
lda #usage
|
|
jsr errputs
|
|
inc status
|
|
bra goexit
|
|
|
|
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
|
|
bra goexit
|
|
|
|
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
|
|
inc status
|
|
goexit bra 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
|
|
~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 2:status
|
|
|
|
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]
|
|
incad cp
|
|
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
|