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
35 changed files with 234 additions and 260 deletions
|
@ -38,7 +38,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
OVL1ADDR: load = OVL1ADDR, type = ro;
|
||||
|
|
|
@ -18,7 +18,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,9 @@ MEMORY {
|
|||
ZP: file = "", define = yes, start = $0002, size = $001A;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||
RAM: file = %O, define = yes, start = __HEADER_LAST__, size = __OVERLAYSTART__ - __STACKSIZE__ - __HEADER_LAST__;
|
||||
MOVE: file = %O, start = __ZPSAVE_LOAD__, size = __HIMEM__ - __INIT_RUN__;
|
||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __OVERLAYSTART__ - __STACKSIZE__ - __HEADER_LAST__;
|
||||
MOVE: file = %O, start = __INITBSS_LOAD__, size = __HIMEM__ - __BSS_RUN__;
|
||||
INIT: file = "", start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__;
|
||||
OVL1ADDR: file = "%O.1", start = __OVERLAYSTART__ - 2, size = $0002;
|
||||
OVL1: file = "%O.1", start = __OVERLAYSTART__, size = __OVERLAYSIZE__;
|
||||
OVL2ADDR: file = "%O.2", start = __OVERLAYSTART__ - 2, size = $0002;
|
||||
|
@ -36,35 +37,35 @@ MEMORY {
|
|||
OVL9: file = "%O.9", start = __OVERLAYSTART__, size = __OVERLAYSIZE__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = RAM, type = ro;
|
||||
LOWCODE: load = RAM, type = ro, optional = yes;
|
||||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss, define = yes;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
INIT: load = MOVE, run = RAM, type = ro, define = yes;
|
||||
OVL1ADDR: load = OVL1ADDR, type = ro;
|
||||
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
|
||||
OVL2ADDR: load = OVL2ADDR, type = ro;
|
||||
OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
|
||||
OVL3ADDR: load = OVL3ADDR, type = ro;
|
||||
OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
|
||||
OVL4ADDR: load = OVL4ADDR, type = ro;
|
||||
OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
|
||||
OVL5ADDR: load = OVL5ADDR, type = ro;
|
||||
OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
|
||||
OVL6ADDR: load = OVL6ADDR, type = ro;
|
||||
OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
|
||||
OVL7ADDR: load = OVL7ADDR, type = ro;
|
||||
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
|
||||
OVL8ADDR: load = OVL8ADDR, type = ro;
|
||||
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
|
||||
OVL9ADDR: load = OVL9ADDR, type = ro;
|
||||
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = MAIN, type = ro;
|
||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = ro;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
INITBSS: load = MAIN, type = bss, define = yes;
|
||||
BSS: load = MAIN, type = bss, define = yes;
|
||||
INIT: load = MOVE, run = INIT, type = ro, define = yes;
|
||||
OVL1ADDR: load = OVL1ADDR, type = ro;
|
||||
OVERLAY1: load = OVL1, type = ro, define = yes, optional = yes;
|
||||
OVL2ADDR: load = OVL2ADDR, type = ro;
|
||||
OVERLAY2: load = OVL2, type = ro, define = yes, optional = yes;
|
||||
OVL3ADDR: load = OVL3ADDR, type = ro;
|
||||
OVERLAY3: load = OVL3, type = ro, define = yes, optional = yes;
|
||||
OVL4ADDR: load = OVL4ADDR, type = ro;
|
||||
OVERLAY4: load = OVL4, type = ro, define = yes, optional = yes;
|
||||
OVL5ADDR: load = OVL5ADDR, type = ro;
|
||||
OVERLAY5: load = OVL5, type = ro, define = yes, optional = yes;
|
||||
OVL6ADDR: load = OVL6ADDR, type = ro;
|
||||
OVERLAY6: load = OVL6, type = ro, define = yes, optional = yes;
|
||||
OVL7ADDR: load = OVL7ADDR, type = ro;
|
||||
OVERLAY7: load = OVL7, type = ro, define = yes, optional = yes;
|
||||
OVL8ADDR: load = OVL8ADDR, type = ro;
|
||||
OVERLAY8: load = OVL8, type = ro, define = yes, optional = yes;
|
||||
OVL9ADDR: load = OVL9ADDR, type = ro;
|
||||
OVERLAY9: load = OVL9, type = ro, define = yes, optional = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
|
|
33
cfg/c64.cfg
33
cfg/c64.cfg
|
@ -8,24 +8,25 @@ SYMBOLS {
|
|||
__HIMEM__: type = weak, value = $D000;
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", define = yes, start = $0002, size = $001A;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||
RAM: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__;
|
||||
MOVE: file = %O, start = __ZPSAVE_LOAD__, size = __HIMEM__ - __INIT_RUN__;
|
||||
ZP: file = "", define = yes, start = $0002, size = $001A;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
HEADER: file = %O, define = yes, start = %S, size = $000D;
|
||||
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __STACKSIZE__ - __HEADER_LAST__;
|
||||
MOVE: file = %O, start = __INITBSS_LOAD__, size = __HIMEM__ - __BSS_RUN__;
|
||||
INIT: file = "", start = __BSS_RUN__, size = __HIMEM__ - __BSS_RUN__;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = RAM, type = ro;
|
||||
LOWCODE: load = RAM, type = ro, optional = yes;
|
||||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss, define = yes;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
INIT: load = MOVE, run = RAM, type = ro, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = HEADER, type = ro;
|
||||
STARTUP: load = MAIN, type = ro;
|
||||
LOWCODE: load = MAIN, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = ro;
|
||||
RODATA: load = MAIN, type = ro;
|
||||
DATA: load = MAIN, type = rw;
|
||||
INITBSS: load = MAIN, type = bss, define = yes;
|
||||
BSS: load = MAIN, type = bss, define = yes;
|
||||
INIT: load = MOVE, run = INIT, type = ro, define = yes;
|
||||
}
|
||||
FEATURES {
|
||||
CONDES: type = constructor,
|
||||
|
|
|
@ -22,6 +22,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
EXTZP: load = ZP, type = rw, define = yes;
|
||||
|
|
|
@ -19,6 +19,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
EXTZP: load = ZP, type = rw, define = yes;
|
||||
|
|
|
@ -18,7 +18,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ SEGMENTS {
|
|||
CODE: load = RAM, type = ro;
|
||||
RODATA: load = RAM, type = ro;
|
||||
DATA: load = RAM, type = rw;
|
||||
ZPSAVE: load = RAM, type = bss;
|
||||
INITBSS: load = RAM, type = bss;
|
||||
BSS: load = RAM, type = bss, define = yes;
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
.proc initcwd
|
||||
|
||||
lda #0
|
||||
sta __cwd
|
||||
jsr findfreeiocb
|
||||
bne oserr
|
||||
lda #GETCWD
|
||||
|
|
|
@ -108,7 +108,7 @@ L2: lda zpsave,x
|
|||
; ------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.segment "ZPSAVE"
|
||||
.segment "INITBSS"
|
||||
|
||||
zpsave: .res zpspace
|
||||
|
||||
|
|
|
@ -30,8 +30,7 @@
|
|||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special INIT segment,
|
||||
; which may be reused after the startup code is run
|
||||
|
@ -42,26 +41,26 @@ initmainargs:
|
|||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
; Because the buffer, that we're copying into, was zeroed out,
|
||||
; we don't need to add a NUL character.
|
||||
;
|
||||
|
||||
lda #0 ; The terminating NUL character
|
||||
ldy FNAM_LEN
|
||||
cpy #NAME_LEN + 1
|
||||
bcc L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda #FNAM ; Load vector address for FETCH routine
|
||||
ldx FNAM_BANK ; Load bank for FETCH routine
|
||||
jsr INDFET ; Load byte from (FETVEC),y
|
||||
sta name,y ; Save byte from filename
|
||||
L1: dey
|
||||
L1: sta name,y ; Save byte from filename
|
||||
dey
|
||||
bpl L0
|
||||
inc __argc ; argc always is equal to, at least, 1
|
||||
|
||||
; Find the "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; no "rem," no args.
|
||||
beq done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
|
@ -73,7 +72,7 @@ next: lda BASIC_BUF,x
|
|||
beq done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. This is useful since we
|
||||
|
@ -128,15 +127,13 @@ done: lda #<argv
|
|||
stx __argv + 1
|
||||
rts
|
||||
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ L2: lda zpsave,x
|
|||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "ZPSAVE"
|
||||
.segment "INITBSS"
|
||||
|
||||
zpsave: .res zpspace
|
||||
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
.include "plus4.inc"
|
||||
|
||||
|
||||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special INIT segment,
|
||||
; which may be reused after the startup code is run
|
||||
|
@ -42,25 +41,25 @@ initmainargs:
|
|||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
; Because the buffer, that we're copying into, was zeroed out,
|
||||
; we don't need to add a NUL character.
|
||||
;
|
||||
|
||||
lda #0 ; The terminating NUL character
|
||||
ldy FNAM_LEN
|
||||
cpy #NAME_LEN + 1
|
||||
bcc L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda #FNAM ; Vector address
|
||||
jsr FETCH ; Load byte from RAM
|
||||
sta name,y
|
||||
L1: dey
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
inc __argc ; argc always is equal to, at least, 1
|
||||
|
||||
; Find the "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; no "rem," no args.
|
||||
beq done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
|
@ -72,7 +71,7 @@ next: lda BASIC_BUF,x
|
|||
beq done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. This is useful since we
|
||||
|
@ -127,15 +126,13 @@ done: lda #<argv
|
|||
stx __argv + 1
|
||||
rts
|
||||
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
.import initlib, donelib
|
||||
.import moveinit, zerobss, callmain
|
||||
.import BSOUT
|
||||
.import __RAM_START__, __RAM_SIZE__ ; Linker generated
|
||||
.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated
|
||||
.import __STACKSIZE__ ; from configure file
|
||||
.importzp ST
|
||||
|
||||
|
@ -45,16 +45,24 @@ Start:
|
|||
ldx move_init
|
||||
beq L0
|
||||
|
||||
; Move the INIT segment from where it was loaded (over ZPSAVE and BSS)
|
||||
; into where it must be run (in the heap).
|
||||
; Move the INIT segment from where it was loaded (over the bss segments)
|
||||
; into where it must be run (over the BSS segment).
|
||||
|
||||
jsr moveinit
|
||||
dec move_init ; set to false
|
||||
dec move_init ; Set to false
|
||||
|
||||
; Save space by putting the rest of the start-up code in the INIT segment,
|
||||
; which can be re-used by the heap and the C stack.
|
||||
; Save space by putting some of the start-up code in the INIT segment,
|
||||
; which can be re-used by the BSS segment, the heap and the C stack.
|
||||
|
||||
L0: jsr initstart
|
||||
L0: jsr runinit
|
||||
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Back from main() [this is also the exit() entry]. Run the module destructors.
|
||||
|
||||
|
@ -90,7 +98,7 @@ L2: lda zpsave,x
|
|||
|
||||
.segment "INIT"
|
||||
|
||||
initstart:
|
||||
runinit:
|
||||
|
||||
; Save the zero-page locations that we need.
|
||||
|
||||
|
@ -100,24 +108,16 @@ L1: lda sp,x
|
|||
dex
|
||||
bpl L1
|
||||
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Set up the stack.
|
||||
|
||||
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
ldx #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
|
||||
ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
|
||||
sta sp
|
||||
stx sp+1 ; Set argument stack ptr
|
||||
|
||||
; Call the module constructors.
|
||||
|
||||
jsr initlib
|
||||
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jmp callmain
|
||||
jmp initlib
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
@ -134,6 +134,6 @@ spsave: .res 1
|
|||
move_init:
|
||||
.byte 1
|
||||
|
||||
.segment "ZPSAVE"
|
||||
.segment "INITBSS"
|
||||
|
||||
zpsave: .res zpspace
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
.include "c64.inc"
|
||||
|
||||
|
||||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special INIT segment,
|
||||
; which may be reused after the startup code is run
|
||||
|
@ -42,24 +41,24 @@ initmainargs:
|
|||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
; Because the buffer, that we're copying into, was zeroed out,
|
||||
; we don't need to add a NUL character.
|
||||
;
|
||||
|
||||
lda #0 ; The terminating NUL character
|
||||
ldy FNAM_LEN
|
||||
cpy #NAME_LEN + 1
|
||||
bcc L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda (FNAM),y
|
||||
sta name,y
|
||||
L1: dey
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
inc __argc ; argc always is equal to, at least, 1
|
||||
|
||||
; Find the "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; no "rem," no args.
|
||||
beq done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
|
@ -71,7 +70,7 @@ next: lda BASIC_BUF,x
|
|||
beq done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. This is useful since we
|
||||
|
@ -126,15 +125,13 @@ done: lda #<argv
|
|||
stx __argv + 1
|
||||
rts
|
||||
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
;
|
||||
|
||||
|
||||
.include "cbm.inc"
|
||||
.include "filedes.inc"
|
||||
|
||||
.code
|
||||
|
@ -29,9 +30,14 @@ found: rts
|
|||
;--------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
fdtab: .res MAX_FDS
|
||||
unittab:.res MAX_FDS
|
||||
|
||||
.data
|
||||
|
||||
fdtab: .byte LFN_READ
|
||||
.byte LFN_WRITE
|
||||
.byte LFN_WRITE
|
||||
.res MAX_FDS-3
|
||||
|
||||
unittab:.byte CBMDEV_KBD
|
||||
.byte CBMDEV_SCREEN
|
||||
.byte CBMDEV_SCREEN
|
||||
.res MAX_FDS-3
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
.importzp devnum
|
||||
|
||||
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
curunit:
|
||||
.res 1
|
||||
|
|
|
@ -26,11 +26,8 @@
|
|||
|
||||
.proc initstdin
|
||||
|
||||
lda #LFN_READ
|
||||
sta fdtab+STDIN_FILENO
|
||||
lda #STDIN_FILENO + LFN_OFFS
|
||||
ldx #CBMDEV_KBD
|
||||
stx unittab+STDIN_FILENO
|
||||
ldy #$FF
|
||||
jsr SETLFS
|
||||
jmp OPEN ; Will always succeed
|
||||
|
@ -155,5 +152,3 @@ invalidfd:
|
|||
.bss
|
||||
|
||||
unit: .res 1
|
||||
|
||||
|
||||
|
|
|
@ -24,12 +24,6 @@
|
|||
|
||||
.proc initstdout
|
||||
|
||||
lda #LFN_WRITE
|
||||
sta fdtab+STDOUT_FILENO
|
||||
sta fdtab+STDERR_FILENO
|
||||
lda #CBMDEV_SCREEN
|
||||
sta unittab+STDOUT_FILENO
|
||||
sta unittab+STDERR_FILENO
|
||||
lda #STDOUT_FILENO + LFN_OFFS
|
||||
jsr @L1
|
||||
lda #STDERR_FILENO + LFN_OFFS
|
||||
|
@ -122,7 +116,3 @@ invalidfd:
|
|||
jmp __directerrno ; Sets _errno, clears _oserror, returns -1
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -31,10 +31,9 @@
|
|||
.macpack generic
|
||||
|
||||
|
||||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special INIT segment,
|
||||
; which may be reused after the startup code is run.
|
||||
|
@ -61,40 +60,42 @@ initmainargs:
|
|||
ldy #FNAM_LEN
|
||||
lda (sysp0),y
|
||||
tay
|
||||
lda #0 ; The terminating NUL character
|
||||
stx IndReg ; Look for name in correct bank
|
||||
cpy #NAME_LEN + 1
|
||||
blt L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda (ptr1),y
|
||||
sta name,y
|
||||
L1: dey
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
jsr restore_bank
|
||||
inc __argc ; argc always is equal to at least 1
|
||||
|
||||
; Find a "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
bze done ; no "rem," no args.
|
||||
bze done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
ldy #1 * 2
|
||||
|
||||
; Find the next argument.
|
||||
;
|
||||
|
||||
next: lda BASIC_BUF,x
|
||||
bze done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. That is useful because we
|
||||
; will check now for a quoted argument; in which case, we will have to skip that
|
||||
; first character.
|
||||
;
|
||||
|
||||
found: cmp #'"' ; Is the argument quoted?
|
||||
beq setterm ; Jump if so
|
||||
dex ; Reset pointer to first argument character
|
||||
|
@ -102,7 +103,7 @@ found: cmp #'"' ; Is the argument quoted?
|
|||
setterm:sta term ; Set end-of-argument marker
|
||||
|
||||
; Now, store a pointer to the argument into the next slot.
|
||||
;
|
||||
|
||||
txa ; Get low byte
|
||||
add #<BASIC_BUF
|
||||
sta argv,y ; argv[y]= &arg
|
||||
|
@ -114,7 +115,7 @@ setterm:sta term ; Set end-of-argument marker
|
|||
inc __argc ; Found another arg
|
||||
|
||||
; Search for the end of the argument.
|
||||
;
|
||||
|
||||
argloop:lda BASIC_BUF,x
|
||||
bze done
|
||||
inx
|
||||
|
@ -124,7 +125,7 @@ argloop:lda BASIC_BUF,x
|
|||
; We've found the end of the argument. X points one character behind it, and
|
||||
; A contains the terminating character. To make the argument a valid C string,
|
||||
; replace the terminating character by a zero.
|
||||
;
|
||||
|
||||
lda #$00
|
||||
sta BASIC_BUF-1,x
|
||||
|
||||
|
@ -136,21 +137,20 @@ argloop:lda BASIC_BUF,x
|
|||
blt next ; Parse next one if not
|
||||
|
||||
; (The last vector in argv[] already is NULL.)
|
||||
;
|
||||
|
||||
done: lda #<argv
|
||||
ldx #>argv
|
||||
sta __argv
|
||||
stx __argv + 1
|
||||
rts
|
||||
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2, $00
|
||||
.res MAXARGS * 2
|
||||
|
|
|
@ -31,10 +31,9 @@
|
|||
.macpack generic
|
||||
|
||||
|
||||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special INIT segment,
|
||||
; which may be reused after the startup code is run.
|
||||
|
@ -45,9 +44,7 @@ initmainargs:
|
|||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
; Because the buffer, that we're copying into, was zeroed out,
|
||||
; we don't need to add a NUL character.
|
||||
;
|
||||
|
||||
jsr sys_bank
|
||||
ldy #FNAM
|
||||
lda (sysp0),y ; Get file-name pointer from system bank
|
||||
|
@ -61,40 +58,42 @@ initmainargs:
|
|||
ldy #FNAM_LEN
|
||||
lda (sysp0),y
|
||||
tay
|
||||
lda #0 ; The terminating NUL character
|
||||
stx IndReg ; Look for name in correct bank
|
||||
cpy #NAME_LEN + 1
|
||||
blt L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda (ptr1),y
|
||||
sta name,y
|
||||
L1: dey
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
jsr restore_bank
|
||||
inc __argc ; argc always is equal to at least 1
|
||||
|
||||
; Find a "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
bze done ; no "rem," no args.
|
||||
bze done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
ldy #1 * 2
|
||||
|
||||
; Find the next argument.
|
||||
;
|
||||
|
||||
next: lda BASIC_BUF,x
|
||||
bze done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. That is useful because we
|
||||
; will check now for a quoted argument; in which case, we will have to skip that
|
||||
; first character.
|
||||
;
|
||||
|
||||
found: cmp #'"' ; Is the argument quoted?
|
||||
beq setterm ; Jump if so
|
||||
dex ; Reset pointer to first argument character
|
||||
|
@ -102,7 +101,7 @@ found: cmp #'"' ; Is the argument quoted?
|
|||
setterm:sta term ; Set end-of-argument marker
|
||||
|
||||
; Now, store a pointer to the argument into the next slot.
|
||||
;
|
||||
|
||||
txa ; Get low byte
|
||||
add #<BASIC_BUF
|
||||
sta argv,y ; argv[y]= &arg
|
||||
|
@ -114,7 +113,7 @@ setterm:sta term ; Set end-of-argument marker
|
|||
inc __argc ; Found another arg
|
||||
|
||||
; Search for the end of the argument.
|
||||
;
|
||||
|
||||
argloop:lda BASIC_BUF,x
|
||||
bze done
|
||||
inx
|
||||
|
@ -124,33 +123,32 @@ argloop:lda BASIC_BUF,x
|
|||
; We've found the end of the argument. X points one character behind it, and
|
||||
; A contains the terminating character. To make the argument a valid C string,
|
||||
; replace the terminating character by a zero.
|
||||
;
|
||||
|
||||
lda #$00
|
||||
sta BASIC_BUF-1,x
|
||||
|
||||
; Check if the maximum number of command-line arguments is reached. If not,
|
||||
; parse the next one.
|
||||
;
|
||||
|
||||
lda __argc ; Get low byte of argument count
|
||||
cmp #MAXARGS ; Maximum number of arguments reached?
|
||||
blt next ; Parse next one if not
|
||||
|
||||
; (The last vector in argv[] already is NULL.)
|
||||
;
|
||||
|
||||
done: lda #<argv
|
||||
ldx #>argv
|
||||
sta __argv
|
||||
stx __argv + 1
|
||||
rts
|
||||
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2, $00
|
||||
.res MAXARGS * 2
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
.import initcwd
|
||||
|
||||
.include "stdio.inc"
|
||||
|
||||
|
||||
__cwd_buf_size = FILENAME_MAX
|
||||
|
||||
cwd_init := initcwd
|
||||
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
__cwd: .res __cwd_buf_size
|
||||
|
||||
|
@ -29,4 +29,3 @@ __cwd: .res __cwd_buf_size
|
|||
; checking the other sources.
|
||||
|
||||
.assert __cwd_buf_size < 256, error, "__cwd_buf_size must not be > 255"
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
.data
|
||||
|
||||
; Move the INIT segment from where it was loaded (over the bss segments)
|
||||
; into where it must be run (in the heap). The two areas might overlap; and,
|
||||
; the segment is moved upwards. Therefore, this code starts at the highest
|
||||
; into where it must be run (over the BSS segment). The two areas might overlap;
|
||||
; and, the segment is moved upwards. Therefore, this code starts at the highest
|
||||
; address, and decrements to the lowest address. The low bytes of the starting
|
||||
; pointers are not sums. The high bytes are sums; but, they do not include the
|
||||
; carry. Both the low-byte sums and the carries will be done when the pointers
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
.importzp ptr1
|
||||
|
||||
|
||||
.segment "INIT"
|
||||
.code
|
||||
|
||||
zerobss:
|
||||
lda #<__BSS_RUN__
|
||||
|
@ -41,6 +41,3 @@ L3: cpy #<__BSS_SIZE__
|
|||
; Done
|
||||
|
||||
L4: rts
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ L2: lda zpsave,x
|
|||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "ZPSAVE"
|
||||
.segment "INITBSS"
|
||||
|
||||
zpsave: .res zpspace
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
|
@ -25,24 +25,24 @@ NAME_LEN = 16 ; maximum length of command-name
|
|||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
; Because the buffer, that we're copying into, was zeroed out,
|
||||
; we don't need to add a NUL character.
|
||||
;
|
||||
|
||||
lda #0 ; The terminating NUL character
|
||||
ldy FNLEN
|
||||
cpy #NAME_LEN + 1
|
||||
bcc L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda (FNADR),y
|
||||
sta name,y
|
||||
L1: dey
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
inc __argc ; argc always is equal to, at least, 1
|
||||
|
||||
; Find the "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; no "rem," no args.
|
||||
beq done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
|
@ -54,7 +54,7 @@ next: lda BASIC_BUF,x
|
|||
beq done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. This is useful since we
|
||||
|
@ -111,14 +111,13 @@ done: lda #<argv
|
|||
|
||||
.endproc
|
||||
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
||||
|
|
|
@ -195,7 +195,7 @@ spsave: .res 1
|
|||
|
||||
irqcount: .byte 0
|
||||
|
||||
.segment "ZPSAVE"
|
||||
.segment "INITBSS"
|
||||
|
||||
zpsave: .res zpspace
|
||||
|
||||
|
|
|
@ -26,12 +26,11 @@
|
|||
.import __argc, __argv
|
||||
|
||||
.include "plus4.inc"
|
||||
|
||||
|
||||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special INIT segment,
|
||||
; which may be reused after the startup code is run
|
||||
|
@ -42,24 +41,24 @@ initmainargs:
|
|||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
; Because the buffer, that we're copying into, was zeroed out,
|
||||
; we don't need to add a NUL character.
|
||||
;
|
||||
|
||||
lda #0 ; The terminating NUL character
|
||||
ldy FNAM_LEN
|
||||
cpy #NAME_LEN + 1
|
||||
bcc L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda (FNAM),y
|
||||
sta name,y
|
||||
L1: dey
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
inc __argc ; argc always is equal to, at least, 1
|
||||
|
||||
; Find the "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; no "rem," no args.
|
||||
beq done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
|
@ -71,7 +70,7 @@ next: lda BASIC_BUF,x
|
|||
beq done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. This is useful since we
|
||||
|
@ -125,17 +124,14 @@ done: lda #<argv
|
|||
sta __argv
|
||||
stx __argv + 1
|
||||
rts
|
||||
|
||||
; --------------------------------------------------------------------------
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
||||
|
||||
|
|
|
@ -31,9 +31,9 @@
|
|||
;---------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
__argc: .res 2
|
||||
__argv: .res 2
|
||||
.data
|
||||
__argc: .word 0
|
||||
__argv: .addr 0
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -101,14 +101,14 @@ Fail: lda #4
|
|||
; ----------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
; Initial stack pointer value. Stack is reset to this in case of overflows to
|
||||
; allow program exit processing.
|
||||
initialsp: .word 0
|
||||
initialsp: .res 2
|
||||
|
||||
; Stack low water mark.
|
||||
lowwater: .word 0
|
||||
lowwater: .res 2
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ L2: lda zpsave,x
|
|||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "ZPSAVE"
|
||||
.segment "INITBSS"
|
||||
|
||||
zpsave: .res zpspace
|
||||
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
.include "vic20.inc"
|
||||
|
||||
|
||||
|
||||
MAXARGS = 10 ; Maximum number of arguments allowed
|
||||
REM = $8f ; BASIC token-code
|
||||
NAME_LEN = 16 ; maximum length of command-name
|
||||
NAME_LEN = 16 ; Maximum length of command-name
|
||||
|
||||
; Get possible command-line arguments. Goes into the special INIT segment,
|
||||
; which may be reused after the startup code is run
|
||||
|
@ -42,24 +41,24 @@ initmainargs:
|
|||
|
||||
; Assume that the program was loaded, a moment ago, by the traditional LOAD
|
||||
; statement. Save the "most-recent filename" as argument #0.
|
||||
; Because the buffer, that we're copying into, was zeroed out,
|
||||
; we don't need to add a NUL character.
|
||||
;
|
||||
|
||||
lda #0 ; The terminating NUL character
|
||||
ldy FNAM_LEN
|
||||
cpy #NAME_LEN + 1
|
||||
bcc L1
|
||||
ldy #NAME_LEN - 1 ; limit the length
|
||||
ldy #NAME_LEN ; Limit the length
|
||||
bne L1 ; Branch always
|
||||
L0: lda (FNAM),y
|
||||
sta name,y
|
||||
L1: dey
|
||||
L1: sta name,y
|
||||
dey
|
||||
bpl L0
|
||||
inc __argc ; argc always is equal to, at least, 1
|
||||
|
||||
; Find the "rem" token.
|
||||
;
|
||||
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; no "rem," no args.
|
||||
beq done ; No "rem," no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
|
@ -71,7 +70,7 @@ next: lda BASIC_BUF,x
|
|||
beq done ; End of line reached
|
||||
inx
|
||||
cmp #' ' ; Skip leading spaces
|
||||
beq next ;
|
||||
beq next
|
||||
|
||||
; Found start of next argument. We've incremented the pointer in X already, so
|
||||
; it points to the second character of the argument. This is useful since we
|
||||
|
@ -126,15 +125,13 @@ done: lda #<argv
|
|||
stx __argv + 1
|
||||
rts
|
||||
|
||||
; These arrays are zeroed before initmainargs is called.
|
||||
; char name[16+1];
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
;
|
||||
.bss
|
||||
.segment "INITBSS"
|
||||
|
||||
term: .res 1
|
||||
name: .res NAME_LEN + 1
|
||||
|
||||
.data
|
||||
|
||||
; char* argv[MAXARGS+1]={name};
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue