mirror of https://github.com/GnoConsortium/gno.git
1970 lines
33 KiB
NASM
1970 lines
33 KiB
NASM
************************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
*
|
|
* $Id: builtin.asm,v 1.10 1999/01/14 17:44:22 tribby Exp $
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* BUILTIN.ASM
|
|
* By Tim Meekins
|
|
* Modified by Dave Tribby for GNO 2.0.6
|
|
*
|
|
* Builtin command searching and execution.
|
|
*
|
|
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
|
|
* | | | | | |
|
|
* ^ ^ ^ ^ ^ ^
|
|
**************************************************************************
|
|
*
|
|
* Interfaces defined in this file:
|
|
*
|
|
* builtin subroutine (2:argc,4:argv)
|
|
* Returns completion status in Accumulator
|
|
*
|
|
* IsBuiltin subroutine (4:name)
|
|
* return 2:tbl
|
|
*
|
|
* Remainder are interfaces to builtin commands with interface
|
|
* subroutine (4:argv,2:argc)
|
|
* returns status in accumulator
|
|
* cd (chdir is entry as an alternate name)
|
|
* clear
|
|
* echo
|
|
* pwd
|
|
* which
|
|
* prefix
|
|
* rehash (unhash is entry as an alternate name)
|
|
* exit
|
|
* setdebug
|
|
* psbi (command name is "ps")
|
|
* hashbi (command name is "hash")
|
|
* source
|
|
* cmdbi (command name is "commands")
|
|
*
|
|
**************************************************************************
|
|
|
|
mcopy /obj/gno/bin/gsh/builtin.mac
|
|
|
|
dummybuiltin start ; ends up in .root
|
|
end
|
|
|
|
setcom 60
|
|
|
|
p_next gequ 0 ;next in global proclist
|
|
p_friends gequ p_next+4 ;next in job list
|
|
p_flags gequ p_friends+4 ;various job status flags
|
|
p_reason gequ p_flags+2 ;reason for entering this state
|
|
p_index gequ p_reason+2 ;job index
|
|
p_pid gequ p_index+2 ;process id
|
|
p_jobid gequ p_pid+2 ;process id of job leader
|
|
p_command gequ p_jobid+2 ;command (how job invoked)
|
|
p_space gequ p_command+4 ;space for structure
|
|
|
|
**************************************************************************
|
|
*
|
|
* Find and execute a builtin command
|
|
*
|
|
**************************************************************************
|
|
|
|
builtin START
|
|
|
|
using BuiltinData
|
|
|
|
val equ 1
|
|
file equ val+2
|
|
tbl equ file+4
|
|
space equ tbl+4
|
|
argv equ space+3
|
|
argc equ argv+4
|
|
end equ argc+2
|
|
|
|
; subroutine (2:argc,4:argv),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
ldy #2
|
|
lda [argv]
|
|
sta file
|
|
lda [argv],y
|
|
sta file+2
|
|
ld4 builtintbl,tbl
|
|
ld2 -1,val
|
|
lda argc
|
|
beq done
|
|
|
|
loop ldy #2
|
|
lda [tbl]
|
|
ora [tbl],y
|
|
beq done
|
|
lda [tbl],y
|
|
pha
|
|
lda [tbl]
|
|
pha
|
|
pei (file+2)
|
|
pei (file)
|
|
jsr cmpcstr
|
|
beq foundit
|
|
bpl done
|
|
add2 tbl,#10,tbl
|
|
bra loop
|
|
;
|
|
; Found the command handler address. Since we don't have a "jsl [tbl],y"
|
|
; instruction, after pushing parameters on the stack we will push the
|
|
; return address, then the command's address - 1 (2 bytes only, since it's
|
|
; in the current bank). An rts will take us to the command handler, and a
|
|
; rtl at the end of the handler will bring us back.
|
|
;
|
|
foundit anop
|
|
pei (argv+2) Push parameters (3 words)
|
|
pei (argv)
|
|
pei (argc)
|
|
phk Push return address (high byte)
|
|
per return-1 Push return address (low bytes)
|
|
ldy #4 Get address of builtin handler
|
|
lda [tbl],y (16 bytes; assume in this bank)
|
|
dec a subtract 1 so rts will take us there
|
|
pha
|
|
rts Go to builtin handler routine.
|
|
;
|
|
; Return from handler to this location
|
|
;
|
|
return sta val Save return status.
|
|
|
|
;
|
|
; Free the argv array
|
|
;
|
|
ph4 #0 (no path)
|
|
pei (argc)
|
|
pei (argv+2)
|
|
pei (argv)
|
|
jsl argfree
|
|
|
|
done ldy val Y-reg = return value.
|
|
|
|
lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya Accumulator = return value.
|
|
|
|
rtl
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* Is it a built-in?
|
|
*
|
|
* Return value is: -1 if not a built-in, 0 if forked built-in,
|
|
* 1 if non-forked built-in.
|
|
*
|
|
**************************************************************************
|
|
|
|
IsBuiltin START
|
|
|
|
using BuiltinData
|
|
|
|
tbl equ 0
|
|
space equ tbl+4
|
|
|
|
subroutine (4:name),space
|
|
|
|
ld4 builtintbl,tbl
|
|
builtinloop ldy #2
|
|
lda [tbl]
|
|
ora [tbl],y
|
|
beq nofile
|
|
lda [tbl],y
|
|
pha
|
|
lda [tbl]
|
|
pha
|
|
pei (name+2)
|
|
pei (name)
|
|
jsr cmpcstr
|
|
beq foundit
|
|
bpl nofile
|
|
add2 tbl,#10,tbl
|
|
bra builtinloop
|
|
foundit ldy #8 Get the fork/nofork flag
|
|
lda [tbl],y and use it as return value.
|
|
bra foundbuiltin
|
|
|
|
nofile lda #-1 Set not-found return value.
|
|
foundbuiltin sta tbl
|
|
|
|
return 2:tbl
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* Builtin data
|
|
*
|
|
**************************************************************************
|
|
|
|
BuiltinData DATA
|
|
;
|
|
; First address is a pointer to the name, the second is a pointer to the
|
|
; command. Third value is fork flag (0 to fork, 1 for no fork).
|
|
; TABLE MUST BE SORTED BY COMMAND NAME.
|
|
;
|
|
builtintbl dc a4'aliasname,alias',i2'0'
|
|
dc a4'bgname,bg',i2'1'
|
|
dc a4'bindkeyname,bindkey',i2'0'
|
|
dc a4'cdname,cd',i2'1'
|
|
dc a4'chdirname,chdir',i2'1'
|
|
dc a4'clearname,clear',i2'1' Changed to unforked
|
|
dc a4'cmdname,cmdbi',i2'0'
|
|
dc a4'dirsname,dirs',i2'0'
|
|
dc a4'echoname,echo',i2'0'
|
|
dc a4'editname,edit',i2'1'
|
|
dc a4'exitname,exit',i2'1'
|
|
dc a4'exportname,export',i2'1'
|
|
dc a4'fgname,fg',i2'1'
|
|
dc a4'hashname,hashbi',i2'0'
|
|
dc a4'hname,PrintHistory',i2'0'
|
|
dc a4'jobsname,jobs',i2'1'
|
|
dc a4'killname,kill',i2'1'
|
|
dc a4'popdname,popd',i2'1'
|
|
dc a4'pfxname,prefix',i2'1'
|
|
dc a4'psname,psbi',i2'0'
|
|
dc a4'pushdname,pushd',i2'1'
|
|
dc a4'pwdname,pwd',i2'1'
|
|
dc a4'rehashname,rehash',i2'1'
|
|
dc a4'setname,set',i2'0'
|
|
dc a4'setbugname,setdebug',i2'0'
|
|
dc a4'setenvname,setenv',i2'0'
|
|
dc a4'sourcename,source',i2'1' Changed to unforked
|
|
dc a4'stopname,stop',i2'1'
|
|
dc a4'tsetname,tset',i2'1'
|
|
dc a4'unaliasname,unalias',i2'1'
|
|
dc a4'unhashname,unhash',i2'1'
|
|
dc a4'unsetname,unset',i2'1'
|
|
dc a4'whichname,which',i2'0'
|
|
dc i4'0,0'
|
|
|
|
aliasname dc c'alias',h'00'
|
|
bgname dc c'bg',h'00'
|
|
bindkeyname dc c'bindkey',h'00'
|
|
chdirname dc c'chdir',h'00'
|
|
cdname dc c'cd',h'00'
|
|
clearname dc c'clear',h'00'
|
|
cmdname dc c'commands',h'00'
|
|
dirsname dc c'dirs',h'00'
|
|
echoname dc c'echo',h'00'
|
|
editname dc c'edit',h'00'
|
|
exitname dc c'exit',h'00'
|
|
exportname dc c'export',h'00'
|
|
fgname dc c'fg',h'00'
|
|
hashname dc c'hash',h'00'
|
|
hname dc c'history',h'00'
|
|
jobsname dc c'jobs',h'00'
|
|
killname dc c'kill',h'00'
|
|
pfxname dc c'prefix',h'00'
|
|
popdname dc c'popd',h'00'
|
|
psname dc c'ps',h'00'
|
|
pushdname dc c'pushd',h'00'
|
|
pwdname dc c'pwd',h'00'
|
|
rehashname dc c'rehash',h'00'
|
|
setbugname dc c'setdebug',h'00'
|
|
setname dc c'set',h'00'
|
|
setenvname dc c'setenv',h'00'
|
|
sourcename dc c'source',h'00'
|
|
stopname dc c'stop',h'00'
|
|
tsetname dc c'tset',h'00'
|
|
unaliasname dc c'unalias',h'00'
|
|
unhashname dc c'unhash',h'00'
|
|
unsetname dc c'unset',h'00'
|
|
whichname dc c'which',h'00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* CD: builtin command
|
|
* syntax: cd [pathname]
|
|
*
|
|
* Changes the current prefix to pathname. If no pathname then set to $HOME
|
|
*
|
|
**************************************************************************
|
|
|
|
cd START
|
|
chdir ENTRY
|
|
|
|
dpg equ 1 Direct page pointer.
|
|
buf equ dpg+4 Buffer address to be freed.
|
|
status equ buf+4 Status returned from command.
|
|
space equ status+2
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
lock cdmutex
|
|
|
|
stz buf Clear the pointer to
|
|
stz buf+2 allocated buffer.
|
|
|
|
stz status Assume good status.
|
|
|
|
lda argc Number of parameters
|
|
dec a determines type of cd...
|
|
beq cdhome either to $HOME
|
|
dec a or to the directory
|
|
jeq paramcd on the command line.
|
|
|
|
;
|
|
; Illegal parameters: print usage string
|
|
;
|
|
showusage inc status Return status = 1.
|
|
lda [argv]
|
|
tax
|
|
ldy #2
|
|
lda [argv],y
|
|
stx argv
|
|
sta argv+2
|
|
lda [argv],y
|
|
and #$FF
|
|
beq cdusage
|
|
ldx #^Usage2 Print chdir usage
|
|
lda #Usage2
|
|
jsr errputs
|
|
jmp exit
|
|
cdusage ldx #^Usage Print cd usage
|
|
lda #Usage
|
|
jsr errputs
|
|
jmp exit
|
|
|
|
;
|
|
; Set prefix to $home
|
|
;
|
|
cdhome anop
|
|
ph4 #home Get value of $HOME
|
|
jsl getenv
|
|
sta buf If GS/OS result buffer
|
|
stx buf+2 wasn't allocated,
|
|
ora buf+2
|
|
jeq exit there's no more to do.
|
|
|
|
clc Calculate address
|
|
lda buf of GS/OS input string
|
|
adc #2 (2 bytes from start of
|
|
sta PRecPath result buffer).
|
|
sta GRecPath
|
|
lda buf+2
|
|
adc #0
|
|
sta PRecPath+2
|
|
sta GRecPath+2
|
|
|
|
bra getinfo
|
|
|
|
;
|
|
; Set prefix to path specified on command line
|
|
;
|
|
paramcd anop
|
|
|
|
ldy #4
|
|
lda [argv],y
|
|
sta dpg
|
|
iny2
|
|
lda [argv],y
|
|
sta dpg+2
|
|
|
|
lda [dpg]
|
|
and #$FF
|
|
if2 @a,ne,#'-',setprefix
|
|
jmp showusage
|
|
|
|
setprefix pei (dpg+2)
|
|
pei (dpg)
|
|
jsr c2gsstr
|
|
sta PRecPath
|
|
sta GRecPath
|
|
sta buf
|
|
stx PRecPath+2
|
|
stx GRecPath+2
|
|
stx buf+2
|
|
|
|
;
|
|
; Get file information to determine whether target is a valid directory
|
|
;
|
|
getinfo GetFileInfo GRec
|
|
bcc ok
|
|
ohshit sta ErrError
|
|
ErrorGS Err
|
|
inc status Return status = 1.
|
|
bra done
|
|
|
|
ok if2 GRecFT,eq,#$F,ok2
|
|
ldx dpg+2
|
|
lda dpg
|
|
jsr errputs
|
|
ldx #^direrr
|
|
lda #direrr
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
bra done
|
|
|
|
;
|
|
; Everything looks OK. Set prefix 0 to the indicated value
|
|
;
|
|
ok2 SetPrefix PRec
|
|
bcs ohshit
|
|
|
|
;
|
|
; Deallocate buffer (if necessary), unlock mutex, cleanup stack, and leave
|
|
;
|
|
done ph4 buf
|
|
jsl nullfree
|
|
|
|
exit unlock cdmutex
|
|
|
|
ldy status Put return status in Y-reg
|
|
|
|
lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya Put return status in Accumulator.
|
|
|
|
rtl
|
|
|
|
cdmutex key Mutual exclusion key
|
|
|
|
; Parameter block for GS/OS SetPrefix call
|
|
PRec dc i'2' pCount
|
|
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)
|
|
|
|
home gsstr 'home' Env variable name
|
|
|
|
; Parameter block for shell ErrorGS call (p 393 in ORCA/M manual)
|
|
Err dc i2'1' pCount
|
|
ErrError ds 2 Error number
|
|
|
|
Usage dc c'Usage: cd [pathname]',h'0d00'
|
|
Usage2 dc c'Usage: chdir [pathname]',h'0d00'
|
|
dirErr dc c': Not a directory',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* CLEAR: builtin command
|
|
* syntax: clear
|
|
*
|
|
* clears the screen
|
|
*
|
|
**************************************************************************
|
|
|
|
clear START
|
|
|
|
space equ 1
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
tsc
|
|
phd
|
|
tcd
|
|
|
|
lda argc
|
|
dec a
|
|
beq clearit
|
|
|
|
ldx #^Usage
|
|
lda #Usage
|
|
jsr errputs
|
|
ldy #1 Return status = 1.
|
|
bra exit
|
|
|
|
clearit jsr clearscrn
|
|
jsr flush
|
|
ldy #0 Return status = 0.
|
|
|
|
exit lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya
|
|
|
|
rtl
|
|
|
|
Usage dc c'Usage: clear',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* ECHO: builtin command
|
|
* syntax: echo [-n] [text][...]
|
|
*
|
|
* Echo displays to stdout what is on the command (except -n).
|
|
*
|
|
* If '-n' specified then don't print newline.
|
|
*
|
|
**************************************************************************
|
|
|
|
echo START
|
|
|
|
val equ 1
|
|
nl equ val+2 flag: was -n option set?
|
|
ptr equ nl+2
|
|
status equ ptr+4
|
|
space equ status+2
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
* Add space on stack for local variables
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
stz status Clear return status.
|
|
stz nl Clear the -n flag.
|
|
dec argc Decrement argument counter.
|
|
jeq done Done if no more arguments.
|
|
|
|
ldy #4
|
|
lda [argv],y Set ptr to
|
|
sta ptr point to the
|
|
iny2 text of the
|
|
lda [argv],y first
|
|
sta ptr+2 argument.
|
|
ldy #1
|
|
lda [ptr] Get first
|
|
and #$FF character.
|
|
if2 @a,ne,#'-',loop If != '-', handle as regular param.
|
|
|
|
|
|
; First argument begins with "-"; only legal value is -n
|
|
|
|
lda [ptr],y Get second
|
|
and #$FF character.
|
|
if2 @a,eq,#'n',gotn If != 'n', it's a bad one.
|
|
|
|
showusage ldx #^Usage Incorrect parameter usage:
|
|
lda #Usage display the usage string.
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
jmp exit
|
|
|
|
gotn iny
|
|
lda [ptr],y Get third
|
|
and #$FF character.
|
|
bne showusage If != 0, it's a bad one.
|
|
inc nl Set the -n flag.
|
|
add2 argv,#4,argv Bump argument pointer.
|
|
dec argc Decrement argument counter.
|
|
jeq done Done if no more arguments.
|
|
|
|
;
|
|
; Beginning of main processing loop of echo parameters.
|
|
;
|
|
loop add2 argv,#4,argv Bump argument pointer.
|
|
ldy #2
|
|
lda [argv],y Set ptr to argv (next argument)
|
|
sta ptr+2
|
|
lda [argv]
|
|
sta ptr
|
|
putloop lda [ptr] Get first
|
|
and #$FF character.
|
|
cmp #0 If 0,
|
|
jeq doneput done with this argument.
|
|
cmp #'\' If != "\"
|
|
jne putit go save in print buffer.
|
|
incad ptr Escape character found; point
|
|
lda [ptr] to the next
|
|
and #$FF character.
|
|
beq doneput If 0, done with this argument.
|
|
if2 @a,ne,#'b',esc02 Check for escape codes: "b"
|
|
ldx #1
|
|
jsr moveleft moveleft
|
|
bra didit
|
|
esc02 if2 @a,ne,#'f',esc03 "f"
|
|
jsr clearscrn clearscreen
|
|
bra didit
|
|
esc03 if2 @a,ne,#'n',esc04 "n"
|
|
lda #13 print newline
|
|
bra putit
|
|
esc04 if2 @a,ne,#'r',esc05 "r"
|
|
lda #13 print newline
|
|
bra putit
|
|
esc05 if2 @a,ne,#'t',esc06 "t"
|
|
lda #9 print tab
|
|
bra putit
|
|
esc06 if2 @a,ne,#'0',putit "0"
|
|
stz val decode numeric value
|
|
ldy #1
|
|
escloop lda [ptr],y
|
|
and #$FF
|
|
beq putval
|
|
if2 @a,cc,#'0',putval
|
|
if2 @a,cs,#'9'+1,putval
|
|
sub2 @a,#'0',@a
|
|
pha
|
|
lda val
|
|
asl2 a
|
|
adc val
|
|
asl a
|
|
adc 1,s
|
|
sta val
|
|
pla
|
|
incad ptr
|
|
bra escloop
|
|
|
|
putval lda val Get numeric escape code.
|
|
|
|
putit jsr putchar Save character in accumulator.
|
|
didit incad ptr Point to next char in arg
|
|
jmp putloop and go process it.
|
|
|
|
doneput dec argc Decrement argument counter.
|
|
beq done Done if no more arguments.
|
|
bmi done (or if there were no arguments!)
|
|
lda #' ' Add a blank
|
|
jsr putchar between arguments.
|
|
jmp loop Get next argument.
|
|
|
|
done lda nl If "-n" flag isn't set,
|
|
bne exit
|
|
jsr newline add a newline.
|
|
|
|
exit jsr flush Print the buffer.
|
|
ldy status
|
|
|
|
* Clear parameters from stack and return from subroutine.
|
|
|
|
lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya
|
|
|
|
rtl
|
|
|
|
Usage dc c'Usage: echo [-n] [strings...]',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* PWD: builtin command
|
|
* syntax: pwd
|
|
*
|
|
* print the working directory.
|
|
*
|
|
**************************************************************************
|
|
|
|
pwd START
|
|
|
|
ptr equ 1
|
|
space equ ptr+4
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
dec argc If an argument was provided,
|
|
beq wait
|
|
|
|
ldx #^Usage print the usage string.
|
|
lda #Usage
|
|
jsr errputs
|
|
ldy #1 Return status = 1.
|
|
bra exit
|
|
|
|
wait pea 0
|
|
jsl getpfxstr Get value of prefix 0.
|
|
sta ptr
|
|
stx ptr+2
|
|
|
|
ora ptr+2 If NULL pointer returned,
|
|
beq done an error was reported.
|
|
|
|
ldy #2 If length of returned
|
|
lda [ptr],y GS/OS string is 0,
|
|
beq freebuf an error was reported.
|
|
|
|
lda ptr X/A = address of
|
|
clc text (four bytes
|
|
adc #4 beyond start).
|
|
bcc doputs
|
|
inx
|
|
doputs jsr puts Print the c-string
|
|
jsr newline and add a newline.
|
|
|
|
freebuf ph4 ptr Free the buffer.
|
|
jsl nullfree
|
|
|
|
done ldy #0 Return status = 0.
|
|
|
|
exit lda space Deallocate stack space
|
|
sta end-3 and return to the caller.
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya Return status.
|
|
|
|
rtl
|
|
|
|
Usage dc c'Usage: pwd',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* WHICH: builtin command
|
|
* syntax: which [command ...]
|
|
*
|
|
* displays the location of command
|
|
*
|
|
**************************************************************************
|
|
|
|
which START
|
|
|
|
using hashdata
|
|
|
|
ptr equ 1
|
|
sptr equ ptr+4
|
|
file equ sptr+4
|
|
status equ file+4
|
|
space equ status+2
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
stz status Clear return status.
|
|
;
|
|
; Display usage if no argument
|
|
;
|
|
if2 argc,ge,#2,loop
|
|
ldx #^whicherr
|
|
lda #whicherr
|
|
jsr errputs
|
|
inc status Return status = 1
|
|
jmp exit
|
|
;
|
|
; loop through each argument
|
|
;
|
|
loop add2 argv,#4,argv
|
|
dec argc
|
|
jeq exit
|
|
|
|
lda [argv]
|
|
sta file
|
|
ldy #2
|
|
lda [argv],y
|
|
sta file+2
|
|
|
|
;
|
|
; see if it's an alias
|
|
;
|
|
pei (file+2)
|
|
pei (file)
|
|
jsl findalias
|
|
sta ptr
|
|
stx ptr+2
|
|
ora ptr+2
|
|
beq chkbuiltin
|
|
ldx #^aliasstr
|
|
lda #aliasstr
|
|
jsr puts
|
|
ldx ptr+2
|
|
lda ptr
|
|
jsr puts
|
|
jmp nextarg
|
|
;
|
|
; was it a built-in?
|
|
;
|
|
chkbuiltin pei (file+2)
|
|
pei (file)
|
|
jsl IsBuiltin
|
|
cmp #-1
|
|
beq tryhash
|
|
foundbuiltin ldx #^builtstr
|
|
lda #builtstr
|
|
jsr puts
|
|
jmp nextarg
|
|
;
|
|
; See if it was hashed
|
|
;
|
|
tryhash pei (file+2)
|
|
pei (file)
|
|
ph4 hash_table
|
|
ph4 #hash_paths
|
|
jsl search
|
|
cmp #0
|
|
bne foundhash
|
|
cpx #0
|
|
beq thispfx
|
|
;
|
|
; It was hashed, so say so.
|
|
;
|
|
foundhash sta sptr
|
|
stx sptr+2
|
|
jsr puts
|
|
pei (sptr+2) Free memory allocated
|
|
pei (sptr) by search to hold full path.
|
|
jsl nullfree
|
|
jmp nextarg
|
|
;
|
|
; It must be in the current prefix, so check it out.
|
|
;
|
|
thispfx lock whichmutex
|
|
;
|
|
; check for existence of file
|
|
;
|
|
pei (file+2)
|
|
pei (file)
|
|
jsr c2gsstr
|
|
sta GRecPath
|
|
stx GRecPath+2
|
|
sta ptr
|
|
stx ptr+2
|
|
|
|
GetFileInfo GRec
|
|
bcs nofile
|
|
;
|
|
; we found the file, so display the cwd
|
|
;
|
|
showcwd pei (ptr+2)
|
|
pei (ptr)
|
|
jsl nullfree
|
|
|
|
pea 0
|
|
jsl getpfxstr Get value of prefix 0.
|
|
sta ptr
|
|
stx ptr+2
|
|
|
|
ora ptr+2 If NULL pointer returned,
|
|
beq donecwd an error was reported.
|
|
|
|
ldy #2 If length of returned
|
|
lda [ptr],y GS/OS string is 0,
|
|
beq freebuf an error was reported.
|
|
|
|
lda ptr X/A = address of
|
|
clc text (four bytes
|
|
adc #4 beyond start).
|
|
bcc doputs
|
|
inx
|
|
doputs jsr puts Print the directory name.
|
|
|
|
ldx file+2 Print the file name.
|
|
lda file
|
|
jsr puts
|
|
|
|
freebuf ph4 ptr Free the buffer.
|
|
jsl nullfree
|
|
stz ptr
|
|
stz ptr+2
|
|
bra donecwd
|
|
;
|
|
; No such command
|
|
;
|
|
nofile ldx #^cantdoit
|
|
lda #cantdoit
|
|
jsr puts
|
|
donecwd unlock whichmutex
|
|
pei (ptr+2)
|
|
pei (ptr)
|
|
jsl nullfree
|
|
;
|
|
; Go try the next file.
|
|
;
|
|
nextarg jsr newline
|
|
jmp loop
|
|
|
|
exit ldy status
|
|
lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya
|
|
|
|
rtl
|
|
|
|
whicherr dc c'Usage: which [file ...]',h'0d00'
|
|
builtstr dc c'Shell Built-in Command',h'00'
|
|
cantdoit dc c'Command Not Found',h'00'
|
|
aliasstr dc c'Aliased as ',h'00'
|
|
|
|
whichmutex key
|
|
|
|
GRec dc i'4'
|
|
GRecPath ds 4
|
|
ds 2
|
|
GRecFileType ds 2
|
|
GRecAuxType ds 4
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* PREFIX: builtin command
|
|
* syntax: prefix [num [prefix]]
|
|
*
|
|
* sets prefix number num to prefix or print list of all prefixes
|
|
*
|
|
**************************************************************************
|
|
|
|
prefix START
|
|
|
|
dir equ 1
|
|
numstr equ dir+4
|
|
pfxnum equ numstr+4
|
|
status equ pfxnum+2
|
|
space equ status+2
|
|
argc equ space+3
|
|
argv equ argc+2
|
|
end equ argv+4
|
|
|
|
; subroutine (4:argv,2:argc),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
lock prefixmutex
|
|
|
|
stz status Clear return status.
|
|
lda argc Get number of arguments.
|
|
dec a
|
|
beq showall If no parameters, show all prefixes.
|
|
dec a
|
|
jeq showone If one, show one.
|
|
dec a
|
|
jeq setprefix If two, set a prefix.
|
|
|
|
ldx #^usage
|
|
lda #usage
|
|
jsr errputs
|
|
jmp badstat
|
|
|
|
; -------------------------------------------------------------------
|
|
;
|
|
; No parameters provided: show all the prefixes
|
|
;
|
|
showall anop
|
|
lda #$FFFF
|
|
sta pfxnum First prefix # will be 0.
|
|
|
|
pha Get the boot volume string.
|
|
jsl getpfxstr
|
|
sta dir
|
|
stx dir+2
|
|
|
|
ora dir+2 If NULL pointer returned,
|
|
beq bumppfx an error was reported.
|
|
|
|
ldx #^bootstr
|
|
lda #bootstr
|
|
bra printid Jump into the loop
|
|
|
|
allloop lda pfxnum
|
|
pha
|
|
jsl getpfxstr
|
|
sta dir
|
|
stx dir+2
|
|
|
|
ora dir+2 If NULL pointer returned,
|
|
beq bumppfx an error was reported.
|
|
|
|
ldy #2 Get length word.
|
|
lda [dir],y
|
|
beq nextall If zero, do the next prefix.
|
|
Int2Dec (pfxnum,#pfxstr,#2,#0)
|
|
ldx #^pfxstr
|
|
lda #pfxstr
|
|
printid jsr puts
|
|
ldx dir+2
|
|
lda dir X/A = address of
|
|
clc text (four bytes
|
|
adc #4 beyond start).
|
|
bcc doputs2
|
|
inx
|
|
doputs2 jsr puts Print the directory name
|
|
jsr newline
|
|
|
|
nextall ph4 dir Free the GS/OS result buffer
|
|
jsl nullfree allocated for pathname.
|
|
bumppfx inc pfxnum Bump the prefix number.
|
|
if2 pfxnum,cc,#32,allloop
|
|
jmp done
|
|
|
|
; -------------------------------------------------------------------
|
|
;
|
|
; One parameter provided: show a single prefix
|
|
;
|
|
showone ldy #1*4+2 Put pointer to
|
|
lda [argv],y first command
|
|
sta numstr+2 argument in
|
|
pha numstr, and
|
|
dey2 also on stack
|
|
lda [argv],y as parameter.
|
|
sta numstr
|
|
pha
|
|
jsr cstrlen Get length of argument.
|
|
tax
|
|
|
|
Dec2Int (numstr,@x,#0),@a Convert to integer.
|
|
cmp #32 If prefix num >= 32,
|
|
bcc getpfx
|
|
jsr newline just print blank line.
|
|
jmp done
|
|
|
|
getpfx pha Get that prefix value.
|
|
jsl getpfxstr
|
|
sta dir
|
|
stx dir+2
|
|
|
|
ora dir+2 If NULL pointer returned,
|
|
jeq done an error was reported.
|
|
|
|
Int2Dec (pfxnum,#pfxstr,#2,#0)
|
|
|
|
ldy #2 Get length word.
|
|
lda [dir],y
|
|
beq donewline If zero, just print newline.
|
|
ldx dir+2
|
|
lda dir X/A = address of
|
|
clc text (four bytes
|
|
adc #4 beyond start).
|
|
bcc doputs3
|
|
inx
|
|
doputs3 jsr puts Print the directory name
|
|
donewline jsr newline
|
|
ph4 dir Free the GS/OS result buffer
|
|
jsl nullfree allocated for pathname.
|
|
jmp done
|
|
|
|
; -------------------------------------------------------------------
|
|
;
|
|
; Two parameters provided: set a prefix
|
|
;
|
|
setprefix ldy #1*4+2 Put pointer to
|
|
lda [argv],y first command
|
|
sta numstr+2 argument (prefix
|
|
pha num) in numstr, and
|
|
dey2 also on stack
|
|
lda [argv],y as parameter.
|
|
sta numstr
|
|
pha
|
|
jsr cstrlen Get length of argument.
|
|
tax
|
|
|
|
Dec2Int (numstr,@x,#0),PRecNum Convert to integer string.
|
|
|
|
lda PRecNum
|
|
cmp #32 If prefix num >= 32,
|
|
bcs done nothing to do.
|
|
|
|
ldy #2*4+2 Put pointer to
|
|
lda [argv],y second command
|
|
pha argument (value)
|
|
dey2 on stack as parameter.
|
|
lda [argv],y
|
|
pha
|
|
jsr c2gsstr Convert to GS string.
|
|
|
|
sta GRecPath Store in GetFileInfo
|
|
stx GRecPath+2 parameter block and
|
|
sta PRecPath SetPrefix p.b.
|
|
stx PRecPath+2
|
|
|
|
;
|
|
; Get file information to determine whether target is a valid directory
|
|
;
|
|
GetFileInfo GRec
|
|
bcc ok
|
|
sta ErrError
|
|
ErrorGS Err
|
|
bra done
|
|
|
|
ok if2 GRecFT,eq,#$F,ok2 If filetype != $F,
|
|
ldx #^direrr print error message
|
|
lda #direrr 'Not a directory'
|
|
jsr errputs
|
|
badstat inc status Return status = 1.
|
|
bra done
|
|
|
|
ok2 SetPrefix PRec Set the prefix.
|
|
bcc finish If error flag set,
|
|
ldx #^errorstr print error message
|
|
lda #errorstr 'could not set prefix,
|
|
jsr errputs pathname may not exist.'
|
|
inc status Return status = 1.
|
|
|
|
; -------------------------------------------------------------------
|
|
;
|
|
; All done: cleanup and return
|
|
;
|
|
finish ph4 PRecPath Free the name string buffer.
|
|
jsl nullfree
|
|
|
|
;
|
|
; Exit through here if PRecPath wasn't used
|
|
;
|
|
done unlock prefixmutex
|
|
|
|
ldy status
|
|
|
|
lda space
|
|
sta end-3
|
|
lda space+1
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
|
|
tya
|
|
|
|
rtl
|
|
|
|
prefixmutex key
|
|
|
|
errorstr dc c'prefix: could not set prefix, pathname may not exist.'
|
|
dc h'0d00'
|
|
usage dc c'Usage: prefix prefixnum prefixname',h'0d00'
|
|
bootstr dc c' *: ',h'00'
|
|
pfxstr dc c'00: ',h'00'
|
|
dirErr dc c'prefix: Not a directory',h'0d00'
|
|
|
|
;
|
|
; 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 buffer for SetPrefix GS/OS call
|
|
;
|
|
PRec dc i'2' pCount
|
|
PRecNum dc i'0' prefix number
|
|
PRecPath ds 4 pointer to GS/OS string with value
|
|
|
|
;
|
|
; Parameter block for shell ErrorGS call (p 393 in ORCA/M manual)
|
|
;
|
|
Err dc i2'1' pCount
|
|
ErrError ds 2 Error number
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* REHASH: builtin command
|
|
* syntax: rehash
|
|
*
|
|
* rehashes the path
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* UNHASH: builtin command
|
|
* syntax: unhash
|
|
*
|
|
* turns off command hashing
|
|
*
|
|
**************************************************************************
|
|
|
|
rehash START
|
|
unhash ENTRY
|
|
|
|
status equ 0
|
|
space equ status+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
stz status
|
|
|
|
lda argc
|
|
dec a
|
|
beq doit
|
|
|
|
ldx #^Usage
|
|
lda #Usage
|
|
jsr errputs
|
|
ldy #2
|
|
lda [argv],y
|
|
tax
|
|
lda [argv]
|
|
jsr errputs
|
|
lda #13
|
|
jsr errputchar
|
|
inc status Return status = 1.
|
|
bra exit
|
|
|
|
doit jsr dispose_hash ;remove old table
|
|
lda [argv]
|
|
tax
|
|
ldy #2
|
|
lda [argv],y
|
|
sta argv+2
|
|
stx argv
|
|
lda [argv]
|
|
and #$FF
|
|
jsr tolower
|
|
if2 @a,eq,#'u',exit ;if 'rehash' do the hashing.
|
|
jsl hashpath ;hash the path
|
|
|
|
exit return 2:status
|
|
|
|
Usage dc c'Usage: ',h'00'
|
|
|
|
END
|
|
|
|
|
|
**************************************************************************
|
|
*
|
|
* EXIT: builtin command
|
|
* syntax: exit
|
|
*
|
|
* exit gsh
|
|
*
|
|
**************************************************************************
|
|
|
|
exit START
|
|
|
|
using global
|
|
|
|
space equ 0
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
inc exit_requested
|
|
|
|
return 2:#0
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* SETDEBUG: builtin command
|
|
* syntax: setdebug (val | [+|-]flag)
|
|
*
|
|
* sets debugging in kernel
|
|
*
|
|
**************************************************************************
|
|
|
|
setdebug START
|
|
|
|
arg equ 0
|
|
newdebug equ arg+4
|
|
mode equ newdebug+2
|
|
status equ mode+2
|
|
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 Return status = 1.
|
|
jmp return
|
|
|
|
ok stz mode
|
|
mv2 globaldebug,newdebug
|
|
dec argc
|
|
add2 argv,#4,argv
|
|
loop lda [argv]
|
|
sta arg
|
|
ldy #2
|
|
lda [argv],y
|
|
sta arg+2
|
|
lda [arg]
|
|
and #$FF
|
|
if2 @a,eq,#'-',turnoff
|
|
if2 @a,eq,#'+',turnon
|
|
ldx mode
|
|
bne showusage
|
|
ldx argc
|
|
dex
|
|
bne showusage
|
|
if2 @a,cc,#'0',showusage
|
|
if2 @a,cs,#'9'+1,showusage
|
|
pei (arg+2)
|
|
pei (arg)
|
|
jsr cstrlen
|
|
tax
|
|
Dec2Int (arg,@x,#0),@a
|
|
sta newdebug
|
|
jmp done
|
|
|
|
turnoff jsr findflag
|
|
eor #$FFFF
|
|
and newdebug
|
|
bra turnnext
|
|
turnon jsr findflag
|
|
ora newdebug
|
|
turnnext sta newdebug
|
|
ld2 1,mode
|
|
add2 argv,#4,argv
|
|
dec argc
|
|
beq done
|
|
jmp loop
|
|
|
|
done setdebug newdebug
|
|
mv2 newdebug,globaldebug
|
|
return return 2:status
|
|
|
|
findflag incad arg
|
|
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
|
|
|
|
foundit pla
|
|
lsr a
|
|
tax
|
|
lda bittbl,x
|
|
rts
|
|
|
|
nofind pla
|
|
ldx arg+2
|
|
lda arg
|
|
jsr errputs
|
|
ldx #^errstr
|
|
lda #errstr
|
|
jsr errputs
|
|
lda #-1
|
|
pla ;rts address
|
|
jmp showusage
|
|
|
|
usage dc c'Usage: setdebug (value | [+|-]flag ... )',h'0d0d'
|
|
dc c'Flags: gsostrace - Trace GS/OS calls',h'0d'
|
|
dc c' gsosblocks - Trace GS/OS parameter blocks',h'0d'
|
|
dc c' gsoserrors - Trace GS/OS errors',h'0d'
|
|
dc c' pathtrace - Trace GS/OS pathnames',h'0d'
|
|
dc c' sigtrace - Trace signals',h'0d'
|
|
dc c' systrace - Trace system calls',h'0d'
|
|
* >> Next line is temporary
|
|
dc c' breakpoint - Coded brk instructions',h'0d'
|
|
dc h'00'
|
|
|
|
errstr dc c': Unknown flag',h'0d0d00'
|
|
|
|
nametbl dc a4'str01,str02,str03,str04,str05,str06,str07,0'
|
|
str01 dc c'gsostrace',h'00'
|
|
str02 dc c'pathtrace',h'00'
|
|
str03 dc c'gsoserrors',h'00'
|
|
str04 dc c'sigtrace',h'00'
|
|
str05 dc c'systrace',h'00'
|
|
str06 dc c'gsosblocks',h'00'
|
|
* >> Next line is temporary; Also: remove str07 in nametbl
|
|
str07 dc c'breakpoint',h'00'
|
|
|
|
bittbl dc i2'%000001'
|
|
dc i2'%000010'
|
|
dc i2'%000100'
|
|
dc i2'%001000'
|
|
dc i2'%010000'
|
|
dc i2'%100000'
|
|
* >> Next line is temporary
|
|
dc i2'%10000000'
|
|
|
|
* >> Next line is temporary
|
|
check4debug ENTRY
|
|
|
|
globaldebug dc i2'0'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* PS: builtin command
|
|
* syntax: ps
|
|
*
|
|
* display process status
|
|
*
|
|
**************************************************************************
|
|
|
|
psbi START
|
|
|
|
using pdata
|
|
|
|
myuid equ 0
|
|
t equ myuid+2
|
|
ps2 equ t+4
|
|
pr2 equ ps2+4
|
|
pr equ pr2+4
|
|
ps equ pr+4
|
|
status equ ps+4
|
|
space equ status+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
stz status
|
|
|
|
lda argc
|
|
dec a
|
|
beq ok
|
|
showusage ldx #^usage
|
|
lda #usage
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
jmp return
|
|
|
|
ok getuid
|
|
sta myuid
|
|
kvm_open
|
|
sta ps
|
|
stx ps+2
|
|
ora2 @a,ps+2,@a
|
|
bne ok2
|
|
ldx #^kvmerrstr
|
|
lda #kvmerrstr
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
jmp done
|
|
|
|
ok2 ldx #^header
|
|
lda #header
|
|
jsr puts
|
|
|
|
loop kvmnextproc ps
|
|
sta pr
|
|
stx pr+2
|
|
ora2 @a,pr+2,@a
|
|
jeq done
|
|
|
|
ldy #94 ;ps->p_uid
|
|
lda [pr],y
|
|
cmp myuid
|
|
jne skip
|
|
|
|
ldy #2
|
|
lda [ps],y ;ps->pid
|
|
Int2Dec (@a,#pidstr,#5,#0)
|
|
ldx #^pidstr
|
|
lda #pidstr
|
|
jsr puts
|
|
|
|
ldy #2
|
|
lda [pr],y ;pr->processState
|
|
cmp #9
|
|
bcc okstate
|
|
lda #9
|
|
okstate asl a
|
|
asl a
|
|
asl a
|
|
tax
|
|
ldy #8
|
|
putstate lda statetbl,x
|
|
phx
|
|
phy
|
|
jsr putchar
|
|
ply
|
|
plx
|
|
inx
|
|
dey
|
|
bne putstate
|
|
|
|
ldy #6
|
|
lda [pr],y ;pr->ttyID
|
|
beq ttnul
|
|
cmp #3
|
|
bne ttnum
|
|
lda #'c'
|
|
jsr putchar
|
|
lda #'o'
|
|
bra showuser
|
|
ttnul lda #'n'
|
|
jsr putchar
|
|
lda #'u'
|
|
bra showuser
|
|
ttnum ldy #0
|
|
ttnumlup cmp #10
|
|
bcc ttnum0
|
|
sec
|
|
sbc #10
|
|
iny
|
|
bra ttnumlup
|
|
ttnum0 pha
|
|
tya
|
|
clc
|
|
adc #'0'
|
|
jsr putchar
|
|
pla
|
|
clc
|
|
adc #'0'
|
|
showuser jsr putchar
|
|
|
|
ldy #4
|
|
lda [pr],y ;pr->userID
|
|
Int2Hex (@a,#userstr+1,#4)
|
|
ldx #^userstr
|
|
lda #userstr
|
|
jsr puts
|
|
|
|
ldy #94
|
|
lda [pr],y ;pr->puid
|
|
Int2Hex (@a,#puidstr,#4)
|
|
ldx #^puidstr
|
|
lda #puidstr
|
|
jsr puts
|
|
|
|
ldy #50
|
|
lda [pr],y ;pr->ticks
|
|
tax
|
|
iny2
|
|
lda [pr],y
|
|
LongDivide (@ax,#60),(@ax,@yy)
|
|
LongDivide (@xa,#60),(t,@ax)
|
|
Long2Dec (@xa,#timestr+4,#2,#0)
|
|
Long2Dec (t,#timestr,#3,#0)
|
|
lda timestr+4
|
|
and #$FF
|
|
cmp #' '
|
|
bne time0
|
|
short a
|
|
lda #'0'
|
|
sta timestr+4
|
|
long a
|
|
time0 ldx #^timestr
|
|
lda #timestr
|
|
jsr puts
|
|
|
|
ldy #34
|
|
lda [pr],y ;pr->args
|
|
tax
|
|
iny2
|
|
lda [pr],y
|
|
jne goodcmd
|
|
cpx #0
|
|
jne goodcmd
|
|
|
|
lda pjoblist ;check for name in job list
|
|
ldx pjoblist+2
|
|
|
|
jobloop sta pr2
|
|
stx pr2+2
|
|
|
|
ora pr2+2
|
|
beq childof
|
|
ldy #p_pid
|
|
lda [pr2],y
|
|
ldy #2
|
|
cmp [ps],y ;ps->pid
|
|
bne loop2
|
|
|
|
ldy #p_command+2
|
|
lda [pr2],y
|
|
tax
|
|
ldy #p_command
|
|
lda [pr2],y
|
|
jsr puts
|
|
bra next
|
|
|
|
loop2 ldy #p_next+2
|
|
lda [pr2],y
|
|
tax
|
|
ldy #p_next
|
|
lda [pr2],y
|
|
bra jobloop
|
|
|
|
childof ldx #^forkstr
|
|
lda #forkstr
|
|
jsr puts
|
|
kvm_open
|
|
sta ps2
|
|
stx ps2+2
|
|
lda [pr]
|
|
tay
|
|
kvmgetproc (ps2,@y)
|
|
sta pr2
|
|
stx pr2+2
|
|
kvm_close ps2
|
|
ldy #34
|
|
lda [pr2],y ;pr2->args
|
|
tax
|
|
iny2
|
|
lda [pr2],y
|
|
bne goodcmd
|
|
cpx #0
|
|
bne goodcmd
|
|
|
|
ldx #^forkstr2
|
|
lda #forkstr2
|
|
jsr puts
|
|
bra next
|
|
|
|
goodcmd tay
|
|
txa
|
|
tyx
|
|
clc
|
|
adc #8
|
|
jsr puts
|
|
|
|
next jsr newline
|
|
skip jmp loop
|
|
|
|
done kvm_close ps
|
|
|
|
return return 2:status
|
|
|
|
usage dc c'Usage: ps',h'0d00'
|
|
kvmerrstr dc c'ps: error in kvm_open()',h'0d00'
|
|
header dc c' ID STATE TT MMID UID TIME COMMAND',h'0d00'
|
|
pidstr dc c'00000 ',h'00'
|
|
userstr dc c' 0000 ',h'00'
|
|
puidstr dc c'0000 ',h'00'
|
|
timestr dc c'000:00 ',h'00'
|
|
forkstr dc c'forked child of ',h'00'
|
|
forkstr2 dc c'an unknown process',h'00'
|
|
|
|
test1 dc c'getuid = $'
|
|
test1a dc c'0000',h'0d00'
|
|
|
|
statetbl dc c'defunct '
|
|
dc c'running '
|
|
dc c'ready '
|
|
dc c'blocked '
|
|
dc c'ready '
|
|
dc c'suspend '
|
|
dc c'waiting '
|
|
dc c'waiting '
|
|
dc c'paused '
|
|
dc c'unknown '
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* HASH: builtin command
|
|
* syntax: hash
|
|
*
|
|
* display hashed commands
|
|
*
|
|
**************************************************************************
|
|
|
|
hashbi START
|
|
|
|
using hashdata
|
|
|
|
sv equ 0
|
|
q equ sv+4
|
|
p equ q+4
|
|
status equ p+4
|
|
space equ status+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
stz status
|
|
|
|
lda argc
|
|
dec a
|
|
beq dohash
|
|
|
|
ldx #^Usage
|
|
lda #Usage
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
bra exit
|
|
|
|
dohash ph2 t_size Get size of hash table.
|
|
jsl sv_alloc Allocate a string vector array.
|
|
sta sv
|
|
stx sv+2
|
|
|
|
lda hash_table If no hash table
|
|
ora hash_table+2 has been allocated,
|
|
beq exit exit.
|
|
|
|
mv4 hash_table,p Move address to dir pg variable.
|
|
lda hash_numexe Get the number of executable files.
|
|
beq doneadd Done if 0.
|
|
;
|
|
; loop through every hashed file and add it the string vector
|
|
;
|
|
ldy #0 Y is index into the next entry.
|
|
ldx t_size X is the number of entries left.
|
|
beq doneadd
|
|
addloop lda [p],y Get next hash table entry.
|
|
sta q
|
|
iny
|
|
iny
|
|
lda [p],y
|
|
sta q+2
|
|
iny
|
|
iny
|
|
ora q If this entry isn't used,
|
|
beq skip skip to the next one.
|
|
|
|
phy Hold the Y and X regs on stack.
|
|
phx
|
|
pei (sv+2) Insert string in table entry
|
|
pei (sv) into the string vector.
|
|
clc
|
|
lda q
|
|
adc #2 (Note: tn_name in hash.asm == 2)
|
|
tax
|
|
lda q+2
|
|
adc #0
|
|
pha
|
|
phx
|
|
pea 1 (allocflag: 1 = allocate memory)
|
|
jsl sv_add
|
|
plx Restore X and Y regs from stack.
|
|
ply
|
|
skip dex
|
|
bne addloop
|
|
;
|
|
; Files have all been added to the string vector
|
|
;
|
|
doneadd anop
|
|
|
|
pei (sv+2)
|
|
pei (sv)
|
|
jsl sv_sort Sort the string vector.
|
|
|
|
pei (sv+2)
|
|
pei (sv)
|
|
jsl sv_colprint Print the string vector in columns.
|
|
|
|
pei (sv+2)
|
|
pei (sv)
|
|
jsl sv_dispose Dispose of the string vector memory.
|
|
|
|
exit return 2:status
|
|
|
|
usage dc c'Usage: hash',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* SOURCE: builtin command
|
|
* syntax: source file [arguments...]
|
|
*
|
|
* executes a shell file w/o pushing environment
|
|
*
|
|
**************************************************************************
|
|
|
|
source START
|
|
|
|
retval equ 0
|
|
space equ retval+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
dec argc If no filename was provided,
|
|
bne ok
|
|
|
|
ldx #^usage Print usage string.
|
|
lda #usage
|
|
jsr errputs
|
|
lda #1 Return error status.
|
|
sta retval
|
|
bra exit
|
|
|
|
ok stz retval
|
|
|
|
add2 argv,#4,argv
|
|
|
|
* ShellExec subroutine (4:path,2:argc,4:argv,2:jobflag)
|
|
|
|
ldy #2 path is filename argument
|
|
lda [argv],y
|
|
pha
|
|
lda [argv]
|
|
pha
|
|
pei (argc) reuse argc
|
|
pei (argv+2) reuse argv
|
|
pei (argv)
|
|
pea 0 jobflag = 0
|
|
jsl ShellExec
|
|
sta retval
|
|
|
|
exit return 2:retval
|
|
|
|
usage dc c'usage: source file [arguments...]',h'0d00'
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* COMMANDS: builtin command
|
|
* syntax: commands
|
|
*
|
|
* display builtin commands
|
|
*
|
|
**************************************************************************
|
|
|
|
cmdbi START
|
|
|
|
using BuiltinData
|
|
|
|
sv equ 0
|
|
status equ sv+4
|
|
space equ status+2
|
|
|
|
subroutine (4:argv,2:argc),space
|
|
|
|
stz status
|
|
|
|
lda argc
|
|
dec a
|
|
beq docmds
|
|
|
|
ldx #^Usage
|
|
lda #Usage
|
|
jsr errputs
|
|
inc status Return status = 1.
|
|
bra exit
|
|
|
|
docmds ph2 #50
|
|
jsl sv_alloc
|
|
|
|
sta sv
|
|
stx sv+2
|
|
|
|
ldx #0
|
|
;
|
|
; loop through every hashed file and add it the string vector
|
|
;
|
|
addloop lda builtintbl,x
|
|
ora builtintbl+2,x
|
|
beq doneadd
|
|
phx
|
|
pei (sv+2)
|
|
pei (sv)
|
|
lda builtintbl+2,x
|
|
pha
|
|
lda builtintbl,x
|
|
pha
|
|
pea 1
|
|
jsl sv_add
|
|
pla
|
|
clc
|
|
adc #10
|
|
tax
|
|
bra addloop
|
|
doneadd anop
|
|
|
|
pei (sv+2)
|
|
pei (sv)
|
|
jsl sv_sort
|
|
pei (sv+2)
|
|
pei (sv)
|
|
jsl sv_colprint
|
|
|
|
pei (sv+2)
|
|
pei (sv)
|
|
jsl sv_dispose
|
|
|
|
exit return 2:status
|
|
|
|
usage dc c'Usage: commands',h'0d00'
|
|
|
|
END
|