The constructors are _NOT_ allowed anymore to access the BSS. Rather they must use the DATA segment or the INIT 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.
__RAMEND__: type = weak, value = $9800 + $1C00 * __GRAB__;
}
MEMORY {
- ZP: file = "", define = yes, start = $00E2, size = $001A;
- TAPEHDR: file = %O, type = ro, start = $0000, size = $001F;
- BASHEAD: file = %O, define = yes, start = $0501, size = $000D;
- MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __RAM_START__ - __STACKSIZE__;
+ ZP: file = "", define = yes, start = $00E2, size = $001A;
+ TAPEHDR: file = %O, type = ro, start = $0000, size = $001F;
+ BASHEAD: file = %O, define = yes, start = $0501, size = $000D;
+ MAIN: file = %O, define = yes, start = __BASHEAD_LAST__, size = __RAMEND__ - __MAIN_START__ - __STACKSIZE__;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
LOWCODE: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
- ONCE: load = MAIN, type = ro, define = yes, optional = yes;
+ ONCE: load = MAIN, type = ro, optional = yes;
DATA: load = MAIN, type = rw;
+ INIT: load = MAIN, type = rw, optional = yes;
ZPSAVE1: load = MAIN, type = rw, define = yes; # ZPSAVE1, ZPSAVE2 must be together
ZPSAVE2: load = MAIN, type = bss; # see "libsrc/atmos/crt0.s"
BSS: load = MAIN, type = bss, define = yes;
CODE: type = ro, run = VLIR0, load = CVT;
RODATA: type = ro, run = VLIR0, load = CVT;
DATA: type = rw, run = VLIR0, load = CVT;
+ INIT: type = bss, load = VLIR0, optional = yes;
BSS: type = bss, load = VLIR0, define = yes;
VLIRIDX1: type = ro, load = CVT, align = $200, optional = yes;
OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $200, optional = yes;
CODE: type = ro, run = VLIR0, load = CVT;
RODATA: type = ro, run = VLIR0, load = CVT;
DATA: type = rw, run = VLIR0, load = CVT;
+ INIT: type = bss, load = VLIR0, optional = yes;
BSS: type = bss, load = VLIR0, define = yes;
OVERLAY1: type = ro, run = VLIR1, load = CVT, align_load = $FE, optional = yes;
OVERLAY2: type = ro, run = VLIR2, load = CVT, align_load = $FE, optional = yes;
: sta __dos_type
done: rts
- .bss
+ .data
-__dos_type: .res 1
+__dos_type: .byte $00
; ------------------------------------------------------------------------
- .bss
+ .data
table: .res MAX_FDS
ldx #$00
rts
- .bss
+ .segment "INIT"
ostype: .res 1
; destroyed.
ldy #$00
+ sty buffer + BUF_LEN - 1
: lda BASIC_BUF,x
sta buffer,y
inx
stx __argv+1
rts
-; This array is zeroed before initmainargs is called.
-; char* argv[MAXARGS+1] = {FNAM};
-
.data
+; char* argv[MAXARGS+1] = {FNAM};
+
argv: .addr FNAM
.res MAXARGS * 2
- .bss
+ .segment "INIT"
buffer: .res BUF_LEN
; ------------------------------------------------------------------------
; Data
- .bss
+ .data
-__dos_type: .res 1 ; default to ATARIDOS
+__dos_type: .byte 0 ; default to ATARIDOS
.segment "ONCE"
initmainargs:
- lda #0
- sta __argc
- sta __argc+1
- sta __argv
- sta __argv+1
-
lda __dos_type ; which DOS?
cmp #ATARIDOS
beq nargdos ; DOS does not support arguments
finargs:
lda __argc
- asl
+ asl
tax
lda #0
sta argv,x
; --------------------------------------------------------------------------
; Data
-.bss
+.segment "INIT"
argv: .res (1 + MAXARGS) * 2
;--------------------------------------------------------------------------
-.bss
+.segment "INIT"
capsave:
.res 1
.macpack generic
MAXARGS = 10 ; Maximum number of arguments allowed
-REM = $9d ; BASIC token-code
+REM = $9D ; BASIC token-code
;---------------------------------------------------------------------------
; 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.
-;
- ldy #FNAME_LEN - 1 ; limit the length
+
+ ldy #FNAME_LEN ; Limit the length
+ lda #0 ; The terminating NUL character
+ beq L1 ; Branch always
L0: lda CFOUND_NAME,y
- sta name,y
+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
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
txa ; Get low byte
add #<args
- sta argv,y ; argv[y]= &arg
+ sta argv,y ; argv[y]=&arg
lda #>$0000
adc #>args
sta argv+1,y
; A contains the terminating character. To make the argument a valid C string,
; replace the terminating character by a zero.
- lda #$00
+ lda #0
sta args-1,x
; Check if the maximum number of command line arguments is reached. If not,
.endproc
; These arrays are zeroed before initmainargs is called.
-; char name[16+1];
-; char* argv[MAXARGS+1]={name};
-;
-.bss
+
+.segment "INIT"
+
term: .res 1
name: .res FNAME_LEN + 1
args: .res SCREEN_XSIZE * 2 - 1
.data
+
+; char* argv[MAXARGS+1]={name};
+
argv: .addr name
- .res MAXARGS * 2, $00
+ .res MAXARGS * 2
;--------------------------------------------------------------------------
-.bss
+.segment "INIT"
text_count:
.res 1
-
;--------------------------------------------------------------------------
; Module constructor/destructor
-.bss
+.segment "INIT"
keyvec: .res 2
.segment "ONCE"
; Save the old vector
lda KeyStoreVec
+ ldx KeyStoreVec+1
sta keyvec
- lda KeyStoreVec+1
- sta keyvec+1
+ stx keyvec+1
; Set the new vector. I can only hope that this works for other C128
; versions...
stx KeyStoreVec+1
cli
rts
-
-
.export __environ, __envcount, __envsize
.import initenv
.constructor env_init
-
+
env_init := initenv
-
-.bss
+
+.data
__environ:
.addr 0
.byte 0
__envsize:
.byte 0
-
-
ldy ysize
rts
-.bss
+.segment "INIT"
xsize:
.res 1
; Setup arguments for main
;
; There is always either 1 or 3 arguments:
-; <program name>,0
+; <program name>, 0
; or
; <program name>, <data file name>, <data disk name>, 0
; the 2nd case is when using DeskTop user drags an icon of a file and drops it
.word dataDiskName ; dataDiskName
.word $0000 ; last one must be NULL
-.bss
+.segment "INIT"
argv0:
.res 17 ; Program name