]> git.sur5r.net Git - cc65/commitdiff
adapt to new segments; some other text changes
authorcpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 25 Jun 2010 23:47:37 +0000 (23:47 +0000)
committercpg <cpg@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 25 Jun 2010 23:47:37 +0000 (23:47 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@4728 b7a2c559-68d2-44c3-8de9-860c34a00d81

doc/atari.sgml

index 0424dde627d3a6137961262609bf83a12ac0b12e..ccf2ec323ec1627ddeab54829b367dbb085b86d7 100644 (file)
@@ -271,15 +271,15 @@ or f80.com software is missing. Of course you may use stdio.h functions.
 
 <sect1>Function keys<p>
 
-These are defined to be Atari + number key.
+Function keys are mapped to Atari + number key.
 
 <sect1>Reserving a memory area inside a program<label id="memhole"><p>
 
 The Atari 130XE maps its additional memory into CPU memory in 16K
 chunks at address &dollar;4000 to &dollar;7FFF. One might want to
 prevent this memory area from being used by cc65. Other reasons to
-prevent the use of some memory area could be the buffers for display
-lists and screen memory.
+prevent the use of some memory area could be to reserve space for the
+buffers for display lists and screen memory.
 <p>
 The Atari executable format allows holes inside a program, e.g. one
 part loads into &dollar;2E00 to &dollar;3FFF, going below the reserved
@@ -288,7 +288,9 @@ memory area (assuming a reserved area from &dollar;4000 to
 &dollar;BC1F.
 <p>
 Each load chunk of the executable starts with a 4 byte header which
-defines its load address and size.
+defines its load address and size. In the following linker scripts
+these headers are named HEADER and SECHDR (for the MEMORY layout), and
+accordingly NEXEHDR and CHKHDR (for the SEGMENTS layout).
 <p>
 <sect2>Low code and high data example<p>
 Goal: Create an executable with 2 load chunks which doesn't use the
@@ -298,14 +300,16 @@ segments should go above &dollar;7FFF.
 <p>
 The main problem is that the EXE header generated by the cc65 runtime
 lib is wrong. It defines a single load chunk with the sizes/addresses
-of the LOWCODE, INIT, CODE, RODATA, and DATA segments (the whole user
+of the STARTUP, LOWCODE, INIT, CODE, RODATA, and DATA segments (the whole user
 program).
 <p>
 The contents of the EXE header come from the EXEHDR segment, which is
-defined in crt0.s. This cannot be changed w/o modifying and
+defined in crt0.s. This cannot be changed without modifying and
 recompiling the cc65 atari runtime lib. Therefore the original EXE
 header must be discarded. It will be replaced by a user created
-one.
+one. The discarding is done by assigning the EXEHDR segment to the
+BANK memory area. The BANK memory area is discarded in the new linker
+script (written to file "").
 <p>
 The user needs to create a customized linker config file which adds
 new memory areas and segments to hold the new EXE header and the
@@ -314,24 +318,32 @@ needs to be created which defines the contents of the new EXE header
 and the second load chunk header.
 <p>
 <p>
-This is a modified cc65 Atari linker configuration file (split.cfg):
+This is an example of a modified cc65 Atari linker configuration file
+(split.cfg):
 <tscreen><verb>
+SYMBOLS {
+    __STACKSIZE__ = $800;                               # 2K stack
+    __RESERVED_MEMORY__: value = $0000, weak = yes;
+}
+FEATURES {
+    STARTADDRESS: default = $2E00;
+}
 MEMORY {
     ZP: start = $82, size = $7E, type = rw, define = yes;
 
     HEADER: start = $0000, size = $6, file = %O;        # first load chunk
-    RAMLO: start = $2E00, size = $1200, file = %O;
+    RAMLO: start = %S, size = $4000 - %S, file = %O;
 
     BANK: start = $4000, size = $4000, file = "";
 
     SECHDR: start = $0000, size = $4, file = %O;        # second load chunk
     RAM: start = $8000, size = $3C20, file = %O;        # $3C20: matches upper bound $BC1F
-    TRAILER: start = $0000, size = $0006, file = %O;
 }
 SEGMENTS {
     EXEHDR: load = BANK, type = ro;
 
     NEXEHDR: load = HEADER, type = ro;                  # first load chunk
+    STARTUP: load = RAMLO, type = ro, define = yes;
     LOWCODE: load = RAMLO, type = ro, define = yes, optional = yes;
     INIT: load = RAMLO, type = ro, optional = yes;
     CODE: load = RAMLO, type = ro, define = yes;
@@ -340,9 +352,10 @@ SEGMENTS {
     RODATA: load = RAM, type = ro, define = yes;
     DATA: load = RAM, type = rw, define = yes;
     BSS: load = RAM, type = bss, define = yes;
+    ZPSAVE: load = RAM, type = bss, define = yes;
 
     ZEROPAGE: load = ZP, type = zp;
-    AUTOSTRT: load = TRAILER, type = ro;                # defines program entry point
+    AUTOSTRT: load = RAM, type = ro;                    # defines program entry point
 }
 FEATURES {
     CONDES: segment = RODATA,
@@ -354,10 +367,6 @@ FEATURES {
             label = __DESTRUCTOR_TABLE__,
             count = __DESTRUCTOR_COUNT__;
 }
-SYMBOLS {
-    __STACKSIZE__ = $800;       # 2K stack
-    __RESERVED_MEMORY__: value = $0, weak = yes;
-}
 </verb></tscreen>
 <p>
 
@@ -366,30 +375,29 @@ It gets loaded with the contents of the old EXEHDR segment. But the
 memory area isn't written to the output file. This way the contents of
 the EXEHDR segment get discarded.
 <p>
-The added NEXEHDR segment defines the correct EXE header. It puts only
-the CODE segment into load chunk #1 (RAMLO memory area).
+The newly added NEXEHDR segment defines the correct EXE header. It
+puts the STARTUP, LOWCODE, INIT, and CODE segments, which are the
+segments containing only code, into load chunk #1 (RAMLO memory area).
 <p>
 The header for the second load chunk comes from the new CHKHDR
-segment. It puts the RODATA and DATA segments into load chunk #2 (RAM
-memory area).
+segment. It puts the RODATA, DATA, BSS, and ZPSAVE segments into load
+chunk #2 (RAM memory area).
 <p>
 <p>
 The contents of the new NEXEHDR and CHKHDR segments come from this
 file (split.s):
 <tscreen><verb>
-        .import __LOWCODE_LOAD__, __BSS_LOAD__, __CODE_SIZE__
-        .import __CODE_LOAD__, __DATA_LOAD__, __RODATA_LOAD__
-
-        .segment "NEXEHDR"
-        .word    $FFFF          ; EXE file magic number
-        ; 1st load chunk
-        .word    __LOWCODE_LOAD__
-        .word    __CODE_LOAD__ + __CODE_SIZE__ - 1
-
-        .segment "CHKHDR"
-        ; 2nd load chunk (contains with AUTOSTRT in fact a 3rd load chunk)
-        .word    __RODATA_LOAD__
-        .word    __BSS_LOAD__ - 1
+       .import __CODE_LOAD__, __BSS_LOAD__, __CODE_SIZE__
+       .import __DATA_LOAD__, __RODATA_LOAD__, __STARTUP_LOAD__
+
+       .segment "NEXEHDR"
+       .word    $FFFF
+       .word    __STARTUP_LOAD__
+       .word    __CODE_LOAD__ + __CODE_SIZE__ - 1
+
+       .segment "CHKHDR"
+       .word    __RODATA_LOAD__
+       .word    __BSS_LOAD__ - 1
 </verb></tscreen>
 <p>
 Compile with
@@ -400,21 +408,27 @@ cl65 -t atari -C split.cfg -o prog.com prog.c split.s
 <sect2>Low data and high code example<p>
 
 
-Goal: Put RODATA and DATA into low memory and LOWCODE, INIT, CODE, BSS
-into high memory (split2.cfg):
+Goal: Put RODATA and DATA into low memory and STARTUP, LOWCODE, INIT,
+CODE, BSS, ZPSAVE into high memory (split2.cfg):
 
 <tscreen><verb>
+SYMBOLS {
+    __STACKSIZE__ = $800;       # 2K stack
+    __RESERVED_MEMORY__: value = $0000, weak = yes;
+}
+FEATURES {
+    STARTADDRESS: default = $2E00;
+}
 MEMORY {
     ZP: start = $82, size = $7E, type = rw, define = yes;
 
     HEADER: start = $0000, size = $6, file = %O;        # first load chunk
-    RAMLO: start = $2E00, size = $1200, file = %O;
+    RAMLO: start = %S, size = $4000 - %S, file = %O;
 
     BANK: start = $4000, size = $4000, file = "";
 
     SECHDR: start = $0000, size = $4, file = %O;        # second load chunk
     RAM: start = $8000, size = $3C20, file = %O;        # $3C20: matches upper bound $BC1F
-    TRAILER: start = $0000, size = $0006, file = %O;
 }
 SEGMENTS {
     EXEHDR: load = BANK, type = ro;                     # discarded old EXE header
@@ -424,13 +438,14 @@ SEGMENTS {
     DATA: load = RAMLO, type = rw, define = yes;
 
     CHKHDR: load = SECHDR, type = ro;                   # second load chunk
-    LOWCODE: load = RAM, type = ro, define = yes, optional = yes;
+    STARTUP: load = RAM, type = ro, define = yes;
     INIT: load = RAM, type = ro, optional = yes;
     CODE: load = RAM, type = ro, define = yes;
+    ZPSAVE: load = RAM, type = bss, define = yes;
     BSS: load = RAM, type = bss, define = yes;
 
     ZEROPAGE: load = ZP, type = zp;
-    AUTOSTRT: load = TRAILER, type = ro;                # defines program entry point
+    AUTOSTRT: load = RAM, type = ro;                    # defines program entry point
 }
 FEATURES {
     CONDES: segment = RODATA,
@@ -442,25 +457,21 @@ FEATURES {
             label = __DESTRUCTOR_TABLE__,
             count = __DESTRUCTOR_COUNT__;
 }
-SYMBOLS {
-    __STACKSIZE__ = $800;       # 2K stack
-    __RESERVED_MEMORY__: value = $0, weak = yes;
-}
 </verb></tscreen>
 
 New contents for NEXEHDR and CHKHDR are needed (split2.s):
 <tscreen><verb>
-        .import __LOWCODE_LOAD__, __BSS_LOAD__, __DATA_SIZE__
-        .import __DATA_LOAD__, __RODATA_LOAD__
+       .import __STARTUP_LOAD__, __ZPSAVE_LOAD__, __DATA_SIZE__
+       .import __DATA_LOAD__, __RODATA_LOAD__
 
-        .segment "NEXEHDR"
-        .word    $FFFF
-        .word    __RODATA_LOAD__
-        .word    __DATA_LOAD__ + __DATA_SIZE__ - 1
+       .segment "NEXEHDR"
+       .word    $FFFF
+       .word    __RODATA_LOAD__
+       .word    __DATA_LOAD__ + __DATA_SIZE__ - 1
 
-        .segment "CHKHDR"
-        .word    __LOWCODE_LOAD__
-        .word    __BSS_LOAD__ - 1
+       .segment "CHKHDR"
+       .word    __STARTUP_LOAD__
+       .word    __ZPSAVE_LOAD__ - 1
 </verb></tscreen>
 
 Compile with