1 <!doctype linuxdoc system>
4 <title>Atari specific information for cc65
6 <url url="mailto:shawnjefferson@24fightingchickens.com" name="Shawn Jefferson"> and<newline>
7 <url url="mailto:chris@groessler.org" name="Christian Groessler">
10 An overview over the Atari runtime system as it is implemented for the cc65 C
14 <!-- Table of contents -->
17 <!-- Begin the document -->
21 This file contains an overview of the Atari runtime system as it comes
22 with the cc65 C compiler. It describes the memory layout, Atari specific
23 header files, available drivers, and any pitfalls specific to that
26 The Atari runtime support comes in two flavors: <tt/atari/ and <tt/atarixl/.
27 The <tt/atari/ target supports all Atari 8-bit computers, the <tt/atarixl/ only
28 supports XL type or newer machines (excluding the 600XL).
30 The <tt/atarixl/ runtime makes the whole 64K of memory available, with the
31 exception of the I/O area at $D000 - $D7FF. Since the
32 <tt/atarixl/ runtime has some <ref name="limitations" id="limitations">, it is
33 recommended to use the <tt/atari/ target unless lack of memory dictates the
34 use of the <tt/atarixl/ target.
36 Please note that Atari specific functions are just mentioned here, they are
37 described in detail in the separate <url url="funcref.html" name="function
38 reference">. Even functions marked as "platform dependent" may be available on
39 more than one platform. Please see the function reference for more
43 <sect>Binary format<p>
45 The Atari DOS executable file format supports more than one load block (<it/chunk/).
47 The default binary output format generated by the linker for the
48 Atari target is a machine language program with a standard executable
49 header (FF FF <load chunk #1> ... <load chunk #n>).
50 A load chunk has the format [<2 byte start address> <2 bytes end address>
51 <chunk data>].
52 A run vector is added to the end of the
53 file ($02E0 $02E1 <run vector>) and is calculated using
54 the <tt/start/ label in crt0.s. (Technically the run vector is also a load chunk,
55 but is not regarded as such here.)
57 An <tt/atari/ program has two load chunks, an <tt/atarixl/ program has three load
58 chunks. The load chunks are defined in the linker configuration files. For more
59 detailed information about the load chunks see the chapter
60 <ref name="Technical details" id="techdetail">. For the discussion here it's
61 sufficient to know that the first load chunk(s) do preparation work and the
62 main part of the program is in the last load chunk.
64 The values determining the size of the main part of the program (the second load
65 chunk for <tt/atari/, the third load chunk for <tt/atarixl/) are calculated in
66 the crt0.s file from the __STARTUP_LOAD__ and __BSS_LOAD__ values.
67 Be aware of that if you create a custom linker config file and start moving segments around (see section
68 <ref name="Reserving a memory area inside the program" id="memhole">).
71 <sect>Memory layout<p>
73 <sect1><tt/atari/ target<p>
75 The default linker config file assumes that the BASIC ROM is disabled (or
76 the BASIC cartridge unplugged). This gives a usable memory range of
77 [$2000-$BC1F]. The library startup code examines the
78 current memory configuration, which depends on the size of the
79 installed memory and cartridges. It does so by using the value in
80 the MEMTOP ($2E5) variable as highest memory address the program
81 can use. The initial stack pointer, which is the upper bound of
82 memory used by the program, is set to this value, minus an optionally
83 defined __RESERVED_MEMORY__ value.
85 The default load address of $2000 can be changed by creating a custom
86 linker config file or by using the "--start-addr" cl65 command line
87 argument or the "--start-addr" or "-S" ld65 command line arguments.
89 Please note that the first load chunk (which checks the available memory)
90 will always be loaded at $2E00, regardless of the specified start
91 address. This address can only be changed by a custom linker config file.
97 The text screen depends on the installed memory size and cartridges
98 and can be obtained from the SAVMSC variable ($58).
101 The C runtime stack is located at MEMTOP and grows downwards,
102 regardless of how your linker config file is setup. This
103 accommodates the different memory configurations of the Atari
104 machines, as well as having a cartridge installed. You can override
105 this behaviour by writing your own crt0.s file and linking it to
106 your program (see also <ref name="Final note"
107 id="memhole_final_note">).
110 The C heap is located at the end of the program and grows towards the C
115 <sect1><tt/atarixl/ target<p>
117 The startup code rearranges the memory as follows:
120 <item>Sceen memory and display list are moved below the program start address.
121 <item>The ROM is disabled, making the memory in the areas [$C000-$CFFF]
122 and [$D800-$FFF9] available.
123 <item>Character generator data is copied from ROM to the CHARGEN location specified in the
124 linker config file. This is (in the default <tt/atarixl.cfg/ file) at the same address as
125 where it is in ROM ($E000, it can be changed, see <ref name="atarixl chargen location"
126 id="chargenloc">). With the character generator at $E000, there are two upper memory
127 areas available, [$D800-$DFFF] and [$E400-$FFF9].
130 With the default load address of $2400 this gives a usable memory range of
131 [$2400-$CFFF].
133 Please note that the first load chunk (which checks the system
134 compatibilty and available memory) will always be loaded at
135 $2E00, regardless of the specified start address. This address
136 can only be changed by a custom linker config file.
142 The text screen depends on the selected load address ($2400
143 by default), and resides directly before that address, rounded to the next
145 The screen memory's start address can be obtained from the SAVMSC variable
149 The C runtime stack is located at end of the MAIN memory area ($CFFF)
153 The C heap is located at the end of the program (end of BSS segment) and
154 grows towards the C runtime stack.
158 <sect>Linker configurations<p>
160 The ld65 linker comes with default config files for the Atari. There
161 are two targets for the Atari, <tt/atari/ and <tt/atarixl/.
162 The default config file for <tt/atari/ is selected with
163 <tt/-t atari/, and the default config file for <tt/atarixl/ is selected with
165 The Atari package comes with additional secondary linker config files which
166 can be used via <tt/-t atari -C <configfile>/ (for <tt/atari/ target) or
167 <tt/-t atarixl -C <configfile>/ (for <tt/atarixl/ target).
169 <sect1><tt/atari/ config files<p>
171 <sect2>default config file (<tt/atari.cfg/)<p>
173 The default configuration is tailored to C programs. It creates files
174 which have a default load address of $2000.
176 The files generated by this config file include the
177 <ref name="&dquot;system check&dquot;" id="syschk"> load chunk. It can
178 optionally be left out, see <ref name="Getting rid of the &dquot;system check&dquot; load chunk" id="nosyschk">.
180 <sect2><tt/atari-asm.cfg/<p>
182 This config file aims to give the assembler programmer maximum
183 flexibility. All program segments (<tt/CODE/, <tt/DATA/, etc.) are
186 By default it creates regular DOS executable files, which have a default
187 load address of $2E00. It's also possible to generate an image of
188 just the program data without EXE header, load address, or (auto-)start address.
189 To you so, you have to define the symbols <tt/__AUTOSTART__/ and <tt/__EXEHDR__/
190 when linking the program. Therefore, to generate a "plain" binary file, pass the
191 options "<tt/-D__AUTOSTART__=1 -D__EXEHDR__=1/" to the linker.
192 It's also possible to create a non auto-starting program file, by defining
193 only the <tt/__AUTOSTART__/ symbol. Such a program has to be run manually
194 after being loaded by DOS (for example by using the "M" option of DOS 2.5).
195 Defining only the <tt/__EXEHDR__/ symbol will create a (useless) file which
196 doesn't conform to the DOS executable file format (like a "plain" binary file)
197 but still has the "autostart" load chunk appended.
199 The sections of the file which the defines refer to (<tt/__AUTOSTART__/ for
200 the autostart trailer, <tt/__EXEHDR__/ for the EXE header and load address)
201 is <it/left out/, keep this in mind.
203 The values you assign to the two symbols <tt/__AUTOSTART__/ and <tt/__EXEHDR__/
206 <sect2><tt/atari-cart.cfg/<p>
208 This config file can be used to create 8K or 16K cartridges. It's suited both
209 for C and assembly language programs.
211 By default, an 8K cartridge is generated. To create a 16K cartridge, pass the
212 size of the cartridge to the linker, like "<tt/-D__CARTSIZE__=0x4000/".
213 The only valid values for <tt/__CARTSIZE__/ are 0x2000 and 0x4000.
215 The option byte of the cartridge can be set with the <tt/__CARTFLAGS__/
216 value, passed to the linker. The default value is $01, which means
217 that the cartridge doesn't prevent the booting of DOS.
219 The option byte will be located at address $BFFD. For more information
220 about its use, see e.g. "Mapping the Atari".
222 <sect2><tt/atari-cassette.cfg/<p>
224 This config file can be used to create cassette boot files. It's suited both
225 for C and assembly language programs.
227 The size of a cassette boot file is restricted to 32K. Larger programs
228 would need to be split in more parts and the parts to be loaded manually.
230 To write the generated file to a cassette, a utility (<tt/w2cas.com/) to run
231 on an Atari is provided in the <tt/util/ directory of <tt/atari/ target dir.
233 <sect1><tt/atarixl/ config files<p>
235 <sect2>default config file (<tt/atarixl.cfg/)<p>
237 The default configuration is tailored to C programs. It creates files
238 which have a default load address of $2400.
240 The files generated by this config file include the
241 <ref name="&dquot;system check&dquot;" id="syschkxl"> load chunk. It can
242 optionally be left out, see <ref name="Getting rid of the &dquot;system check&dquot; load chunk" id="nosyschk">.
244 <sect2><tt/atarixl-largehimem.cfg/<p>
246 This is the same as the default config file, but it rearranges the
247 high memory beneath the ROM into one large block. In order for this
248 config file to work, the runtime library has to be recompiled with a
249 special define. See the file <tt/libsrc/atari/Makefile.inc/ in the
252 The files generated by this config file include the
253 <ref name="&dquot;system check&dquot;" id="syschkxl"> load chunk. It can
254 optionally be left out, see <ref name="Getting rid of the &dquot;system check&dquot; load chunk" id="nosyschk">.
257 <sect>Platform specific header files<p>
259 Programs containing Atari specific code may use the <tt/atari.h/
263 <sect1>Atari specific functions<p>
265 The functions and global variable listed below are special for the Atari.
266 See the <url url="funcref.html" name="function reference"> for declaration and usage.
276 <item>_is_cmdline_dos
285 <sect1>Hardware access<p>
287 The following pseudo variables declared in the <tt/atari.h/ header
288 file do allow access to hardware located in the address space. Some
289 variables are structures, accessing the struct fields will access the
294 <tag><tt/GTIA_READ/ and <tt/GTIA_WRITE/</tag>
295 The <tt/GTIA_READ/ structure allows read access to the GTIA. The
296 <tt/GTIA_WRITE/ structure allows write access to the GTIA.
297 See the <tt/_gtia.h/ header file located in the include directory
298 for the declaration of the structure.
300 <tag><tt/POKEY_READ/ and <tt/POKEY_WRITE/</tag>
301 The <tt/POKEY_READ/ structure allows read access to the POKEY. The
302 <tt/POKEY_WRITE/ structure allows write access to the POKEY.
303 See the <tt/_pokey.h/ header file located in the include directory
304 for the declaration of the structure.
306 <tag><tt/ANTIC/</tag>
307 The <tt/ANTIC/ structure allows read access to the ANTIC.
308 See the <tt/_antic.h/ header file located in the include directory
309 for the declaration of the structure.
312 The <tt/PIA/ structure allows read access to the PIA 6520.
313 See the <tt/_pia.h/ header file located in the include directory
314 for the declaration of the structure.
318 <sect1>Display lists<p>
320 A major feature of the Atari graphics chip "ANTIC" is to
321 process instructions for the display generation.
322 cc65 supports constructing these display lists by offering defines
323 for the instructions. In conjunction with the "void"-variable extension
324 of cc65, display lists can be created quite comfortable:
328 unsigned char ScreenMemory[100];
335 DL_LMS(DL_CHR20x8x2),
345 POKEW(560,(unsigned int)&DisplayList); // SDLSTL
349 Please inspect the <tt/_antic.h/ header file to detemine the supported
350 instruction names. Modifiers on instructions can be nested without need
353 <tt/DL_LMS(DL_HSCROL(DL_VSCROL(DL_DLI(DL_MAP80x4x2))))/
355 Please mind that ANTIC has memory alignment requirements for "player
356 missile graphics"-data, font data, display lists and screen memory. Creation
357 of a special linker configuration with appropriate aligned segments and
358 switching to that segment in the c-code is usually neccessary. A more memory
359 hungry solution consists in using the "<tt/posix_memalign()/" function in
360 conjunction with copying your data to the allocated memory.
362 <sect1>Character mapping<p>
364 The Atari has two representations for characters:
366 <item> ATASCII is character mapping which is similar to ASCII and used
367 by the CIO system of the OS. This is the default mapping of cc65 when
368 producing code for the atari target.
369 <item> The internal/screen mapping represents the real value of the
370 screen ram when showing a character.
373 For direct memory access (simplicity and speed) enabling the internal
374 mapping can be useful. This can be achieved by including the
375 "<tt/atari_screen_charmap.h/" header.
377 A word of caution: Since the <tt/0x00/ character has to be mapped in an
378 incompatible way to the C-standard, the usage of string functions in
379 conjunction with internal character mapped strings delivers unexpected
380 results regarding the string length. The end of strings are detected where
381 you may not expect them (too early or (much) too late). Internal mapped
382 strings typically support the "<tt/mem...()/" functions.
384 <em>For assembler sources the macro "<tt/scrcode/" from the "<tt/atari.mac/"
385 package delivers the same feature.</em>
387 You can switch back to the ATASCII mapping by including
388 "<tt/atari_atascii_charmap.h/".
390 A final note: Since cc65 has currently some difficulties with string merging
391 under different mappings, defining remapped strings works only flawlessly
392 with static array initialization:
395 #include <atari_screen_charmap.h>
396 char pcScreenMappingString[] = "Hello Atari!";
398 #include <atari_atascii_charmap.h>
399 char pcAtasciiMappingString[] = "Hello Atari!";
402 delivers correct results, while
405 #include <atari_screen_charmap.h>
406 char* pcScreenMappingString = "Hello Atari!";
408 #include <atari_atascii_charmap.h>
409 char* pcAtasciiMappingString = "Hello Atari!";
415 <sect>Loadable drivers<p>
417 The names in the parentheses denote the symbols to be used for static linking of the drivers.
420 <sect1>Graphics drivers<p>
422 <table><tabular ca="rrrr">
423 <tt/atari/|<tt/atarixl/|screen resolution|display pages@<hline>
424 <tt/atr3.tgi (atr3_tgi)/|<tt/atrx3.tgi (atrx3_tgi)/|40x24x4 (CIO mode 3, ANTIC mode 8)|1@
425 <tt/atr4.tgi (atr4_tgi)/|<tt/atrx4.tgi (atrx4_tgi)/|80x48x2 (CIO mode 4, ANTIC mode 9)|1@
426 <tt/atr5.tgi (atr5_tgi)/|<tt/atrx5.tgi (atrx5_tgi)/|80x48x4 (CIO mode 5, ANTIC mode A)|1@
427 <tt/atr6.tgi (atr6_tgi)/|<tt/atrx6.tgi (atrx6_tgi)/|160x96x2 (CIO mode 6, ANTIC mode B)|1@
428 <tt/atr7.tgi (atr7_tgi)/|<tt/atrx7.tgi (atrx7_tgi)/|160x96x4 (CIO mode 7, ANTIC mode D)|1@
429 <tt/atr8.tgi (atr8_tgi)/|<tt/atrx8.tgi (atrx8_tgi)/|320x192x2 (CIO mode 8, ANTIC mode F)|1@
430 <tt/atr8p2.tgi (atr8p2_tgi)/|<tt/atrx8p2.tgi (atrx8p2_tgi)/|320x192x2 (CIO mode 8, ANTIC mode F)|2@
431 <tt/atr9.tgi (atr9_tgi)/|<tt/atrx9.tgi (atrx9_tgi)/|80x192x16b (CIO mode 9, ANTIC mode F, GTIA mode $40)|1@
432 <tt/atr9p2.tgi (atr9p2_tgi)/|<tt/atrx9p2.tgi (atrx9p2_tgi)/|80x192x16b (CIO mode 9, ANTIC mode F, GTIA mode $40)|2@
433 <tt/atr10.tgi (atr10_tgi)/|<tt/atrx10.tgi (atrx10_tgi)/|80x192x9 (CIO mode 10, ANTIC mode F, GTIA mode $80)|1@
434 <tt/atr10p2.tgi (atr10p2_tgi)/|<tt/atrx10p2.tgi (atrx10p2_tgi)/|80x192x9 (CIO mode 10, ANTIC mode F, GTIA mode $80)|2@
435 <tt/atr11.tgi (atr11_tgi)/|<tt/atrx11.tgi (atrx11_tgi)/|80x192x16h (CIO mode 11, ANTIC mode F, GTIA mode $C0)|1@
436 <tt/atr14.tgi (atr14_tgi)/|<tt/atrx14.tgi (atrx14_tgi)/|160x192x2 (CIO mode 14, ANTIC mode C)|1@
437 <tt/atr15.tgi (atr15_tgi)/|<tt/atrx15.tgi (atrx15_tgi)/|160x192x4 (CIO mode 15, ANTIC mode E)|1@
438 <tt/atr15p2.tgi (atr15p2_tgi)/|<tt/atrx15p2.tgi (atrx15p2_tgi)/|160x192x4 (CIO mode 15, ANTIC mode E)|2
440 <!-- <caption>bla bla -->
444 Many graphics modes require more memory than the text screen which is
445 in effect when the program starts up. Therefore the programmer has to
446 tell the program beforehand the memory requirements of the graphics
447 modes the program intends to use.
449 On the <tt/atari/ target his can be done by using the __RESERVED_MEMORY__
450 linker config variable. The number specified there describes the number
451 of bytes to subtract from the top of available memory as seen from the
452 runtime library. This memory is then used by the screen buffer.
454 On the <tt/atarixl/ target the screen memory resides below the program
455 load address. In order to reserve memory for a graphics mode, one
456 simply uses a higher program load address. There are restrictions on
457 selectable load addresses,
458 see <ref name="Selecting a good program load address" id="loadaddr">.
460 The numbers for the different graphics modes presented below should
461 only be seen as a rule of thumb. Since the screen buffer memory needs
462 to start at specific boundaries, the numbers depend on the current top
464 The following numbers were determined by a BASIC program.
468 graphics mode|reserved memory@<hline>
502 <caption>reserved memory required for different graphics modes
505 The values of "1" are needed because the graphics command crashes if
506 it doesn't have at least one byte available. This seems to be a bug of
509 Default drivers: <tt/atr8.tgi (atr8_tgi)/ and <tt/atrx8.tgi (atrx8_tgi)/.
511 <sect1>Extended memory drivers<p>
513 Currently there is only one extended memory driver. It manages the second 64K of a 130XE.
517 <tt/atari/|<tt/atarixl/@<hline>
518 <tt/atr130.emd (atr130_emd)/|<tt/atrx130.emd (atrx130_emd)/
522 <sect1>Joystick drivers<p>
524 Currently there are two joystick drivers available:
528 <tt/atari/|<tt/atarixl/|description@<hline>
529 <tt/atrstd.joy (atrstd_joy)/|<tt/atrxstd.joy (atrxstd_joy)/|Supports up to two/four standard joysticks connected to the joystick ports of the Atari. (Four on the pre-XL systems, two on XL or newer.)@
530 <tt/atrmj8.joy (atrmj8_joy)/|<tt/atrxmj8.joy (atrxmj8_joy)/|Supports up to eight standard joysticks connected to a MultiJoy adapter.
534 Default drivers: <tt/atrstd.joy (atrstd_joy)/ and <tt/atrxstd.joy (atrxstd_joy)/.
536 <sect1>Mouse drivers<p>
538 Currently there are five mouse drivers available:
542 <tt/atari/|<tt/atarixl/|description@<hline>
543 <tt/atrjoy.mou (atrjoy_mou)/|<tt/atrxjoy.mou (atrxjoy_mou)/|Supports a mouse emulated by a standard joystick.@
544 <tt/atrst.mou (atrst_mou)/|<tt/atrxst.mou (atrxst_mou)/|Supports an Atari ST mouse.@
545 <tt/atrami.mou (atrami_mou)/|<tt/atrxami.mou (atrxami_mou)/|Supports an Amiga mouse.@
546 <tt/atrtrk.mou (atrtrk_mou)/|<tt/atrxtrk.mou (atrxtrk_mou)/|Supports an Atari trakball.@
547 <tt/atrtt.mou (atrtt_mou)/|<tt/atrxtt.mou (atrxtt_mou)/|Supports an Atari touch tablet.
551 All mouse devices connect to joystick port #0.
553 Default drivers: <tt/atrst.mou (atrst_mou)/ and <tt/atrxst.mou (atrxst_mou)/.
555 <sect2>Mouse callbacks<p>
557 There are two mouse callbacks available.
559 The "text mode" callbacks (<tt/mouse_txt_callbacks/) display the mouse cursor as a "diamond" character
560 on the standard "GRAPHICS 0" text mode screen. The mouse cursor character can be changed by an
561 assembly file defining the character by exporting the zeropage symbol <tt/mouse_txt_char/.
562 The default file looks like this:
564 .export mouse_txt_char : zp = 96 ; 'diamond' screen code
567 The "P/M" callbacks (<tt/mouse_pm_callbacks/) use Player-Missile graphics for the mouse cursor.
568 The cursor shape can be changed, too, by an assembly file. Here's the default shape definition:
570 .export mouse_pm_bits
571 .export mouse_pm_height : zeropage
572 .export mouse_pm_hotspot_x : zeropage
573 .export mouse_pm_hotspot_y : zeropage
583 mouse_pm_height = * - mouse_pm_bits
584 ; hot spot is upper left corner
585 mouse_pm_hotspot_x = 0
586 mouse_pm_hotspot_y = 0
589 <tt/mouse_pm_bits/ defines the shape of the cursor, <tt/mouse_pm_height/ defines the number of
590 bytes in <tt/mouse_pm_bits/. <tt/mouse_pm_hotspot_x/ and <tt/mouse_pm_hotspot_y/ define the
591 position in the shape where "the mouse points to". When using this callback page #6 ($600
592 - $6FF) is used for the P/M graphics data and no P/M graphics can otherwise be used
593 by the program. The height of the shape (<tt/mouse_pm_height/)
594 must not exceed 32 lines since the callback routines cannot handle more than 32 lines.
596 The default callbacks definition (<tt/mouse_def_callbacks/) is an alias for the "P/M" callbacks.
598 <sect1>RS232 device drivers<p>
600 Currently there is one RS232 driver. It uses the R: device (therefore
601 an R: driver needs to be installed) and was tested with the 850
606 <tt/atari/|<tt/atarixl/@<hline>
607 <tt/atrrdev.ser (atrrdev_ser)/|<tt/atrxrdev.ser (atrxrdev_ser)/
614 <sect1><tt/atarixl/<#if output="info|latex2e"> limitations</#if><label id="limitations"<p>
617 <item>The display is cleared at program start and at program termination. This is a side
618 effect of relocating the display memory below the program start address.
619 <item>Not all possible CIO and SIO functions are handled by the runtime stub code which banks
620 the ROM in and out. All functions used by the runtime library are handled, though.
621 <item>The <tt/_sys()/ function is not supported.
622 <item>It is not compatible with DOSes or other programs using the memory below the ROM.
625 <sect>DIO implementation<label id="dio"><p>
627 The Atari supports disk drives with either 128 or 256 byte sectors.
628 The first three sectors of any disk are always 128 bytes long though. This is
629 because the system can only boot from 128 bytes sectors.
631 Therefore the DIO read and write functions transfer only 128 bytes
632 for sectors 1 to 3, regardless of the type of diskette.
635 <sect>CONIO implementation<label id="conio"><p>
637 The console I/O is speed optimized therefore support for XEP80 hardware
638 or f80.com software is missing. Of course you may use stdio.h functions.
641 <sect>Technical details<label id="techdetail"><p>
643 <sect1><tt/atari/<#if output="info|latex2e"> details</#if><p>
645 <sect2><#if output="info|latex2e"><tt/atari/ </#if>Load chunks<p>
647 An <tt/atari/ program contains two load chunks.
650 <item>"system check"<label id="syschk">&nl;
651 This load chunk is always loaded at address $2E00, and checks if the system has
652 enough memory to run the program. It also checks if the program start address is not
653 below MEMLO. If any of the checks return false, the loading of the program is aborted.&nl;
654 The contents of this chunk come from the SYSCHKCHNK memory area of the linker config file.
655 <item>main program&nl;
656 This load chunk is loaded at the selected program start address (default $2000) and
657 contains all of the code and data of the program.&nl;
658 The contents of this chunk come from the MAIN memory area of the linker config file.
662 <sect1><tt/atarixl/<#if output="info|latex2e"> details</#if><p>
664 <sect2>General operation<p>
666 The <tt/atarixl/ target banks out the ROM while the program is running in
667 order to make more memory available to the program.
669 The screen memory is by default located at the top of available memory,
670 $BFFF if BASIC is not enabled, $9FFF if BASIC is enabled.
671 Therefore, in order to create a largest possible continuous memory area,
672 the screen memory is moved below the program load address. This gives
673 a memory area from <program load addr> to $CFFF.
675 The startup code installs wrappers for interrupt handlers and ROM routines.
676 When an interrupt or call to a ROM routine happens, the wrappers enable the
677 ROM, call the handler or routine, and disable the ROM again.
679 The "wrapping" of the ROM routines is done by changing the ROM entry
680 point symbols in <tt/atari.inc/ to point to the wrapper functions.
682 For ROM functions which require input or output buffers, the wrappers
683 copy the data as required to buffers in low memory.
685 <sect2><#if output="info|latex2e"><tt/atarixl/ </#if>Load chunks<label id="xlchunks"><p>
687 An <tt/atarixl/ program contains three load chunks.
690 <item>"system check"<label id="syschkxl">&nl;
691 This load chunk is always loaded at address $2E00, and checks if the system is
692 suitable for running the program. It also checks if there is enough room between MEMLO
693 and the program start address to move the text mode screen buffer there. If any of the
694 checks return false, the loading of the program is aborted.&nl;
695 The contents of this chunk come from the SYSCHKCHNK memory area of the linker config file.
696 <item>"shadow RAM prepare"&nl;
697 The second load chunk gets loaded to the selected program load address (default $2400).
698 It moves the screen memory below the program load address, copies the character generator
699 from ROM to its new place in RAM, and copies the parts of the program which reside in
700 high memory below the ROM to their place. The high memory parts are included in this load chunk.&nl;
701 At the beginning of this load chunk there is a .bss area, which is not part of the
702 EXE file. Therefore the on-disk start address of this load chunk will be higher than the
703 selected start address. This .bss area (segment LOWBSS) contains the buffers for the
704 double buffering of ROM input and output data. If you add contents to this segment be aware
705 that the contents won't be zero initialized by the startup code.&nl;
706 The contents of this chunk come from the SRPREPCHNK memory area of the linker config file.
707 <item>main program&nl;
708 This load chunk is loaded just above the LOWBSS segment, replacing the code of
709 the previous load chunk. It contains all remaining code and data sections of the program,
710 including the startup code.&nl;
711 The contents of this chunk come from the RAM memory area of the linker config file.
714 <sect2>Moving screen memory below the program start address<p>
716 When setting a graphics mode, the ROM looks at the RAMTOP location. RAMTOP
717 describes the amount of installed memory in pages (RAMTOP is only one byte).
718 The screen memory and display list are placed immediately below RAMTOP.
720 Now in order to relocate the screen memory to lower memory, the startup code
721 puts a value into RAMTOP which causes the ROM routines to allocate the display
722 memory below the program start address and then it issues a ROM call to setup
723 the regular text mode.
725 <sect2>Selecting a good program load address<label id="loadaddr"><p>
727 Due to the movement of the screen memory below the program start, there are some
728 load addresses which are sub-optimal because they waste memory or prevent a
729 higher resolution graphics mode from being enabled.
731 There are restrictions at which addresses screen memory (display buffer and display
732 list) can be placed. The display buffer cannot cross a 4K boundary and a display
733 list cannot cross a 1K boundary.
735 The startup code takes this into account when moving the screen memory down.
736 If the program start address (aligned to the next lower page boundary) minus
737 the screen buffer size would result in a screen buffer which spans a 4K
738 boundary, the startup code lowers RAMTOP to this 4K boundary.&nl;
739 The size of the screen buffer in text mode is 960 ($3C0) bytes. So, for
740 example, a selected start address of $2300 would span the 4K boundary
741 at $2000. The startup code would adjust the RAMTOP value in such way that
742 the screen memory would be located just below this boundary (at $1C40).
743 This results in the area [$2000-$22FF] being wasted.
744 Additionally, the program might fail to load since the lowest address used
745 by the screen memory could be below MEMLO. (The lowest address used in this
746 example would be at $1C20, where the display list would allocated.)
748 These calculations are performed by the startup code (in the first two
749 load chunks), but the startup code only takes the default 40x24 text mode
750 into account. If the program later wants to load TGI drivers which set
751 a more memory consuming graphics mode, the user has to pick a higher
753 Using higher resolution modes there is a restriction in the ROM that it
754 doesn't expect RAMTOP to be at arbitrary values. The Atari memory modules
755 came only in 8K or 16K sizes, so the ROM expects RAMTOP to only have
756 values in 8K steps. Therefore, when using the highest resolution modes
757 the program start address must be at an 8K boundary.
760 <sect2>Character generator location<label id="chargenloc"><p>
762 The default <tt/atarixl/ linker config file (<tt/atarixl.cfg/) leaves the
763 character generator location at the same address where it is in ROM
764 ($E000). This has the disadvatage to split the upper memory into
765 two parts ([$D800-$DFFF] and
766 [$E400-$FFF9]). For applications which
767 require a large continuous upper memory area, an alternative linker
768 config file (<tt/atarixl-largehimem.cfg/) is provided. It relocates the
769 character generator to $D800, providing a single big upper
770 memory area at [$DC00-$FFF9].
772 With the character generator at a different address than in ROM, the routines
773 which enable and disable the ROM also have to update the chargen pointer.
774 This code is not enabled by default. In order to enable it,
775 uncomment the line which sets CHARGEN_RELOC in <tt/libsrc/atari/Makefile.inc/
776 and recompile the <tt/atarixl/ runtime library.
781 <sect1>Function keys<p>
783 Function keys are mapped to Atari + number key.
786 <sect1>Passing arguments to the program<p>
788 Command line arguments can be passed to <tt/main()/ when the used DOS supports it.
791 <item>Arguments are separated by spaces.
792 <item>Leading and trailing spaces around an argument are ignored.
793 <item>The first argument passed to <tt/main/ is the program name.
794 <item>A maximum number of 16 arguments (including the program name) are
801 The runtime for the Atari uses routines marked as <tt/.INTERRUPTOR/ for
802 interrupt handlers. Such routines must be written as simple machine language
803 subroutines and will be called automatically by the VBI handler code
804 when they are linked into a program. See the discussion of the <tt/.CONDES/
805 feature in the <url url="ca65.html" name="assembler manual">.
807 Please note that on the Atari targets the <tt/.INTERRUPTOR/s are being
808 run in NMI context. The other targets run them in IRQ context.
810 <sect1>Reserving a memory area inside a program<label id="memhole"><p>
812 (This section is primarily applicable to the <tt/atari/ target, but the
813 principles apply to <tt/atatixl/ as well.)
815 The Atari 130XE maps its additional memory into CPU memory in 16K
816 chunks at address $4000 to $7FFF. One might want to
817 prevent this memory area from being used by cc65. Other reasons to
818 prevent the use of some memory area could be to reserve space for the
819 buffers for display lists and screen memory.
821 The Atari executable format allows holes inside a program, e.g. one
822 part loads into $2E00 to $3FFF, going below the reserved
823 memory area (assuming a reserved area from $4000 to
824 $7FFF), and another part loads into $8000 to
827 Each load chunk of the executable starts with a 4 byte header which
828 defines its load address and size. In the following linker config files
829 these headers are named HEADER and SECHDR (for the MEMORY layout), and
830 accordingly NEXEHDR and CHKHDR (for the SEGMENTS layout).
832 <sect2>Low code and high data example<p>
833 Goal: Create an executable with 2 load chunks which doesn't use the
834 memory area from $4000 to $7FFF. The CODE segment of
835 the program should go below $4000 and the DATA and RODATA
836 segments should go above $7FFF.
838 The main problem is that the EXE header generated by the cc65 runtime
839 lib is wrong. It defines a single load chunk with the sizes/addresses
840 of the STARTUP, LOWCODE, ONCE, CODE, RODATA, and DATA segments, in
841 fact, the whole user program (we're disregarding the "system check"
844 The contents of the EXE header come from the EXEHDR and MAINHDR segments.
845 The EXEHDR segment just contains the $FFFF value which is required
846 to be the first bytes of the EXE file.&nl;
847 The MAINHDR are defined in in crt0.s. This cannot be changed without
848 modifying and recompiling the cc65 atari runtime library. Therefore
849 the original contents of this segment must be discarded and be
850 replaced by a user created one. This discarding is done by assigning the
851 MAINHDR segment to the (new introduced) DISCARD memory area. The DISCARD memory area is
852 thrown away in the new linker config file (written to file "").
853 We add a new FSTHDR segment for the chunk header of the first chunk.
855 The user needs to create a customized linker config file which adds
856 new memory areas and segments to hold the new header data for the first load
857 chunk and the header data for the second load chunk. Also an assembly source file
858 needs to be created which defines the contents of the new header data
859 for the two load chunks.
862 This is an example of a modified cc65 Atari linker configuration file
866 __STACKSIZE__: value = $800 type = weak; # 2K stack
867 __RESERVED_MEMORY__: value = $0000, type = weak;
870 STARTADDRESS: default = $2E00;
873 ZP: start = $82, size = $7E, type = rw, define = yes;
875 HEADER: start = $0000, size = $2, file = %O; # first load chunk
877 FSTHDR: start = $0000, size = $4, file = %O; # second load chunk
878 RAMLO: start = %S, size = $4000 - %S, file = %O;
880 DISCARD: start = $4000, size = $4000, file = "";
882 SECHDR: start = $0000, size = $4, file = %O; # second load chunk
883 RAM: start = $8000, size = $3C20, file = %O; # $3C20: matches upper bound $BC1F
886 EXEHDR: load = HEADER, type = ro;
888 MAINHDR: load = DISCARD, type = ro;
890 NEXEHDR: load = FSTHDR, type = ro; # first load chunk
891 STARTUP: load = RAMLO, type = ro, define = yes;
892 LOWCODE: load = RAMLO, type = ro, define = yes, optional = yes;
893 ONCE: load = RAMLO, type = ro, optional = yes;
894 CODE: load = RAMLO, type = ro, define = yes;
896 CHKHDR: load = SECHDR, type = ro; # second load chunk
897 RODATA: load = RAM, type = ro, define = yes;
898 DATA: load = RAM, type = rw, define = yes;
899 BSS: load = RAM, type = bss, define = yes;
901 ZEROPAGE: load = ZP, type = zp;
902 AUTOSTRT: load = RAM, type = ro; # defines program entry point
905 CONDES: segment = ONCE,
907 label = __CONSTRUCTOR_TABLE__,
908 count = __CONSTRUCTOR_COUNT__;
909 CONDES: segment = RODATA,
911 label = __DESTRUCTOR_TABLE__,
912 count = __DESTRUCTOR_COUNT__;
917 A new memory area DISCARD was added.
918 It gets loaded with the contents of the (now unused) MAINHDR segment. But the
919 memory area isn't written to the output file. This way the contents of
920 the MAINHDR segment get discarded.
922 The newly added NEXEHDR segment defines the correct chunk header for the
923 first intended load chunk. It
924 puts the STARTUP, LOWCODE, ONCE, and CODE segments, which are the
925 segments containing only code, into load chunk #1 (RAMLO memory area).
927 The header for the second load chunk comes from the new CHKHDR
928 segment. It puts the RODATA, DATA, BSS, and ZPSAVE segments into load
929 chunk #2 (RAM memory area).
932 The contents of the new NEXEHDR and CHKHDR segments come from this
935 .import __CODE_LOAD__, __BSS_LOAD__, __CODE_SIZE__
936 .import __DATA_LOAD__, __RODATA_LOAD__, __STARTUP_LOAD__
939 .word __STARTUP_LOAD__
940 .word __CODE_LOAD__ + __CODE_SIZE__ - 1
943 .word __RODATA_LOAD__
944 .word __BSS_LOAD__ - 1
949 cl65 -t atari -C split.cfg -o prog.com prog.c split.s
952 <sect2>Low data and high code example<p>
955 Goal: Put RODATA and DATA into low memory and STARTUP, LOWCODE, ONCE,
956 CODE, BSS, ZPSAVE into high memory (split2.cfg):
960 __STACKSIZE__: value = $800 type = weak; # 2K stack
961 __RESERVED_MEMORY__: value = $0000, type = weak;
964 STARTADDRESS: default = $2E00;
967 ZP: start = $82, size = $7E, type = rw, define = yes;
969 HEADER: start = $0000, size = $2, file = %O; # first load chunk
971 FSTHDR: start = $0000, size = $4, file = %O; # second load chunk
972 RAMLO: start = %S, size = $4000 - %S, file = %O;
974 DISCARD: start = $4000, size = $4000, file = "";
976 SECHDR: start = $0000, size = $4, file = %O; # second load chunk
977 RAM: start = $8000, size = $3C20, file = %O; # $3C20: matches upper bound $BC1F
980 EXEHDR: load = HEADER, type = ro; # discarded old EXE header
982 MAINHDR: load = DISCARD, type = ro;
984 NEXEHDR: load = FSTHDR, type = ro; # first load chunk
985 RODATA: load = RAMLO, type = ro, define = yes;
986 DATA: load = RAMLO, type = rw, define = yes;
988 CHKHDR: load = SECHDR, type = ro; # second load chunk
989 STARTUP: load = RAM, type = ro, define = yes;
990 ONCE: load = RAM, type = ro, optional = yes;
991 CODE: load = RAM, type = ro, define = yes;
992 BSS: load = RAM, type = bss, define = yes;
994 ZEROPAGE: load = ZP, type = zp;
995 AUTOSTRT: load = RAM, type = ro; # defines program entry point
998 CONDES: segment = ONCE,
1000 label = __CONSTRUCTOR_TABLE__,
1001 count = __CONSTRUCTOR_COUNT__;
1002 CONDES: segment = RODATA,
1004 label = __DESTRUCTOR_TABLE__,
1005 count = __DESTRUCTOR_COUNT__;
1009 New contents for NEXEHDR and CHKHDR are needed (split2.s):
1011 .import __STARTUP_LOAD__, __BSS_LOAD__, __DATA_SIZE__
1012 .import __DATA_LOAD__, __RODATA_LOAD__
1015 .word __RODATA_LOAD__
1016 .word __DATA_LOAD__ + __DATA_SIZE__ - 1
1019 .word __STARTUP_LOAD__
1020 .word __BSS_LOAD__ - 1
1025 cl65 -t atari -C split2.cfg -o prog.com prog.c split2.s
1028 <sect2>Final note<label id="memhole_final_note"><p>
1030 There are two other memory areas which don't appear directly in the
1031 linker config file. They are the stack and the heap.
1033 The cc65 runtime lib places the stack location at the end of available
1034 memory. This is dynamically set from the MEMTOP system variable at
1035 startup. The heap is located in the area between the end of the BSS
1036 segment and the top of the stack as defined by __STACKSIZE__.
1038 If BSS and/or the stack shouldn't stay at the end of the program,
1039 some parts of the cc65 runtime lib need to be replaced/modified.
1041 common/_heap.s defines the location of the heap and atari/crt0.s
1042 defines the location of the stack by initializing sp.
1045 <sect1>Upgrading from an older cc65 version<p>
1047 If you are using a customized linker config file you might get some errors
1048 regarding the MAINHDR segment. Like this:
1051 ld65: Error: Missing memory area assignment for segment `MAINHDR'
1054 The old "HEADER" memory description contained six bytes: $FFFF
1055 and the first and last memory addess of the program. For the "system
1056 check" load chunk this had to be split into two memory assigments. The
1057 "HEADER" now only contains the $FFFF. The main program's first
1058 and last memory address were moved to a new segment, called "MAINHDR",
1059 which in the new linker config file goes into its own memory area (also
1060 called "MAINHDR").&nl;&nl;
1061 A simple way to adapt your old linker config file is to add the
1062 following line to the "SEGMENTS" section:
1065 MAINHDR: load = HEADER, type = ro;
1070 <sect1>Getting rid of the "system check" load chunk<label id="nosyschk"><p>
1072 If, for some reason, you don't want to include the "system check" load
1073 chunk, you can do so by defining the symbol <tt/__SYSTEM_CHECK__/ when linking the
1074 program. The "system check" chunk doesn't include vital parts of the
1075 program. So if you don't want the system checks, it is save to leave them out.
1076 This is probably mostly interesting for debugging.
1078 When using cl65, you can leave it out with this command line:
1081 cl65 -Wl -D__SYSTEM_CHECK__=1 <arguments>
1084 The value you assign to <tt/__SYSTEM_CHECK_/ doesn't matter. If the
1085 <tt/__SYSTEM_CHECK__/ symbol is defined, the load chunk won't be included.
1090 This software is provided 'as-is', without any expressed or implied
1091 warranty. In no event will the authors be held liable for any damages
1092 arising from the use of this software.
1094 Permission is granted to anyone to use this software for any purpose,
1095 including commercial applications, and to alter it and redistribute it
1096 freely, subject to the following restrictions:
1099 <item> The origin of this software must not be misrepresented; you must not
1100 claim that you wrote the original software. If you use this software
1101 in a product, an acknowledgment in the product documentation would be
1102 appreciated but is not required.
1103 <item> Altered source versions must be plainly marked as such, and must not
1104 be misrepresented as being the original software.
1105 <item> This notice may not be removed or altered from any source