mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-06-03 19:29:29 +00:00
2e0ebb5392
removed the need for p-string routines, so they were removed. Also removed alloc256/free256 and associated data structures. In removing calls, found instances in pwd & prefix commands and prompt handler where current directory name was assumed to be < 256 characters; recoded to use a flexible buffer size. Updated and expanded mmdebug.asm routines that perform error checking on memory management calls. Added macros ~NEW and ~DISPOSE that invoke either the real or debug routines. Fixed call to read $TERM variable's length to fix PR#81. Removed echo of data when setting value of $< in expandvars (expand.asm). The characters are echoed as they are typed and do not need to be reprinted on stdout after carriage-return is typed. Added error checking to the various flavors of prefix (just like cd): - Verify 2nd parameter is a valid directory before setting. - Verify 1st parameter < 32 before displaying or setting.
610 lines
11 KiB
NASM
610 lines
11 KiB
NASM
**************************************************************************
|
|
*
|
|
* The GNO Shell Project
|
|
*
|
|
* Developed by:
|
|
* Jawaid Bazyar
|
|
* Tim Meekins
|
|
*
|
|
* $Id: shellutil.asm,v 1.5 1998/08/03 17:30:24 tribby Exp $
|
|
*
|
|
**************************************************************************
|
|
*
|
|
* SHELLUTIL.ASM
|
|
* By Tim Meekins
|
|
* Modified by Dave Tribby for GNO 2.0.6
|
|
*
|
|
* Utility functions used by the shell. Mainly string functions.
|
|
*
|
|
* Note: text set up for tabs at col 16, 22, 41, 49, 57, 65
|
|
* | | | | | |
|
|
* ^ ^ ^ ^ ^ ^
|
|
**************************************************************************
|
|
|
|
mcopy /obj/gno/bin/gsh/shellutil.mac
|
|
|
|
dummyshellutil start ; ends up in .root
|
|
end
|
|
|
|
setcom 60
|
|
|
|
;=========================================================================
|
|
;
|
|
; Convert the accumulator to lower case.
|
|
;
|
|
;=========================================================================
|
|
|
|
tolower START
|
|
|
|
cmp #'A'
|
|
bcc done
|
|
cmp #'Z'+1
|
|
bcs done
|
|
adc #'a'-'A'
|
|
done rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Convert ':' to '/'
|
|
;
|
|
;=========================================================================
|
|
|
|
toslash START
|
|
|
|
cmp #':'
|
|
bne done
|
|
lda #'/'
|
|
done rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Convert a c string to lower case
|
|
;
|
|
;=========================================================================
|
|
|
|
lowercstr START
|
|
|
|
space equ 1
|
|
p equ space+2
|
|
end equ p+4
|
|
|
|
tsc
|
|
phd
|
|
tcd
|
|
|
|
short a
|
|
|
|
ldy #-1
|
|
loop iny
|
|
lda [p],y
|
|
beq done
|
|
cmp #'A'
|
|
bcc loop
|
|
cmp #'Z'+1
|
|
bcs loop
|
|
adc #'a'-'A'
|
|
sta [p],y
|
|
bra loop
|
|
|
|
done rep #$21
|
|
longa on
|
|
lda space
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
adc #end-3
|
|
tcs
|
|
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Get the length of a c string.
|
|
;
|
|
;=========================================================================
|
|
|
|
cstrlen START
|
|
|
|
space equ 1
|
|
p equ space+2
|
|
end equ p+4
|
|
|
|
tsc
|
|
phd
|
|
tcd
|
|
|
|
short a
|
|
|
|
ldy #0
|
|
loop lda [p],y
|
|
beq done
|
|
iny
|
|
bra loop
|
|
|
|
done rep #$21
|
|
longa on
|
|
lda space
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
adc #end-3
|
|
tcs
|
|
|
|
tya
|
|
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Copy one string to another. Assumes an alloccstr has been performed on
|
|
; destination.
|
|
;
|
|
;=========================================================================
|
|
|
|
copycstr START
|
|
|
|
space equ 1
|
|
q equ space+2
|
|
p equ q+4
|
|
end equ p+4
|
|
|
|
tsc
|
|
phd
|
|
tcd
|
|
|
|
short a
|
|
|
|
ldy #0
|
|
loop lda [p],y
|
|
beq done
|
|
sta [q],y
|
|
iny
|
|
bra loop
|
|
|
|
done sta [q],y
|
|
|
|
rep #$21
|
|
longa on
|
|
lda space
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
adc #end-3
|
|
tcs
|
|
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Compare two c strings. Return 0 if equal, -1 if less than, +1 greater
|
|
;
|
|
;=========================================================================
|
|
|
|
cmpcstr START
|
|
|
|
space equ 1
|
|
q equ space+2
|
|
p equ q+4
|
|
end equ p+4
|
|
|
|
tsc
|
|
phd
|
|
tcd
|
|
|
|
short a
|
|
|
|
ldx #0
|
|
|
|
ldy #0
|
|
strloop lda [p],y
|
|
beq strchk
|
|
cmp [q],y
|
|
bne notequal
|
|
iny
|
|
bra strloop
|
|
|
|
strchk lda [q],y
|
|
beq done
|
|
|
|
lessthan dex
|
|
bra done
|
|
|
|
notequal bcc lessthan
|
|
inx
|
|
|
|
done rep #$21
|
|
longa on
|
|
lda space
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
adc #end-3
|
|
tcs
|
|
|
|
txa
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Compare two downshifted c strings. Return 0 if ==, -1 if <, +1 >
|
|
;
|
|
;=========================================================================
|
|
|
|
cmpdcstr START
|
|
|
|
hold equ 1
|
|
space equ hold+2
|
|
q equ space+2
|
|
p equ q+4
|
|
end equ p+4
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
ldx #0
|
|
|
|
ldy #0
|
|
strloop lda [q],y
|
|
and #$FF
|
|
jsr tolower
|
|
sta hold
|
|
lda [p],y
|
|
and #$FF
|
|
beq strchk
|
|
jsr tolower
|
|
cmp hold
|
|
bne notequal
|
|
iny
|
|
bra strloop
|
|
|
|
strchk lda hold
|
|
beq done
|
|
|
|
lessthan dex
|
|
bra done
|
|
|
|
notequal bcc lessthan
|
|
inx
|
|
|
|
done anop
|
|
lda space
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-3
|
|
tcs
|
|
|
|
txa
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Convert a c string to a GS/OS string (don't forget to dispose when done)
|
|
;
|
|
;=========================================================================
|
|
|
|
c2gsstr START
|
|
|
|
len equ 1
|
|
gstr equ len+2
|
|
space equ gstr+4
|
|
cstr equ space+2
|
|
end equ cstr+4
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
pei (cstr+2)
|
|
pei (cstr)
|
|
jsr cstrlen
|
|
sta len
|
|
adc #3
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta gstr
|
|
stx gstr+2
|
|
incad @xa
|
|
incad @xa
|
|
pei (cstr+2)
|
|
pei (cstr)
|
|
phx
|
|
pha
|
|
jsr copycstr
|
|
lda len
|
|
sta [gstr]
|
|
|
|
ldx gstr+2
|
|
ldy gstr
|
|
|
|
lda space
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
adc #end-3
|
|
tcs
|
|
|
|
tya
|
|
rts
|
|
|
|
END
|
|
|
|
;=========================================================================
|
|
;
|
|
; Takes two strings, concats into a newly created string.
|
|
;
|
|
;=========================================================================
|
|
|
|
catcstr START
|
|
|
|
new equ 1
|
|
space equ new+4
|
|
q equ space+2
|
|
p equ q+4
|
|
end equ p+4
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
pei (p+2)
|
|
pei (p)
|
|
jsr cstrlen
|
|
pha
|
|
pei (q+2)
|
|
pei (q)
|
|
jsr cstrlen
|
|
adc 1,s
|
|
inc a
|
|
inc a
|
|
plx
|
|
pea 0
|
|
pha
|
|
~NEW
|
|
sta new
|
|
stx new+2
|
|
|
|
ldy #0
|
|
copy1 lda [p],y
|
|
and #$FF
|
|
beq copy2
|
|
sta [new],y
|
|
iny
|
|
bra copy1
|
|
copy2 lda [q]
|
|
and #$FF
|
|
sta [new],y
|
|
beq done
|
|
iny
|
|
incad q
|
|
bra copy2
|
|
|
|
done ldx new+2
|
|
ldy new
|
|
lda space
|
|
sta end-2
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-3
|
|
tcs
|
|
|
|
tya
|
|
rts
|
|
|
|
END
|
|
|
|
;=====================================================================
|
|
;
|
|
; call ~DISPOSE if pointer is not NULL
|
|
;
|
|
;=====================================================================
|
|
|
|
nullfree START
|
|
|
|
lda 4,s
|
|
ora 6,s
|
|
bne ok
|
|
lda 2,s
|
|
sta 6,s
|
|
lda 1,s
|
|
sta 5,s
|
|
plx
|
|
plx
|
|
rtl
|
|
|
|
ok ~DISPOSE
|
|
|
|
END
|
|
|
|
;=====================================================================
|
|
;
|
|
; Print a carriage return and a newline, unless "newline" shell var
|
|
; is set.
|
|
;
|
|
;=====================================================================
|
|
|
|
newlineX START
|
|
|
|
using vardata
|
|
|
|
lda varnewline
|
|
beq newline
|
|
rts
|
|
|
|
;=====================================================================
|
|
;
|
|
; Print a carriage return and a newline
|
|
;
|
|
;=====================================================================
|
|
|
|
newline ENTRY
|
|
|
|
lda #13
|
|
jmp putchar
|
|
|
|
END
|
|
|
|
**************************************************************************
|
|
*
|
|
* Quick little routine for reading variables and converting to
|
|
* null terminated strings. We could probably just link the Orca/C
|
|
* library getenv(), but lets stay Orca-free, after all, that's why this
|
|
* is written in assembly! :)
|
|
*
|
|
* For gsh 2.0: pass in addr of a GS/OS string, and pass back addr of
|
|
* allocated GS/OS result buffer (with null word added at end), not c-strings.
|
|
*
|
|
**************************************************************************
|
|
|
|
getenv START
|
|
|
|
len equ 1
|
|
retval equ len+2
|
|
space equ retval+4
|
|
var equ space+3
|
|
end equ var+4
|
|
|
|
; subroutine (4:var),space
|
|
|
|
tsc
|
|
sec
|
|
sbc #space-1
|
|
tcs
|
|
phd
|
|
tcd
|
|
|
|
lock mutex
|
|
;
|
|
; Get the variable's length using ReadVariableGS
|
|
; Set up parameter block:
|
|
mv4 var,RVname Addr of name, from user.
|
|
ld4 TempResultBuf,RVresult Use temporary result buf.
|
|
ReadVariableGS ReadVar Get length.
|
|
;
|
|
; Allocate memory for value string
|
|
;
|
|
lda TempRBlen Get length of value.
|
|
bne notnull Return null if 0.
|
|
sta retval
|
|
sta retval+2
|
|
bra exit
|
|
|
|
notnull inc2 a Add 4 bytes for result buf len words.
|
|
inc2 a
|
|
sta len Save result buf len.
|
|
inc a Add 1 more for terminating null byte.
|
|
pea 0
|
|
pha
|
|
~NEW Request the memory.
|
|
sta RVresult Store address in ReadVariable
|
|
stx RVresult+2 parameter block and
|
|
sta retval direct page pointer.
|
|
stx retval+2
|
|
ora retval+2 If address == NULL,
|
|
beq exit return NULL to user.
|
|
|
|
lda len Store result buffer length
|
|
sta [retval] at beginning of buf.
|
|
;
|
|
; Read the full value into the allocated memory
|
|
;
|
|
ReadVariableGS ReadVar
|
|
;
|
|
; Add null byte at end of text to make it work as a C string
|
|
;
|
|
ldy TempRBlen Get length of value,
|
|
iny4 + 4 (for length words at start)
|
|
lda #0 Store zero at end of string.
|
|
short a
|
|
sta [retval],y
|
|
long a
|
|
;
|
|
; All done.
|
|
;
|
|
exit unlock mutex
|
|
|
|
ldy retval
|
|
ldx retval+2
|
|
|
|
lda space+1
|
|
sta end-2
|
|
lda space
|
|
sta end-3
|
|
pld
|
|
tsc
|
|
clc
|
|
adc #end-4
|
|
tcs
|
|
tya
|
|
|
|
rtl
|
|
|
|
mutex key
|
|
|
|
; Parameter block for shell ReadVariableGS call (p 423 in ORCA/M manual)
|
|
ReadVar anop
|
|
dc i2'3' pCount
|
|
RVname ds 4 Pointer to name (passed by user)
|
|
RVresult ds 4 GS/OS Output buffer ptr
|
|
RVexpflag ds 2 export flag
|
|
|
|
; GS/OS result buffer for getting the full length of the PATH env var.
|
|
TempResultBuf dc i2'5' Only five bytes total.
|
|
TempRBlen ds 2 Value's length returned here.
|
|
ds 1 Only 1 byte for value.
|
|
|
|
END
|
|
|
|
rmemcpy START
|
|
subroutine (2:num,4:src,4:dest),0
|
|
|
|
ldy num
|
|
beq done
|
|
tya
|
|
dey
|
|
bit #1
|
|
bne odd
|
|
dey
|
|
bra lp1
|
|
odd short m
|
|
lda [src],y
|
|
sta [dest],y
|
|
long m
|
|
dey
|
|
dey
|
|
bmi done
|
|
lp1 lda [src],y
|
|
sta [dest],y
|
|
dey
|
|
dey
|
|
bpl lp1
|
|
done return
|
|
END
|