<title>Atari Lynx specific information for cc65
<author>Karri Kaksonen, <htmlurl url="mailto:karri@sipo.fi" name="karri@sipo.fi">
Ullrich von Bassewitz, <htmlurl url="mailto:uz@cc65.org" name="uz@cc65.org">
-<date>2004-10-14
+<date>2011-04-01
<abstract>
An overview over the Atari Lynx runtime system as it is implemented for the
information.
+<sect>Building your first Hello World application<p>
+
+Here is a small traditional Hello World program for the Atari Lynx.
+
+<tscreen><verb>
+#include <lynx.h>
+#include <tgi.h>
+#include <6502.h>
+extern char lynxtgi[];
+
+void main(void) {
+ tgi_install(&lynxtgi);
+ tgi_init();
+ CLI();
+ while (tgi_busy())
+ ;
+ tgi_clear();
+ tgi_setcolor(COLOR_GREEN);
+ tgi_outtextxy(0, 0, "Hello World");
+ tgi_updatedisplay();
+ while (1)
+ ;
+}
+</verb></tscreen>
+
+The lynx.h contains all kind of system dependent things.
+
+The tgi.h contains the graphics driver functions.
+
+The 6502.h is needed for executing the CLI() command.
+
+As the Atari Lynx does not have ASCII characters available you need to use
+the Tiny Graphics Interface library for producing letters on the screen.
+
+The cc65 compiler suite has a graphics library called "Tiny Graphics
+Interface". This interface has some relocatable code. In order to use this
+in your own program you need to load it at run time.
+
+Unfortunately the Lynx does not have a disk drive from where to load it.
+Therefore you must already load it at compile time. The easiest way is to
+link it in statically.
+
+This relocatable driver is found in <tt>$(CC65_HOME)/tgi/lynx-160-102-16.tgi</tt>.
+Copy it from here.
+
+The name comes from 160 by 102 pixels (The Lynx LCD size), 16 colors.
+
+In order to link in this statically we have to make it back to a source
+file so that we can compile it. The next command will turn the compiled
+driver object file into an assembler source and compile it with the ca65
+assembler.
+
+<tscreen><verb>
+co65 --code-label _lynxtgi lynx-160-102-16.tgi
+ca65 -t lynx lynx-160-102-16.s
+</verb></tscreen>
+
+This will create a linkable object file called lynx-160-102-16.o
+
+Then we need to compile our main file to a linkable object file.
+
+<tscreen><verb>
+cc65 -t lynx main.c
+ca65 -t lynx main.s
+</verb></tscreen>
+
+Finally we have to link them together to produce an executable cart.
+
+<tscreen><verb>
+cl65 -t lynx -o game.lnx main.o lynx-160-102-16.o lynx.lib
+</verb></tscreen>
+
+This will create a bootable cart image called game.lnx
+
+
<sect>Binary format<p>
The standard binary output format generated by the linker for the Lynx target
-is a machine language program with an executable header. It is of course
-possible to change this behaviour by using a modified startup file and linker
-config.
+is a cart image. By specifying the config file lynx-bll.cfg the linker will
+generate BLL download compatible binary files.
+
+It is of course possible to change this behaviour by using a modified startup
+file and linker config.
+
+The bootloader used in the cc65 lynx library uses a very minimal bootloader
+that does not check the cart or show a title screen.
-You can also produce real carts with directory structures and encrypted
-headers by modifying the startup and linker config files. There is a simple
-example archive called <tt/lynx-cart-demo/ in the <htmlurl
-url="ftp://ftp.musoftware.de/pub/uz/cc65/contrib/" name="contrib directory">
-that shows how to create a complete bootable Lynx cart.
+The advantage of this bootloader is that it allows creation of cart images to
+many common formats.
+
+Cart sizes
+<tscreen><verb>
+Block size Rom size Description
+512 bytes 128k Standard old games like Warbirds
+1024 bytes 256k Most common format for homebrew. Also newer games like Lemmings
+2048 bytes 512k Largest games like EOTB
+</verb></tscreen>
<sect>Memory layout<p>
cc65 generated programs with the default setup run with the I/O area and the
-kernal enabled, which gives a usable memory range of $400 - $BE3F.
-All boot ROM entry points may be called directly without additional code.
+kernal enabled, which gives a usable memory range of $200 - $C037.
Special locations:
+<tscreen><verb>
+ 0000 - 00FF Zero page
+ 0100 - 01FF Machine stack
+
+ A058 - C037 Collision buffer
+ C038 - E017 Screen buffer 1
+ E018 - FFF7 Screen buffer 0
+ FFF8 - FFFF Hardware vectors
+</verb></tscreen>
<descrip>
<tag/Text screen/
'?' for all keys down at the same time.
<tag/Stack/
- The C runtime stack is located at $BE3F and growing downwards.
+ The C runtime stack is located at $C037 (or $A057 if collision
+ detection is enabled) and growing downwards.
<tag/Heap/
The C heap is located at the end of the program and grows towards the C
runtime stack.
+ <tag/Screen/
+ The collision detection screen is at $A058 if it is enabled. The
+ double buffered screens are at $C038 and $E018.
+
</descrip><p>
<sect1>Lynx specific functions<p>
<itemize>
-<item>lynx_change_framerate
<item>lynx_eeprom_erase
<item>lynx_eeprom_read
<item>lynx_eeprom_write
+<item>lynx_eeread
+<item>lynx_eewrite
+<item>lynx_exec
+<item>lynx_load
</itemize>
See the documentation for the <htmlurl url="co65.html" name="co65 utility">
for information on how to do that.
-The TGI driver is implemented as a dual buffering device. To use it as a
-single-buffer device set draw page and view page to the same value 0 or 1;
+The TGI driver is implemented as an interrupt driven dual buffering device.
+To use it as a single-buffer device set draw page and view page to the same
+value 0 or 1;
The TGI driver has a few Lynx-specific extensions.
will wait for the next VBL interrupt and set the draw buffer to the
view buffer. The draw buffer is also changed to (drawbuffer xor 1).
+You can also enable or disable collision detection by a call to
+tgi_setcollisiondetection(active) or tgi_ioctl(5, active). The collision
+result is located before the sprite structure by default in this driver.
+
+In order to reserve memory for the collision detection buffer you need to
+specify lynx-coll.cfg as the configuration file to the linker.
+
<sect1>Extended memory drivers<p>
No extended memory drivers are currently available for the Lynx.
the <htmlurl url="co65.html" name="co65 utility"> for information on how to do
that.
-The joystick will check to see if the screen is flipped or not in the install
-routine and adapt itself to the currect state.
-
<sect1>Mouse drivers<p>
No mouse drivers are currently available for the Lynx.
<sect1>RS232 device drivers<p>
-No serial drivers are currently available for the Lynx.
+<descrip>
+
+ The ComLynx port has Tx and Rx wired together. Every byte is sent
+ to all connected Lynxes. Only one Lynx can send at a time. There is no
+ protocol created for communication. You are on your own.
+
+ If the Lynx returns framing error then it is likely that another Lynx is
+ sending data at the same time.
+
+ The Lynx can also send a break and receive a break. The Lynx break is
+ recognized if the bit is down for 24 bit cycles or more.
+
+ To send a break you just set the break bit. The length of the break depends
+ on how long this bit is down.
+
+ The driver supports the baudrates:
+ <itemize>
+ <item>62500
+ <item>31250
+ <item>9600
+ <item>7200
+ <item>4800
+ <item>3600
+ <item>2400
+ <item>1800
+ <item>1200
+ <item>600
+ <item>300
+ <item>150
+ <item>134.5
+ <item>110
+ <item>75
+ </itemize>
+ The parity bit supports MARK and SPACE. It also supports EVEN and ODD parity
+ but the parity bit is included in the calculation. Most of us don't want it
+ this way. But there is nothing we can do about it.
+
+ The Lynx hardware will always check parity on incoming traffic. Currently
+ the driver cannot receive data from standard PC's due to this parity bug.
+ For working with Lynx to Lynx communication use EVEN parity.
+
+ To send data to standard PC's use MARK or SPACE as parity setting.
+
+ There is always only one stop bit. And the data length is always 8 bits.
+
+ We have no handshaking available. Even software handshake is impossible
+ as ComLynx has only one wire for the data.
+
+ Both transmit and receive are interrupt driven.
+</descrip><p>
<sect>Limitations<p>
-<sect>Other hints<p>
+<sect>Cart access<p>
At this point in time there is no support for the cart filesystem yet. I have
a <tt/lynx-cart-demo/ example project that uses an interrupt driven display,
</enum>
</article>
-
-
-