From c992a3596bfee34af3d376dc8e8d12b8e9f4ecdc Mon Sep 17 00:00:00 2001 From: cpg Date: Fri, 25 Jun 2010 23:47:37 +0000 Subject: [PATCH] adapt to new segments; some other text changes git-svn-id: svn://svn.cc65.org/cc65/trunk@4728 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- doc/atari.sgml | 113 +++++++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/doc/atari.sgml b/doc/atari.sgml index 0424dde62..ccf2ec323 100644 --- a/doc/atari.sgml +++ b/doc/atari.sgml @@ -271,15 +271,15 @@ or f80.com software is missing. Of course you may use stdio.h functions. Function keys

-These are defined to be Atari + number key. +Function keys are mapped to Atari + number key. Reserving a memory area inside a program

The Atari 130XE maps its additional memory into CPU memory in 16K chunks at address $4000 to $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.

The Atari executable format allows holes inside a program, e.g. one part loads into $2E00 to $3FFF, going below the reserved @@ -288,7 +288,9 @@ memory area (assuming a reserved area from $4000 to $BC1F.

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).

Low code and high data example

Goal: Create an executable with 2 load chunks which doesn't use the @@ -298,14 +300,16 @@ segments should go above $7FFF.

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).

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 "").

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.

-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): +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; -}

@@ -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.

-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).

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).

The contents of the new NEXEHDR and CHKHDR segments come from this file (split.s): - .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

Compile with @@ -400,21 +408,27 @@ cl65 -t atari -C split.cfg -o prog.com prog.c split.s Low data and high code example

-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): +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; -} New contents for NEXEHDR and CHKHDR are needed (split2.s): - .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 Compile with -- 2.39.5