1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 05:29:30 +00:00

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; CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro; RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw; DATA: load = RAM, type = rw;
ZPSAVE: load = RAM, type = bss; INITBSS: load = RAM, type = bss;
BSS: load = RAM, type = bss, define = yes; BSS: load = RAM, type = bss, define = yes;
ZEROPAGE: load = ZP, type = zp; ZEROPAGE: load = ZP, type = zp;
OVL1ADDR: load = OVL1ADDR, type = ro; OVL1ADDR: load = OVL1ADDR, type = ro;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,6 +5,7 @@
; ;
.include "cbm.inc"
.include "filedes.inc" .include "filedes.inc"
.code .code
@ -29,9 +30,14 @@ found: rts
;-------------------------------------------------------------------------- ;--------------------------------------------------------------------------
; Data ; Data
.bss .data
fdtab: .res MAX_FDS
unittab:.res MAX_FDS
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 .importzp devnum
.bss .segment "INITBSS"
curunit: curunit:
.res 1 .res 1

View File

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

View File

@ -24,12 +24,6 @@
.proc initstdout .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 lda #STDOUT_FILENO + LFN_OFFS
jsr @L1 jsr @L1
lda #STDERR_FILENO + LFN_OFFS lda #STDERR_FILENO + LFN_OFFS
@ -122,7 +116,3 @@ invalidfd:
jmp __directerrno ; Sets _errno, clears _oserror, returns -1 jmp __directerrno ; Sets _errno, clears _oserror, returns -1
.endproc .endproc

View File

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

View File

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

View File

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

View File

@ -15,8 +15,8 @@
.data .data
; Move the INIT segment from where it was loaded (over the bss segments) ; 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, ; into where it must be run (over the BSS segment). The two areas might overlap;
; the segment is moved upwards. Therefore, this code starts at the highest ; 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 ; 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 ; 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 ; carry. Both the low-byte sums and the carries will be done when the pointers

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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