Added environment routines
git-svn-id: svn://svn.cc65.org/cc65/trunk@3483 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
198
libsrc/common/putenv.s
Normal file
198
libsrc/common/putenv.s
Normal file
@@ -0,0 +1,198 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2005-04-21
|
||||
;
|
||||
; int putenv (char* s);
|
||||
;
|
||||
; Note: The function will place s into the environment, *not* a copy!
|
||||
;
|
||||
|
||||
.export _putenv
|
||||
.import _malloc, _free
|
||||
.import searchenv, copyenvptr
|
||||
.import __environ, __envcount, __envsize
|
||||
.import seterrno, return0
|
||||
.import ptr1:zp, ptr2:zp, ptr3:zp, tmp1:zp
|
||||
|
||||
.include "errno.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; putenv()
|
||||
|
||||
.proc _putenv
|
||||
|
||||
sta ptr1
|
||||
sta name
|
||||
stx ptr1+1 ; Save name
|
||||
stx name+1
|
||||
|
||||
; Loop over the name to find the '='. If there is no '=', set errno to EINVAL
|
||||
; and return an error.
|
||||
|
||||
ldy #$FF
|
||||
@L0: iny
|
||||
lda (ptr1),y
|
||||
bne @L1
|
||||
lda #EINVAL
|
||||
jmp error ; End of string without '=' found
|
||||
@L1: cmp #'='
|
||||
bne @L0
|
||||
|
||||
; Remember the offset of the equal sign and replace it by a zero.
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
phy
|
||||
stz (ptr1),y
|
||||
.else
|
||||
sty tmp1
|
||||
lda #$00
|
||||
sta (ptr1),y
|
||||
.endif
|
||||
|
||||
; Search for the string in the environment. searchenv will set the N flag if
|
||||
; the string is not found, otherwise X contains the index of the entry, ptr2
|
||||
; contains the entry and Y the offset of the '=' in the string. ptr3 will
|
||||
; point to the environment.
|
||||
|
||||
jsr searchenv
|
||||
|
||||
; Before doing anything else, restore the old environment string.
|
||||
|
||||
.if (.cpu .bitand ::CPU_ISET_65SC02)
|
||||
ply
|
||||
.else
|
||||
ldy tmp1
|
||||
.endif
|
||||
lda #'='
|
||||
sta (ptr1),y
|
||||
|
||||
; Check the result of searchenv
|
||||
|
||||
txa ; Did we find the entry?
|
||||
bpl addentry ; Jump if yes
|
||||
|
||||
; We didn't find the entry, so we have to add a new one. Before doing so, we
|
||||
; must check if the size of the _environ array must be increased.
|
||||
; Note: There must be one additional slot for the final NULL entry.
|
||||
|
||||
ldx __envcount
|
||||
inx
|
||||
cpx __envsize
|
||||
bcc addnewentry ; Jump if space enough
|
||||
|
||||
; We need to increase the size of the environ array. Calculate the new size.
|
||||
; We will not support a size larger than 64 entries, double the size with
|
||||
; each overflow, and the starting size is 8 entries.
|
||||
|
||||
lda __envsize
|
||||
bne @L2
|
||||
lda #4 ; Start with 4*2 entries
|
||||
@L2: asl a ; Double current size
|
||||
bmi nomem ; Bail out if > 64
|
||||
sta newsize ; Remember the new size
|
||||
|
||||
; Call malloc() and store the result in ptr2
|
||||
|
||||
asl a ; Make words
|
||||
ldx #$00
|
||||
jsr _malloc
|
||||
sta ptr2
|
||||
stx ptr2+1
|
||||
|
||||
; Check the result of malloc
|
||||
|
||||
ora ptr2+1
|
||||
beq nomem
|
||||
|
||||
; Copy the old environment pointer to ptr3, and the new one to __environ.
|
||||
|
||||
ldx #1
|
||||
@L3: lda __environ,x
|
||||
sta ptr3,x
|
||||
lda ptr2,x
|
||||
sta __environ,x
|
||||
dex
|
||||
bpl @L3
|
||||
|
||||
; Use the new size.
|
||||
|
||||
lda newsize
|
||||
sta __envsize
|
||||
|
||||
; Copy the old environment data into the new space.
|
||||
|
||||
lda __envcount
|
||||
asl a
|
||||
tay
|
||||
jmp @L5
|
||||
@L4: lda (ptr3),y
|
||||
sta (ptr2),y
|
||||
@L5: dey
|
||||
bpl @L4
|
||||
|
||||
; Free the old environment space
|
||||
|
||||
lda ptr3
|
||||
ldx ptr3+1
|
||||
jsr _free
|
||||
|
||||
; Since free() has destroyed ptr2, we need another copy ...
|
||||
|
||||
jsr copyenvptr ; Copy __environ to ptr2
|
||||
|
||||
; Bump the environment count and remember it in X. Add the final NULL entry.
|
||||
|
||||
addnewentry:
|
||||
inc __envcount
|
||||
ldx __envcount
|
||||
txa
|
||||
asl a
|
||||
tay
|
||||
lda #$00
|
||||
sta (ptr2),y
|
||||
iny
|
||||
sta (ptr2),y
|
||||
|
||||
; The index of the new entry is the old environment count.
|
||||
|
||||
dex
|
||||
txa
|
||||
|
||||
; Add the new entry to the slot with index in X. The pointer to the environment
|
||||
; is already in ptr2, either by a call to searchenv, or by above code.
|
||||
|
||||
addentry:
|
||||
asl a
|
||||
tay
|
||||
lda name
|
||||
sta (ptr2),y
|
||||
iny
|
||||
lda name+1
|
||||
sta (ptr2),y
|
||||
|
||||
; Done
|
||||
|
||||
jmp return0
|
||||
|
||||
; Error entries
|
||||
|
||||
nomem: lda #ENOMEM
|
||||
error: jsr seterrno
|
||||
lda #$FF ; Return -1
|
||||
tax
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; data
|
||||
|
||||
.bss
|
||||
|
||||
name: .addr 0 ; Pointer to name
|
||||
newsize: .byte 0 ; New environment size
|
||||
|
||||
Reference in New Issue
Block a user