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:
parent
023b461bb8
commit
0ee9b2e446
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
33
cfg/c64.cfg
33
cfg/c64.cfg
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
|
|
||||||
.proc initcwd
|
.proc initcwd
|
||||||
|
|
||||||
|
lda #0
|
||||||
|
sta __cwd
|
||||||
jsr findfreeiocb
|
jsr findfreeiocb
|
||||||
bne oserr
|
bne oserr
|
||||||
lda #GETCWD
|
lda #GETCWD
|
||||||
|
|
|
@ -108,7 +108,7 @@ L2: lda zpsave,x
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
; Data
|
; Data
|
||||||
|
|
||||||
.segment "ZPSAVE"
|
.segment "INITBSS"
|
||||||
|
|
||||||
zpsave: .res zpspace
|
zpsave: .res zpspace
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ L2: lda zpsave,x
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
|
|
||||||
.segment "ZPSAVE"
|
.segment "INITBSS"
|
||||||
|
|
||||||
zpsave: .res zpspace
|
zpsave: .res zpspace
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
.importzp devnum
|
.importzp devnum
|
||||||
|
|
||||||
|
|
||||||
.bss
|
.segment "INITBSS"
|
||||||
|
|
||||||
curunit:
|
curunit:
|
||||||
.res 1
|
.res 1
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ L2: lda zpsave,x
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
|
|
||||||
.segment "ZPSAVE"
|
.segment "INITBSS"
|
||||||
|
|
||||||
zpsave: .res zpspace
|
zpsave: .res zpspace
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -195,7 +195,7 @@ spsave: .res 1
|
||||||
|
|
||||||
irqcount: .byte 0
|
irqcount: .byte 0
|
||||||
|
|
||||||
.segment "ZPSAVE"
|
.segment "INITBSS"
|
||||||
|
|
||||||
zpsave: .res zpspace
|
zpsave: .res zpspace
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
;---------------------------------------------------------------------------
|
;---------------------------------------------------------------------------
|
||||||
; Data
|
; Data
|
||||||
|
|
||||||
.bss
|
.data
|
||||||
__argc: .res 2
|
__argc: .word 0
|
||||||
__argv: .res 2
|
__argv: .addr 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ L2: lda zpsave,x
|
||||||
|
|
||||||
; ------------------------------------------------------------------------
|
; ------------------------------------------------------------------------
|
||||||
|
|
||||||
.segment "ZPSAVE"
|
.segment "INITBSS"
|
||||||
|
|
||||||
zpsave: .res zpspace
|
zpsave: .res zpspace
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user