gno/bin/gsh/dir.asm

738 lines
10 KiB
NASM
Raw Normal View History

**************************************************************************
*
* The GNO Shell Project
*
* Developed by:
* Jawaid Bazyar
* Tim Meekins
*
* $Id: dir.asm,v 1.4 1998/07/20 16:23:03 tribby Exp $
*
**************************************************************************
*
* DIR.ASM
* By Tim Meekins
* Modified by Dave Tribby for GNO 2.0.6
*
* Directory stack management
*
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
* | | | | | |
* ^ ^ ^ ^ ^ ^
**************************************************************************
*
* Interfaces defined in this file:
*
* InitDStack
*
* dirs
*
* pushd
*
* popd
*
* path2tilde
*
**************************************************************************
mcopy /obj/gno/bin/gsh/dir.mac
dummydir start ; ends up in .root
end
setcom 60
MAXD gequ 50
**************************************************************************
*
* Initialize directory stack
*
**************************************************************************
InitDStack START
using DirData
stz tods
stz dirstack
stz dirstack+2
rts
END
**************************************************************************
*
* DIRS: builtin command
* syntax: dirs [-l]
*
* display the directory stack
*
**************************************************************************
dirs START
using DirData
arg equ 0
space equ arg+4
subroutine (4:argv,2:argc),space
lda argc
dec a
beq showshort
dec a
bne using
ldy #4
lda [argv],y
sta arg
ldy #6
lda [argv],y
sta arg+2
lda [arg]
and #$FF
cmp #'-'
bne using
ldy #1
lda [arg],y
cmp #'l'
beq showlong
using ldx #^usingstr
lda #usingstr
jsr errputs
bra exit
showlong jsl dotods
pea 0
jsl showdir
bra exit
showshort jsl dotods
pea 1
jsl showdir
exit return 2:#0
usingstr dc c'usage: dirs [-l]',h'0d00'
END
**************************************************************************
*
* PUSHD: builtin command
* syntax: pushd [+n | dir]
*
* change directory and push
*
**************************************************************************
pushd START
using DirData
using vardata
count equ 0
p equ count+2
arg equ p+4
space equ arg+4
subroutine (4:argv,2:argc),space
lda argc
dec a
beq xchange
dec a
bne usage
ldy #4
lda [argv],y
sta arg
ldy #6
lda [argv],y
sta arg+2
lda [arg]
and #$FF
cmp #'+'
beq rotate
jmp godir
usage ldx #^usagestr
lda #usagestr
jsr errputs
jmp exit
xchange lda tods
bne xgoodie
ldx #^err1
lda #err1
jsr errputs
jmp exit
xgoodie jsl dotods
lda tods
dec a
asl a
asl a
tax
lda tods
asl a
asl a
tay
lda dirstack,x
pha
lda dirstack,y
sta dirstack,x
pla
sta dirstack,y
lda dirstack+2,x
pha
lda dirstack+2,y
sta dirstack+2,x
pla
sta dirstack+2,y
jmp gototop
rotate add4 arg,#1,p
pei (p+2)
pei (p)
jsr cstrlen
tax
Dec2Int (p,@x,#0),@a
sta count
cmp #0
beq godir
lda tods
beq roterr
lda count
cmp tods
beq rotloop
bcc rotloop
roterr ldx #^err2
lda #err2
jsr errputs
jmp exit
rotloop lda tods
dec a
asl a
asl a
tay
lda dirstack+6,y
pha
lda dirstack+4,y
pha
rotloop2 lda dirstack,y
sta dirstack+4,y
lda dirstack+2,y
sta dirstack+6,y
cpy #0
beq nextrot
dey
dey
dey
dey
bra rotloop2
nextrot pla
sta dirstack
pla
sta dirstack+2
dec count
bne rotloop
bra gototop
godir jsl dotods
pei (arg+2)
pei (arg)
jsl gotodir
bne exit
inc tods
lda tods
asl a
asl a
tay
lda #0
sta dirstack,y
sta dirstack+2,y
jsl dotods
bra done
gototop lda tods
asl a
asl a
tay
lda dirstack+2,y
pha
lda dirstack,y
pha
jsl gotodir
done lda varpushdsil
bne exit
pea 1
jsl showdir
exit return 2:#0
usagestr dc c'usage: pushd [+n | dir]',h'0d00'
err1 dc c'pushd: No other directory',h'0d00'
err2 dc c'pushd: Directory stack not that deep',h'0d00'
END
**************************************************************************
*
* POPD: builtin command
* syntax: popd [+n]
*
* pop a directory from stack and cd to it
*
**************************************************************************
popd START
using DirData
using vardata
count equ 0
arg equ count+2
space equ arg+4
subroutine (4:argv,2:argc),space
lda argc
dec a
jeq noarg
dec a
bne using
ldy #4
lda [argv],y
sta arg
ldy #6
lda [argv],y
sta arg+2
lda [arg]
and #$FF
cmp #'+'
beq plus
using ldx #^usingstr
lda #usingstr
jsr errputs
jmp exit
plus add4 arg,#1,arg
pei (arg+2)
pei (arg)
jsr cstrlen
tax
Dec2Int (arg,@x,#0),@a
sta count
cmp #0
beq noarg
lda tods
beq pluserr
lda count
cmp tods
beq doplus
bcc doplus
pluserr ldx #^err2
lda #err2
jsr errputs
bra exit
doplus jsl dotods
sub2 tods,count,@a
asl a
asl a
tax
phx
lda dirstack+2,x
pha
lda dirstack,x
pha
jsl nullfree
plx
plusloop lda dirstack+4,x
sta dirstack,x
lda dirstack+6,x
sta dirstack+2,x
inx4
dec count
bne plusloop
dec tods
bra gototop
noarg lda tods
bne noarg0
ldx #^err1
lda #err1
jsr errputs
bra exit
noarg0 lda tods
asl a
asl a
tay
lda dirstack+2,y
pha
lda dirstack,y
pha
jsl nullfree
dec tods
gototop lda tods
asl a
asl a
tay
lda dirstack+2,y
pha
lda dirstack,y
pha
jsl gotodir
lda varpushdsil
bne exit
pea 1
jsl showdir
exit return 2:#0
usingstr dc c'Usage: popd [+n]',h'0d00'
err1 dc c'popd: Directory stack empty',h'0d00'
err2 dc c'popd: Directory stack not that deep',h'0d00'
END
**************************************************************************
*
* Set prefix 0 to the passed c string
*
**************************************************************************
gotodir PRIVATE
retval equ 0
space equ retval+2
subroutine (4:dir),space
stz retval
pei (dir+2)
pei (dir)
jsr c2gsstr
sta PRecPath
sta GRecPath
stx PRecPath+2
stx GRecPath+2
lock mutex
GetFileInfo GRec
bcc ok
ohshit sta ErrError
ErrorGS Err
inc retval
bra done
ok if2 GRecFT,eq,#$F,ok2
ldx dir+2
lda dir
jsr errputs
ldx #^direrr
lda #direrr
jsr errputs
inc retval
bra done
ok2 SetPrefix PRec
bcs ohshit
done ph4 PRecPath
jsl nullfree
unlock mutex
return 2:retval
mutex key
; Parameter block for GS/OS SetPrefix call
PRec dc i'2' pCount
PRecNum dc i'0' prefixNum (0 = current directory)
PRecPath ds 4 Pointer to input prefix path
; Parameter block for GS/OS GetFileInfo call
GRec dc i'3' pCount
GRecPath ds 4 Pointer to input pathname
GRecAcc ds 2 access (result)
GRecFT ds 2 fileType (result)
; Parameter block for shell ErrorGS call (p 393 in ORCA/M manual)
Err dc i2'1' pCount
ErrError ds 2 Error number
dirErr dc c': Not a directory',h'0d00'
END
**************************************************************************
*
* Display the directory stack
*
**************************************************************************
showdir PRIVATE
using DirData
idx equ 0
space equ idx+2
subroutine (2:flag),space
lda tods
asl a
asl a
sta idx
loop lda flag
beq long
ldy idx
lda dirstack+2,y
pha
lda dirstack,y
pha
jsl path2tilde
phx
pha
jsr puts
jsl nullfree
bra next
long ldy idx
lda dirstack+2,y
tax
lda dirstack,y
jsr puts
next lda #' '
jsr putchar
lda idx
beq done
sub2 idx,#4,idx
bra loop
done jsr newline
return
END
**************************************************************************
*
* Set the top of the stack to the current directory
*
**************************************************************************
dotods PRIVATE
using DIRDATA
p equ 0
idx equ p+4
space equ idx+2
subroutine (0:dummy),space
lda tods
asl a
asl a
sta idx
tay
lda dirstack,y
ora dirstack+2,y
beq setit
lda dirstack+2,y
pha
lda dirstack,y
pha
jsl nullfree
setit lock mutex
jsl alloc256
sta gppath
stx gppath+2
sta p
stx P+2
lda #254
sta [p]
GetPrefix gpparm
ldy #2
lda [p],y
xba
sta [p],y
add4 p,#3,p
pei (p+2)
pei (p)
jsr p2cstr
sta p
stx p+2
ldx gppath+2
lda gppath
jsl free256
unlock mutex
ldy idx
lda p
sta dirstack,y
lda p+2
sta dirstack+2,y
return
mutex key
gpparm dc i2'2'
dc i2'0'
gppath dc i4'0'
END
**************************************************************************
*
* Directory stack data
*
**************************************************************************
DirData DATA
dirstack ds MAXD*4
tods dc i'0'
END
**************************************************************************
*
* Replace $HOME with a '~' in string
*
**************************************************************************
path2tilde START
ptr equ 0
newpath equ ptr+4
home equ newpath+4
space equ home+4
subroutine (4:path),space
pei (path+2)
pei (path)
jsr cstrlen
inc2 a
pea 0
pha
jsl ~NEW
sta newpath
stx newpath+2
sta ptr
stx ptr+2
jsl alloc256 Allocate 256 byte GS/OS result buf.
sta home
stx home+2
sta ReadName
stx ReadName+2
lda #256 Set buffer length word.
sta [home]
ReadVariableGS ReadVar Read $home environment variable.
ldy #2 Get result length word.
lda [home],y
beq notfound2 If 0, just copy the rest.
tax Use X to count down HOME chars.
ldy #0 path index is based from 0.
checkhome lda [path],y
and #$FF Isolate character in parameter,
beq notfound2 checking for end of string,
jsr tolower converting to lower-case
jsr toslash and changing ":" to "/".
pha Hold that character on the stack.
iny4 $home has 4 bytes of length info
lda [home],y that need to be indexed over.
dey2 Take back 3 of the offset,
dey nudging Y ahead by 1.
and #$FF Isolate $home character,
jsr tolower converting to lower-case
jsr toslash and changing ":" to "/".
cmp 1,s If the parameter character !=,
bne notfound there is no match.
pla Pop the parameter character off stack.
dex Decrement $home length counter.
bne checkhome If more, stay in loop.
; All the characters matched $home.
cmp #'/'
beq found
lda [path],y
and #$FF
beq found
jsr toslash
cmp #'/'
bne notfound2
found lda #'~'
sta [ptr]
incad ptr
bra copyrest
notfound pla
notfound2 ldy #0
copyrest short a
copyloop lda [path],y
beq endcopy
cmp #':'
bne copyput
lda #'/'
copyput sta [ptr]
long a
incad ptr
short a
iny
bra copyloop
endcopy sta [ptr]
long a
dec ptr
lda [ptr]
cmp #'/'
bne skipshorten
lda #0
sta [ptr]
skipshorten ldx home+2
lda home
jsl free256
return 4:newpath
; Parameter block for shell ReadVariableGS call (p 423 in ORCA/M manual)
ReadVar anop
dc i2'3' pCount
dc a4'homename' Pointer to name
ReadName ds 4 GS/OS Output buffer ptr: value
ds 2 export flag
homename gsstr 'home' Env variable name
END