Changed run location of INIT segment.

So far the INIT segment was run from the later heap+stack. Now the INIT segment is run from the later BSS. The background is that so far the INIT segment was pretty small (from $80 to $180 bytes). But upcoming changes will increase the INIT segment in certain scenarios up to ~ $1000 bytes. So programs with very limited heap+stack might just not been able to move the INIT segment to its run location. But moving the INIT segment to the later BSS allows it to occupy the later BSS+heap+stack.

In order to allow that the constructors are _NOT_ allowed anymore to access the BSS. Rather they must use the DATA segment or the new INITBSS segment. The latter isn't cleared at any point so the constructors may use it to expose values to the main program. However they must make sure to always write the values as they are not pre-initialized.
This commit is contained in:
Oliver Schmidt 2015-10-14 22:52:09 +02:00
parent 023b461bb8
commit 0ee9b2e446
35 changed files with 234 additions and 260 deletions

View File

@ -38,7 +38,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
OVL1ADDR: load = OVL1ADDR, type = ro;

View File

@ -18,7 +18,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
}

View File

@ -18,7 +18,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
}

View File

@ -14,8 +14,9 @@ MEMORY {
ZP: file = "", define = yes, start = $0002, size = $001A;
LOADADDR: file = %O, start = %S - 2, size = $0002;
HEADER: file = %O, define = yes, start = %S, size = $000D;
RAM: file = %O, define = yes, start = __HEADER_LAST__, size = __OVERLAYSTART__ - __STACKSIZE__ - __HEADER_LAST__;
MOVE: file = %O, start = __ZPSAVE_LOAD__, size = __HIMEM__ - __INIT_RUN__;
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __OVERLAYSTART__ - __STACKSIZE__ - __HEADER_LAST__;
MOVE: file = %O, start = __INITBSS_LOAD__, size = __HIMEM__ - __BSS_RUN__;
INIT: file = "", start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__;
OVL1ADDR: file = "%O.1", start = __OVERLAYSTART__ - 2, size = $0002;
OVL1: file = "%O.1", start = __OVERLAYSTART__, size = __OVERLAYSIZE__;
OVL2ADDR: file = "%O.2", start = __OVERLAYSTART__ - 2, size = $0002;
@ -36,35 +37,35 @@ MEMORY {
OVL9: file = "%O.9", start = __OVERLAYSTART__, size = __OVERLAYSIZE__;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = HEADER, type = ro;
STARTUP: load = RAM, type = ro;
LOWCODE: load = RAM, type = ro, optional = yes;
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss, define = yes;
BSS: load = RAM, type = bss, define = yes;
INIT: load = MOVE, run = RAM, type = ro, define = yes;
OVL1ADDR: load = OVL1ADDR, type = ro;
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
OVL2ADDR: load = OVL2ADDR, type = ro;
OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
OVL3ADDR: load = OVL3ADDR, type = ro;
OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
OVL4ADDR: load = OVL4ADDR, type = ro;
OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
OVL5ADDR: load = OVL5ADDR, type = ro;
OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
OVL6ADDR: load = OVL6ADDR, type = ro;
OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
OVL7ADDR: load = OVL7ADDR, type = ro;
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
OVL8ADDR: load = OVL8ADDR, type = ro;
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
OVL9ADDR: load = OVL9ADDR, type = ro;
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
ZEROPAGE: load = ZP, type = zp;
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = HEADER, type = ro;
STARTUP: load = MAIN, type = ro;
LOWCODE: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INITBSS: load = MAIN, type = bss, define = yes;
BSS: load = MAIN, type = bss, define = yes;
INIT: load = MOVE, run = INIT, type = ro, define = yes;
OVL1ADDR: load = OVL1ADDR, type = ro;
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
OVL2ADDR: load = OVL2ADDR, type = ro;
OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
OVL3ADDR: load = OVL3ADDR, type = ro;
OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
OVL4ADDR: load = OVL4ADDR, type = ro;
OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
OVL5ADDR: load = OVL5ADDR, type = ro;
OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
OVL6ADDR: load = OVL6ADDR, type = ro;
OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
OVL7ADDR: load = OVL7ADDR, type = ro;
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
OVL8ADDR: load = OVL8ADDR, type = ro;
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
OVL9ADDR: load = OVL9ADDR, type = ro;
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
}
FEATURES {
CONDES: type = constructor,

View File

@ -8,24 +8,25 @@ SYMBOLS {
__HIMEM__: type = weak, value = $D000;
}
MEMORY {
ZP: file = "", define = yes, start = $0002, size = $001A;
LOADADDR: file = %O, start = %S - 2, size = $0002;
HEADER: file = %O, define = yes, start = %S, size = $000D;
RAM: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__;
MOVE: file = %O, start = __ZPSAVE_LOAD__, size = __HIMEM__ - __INIT_RUN__;
ZP: file = "", define = yes, start = $0002, size = $001A;
LOADADDR: file = %O, start = %S - 2, size = $0002;
HEADER: file = %O, define = yes, start = %S, size = $000D;
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__;
MOVE: file = %O, start = __INITBSS_LOAD__, size = __HIMEM__ - __BSS_RUN__;
INIT: file = "", start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = HEADER, type = ro;
STARTUP: load = RAM, type = ro;
LOWCODE: load = RAM, type = ro, optional = yes;
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss, define = yes;
BSS: load = RAM, type = bss, define = yes;
INIT: load = MOVE, run = RAM, type = ro, define = yes;
ZEROPAGE: load = ZP, type = zp;
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = HEADER, type = ro;
STARTUP: load = MAIN, type = ro;
LOWCODE: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INITBSS: load = MAIN, type = bss, define = yes;
BSS: load = MAIN, type = bss, define = yes;
INIT: load = MOVE, run = INIT, type = ro, define = yes;
}
FEATURES {
CONDES: type = constructor,

View File

@ -22,6 +22,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
EXTZP: load = ZP, type = rw, define = yes;

View File

@ -19,6 +19,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
EXTZP: load = ZP, type = rw, define = yes;

View File

@ -18,7 +18,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
}

View File

@ -18,7 +18,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
}

View File

@ -20,7 +20,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
}

View File

@ -18,7 +18,7 @@ SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss;
INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp;
}

View File

@ -9,6 +9,8 @@
.proc initcwd
lda #0
sta __cwd
jsr findfreeiocb
bne oserr
lda #GETCWD

View File

@ -108,7 +108,7 @@ L2: lda zpsave,x
; ------------------------------------------------------------------------
; Data
.segment "ZPSAVE"
.segment "INITBSS"
zpsave: .res zpspace

View File

@ -30,8 +30,7 @@
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run
@ -42,26 +41,26 @@ initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
; Because the buffer, that we're copying into, was zeroed out,
; we don't need to add a NUL character.
;
lda #0 ; The terminating NUL character
ldy FNAM_LEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda #FNAM ; Load vector address for FETCH routine
ldx FNAM_BANK ; Load bank for FETCH routine
jsr INDFET ; Load byte from (FETVEC),y
sta name,y ; Save byte from filename
L1: dey
L1: sta name,y ; Save byte from filename
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
beq done ; no "rem," no args.
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
@ -73,7 +72,7 @@ next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
@ -128,15 +127,13 @@ done: lda #<argv
stx __argv + 1
rts
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2

View File

@ -90,7 +90,7 @@ L2: lda zpsave,x
; ------------------------------------------------------------------------
.segment "ZPSAVE"
.segment "INITBSS"
zpsave: .res zpspace

View File

@ -28,10 +28,9 @@
.include "plus4.inc"
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run
@ -42,25 +41,25 @@ initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
; Because the buffer, that we're copying into, was zeroed out,
; we don't need to add a NUL character.
;
lda #0 ; The terminating NUL character
ldy FNAM_LEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda #FNAM ; Vector address
jsr FETCH ; Load byte from RAM
sta name,y
L1: dey
L1: sta name,y
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
beq done ; no "rem," no args.
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
@ -72,7 +71,7 @@ next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
@ -127,15 +126,13 @@ done: lda #<argv
stx __argv + 1
rts
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2

View File

@ -8,7 +8,7 @@
.import initlib, donelib
.import moveinit, zerobss, callmain
.import BSOUT
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated
.import __STACKSIZE__ ; from configure file
.importzp ST
@ -45,16 +45,24 @@ Start:
ldx move_init
beq L0
; Move the INIT segment from where it was loaded (over ZPSAVE and BSS)
; into where it must be run (in the heap).
; Move the INIT segment from where it was loaded (over the bss segments)
; into where it must be run (over the BSS segment).
jsr moveinit
dec move_init ; set to false
dec move_init ; Set to false
; Save space by putting the rest of the start-up code in the INIT segment,
; which can be re-used by the heap and the C stack.
; Save space by putting some of the start-up code in the INIT segment,
; which can be re-used by the BSS segment, the heap and the C stack.
L0: jsr initstart
L0: jsr runinit
; Clear the BSS data.
jsr zerobss
; Push the command-line arguments; and, call main().
jsr callmain
; Back from main() [this is also the exit() entry]. Run the module destructors.
@ -90,7 +98,7 @@ L2: lda zpsave,x
.segment "INIT"
initstart:
runinit:
; Save the zero-page locations that we need.
@ -100,24 +108,16 @@ L1: lda sp,x
dex
bpl L1
; Clear the BSS data.
jsr zerobss
; Set up the stack.
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
sta sp
stx sp+1 ; Set argument stack ptr
; Call the module constructors.
jsr initlib
; Push the command-line arguments; and, call main().
jmp callmain
jmp initlib
; ------------------------------------------------------------------------
@ -134,6 +134,6 @@ spsave: .res 1
move_init:
.byte 1
.segment "ZPSAVE"
.segment "INITBSS"
zpsave: .res zpspace

View File

@ -28,10 +28,9 @@
.include "c64.inc"
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run
@ -42,24 +41,24 @@ initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
; Because the buffer, that we're copying into, was zeroed out,
; we don't need to add a NUL character.
;
lda #0 ; The terminating NUL character
ldy FNAM_LEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (FNAM),y
sta name,y
L1: dey
L1: sta name,y
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
beq done ; no "rem," no args.
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
@ -71,7 +70,7 @@ next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
@ -126,15 +125,13 @@ done: lda #<argv
stx __argv + 1
rts
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2

View File

@ -5,6 +5,7 @@
;
.include "cbm.inc"
.include "filedes.inc"
.code
@ -29,9 +30,14 @@ found: rts
;--------------------------------------------------------------------------
; Data
.bss
fdtab: .res MAX_FDS
unittab:.res MAX_FDS
.data
fdtab: .byte LFN_READ
.byte LFN_WRITE
.byte LFN_WRITE
.res MAX_FDS-3
unittab:.byte CBMDEV_KBD
.byte CBMDEV_SCREEN
.byte CBMDEV_SCREEN
.res MAX_FDS-3

View File

@ -9,7 +9,7 @@
.importzp devnum
.bss
.segment "INITBSS"
curunit:
.res 1

View File

@ -26,11 +26,8 @@
.proc initstdin
lda #LFN_READ
sta fdtab+STDIN_FILENO
lda #STDIN_FILENO + LFN_OFFS
ldx #CBMDEV_KBD
stx unittab+STDIN_FILENO
ldy #$FF
jsr SETLFS
jmp OPEN ; Will always succeed
@ -155,5 +152,3 @@ invalidfd:
.bss
unit: .res 1

View File

@ -24,12 +24,6 @@
.proc initstdout
lda #LFN_WRITE
sta fdtab+STDOUT_FILENO
sta fdtab+STDERR_FILENO
lda #CBMDEV_SCREEN
sta unittab+STDOUT_FILENO
sta unittab+STDERR_FILENO
lda #STDOUT_FILENO + LFN_OFFS
jsr @L1
lda #STDERR_FILENO + LFN_OFFS
@ -122,7 +116,3 @@ invalidfd:
jmp __directerrno ; Sets _errno, clears _oserror, returns -1
.endproc

View File

@ -31,10 +31,9 @@
.macpack generic
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run.
@ -61,40 +60,42 @@ initmainargs:
ldy #FNAM_LEN
lda (sysp0),y
tay
lda #0 ; The terminating NUL character
stx IndReg ; Look for name in correct bank
cpy #NAME_LEN + 1
blt L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (ptr1),y
sta name,y
L1: dey
L1: sta name,y
dey
bpl L0
jsr restore_bank
inc __argc ; argc always is equal to at least 1
; Find a "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
bze done ; no "rem," no args.
bze done ; No "rem," no args.
inx
cmp #REM
bne L2
ldy #1 * 2
; Find the next argument.
;
next: lda BASIC_BUF,x
bze done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. That is useful because we
; will check now for a quoted argument; in which case, we will have to skip that
; first character.
;
found: cmp #'"' ; Is the argument quoted?
beq setterm ; Jump if so
dex ; Reset pointer to first argument character
@ -102,7 +103,7 @@ found: cmp #'"' ; Is the argument quoted?
setterm:sta term ; Set end-of-argument marker
; Now, store a pointer to the argument into the next slot.
;
txa ; Get low byte
add #<BASIC_BUF
sta argv,y ; argv[y]= &arg
@ -114,7 +115,7 @@ setterm:sta term ; Set end-of-argument marker
inc __argc ; Found another arg
; Search for the end of the argument.
;
argloop:lda BASIC_BUF,x
bze done
inx
@ -124,7 +125,7 @@ argloop:lda BASIC_BUF,x
; We've found the end of the argument. X points one character behind it, and
; A contains the terminating character. To make the argument a valid C string,
; replace the terminating character by a zero.
;
lda #$00
sta BASIC_BUF-1,x
@ -136,21 +137,20 @@ argloop:lda BASIC_BUF,x
blt next ; Parse next one if not
; (The last vector in argv[] already is NULL.)
;
done: lda #<argv
ldx #>argv
sta __argv
stx __argv + 1
rts
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2, $00
.res MAXARGS * 2

View File

@ -31,10 +31,9 @@
.macpack generic
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run.
@ -45,9 +44,7 @@ initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
; Because the buffer, that we're copying into, was zeroed out,
; we don't need to add a NUL character.
;
jsr sys_bank
ldy #FNAM
lda (sysp0),y ; Get file-name pointer from system bank
@ -61,40 +58,42 @@ initmainargs:
ldy #FNAM_LEN
lda (sysp0),y
tay
lda #0 ; The terminating NUL character
stx IndReg ; Look for name in correct bank
cpy #NAME_LEN + 1
blt L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (ptr1),y
sta name,y
L1: dey
L1: sta name,y
dey
bpl L0
jsr restore_bank
inc __argc ; argc always is equal to at least 1
; Find a "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
bze done ; no "rem," no args.
bze done ; No "rem," no args.
inx
cmp #REM
bne L2
ldy #1 * 2
; Find the next argument.
;
next: lda BASIC_BUF,x
bze done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. That is useful because we
; will check now for a quoted argument; in which case, we will have to skip that
; first character.
;
found: cmp #'"' ; Is the argument quoted?
beq setterm ; Jump if so
dex ; Reset pointer to first argument character
@ -102,7 +101,7 @@ found: cmp #'"' ; Is the argument quoted?
setterm:sta term ; Set end-of-argument marker
; Now, store a pointer to the argument into the next slot.
;
txa ; Get low byte
add #<BASIC_BUF
sta argv,y ; argv[y]= &arg
@ -114,7 +113,7 @@ setterm:sta term ; Set end-of-argument marker
inc __argc ; Found another arg
; Search for the end of the argument.
;
argloop:lda BASIC_BUF,x
bze done
inx
@ -124,33 +123,32 @@ argloop:lda BASIC_BUF,x
; We've found the end of the argument. X points one character behind it, and
; A contains the terminating character. To make the argument a valid C string,
; replace the terminating character by a zero.
;
lda #$00
sta BASIC_BUF-1,x
; Check if the maximum number of command-line arguments is reached. If not,
; parse the next one.
;
lda __argc ; Get low byte of argument count
cmp #MAXARGS ; Maximum number of arguments reached?
blt next ; Parse next one if not
; (The last vector in argv[] already is NULL.)
;
done: lda #<argv
ldx #>argv
sta __argv
stx __argv + 1
rts
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2, $00
.res MAXARGS * 2

View File

@ -14,12 +14,12 @@
.import initcwd
.include "stdio.inc"
__cwd_buf_size = FILENAME_MAX
cwd_init := initcwd
.bss
.segment "INITBSS"
__cwd: .res __cwd_buf_size
@ -29,4 +29,3 @@ __cwd: .res __cwd_buf_size
; checking the other sources.
.assert __cwd_buf_size < 256, error, "__cwd_buf_size must not be > 255"

View File

@ -15,8 +15,8 @@
.data
; Move the INIT segment from where it was loaded (over the bss segments)
; into where it must be run (in the heap). The two areas might overlap; and,
; the segment is moved upwards. Therefore, this code starts at the highest
; into where it must be run (over the BSS segment). The two areas might overlap;
; and, the segment is moved upwards. Therefore, this code starts at the highest
; address, and decrements to the lowest address. The low bytes of the starting
; pointers are not sums. The high bytes are sums; but, they do not include the
; carry. Both the low-byte sums and the carries will be done when the pointers

View File

@ -9,7 +9,7 @@
.importzp ptr1
.segment "INIT"
.code
zerobss:
lda #<__BSS_RUN__
@ -41,6 +41,3 @@ L3: cpy #<__BSS_SIZE__
; Done
L4: rts

View File

@ -94,7 +94,7 @@ L2: lda zpsave,x
; ------------------------------------------------------------------------
.segment "ZPSAVE"
.segment "INITBSS"
zpsave: .res zpspace

View File

@ -12,7 +12,7 @@
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
;---------------------------------------------------------------------------
@ -25,24 +25,24 @@ NAME_LEN = 16 ; maximum length of command-name
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
; Because the buffer, that we're copying into, was zeroed out,
; we don't need to add a NUL character.
;
lda #0 ; The terminating NUL character
ldy FNLEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (FNADR),y
sta name,y
L1: dey
L1: sta name,y
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
beq done ; no "rem," no args.
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
@ -54,7 +54,7 @@ next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
@ -111,14 +111,13 @@ done: lda #<argv
.endproc
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2

View File

@ -195,7 +195,7 @@ spsave: .res 1
irqcount: .byte 0
.segment "ZPSAVE"
.segment "INITBSS"
zpsave: .res zpspace

View File

@ -26,12 +26,11 @@
.import __argc, __argv
.include "plus4.inc"
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run
@ -42,24 +41,24 @@ initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
; Because the buffer, that we're copying into, was zeroed out,
; we don't need to add a NUL character.
;
lda #0 ; The terminating NUL character
ldy FNAM_LEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (FNAM),y
sta name,y
L1: dey
L1: sta name,y
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
beq done ; no "rem," no args.
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
@ -71,7 +70,7 @@ next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
@ -125,17 +124,14 @@ done: lda #<argv
sta __argv
stx __argv + 1
rts
; --------------------------------------------------------------------------
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2

View File

@ -31,9 +31,9 @@
;---------------------------------------------------------------------------
; Data
.bss
__argc: .res 2
__argv: .res 2
.data
__argc: .word 0
__argv: .addr 0

View File

@ -101,14 +101,14 @@ Fail: lda #4
; ----------------------------------------------------------------------------
; Data
.bss
.segment "INITBSS"
; Initial stack pointer value. Stack is reset to this in case of overflows to
; allow program exit processing.
initialsp: .word 0
initialsp: .res 2
; Stack low water mark.
lowwater: .word 0
lowwater: .res 2

View File

@ -86,7 +86,7 @@ L2: lda zpsave,x
; ------------------------------------------------------------------------
.segment "ZPSAVE"
.segment "INITBSS"
zpsave: .res zpspace

View File

@ -28,10 +28,9 @@
.include "vic20.inc"
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; maximum length of command-name
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special INIT segment,
; which may be reused after the startup code is run
@ -42,24 +41,24 @@ initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
; Because the buffer, that we're copying into, was zeroed out,
; we don't need to add a NUL character.
;
lda #0 ; The terminating NUL character
ldy FNAM_LEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN - 1 ; limit the length
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (FNAM),y
sta name,y
L1: dey
L1: sta name,y
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
;
ldx #0
L2: lda BASIC_BUF,x
beq done ; no "rem," no args.
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
@ -71,7 +70,7 @@ next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next ;
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
@ -126,15 +125,13 @@ done: lda #<argv
stx __argv + 1
rts
; These arrays are zeroed before initmainargs is called.
; char name[16+1];
; char* argv[MAXARGS+1]={name};
;
.bss
.segment "INITBSS"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2