This commit was generated by cvs2svn to compensate for changes in r2,

which included commits to RCS files with non-trunk default branches.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2000-05-28 13:40:48 +00:00
parent 579491e8a4
commit 53dd513176
847 changed files with 91345 additions and 0 deletions

2
.cvsignore Normal file
View File

@ -0,0 +1,2 @@
dist
test

11
doc/BUGS Normal file
View File

@ -0,0 +1,11 @@
List of known bugs that will not get fixed in the near future:
* The compiler does not detect if part of an expression evaluated
with && or || is constant. Since the expression evaluation is also
used for the preprocessor, this defeats the use of
#if defined(x) && defined(y)
* Initialization of local variables with compound data types is not
possible.

62
doc/CREDITS Normal file
View File

@ -0,0 +1,62 @@
Many special thanks go to the guy who started it all:
John R.Dunning.
Without his great work, there would not be a single freeware C crosscompiler
for the 6502 out there. He built the grounds for this cc65 and some other cc65
implementations and a lot of his code is still in the current compiler.
More special thanks to:
* Keith W. Gerdes <kwg@freebird.ghofn.org>
Without his outstanding help, the assembler/compiler wouldn't be, what it
is now. He helped with suggestions, bug reports and even kicked me here
and then, when I started to get too lazy:-)
* Tennessee Carmel-Veilleux <veilleux@ameth.org>
Tennessee worked on the NES port.
* Kevin Ruland <kevin@rodin.wustl.edu>
Kevin did the Apple 2 port and found at least one serious error in the
C library while doing so.
* Christian Groessler <cpg@aladdin.de>
Christian sent me several fixes for 64 bit machines.
* Sidney Cadot <sidney@ch.twi.tudelft.nl>
Sidney rewrote the random number generator.
* Maciej Witkowiak <ytm@friko.onet.pl>
Maciej is responsible for the GEOS support.
Thanks to
Mark Nasgowitz <MNasgowitz@NAZdesign.com>
da Blondie <db@tvnet.hu>
Jari Tuominen <jer64@kolumbus.fi>
MagerValp <magervalp@cling.gu.se>
Ingo Korb <unseen@gmx.net>
Robert R. Wal <rrw@reptile.eu.org>
Jesse Beach <agmorion@erols.com>
Chris Ward <chris.ward@freenet.co.uk>
Eric Au <eric_au@hotmail.com>
Tim Vanderhoek <hoek@FreeBSD.org>
Bill Craig <craigw@gusun.georgetown.edu>
for bug reports and suggestions.
This list is probably incomplete. So, if you think you should be mentioned
here, but cannot find yourself, please drop me a mail.

152
doc/ar65.txt Normal file
View File

@ -0,0 +1,152 @@
ar65
An Archiver for Object Files Generated by ca65
(C) Copyright 1998-1999 Ullrich von Bassewitz
(uz@musoftware.de)
Contents
--------
1. Overview
2. Usage
3. Bugs/Feedback
4. Copyright
1. Overview
-----------
ar65 is a replacement for the libr65 archiver that was part of the cc65 C
compiler suite developed by John R. Dunning. libr65 had some problems and
the copyright does not permit some things which I wanted to be possible,
so I decided to write a completely new assembler/linker/archiver suite
for the cc65 compiler. ar65 is part of this suite.
2. Usage
--------
The archiver is called as follows:
Usage: ar65 <operation> lib file|module ...
Operation is one of:
a Add modules
d Delete modules
l List library contents
x Extract modules
X Print the archiver version
You may add modules to a library using the `a' command. If the library
does not exist, it is created (and a warning message is printed which you
may ignore if creation of the library was your intention). You may
specify any number of modules on the command line following the library.
If a module with the same name exists in the library, it is replaced by
the new one. The archiver prints a warning, if the module in the library
has a newer timestamp than the one to add.
Here's an example:
ar65 a mysubs.lib sub1.o sub2.o
This will add two modules to the library `mysubs.lib' creating the
library if necessary. If the library contains modules named sub1.o or
sub2.o, they are replaced by the new ones.
Modules names in the library are stored without the path, so, using
ar65 a mysubs.lib ofiles/sub1.o ofiles/sub2.o
will add two modules named `sub1.o' and `sub2.o' to the library.
Deleting modules from a library is done with the `d' command. You may not
give a path when naming the modules.
Example:
ar65 d mysubs.lib sub1.o
This will delete the module named `sub1.o' from the library, printing an
error if the library does not contain that module.
The `l' command prints a list of all modules in the library. Any module
names on the command line are ignored.
Example:
ar65 l mysubs.lib
Using the `x' command, you may extract modules from the library. The
modules named on the command line are extracted from the library and put
into the current directory.
Note: Because of the indexing done by the archiver, the modules may have
a changed binary layout, that is, a binary compare with the old module
(before importing it into the library) may yield differences. The
extracted modules are accepted by the linker and archiver, however, so
this is not a problem.
Example for extracting a module from the library:
ar65 x mysubs.lib sub1.o
The `V' command prints the version number of the assembler. If you send
any suggestions or bugfixes, please include your version number.
In addition to these operations, the archiver will check for, and warn
about duplicate external symbols in the library, every time when an
operation does update the library. This is only a warning, the linker
will ignore one of the duplicate symbols (which one is unspecified).
3. Bugs/Feedback
----------------
If you have problems using the archiver, if you find any bugs, or if
you're doing something interesting with it, I would be glad to hear from
you. Feel free to contact me by email (uz@musoftware.de).
4. Copyright
------------
ar65 (and all cc65 binutils) are (C) Copyright 1998 Ullrich von Bassewitz.
For usage of the binaries and/or sources the following conditions do
apply:
This software is provided 'as-is', without any expressed or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

1903
doc/ca65.txt Normal file

File diff suppressed because it is too large Load Diff

600
doc/cc65.txt Normal file
View File

@ -0,0 +1,600 @@
cc65
A C Compiler for 6502 Systems
(C) Copyright 1989 John R. Dunning
(C) Copyright 1998-2000 Ullrich von Bassewitz
(uz@musoftware.de)
Contents
--------
1. Overview
2. Usage
3. Input and output
4. Differences to the ISO standard
5. Extensions
6. Predefined macros
7. #pragmas
8. Bugs/Feedback
9. Copyright
1. Overview
-----------
cc65 was originally a C compiler for the Atari 8-bit machines written by
John R. Dunning. In prior releases I've described the compiler by listing
up the changes made by me. I have made many more changes in the meantime
(and rewritten major parts of the compiler), so I will no longer do that,
since the list would be too large and of no use to anyone. Instead I will
describe the compiler in respect to the ANSI/ISO C standard. In fact, I'm
planning a complete rewrite (that is, a complete new compiler) for the
next release, since there are too many limitations in the current code,
and removing these limitations would mean a rewrite of many more parts of
the compiler.
There is a separate document named "library.txt" that covers the library
available for the compiler. If you know C and are interested in doing
actual programming, the library documentation is probably of much more use
than this document.
If you need some hints for getting the best code out of the compiler, you
may have a look at "coding.txt" which covers some code generation issues.
2. Usage
--------
The compiler translates C files into files containing assembler code that
may be translated by the ca65 macroassembler (for more information about
the assembler, have a look at ca65.txt).
The compiler may be called as follows:
Usage: cc65 [options] file
-d Debug mode
-g Add debug info to object files
-h Print this help
-j Default characters are signed
-o name Name the output file
-s Print some statistics
-tx Set target system x
-v Verbose mode
-A Strict ANSI mode
-Cl Make local variables static
-Dsym[=defn] Define a symbol
-I path Set include directory
-O Optimize code
-Oi Optimize code, inline more code
-Or Enable register variables
-Os Inline some known functions
-T Include source as comment
-V Print version number
-W Suppress warnings
The -A option disables any compiler exensions. Have a look at section 5
for a discussion of compiler extensions. In addition, the macro
__STRICT_ANSI__
is defined, when compiling with -A.
-d enables debug mode, something that should not be needed for mere
mortals:-)
-g will cause the compiler to insert a .DEBUGINFO command into the
generated assembler code. This will cause the assembler to include all
symbols in a special section in the object file.
-h and -s print some statistics, nothing spectacular.
Using -j you can make the default characters signed. Since the 6502 has
no provisions for sign extending characters (which is needed on almost
any load operation), this will make the code larger and slower. A better
way is to declare characters explicitly as "signed" if needed. You can
also use "#pragma signedchars" for better control of this option (see
section 7).
The -t option is used to set the target system. The target system
determines things like the character set that is used for strings and
character constants. The following target systems are supported:
none
c64
c128
ace (no library support)
plus4
cbm610
pet (all CBM PET systems except the 2001)
nes (Nintendo Entertainment System)
apple2
geos
Using -v, the compiler will be somewhat more verbose if errors or warnings
are encountered.
-Cl will use static storage for local variables instead of storage on the
stack. Since the stack is emulated in software, this gives shorter and
usually faster code, but the code is no longer reentrant. The difference
between -Cl and declaring local variables as static yourself is, that
initializer code is executed each time, the function is entered. So when
using
void f (void)
{
unsigned a = 1;
...
}
the variable a will always have the value 1 when entering the function and
using -Cl, while in
void f (void)
{
static unsigned a = 1;
....
}
the variable a will have the value 1 only the first time, the function is
entered, and will keep the old value from one call of the function to the
next.
You may also use #pragma staticlocals to change this setting in your
sources (see section 7).
-I sets the directory where the compiler searches for include files. You
may use -I multiple times to add more than one directory to the search
list.
-O will enable an optimizer run over the produced code. Using -Oi, the
code generator will inline some code where otherwise a runtime functions
would have been called, even if the generated code is larger. This will
not only remove the overhead for a function call, but will make the code
visible for the optimizer.
-Or will make the compiler honor the "register" keyword. Local variables
may be placed in registers (which are actually zero page locations).
There is some overhead involved with register variables, since the old
contents of the registers must be saved and restored. In addition, the
current implementation does not make good use of register variables, so
using -Or may make your program even slower and larger. Use with care!
Using -Os will force the compiler to inline some known functions from the
C library like strlen. Note: This has two consequences:
* You may not use names of standard C functions in your own code. If
you do that, your program is not standard compliant anyway, but
using -Os will actually break things.
* The inlined string and memory functions will not handle strings or
memory areas larger than 255 bytes. Similar, the inlined is..()
functions will not work with values outside char range.
It is possible to concatenate the modifiers for -O. For example, to
enable register variables and inlining of known functions, you may use
-Ors.
-T will include the source code as comments in the generated code. This is
normally not needed.
-V prints the version number of the compiler. When submitting a bug
report, please include the operating system you're using, and the compiler
version.
The -W switch suppresses any warnings generated by the compiler. Since any
source file may be written in a manner that it will not produce compiler
warnings, using this option is usually not a good idea.
3. Input and output
-------------------
The compiler will accept one C file per invocation and create a file with
the same base name, but with the extension replaced by ".s". The output
file contains assembler code suitable for the use with the ca65 macro
assembler.
In addition to the paths named in the -I option on the command line, the
directory named in the environment variable CC65_INC is added to the
search path for include files on startup.
4. Differences to the ISO standard
----------------------------------
Here is a list of differences between the language, the compiler accepts,
and the one defined by the ISO standard:
* The compiler allows single line comments that start with //. This
feature is disabled in strict ANSI mode.
* The compiler allows unnamed parameters in parameter lists. The
compiler will not issue warnings about unused parameters that don't
have a name. This feature is disabled in strict ANSI mode.
* The compiler has some additional keywords:
asm, __asm__, fastcall, __fastcall__, __AX__, __EAX__, __func__
The keywords without the underlines are disabled in strict ANSI mode.
* The "const" modifier is available, but has no effect.
* The datatypes "float" and "double" are not available.
* The compiler does not support bit fields.
* Initialization of local variables is only possible for scalar data
types (that is, not for arrays and structs).
* Because of the "wrong" order of the parameters on the stack, there is
an additional macro needed to access parameters in a variable
parameter list in a C function.
* The compiler has only one symbol table. Because of that, it's not
possible to use the name of a local variable in a nested block in the
same function (global and local names are distinct, however).
+ The preprocessor does not understand the "defined" keyword in
expressions evaluated in #if statements.
* Functions may not return structs, struct assignment is not possible.
* The size of any struct referenced via a pointer may not exceed 256
bytes (this is because the Y register is used as index).
* In a function, the size of the parameters plus the size of all local
variables may not exceed 256 bytes (in fact, the limit may be even less
depeding on the complexity of your expressions).
* Part of the C library is available only with fastcall calling
conventions (see below). This means, that you may not mix pointers to
those functions with pointers to user written functions.
There may be some more minor differences, I'm currently not aware off. The
biggest problems are the missing const and float data types. With both
these things in mind, you should be able to write fairly portable code.
5. Extensions
-------------
This cc65 version has some extensions to the ISO C standard.
* The compiler allows // comments (like in C++ and in the proposed C9x
standard). This feature is disabled by -A.
* The compiler allows to insert assembler statements into the output
file. The syntax is
asm (<string literal>) ;
or
__asm__ (<string literal>) ;
The first form is in the user namespace and is disabled if the -A
switch is given.
The given string is inserted literally into the output file, and a
newline is appended. The statements in this string are not checked by
the compiler, so be careful!
The asm statement may be used inside a function and on global file
level.
* There is a special calling convention named "fastcall". This calling
convention is currently only usable for functions written in
assembler. The syntax for a function declaration using fastcall is
<return type> fastcall <function name> (<parameter list>)
or
<return type> __fastcall__ <function name> (<parameter list>)
An example would be
void __fastcall__ f (unsigned char c)
The first form of the fastcall keyword is in the user namespace and is
therefore disabled in strict ANSI mode.
For functions declared as fastcall, the rightmost parameter is not
pushed on the stack but left in the primary register when the function
is called. This will reduce the cost when calling assembler functions
significantly, especially when the function itself is rather small.
BEWARE: You must not declare C functions as fastcall! This will not
work for now and is not checked by the assembler, so you will get
wrong code.
* There are two pseudo variables named __AX__ and __EAX__. Both refer to
the primary register that is used by the compiler to evaluate
expressions or return function results. __AX__ is of type unsigned int
and __EAX__ of type long unsigned int respectively. The pseudo
variables may be used as lvalue and rvalue as every other variable.
They are most useful together with short sequences of assembler code.
For example, the macro
#define hi(x) (__AX__=(x),asm("\ttxa\n\tldx\t#$00",__AX__)
will give the high byte of any unsigned value.
* Inside a function, the identifier __func__ gives the name of the
current function as a string. Outside of functions, __func__ is
undefined.
Example:
#define PRINT_DEBUG(s) printf ("%s: %s\n", __func__, s);
The macro will print the name of the current function plus a given
string.
6. Predefined macros
--------------------
The compiler defines several macros at startup:
__CC65__ This macro is always defined. Its value is the version
number of the compiler in hex. Version 2.0.1 of the
compiler will have this macro defined as 0x0201.
__CBM__ This macro is defined if the target system is one of the
CBM targets.
__C64__ This macro is defined if the target is the c64 (-t c64).
__C128__ This macro is defined if the target is the c128 (-t c128).
__PLUS4__ This macro is defined if the target is the plus/4
(-t plus4).
__CBM610__ This macro is defined if the target is one of the CBM
600/700 family of computers (called B series in the US).
__PET__ This macro is defined if the target is the PET family of
computers (-t pet).
__NES__ This macro is defined if the target is the Nintendo
Entertainment System (-t nes).
__ATARI__ This macro is defined if the target is one of the Atari
computers (400/800/130XL/800XL). Note that there is no
runtime and C library support for atari systems.
__ACE__ This macro is defined if the target is Bruce Craigs ACE
operating system. Note that there is no longer runtime
and library support for ACE.
__APPLE2__ This macro is defined if the target is the Apple ][
(-t apple2).
__GEOS__ This macro is defined if you are compiling for the GEOS
system (-t geos).
__FILE__ This macro expands to a string containing the name of
the C source file.
__LINE__ This macro expands to the current line number.
__STRICT_ANSI__ This macro is defined to 1 if the -A compiler option was
given, and undefined otherwise.
__OPT__ Is defined if the compiler was called with the -O command
line option.
__OPT_i__ Is defined if the compiler was called with the -Oi command
line option.
__OPT_r__ Is defined if the compiler was called with the -Or command
line option.
__OPT_s__ Is defined if the compiler was called with the -Os command
line option.
7. #pragmas
-----------
The compiler understands some pragmas that may be used to change code
generation and other stuff.
#pragma bssseg (<name>)
This pragma changes the name used for the BSS segment (the BSS segment
is used to store uninitialized data). The argument is a string enclosed
in double quotes.
Note: The default linker configuration file does only map the standard
segments. If you use other segments, you have to create a new linker
configuration file.
Beware: The startup code will zero only the default BSS segment. If you
use another BSS segment, you have to do that yourself, otherwise
uninitialized variables do not have the value zero.
Example:
#pragma bssseg ("MyBSS")
#pragma codeseg (<name>)
This pragma changes the name used for the CODE segment (the CODE segment
is used to store executable code). The argument is a string enclosed in
double quotes.
Note: The default linker configuration file does only map the standard
segments. If you use other segments, you have to create a new linker
configuration file.
Example:
#pragma bssseg ("MyCODE")
#pragma dataseg (<name>)
This pragma changes the name used for the DATA segment (the DATA segment
is used to store initialized data). The argument is a string enclosed in
double quotes.
Note: The default linker configuration file does only map the standard
segments. If you use other segments, you have to create a new linker
configuration file.
Example:
#pragma bssseg ("MyDATA")
#pragma rodataseg (<name>)
This pragma changes the name used for the RODATA segment (the RODATA
segment is used to store readonly data). The argument is a string
enclosed in double quotes.
Note: The default linker configuration file does only map the standard
segments. If you use other segments, you have to create a new linker
configuration file.
Example:
#pragma bssseg ("MyRODATA")
#pragma regvaraddr (<const int>)
The compiler does not allow to take the address of register variables.
The regvaraddr pragma changes this. Taking the address of a register
variable is allowed after using this pragma, if the argument is not
zero. Using an argument of zero changes back to the default behaviour.
Beware: The C standard does not allow taking the address of a variable
declared as register. So your programs become non-portable if you use
this pragma. In addition, your program may not work. This is usually the
case if a subroutine is called with the address of a register variable,
and this subroutine (or a subroutine called from there) uses itself
register variables. So be careful with this #pragma.
Example:
#pragma regvaraddr(1) /* Allow taking the address
* of register variables
*/
#pragma signedchars (<const int>)
Changed the signedness of the default character type. If the argument
is not zero, default characters are signed, otherwise characters are
unsigned. The compiler default is to make characters unsigned since this
creates a lot better code.
#pragma staticlocals (<const int>)
Use variables in the bss segment instead of variables on the stack. This
pragma changes the default set by the compiler option -Cl. If the argument
is not zero, local variables are allocated in the BSS segment, leading to
shorter and in most cases faster, but non-reentrant code.
#pragma zpsym (<name>)
Tell the compiler that the - previously as external declared - symbol with
the given name is a zero page symbol (usually from an assembler file).
The compiler will create a matching import declaration for the assembler.
Example:
extern int foo;
#pragma zpsym ("foo"); /* foo is in the zeropage */
8. Bugs/Feedback
----------------
If you have problems using the compiler, if you find any bugs, or if
you're doing something interesting with the compiler, I would be glad to
hear from you. Feel free to contact me by email (uz@musoftware.de).
9. Copyright
------------
This is the original compiler copyright:
--------------------------------------------------------------------------
-*- Mode: Text -*-
This is the copyright notice for RA65, LINK65, LIBR65, and other
Atari 8-bit programs. Said programs are Copyright 1989, by John R.
Dunning. All rights reserved, with the following exceptions:
Anyone may copy or redistribute these programs, provided that:
1: You don't charge anything for the copy. It is permissable to
charge a nominal fee for media, etc.
2: All source code and documentation for the programs is made
available as part of the distribution.
3: This copyright notice is preserved verbatim, and included in
the distribution.
You are allowed to modify these programs, and redistribute the
modified versions, provided that the modifications are clearly noted.
There is NO WARRANTY with this software, it comes as is, and is
distributed in the hope that it may be useful.
This copyright notice applies to any program which contains
this text, or the refers to this file.
This copyright notice is based on the one published by the Free
Software Foundation, sometimes known as the GNU project. The idea
is the same as theirs, ie the software is free, and is intended to
stay that way. Everybody has the right to copy, modify, and re-
distribute this software. Nobody has the right to prevent anyone
else from copying, modifying or redistributing it.
--------------------------------------------------------------------------
In acknowledgment of this copyright, I will place my own changes to the
compiler under the same copyright. Please note however, that the library
and all binutils are covered by another copyright, and that I'm planning
to do a complete rewrite of the compiler, after which the compiler
copyright will also change.
For the list of changes requested by this copyright see newvers.txt.

183
doc/cl65.txt Normal file
View File

@ -0,0 +1,183 @@
cl65
Compile and link utility for cc65
(C) Copyright 1999 Ullrich von Bassewitz
(uz@musoftware.de)
Contents
--------
1. Overview
2. Basic Usage
3. More usage
4. Examples
5. Bugs/Feedback
6. Copyright
1. Overview
-----------
cl65 is a frontend for cc65, ca65 and ld65. While you may not use the full
power of the tools when calling them through cl65, most features are
available, and the use of cl65 is much simpler.
2. Usage
--------
The cl65 compile and link utility may be used to compile, assemble and
link files. While the separate tools do just one step, cl65 knows how to
build object files from C files (by calling the compiler, then the
assembler) and other things.
Usage: cl65 [options] file
Options:
-A Strict ANSI mode
-C name Use linker config file
-D sym[=defn] Define a preprocessor symbol
-I path Set an include directory path
-Ln name Create a VICE label file
-O Optimize code
-Oi Optimize code, inline functions
-Or Optimize code, honour the register keyword
-Os Optimize code, inline known C funtions
-S Compile but don't assemble and link
-V Print the version number
-W Suppress warnings
-c Compiler and assemble but don't link
-d Debug mode
-g Add debug info
-h Help (this text)
-m name Create a map file
-o name Name the output file
-t system Set the target system
-v Verbose mode
-vm Verbose map file
Most of the options have the same meaning than the corresponding compiler,
assembler or linker option. If an option is available for more than one
of the tools, it is set for all tools, where it is available. One example
for this is -v: The compiler, the assembler and the linker are all called
with the -v switch.
There are a few remaining options that control the behaviour of cl65:
The -S option forces cl65 to stop after the assembly step. This means that
C files are translated into assembler files, but nothing more is done.
Assembler files, object files and libraries given on the command line are
ignored.
The -c options forces cl65 to stop after the assembly step. This means
that C and assembler files given on the command line are translated into
object files, but there is no link step, and object files and libraries
given on the command line are ignored.
The -o option is used for the target name in the final step. This causes
problems, if the linker will not be called, and there are several input
files on the command line. In this case, the name given with -o will be
used for all of them, which makes the option pretty useless. You shouldn't
use -o when more than one output file is created.
The default for the -t option is different from the compiler and linker in
the case that the option is missing: While the compiler and linker will
use the "none" system settings by default, cl65 will use the C64 as a
target system by default. This was choosen since most people seem to use
cc65 to develop for the C64.
3. More usage
-------------
Since cl65 was created to simplify the use of the cc65 development
package, it tries to be smart about several things.
- If you don't give a target system on the command line, cl65
defaults to the C64.
- When linking, cl65 will supply the names of the startup file and
library for the target system to the linker, so you don't have to do
that.
- If the final step is the linker, and the name of the output file was
not explicitly given, cl65 will use the name of the first input file
without the extension, provided that the name of this file has an
extension. So you don't need to name the executable name in most
cases, just give the name of your "main" file as first input file.
4. Examples
-----------
The morse trainer software, which consists of one C file (morse.c) and one
assembler file (irq.s) will need the following separate steps to compile
into an executable named morse:
cc65 -g -Oi -t c64 morse.c
ca65 -g morse.s
ca65 -g irq.s
ld65 -t c64 -o morse c64.o morse.o irq.o c64.lib
When using cl65, this is simplified to
cl65 -g -Oi morse.c irq.s
As a general rule, you may use cl65 instead of cc65 at most times,
especially in makefiles to build object files directly from C files. Use
.c.o:
cl65 -g -Oi $<
to do this.
5. Bugs/Feedback
----------------
If you have problems using the utility, if you find any bugs, or if you're
doing something interesting with it, I would be glad to hear from you.
Feel free to contact me by email (uz@musoftware.de).
6. Copyright
------------
cl65 is (C) Copyright 1998 Ullrich von Bassewitz. For usage of the
binaries and/or sources the following conditions do apply:
This software is provided 'as-is', without any expressed or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

340
doc/coding.txt Normal file
View File

@ -0,0 +1,340 @@
How to generate the most effective code with cc65.
1. Use prototypes.
This will not only help to find errors between separate modules, it will
also generate better code, since the compiler must not assume that a
variable sized parameter list is in place and must not pass the argument
count to the called function. This will lead to shorter and faster code.
2. Don't declare auto variables in nested function blocks.
Variable declarations in nested blocks are usually a good thing. But with
cc65, there are several drawbacks:
a. The compiler has only one symbol table (there's no true nesting).
This means that your variables must not have the same names as
variables in the enclosing block.
b. Since the compiler generates code in one pass, it must create the
the variables on the stack each time the block is entered and destroy
them when the block is left. This causes a speed penalty and larger
code.
3. Remember that the compiler does not optimize.
The compiler needs hints from you about the code to generate. When
accessing indexed data structures, get a pointer to the element and
use this pointer instead of calculating the index again and again.
If you want to have your loops unrolled, or loop invariant code moved
outside the loop, you have to do that yourself.
4. Longs are slow!
While long support is necessary for some things, it's really, really slow
on the 6502. Remember that any long variable will use 4 bytes of memory,
and any operation works on double the data compared to an int.
5. Use unsigned types wherever possible.
The CPU has no opcodes to handle signed values greater than 8 bit. So
sign extension, test of signedness etc. has to be done by hand. The
code to handle signed operations is usually a bit slower than the same
code for unsigned types.
6. Use chars instead of ints if possible.
While in arithmetic operations, chars are immidiately promoted to ints,
they are passed as chars in parameter lists and are accessed as chars
in variables. The code generated is usually not much smaller, but it
is faster, since accessing chars is faster. For several operations, the
generated code may be better if intermediate results that are known not
to be larger than 8 bit are casted to chars.
When doing
unsigned char a;
...
if ((a & 0x0F) == 0)
the result of the & operator is an int because of the int promotion
rules of the language. So the compare is also done with 16 bits. When
using
unsigned char a;
...
if ((unsigned char)(a & 0x0F) == 0)
the generated code is much shorter, since the operation is done with
8 bits instead of 16.
7. Make the size of your array elements one of 1, 2, 4, 8.
When indexing into an array, the compiler has to calculate the byte
offset into the array, which is the index multiplied by the size of
one element. When doing the multiplication, the compiler will do a
strength reduction, that is, replace the multiplication by a shift
if possible. For the values 2, 4 and 8, there are even more specialized
subroutines available. So, array access is fastest when using one of
these sizes.
8. Expressions are evaluated from left to right.
Since cc65 is not building an explicit expression tree when parsing an
expression, constant subexpressions may not be detected and optimized
properly if you don't help. Look at this example:
#define OFFS 4
int i;
i = i + OFFS + 3;
The expression is parsed from left to right, that means, the compiler sees
'i', and puts it contents into the secondary register. Next is OFFS, which
is constant. The compiler emits code to add a constant to the secondary
register. Same thing again for the constant 3. So the code produced
contains a fetch of 'i', two additions of constants, and a store (into
'i'). Unfortunately, the compiler does not see, that "OFFS + 3" is a
constant for itself, since it does it's evaluation from left to right.
There are some ways to help the compiler to recognize expression like
this:
a. Write "i = OFFS + 3 + i;". Since the first and second operand are
constant, the compiler will evaluate them at compile time reducing the
code to a fetch, one addition (secondary + constant) and one store.
b. Write "i = i + (OFFS + 3)". When seeing the opening parenthesis, the
compiler will start a new expression evaluation for the stuff in the
braces, and since all operands in the subexpression are constant, it
will detect this and reduce the code to one fetch, one addition and
one store.
9. Case labels in a switch statments are checked in source order.
Labels that appear first in a switch statement are tested first. So,
if your switch statement contains labels that are selected most of
the time, put them first in your source code. This will speed up the
code.
10. Use the preincrement and predecrement operators.
The compiler is currently not smart enough to figure out, if the rvalue of
an increment is used or not. So it has to save and restore that value when
producing code for the postincrement and postdecrement operators, even if
this value is never used. To avoid the additional overhead, use the
preincrement and predecrement operators if you don't need the resulting
value. That means, use
...
++i;
...
instead of
...
i++;
...
11. Use constants to access absolute memory locations.
The compiler produces optimized code, if the value of a pointer is a
constant. So, to access direct memory locations, use
#define VDC_DATA 0xD601
*(char*)VDC_STATUS = 0x01;
That will be translated to
lda #$01
sta $D600
The constant value detection works also for struct pointers and arrays,
if the subscript is a constant. So
#define VDC ((unsigned char*)0xD600)
#define STATUS 0x01
VDC [STATUS] = 0x01;
will also work.
If you first load the constant into a variable and use that variable to
access an absolute memory location, the generated code will be much
slower, since the compiler does not know anything about the contents of
the variable.
12. Use initialized local variables - but use it with care.
Initialization of local variables when declaring them gives shorter
and faster code. So, use
int i = 1;
instead of
int i;
i = 1;
But beware: To maximize your savings, don't mix uninitialized and
initialized variables. Create one block of initialized variables and
one of uniniitalized ones. The reason for this is, that the compiler
will sum up the space needed for uninitialized variables as long as
possible, and then allocate the space once for all these variables.
If you mix uninitialized and initialized variables, you force the
compiler to allocate space for the uninitialized variables each time,
it parses an initialized one. So do this:
int i, j;
int a = 3;
int b = 0;
instead of
int i;
int a = 3;
int j;
int b = 0;
The latter will work, but will create larger and slower code.
13. When using the ?: operator, cast values that are not ints.
The result type of the ?: operator is a long, if one of the second or
third operands is a long. If the second operand has been evaluated and
it was of type int, and the compiler detects that the third operand is
a long, it has to add an additional int->long conversion for the
second operand. However, since the code for the second operand has
already been emitted, this gives much worse code.
Look at this:
long f (long a)
{
return (a != 0)? 1 : a;
}
When the compiler sees the literal "1", it does not know, that the
result type of the ?: operator is a long, so it will emit code to load
a integer constant 1. After parsing "a", which is a long, a int->long
conversion has to be applied to the second operand. This creates one
additional jump, and an additional code for the conversion.
A better way would have been to write:
long f (long a)
{
return (a != 0)? 1L : a;
}
By forcing the literal "1" to be of type long, the correct code is
created in the first place, and no additional conversion code is
needed.
14. Use the array operator [] even for pointers.
When addressing an array via a pointer, don't use the plus and
dereference operators, but the array operator. This will generate
better code in some common cases.
Don't use
char* a;
char b, c;
char b = *(a + c);
Use
char* a;
char b, c;
char b = a[c];
instead.
15. Use register variables with care.
Register variables may give faster and shorter code, but they do also
have an overhead. Register variables are actually zero page
locations, so using them saves roughly one cycle per access. Since
the old values have to be saved and restored, there is an overhead of
about 70 cycles per 2 byte variable. It is easy to see, that - apart
from the additional code that is needed to save and restore the
values - you need to make heavy use of a variable to justify the
overhead.
An exception are pointers, especially char pointers. The optimizer
has code to detect and transform the most common pointer operations
if the pointer variable is a register variable. Declaring heavily
used character pointers as register may give significant gains in
speed and size.
And remember: Register variables must be enabled with -Or.
16. Decimal constants greater than 0x7FFF are actually long ints
The language rules for constant numeric values specify that decimal
constants without a type suffix that are not in integer range must be
of type long int or unsigned long int. This means that a simple
constant like 40000 is of type long int, and may cause an expression
to be evaluated with 32 bits.
An example is:
unsigned val;
...
if (val < 65535) {
...
}
Here, the compare is evaluated using 32 bit precision. This makes the
code larger and a lot slower.
Using
unsigned val;
...
if (val < 0xFFFF) {
...
}
or
unsigned val;
...
if (val < 65535U) {
...
}
instead will give shorter and faster code.

159
doc/compile.txt Normal file
View File

@ -0,0 +1,159 @@
Instructions for compiling cc65 and the ca65 binutils:
Linux (and probably most other Unices)
--------------------------------------
You need the GNU C compiler. Do a
make -f make/gcc.mak
twice(!) in each of the directories
cc65
binutils
After that, you need to compile the libraries. Do
cd lib
make clean c64lib
make clean c128lib
make clean plus4lib
make clean cbm610lib
make clean petlib
make clean apple2lib
Be sure to say "clean" each time, since some of the sources have a
"#ifdef <target_system>".
DOS using the DJGPP compiler
----------------------------
Most information in this section was provided by Keith W. Gerdes
(kwg@freebird.ghofn.org). Thanks a lot!
The tmpfile() function in DJGPP has a bug and will not open the scratch
file in binary mode. If you have problems with the archiver (which uses
the tmpfile() function), you have two choices:
1. Get a fix from http://www.cartsys.com/eldredge/djgpp-patches.html
and apply it. This will solve the problem once and forever.
2. For a temporary solution, in the file binutils/ar65/main.c, add the
following lines:
At top:
#include <fcntl.h>
At start of main:
_fmode = O_BINARY;
This will switch the default mode to binary and will work around the
bug.
Keith sent me the following notes how to build the tools on a DOS system
using DJGPP (add your system type to CFLAGS if needed):
-------------------------------------------------------------------------
Here's my current batch file:
cd cc65
if exist .depend goto ahead1
make -f make\gcc.mak
:ahead1
make -f make\gcc.mak
move *.exe ..\binutils
cd ..\cl65
if exist .depend goto ahead2
make -f make\gcc.mak
:ahead2
make -f make\gcc.mak
move *.exe ..\binutils
cd ..\binutils\common
if exist .depend goto ahead3
make -f make\gcc.mak
:ahead3
make -f make\gcc.mak
cd ..\ca65
if exist .depend goto ahead4
make -f make\gcc.mak
:ahead4
make -f make\gcc.mak
move *.exe ..
cd ..\ld65
if exist .depend goto ahead5
make -f make\gcc.mak
:ahead5
make -f make\gcc.mak
move *.exe ..
cd ..\ar65
if exist .depend goto ahead6
make -f make\gcc.mak
:ahead6
make -f make\gcc.mak
move *.exe ..
cd ..\..\lib\common
make 'CFLAGS=-Oi -I../../include/'
ar65 a common.lib *.o
move common.lib ..
cd ..\runtime
make 'CFLAGS=-Oi -I../../include/'
ar65 a runtime.lib *.o
move runtime.lib ..
--
In djgpp.env I use:
+LFN=Y
for the .depend file.
--
And in autoexec.bat I have:
set CC65_INC=E:\djgpp_v2\cc65\include
set CC65_LIB=E:\djgpp_v2\cc65\lib
PATH=E:\djgpp_v2\cc65\binutils;%PATH%
-------------------------------------------------------------------------
DOS, Windows, OS/2 using the Watcom Compiler
--------------------------------------------
This is what I'm using. You need the Borland make in addition to the
Watcom tools, or you have to change the makefile.
1. Copy %WATCOM%\src\startup\wildargv.c from your Watcom directory into
binutils\common.
2. Enter
make -f make\watcom.mak
in each of the directories
cc65
binutils
3. Use Linux to build the libraries:-) If you don't have Linux, get it
now! More serious: There is no makefile to build the libraries. Use a
batch file similar to the one above, or rewrite the makefile.

151
doc/debugging.txt Normal file
View File

@ -0,0 +1,151 @@
Debugging your code using VICE
Ullrich von Bassewitz, March 1999
Contents
--------
1. Overview
2. What is VICE?
3. How to prepare your sources
4. How to use the label file
5. Problems and workarounds
1. Overview
-----------
This document describes how to debug your programs using the cc65
development tools and the VICE CBM emulator.
2. What is VICE?
----------------
VICE is an emulator for many of the CBM machines. It runs on Unix, DOS and
Windows 95. It emulates the Commodore 64, 128, VIC20, PET and the 600/700
machines. For more information see the VICE home page:
http://www.cs.cmu.edu/~dsladic/vice/vice.html
VICE has a builtin machine language monitor that may be used for debugging
your programs. Using an emulator for debugging has some advantages:
- Since you're using a crossassembler/-compiler anyway, you don't need
to transfer the program to the real machine until it is done.
- An emulator allows many things that are almost impossible one of the
original machines. You may set watchpoints (detect read or write
access to arbitary addresses), debug interrupt handlers and even debug
routines that run inside the 1541 floppy.
- You may use the label file generated by the linker to make much more
use from the monitor.
Please note that you need at least VICE version 0.16 for the label file
feature to work. This version has still some problems (see section 5 for
descriptions and some workarounds), but older versions had even more
problems and do NOT work correctly.
3. How to prepare your programs
-------------------------------
VICE support is mostly done via a label file that is generated by the
linker and that may be read by the VICE monitor, so it knows about your
program. Source level debugging is *not* available, you have to debug your
programs in the assembler view.
The first step is to generate object files that contain information about
ALL labels in your sources, not just the exported ones. This can be done
by several means:
- Use the -g switch on the assembler command line.
- Use the
.debuginfo +
command in your source.
- Use the -g switch when invoking the compiler. The compiler will then
put the .debuginfo command into the generated assembler source.
So, if you have just C code, all you need is to invoke the compiler with
-g. If you're using assembler code, you have to use -g for the assembler,
or add ".debuginfo +" to your source files. Since the generated debug info
is not appended to the generated executables, it is a good idea to always
use -g. It makes the object files and libraries slightly larger (~30%),
but this is usually not a problem.
The second step is to tell the linker that it should generate a VICE label
file. This is done by the -L switch followed by the name of the label file
(I'm usually using a .lbl extension for these files). An example for a
linker command line would be:
ld65 -t c64 -L hello.lbl -m hello.map -o hello crt0 hello.o c64.lib
This will generate a file named hello.lbl that contains all symbols used
in your program.
Note: The runtime libraries and startup files were generated with debug
info, so you don't have to care about this.
4. How to use the label file
----------------------------
Load your program, then enter the monitor and use the "pb" command to load
your label file like this:
pb "hello.lbl"
You will get lots of warnings and even a few errors. You may ignore safely
all these warnings and errors as long as they reference any problems VICE
thinks it has with the labels.
After loading the labels, they are used by VICE in the disassembler
listing, and you may use them whereever you need to specify an address.
Try
d ._main
as an example (note that VICE needs a leading dot before all labels, and
that the compiler prepends an underline under most named labels).
5. Problems and workarounds
---------------------------
Unfortunately, the VICE monitor has several problems with labels. However,
it is still tremendously useful, and I think that most problems are gone
in the next version. So, here is a list of the problems known to me as of
version 0.16.1:
* The "ll" command does not work. Worse, it seems that internal memory
gets corrupted when using this command, so VICE will crash after use.
Be sure to use the "pb" command to load the label file.
* VICE will crash if you use a label that is undefined. This is probably
the worst problem of all, since it needs just one typo to kill VICE.
So, watch your steps:-)
* Cheap labels, that is, labels starting with '@' or '?' are not
accepted.
* The disassembly output is somewhat suboptimal. However, most things are
just cosmetical, e.g. labels appended to the right side of the
disassembled code.

185
doc/internal.doc Normal file
View File

@ -0,0 +1,185 @@
Internals doc for CC65
Stacks:
-------
The program stack used by programs compiled with CC65 is located in high
memory. The stack starts there and grows down. Arguments to functions, local
data etc are allocated on this stack, and deallocated when functions exit.
The program code and data is located in low memory. The heap is located
between the program code and the stack. The default size for the parameter
stack is 2K, you may change this by declaring an externally visible variable
named named _stksize that holds the new stack size:
unsigned _stksize = 4*1024; /* Use 4K stack */
Note: The size of the stack is only needed if you use the heap, or if you
call the stack checking routine (_stkcheck) from somewhere in your program.
When calling other functions, the return address goes on the normal 6502
stack, *not* on the parameter stack.
Registers:
----------
Since CC65 is a member of the Small-C family of compilers, it uses the notion
of a 'primary register'. In the CC65 implementation, I used the AX register
pair as the primary register. Just about everything interesting that the
library code does is done by somehow getting a value into AX, and then calling
some routine or other. In places where Small-C would use a secondary
register, top-of-stack is used, so for instance two argument function like
integer-multiply work by loading AX, pushing it on the stack, loading the
second value, and calling the internal function. The stack is popped, and the
result comes back in AX.
Calling sequences:
------------------
C functions are called by pushing their args on the stack, and JSR'ing to the
entry point. (See ex 1, below) If the function returns a value, it comes back
in AX. NOTE!!! A potentially significant difference between the CC65
environment and other C environments is that the CALLEE pops arguments, not
the CALLER. (This is done so as to generate more compact code) In normal use,
this doesn't cause any problems, as the normal function entry/exit conventions
take care of popping the right number of things off the stack, but you may
have to worry about it when doing things like writing hand-coded assembly
language routines that take variable numbers of arguments. More about that
later.
Ex 1: Function call: Assuming 'i' declared int and 'c' declared
char, the following C code
i = baz(i, c);
in absence of a prototype generates this assembler code. I've added
the comments.
lda _i ; get 'i', low byte
ldx _i+1 ; get 'i', hi byte
jsr pushax ; push it
lda _c ; get 'c'
ldx #0 ; fill hi byte with 0
jsr pushax ; push it
ldy #4 ; arg size
jsr _baz ; call the function
sta _i ; store the result
stx _i+1
In presence of a prototype, the picture changes slightly, since the
compiler is able to do some optimizations:
lda _i ; get 'i', low byte
ldx _i+1 ; get 'i', hi byte
jsr pushax ; push it
lda _c ; get 'c'
jsr pusha ; push it
jsr _baz ; call the function
sta _i ; store the result
stx _i+1
Note that the two words of arguments to baz were popped before it exitted.
The way baz could tell how much to pop was by the argument count in Y at call
time. Thus, even if baz had been called with 3 args instead of the 2 it was
expecting, that would not cause stack corruption.
There's another tricky part about all this, though. Note that the args to baz
are pushed in FORWARD order, ie the order they appear in the C statement.
That means that if you call a function with a different number of args than it
was expecting, they wont end up in the right places, ie if you call baz, as
above, with 3 args, it'll operate on the LAST two, not the first two.
Symbols:
--------
CC65 does the usual trick of prepending an underbar ('_') to symbol names when
compiling them into assembler. Therefore if you have a C function named
'bar', CC65 will define and refer to it as '_bar'.
Systems:
--------
Supported systems at this time are: C64, C128, Plus/4, CBM 600/700, the newer
PET machines (not 2001), and the Apple ][ (thanks to Kevin Ruland, who did the
port).
C64: The program runs in a memory configuration, where only the kernal ROM
is enabled. The text screen is expected at the usual place ($400), so
54K of memory are available to the program.
C128: The startup code will reprogram the MMU, so that only the kernal ROM
is enabled. This means, there are 41K of memory available to the
program.
Plus/4: Unfortunately, the Plus/4 is not able to disable only part of it's
ROM, it's an all or nothing approach. So, on the Plus/4, the program
has only 28K available (16K machines are detected and the amount of
free memory is reduced to 12K).
CBM 600/700:
The C program runs in a separate segment and has almost full 64K of
memory available.
PET: The startup code will adjust the upper memory limit to the installed
memory. However, only linear memory is used, this limits the top to
$8000, so on a 8032 or similar machine, 31K of memory are available to
the program.
APPLE2: The program starts at $800, and of RAM is $8E00, so 33.5K of memory
(including stack) are available.
Note: The above numbers do not mean that the remaining memory is unusable.
However, it is not linear memory and must be accessed by other, nonportable
methods. I'm thinking about a library extension that allows access to the
additional memory as a far heap, but these routines do not exist until now.
Inline Assembly:
----------------
CC65 allows inline assembly by a special keyword named "asm". Inline assembly
looks like a function call. The string in parenthesis is output in the
assembler file.
Example, insert a break instruction into the code:
asm ("\t.byte\t$00")
Note: The \t in the string is replaced by the tab character, as in all other
strings.
Pseudo variables:
-----------------
There are two special variables available named __AX__ and __EAX__. These
variables must never be declared (this gives an error), but may be used as any
other variable. However, accessing these variables will access the primary
register that is used by the compiler to evaluate expressions, return
functions results and pass parameters.
This feature is useful with inline assembly and macros. For example, a macro
that reads a CRTC register may be written like this:
#define wr(idx) (__AX__=(idx),asm("\tsta\t$2000\n\tlda\t$2000\n\tldx\t#$00"),__AX__)
An obvious problem here is that macro definitions may not use more than one
line.

206
doc/intro.txt Normal file
View File

@ -0,0 +1,206 @@
How to use the cc65 C compiler
Ullrich von Bassewitz, 1998/1999
Contents
--------
1. Overview
2. The compiler
3. The assembler
4. The linker
5. The easy way (using the cl65 utility)
1. Overview
-----------
This is a short intro, how to use the compiler and the binutils. It
contains a step-by-step example, how to build a complete application from
one C and one assembler module. This file does *NOT* contain a complete
reference for the tools used in the process. There are separate files
describing these tools in detail.
Note: There is a much simpler way to compile this example using the cl65
compiler and link utility. However, it makes sense to understand how the
separate steps work. How to do the example with the cl65 utility is
described in section 5.
To explain the development flow, I will use the following example modules:
hello.c:
#include <stdio.h>
#include <stdlib.h>
extern const char text[]; /* In text.s */
int main (void)
{
printf ("%s\n", text);
return EXIT_SUCCESS;
}
text.s:
.export _text
_text: .asciiz "Hello world!"
We assume that the target file should be named "hello", and the target
system is the C64.
+---------+
| hello.c |
+---------+
|
cc65
\/
+---------+ +---------+
| hello.s | | text.s |
+---------+ +---------+
| |
ca65 ca65
\/ \/
+---------+ +---------+ +----------+ +---------+
| hello.o | | text.o | | c64.o | | c64.lib |
+---------+ +---------+ +----------+ +---------+
| \ / |
| \ / |
| \ / |
+----------------------->ld65<-------------------------+
\/
hello
c64.o (the startup code) and c64.lib (the c64 version of the runtime and C
library) are provided in binary form in the cc65 package.
2. The compiler
---------------
The compiler translates one C source into one assembler source for each
invocation. It does *NOT* create object files directly, and it is *NOT*
able to translate more than one file per run.
In the example above, we would use the following command line, to
translate hello.c into hello.s:
cc65 -O -I ../include -t c64 hello.c
The -O switch tells the compiler to do an additional optimizer run, which
is usually a good idea, since it makes the code smaller. If you don't care
about the size, but want to have slightly faster code, use -Oi to inline
some runtime functions.
The -I switch gives a search path for the include files. You may also set
the environment variable CC65_INC to the search path.
The -t switch is followed by the target system.
If the compiler does not complain about errors in our hello world, we will
have a file named "hello.s" in our directory that contains the assembler
source for the hello module.
For more information about the compiler see cc65.txt.
3. The assembler
----------------
The assembler translates one assembler source into an object file for each
invocation. The assembler is *NOT* able to translate more than one source
file per run.
Let's translate the hello.s and text.s files from our example:
ca65 hello.s
ca65 text.s
If the assembler does not complain, we should now have two object files
(named hello.o and text.o) in the current directory.
For more information about the assembler see ca65.txt.
4. The linker
-------------
The linker combines several object and library file into one output file.
ld65 is very configurable, but fortunately has a builtin configuration for
the C64, so we don't need to mess with configuration files here.
The compiler uses small functions to do things that cannot be done inline
without big impact on code size. These runtime functions, together with
the C library are in an object file archive named after the system, in
this case "c64.lib". We have to specify this file on the command line so
that the linker can resolve these functions.
A second file (this time an object file) needed, is the startup code that
prepares the grounds for the C program to run. The startup file must be
executed first, so it must be the first file on the linker command line.
Let's link our files to get the final executable:
ld65 -t c64 -o hello c64.o hello.o text.o c64.lib
The argument after -o specifies the name of the output file, the argument
after -t gives the target system. As discussed, the startup file must be the
first file on the command line (you may have to add a path here, if c64.o is
not in your current directory). Since the library resolves imports in hello.o
and text.o, it must be specified *after* these files.
After a successful linker run, we have a file named "hello", ready for our
C64!
For more information about the linker see ld65.txt.
5. The easy way (using the cl65 utility)
----------------------------------------
The cl65 utility is able to do all of the steps described above in just
one call, and it has defaults for some options that are very well suited
for our example.
To compile both files into one executable enter
cl65 -O -I ../include hello.c test.s
(The -I switch is not needed if you are working under Linux with the
include files in the default path, or the CC65_INC environment variable is
set correctly).
The cl65 utility knows, how to translate C files into object files (it
will call the compiler and then the assembler). It does also know how to
create object files from assembler files (it will call the assember for
that). It knows how to build an executable (it will pass all object files
to the linker). And, finally, it has the C64 as a default target and will
supply the correct startup file and runtime library names to the linker,
so you don't have to care about that.
The one-liner above should give you a C64 executable named "hello" in the
current directory.
For more information about the compile & link utility see cl65.txt.

655
doc/ld65.txt Normal file
View File

@ -0,0 +1,655 @@
ld65
A Linker for ca65 Object modules
(C) Copyright 1998-1999 Ullrich von Bassewitz
(uz@musoftware.de)
Contents
--------
1. Overview
2. Usage
3. Detailed workings
4. Output configuration files
4.1 Introduction
4.2 Reference
4.3 Builtin configurations
5. Bugs/Feedback
6. Copyright
1. Overview
-----------
ld65 is a replacement for the link65 linker that was part of the cc65 C
compiler suite developed by John R. Dunning. link65 had some problems and
the copyright does not permit some things which I wanted to be possible,
so I decided to write a completely new assembler/linker/archiver suite
for the cc65 compiler. ld65 is part of this suite.
The ld65 linker combines several object modules, producing an executable
file. The object modules may be read from a library created by the ar65
archiver (this is somewhat faster and more convenient). The linker was
designed to be as flexible as possible. It complements the features that
are built into the ca65 macroassembler:
* Accept any number of segments to form an executable module.
* Resolve arbitrary expressions stored in the object files.
* In case of errors, use the meta information stored in the object
files to produce helpful error messages. In case of undefined
symbols, expression range errors, or symbol type mismatches, ld65 is
able to tell you the exact location in the source, where the symbol
was referenced.
* Flexible output. The output of ld65 is highly configurable by a
config file. More common platforms are supported by builtin
configurations that may be activated by naming the target system.
The output generation was designed with different output formats in
mind, so adding other formats shouldn't be a great problem.
2. Usage
--------
The linker is called as follows:
Usage: ld65 [options] module ...
Options are:
-m name Create a map file
-o name Name the default output file
-t type Type of target system
-v Verbose mode
-vm Verbose map file
-C name Use linker config file
-Ln name Create a VICE label file
-Lp Mark write protected segments as such (VICE)
-S addr Set the default start address
-V Print linker version
The -m switch (which needs an argument that will used as a filename for
the generated map file) will cause the linker to generate a map file. The
map file does contain a detailed overview over the modules used, the
sizes for the different segments, and a table containing exported
symbols.
The -o switch is used to give the name of the default output file.
Depending on your output configuration, this name may NOT be used as name
for the output file. However, for the builtin configurations, this name
is used for the output file name.
The argument for the -t switch is the name of the target system. Since
this switch will activate a builtin configuration, it may not be used
together with the -C option.
The following target systems are defined (* = currently unsupported):
none
atari
c64
c128
ace
plus4
cbm610
pet
nes
apple2
See section 4.3 for more information about the builtin configurations.
Using the -v option, you may enable more output that may help you to
locate problems. If an undefined symbol is encountered, -v causes the
linker to print a detailed list of the references (that is, source file
and line) for this symbol.
-C gives the name of an output config file to use. See section 4 for more
information about config files. -C may not be used together with -t.
-L allows you to create a file that contains all global labels and may be
loaded into VICE emulator using the pb (playback) command. You may use
this to debug your code with VICE. Note: The label feature is very new in
VICE and has some bugs. If you have problems, please get the latest VICE
version.
Using -S you may define the default starting address. If and how this
address is used depends on the config file in use. For the builtin
configurations, only the "none" system honors an explicit start address,
all other builtin config provide their own.
-V prints the version number of the linker. If you send any suggestions or
bugfixes, please include this number.
If one of the modules is not found in the current directory, and the
module name does not have a path component, the value of the environment
variable CC65_LIB is prepended to the name, and the linker tries to open
the module with this new name.
3. Detailed workings
--------------------
The linker does several things when combining object modules:
First, the command line is parsed from left to right. For each object file
encountered (object files are recognized by a magic word in the header, so
the linker does not care about the name), imported and exported
identifiers are read from the file and inserted in a table. If a library
name is given (libraries are also recognized by a magic word, there are no
special naming conventions), all modules in the library are checked if an
export from this module would satisfy an import from other modules. All
modules where this is the case are marked. If duplicate identifiers are
found, the linker issues a warning.
This procedure (parsing and reading from left to right) does mean, that a
library may only satisfy references for object modules (given directly or
from a library) named BEFORE that library. With the command line
ld65 crt0.o clib.lib test.o
the module test.o may not contain references to modules in the library
clib.lib. If this is the case, you have to change the order of the modules
on the command line:
ld65 crt0.o test.o clib.lib
Step two is, to read the configuration file, and assign start addresses
for the segments and define any linker symbols (see section 4).
After that, the linker is ready to produce an output file. Before doing
that, it checks it's data for consistency. That is, it checks for
unresolved externals (if the output format is not relocatable) and for
symbol type mismatches (for example a zero page symbol is imported by a
module as absolute symbol).
Step four is, to write the actual target files. In this step, the linker
will resolve any expressions contained in the segment data. Circular
references are also detected in this step (a symbol may have a circular
reference that goes unnoticed if the symbol is not used).
Step five is to output a map file with a detailed list of all modules,
segments and symbols encountered.
And, last step, if you give the -v switch twice, you get a dump of the
segment data. However, this may be quite unreadable if you're not a
developer:-)
4. Output configuration files
-----------------------------
Configuration files are used to describe the layout of the output file(s).
Two major topics are covered in a config file: The memory layout of the
target architecture, and the assignment of segments to memory areas. In
addition, several other attributes may be specified.
Case is ignored for keywords, that is, section or attribute names, but it
is NOT ignored for names and strings.
4.1 Introduction
----------------
Memory areas are specified in a "MEMORY" section. Lets have a look at an
example (this one describes the usable memory layout of the C64):
MEMORY {
RAM1: start = $0800, size = $9800;
ROM1: start = $A000, size = $2000;
RAM2: start = $C000, size = $1000;
ROM2: start = $E000, size = $2000;
}
As you can see, there are two ram areas and two rom areas. The names
(before the colon) are arbitrary names that must start with a letter, with
the remaining characters being letters or digits. The names of the memory
areas are used when assigning segments. As mentioned above, case is
significant for these names.
The syntax above is used in all sections of the config file. The name
("ROM1" etc.) is said to be an identifier, the remaining tokens up to the
semicolon specify attributes for this identifier. You may use the equal
sign to assign values to attributes, and you may use a comma to separate
attributes, you may also leave both out. But you MUST use a semicolon to
mark the end of the attributes for one identifier. The section above may
also have looked like this:
# Start of memory section
MEMORY
{
RAM1:
start $0800
size $9800;
ROM1:
start $A000
size $2000;
RAM2:
start $C000
size $1000;
ROM2:
start $E000
size $2000;
}
There are of course more attributes for a memory section than just start
and size. Start and size are mandatory attributes, that means, each memory
area defined MUST have these attributes given (the linker will check
that). I will cover other attributes later. As you may have noticed, I've
used a comment in the example above. Comments start with a hash mark
(`#'), the remainder of the line is ignored if this character is found.
Let's assume you have written a program for your trusty old C64, and you
would like to run it. For testing purposes, it should run in the RAM area.
So we will start to assign segments to memory sections in the SEGMENTS
section:
SEGMENTS {
CODE: load = RAM1, type = ro;
RODATA: load = RAM1, type = ro;
DATA: load = RAM1, type = rw;
BSS: load = RAM1, type = bss, define = yes;
}
What we are doing here is telling the linker, that all segments go into
the RAM1 memory area in the order specified in the SEGMENTS section. So
the linker will first write the CODE segment, then the RODATA segment,
then the DATA segment - but it will not write the BSS segment. Why? Enter
the segment type: For each segment specified, you may also specify a
segment attribute. There are five possible segment attributes:
ro means readonly
wprot same as ro but will be marked as write protected in
the VICE label file if -Lp is given
rw means read/write
bss means that this is an uninitialized segment
empty will not go in any output file
So, because we specified that the segment with the name BSS is of type
bss, the linker knows that this is uninitialized data, and will not write
it to an output file. This is an important point: For the assembler, the
BSS segment has no special meaning. You specify, which segments have the
bss attribute when linking. This approach is much more flexible than
having one fixed bss segment, and is a result of the design decision to
supporting an arbitrary segment count.
If you specify "type = bss" for a segment, the linker will make sure that
this segment does only contain uninitialized data (that is, zeroes), and
issue a warning if this is not the case.
For a bss type segment to be useful, it must be cleared somehow by your
program (this happens usually in the startup code - for example the
startup code for cc65 generated programs takes care about that). But how
does your code know, where the segment starts, and how big it is? The
linker is able to give that information, but you must request it. This is,
what we're doing with the "define = yes" attribute in the BSS definitions.
For each segment, where this attribute is true, the linker will export
three symbols.
__NAME_LOAD__ This is set to the address where the segment is
loaded.
__NAME_RUN__ This is set to the run address of the segment.
We will cover run addresses later.
__NAME_SIZE__ This is set to the segment size.
Replace "NAME" by the name of the segment, in the example above, this
would be "BSS". These symbols may be accessed by your code.
Now, as we've configured the linker to write the first three segments and
create symbols for the last one, there's only one question left: Where
does the linker put the data? It would be very convenient to have the data
in a file, wouldn't it?
We don't have any files specified above, and indeed, this is not needed in
a simple configuration like the one above. There is an additional
attribute "file" that may be specified for a memory area, that gives a
file name to write the area data into. If there is no file name given, the
linker will assign the default file name. This is "a.out" or the one given
with the -o option on the command line. Since the default behaviour is ok
for our purposes, I did not use the attribute in the example above. Let's
have a look at it now.
The "file" attribute (the keyword may also be written as "FILE" if you
like that better) takes a string enclosed in double quotes (`"') that
specifies the file, where the data is written. You may specifiy the same
file several times, in that case the data for all memory areas having this
file name is written into this file, in the order of the memory areas
defined in the MEMORY section. Let's specify some file names in the MEMORY
section used above:
MEMORY {
RAM1: start = $0800, size = $9800, file = %O;
ROM1: start = $A000, size = $2000, file = "rom1.bin";
RAM2: start = $C000, size = $1000, file = %O;
ROM2: start = $E000, size = $2000, file = "rom2.bin";
}
The %O used here is a way to specify the default behaviour explicitly: %O
is replaced by a string (including the quotes) that contains the default
output name, that is, "a.out" or the name specified with the -o option on
the command line. Into this file, the linker will first write any segments
that go into RAM1, and will append then the segments for RAM2, because the
memory areas are given in this order. So, for the RAM areas, nothing has
really changed.
We've not used the ROM areas, but we will do that below, so we give the
file names here. Segments that go into ROM1 will be written to a file
named "rom1.bin", and segments that go into ROM2 will be written to a file
named "rom2.bin". The name given on the command line is ignored in both
cases.
Let us look now at a more complex example. Say, you've successfully tested
your new "Super Operating System" (SOS for short) for the C64, and you
will now go and replace the ROMs by your own code. When doing that, you
face a new problem: If the code runs in RAM, we need not to care about
read/write data. But now, if the code is in ROM, we must care about it.
Remember the default segments (you may of course specify your own):
CODE read only code
RODATA read only data
DATA read/write data
BSS uninitialized data, read/write
Since the BSS is not initialized, we must not care about it now, but what
about DATA? DATA contains initialized data, that is, data that was
explicitly assigned a value. And your program will rely on these values on
startup. Since there's no other way to remember the contents of the data
segment, than storing it into one of the ROMs, we have to put it there.
But unfortunately, ROM is not writeable, so we have to copy it into RAM
before running the actual code.
The linker cannot help you copying the data from ROM into RAM (this must
be done by the startup code of your program), but it has some features
that will help you in this process.
First, you may not only specify a "load" attribute for a segment, but also
a "run" attribute. The "load" attribute is mandatory, and, if you don't
specify a "run" attribute, the linker assumes that load area and run area
are the same. We will use this feature for our data area:
SEGMENTS {
CODE: load = ROM1, type = ro;
RODATA: load = ROM2, type = ro;
DATA: load = ROM2, run = RAM2, type = rw, define = yes;
BSS: load = RAM2, type = bss, define = yes;
}
Let's have a closer look at this SEGMENTS section. We specify that the
CODE segment goes into ROM1 (the one at $A000). The readonly data goes
into ROM2. Read/write data will be loaded into ROM2 but is run in RAM2.
That means that all references to labels in the DATA segment are relocated
to be in RAM2, but the segment is written to ROM2. All your startup code
has to do is, to copy the data from it's location in ROM2 to the final
location in RAM2.
So, how do you know, where the data is located? This is the second point,
where you get help from the linker. Remember the "define" attribute? Since
we have set this attribute to true, the linker will define three external
symbols for the data segment that may be accessed from your code:
__DATA_LOAD__ This is set to the address where the segment is
loaded, in this case, it is an address in ROM2.
__DATA_RUN__ This is set to the run address of the segment, in
this case, it is an address in RAM2.
__DATA_SIZE__ This is set to the segment size.
So, what your startup code must do, is to copy __DATA_SIZE__ bytes from
__DATA_LOAD__ to __DATA_RUN__ before any other routines are called. All
references to labels in the DATA segment are relocated to RAM2 by the
linker, so things will work properly.
There are some other attributes not covered above. Before starting the
reference section, I will discuss the remaining things here.
You may request symbols definitions also for memory areas. This may be
useful for things like a software stack, or an i/o area.
MEMORY {
STACK: start = $C000, size = $1000, define = yes;
}
This will define three external symbols that may be used in your code:
__STACK_START__ This is set to the start of the memory
area, $C000 in this example.
__STACK_SIZE__ The size of the area, here $1000.
__STACK_LAST__ This is NOT the same as START+SIZE.
Instead, it it defined as the first
address that is not used by data. If we
don't define any segments for this area,
the value will be the same as START.
A memory section may also have a type. Valid types are
ro for readonly memory
and rw for read/write memory.
The linker will assure, that no segment marked as read/write or bss is put
into a memory area that is marked as readonly.
Unused memory in a memory area may be filled. Use the "fill = yes"
attribute to request this. The default value to fill unused space is zero.
If you don't like this, you may specify a byte value that is used to fill
these areas with the "fillval" attribute. This value is also used to fill
unfilled areas generated by the assemblers .ALIGN and .RES directives.
Segments may be aligned to some memory boundary. Specify "align = num" to
request this feature. Num must be a power of two. To align all segments on
a page boundary, use
SEGMENTS {
CODE: load = ROM1, type = ro, align = $100;
RODATA: load = ROM2, type = ro, align = $100;
DATA: load = ROM2, run = RAM2, type = rw, define = yes,
align = $100;
BSS: load = RAM2, type = bss, define = yes, align = $100;
}
If an alignment is requested, the linker will add enough space to the
output file, so that the new segment starts at an address that is
divideable by the given number without a remainder. All addresses are
adjusted accordingly. To fill the unused space, bytes of zero are used,
or, if the memory area has a "fillval" attribute, that value. Alignment is
always needed, if you have the used the .ALIGN command in the assembler.
The alignment of a segment must be equal or greater than the alignment
used in the .ALIGN command. The linker will check that, and issue a
warning, if the alignment of a segment is lower than the alignment
requested in a .ALIGN command of one of the modules making up this
segment.
For a given segment you may also specify a fixed offset into a memory area or
a fixed start address. Use this if you want the code to run at a specific
address (a prominent case is the interrupt vector table which must go at
address $FFFA). Only one of ALIGN or OFFSET or START may be specified. If the
directive creates empty space, it will be filled with zero, of with the value
specified with the "fillval" attribute if one is given. The linker will warn
you if it is not possible to put the code at the specified offset (this may
happen if other segments in this area are too large). Here's an example:
SEGMENTS {
VECTORS: load = ROM2, type = ro, start = $FFFA;
}
or (for the segment definitions from above)
SEGMENTS {
VECTORS: load = ROM2, type = ro, offset = $1FFA;
}
File names may be empty, data from segments assigned to a memory area with
an empty file name is discarded. This is useful, if the a memory area has
segments assigned that are empty (for example because they are of type
bss). In that case, the linker will create an empty output file. This may
be suppressed by assigning an empty file name to that memory area.
The symbol %S may be used to access the default start address (that is,
$200 or the value given on the command line with the -S option).
4.2 Reference
-------------
4.3 Builtin configurations
--------------------------
Here is a list of the builin configurations for the different target
types:
none:
MEMORY {
RAM: start = %S, size = $10000, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = rw;
RODATA: load = RAM, type = rw;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
atari:
(non-existent)
c64:
MEMORY {
RAM: start = $7FF, size = $c801, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
c128:
MEMORY {
RAM: start = $1bff, size = $a401, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
ace:
(non-existent)
plus4:
MEMORY {
RAM: start = $0fff, size = $7001, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
cbm610:
MEMORY {
RAM: start = $0001, size = $FFF0, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
pet:
MEMORY {
RAM: start = $03FF, size = $7BFF, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
nes:
MEMORY {
RAM: start = $0200, size = $0600, file = "";
ROM: start = $8000, size = $8000, file = %O;
}
SEGMENTS {
CODE: load = ROM, type = ro;
RODATA: load = ROM, type = ro;
DATA: load = ROM, run = RAM, type = rw, define = yes;
BSS: load = RAM, type = bss, define = yes;
VECTORS: load = ROM, type = ro, start = $FFFA;
}
apple2:
MEMORY {
RAM: start = $800, size = $8E00, file = %O;
}
SEGMENTS {
CODE: load = RAM, type = ro;
RODATA: load = RAM, type = ro;
DATA: load = RAM, type = rw;
BSS: load = RAM, type = bss, define = yes;
}
The "start" attribute for the RAM memory area of the CBM systems is two
less than the actual start of the basic RAM to account for the two bytes
load address that is needed on disk and supplied by the startup code.
5. Bugs/Feedback
----------------
If you have problems using the linker, if you find any bugs, or if you're
doing something interesting with it, I would be glad to hear from you.
Feel free to contact me by email (uz@musoftware.de).
6. Copyright
------------
ld65 (and all cc65 binutils) are (C) Copyright 1998 Ullrich von Bassewitz.
For usage of the binaries and/or sources the following conditions do
apply:
This software is provided 'as-is', without any expressed or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

235
doc/library.txt Normal file
View File

@ -0,0 +1,235 @@
Description of the C library for the cc65 C compiler
(C) Copyright 1998-1999 Ullrich von Bassewitz
(uz@musoftware.de)
Contents
--------
1. Overview
2. ISO C compatible library
3. CPU specific stuff - 6502.h
4. System specific stuff
5. Direct console I/O - conio.h
6. Using the joystick - joystick.h
7. Bugs/Feedback
8. Copyright
1. Overview
-----------
This file contains a description of the library routines available for the
cc65 C compiler. It is not complete in some areas, so if you miss
something, have a look into the header files. All functions, that are not
defined by the ISO C standard have a short comment in the headers,
explaining their use.
2. ISO C compatible library
---------------------------
The C library contains a large subset of the ISO C library. Functions are
usually missing in areas, where there is no support on typical 6502
systems. Wide character sets are an example for this.
I will not go into detail about the ISO functions. If a function is not
mentioned here explicitly, expect it to be available and to behave as
defined in the C standard.
Functions that are NOT available:
* ftell/fseek/fgetpos/fsetpos
* tmpfile/tmpnam
* The scanf family of functions
* time/asctime/ctime/difftime/asctime/gmtime/localtime/mktime/strftime
* system
* All functions that handle floating point numbers in some manner.
* The div and ldiv functions (because cc65 is not able to return
structs).
* All functions handling wide character strings.
* Signals and all related functions (having SIGSEGV would be cool:-)
* rename/remove/rewind
* setbuf/setvbuf/ungetc
Functions that are limited in any way:
* fopen/fread/fwrite/fclose/fputs/fgets/fscanf....
These functions are built on open/read/write/close. Neither of these
low level functions is currently available for the supported systems,
and so, fopen and friends do not work. However, the functions exist
and are tested to some degree under the ACE operating systems (which
is no longer supported).
* The va_... family of macros
The macros do not work completely as defined by the standard. Since cc65
has the wrong calling order, the (non-standard) va_fix macro must be used
to access fixed parameters in functions with a variable parameter size.
See newvers.txt for a discussion of the problem.
* The character classification functions (is...)
These functions have unexpected results when called with arguments that
are not really chars (are outside the 0..255 range).
* The strerror function
The function will return "error #n" where n is the error number.
* strcspn/strpbrk/strspn
These functions have a length limitation of 256 for the second string
argument. Since this string gives a character set, and there are only 256
distinct characters, this shouldn't be a problem.
* Since there is no such thing as an environment on all supported
systems, the getenv function will always return a NULL pointer.
* There is no other locale than the "C" locale. The native locale is
identical to the "C" locale.
3. CPU specific stuff - 6502.h
------------------------------
The header file 6502.h contains some functions that make only sense with
the 6502 CPU. Examples are macros to insert more or less useful
instructions into your C code, or a function to call arbitrary machine
language subroutines, passing registers in and out.
4. System specific stuff
------------------------
For each supported system there's a header file that contains calls or
defines specific for this system. So, when programming for the C64,
include c64.h, for the C128, include c128.h and so on. To make the task
for the Commodore systems easier, there is also a header file named cbm.h
that will define stuff common for all CBM systems, and include the header
file for the specific target system.
The header files contain
* Defines for special keys (like function keys)
* Defines for special characters (like the graphics characters)
* Variables with a fixed address in memory that may be used to access
special hardware. For the C64 and C128 there is a variable struct
named "sid". Writing to the fields of this struct will write to the
SID device instead. Using these variables will make your program more
readable and more portable. Don't fear ineffective code when using
these variables, the compiler will translate reads and writes to these
structs into direct memory accesses.
* Other routines that make only sense for a specific system. One example
are routines to write memory locations in the system bank for the CBM
600/700 family (called B128/B256 in the US).
5. Direct console I/O - conio.h
-------------------------------
The conio header file contains a large set of functions that do screen and
keyboard I/O. The functions will write directly to the screen or poll the
keyboard directly with no more help from the operating system than needed.
This has some disadvantages, but on the other side it's fast and
reasonably portable. conio implementations exist for the following
targets:
c64
c128
plus/4
cbm610 (that is, the complete 600/700 series)
pet (all PETs except the 2001)
apple 2
The conio.h header file does also include the system specific header files
which define constants for special characters and keys.
6. Using the joystick - joystick.h
----------------------------------
For systems that have a joystick, joystick.h will define a subroutine to
read the current value, including constants to evaluate the result of this
function. To help in writing portable code, the header file will define
the symbol __JOYSTICK__ on systems that have a joystick.
7. Bugs/Feedback
----------------
If you have problems using the library, if you find any bugs, or if you've
written some extensions or otherwise interesting programs, I would be glad
to hear from you. Feel free to contact me by email (uz@musoftware.de).
8. Copyright
------------
This C runtime library implementation for the cc65 compiler is (C)
Copyright 1998-1999 Ullrich von Bassewitz. For usage of the binaries
and/or sources the following conditions do apply:
This software is provided 'as-is', without any expressed or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

511
doc/newvers.txt Normal file
View File

@ -0,0 +1,511 @@
This document is slightly outdated! See cc65.txt and library.txt for a more
up-to-date discussion.
Discussion of some of the features/non features of the current cc65 version
---------------------------------------------------------------------------
1. Copyright
2. Differences to the original version
3. Known bugs and limitations
4. Library
5. Bugs
1. Copyright
-----------
This is the original compiler copyright:
--------------------------------------------------------------------------
-*- Mode: Text -*-
This is the copyright notice for RA65, LINK65, LIBR65, and other
Atari 8-bit programs. Said programs are Copyright 1989, by John R.
Dunning. All rights reserved, with the following exceptions:
Anyone may copy or redistribute these programs, provided that:
1: You don't charge anything for the copy. It is permissable to
charge a nominal fee for media, etc.
2: All source code and documentation for the programs is made
available as part of the distribution.
3: This copyright notice is preserved verbatim, and included in
the distribution.
You are allowed to modify these programs, and redistribute the
modified versions, provided that the modifications are clearly noted.
There is NO WARRANTY with this software, it comes as is, and is
distributed in the hope that it may be useful.
This copyright notice applies to any program which contains
this text, or the refers to this file.
This copyright notice is based on the one published by the Free
Software Foundation, sometimes known as the GNU project. The idea
is the same as theirs, ie the software is free, and is intended to
stay that way. Everybody has the right to copy, modify, and re-
distribute this software. Nobody has the right to prevent anyone
else from copying, modifying or redistributing it.
--------------------------------------------------------------------------
In acknowledgment of this copyright, I will place my own changes to the
compiler under the same copyright.
However, since the library and all binutils (assembler, archiver, linker)
are a complete rewrite, they are covered by another copyright:
--------------------------------------------------------------------------
CC65 C Library and Binutils
(C) Copyright 1998 Ullrich von Bassewitz
COPYING CONDITIONS
This software is provided 'as-is', without any expressed or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution
--------------------------------------------------------------------------
I will try to contact John, maybe he is also willing to place his sources
under a less restrictive copyright, after all these years:-)
2. Differences to the original version
--------------------------------------
This is a list of changes against the cc65 archives. I got the originals
from:
http://www.umich.edu/~archive/atari/8bit/Languages/Cc65/
* Removed all assembler code from the compiler. It was unportable because
it made assumptions about the character set (ATASCII) and made the
sources hard to read and to debug.
* All programs do return an error code, so they may be used by make. All
programs try to remove the target file, if there were errors.
* The assembler now checks several error conditions (others still go
undetected - see "known bugs").
* Removed many bugs from the compiler. One error was invalid code
produced by the compiler that went through the assembler since the
assembler did not check for ranges itself.
* Removed many non-portable constructs from the compiler. Code cleanups,
rewrite of the function headers and more.
* New style function prototypes supported instead of the old K&R syntax.
The new syntax is a must, that is, the old style syntax is no longer
understood. As an extension, unnamed parameters may be used to avoid
warnings about unused parameters.
* New void type. May also be used as a function return type.
* Changed the memory management in the compiler. Use malloc/free instead
of the old homebrew (and unportable) stuff.
* Default character type is unsigned. This is much more what you want in
small systems environments, since a char is often used to represent a
small numerical value, and the integer promotion does the wrong thing
in those cases. Look at the follwing piece of code:
char c = read_char ();
switch (c) {
case 0x80: printf ("c is 0x80\n"); break;
default: printf ("c is something else\n"); break;
}
With signed chars, the code above, will *always* run into the default
selector. c is promoted to int, and since it is signed, 0x80 will get
promoted to 0xFF80 - which will select the default label. With unsigned
chars, the code works as intended (but note: the code works for cc65
but it is non portable anyway, since many other compilers have signed
chars by default, so be careful! Having unsigned chars is just a
convenience thing).
* Shorter code when using the builtin operators and the lhs of an expr
is a constant (e.g. expressions like "c == 0x80" are encoded two
bytes shorter).
* Some optimizations when pushing constants.
* Character set translation by the compiler. A new -t option was added
to set the target system type. Use
-t0 For no spefic target system (default)
-t1 For the atari (does not work completely, since I did not
have an ATASCII translation table).
-t2 Target system is C64.
-t3 Target system is C128.
-t4 Target system is ACE.
-t5 Target system is Plus/5.
* Dito for the linker: Allow an option to set the target system and add
code to the linker to produce different headers and set the correct
start address.
* Complete rewrite of the C library. See extra chapter.
* Many changes in the runtime library. Splitted it into more than one
file to allow for smaller executables if not all of the code is needed.
* Allow longer names. Now the first 12 characters are sigificant at the
expense of some more memory used at runtime.
* String constants are now concatenated in all places. This allows
things like:
fputs ("Options:\n"
" -b bomb computer\n"
" -f format hard disk\n"
" -k kill init\n",
stderr);
saving code for more than one call to the function.
* Several new macros are defined:
M6502 This one is old - don't use!
__CC65__ Use this instead. Defined when compiling with cc65.
__ATARI__ Defined when the target system is atari.
__CBM__ Defined when compiling for a CBM system as target.
__C64__ Defined when the C64 is the target system.
__C128__ Defined when compiling for the 128.
__ACE__ Defined when compiling for ACE.
__PLUS4__ Defined when compiling for the Plus/4.
The __CC65__ macro has the compiler version as its value, version
1.0 of the compiler will define this macro as 0x100.
* The -a option is gone.
* The compiler will generate external references (via .globl) only if a
function is defined as extern in a module, or not defined but called
from a module. The old behaviour was to generate a reference for every
function prototype ever seen, which meant that using a header file like
stdio.h got most of the C library linked in, even if it was never used.
* Many new warnings added (about unused parameters, unused variables,
compares of unsigneds against zero, function call without prototype
and much more).
* Added a new compiler option (-W) to suppress all warnings.
* New internal variable __fixargs__ that gives the size of fixed
arguments, a function takes. This allows to work (somehow) around the
problem, that cc65 has the "wrong" (that is, pascal) calling order. See
below ("Known problems") for a discussion.
* The "empty" preprocessor directive ("#" on a line) is now ignored.
* Added a "#error" directive to force user errors.
* Optimization of the code generation. Constant parts of expressions are
now detected in many places where the old compiler evaluated the
constants at runtime.
* Allow local static variables (there was code in the original compiler for
that, but it did not work). Allow also initialization in this case (no
code for that in the original). Local static variables in the top level
function block have no penalty, for static variables in nested blocks, the
compiler generates a jump around the variable space. To eliminate this,
an assembler/linker with support for segments is needed.
* You cannot return a value from a void function, and must return a value
in a non-void function. Violations are flagged as an error.
* Typedefs added.
* The nonstandard evaluation of the NOARGC and FIXARGC macros has been
replaced by a smart algorithm that does the same thing automagically
and without user help (provided there are function prototypes).
* Function pointers may now be used to call a function without
dereferencing. Given a function
void f1 (void (*f2) ())
the following was valid before:
(*f2) ();
The ANSI standard allows a second form (because there's no ambiguity)
which is now also allowed:
f2 ();
* Pointer subtraction was completely messed up and did not work (that is,
subtraction of a pointer from a pointer produced wrong results).
* Local struct definitions are allowed.
* Check types in assignments, parameters for function calls and more.
* A new long type (32 bit) is available. The integer promotion rules
are applied if needed. This includes much more type checking and a
better handling of chars (they are handled as chars, not as ints, in
all places where this is possible).
* Integer constants now have an associated type, 'U' and 'L' modifers
may be used.
* The old #asm statement is gone. Instead, there's now a asm ("xxx")
statement that has the syntax that is defined by the C++ standard
(the C standard does not define an ASM statement). The string literal
in parenthesis is inserted in the assembler output. You may also
use __asm__ instead of asm (see below).
* Allow // comments.
* New compiler option -A (ANSI) that disables several extensions (asm
directive, // comments, unnamed function parameters) and also defines
a macro named __STRICT_ANSI__. The header files will exclude some
non-ANSI functions if __STRICT_ANSI__ is defined (that is, -A is given
on the command line).
-A will not disable the __asm__ directive (identifiers starting with
__ are in the namespace of the implementation).
* Create optimized code if the address of a variable is a constant. This
may be achieved by constructs like "*(char*)0x200 = 0x01" and is used
to access absolute memory locations. The compiler detects this case
also if structs or arrays are involved and generates direct stores and
fetches.
3. Known problems
-----------------
* No floats.
* Only simple automatic variables may be initialized (no arrays).
* "Wrong" order of arguments on the stack. The arguments are pushed in
the order, the arguments are parsed. That means that the va_xxx macros
in stdarg.h are ok (they work as expected), but the fixed parameters of
a function with a variable argument list do not match and must be
determined with the (non-standard) va_fix macro.
Using the __fixargs__ kludge, it is possible to write standard conform
va_xxx macros to work with variable sized argument lists. However, the
fixed parameters in the function itself usually have the wrong values,
because the order of the arguments on the stack is reversed compared to
a stock C compiler. Pushing the args the other way round requires much
work and a more elaborated intermediate code than cc65 has.
To understand the problem, have a look at this (non working!) sprintf
function:
int sprintf (char* buf, char* format, ...)
/* Non working version */
{
int count;
va_list ap;
va_start (ap, format);
count = vsprintf (buf, format, ap);
va_end (ap);
return count;
}
The problem here is in the "format" and "buf" parameters. They do (in
most cases) not contain, what the caller gave us as arguments. To
access the "real" arguments, use the va_fix macro. It is only valid
before the first call to va_arg, and takes the va_list and the number
of the fixed argument as parameters. So the right way would be
int sprintf (char* buf, char* format, ...)
/* Working version */
{
int count;
va_list ap;
va_start (ap, format);
count = vsprintf (va_fix (ap, 1), va_fix (ap, 2), ap);
va_end (ap);
return count;
}
The fixed parameter are obtained by using the va_fix macro with the
number of the parameter given as second argument. Beware: Since the
fixed arguments declared are usually one of the additional parameters,
the following code, which tries to be somewhat portable, does *not*
work. The assignment will overwrite the other parameters instead,
causing unexpected results:
int sprintf (char* buf, char* format, ...)
/* Non working version */
{
int count;
va_list ap;
va_start (ap, format);
#ifdef __CC65__
buf = va_fix (ap, 1);
format = va_fix (ap, 2);
#endif
count = vsprintf (buf, format, ap);
va_end (ap);
return count;
}
To write a portable version of sprintf, use code like this instead:
int sprintf (char* buf, char* format, ...)
/* Working version */
{
int count;
va_list ap;
va_start (ap, format);
#ifdef __CC65__
count = vsprintf (va_fix (ap, 1), va_fix (ap, 2), ap);
#else
count = vsprintf (buf, format, ap);
#endif
va_end (ap);
return count;
}
I know, va_fix is a kludge, but at least it *is* possible to write
functions with variable sized argument lists in a comfortable manner.
* The assembler still accepts lots of illegal stuff without an error (and
creates wrong code). Be careful!
* When starting a compiled program twice on the C64 (or 128), you may get
other results or the program may even crash. This is because static
variables do not have their startup values, they were changed in the
first run.
* There's only *one* symbol table level. It is - via a flag - used for both,
locals and global symbols. However, if you have variables in nested
blocks, the names may collide with the ones in the upper block. I will
probably add real symbol tables some time to remove this problem.
* Variables in nested blocks are handled inefficiently, especially in loops.
The frame on the stack is allocated and deallocated for each loop
iteration. There's no way around this, since the compiler has not enough
memory to hold a complete function body in memory (it would be able to
backpatch the frame generating code on function entry).
4. Library
----------
The C library is a complete rewrite and has nothing in common with the old
Atari stuff. When rewriting the library, I was guided by the following
rules:
* Use standard conform functions as far as possible. In addition, if
there's a ANSI-C compatible function, it should act as defined in the
ANSI standard. If if does not act as defined, this is an error.
* Do not use non-standard functions if the functionality of those
functions is covered by a standard function. Use exceptions only, if
there is a non-ANSI function that is very popular (example: itoa).
* Use new style prototpyes and header files.
* Make the library portable. For example, the complete stdio stuff is
based on only four system dependent functions:
open, read, write, close
So, if you rewrite these functions for a new system, all others
(printf, fprintf, fgets, fputc ...) will work, too.
* Do not expect a common character set. Unfortunately, I was not able to
be completely consequent in this respect. C sources are no problem
since the compiler does character translation, but the assembler
sources make assumptions about the following characters:
0 --> code $30
+ --> code $2B
- --> code $2D
All other functions (especially the isxxx ones) are table driven, so
only the classification table is system dependent.
The first port was for the ACE operating system. The current version has also
support for the C64, the C128 and the Plus/4 in native mode. The ACE port has
disk support but no conio module, all others don't have disk support but
direct console I/O.
Currently the following limitations the are known:
* getwd (ace) does not work. I get an error (carry flag) with an error
code of zero (aceErrStopped). Maybe my code is wrong...
* The error codes are currently system error codes. They should be
translated to something system independent. The ace codes are a good
starting point. However, I don't like the idea, that zero is a valid
error code, and some other codes are missing ("invalid parameter" and
more). As soon as this is done, it is also possible to write a
strerror() function to give more descriptive error messages to the
user.
* Many functions not very good tested.
* The printf and heap functions are way too big. Rewritting _printf
and malloc/free in assembler will probably squeeze 2K out of the
code.
* The isxxx functions do not handle EOF correctly. This is probably
a permanent restriction, even if it is non-standard. It would require
extra code in each of the isxxx functions, since EOF is defined as -1
and cannot be handled effectively with the table approach and 8 bit
index registers.
* The strcspn, strpbrk and strspn functions have a string length limitation
of 256 for the second argument. This is usually not a problem since the
second argument gives a character set, and a character set cannot be
larger than 256 chars for all known 6502 systems.
5. Bugs
-------
Please note that the compiler and the libraries are beta! Send bug reports to
uz@musoftware.de.

34
doc/readme.1st Normal file
View File

@ -0,0 +1,34 @@
If you have got the source package, see
doc/compile.txt
for instructions how to compile the stuff for the different systems.
If you have a binary package: Have a look in the doc directory for
information on how to use the tools. If you are new to cc65, the file
intro.txt may be of interest to you.
To avoid having to mess with paths, you may want to set the environment
variables
CC65_LIB
and CC65_INC
to the directory containing the libraries and the system include files
respectively. If you have installed cc65 in C:\cc65 (assuming a DOS or
Windows system), you should use
set CC65_LIB=c:\cc65\lib
and set CC65_INC=c:\cc65\include
Unix people probably know, how to translate these lines into the
appropriate Unix commands:-)
Have fun!
Uz

31
doc/readme.txt Normal file
View File

@ -0,0 +1,31 @@
Documentation overview:
ar65.txt - Describes the ar65 archiver.
debugging.txt - Debug programs using the VICE emulator.
ca65.txt - Describes the ca65 macro assembler.
cc65.txt - Describes the cc65 C compiler.
cl65.txt - Describes the cl65 compile & link utility.
coding.txt - Containes hints on creating the most effective code
with cc65.
intro.txt - Describes the use of the tools by a short "hello world"
example.
ld65.txt - Describes the ld65 linker.
library.txt - Describes the cc65 runtime and C libraries.
newvers.txt - Somewhat outdated. Lists the differences between the
current cc65 release and the original atari version
created by J.R Dunning.
readme.txt - This file.

88
include/6502.h Normal file
View File

@ -0,0 +1,88 @@
/*
* 6502.h
*
* Ullrich von Bassewitz, 20.09.1998
*/
#ifndef _6502_H
#define _6502_H
/* Possible returns of getcpu() */
#define CPU_6502 0
#define CPU_65C02 1
#define CPU_65816 2
unsigned char getcpu (void);
/* Detect the CPU the program is running on */
/* Macros for CPU instructions */
#define BRK() __asm__ ("\tbrk")
#define CLI() __asm__ ("\tcli")
#define SEI() __asm__ ("\tsei")
#define JAM() __asm__ ("\t.byte\t$02")
/* Struct that holds the registers for the sys function */
struct regs {
unsigned char a; /* A register value */
unsigned char x; /* X register value */
unsigned char y; /* Y register value */
unsigned char flags; /* Flags value */
unsigned pc; /* Program counter */
};
/* Defines for the flags in the regs structure */
#define F_NEG 0x80 /* N flag */
#define F_OVF 0x40 /* V flag */
#define F_BRK 0x10 /* B flag */
#define F_DEC 0x08 /* D flag */
#define F_IEN 0x04 /* I flag */
#define F_ZERO 0x02 /* Z flag */
#define F_CARRY 0x01 /* C flag */
/* Function to call any machine language subroutine. All registers in the
* regs structure are passed into the routine and the results are passed
* out. Some of the flags are ignored on input. The called routine must
* end with an RTS.
*/
void __fastcall__ _sys (struct regs* r);
/* Set and reset the break vector. The given user function is called if
* a break occurs. The values of the registers may be read from the brk_...
* variables. The value in brk_pc will point to the address that contains
* the brk instruction.
* The set_brk function will install an exit handler that will reset the
* vector if the program ends.
*/
extern unsigned char brk_a; /* A register value */
extern unsigned char brk_x; /* X register value */
extern unsigned char brk_y; /* Y register value */
extern unsigned char brk_sr; /* Status register */
extern unsigned brk_pc; /* PC value */
typedef void (*brk_handler) (void);
/* Type of the break handler */
void __fastcall__ set_brk (brk_handler f);
/* Set the break vector to the given address, return the old address */
void reset_brk (void);
/* Reset the break vector to the original value */
/* End of 6502.h */
#endif

38
include/_6525.h Normal file
View File

@ -0,0 +1,38 @@
/*
* _6525.h
*
* Ullrich von Bassewitz, 22.09.1998
*
* Internal include file, do not use directly.
*
*/
#ifndef __6525_H
#define __6525_H
/* Define a structure with the 6525 register offsets. The shadow registers
* (if port C is unused) are currently not implemented, we would need a
* union to do that, however that would introduce an additional name.
*/
struct __6525 {
unsigned char pra; /* Port register A */
unsigned char prb; /* Port register B */
unsigned char prc; /* Port register C */
unsigned char ddra; /* Data direction register A */
unsigned char ddrb; /* Data direction register B */
unsigned char ddrc; /* Data direction register C */
unsigned char cr; /* Control register */
unsigned char air; /* Active interrupt register */
};
/* End of _6525.h */
#endif

43
include/_6526.h Normal file
View File

@ -0,0 +1,43 @@
/*
* _6526.h
*
* Ullrich von Bassewitz, 22.09.1998
*
* Internal include file, do not use directly.
*
*/
#ifndef __6526_H
#define __6526_H
/* Define a structure with the 6526 register offsets */
struct __6526 {
unsigned char pra; /* Port register A */
unsigned char prb; /* Port register B */
unsigned char ddra; /* Data direction register A */
unsigned char ddrb; /* Data direction register B */
unsigned char ta_lo; /* Timer A, low byte */
unsigned char ta_hi; /* Timer A, high byte */
unsigned char tb_lo; /* Timer B, low byte */
unsigned char tb_hi; /* Timer B, high byte */
unsigned char tod_10; /* TOD, 1/10 sec. */
unsigned char tod_sec; /* TOD, seconds */
unsigned char tod_min; /* TOD, minutes */
unsigned char tod_hour; /* TOD, hours */
unsigned char sdr; /* Serial data register */
unsigned char icr; /* Interrupt control register */
unsigned char cra; /* Control register A */
unsigned char crb; /* Control register B */
};
/* End of _6526.h */
#endif

29
include/_6545.h Normal file
View File

@ -0,0 +1,29 @@
/*
* _6545.h
*
* Ullrich von Bassewitz, 22.09.1998
*
* Internal include file, do not use directly.
*
*/
#ifndef __6545_H
#define __6545_H
/* Define a structure with the 6545 register offsets */
struct __6545 {
unsigned char ctrl; /* Control register */
unsigned char data; /* Data register */
};
/* End of _6545.h */
#endif

31
include/_6551.h Normal file
View File

@ -0,0 +1,31 @@
/*
* _6551.h
*
* Ullrich von Bassewitz, 22.09.1998
*
* Internal include file, do not use directly.
*
*/
#ifndef __6551_H
#define __6551_H
/* Define a structure with the 6551 register offsets */
struct __6551 {
unsigned char data; /* Data register */
unsigned char status; /* Status register */
unsigned char cmd; /* Command register */
unsigned char ctrl; /* Control register */
};
/* End of _6551.h */
#endif

37
include/_antic.h Normal file
View File

@ -0,0 +1,37 @@
/*
* _antic.h
*
* Freddy Offenga, 4/9/2000
*
* Internal include file, do not use directly.
*
*/
#ifndef __ANTIC_H
#define __ANTIC_H
/* Define a structure with the antic register offsets */
struct __antic {
unsigned char dmactl; /* direct memory access control */
unsigned char chactl; /* character mode control */
unsigned char dlistl; /* display list pointer low-byte */
unsigned char dlisth; /* display list pointer high-byte */
unsigned char hscrol; /* horizontal scroll enable */
unsigned char vscrol; /* vertical scroll enable */
unsigned char unuse0; /* unused */
unsigned char pmbase; /* msb of p/m base address */
unsigned char unuse1; /* unused */
unsigned char chbase; /* character base address */
unsigned char wsync; /* wait for horizontal synchronization */
unsigned char vcount; /* vertical line counter */
unsigned char penh; /* light pen horizontal position */
unsigned char penv; /* light pen vertical position */
unsigned char nmien; /* non-maskable interrupt enable */
unsigned char nmires; /* nmi reset/status */
};
/* End of _antic.h */
#endif

78
include/_gtia.h Normal file
View File

@ -0,0 +1,78 @@
/*
* _gtia.h
*
* Freddy Offenga, 4/9/2000
*
* Internal include file, do not use directly.
*
*/
#ifndef __GTIA_H
#define __GTIA_H
/* Define a structure with the gtia register offsets */
struct __gtia_write {
unsigned char hposp0; /* horizontal position player 0 */
unsigned char hposp1; /* horizontal position player 1 */
unsigned char hposp2; /* horizontal position player 2 */
unsigned char hposp3; /* horizontal position player 3 */
unsigned char hposm0; /* horizontal position missile 0 */
unsigned char hposm1; /* horizontal position missile 1 */
unsigned char hposm2; /* horizontal position missile 2 */
unsigned char hposm3; /* horizontal position missile 3 */
unsigned char sizep0; /* size of player 0 */
unsigned char sizep1; /* size of player 1 */
unsigned char sizep2; /* size of player 2 */
unsigned char sizep3; /* size of player 3 */
unsigned char sizem; /* size of missiles */
unsigned char grafp0; /* graphics shape player 0 */
unsigned char grafp1; /* graphics shape player 1 */
unsigned char grafp2; /* graphics shape player 2 */
unsigned char grafp3; /* graphics shape player 3 */
unsigned char grafm; /* graphics shape missiles */
unsigned char colpm0; /* color player and missile 0 */
unsigned char colpm1; /* color player and missile 1 */
unsigned char colpm2; /* color player and missile 2 */
unsigned char colpm3; /* color player and missile 3 */
unsigned char colpf0; /* color playfield 0 */
unsigned char colpf1; /* color playfield 1 */
unsigned char colpf2; /* color playfield 2 */
unsigned char colpf3; /* color playfield 3 */
unsigned char colbk; /* color background */
unsigned char prior; /* priority selection */
unsigned char vdelay; /* vertical delay */
unsigned char gractl; /* stick/paddle latch, p/m control */
unsigned char hitclr; /* clear p/m collision */
unsigned char consol; /* console buttons */
};
/* Define a structure with the gtia register offsets */
struct __gtia_read {
unsigned char m0pf; /* missile 0 to playfield collision */
unsigned char m1pf; /* missile 1 to playfield collision */
unsigned char m2pf; /* missile 2 to playfield collision */
unsigned char m3pf; /* missile 3 to playfield collision */
unsigned char p0pf; /* player 0 to playfield collision */
unsigned char p1pf; /* player 1 to playfield collision */
unsigned char p2pf; /* player 2 to playfield collision */
unsigned char p3pf; /* player 3 to playfield collision */
unsigned char m0pl; /* missile 0 to player collision */
unsigned char m1pl; /* missile 1 to player collision */
unsigned char m2pl; /* missile 2 to player collision */
unsigned char m3pl; /* missile 3 to player collision */
unsigned char p0pl; /* player 0 to player collision */
unsigned char p1pl; /* player 1 to player collision */
unsigned char p2pl; /* player 2 to player collision */
unsigned char p3pl; /* player 3 to player collision */
unsigned char trig0; /* joystick trigger 0 */
unsigned char trig1; /* joystick trigger 1 */
unsigned char trig2; /* joystick trigger 2 */
unsigned char trig3; /* joystick trigger 3 */
unsigned char pal; /* pal/ntsc flag */
};
/* End of _gtia.h */
#endif

44
include/_pbi.h Normal file
View File

@ -0,0 +1,44 @@
/*
* _pbi.h
*
* Freddy Offenga, 4/25/2000
*
* Internal include file, do not use directly.
* Atari parallel bus definitions
*
*/
#ifndef __PBI_H
#define __PBI_H
/* parallel bus interface area */
#define PBI ((unsigned char*)0xD100)
/* parallel device IRQ status */
#define PDVI ((unsigned char*)0xD1FF)
/* parallel device select */
#define PDVS ((unsigned char*)0xD1FF)
/* parallel bus interface RAM area */
#define PBIRAM ((unsigned char*)0xD600)
/* parallel device ID 1 */
#define PDID1 ((unsigned char*)0xD803)
/* parallel device I/O vector */
#define PDIDV ((unsigned char*)0xD805)
/* parallel device IRQ vector */
#define PDIRQV ((unsigned char*)0xD808)
/* parallel device ID 2 */
#define PDID2 ((unsigned char*)0xD80B)
/* parallel device vector table */
#define PDVV ((unsigned char*)0xD80D)
/* End of _pbi.h */
#endif

25
include/_pia.h Normal file
View File

@ -0,0 +1,25 @@
/*
* _pia.h
*
* Freddy Offenga, 4/9/2000
*
* Internal include file, do not use directly.
*
*/
#ifndef __PIA_H
#define __PIA_H
/* Define a structure with the pia register offsets */
struct __pia {
unsigned char porta; /* port A data r/w */
unsigned char portb; /* port B data r/w */
unsigned char pactl; /* port A control */
unsigned char pbctl; /* port B control */
};
/* End of _pia.h */
#endif

55
include/_pokey.h Normal file
View File

@ -0,0 +1,55 @@
/*
* _pokey.h
*
* Freddy Offenga, 4/9/2000
*
* Internal include file, do not use directly.
*
*/
#ifndef __POKEY_H
#define __POKEY_H
/* Define a structure with the pokey register offsets */
struct __pokey_write {
unsigned char audf1; /* audio channel #1 frequency */
unsigned char audc1; /* audio channel #1 control */
unsigned char audf2; /* audio channel #2 frequency */
unsigned char audc2; /* audio channel #2 control */
unsigned char audf3; /* audio channel #3 frequency */
unsigned char audc3; /* audio channel #3 control */
unsigned char audf4; /* audio channel #4 frequency */
unsigned char audc4; /* audio channel #4 control */
unsigned char audctl; /* audio control */
unsigned char stimer; /* start pokey timers */
unsigned char skrest; /* reset serial port status reg. */
unsigned char potgo; /* start paddle scan sequence */
unsigned char unuse1; /* unused */
unsigned char serout; /* serial port data output */
unsigned char irqen; /* interrupt request enable */
unsigned char skctl; /* serial port control */
};
struct __pokey_read {
unsigned char pot0; /* paddle 0 value */
unsigned char pot1; /* paddle 1 value */
unsigned char pot2; /* paddle 2 value */
unsigned char pot3; /* paddle 3 value */
unsigned char pot4; /* paddle 4 value */
unsigned char pot5; /* paddle 5 value */
unsigned char pot6; /* paddle 6 value */
unsigned char pot7; /* paddle 7 value */
unsigned char allpot; /* eight paddle port status */
unsigned char kbcode; /* keyboard code */
unsigned char random; /* random number generator */
unsigned char unuse2; /* unused */
unsigned char unuse3; /* unused */
unsigned char serin; /* serial port input */
unsigned char irqst; /* interrupt request status */
unsigned char skstat; /* serial port status */
};
/* End of _pokey.h */
#endif

43
include/_sid.h Normal file
View File

@ -0,0 +1,43 @@
/*
* _sid.h
*
* Ullrich von Bassewitz, 22.09.1998
*
* Internal include file, do not use directly.
*
*/
#ifndef __SID_H
#define __SID_H
/* Define a structure with the sid register offsets */
struct __sid_voice {
unsigned freq; /* Frequency */
unsigned pw; /* Pulse width */
unsigned char ctrl; /* Control register */
unsigned char ad; /* Attack/decay */
unsigned char sr; /* Sustain/release */
};
struct __sid {
struct __sid_voice v1; /* Voice 1 */
struct __sid_voice v2; /* Voice 2 */
struct __sid_voice v3; /* Voice 3 */
unsigned flt_freq; /* Filter frequency */
unsigned char flt_ctrl; /* Filter control register */
unsigned char amp; /* Amplitude */
unsigned char ad1; /* A/D converter 1 */
unsigned char noise; /* Noise generator */
unsigned char read3; /* Value of voice 3 */
};
/* End of _sid.h */
#endif

29
include/_vdc.h Normal file
View File

@ -0,0 +1,29 @@
/*
* _vdc.h
*
* Ullrich von Bassewitz, 22.09.1998
*
* Internal include file, do not use directly.
*
*/
#ifndef __VDC_H
#define __VDC_H
/* Define a structure with the vdc register offsets */
struct __vdc {
unsigned char ctrl; /* Control register */
unsigned char data; /* Data register */
};
/* End of _vdc.h */
#endif

78
include/_vic.h Normal file
View File

@ -0,0 +1,78 @@
/*
* _vic.h
*
* Ullrich von Bassewitz, 12.08.1998
*
* Internal include file, do not use directly.
*
*/
#ifndef __VIC_H
#define __VIC_H
/* Define a structure with the vic register offsets */
struct __vic {
unsigned char spr0_x; /* Sprite 0, X coordinate */
unsigned char spr0_y; /* Sprite 0, Y coordinate */
unsigned char spr1_x; /* Sprite 1, X coordinate */
unsigned char spr1_y; /* Sprite 1, Y coordinate */
unsigned char spr2_x; /* Sprite 2, X coordinate */
unsigned char spr2_y; /* Sprite 2, Y coordinate */
unsigned char spr3_x; /* Sprite 3, X coordinate */
unsigned char spr3_y; /* Sprite 3, Y coordinate */
unsigned char spr4_x; /* Sprite 4, X coordinate */
unsigned char spr4_y; /* Sprite 4, Y coordinate */
unsigned char spr5_x; /* Sprite 5, X coordinate */
unsigned char spr5_y; /* Sprite 5, Y coordinate */
unsigned char spr6_x; /* Sprite 6, X coordinate */
unsigned char spr6_y; /* Sprite 6, Y coordinate */
unsigned char spr7_x; /* Sprite 7, X coordinate */
unsigned char spr7_y; /* Sprite 7, Y coordinate */
unsigned char spr_hi_x; /* High bits of X coordinate */
unsigned char ctrl1; /* Control register 1 */
unsigned char rasterline; /* Current raster line */
unsigned char strobe_x; /* Light pen, X position */
unsigned char strobe_y; /* Light pen, Y position */
unsigned char spr_ena; /* Enable sprites */
unsigned char ctrl2; /* Control register 2 */
unsigned char spr_exp_x; /* Expand sprites in X dir */
unsigned char addr; /* Address of chargen and video ram */
unsigned char irr; /* Interrupt request register */
unsigned char imr; /* Interrupt mask register */
unsigned char spr_bg_prio; /* Priority to background */
unsigned char spr_mcolor; /* Sprite multicolor bits */
unsigned char spr_exp_y; /* Expand sprites in Y dir */
unsigned char spr_coll; /* Sprite/sprite collision reg */
unsigned char spr_bg_coll; /* Sprite/background collision reg */
unsigned char bordercolor; /* Border color */
unsigned char bgcolor0; /* Background color 0 */
unsigned char bgcolor1; /* Background color 1 */
unsigned char bgcolor2; /* Background color 2 */
unsigned char bgcolor3; /* Background color 3 */
unsigned char spr_mcolor0; /* Color 0 for multicolor sprites */
unsigned char spr_mcolor1; /* Color 1 for multicolor sprites */
unsigned char spr0_color; /* Color sprite 0 */
unsigned char spr1_color; /* Color sprite 1 */
unsigned char spr2_color; /* Color sprite 2 */
unsigned char spr3_color; /* Color sprite 3 */
unsigned char spr4_color; /* Color sprite 4 */
unsigned char spr5_color; /* Color sprite 5 */
unsigned char spr6_color; /* Color sprite 6 */
unsigned char spr7_color; /* Color sprite 7 */
/* The following ones are only valid in the C128: */
unsigned char x_kbd; /* Additional keyboard lines */
unsigned char clock; /* Clock switch bit */
};
/* End of _vic.h */
#endif

86
include/ace.h Normal file
View File

@ -0,0 +1,86 @@
/*
* ace.h
*
* Ullrich von Bassewitz, 06.06.1998
*
*/
#ifndef _ACE_H
#define _ACE_H
#ifndef _STDDEF_H
#include <stddef.h>
#endif
struct aceDirentBuf {
unsigned long ad_size; /* Size in bytes */
unsigned char ad_date [8]; /* YY:YY:MM:DD:HH:MM:SS:TW */
char ad_type [4]; /* File type as ASCIIZ string */
unsigned char ad_flags; /* File flags */
unsigned char ad_usage; /* More flags */
unsigned char ad_namelen; /* Length of name */
char ad_name [17]; /* Name itself, ASCIIZ */
};
int aceDirOpen (char* dir);
int aceDirClose (int handle);
int aceDirRead (int handle, struct aceDirentBuf* buf);
/* Type of an ACE key. Key in low byte, shift mask in high byte */
typedef unsigned int aceKey;
/* #defines for the shift mask returned by aceConGetKey */
#define aceSH_KEY 0x00FF /* Mask key itself */
#define aceSH_MASK 0xFF00 /* Mask shift mask */
#define aceSH_EXT 0x2000 /* Extended key */
#define aceSH_CAPS 0x1000 /* Caps lock key */
#define aceSH_ALT 0x0800 /* Alternate key */
#define aceSH_CTRL 0x0400 /* Ctrl key */
#define aceSH_CBM 0x0200 /* Commodore key */
#define aceSH_SHIFT 0x0100 /* Shift key */
/* #defines for the options in aceConSetOpt/aceConGetOpt */
#define aceOP_PUTMASK 1 /* Console put mask */
#define aceOP_CHARCOLOR 2 /* Character color */
#define aceOP_CHARATTR 3 /* Character attribute */
#define aceOP_FILLCOLOR 4 /* Fill color */
#define aceOP_FILLATTR 5 /* Fill attribute */
#define aceOP_CRSCOLOR 6 /* Cursor color */
#define aceOP_CRSWRAP 7 /* Force cursor wrap */
#define aceOP_SHSCROLL 8 /* Shift keys for scrolling */
#define aceOP_MOUSCALE 9 /* Mouse scaling */
#define aceOP_RPTDELAY 10 /* Key repeat delay */
#define aceOP_RPTRATE 11 /* Key repeat rate */
/* Console functions */
void aceConWrite (char* buf, size_t count);
void aceConPutLit (int c);
void aceConPos (unsigned x, unsigned y);
void aceConGetPos (unsigned* x, unsigned* y);
unsigned aceConGetX (void);
unsigned aceConGetY (void);
char* aceConInput (char* buf, unsigned initial);
int aceConStopKey (void);
aceKey aceConGetKey (void);
int aceConKeyAvail (aceKey* key);
void aceConKeyMat (char* matrix);
void aceConSetOpt (unsigned char opt, unsigned char val);
int aceConGetOpt (unsigned char opt);
/* Misc stuff */
int aceMiscIoPeek (unsigned addr);
void aceMiscIoPoke (unsigned addr, unsigned char val);
/* End of ace.h */
#endif

58
include/apple2.h Normal file
View File

@ -0,0 +1,58 @@
/*
* apple2.h
*
* Written by Kevin Ruland.
*/
#ifndef _APPLE2_H
#define _APPLE2_H
/* Color Defines
* Since Apple2 does not support color text these defines are only
* used to get the library to compile correctly. They should not be used
* in user code
*/
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
/* Characters codes */
#define CH_DEL 0x7F
#define CH_ESC 0x1B
#define CH_CURS_UP 0x0B
#define CH_CURS_DOWN 0x0A
/* These are defined to be OpenApple + NumberKey */
#define CH_F1 0xB1
#define CH_F2 0xB2
#define CH_F3 0xB3
#define CH_F4 0xB4
#define CH_F5 0xB5
#define CH_F6 0xB6
#define CH_F7 0xB7
#define CH_F8 0xB8
#define CH_F9 0xB9
#define CH_F10 0xB0
#define CH_ULCORNER '+'
#define CH_URCORNER '+'
#define CH_LLCORNER '+'
#define CH_LRCORNER '+'
#define CH_TTEE '+'
#define CH_BTEE '+'
#define CH_LTEE '+'
#define CH_RTEE '+'
#define CH_CROSS '+'
/* End of apple2.h */
#endif

29
include/assert.h Normal file
View File

@ -0,0 +1,29 @@
/*
* assert.h
*
* Ullrich von Bassewitz, 06.06.1998
*
*/
#ifndef _ASSERT_H
#define _ASSERT_H
#undef assert
#ifdef NDEBUG
# define assert(expr)
#else
extern void _afailed (const char*, unsigned);
# define assert(expr) if ((expr) == 0) _afailed (__FILE__, __LINE__)
#endif
/* End of assert.h */
#endif

75
include/atari.h Normal file
View File

@ -0,0 +1,75 @@
/*
* atari.h
*
* Contributing authors:
* Mark Keates
* Freddy Offenga
* Christian Groessler
*/
#ifndef _ATARI_H
#define _ATARI_H
/* Color Defines */
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x0E
/* Characters codes */
#define CH_DEL 0xFE
#define CH_ESC 0x1B
#define CH_CURS_UP 28
#define CH_CURS_DOWN 29
#define CH_CURS_LEFT 30
#define CH_CURS_RIGHT 31
#define CH_TAB 0x7F /* tabulator */
#define CH_EOL 0x0B /* end-of-line marker */
#define CH_CLR 0x7D /* clear screen */
#define CH_BEL 0xFD /* bell */
#define CH_RUBOUT 0x7E /* back space (rubout) */
#define CH_DELLINE 0x9C /* delete line */
#define CH_INSLINE 0x9D /* insert line */
/* These are defined to be Atari + NumberKey */
#define CH_F1 177
#define CH_F2 178
#define CH_F3 179
#define CH_F4 180
#define CH_F5 181
#define CH_F6 182
#define CH_F7 183
#define CH_F8 184
#define CH_F9 185
#define CH_F10 176
#define CH_ULCORNER 0x11
#define CH_URCORNER 0x05
#define CH_LLCORNER 0x1A
#define CH_LRCORNER 0x03
#define CH_TTEE 0x17
#define CH_BTEE 0x18
#define CH_LTEE 0x01
#define CH_RTEE 0x04
#define CH_CROSS 0x19
#define CH_HLINE 0x12
#define CH_VLINE 0x16
/* Define hardware */
#include <_gtia.h>
#define GTIA (*(struct __gtia_write*)0xD000)
#define GTIA (*(struct __gtia_read*)0xD000)
#include <_pbi.h>
#include <_pokey.h>
#define POKEY (*(struct __pokey_write*)0xD200)
#define POKEY (*(struct __pokey_read*)0xD200)
#include <_pia.h>
#define PIA (*(struct __pia*)0xD300)
#include <_antic.h>
#define ANTIC (*(struct __antic*)0xD400)
/* End of atari.h */
#endif

68
include/c128.h Normal file
View File

@ -0,0 +1,68 @@
/*
* c128.h
*
* Ullrich von Bassewitz, 12.08.1998
*/
#ifndef _C128_H
#define _C128_H
/* Additional key defines */
#define CH_F1 133
#define CH_F2 137
#define CH_F3 134
#define CH_F4 138
#define CH_F5 135
#define CH_F6 139
#define CH_F7 136
#define CH_F8 140
/* Color defines */
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
#define COLOR_RED 0x02
#define COLOR_CYAN 0x03
#define COLOR_VIOLET 0x04
#define COLOR_GREEN 0x05
#define COLOR_BLUE 0x06
#define COLOR_YELLOW 0x07
#define COLOR_ORANGE 0x08
#define COLOR_BROWN 0x09
#define COLOR_LIGHTRED 0x0A
#define COLOR_GRAY1 0x0B
#define COLOR_GRAY2 0x0C
#define COLOR_LIGHTGREEN 0x0D
#define COLOR_LIGHTBLUE 0x0E
#define COLOR_GRAY3 0x0F
/* Define hardware */
#include <_vic.h>
#define VIC (*(struct __vic*)0xD000)
#include <_sid.h>
#define SID (*(struct __sid*)0xD400)
#include <_6526.h>
#define CIA1 (*(struct __6526*)0xDC00)
#define CIA2 (*(struct __6526*)0xDD00)
/* Define special memory areas */
#define COLOR_RAM ((unsigned char*)0xD800)
/* End of c128.h */
#endif

68
include/c64.h Normal file
View File

@ -0,0 +1,68 @@
/*
* c64.h
*
* Ullrich von Bassewitz, 12.08.1998
*/
#ifndef _C64_H
#define _C64_H
/* Additional key defines */
#define CH_F1 133
#define CH_F2 137
#define CH_F3 134
#define CH_F4 138
#define CH_F5 135
#define CH_F6 139
#define CH_F7 136
#define CH_F8 140
/* Color defines */
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
#define COLOR_RED 0x02
#define COLOR_CYAN 0x03
#define COLOR_VIOLET 0x04
#define COLOR_GREEN 0x05
#define COLOR_BLUE 0x06
#define COLOR_YELLOW 0x07
#define COLOR_ORANGE 0x08
#define COLOR_BROWN 0x09
#define COLOR_LIGHTRED 0x0A
#define COLOR_GRAY1 0x0B
#define COLOR_GRAY2 0x0C
#define COLOR_LIGHTGREEN 0x0D
#define COLOR_LIGHTBLUE 0x0E
#define COLOR_GRAY3 0x0F
/* Define hardware */
#include <_vic.h>
#define VIC (*(struct __vic*)0xD000)
#include <_sid.h>
#define SID (*(struct __sid*)0xD400)
#include <_6526.h>
#define CIA1 (*(struct __6526*)0xDC00)
#define CIA2 (*(struct __6526*)0xDD00)
/* Define special memory areas */
#define COLOR_RAM ((unsigned char*)0xD800)
/* End of c64.h */
#endif

74
include/cbm.h Normal file
View File

@ -0,0 +1,74 @@
/*
* cbm.h
*
* Ullrich von Bassewitz, 07.08.1998
*/
#ifndef _CBM_H
#define _CBM_H
/* Load the system specific files here, if needed */
#ifdef __C64__
#ifndef _C64_H
#include <c64.h>
#endif
#endif
#ifdef __C128__
#ifndef _C128_H
#include <c128.h>
#endif
#endif
#ifdef __PLUS4__
#ifndef _PLUS4_H
#include <plus4.h>
#endif
#endif
#ifdef __CBM610__
#ifndef _CBM610_H
#include <cbm610.h>
#endif
#endif
#ifdef __PET__
#ifndef _PET_H
#include <pet.h>
#endif
#endif
/* Characters codes (CBM charset) */
#define CH_HLINE 96
#define CH_VLINE 125
#define CH_ULCORNER 176
#define CH_URCORNER 174
#define CH_LLCORNER 173
#define CH_LRCORNER 189
#define CH_TTEE 178
#define CH_RTEE 179
#define CH_BTEE 177
#define CH_LTEE 171
#define CH_CROSS 123
#define CH_CURS_UP 145
#define CH_CURS_DOWN 17
#define CH_CURS_LEFT 157
#define CH_CURS_RIGHT 29
#define CH_PI 126
#define CH_DEL 20
#define CH_INS 148
#define CH_ESC 95
/* End of cbm.h */
#endif

73
include/cbm610.h Normal file
View File

@ -0,0 +1,73 @@
/*
* cbm610.h
*
* Ullrich von Bassewitz, 12.08.1998
*/
#ifndef _CBM610_H
#define _CBM610_H
/* Additional key defines */
#define CH_F1 224
#define CH_F2 225
#define CH_F3 226
#define CH_F4 227
#define CH_F5 228
#define CH_F6 229
#define CH_F7 230
#define CH_F8 231
#define CH_F9 232
#define CH_F10 233
#define CH_F11 234
#define CH_F12 235
#define CH_F13 236
#define CH_F14 237
#define CH_F15 238
#define CH_F16 239
#define CH_F17 240
#define CH_F18 241
#define CH_F19 242
#define CH_F20 243
/* Color defines */
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
/* Special routines to write bytes and words in the system bank */
void __fastcall__ pokebsys (unsigned addr, unsigned char val);
void __fastcall__ pokewsys (unsigned addr, unsigned val);
/* Define hardware */
#include <_6545.h>
#define CRTC (*(struct __6545)0xD800)
#include <_sid.h>
#define SID (*(struct __sid*)0xDA00)
#include <_6526.h>
#define CIA (*(struct __cia*)0xDC00)
#include <_6551.h>
#define ACIA (*(struct __6551*)0xDD00)
#include <_6525.h>
#define TPI1 (*(struct __6525*)0xDE00)
#define TPI2 (*(struct __6525*)0xDF00)
/* End of cbm610.h */
#endif

158
include/conio.h Normal file
View File

@ -0,0 +1,158 @@
/*
* conio.h
*
* Ullrich von Bassewitz, 06.08.1998
*
*
* This is the direct console interface for cc65. I do not like the function
* names very much, but the first version started as a rewrite of Borlands
* conio, and, even if the interface has changed, the names did not.
*
* The interface does direct screen I/O, so it is fast enough for most
* programs. I did not implement text windows, since many applications do
* not need them and should not pay for the additional overhead. It should
* be easy to add text windows on a higher level if needed,
*
* Most routines do not check the parameters. This may be unfortunate but is
* also related to speed. The coordinates are always 0/0 based.
*
*/
#ifndef _CONIO_H
#define _CONIO_H
#ifndef _STDARG_H
# include <stdarg.h>
#endif
/* Read the CBM file if we're compiling for a CBM machine */
#ifdef __CBM__
# ifndef _CBM_H
# include <cbm.h>
# endif
#endif
#ifdef __APPLE2__
# ifndef _APPLE2_H
# include <apple2.h>
# endif
#endif
#ifdef __ATARI__
# ifndef _ATARI_H
# include <atari.h>
# endif
#endif
/*****************************************************************************/
/* Functions */
/*****************************************************************************/
void clrscr (void);
/* Clear the whole screen and put the cursor into the top left corner */
unsigned char kbhit (void);
/* Return true if there's a key waiting, return false if not */
void __fastcall__ gotox (unsigned char x);
/* Set the cursor to the specified X position, leave the Y position untouched */
void __fastcall__ gotoy (unsigned char y);
/* Set the cursor to the specified Y position, leave the X position untouched */
void __fastcall__ gotoxy (unsigned char x, unsigned char y);
/* Set the cursor to the specified position */
unsigned char wherex (void);
/* Return the X position of the cursor */
unsigned char wherey (void);
/* Return the Y position of the cursor */
void __fastcall__ cputc (char c);
/* Output one character at the current cursor position */
void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c);
/* Same as "gotoxy (x, y); cputc (c);" */
void __fastcall__ cputs (const char* s);
/* Output a NUL terminated string at the current cursor position */
void __fastcall__ cputsxy (unsigned char x, unsigned char y, const char* s);
/* Same as "gotoxy (x, y); puts (s);" */
int cprintf (const char* format, ...);
/* Like printf, but uses direct screen I/O */
int vcprintf (const char* format, va_list ap);
/* Like vprintf, but uses direct screen I/O */
char cgetc (void);
/* Return a character from the keyboard. If there is no character available,
* the functions waits until the user does press a key. If cursor is set to
* 1 (see below), a blinking cursor is displayed while waiting.
*/
unsigned char __fastcall__ cursor (unsigned char onoff);
/* If onoff is 1, a cursor is display when waiting for keyboard input. If
* onoff is 0, the cursor is hidden when waiting for keyboard input. The
* function returns the old cursor setting.
*/
unsigned char __fastcall__ revers (unsigned char onoff);
/* Enable/disable reverse character display. This may not be supported by
* the output device. Return the old setting.
*/
unsigned char __fastcall__ textcolor (unsigned char color);
/* Set the color for text output. The old color setting is returned. */
unsigned char __fastcall__ bgcolor (unsigned char color);
/* Set the color for the background. The old color setting is returned. */
unsigned char __fastcall__ bordercolor (unsigned char color);
/* Set the color for the border. The old color setting is returned. */
void __fastcall__ chline (unsigned char length);
/* Output a horizontal line with the given length starting at the current
* cursor position.
*/
void __fastcall__ chlinexy (unsigned char x, unsigned char y, unsigned char length);
/* Same as "gotoxy (x, y); chline (length);" */
void __fastcall__ cvline (unsigned char length);
/* Output a vertical line with the given length at the current cursor
* position.
*/
void __fastcall__ cvlinexy (unsigned char x, unsigned char y, unsigned char length);
/* Same as "gotoxy (x, y); cvline (length);" */
void __fastcall__ cclear (unsigned char length);
/* Clear part of a line (write length spaces). */
void __fastcall__ cclearxy (unsigned char x, unsigned char y, unsigned char length);
/* Same as "gotoxy (x, y); cclear (length);" */
void __fastcall__ screensize (unsigned char* x, unsigned char* y);
/* Return the current screen size. */
void __fastcall__ cputhex8 (unsigned char val);
void __fastcall__ cputhex16 (unsigned val);
/* These shouldn't be here... */
/* End of conio.h */
#endif

70
include/ctype.h Normal file
View File

@ -0,0 +1,70 @@
/*
* ctype.h
*
* Ullrich von Bassewitz, 03.06.1998
*
*/
#ifndef _CTYPE_H
#define _CTYPE_H
int __fastcall__ isalnum (int c);
int __fastcall__ isalpha (int c);
int __fastcall__ iscntrl (int c);
int __fastcall__ isdigit (int c);
int __fastcall__ isgraph (int c);
int __fastcall__ islower (int c);
int __fastcall__ isprint (int c);
int __fastcall__ ispunct (int c);
int __fastcall__ isspace (int c);
int __fastcall__ isupper (int c);
int __fastcall__ isxdigit (int c);
#ifndef __STRICT_ANSI__
int __fastcall__ isblank (int c); /* cc65 (and GNU) extension */
#endif
int __fastcall__ toupper (int c); /* Always external */
int __fastcall__ tolower (int c); /* Always external */
/* When inlining of known function is enabled, overload most of the above
* functions by macros. The function prototypes are again available after
* #undef'ing the macros.
*/
#ifdef __OPT_s__
extern unsigned char _ctype[256];
#define isalnum(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$07"), __AX__)
#define isalpha(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$03"), __AX__)
#define iscntrl(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$10"), __AX__)
#define isdigit(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$04"), __AX__)
#define isgraph(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\teor\t#$30\n\tand\t#$30"), __AX__)
#define islower(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$01"), __AX__)
#define isprint(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\teor\t#$10\n\tand\t#$10"), __AX__)
#define ispunct(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\teor\t#$37\n\tand\t#$37"), __AX__)
#define isspace(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$60"), __AX__)
#define isupper(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$02"), __AX__)
#define isxdigit(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$08"), __AX__)
#ifndef __STRICT_ANSI__
/* cc65 and GNU extension */
#define isblank(c) (__AX__ = (c), __asm__ ("\ttay\n\tlda\t__ctype,y\n\tand\t#$80"), __AX__)
#endif
#endif
/* End of ctype.h */
#endif

96
include/dbg.h Normal file
View File

@ -0,0 +1,96 @@
/*
* dbg.h
*
* Ullrich von Bassewitz, 08.08.1998
*
*
* This is the interface to the cc65 debugger. Since many of the functions
* used for the debugger are quite usable even in another context, they
* are declared here.
*
* To use the debugger, just call DbgStart in your application. This will
* clear the screen and startup the debugger with the program counter
* pointing to the next instruction after the call to DbgStart. Once DbgStart
* has been executed, the debugger will also catch any BRK opcode. Use the
* BREAK function declared below to insert additional breakpoints into your
* code.
*
* There are currently a lot of things that cannot be debugged, graphical
* applications are an example. The debugger does not save your screen
* contents, so even your text screen gets destroyed. However, you can
* debug the C and runtime library, even if the debugger is using this
* stuff itself.
*
* Note: When using the debugger, there are some other identifiers with
* external linkage, that start with Dbg. Avoid those names if you use the
* module.
*/
#ifndef _DBG_H
#define _DBG_H
/*****************************************************************************/
/* Utuility functions */
/*****************************************************************************/
unsigned __fastcall__ DbgDisAsm (unsigned Addr, char* Buf, unsigned char Len);
/* Disassemble one instruction at address addr into the given buffer.
* The resulting line has the format, "AAAA__BB_BB_BB___OPC_OPERAND",
* where AAAA is the hexadecimal representation of addr, BB are the
* bytes (in hex) that make the instruction, OPC is the mnemonic, and
* OPERAND is an operand for the instruction.
* The buffer is filled with spaces up to the given length and terminated as
* a usual C string. NOTE: Buf must be able to hold Len+1 characters.
* The function returns the length of the disassembled instruction, so,
* to disassemble the next instruction, add the return value to addr
* and call the function again.
*/
unsigned __fastcall__ DbgDisAsmLen (unsigned Addr);
/* Disassemble one instruction, but do only return the length, do not
* create a visible representation. This function is useful when
* disassembling backwards, it is much faster than DbgDisAsm.
*/
int __fastcall__ DbgIsRAM (unsigned Addr);
/* Return true if we can read and write the given address */
char* DbgMemDump (unsigned Addr, char* Buf, unsigned char Len);
/* Create a line of a memory dump in the given buffer. The buffer contains
* the starting address (4 digits hex), then Len bytes in this format:
* "AAAA__XX_YY_ZZ_...". The passed char buffer must hold Len*3+5 bytes
* plus a terminator byte.
* The function does not work correctly if the created string is longer
* than 255 bytes.
* The return value is Buf.
*/
/*****************************************************************************/
/* High level user interface */
/*****************************************************************************/
void __fastcall__ DbgInit (unsigned unused);
/* Initialize the debugger. Use 0 as parameter. The debugger will popup on
* next brk encountered.
*/
#define BREAK() __asm__ ("\tbrk")
/* Use this to insert breakpoints into your code */
/* End of dbg.h */
#endif

54
include/errno.h Normal file
View File

@ -0,0 +1,54 @@
/*
* errno.h
*
* Ullrich von Bassewitz, 18.08.1998
*
*/
#ifndef _ERRNO_H
#define _ERRNO_H
/* Operating system specific error codes */
extern unsigned char _oserror;
/* Mapper function, don't call directly */
void _maperrno (void);
/* This one is called under the hood. User callable. */
int __fastcall__ _osmaperrno (unsigned char oserror);
/* System error codes go here */
extern int _errno;
/* errno must be a macro, here the mapper is called */
#define errno (_maperrno(), _errno)
/* Possible error codes */
#define ENOENT 1 /* No such file or directory */
#define ENOMEM 2 /* Out of memory */
#define EACCES 3 /* Permission denied */
#define ENODEV 4 /* No such device */
#define EMFILE 5 /* Too many open files */
#define EBUSY 6 /* Device or resource busy */
#define EINVAL 7 /* Invalid argument */
#define ENOSPC 8 /* No space left on device */
#define EEXIST 9 /* File exists */
#define EAGAIN 10 /* Try again */
#define EIO 11 /* I/O error */
#define EINTR 12 /* Interrupted system call */
#define ENOSYS 13 /* Function not implemented */
#define ESPIPE 14 /* Illegal seek */
#define EUNKNOWN 15 /* Unknown OS specific error */
#endif

39
include/fcntl.h Normal file
View File

@ -0,0 +1,39 @@
/*
* fcntl.h
*
* Ullrich von Bassewitz, 30.05.1998
*
*/
#ifndef _FCNTL_H
#define _FCNTL_H
/* Flag values for the open() call */
#define O_RDONLY 0x01
#define O_WRONLY 0x02
#define O_RDWR 0x03
#define O_CREAT 0x10
#define O_TRUNC 0x20
#define O_APPEND 0x40
/* Functions */
int open (const char* name, int flags, ...); /* May take a mode argument */
int close (int fd);
int write (int fd, const void* buf, unsigned count);
int read (int fd, void* buf, unsigned count);
int mkdir (const char* name, ...); /* May take a mode argument */
int rmdir (const char* name);
/* End of fcntl.h */
#endif

69
include/geos.h Normal file
View File

@ -0,0 +1,69 @@
/*
Supreme GEOS header file
includes all other headers
Maciej 'YTM/Alliance' Witkowiak, 27.10.1999
*/
#ifndef _GEOS_H
#define _GEOS_H
#ifndef _GCONST_H
#include <geos/gconst.h>
#endif
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
#ifndef _GSYM_H
#include <geos/gsym.h>
#endif
#ifndef _GDISK_H
#include <geos/gdisk.h>
#endif
#ifndef _GFILE_H
#include <geos/gfile.h>
#endif
#ifndef _GPROCESS_H
#include <geos/gprocess.h>
#endif
#ifndef _GGRAPH_H
#include <geos/ggraph.h>
#endif
#ifndef _GMENU_H
#include <geos/gmenu.h>
#endif
#ifndef _GSPRITE_H
#include <geos/gsprite.h>
#endif
#ifndef _GMEMORY_H
#include <geos/gmemory.h>
#endif
#ifndef _GSYS_H
#include <geos/gsys.h>
#endif
#ifndef _GDLGBOX_H
#include <geos/gdlgbox.h>
#endif
/* End of geos.h */
#endif

63
include/geos/gconst.h Normal file
View File

@ -0,0 +1,63 @@
/*
GEOS constants, 4-2-99, 18-3-99
small C version: 25-27.10.99
reassembled by Maciej 'YTM/Alliance' Witkowiak
*/
/* Here are constants which didn't fit into any other cathegory... */
#ifndef _GCONST_H
#define _GCONST_H
#define NULL 0
#define FALSE NULL
#define TRUE 0xff
#define MOUSE_SPRNUM 0
#define DISK_DRV_LGH 0x0d80
/* drivetypes */
#define DRV_NULL 0
#define DRV_1541 1
#define DRV_1571 2
#define DRV_1581 3
#define DRV_NETWORK 15
/* various disk constants */
#define REL_FILE_NUM 9
#define CMND_FILE_NUM 15
#define MAX_CMND_STR 32
#define DIR_1581_TRACK 40
#define DIR_ACC_CHAN 13
#define DIR_TRACK 18
#define N_TRACKS 35
#define DK_NM_ID_LEN 18
#define TRACK 9
#define SECTOR 12
#define TOTAL_BLOCKS 664
/* offset to something */
#define OFF_INDEX_PTR 1
/* values for MMU config - C128 */
#define CIOIN 0x7E
#define CRAM64K 0x7F
#define CKRNLBASIOIN 0x40
#define CKRNLIOIN 0x4E
/* alarmSetFlag */
#define ALARMMASK 4
#define CLR_SAVE 0x40
#define CONSTRAINED 0x40
#define UN_CONSTRAINED 0
#define FG_SAVE 0x80
#define FUTURE1 7
#define FUTURE2 8
#define FUTURE3 9
#define FUTURE4 10
#define USELAST 127
#define SHORTCUT 128
#endif

81
include/geos/gdisk.h Normal file
View File

@ -0,0 +1,81 @@
/*
GEOS functions from disk driver
ported to small C on 21.12.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GDISK_H
#define _GDISK_H
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
char __fastcall__ ReadBuff(struct tr_se *myTrSe);
char __fastcall__ WriteBuff(struct tr_se *myTrSe);
char __fastcall__ GetBlock(struct tr_se *myTrSe, char *buffer);
char __fastcall__ PutBlock(struct tr_se *myTrSe, char *buffer);
char __fastcall__ ReadBlock(struct tr_se *myTrSe, char *buffer);
char __fastcall__ WriteBlock(struct tr_se *myTrSe, char *buffer);
char __fastcall__ VerWriteBlock(struct tr_se *myTrSe, char *buffer);
int __fastcall__ CalcBlksFree(void);
char __fastcall__ ChkDkGEOS(void);
char __fastcall__ SetGEOSDisk(void);
char __fastcall__ NewDisk(void);
char __fastcall__ OpenDisk(void);
char __fastcall__ FindBAMBit(struct tr_se *myTrSe);
char __fastcall__ BlkAlloc(struct tr_se output[], int length);
char __fastcall__ NxtBlkAlloc(struct tr_se *startTrSe,
struct tr_se output[], int length);
char __fastcall__ FreeBlock(struct tr_se *myTrSe);
struct tr_se __fastcall__ SetNextFree(struct tr_se *myTrSe);
// above needs (int) casts on both sides of '='
char __fastcall__ GetDirHead(void);
char __fastcall__ PutDirHead(void);
void __fastcall__ GetPtrCurDkNm(char *name);
void __fastcall__ EnterTurbo(void);
void __fastcall__ ExitTurbo(void);
void __fastcall__ PurgeTurbo(void);
char __fastcall__ ChangeDiskDevice(char newdev);
/* disk header offsets */
#define OFF_TO_BAM 4
#define OFF_DISK_NAME 144
#define OFF_GS_DTYPE 189
#define OFF_OP_TR_SC 171
#define OFF_GS_ID 173
/* disk errors */
#define ANY_FAULT 0xf0
#define NO_BLOCKS 1
#define INV_TRACK 2
#define INSUFF_SPACE 3
#define FULL_DIRECTORY 4
#define FILE_NOT_FOUND 5
#define BAD_BAM 6
#define UNOPENED_VLIR 7
#define INV_RECORD 8
#define OUT_OF_RECORDS 9
#define STRUCT_MISMAT 10
#define BFR_OVERFLOW 11
#define CANCEL_ERR 12
#define DEV_NOT_FOUND 13
#define INCOMPATIBLE 14
#define HDR_NOT_THERE 0x20
#define NO_SYNC 0x21
#define DBLK_NOT_THERE 0x22
#define DAT_CHKSUM_ERR 0x23
#define WR_VER_ERR 0x25
#define WR_PR_ON 0x26
#define HDR_CHKSUM_ERR 0x27
#define DSK_ID_MISMAT 0x29
#define BYTE_DEC_ERR 0x2e
#define DOS_MISMATCH 0x73
#endif

102
include/geos/gdlgbox.h Normal file
View File

@ -0,0 +1,102 @@
/*
GEOS dialog box functions
ported to small C on 26.12.1999
by Maciej 'YTM/Alliance' Witkowiak
10.03.2000 - update
*/
#ifndef _GDLGBOX_H
#define _GDLGBOX_H
char __fastcall__ DoDlgBox(char *dboxstring);
char __fastcall__ RstrFrmDialogue(void);
/* These are custom, predefined dialog boxes, I'm sure you'll find them usable
Most of them show 2 lines of text */
char __fastcall__ DlgBoxYesNo(char *line1, char *line2);
char __fastcall__ DlgBoxOkCancel(char *line1, char *line2);
void __fastcall__ DlgBoxOk(char *line1, char *line2);
char __fastcall__ DlgBoxGetString(char *myString, char strLength,
char *line1, char *line2);
char __fastcall__ DlgBoxFileSelect(char *classtxt, char ftype,
char *fname);
/* Now the command string type */
typedef void dlgBoxStr;
/* and command string commands - macros */
#define DB_DEFPOS(pattern) (char)(DEF_DB_POS | (pattern))
#define DB_SETPOS(pattern,top,bot,left,right) \
(char)(SET_DB_POS | (pattern)), (char)(top), (char)(bot), \
(unsigned)(left), (unsigned)(right)
#define DB_ICON(i,x,y) (char)(i), (char)(x), (char)(y)
#define DB_TXTSTR(x,y,text) (char)DBTXTSTR, (char)(x), (char)(y), (text)
#define DB_VARSTR(x,y,ptr) (char)DBVARSTR, (char)(x), (char)(y), (char)(ptr)
#define DB_GETSTR(x,y,ptr,length) (char)DBGETSTRING, (char)(x), (char)(y), (char)(ptr), (char)(length)
#define DB_SYSOPV(ptr) (char)DBSYSOPV, (unsigned)(ptr)
#define DB_GRPHSTR(ptr) (char)DBGRPHSTR, (unsigned)(ptr)
#define DB_GETFILES(x,y) (char)DBGETFILES, (char)(x), (char)(y)
#define DB_OPVEC(ptr) (char)DBOPVEC, (unsigned)(ptr)
#define DB_USRICON(x,y,ptr) (char)DBUSRICON, (char)(x), (char)(y), (unsigned)(ptr)
#define DB_USRROUT(ptr) (char)DB_USR_ROUT, (unsigned)(ptr)
#define DB_END (char)NULL
/*
part of constants below is used internally, but some are useful for macros above
*/
/* icons for DB_ICON */
#define OK 1
#define CANCEL 2
#define YES 3
#define NO 4
#define OPEN 5
#define DISK 6
/* commands - internally used by command macros */
#define DBTXTSTR 11
#define DBVARSTR 12
#define DBGETSTRING 13
#define DBSYSOPV 14
#define DBGRPHSTR 15
#define DBGETFILES 16
#define DBOPVEC 17
#define DBUSRICON 18
#define DB_USR_ROUT 19
/* icons tabulation in standard window */
#define DBI_X_0 1
#define DBI_X_1 9
#define DBI_X_2 17
#define DBI_Y_0 8
#define DBI_Y_1 40
#define DBI_Y_2 72
/* standard window size defaults */
#define SET_DB_POS 0
#define DEF_DB_POS 0x80
#define DEF_DB_TOP 32
#define DEF_DB_BOT 127
#define DEF_DB_LEFT 64
#define DEF_DB_RIGHT 255
/* text tabulation in standard window */
#define TXT_LN_1_Y 16
#define TXT_LN_2_Y 32
#define TXT_LN_3_Y 48
#define TXT_LN_4_Y 64
#define TXT_LN_5_Y 80
#define TXT_LN_X 16
/* system icons size */
#define SYSDBI_HEIGHT 16
#define SYSDBI_WIDTH 6
/* dialogbox string offsets */
#define OFF_DB_FORM 0
#define OFF_DB_TOP 1
#define OFF_DB_BOT 2
#define OFF_DB_LEFT 3
#define OFF_DB_RIGHT 5
#define OFF_DB_1STCMD 7
#endif

101
include/geos/gfile.h Normal file
View File

@ -0,0 +1,101 @@
/*
GEOS filesystem functions
ported to small C on 25.12.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GFILE_H
#define _GFILE_H
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
struct filehandle *__fastcall__ Get1stDirEntry(void);
struct filehandle *__fastcall__ GetNxtDirEntry(void);
char __fastcall__ FindFTypes(char *buffer, char ftype, char fmaxnum, char *classtxt);
char __fastcall__ FindFile(char *fname);
char __fastcall__ ReadFile(struct tr_se *myTrSe, char *buffer, int flength);
char __fastcall__ SaveFile(struct fileheader *myHeader);
char __fastcall__ FreeFile(struct tr_se myTable[]);
char __fastcall__ DeleteFile(char *fname);
char __fastcall__ RenameFile(char *source, char *target);
char __fastcall__ ReadByte(void);
char __fastcall__ FollowChain(struct tr_se *startTrSe, char *buffer);
char __fastcall__ GetFHdrInfo(struct filehandle *myFile);
char __fastcall__ OpenRecordFile(char *fname);
char __fastcall__ CloseRecordFile(void);
char __fastcall__ NextRecord(void);
char __fastcall__ PreviousRecord(void);
char __fastcall__ PointRecord(char);
char __fastcall__ DeleteRecord(void);
char __fastcall__ InsertRecord(void);
char __fastcall__ AppendRecord(void);
char __fastcall__ ReadRecord(char *buffer, int flength);
char __fastcall__ WriteRecord(char *buffer, int flength);
char __fastcall__ UpdateRecordFile(void);
/* GEOS filetypes */
#define NOT_GEOS 0
#define BASIC 1
#define ASSEMBLY 2
#define DATA 3
#define SYSTEM 4
#define DESK_ACC 5
#define APPLICATION 6
#define APPL_DATA 7
#define FONT 8
#define PRINTER 9
#define INPUT_DEVICE 10
#define DISK_DEVICE 11
#define SYSTEM_BOOT 12
#define TEMPORARY 13
#define AUTO_EXEC 14
#define INPUT_128 15
#define NUMFILETYPES 16
/* supported structures */
#define SEQUENTIAL 0
#define VLIR 1
/* DOS filetypes */
#define DEL 0
#define SEQ 1
#define PRG 2
#define USR 3
#define REL 4
#define CBM 5
/* directory offsets */
/* offsets in dir entry */
#define FRST_FILE_ENTRY 2
#define OFF_CFILE_TYPE 0
#define OFF_DE_TR_SC 1
#define OFF_FNAME 3
#define OFF_GHDR_PTR 19
#define OFF_GSTRUC_TYPE 21
#define OFF_GFILE_TYPE 22
#define OFF_YEAR 23
#define OFF_SIZE 28
#define OFF_NXT_FILE 32
/* offsets in file header */
#define O_GHIC_WIDTH 2
#define O_GHIC_HEIGHT 3
#define O_GHIC_PIC 4
#define O_GHCMDR_TYPE 68
#define O_GHGEOS_TYPE 69
#define O_GHSTR_TYPE 70
#define O_GHST_ADDR 71
#define O_GHEND_ADDR 73
#define O_GHST_VEC 75
#define O_GHFNAME 77
#define O_128_FLAGS 96
#define O_GH_AUTHOR 97
#define O_GHP_DISK 97
#define O_GHP_FNAME 117
#define O_GHINFO_TXT 0xa0
#endif

170
include/geos/ggraph.h Normal file
View File

@ -0,0 +1,170 @@
/*
GEOS graphic (non icon/menu/sprite) functions
ported to small C on 29.10.1999
by Maciej 'YTM/Alliance' Witkowiak
10,11.03.2000 - updates
*/
#ifndef _GGRAPH_H
#define _GGRAPH_H
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
void __fastcall__ SetPattern(char newpattern);
void __fastcall__ HorizontalLine(char pattern, char y, int xstart, int xend);
void __fastcall__ InvertLine(char y, int xstart, int xend);
void __fastcall__ RecoverLine(char y, int xstart, int xend);
void __fastcall__ VerticalLine(char pattern, char ystart, char yend, int x);
void __fastcall__ InitDrawWindow(struct window *myRectangle);
void __fastcall__ Rectangle(void);
void __fastcall__ FrameRectangle(char pattern);
void __fastcall__ InvertRectangle(void);
void __fastcall__ ImprintRectangle(void);
void __fastcall__ RecoverRectangle(void);
void __fastcall__ DrawLine(struct window *topBotCoords);
void __fastcall__ DrawPoint(struct pixel *myPixel);
char __fastcall__ TestPoint(struct pixel *myPixel);
void __fastcall__ PutChar(char character, char y, int x);
void __fastcall__ PutString(char *myString, char y, int x);
void __fastcall__ PutDecimal(char style, int value, char y, int x);
char __fastcall__ GetCharWidth(char character);
void __fastcall__ LoadCharSet(struct fontdesc *myFont);
void __fastcall__ UseSystemFont(void);
void __fastcall__ BitmapUp(struct iconpic *myIcon);
void __fastcall__ BitmapClip(char skipl, char skipr, int skiptop,
struct iconpic *myIcon);
void __fastcall__ BitOtherClip(void *proc1, void *proc2, char skipl,
char skipr, int skiptop,
struct iconpic *myIcon);
void __fastcall__ GraphicsString(char *myGfxString);
/* VIC colour constants */
#define BLACK 0
#define WHITE 1
#define RED 2
#define CYAN 3
#define PURPLE 4
#define GREEN 5
#define BLUE 6
#define YELLOW 7
#define ORANGE 8
#define BROWN 9
#define LTRED 10
#define DKGREY 11
#define GREY 12
#define MEDGREY 12
#define LTGREEN 13
#define LTBLUE 14
#define LTGREY 15
/* VIC memory banks */
#define GRBANK0 3
#define GRBANK1 2
#define GRBANK2 1
#define GRBANK3 0
/* VIC screen sizes */
#define VIC_X_POS_OFF 24
#define VIC_Y_POS_OFF 50
#define SC_BYTE_WIDTH 40
#define SC_PIX_HEIGHT 200
#define SC_PIX_WIDTH 320
#define SC_SIZE 8000
/* VDC screen constants */
#define SCREENBYTEWIDTH 80
#define SCREENPIXELWIDTH 640
/* control characters for use as numbers, not chars */
#define EOF 0
#define BACKSPACE 8
#define FORWARDSPACE 9
#define TAB 9
#define LF 10
#define HOME 11
#define PAGE_BREAK 12
#define UPLINE 12
#define CR 13
#define ULINEON 14
#define ULINEOFF 15
#define ESC_GRAPHICS 16
#define ESC_RULER 17
#define REV_ON 18
#define REV_OFF 19
#define GOTOX 20
#define GOTOY 21
#define GOTOXY 22
#define NEWCARDSET 23
#define BOLDON 24
#define ITALICON 25
#define OUTLINEON 26
#define PLAINTEXT 27
/* control characters for use in
strings: eg: str[10]=BOLD "Hello"; */
#define CCR "\015"
#define CULINEON "\016"
#define CULINEOFF "\017"
#define CREV_ON "\022"
#define CREV_OFF "\023"
#define CBOLDON "\030"
#define CITALICON "\031"
#define COUTLINEON "\032"
#define CPLAINTEXT "\033"
/*values of currentMode */
/* bitNumbers */
#define UNDERLINE_BIT 7
#define BOLD_BIT 6
#define REVERSE_BIT 5
#define ITALIC_BIT 4
#define OUTLINE_BIT 3
#define SUPERSCRIPT_BIT 2
#define SUBSCRIPT_BIT 1
/* bitMasks */
#define SET_UNDERLINE 0x80
#define SET_BOLD 0x40
#define SET_REVERSE 0x20
#define SET_ITALIC 0x10
#define SET_OUTLINE 0x08
#define SET_SUPERSCRIPT 0x04
#define SET_SUBSCRIPT 0x02
#define SET_PLAINTEXT 0
/* values of dispBufferOn */
#define ST_WRGS_FORE 0x20
#define ST_WR_BACK 0x40
#define ST_WR_FORE 0x80
/* PutDecimal parameters */
/* leading 0s? */
#define SET_NOSURPRESS 0
#define SET_SURPRESS 0x40
/* justification */
#define SET_RIGHTJUST 0
#define SET_LEFTJUST 0x80
/* C128 x flags */
#define ADD1_W 0x2000
#define DOUBLE_B 0x80
#define DOUBLE_W 0x8000
typedef void graphicStr;
#define MOVEPENTO(x,y) (char)1, (unsigned)(x), (char)(y)
#define LINETO(x,y) (char)2, (unsigned)(x), (char)(y)
#define RECTANGLETO(x,y) (char)3, (unsigned)(x), (char)(y)
#define NEWPATTERN(p) (char)5, (char)(p)
#define FRAME_RECTO(x,y) (char)7, (unsigned)(x), (char)(y)
#define PEN_X_DELTA(x) (char)8, (unsigned)(x)
#define PEN_Y_DELTA(y) (char)9, (char)(y)
#define PEN_XY_DELTA(x,y) (char)10, (unsigned)(x), (char)(y)
#define GSTR_END (char)NULL
/* ESC_PUTSTRING can't be implemented - it needs text, not pointer to it
#define ESC_PUTSTRING(x,y,text) (char)6, (unsigned)(x), (char)(y), (text), (char)NULL
*/
#endif

33
include/geos/gmemory.h Normal file
View File

@ -0,0 +1,33 @@
/*
GEOS memory and string functions
ported to small C on 27.10.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GMEMORY_H
#define _GMEMORY_H
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
void __fastcall__ CopyString(char *dest, char *source);
void __fastcall__ CmpString(char *dest, char *source);
void __fastcall__ CopyFString(char len, char *dest, char *source);
void __fastcall__ CmpFString(char len, char *dest, char *source);
int __fastcall__ CRC(char *buffer, int len);
void __fastcall__ ClearRam(char *dest, int len);
void __fastcall__ FillRam(char what, char *dest, int len);
void __fastcall__ MoveData(char *source, char *dest, int len);
void __fastcall__ InitRam(char *myInitTab);
void __fastcall__ StashRAM(char REUBank, int len, char *reuaddy, char *cpuaddy);
void __fastcall__ FetchRAM(char REUBank, int len, char *reuaddy, char *cpuaddy);
void __fastcall__ SwapRAM(char REUBank, int len, char *reuaddy, char *cpuaddy);
char __fastcall__ VerifyRAM(char REUBank, int len, char *reuaddy, char *cpuaddy);
#endif

56
include/geos/gmenu.h Normal file
View File

@ -0,0 +1,56 @@
/*
GEOS menu and icon functions
ported to small C on 27.10.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GMENU_H
#define _GMENU_H
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
void __fastcall__ DoMenu(struct menu *myMenu);
void __fastcall__ ReDoMenu(void);
void __fastcall__ RecoverMenu(void);
void __fastcall__ RecoverAllMenus(void);
void __fastcall__ DoPreviousMenu(void);
void __fastcall__ GotoFirstMenu(void);
void __fastcall__ DoIcons(struct icontab *myIconTab);
/* DoMenu - menutypes */
#define MENU_ACTION 0x00
#define DYN_SUB_MENU 0x40
#define SUB_MENU 0x80
#define HORIZONTAL 0x00
#define VERTICAL 0x80
/* menu string offsets */
#define OFF_MY_TOP 0
#define OFF_MY_BOT 1
#define OFF_MX_LEFT 2
#define OFF_MX_RIGHT 4
#define OFF_NUM_M_ITEMS 6
#define OFF_1ST_M_ITEM 7
/* icon string offsets */
#define OFF_NM_ICNS 0
#define OFF_IC_XMOUSE 1
#define OFF_IC_YMOUSE 3
#define OFF_PIC_ICON 0
#define OFF_X_ICON_POS 2
#define OFF_Y_ICON_POS 3
#define OFF_WDTH_ICON 4
#define OFF_HEIGHT_ICON 5
#define OFF_SRV_RT_ICON 6
#define OFF_NX_ICON 8
/* icons, menus status flags */
#define ST_FLASH 0x80
#define ST_INVERT 0x40
#define ST_LD_AT_ADDR 0x01
#define ST_LD_DATA 0x80
#define ST_PR_DATA 0x40
#define ST_WR_PR 0x40
#endif

41
include/geos/gprocess.h Normal file
View File

@ -0,0 +1,41 @@
/*
GEOS processes (~multitasking) functions
ported to small C on 27.10.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GPROCESS_H
#define _GPROCESS_H
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
void __fastcall__ InitProcesses(char number, struct process *proctab);
void __fastcall__ RestartProcess(char number);
void __fastcall__ EnableProcess(char number);
void __fastcall__ BlockProcess(char number);
void __fastcall__ UnBlockProcess(char number);
void __fastcall__ FreezeProcess(char number);
void __fastcall__ UnFreezeProcess(char number);
void __fastcall__ Sleep(int jiffies);
/* Process control variable
these probably should be removed from here, as they are
internal GEOS information which is updated by functions above
*/
/* bit numbers */
#define RUNABLE_BIT 7
#define BLOCKED_BIT 6
#define FROZEN_BIT 5
#define NOTIMER_BIT 4
/* bit masks */
#define SET_RUNABLE 0x80
#define SET_BLOCKED 0x40
#define SET_FROZEN 0x20
#define SET_NOTIMER 0x10
#endif

90
include/geos/gsprite.h Normal file
View File

@ -0,0 +1,90 @@
/*
GEOS mouse and sprite functions
ported to small C on 27.10.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GSPRITE_H
#define _GSPRITE_H
void __fastcall__ StartMouseMode(void);
void __fastcall__ ClearMouseMode(void);
void __fastcall__ MouseUp(void);
void __fastcall__ MouseOff(void);
char __fastcall__ IsMseInRegion(struct window *region);
void __fastcall__ DrawSprite(char spritenum, char *spritepic);
void __fastcall__ PosSprite(char spritenum, struct pixel *position);
void __fastcall__ EnablSprite(char spritenum);
void __fastcall__ DisablSprite(char spritenum);
void __fastcall__ InitTextPrompt(char height);
void __fastcall__ PromptOn(struct pixel *position);
void __fastcall__ PromptOff(void);
char __fastcall__ GetNextChar(void);
/* keyboard constants */
#define KEY_F1 1
#define KEY_F2 2
#define KEY_F3 3
#define KEY_F4 4
#define KEY_F5 5
#define KEY_F6 6
#define KEY_NOSCRL 7
#define KEY_ENTER 11
#define KEY_F7 14
#define KEY_F8 15
#define KEY_UP 16
#define KEY_DOWN 17
#define KEY_HOME 18
#define KEY_CLEAR 19
#define KEY_LARROW 20
#define KEY_UPARROR 21
#define KEY_STOP 22
#define KEY_RUN 23
#define KEY_BPS 24
#define KEY_HELP 25
#define KEY_ALT 26
#define KEY_ESC 27
#define KEY_INSERT 28
#define KEY_DELETE 29
#define KEY_RIGHT 30
#define KEY_INVALID 31
#define KEY_LEFT BACKSPACE
/* values of faultData - pointer position vs. mouseWindow */
/* bit numbers */
#define OFFTOP_BIT 7
#define OFFBOTTOM_BIT 6
#define OFFLEFT_BIT 5
#define OFFRIGHT_BIT 4
#define OFFMENU_BIT 3
/* bit masks */
#define SET_OFFTOP 0x80
#define SET_OFFBOTTOM 0x40
#define SET_OFFLEFT 0x20
#define SET_OFFRIGHT 0x10
#define SET_OFFMENU 0x08
/* mouseOn */
/* bit numbers */
#define MOUSEON_BIT 7
#define MENUON_BIT 6
#define ICONSON_BIT 5
/* bit masks */
#define SET_MSE_ON 0x80
#define SET_MENUON 0x40
#define SET_ICONSON 0x20
/* pressFlag */
/* bit numbers */
#define KEYPRESS_BIT 7
#define INPUT_BIT 6
#define MOUSE_BIT 5
/* bit masks */
#define SET_KEYPRESS 0x80
#define SET_INPUTCHG 0x40
#define SET_MOUSE 0x20
#endif

136
include/geos/gstruct.h Normal file
View File

@ -0,0 +1,136 @@
/*
GEOS structs
ported to small C on 25-27.10.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GSTRUCT_H
#define _GSTRUCT_H
struct f_date { /* date in filedesctiptor */
char f_year;
char f_month;
char f_day;
char f_hour;
char f_minute;
};
struct s_date { /* system date & time */
char s_year;
char s_month;
char s_day;
char s_hour;
char s_minutes;
char s_seconds;
};
struct tr_se { /* track and sector */
char track;
char sector;
};
struct fileheader { /* header block (like fileHeader) */
struct tr_se n_block;
char icon_desc[3];
char icon_pic[63];
char dostype;
char type;
char structure;
int load_address;
int end_address;
int exec_address;
char class_name[19];
char column_flag;
char author[64];
char note[95];
};
struct filehandle { /* filehandle in directory sectors */
char dostype; /* or in dirEntryBuf */
struct tr_se n_block;
char name[16];
struct tr_se header;
char structure;
char type;
struct f_date date;
int size;
};
struct pixel { /* describes point */
int x;
char y;
};
struct fontdesc { /* describes font */
char baseline;
char width;
char height;
char *index_tbl;
char *data_ptr;
};
struct window { /* describes screen region */
char top;
char bot;
int left;
int right;
};
struct VLIR_info { /* VLIR information */
char curRecord; /* currently only used in VLIR */
char usedRecords; /* as system info (curRecord is mainly of your interest */
char fileWritten;
int fileSize;
};
struct process { /* process info, declare table of that type */
int pointer; /* (like: struct process proctab[2]=... */
int jiffies; /* last entry HAVE TO BE {0,0} */
};
struct iconpic { /* icon/encoded bitmap description */
char *pic_ptr; /* ptr to a photo scrap (or encoded bitmap) */
char x; /* position in cards (*8 pixels) */
char y;
char width; /* in cards */
char heigth; /* in lines (pixels) */
};
struct icondef { /* icon definition for DoIcons */
char *pic_ptr; /* ptr to a photo scrap (or encoded bitmap) */
char x; /* position in cards (*8 pixels) */
char y;
char width; /* of icon (in cards) */
char heigth; /* of icon in lines (pixels) */
int proc_ptr; /* pointer to function handling that icon */
};
struct icontab {
char number; /* number of declared icons */
struct pixel mousepos; /* position of mouse after DoIcons */
struct icondef tab[]; /* table of size declared by icontab.number */
};
/* everything below is obsolete and kept for unknown reasons */
struct menuitem {
char *name;
char type;
int rest; /* may be ptr to function, or if submenu ptr to struct menu */
};
struct menu {
struct window size;
char number;
struct menuitem items[];
};
struct inittab { /* use struct inittab mytab[n] for initram */
int ptr; /* ptr to 1st byte */
char number; /* number of following bytes */
char values[]; /* warning - in table size of this is same for all! */
};
#endif

302
include/geos/gsym.h Normal file
View File

@ -0,0 +1,302 @@
/*
GEOS constants reassembled 4-2-99
ported to small C 26.8.99, 25-26.10.99
Maciej 'YTM/Alliance' Witkowiak
ytm@friko.onet.pl
*/
#ifndef _GSYM_H
#define _GSYM_H
#ifndef _GSTRUCT_H
#include <geos/gstruct.h>
#endif
#define nameBuf char[17]
#define blockBuf char[256]
#define zpage *(char*)0x0000
#define CPU_DDR *(char*)0x00
#define CPU_DATA *(char*)0x01
#define r0 *(unsigned int*)0x02
#define r0L *(char*)0x02
#define r0H *(char*)0x03
#define r1 *(unsigned int*)0x04
#define r1L *(char*)0x04
#define r1H *(char*)0x05
#define drawWindow (*(struct window*)0x06)
#define r2 *(unsigned int*)0x06
#define r2L *(char*)0x06
#define r2H *(char*)0x07
#define r3 *(unsigned int*)0x08
#define r3L *(char*)0x08
#define r3H *(char*)0x09
#define r4 *(unsigned int*)0x0a
#define r4L *(char*)0x0a
#define r4H *(char*)0x0b
#define r5 *(unsigned int*)0x0c
#define r5L *(char*)0x0c
#define r5H *(char*)0x0d
#define r6 *(unsigned int*)0x0e
#define r6L *(char*)0x0e
#define r6H *(char*)0x0f
#define r7 *(unsigned int*)0x10
#define r7L *(char*)0x10
#define r7H *(char*)0x11
#define r8 *(unsigned int*)0x12
#define r8L *(char*)0x12
#define r8H *(char*)0x13
#define r9 *(unsigned int*)0x14
#define r9L *(char*)0x14
#define r9H *(char*)0x15
#define r10 *(unsigned int*)0x16
#define r10L *(char*)0x16
#define r10H *(char*)0x17
#define r11 *(unsigned int*)0x18
#define r11L *(char*)0x18
#define r11H *(char*)0x19
#define r12 *(unsigned int*)0x1a
#define r12L *(char*)0x1a
#define r12H *(char*)0x1b
#define r13 *(unsigned int*)0x1c
#define r13L *(char*)0x1c
#define r13H *(char*)0x1d
#define r14 *(unsigned int*)0x1e
#define r14L *(char*)0x1e
#define r14H *(char*)0x1f
#define r15 *(unsigned int*)0x20
#define r15L *(char*)0x20
#define r15H *(char*)0x21
/* WARNING - these are used by C as temporary registers! */
#define a0 *(unsigned int*)0xfb
#define a0L *(char*)0xfb
#define a0H *(char*)0xfc
#define a1 *(unsigned int*)0xfd
#define a1L *(char*)0xfd
#define a1H *(char*)0xfe
#define a2 *(unsigned int*)0x70
#define a2L *(char*)0x70
#define a2H *(char*)0x71
#define a3 *(unsigned int*)0x72
#define a3L *(char*)0x72
#define a3H *(char*)0x73
#define a4 *(unsigned int*)0x74
#define a4L *(char*)0x74
#define a4H *(char*)0x75
#define a5 *(unsigned int*)0x76
#define a5L *(char*)0x76
#define a5H *(char*)0x77
#define a6 *(unsigned int*)0x78
#define a6L *(char*)0x78
#define a6H *(char*)0x79
#define a7 *(unsigned int*)0x7a
#define a7L *(char*)0x7a
#define a7H *(char*)0x7b
#define a8 *(unsigned int*)0x7c
#define a8L *(char*)0x7c
#define a8H *(char*)0x7d
#define a9 *(unsigned int*)0x7e
#define a9L *(char*)0x7e
#define a9H *(char*)0x7f
#define curPattern *(unsigned int*)0x22
#define string *(unsigned int*)0x24
#define curFontDesc (*(struct fontdesc*)0x26)
#define currentMode *(char*)0x2e
#define dispBufferOn *(char*)0x2f
#define mouseOn *(char*)0x30
#define RAM_64K *(char*)0x30
#define msePicPtr *(unsigned int*)0x31
#define curWindow (*(struct window*)0x33)
/*#define IO_IN *(char*)0x35
#define KRNL_IO_IN *(char*)0x36
#define KRNL_BAS_IO_IN *(char*)0x37*/
#define pressFlag *(char*)0x39
#define mousePos (*(struct pixel*)0x3a)
#define returnAddress *(unsigned int*)0x3d
#define graphMode *(char*)0x3f
/*#define TURBO_DD00 *(char*)0x8e
#define TURBO_DD00_CPY *(char*)0x8f*/
#define STATUS *(char*)0x90
#define curDevice *(char*)0xba
/* Here's my own errno location, I hope this won't confilct with anything... */
#define errno *(char*)0x91
#define irqvec *(unsigned int*)0x0314
#define bkvec *(unsigned int*)0x0316
#define nmivec *(unsigned int*)0x0318
#define APP_RAM *(char*)0x0400
#define BACK_SCR_BASE *(char*)0x6000
#define PRINTBASE *(char*)0x7900
#define OS_VARS *(char*)0x8000
#define diskBlkBuf ((blockBuf)0x8000)
#define fileHeader (*(struct fileheader*)0x8100)
#define curDirHead ((blockBuf)0x8200)
#define fileTrScTab ((struct tr_se[128])0x8300)
#define dirEntryBuf (*(struct filehandle*)0x8400)
#define DrACurDkNm ((nameBuf)0x841e)
#define DrBCurDkNm ((nameBuf)0x8430)
#define dataFileName ((nameBuf)0x8442)
#define dataDiskName ((nameBuf)0x8453)
#define PrntFileName ((nameBuf)0x8465)
#define PrntDiskName ((nameBuf)0x8476)
#define curDrive *(char*)0x8489
#define diskOpenFlg *(char*)0x848a
#define isGEOS *(char*)0x848b
#define interleave *(char*)0x848c
#define NUMDRV *(char*)0x848d
#define driveType ((char[4])0x848e)
#define turboFlags ((char[4])0x8492)
#define VLIRInfo (*(struct VLIR_info*)0x8496)
#define appMain *(unsigned int*)0x849b
#define intTopVector *(unsigned int*)0x849d
#define intBotVector *(unsigned int*)0x849f
#define mouseVector *(unsigned int*)0x84a1
#define keyVector *(unsigned int*)0x84a3
#define inputVector *(unsigned int*)0x84a5
#define mouseFaultVec *(unsigned int*)0x84a7
#define otherPressVec *(unsigned int*)0x84a9
#define StringFaultVec *(unsigned int*)0x84ab
#define alarmTmtVector *(unsigned int*)0x84ad
#define BRKVector *(unsigned int*)0x84af
#define RecoverVector *(unsigned int*)0x84b1
#define selectionFlash *(char*)0x84b3
#define alphaFlag *(char*)0x84b4
#define iconSelFlg *(char*)0x84b5
#define faultData *(char*)0x84b6
#define menuNumber *(char*)0x84b7
#define mouseWindow (*(struct window*)0x84b8)
#define stringXY (*(struct pixel*)0x84be)
#define mousePicData *(char*)0x84c1
#define maxMouseSpeed *(char*)0x8501
#define minMouseSpeed *(char*)0x8502
#define mouseAccel *(char*)0x8503
#define keyData *(char*)0x8504
#define mouseData *(char*)0x8505
#define inputData *(char*)0x8506
#define mouseSpeed *(char*)0x8507
#define random *(char*)0x850a
#define saveFontTab (*(struct fontdesc*)0x850c)
#define dblClickCount *(char*)0x8515
#define system_date (*(struct s_date*)0x8516)
#define alarmSetFlag *(char*)0x851c
#define sysDBData *(char*)0x851d
#define screencolors *(char*)0x851e
#define dlgBoxRamBuf *(char*)0x851f
#define savedmoby2 *(char*)0x88bb
#define scr80polar *(char*)0x88bc
#define scr80colors *(char*)0x88bd
#define vdcClrMode *(char*)0x88be
#define driveData ((char[4])0x88bf)
#define ramExpSize *(char*)0x88c3
#define sysRAMFlg *(char*)0x88c4
#define firstBoot *(char*)0x88c5
#define curType *(char*)0x88c6
#define ramBase *(char*)0x88c7
/*Original:
#define inputDevName *(char*)0x88cb
#define memBase *(char*)0x88cf*/
#define inputDevName ((nameBuf)0x88cb)
#define DrCCurDkNm ((nameBuf)0x88dc)
#define DrDCurDkNm ((nameBuf)0x88ee)
#define dir2Head ((blockBuf)0x8900)
#define SPRITE_PICS *(char*)0x8a00
#define sprpic ((char[8][64])0x8a00)
#define COLOR_MATRIX ((char[1000])0x8c00)
#define objPointer ((char[8])0x8ff8)
#define DISK_BASE *(char*)0x9000
#define SCREEN_BASE *(char*)0xa000
#define OS_ROM *(char*)0xc000
#define OS_JUMPTAB *(char*)0xc100
#define RAMC_BASE *(char*)0xde00
#define RAMC_WINDOW *(char*)0xdf00
#define EXP_BASE *(char*)0xdf00
#define MOUSE_BASE_128 *(char*)0xfd00
#define MOUSE_JMP_128 *(char*)0xfd00
#define END_MOUSE_128 *(char*)0xfe80
#define MOUSE_BASE *(char*)0xfe80
#define MOUSE_JMP *(char*)0xfe80
#define config *(char*)0xff00
#define END_MOUSE *(char*)0xfffa
#define NMI_VECTOR *(unsigned int*)0xfffa
#define RESET_VECTOR *(unsigned int*)0xfffc
#define IRQ_VECTOR *(unsigned int*)0xfffe
#define vicbase *(char*)0xd000
#define sidbase *(char*)0xd400
#define mmu *(char*)0xd500
#define VDC *(char*)0xd600
#define ctab *(char*)0xd800
#define cia1base *(char*)0xdc00
#define cia2base *(char*)0xdd00
#define mob0xpos *(char*)0xd000
#define mob0ypos *(char*)0xd001
#define mob1xpos *(char*)0xd002
#define mob1ypos *(char*)0xd003
#define mob2xpos *(char*)0xd004
#define mob2ypos *(char*)0xd005
#define mob3xpos *(char*)0xd006
#define mob3ypos *(char*)0xd007
#define mob4xpos *(char*)0xd008
#define mob4ypos *(char*)0xd009
#define mob5xpos *(char*)0xd00a
#define mob5ypos *(char*)0xd00b
#define mob6xpos *(char*)0xd00c
#define mob6ypos *(char*)0xd00d
#define mob7xpos *(char*)0xd00e
#define mob7ypos *(char*)0xd00f
#define msbxpos *(char*)0xd010
#define grcntrl1 *(char*)0xd011
#define rasreg *(char*)0xd012
#define lpxpos *(char*)0xd013
#define lpypos *(char*)0xd014
#define mobenble *(char*)0xd015
#define grcntrl2 *(char*)0xd016
#define grmemptr *(char*)0xd018
#define grirq *(char*)0xd019
#define grirqen *(char*)0xd01a
#define moby2 *(char*)0xd017
#define mobprior *(char*)0xd01b
#define mobmcm *(char*)0xd01c
#define mobx2 *(char*)0xd01d
#define mobmobcol *(char*)0xd01e
#define mobbakcol *(char*)0xd01f
#define extclr *(char*)0xd020
#define bakclr0 *(char*)0xd021
#define bakclr1 *(char*)0xd022
#define bakclr2 *(char*)0xd023
#define bakclr3 *(char*)0xd024
#define mcmclr0 *(char*)0xd025
#define mcmclr1 *(char*)0xd026
#define mob0clr *(char*)0xd027
#define mob1clr *(char*)0xd028
#define mob2clr *(char*)0xd029
#define mob3clr *(char*)0xd02a
#define mob4clr *(char*)0xd02b
#define mob5clr *(char*)0xd02c
#define mob6clr *(char*)0xd02d
#define mob7clr *(char*)0xd02e
#define keyreg *(char*)0xd02f
#define clkreg *(char*)0xd030
#define vdcreg *(char*)0xd600
#define vdcdata *(char*)0xd601
#endif

26
include/geos/gsys.h Normal file
View File

@ -0,0 +1,26 @@
/*
GEOS system functions
ported to small C on 27.10.1999
by Maciej 'YTM/Alliance' Witkowiak
*/
#ifndef _GSYS_H
#define _GSYS_H
void __fastcall__ FirstInit(void);
void __fastcall__ InitForIO(void);
void __fastcall__ DoneWithIO(void);
void __fastcall__ MainLoop(void);
void __fastcall__ EnterDeskTop(void);
void __fastcall__ ToBASIC(void);
void __fastcall__ Panic(void);
void __fastcall__ CallRoutine(void *myRoutine);
int __fastcall__ GetSerialNumber(void);
char __fastcall__ GetRandom(void);
void __fastcall__ SetDevice(char newdev);
#endif

34
include/iso646.h Normal file
View File

@ -0,0 +1,34 @@
/*
* iso646.h
*
* Ullrich von Bassewitz, 11.12.1998
*
*/
#ifndef _ISO646_H
#define _ISO646_H
/* Operator tokens */
#define and &&
#define and_eq &=
#define bitand &
#define bitor |
#define compl ~
#define not !
#define not_eq !=
#define or ||
#define or_eq |=
#define xor ^
#define xor_eq ^=
/* End of iso646.h */
#endif

66
include/joystick.h Normal file
View File

@ -0,0 +1,66 @@
/*
* joystick.h
*
* Ullrich von Bassewitz, 24.09.1998
*
* Read the joystick on systems that support it.
*
*/
#ifndef _JOYSTICK_H
#define _JOYSTICK_H
/* Define __JOYSTICK__ for systems that support a joystick */
#ifdef __C64__
# define __JOYSTICK__
#endif
#ifdef __C128__
# define __JOYSTICK__
#endif
#ifdef __PLUS4__
# define __JOYSTICK__
#endif
#ifdef __NES__
# define __JOYSTICK__
#endif
/* Argument for the function */
#define JOY_1 0
#define JOY_2 1
/* Result codes of the function. The actual code is a bitwise or
* of one or more of the following values.
*/
#ifdef __NES__
# define JOY_A 0x01
# define JOY_B 0x02
# define JOY_SELECT 0x04
# define JOY_START 0x08
# define JOY_UP 0x10
# define JOY_DOWN 0x20
# define JOY_LEFT 0x40
# define JOY_RIGHT 0x80
#else
# define JOY_UP 0x01
# define JOY_DOWN 0x02
# define JOY_LEFT 0x04
# define JOY_RIGHT 0x08
# define JOY_FIRE 0x10
#endif
unsigned __fastcall__ readjoy (unsigned char joy);
/* Read the joystick. The argument is one of JOY_1/JOY2 */
/* End of joystick.h */
#endif

46
include/limits.h Normal file
View File

@ -0,0 +1,46 @@
/*
* limits.h
*
* Ullrich von Bassewitz, 04.06.1998
*
*/
#ifndef _LIMITS_H
#define _LIMITS_H
#define CHAR_BIT 8
#define SCHAR_MIN (-128)
#define SCHAR_MAX 127
#define UCHAR_MAX 255
#define CHAR_MIN 0
#define CHAR_MAX 255
#define SHRT_MIN (-32768)
#define SHRT_MAX 32767
#define USHRT_MAX 65535U
#define INT_MIN (-32768)
#define INT_MAX 32767
#define UINT_MAX 65535U
#define LONG_MAX 2147483647L
#define LONG_MIN (-2147483648L)
#define ULONG_MAX 4294967295UL
/* End of limits.h */
#endif

61
include/locale.h Normal file
View File

@ -0,0 +1,61 @@
/*
* locale.h
*
* Ullrich von Bassewitz, 11.12.1998
*
*/
#ifndef _LOCALE_H
#define _LOCALE_H
/* NULL pointer */
#ifdef NULL
# undef NULL
#endif
#define NULL 0
/* Locale information constants */
#define LC_ALL 0
#define LC_COLLATE 1
#define LC_CTYPE 2
#define LC_MONETARY 3
#define LC_NUMERIC 4
#define LC_TIME 5
/* Struct containing locale settings */
struct lconv {
char* currency_symbol;
char* decimal_point;
char* grouping;
char* int_curr_symbol;
char* mon_decimal_point;
char* mon_grouping;
char* mon_thousands_sep;
char* negative_sign;
char* positive_sign;
char* thousands_sep;
char frac_digits;
char int_frac_digits;
char n_cs_precedes;
char n_sep_by_space;
char n_sign_posn;
char p_cs_precedes;
char p_sep_by_space;
char p_sign_posn;
};
/* Function prototypes */
struct lconv* localeconv (void);
char* setlocale (int category, const char* locale);
/* End of locale.h */
#endif

88
include/mouse.h Normal file
View File

@ -0,0 +1,88 @@
/*
* mouse.h
*
* Ullrich von Bassewitz, 24.04.1999
*/
#ifndef _MOUSE_H
#define _MOUSE_H
/* Define __MOUSE__ for systems that support a proportional mouse */
#ifdef __C64__
# define __MOUSE__
#endif
#ifdef __C128__
# define __MOUSE__
#endif
void __fastcall__ mouse_init (unsigned char port, unsigned char sprite);
/* Setup the mouse interrupt handler. If the sprite value is != zero, the
* mouse routines will manage the sprite with this number. That means, it
* is moved if the mouse is moved (provided that the mouse cursor is visible),
* and switch on and off in the show and hide functions.
* The port parameter gives the joystick port used for the mouse and is only
* needed to read the mouse button state.
* After calling this function, the mouse is invisble, the cursor is placed
* at 0/0 (upper left corner), and the bounding box is reset to cover the
* whole screen. Call mouse_show once to make the mouse cursor visible.
*/
void mouse_done (void);
/* Disable the mouse, remove the interrupt handler. This function MUST be
* called before terminating the program, otherwise odd things may happen.
* If in doubt, install an exit handler (using atexit) that calls this
* function.
*/
void mouse_hide (void);
/* Hide the mouse. This function doesn't do anything visible if no sprite is
* used. The function manages a counter and may be called more than once.
* For each call to mouse_hide there must be a call to mouse_show to make
* the mouse visible again.
*/
void mouse_show (void);
/* Show the mouse. This function doesn't do anything visible if no sprite is
* used. See mouse_hide for more information.
*/
void __fastcall__ mouse_box (int minx, int miny, int maxx, int maxy);
/* Set the bounding box for the mouse pointer movement. The mouse X and Y
* coordinates will never go outside the given box.
* NOTE: The function does *not* check if the mouse is currently inside the
* given margins. The proper way to use this function therefore is:
*
* - Hide the mouse
* - Set the bounding box
* - Place the mouse at the desired position
* - Show the mouse again.
*
* NOTE2: When setting the box to something that is larger than the actual
* screen, the positioning of the mouse cursor will fail. If such margins
* are really what you want, you have to use your own cursor routines.
*/
void __fastcall__ mouse_move (int x, int y);
/* Set the mouse cursor to the given position. If a mouse cursor is defined
* and currently visible, the mouse cursor is also moved.
* NOTE: This function does not check if the given position is valid and
* inside the bounding box.
*/
void mouse_info (void);
/* Hmmm...
*/
/* End of mouse.h */
#endif

24
include/pet.h Normal file
View File

@ -0,0 +1,24 @@
/*
* pet.h
*
* Ullrich von Bassewitz, 26.11.1998
*/
#ifndef _PET_H
#define _PET_H
/* Color defines */
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
/* End of pet.h */
#endif

81
include/plus4.h Normal file
View File

@ -0,0 +1,81 @@
/*
* plus4.h
*
* Ullrich von Bassewitz, 12.08.1998
*/
#ifndef _PLUS4_H
#define _PLUS4_H
/* Additional key defines */
#define CH_F1 133
#define CH_F2 137
#define CH_F3 134
#define CH_F4 138
#define CH_F5 135
#define CH_F6 139
#define CH_F7 136
#define CH_F8 140
/* Color attributes */
#define CATTR_LUMA0 0x00
#define CATTR_LUMA1 0x10
#define CATTR_LUMA2 0x20
#define CATTR_LUMA3 0x30
#define CATTR_LUMA4 0x40
#define CATTR_LUMA5 0x50
#define CATTR_LUMA6 0x60
#define CATTR_LUMA7 0x70
#define CATTR_BLINK 0x80
/* Base colors */
#define BCOLOR_BLACK 0x00
#define BCOLOR_WHITE 0x01
#define BCOLOR_RED 0x02
#define BCOLOR_CYAN 0x03
#define BCOLOR_VIOLET 0x04
#define BCOLOR_GREEN 0x05
#define BCOLOR_BLUE 0x06
#define BCOLOR_YELLOW 0x07
#define BCOLOR_ORANGE 0x08
#define BCOLOR_BROWN 0x09
#define BCOLOR_LEMON 0x0A /* What's that color? */
#define BCOLOR_LIGHTVIOLET 0x0B
#define BCOLOR_BLUEGREEN 0x0C
#define BCOLOR_LIGHTBLUE 0x0D
#define BCOLOR_DARKBLUE 0x0E
#define BCOLOR_LIGHTGREEN 0x0F
/* Now try to mix up a C64/C128 compatible palette */
#define COLOR_BLACK (BCOLOR_BLACK)
#define COLOR_WHITE (BCOLOR_WHITE | CATTR_LUMA7)
#define COLOR_RED (BCOLOR_RED | CATTR_LUMA4)
#define COLOR_CYAN (BCOLOR_CYAN | CATTR_LUMA7)
#define COLOR_VIOLET (BCOLOR_VIOLET | CATTR_LUMA7)
#define COLOR_GREEN (BCOLOR_GREEN | CATTR_LUMA7)
#define COLOR_BLUE (BCOLOR_BLUE | CATTR_LUMA7)
#define COLOR_YELLOW (BCOLOR_YELLOW | CATTR_LUMA7)
#define COLOR_ORANGE (BCOLOR_ORANGE | CATTR_LUMA7)
#define COLOR_BROWN (BCOLOR_BROWN | CATTR_LUMA7)
#define COLOR_LIGHTRED (BCOLOR_RED | CATTR_LUMA7)
#define COLOR_GRAY1 (BCOLOR_WHITE | CATTR_LUMA1)
#define COLOR_GRAY2 (BCOLOR_WHITE | CATTR_LUMA3)
#define COLOR_LIGHTGREEN (BCOLOR_LIGHTGREEN | CATTR_LUMA7)
#define COLOR_LIGHTBLUE (BCOLOR_LIGHTBLUE | CATTR_LUMA7)
#define COLOR_GRAY3 (BCOLOR_WHITE | CATTR_LUMA5)
/* End of plus4.h */
#endif

125
include/rs232.h Normal file
View File

@ -0,0 +1,125 @@
/*
* rs232.h
*
* Ullrich von Bassewitz, 19.3.1999
*
* This module is based upon the public domain swiftlink module written by
* Craig Bruce. Thanks a lot!
*
*/
#ifndef _RS232_H
#define _RS232_h
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Baudrate settings */
#define RS_BAUD_50 0x00
#define RS_BAUD_110 0x01
#define RS_BAUD_134_5 0x02
#define RS_BAUD_300 0x03
#define RS_BAUD_600 0x04
#define RS_BAUD_1200 0x05
#define RS_BAUD_2400 0x06
#define RS_BAUD_4800 0x07
#define RS_BAUD_9600 0x08
#define RS_BAUD_19200 0x09
#define RS_BAUD_38400 0x0A
#define RS_BAUD_57600 0x0B
#define RS_BAUD_115200 0x0C
#define RS_BAUD_230400 0x0D
/* Stop bit settings */
#define RS_STOP_1 0x00
#define RS_STOP_2 0x80
/* Data bit settings */
#define RS_BITS_5 0x60
#define RS_BITS_6 0x40
#define RS_BITS_7 0x20
#define RS_BITS_8 0x00
/* Parity settings */
#define RS_PAR_NONE 0x00
#define RS_PAR_ODD 0x20
#define RS_PAR_EVEN 0x60
#define RS_PAR_MARK 0xA0
#define RS_PAR_SPACE 0xE0
/* Bit masks to mask out things from the status returned by rs232_status */
#define RS_STATUS_PE 0x01 /* Parity error */
#define RS_STATUS_FE 0x02 /* Framing error */
#define RS_STATUS_OVERRUN 0x04 /* Overrun error */
#define RS_STATUS_RDRF 0x08 /* Receiver data register full */
#define RS_STATUS_THRE 0x10 /* Transmit holding reg. empty */
#define RS_STATUS_DCD 0x20 /* NOT data carrier detect */
#define RS_STATUS_DSR 0x40 /* NOT data set ready */
#define RS_STATUS_IRQ 0x80 /* IRQ condition */
/* Error codes returned by all functions */
#define RS_ERR_OK 0x00 /* Not an error - relax */
#define RS_ERR_NOT_INITIALIZED 0x01 /* Module not initialized */
#define RS_ERR_BAUD_TOO_FAST 0x02 /* Cannot handle baud rate */
#define RS_ERR_BAUD_NOT_AVAIL 0x03 /* Baud rate not available */
#define RS_ERR_NO_DATA 0x04 /* Nothing to read */
#define RS_ERR_OVERFLOW 0x05 /* No room in send buffer */
/*****************************************************************************/
/* Code */
/*****************************************************************************/
unsigned char __fastcall__ rs232_init (char hacked);
/* Initialize the serial port, install the interrupt handler. The parameter
* must be true (non zero) for a hacked swiftlink and false (zero) otherwise.
*/
unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity);
/* Set the port parameters. Use a combination of the #defined values above. */
unsigned char __fastcall__ rs232_done (void);
/* Close the port, deinstall the interrupt hander. You MUST call this function
* before terminating the program, otherwise the machine may crash later. If
* in doubt, install an exit handler using atexit(). The function will do
* nothing, if it was already called.
*/
unsigned char __fastcall__ rs232_get (char* b);
/* Get a character from the serial port. If no characters are available, the
* function will return RS_ERR_NO_DATA, so this is not a fatal error.
*/
unsigned char __fastcall__ rs232_put (char b);
/* Send a character via the serial port. There is a transmit buffer, but
* transmitting is not done via interrupt. The function returns
* RS_ERR_OVERFLOW if there is no space left in the transmit buffer.
*/
unsigned char __fastcall__ rs232_pause (void);
/* Assert flow control and disable interrupts. */
unsigned char __fastcall__ rs232_unpause (void);
/* Re-enable interrupts and release flow control */
unsigned char __fastcall__ rs232_status (unsigned char* status,
unsigned char* errors);
/* Return the serial port status. */
/* End of rs232.h */
#endif

29
include/setjmp.h Normal file
View File

@ -0,0 +1,29 @@
/*
* setjmp.h
*
* Ullrich von Bassewitz, 06.06.1998
*
*/
#ifndef _SETJMP_H
#define _SETJMP_H
typedef char jmp_buf [5];
int __fastcall__ _setjmp (jmp_buf buf);
#define setjmp _setjmp /* ISO insists on a macro */
void __fastcall__ longjmp (jmp_buf buf, int retval);
/* End of stddef.h */
#endif

33
include/stdarg.h Normal file
View File

@ -0,0 +1,33 @@
/*
* stdarg.h
*
* Ullrich von Bassewitz, 31.05.1998
*
*/
#ifndef _STDARG_H
#define _STDARG_H
typedef unsigned char* va_list;
#define va_start(ap, fix) ap = (va_list)&fix + *(((va_list)&fix)-1) - __fixargs__
#define va_arg(ap,type) ((type)*(ap -= ((sizeof (type) + 1) & ~1)))
#define va_end(ap)
/* This is only valid *before* the first call to va_arg. It will also work
* only for int sized parameters.
*/
#define va_fix(ap, offs) *(ap+(__fixargs__-2*offs))
/* End of stdarg.h */
#endif

34
include/stddef.h Normal file
View File

@ -0,0 +1,34 @@
/*
* stddef.h
*
* Ullrich von Bassewitz, 06.06.1998
*
*/
#ifndef _STDDEF_H
#define _STDDEF_H
/* Standard data types */
typedef int ptrdiff_t;
typedef unsigned size_t;
/* NULL pointer */
#ifdef NULL
# undef NULL
#endif
#define NULL 0
/* offsetof macro */
#define offsetof(type, member) (size_t) (&((type*) 0)->member)
/* End of stddef.h */
#endif

101
include/stdio.h Normal file
View File

@ -0,0 +1,101 @@
/*
* stdio.h
*
* Ullrich von Bassewitz, 30.05.1998
*
*/
#ifndef _STDIO_H
#define _STDIO_H
#ifndef _STDDEF_H
# include <stddef.h>
#endif
#ifndef _STDARG_H
# include <stdarg.h>
#endif
/* Types */
typedef struct _FILE FILE;
typedef unsigned long fpos_t;
/* Standard file descriptors */
extern FILE* stdin;
extern FILE* stdout;
extern FILE* stderr;
/* Standard defines */
#define _IOFBF 0
#define _IOLBF 1
#define _IONBF 2
#define BUFSIZ 256
#define EOF -1
#define FILENAME_MAX 16
#define FOPEN_MAX 8
#define L_tmpnam (FILENAME_MAX + 1)
#define SEEK_CUR 0
#define SEEK_END 1
#define SEEK_SET 2
#define TMP_MAX 256
/* Functions */
void __fastcall__ clearerr (FILE* f);
int fclose (FILE* f);
int __fastcall__ feof (FILE* f);
int __fastcall__ ferror (FILE* f);
int __fastcall__ fflush (FILE* f);
int fgetc (FILE* f);
char* fgets (char* buf, size_t size, FILE* f);
FILE* fopen (const char* name, const char* mode);
int fprintf (FILE* f, const char* format, ...);
int fputc (int c, FILE* f);
int fputs (const char* s, FILE* f);
size_t fread (void* buf, size_t size, size_t count, FILE* f);
FILE* freopen (const char* name, const char* mode, FILE* f);
size_t fwrite (const void* buf, size_t size, size_t count, FILE* f);
int getchar (void);
char* gets (char* s);
void perror (const char* s);
int printf (const char* format, ...);
int putchar (int c);
int puts (const char* s);
int remove (const char* name);
int rename (const char* old, const char* new);
int sprintf (char* buf, const char* format, ...);
int vfprintf (FILE* f, const char* format, va_list ap);
int vprintf (const char* format, va_list ap);
int vsprintf (char* buf, const char* format, va_list ap);
#ifndef __STRICT_ANSI__
FILE* fdopen (int fd, const char* mode); /* Unix */
int __fastcall__ fileno (FILE* f); /* Unix */
#endif
/* Masking macros for some functions */
#define getchar() fgetc (stdin) /* ANSI */
#define putchar(c) fputc (c, stdout) /* ANSI */
#define getc(f) fgetc (f) /* ANSI */
#define putc(c, f) fputc (c, f) /* ANSI */
/* Non-standard function like macros */
#ifndef __STRICT_ANSI__
#define flushall() /* Unix */
#define unlink(name) remove (name) /* Unix */
#endif
/* End of stdio.h */
#endif

68
include/stdlib.h Normal file
View File

@ -0,0 +1,68 @@
/*
* stdlib.h
*
* Ullrich von Bassewitz, 02.06.1998
*
*/
#ifndef _STDLIB_H
#define _STDLIB_H
#include <stddef.h>
/* Standard exit codes */
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
/* Memory management */
void* malloc (size_t size);
void* calloc (size_t count, size_t size);
void* realloc (void* block, size_t size);
void free (void* block);
#ifndef __STRICT_ANSI__
void _hadd (void* mem, size_t size); /* Non-standard */
#endif
/* Random numbers */
#define RAND_MAX 0x7FFF
int rand (void);
void __fastcall__ srand (unsigned seed);
/* Other standard stuff */
void abort (void);
int __fastcall__ abs (int val);
long __fastcall__ labs (long val);
int __fastcall__ atoi (char* s);
long __fastcall__ atol (char* s);
int __fastcall__ atexit (void (*exitfunc) (void));
void* bsearch (const void* key, const void* base, size_t n,
size_t size, int (*cmp) (const void*, const void*));
void exit (int ret);
char* __fastcall__ getenv (const char* name);
void qsort (void* base, size_t count, size_t size,
int (*compare) (const void*, const void*));
/* Non-ANSI functions */
#ifndef __STRICT_ANSI__
void __fastcall__ _swap (void* p, void* q, size_t size);
char* __fastcall__ itoa (int val, char* buf, int radix);
char* __fastcall__ utoa (unsigned val, char* buf, int radix);
char* __fastcall__ ltoa (long val, char* buf, int radix);
char* __fastcall__ ultoa (unsigned long val, char* buf, int radix);
#endif
/* End of stdlib.h */
#endif

58
include/string.h Normal file
View File

@ -0,0 +1,58 @@
/*
* string.h
*
* Ullrich von Bassewitz, 04.06.1998
*
*/
#ifndef _STRING_H
#define _STRING_H
#include <stddef.h>
char* __fastcall__ strcat (char* dest, const char* src);
char* __fastcall__ strchr (const char* s, int c);
int __fastcall__ strcmp (const char* s1, const char* s2);
int __fastcall__ strcoll (const char* s1, const char* s2);
char* __fastcall__ strcpy (char* dest, const char* src);
size_t __fastcall__ strcspn (const char* s1, const char* s2);
char* __fastcall__ strerror (int errcode);
size_t __fastcall__ strlen (const char* s);
char* __fastcall__ strncat (char* s1, const char* s2, size_t count);
int __fastcall__ strncmp (const char* s1, const char* s2, size_t count);
char* __fastcall__ strncpy (char* dest, const char* src, size_t count);
char* __fastcall__ strrchr (const char* s, int c);
size_t __fastcall__ strspn (const char* s1, const char* s2);
char* __fastcall__ strstr (const char* str, const char* substr);
char* strtok (char* s1, const char* s2);
size_t strxfrm (char* s1, const char* s2, size_t count);
void* __fastcall__ memchr (const void* mem, int c, size_t count);
int __fastcall__ memcmp (const void* p1, const void* p2, size_t count);
void* __fastcall__ memcpy (void* dest, const void* src, size_t count);
void* __fastcall__ memmove (void* dest, const void* src, size_t count);
void* __fastcall__ memset (void* s, int c, size_t count);
/* Non standard: */
#ifndef __STRICT_ANSI__
char* strdup (const char* s); /* SYSV/BSD */
int __fastcall__ stricmp (const char* s1, const char* s2); /* DOS/Windows */
int __fastcall__ strcasecmp (const char* s1, const char* s2); /* Same for Unix */
char* __fastcall__ strlwr (char* s);
char* __fastcall__ strlower (char* s);
char* __fastcall__ strupr (char* s);
char* __fastcall__ strupper (char* s);
#endif
/* End of string.h */
#endif

58
include/time.h Normal file
View File

@ -0,0 +1,58 @@
/*
* time.h
*
* Ullrich von Bassewitz, 17.06.1998
*
*/
#ifndef _TIME_H
#define _TIME_H
#include <stddef.h>
typedef unsigned long time_t;
typedef unsigned long clock_t;
/* Structure for broken down time */
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
/* The 610 gets its clock from the AC current */
#ifdef __CBM__
# ifdef __CBM610__
# define CLK_TCK 50 /* POSIX */
# define CLOCKS_PER_TICK 50 /* ANSI */
# else
# define CLK_TCK 60 /* POSIX */
# define CLOCKS_PER_TICK 60 /* ANSI */
# endif
#endif
/* Function prototypes */
clock_t clock (void);
/* End of time.h */
#endif

2
libsrc/.cvsignore Normal file
View File

@ -0,0 +1,2 @@
libr65.tmp
*.lib

120
libsrc/Makefile Normal file
View File

@ -0,0 +1,120 @@
#
# makefile for CC65 runtime library
#
.SUFFIXES: .o .obj .s .c
# Defines used by the submakes:
export CC = ../../src/cc65/cc65
export AS = ../../src/ca65/ca65
# Define used within this makefile
AR = ../src/ar65/ar65
#-----------------------------------------------------------------------------
all : apple2lib c64lib c128lib cbm610lib geoslib petlib plus4lib
#-----------------------------------------------------------------------------
# Apple ][
apple2lib:
export CFLAGS="-Osir -g -t apple2 -I../../include";\
for i in apple2 common runtime conio dbg; do $(MAKE) -C $$i; done
mv apple2/crt0.o apple2.o
for i in apple2 common runtime conio dbg; do \
$(AR) a apple2.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# Atari
atarilib:
export CFLAGS="-Osir -g -t atari -I../../include";\
for i in atari common runtime conio dbg; do $(MAKE) -C $$i; done
mv atari/crt0.o atari.o
for i in atari common runtime conio dbg; do \
$(AR) a atari.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# C64
c64lib:
export CFLAGS="-Osir -g -t c64 -I../../include";\
for i in c64 cbm common runtime conio dbg; do $(MAKE) -C $$i; done
mv c64/crt0.o c64.o
for i in c64 cbm common runtime conio dbg; do \
$(AR) a c64.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# C128
c128lib:
export CFLAGS="-Osir -g -t c128 -I../../include";\
for i in c128 cbm common runtime conio dbg; do $(MAKE) -C $$i; done
mv c128/crt0.o c128.o
for i in c128 cbm common runtime conio dbg; do \
$(AR) a c128.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# PET-II series
cbm610lib:
export CFLAGS="-Osir -g -t cbm610 -I../../include";\
for i in cbm610 cbm common runtime conio dbg; do $(MAKE) -C $$i; done
mv cbm610/crt0.o cbm610.o
for i in cbm610 cbm common runtime conio dbg; do \
$(AR) a cbm610.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# GEOS on the C64/128
geoslib:
export CFLAGS="-Osir -g -t geos -I../../include";\
for i in geos common runtime; do $(MAKE) -C $$i; done
for i in common runtime; do \
$(AR) a geos.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# CBM PET machines
petlib:
export CFLAGS="-Osir -g -t pet -I../../include";\
for i in pet cbm common runtime conio dbg; do $(MAKE) -C $$i; done
mv pet/crt0.o pet.o
for i in pet cbm common runtime conio dbg; do \
$(AR) a pet.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# Commodore C116, C16 and Plus/4
plus4lib:
export CFLAGS="-Osir -g -t plus4 -I../../include";\
for i in plus4 cbm common runtime conio dbg; do $(MAKE) -C $$i; done
mv plus4/crt0.o plus4.o
for i in plus4 cbm common runtime conio dbg; do \
$(AR) a plus4.lib $$i/*.o;\
done
#-----------------------------------------------------------------------------
# Dummy targets
.PHONY: clean
clean:
@for i in apple2 atari c128 c64 cbm cbm610 common conio dbg geos pet plus4 runtime; do \
$(MAKE) -C $$i clean; \
done
.PHONY: zap
zap: clean
@rm -f *.lib

29
libsrc/apple2/Makefile Normal file
View File

@ -0,0 +1,29 @@
#
# makefile for CC65 runtime library
#
.SUFFIXES: .o .s .c
%.o: %.c
@echo $<
@$(CC) $(CFLAGS) $<
@$(AS) -o $@ $(AFLAGS) $(*).s
%.o: %.s
@echo $<
@$(AS) -g -o $@ $(AFLAGS) $<
C_OBJS =
S_OBJS = break.o clrscr.o cclear.o cgetc.o chline.o color.o \
cputc.o crt0.o ctype.o \
cvline.o kbhit.o read.o revers.o where.o write.o
all: $(C_OBJS) $(S_OBJS)
clean:
@rm -f $(C_OBJS:.c=.s)
@rm -f $(C_OBJS)
@rm -f $(S_OBJS)
@rm -f crt0.o

43
libsrc/apple2/apple2.inc Normal file
View File

@ -0,0 +1,43 @@
; Break vector
BRKVec = $03F0
; Goto Dos
RESTOR = $03D0
; Top of available memory
; This is actually for DOS 3.3 need to change it for ProDos
TOPMEM = $9600
; Soft switches
;
; write to USEROM to enable apple rom C000-CFFF
USEROM = $C007
; 80 column card switches
C80ON = $C00C
C80OFF = $C00D
RD80COL = $C01F
PG2OFF = $C054
PG2ON = $C055
RDPAGE2 = $C01C
; Text routines
MIN_X = $20
MAX_X = $21
MIN_Y = $22
MAX_Y = $23
CH = $24
CV = $25
BASL = $28
TEXTTYP = $32
HOME = $FC58
VTABZ = $FC24
COUT = $FDED
; Keyboard entries
RDKEY = $FD0C
CLEAR_KEY_STROBE = $C010
KEY_STROBE = $C000
; Game controller
OPEN_APPLE = $C061
CLOSED_APPLE = $C062

109
libsrc/apple2/break.s Normal file
View File

@ -0,0 +1,109 @@
;
; Ullrich von Bassewitz, 27.09.1998
;
; void set_brk (unsigned Addr);
; void reset_brk (void);
;
.export _set_brk, _reset_brk
.export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc
.import _atexit
.include "apple2.inc"
_brk_a = $45
_brk_x = $46
_brk_y = $47
_brk_sr = $48
_brk_sp = $49
_brk_pc = $3A
.bss
oldvec: .res 2 ; Old vector
.data
uservec: jmp $FFFF ; Patched at runtime
.code
; Set the break vector
.proc _set_brk
sta uservec+1
stx uservec+2 ; Set the user vector
lda oldvec
ora oldvec+1 ; Did we save the vector already?
bne L1 ; Jump if we installed the handler already
lda BRKVec
sta oldvec
lda BRKVec+1
sta oldvec+1 ; Save the old vector
lda #<_reset_brk
ldx #>_reset_brk
jsr _atexit ; Install an exit handler
L1: lda #<brk_handler ; Set the break vector to our routine
sta BRKVec
lda #>brk_handler
sta BRKVec+1
rts
.endproc
; Reset the break vector
.proc _reset_brk
lda oldvec
sta BRKVec
lda oldvec+1
sta BRKVec+1
rts
.endproc
; Break handler, called if a break occurs
.proc brk_handler
sec
lda _brk_pc
sbc #$02 ; Point to start of brk
sta _brk_pc
lda _brk_pc+1
sbc #$00
sta _brk_pc+1
clc
lda _brk_sp
adc #$04 ; Adjust stack pointer
sta _brk_sp
lda _brk_sr ; Clear brk
and #$EF
sta _brk_sr
jsr uservec ; Call the user's routine
lda _brk_pc+1
pha
lda _brk_pc
pha
lda _brk_sr
pha
ldx _brk_x
ldy _brk_y
lda _brk_a
rti ; Jump back...
.endproc

30
libsrc/apple2/cclear.s Normal file
View File

@ -0,0 +1,30 @@
;
; Ullrich von Bassewitz, 08.08.1998
;
; void cclearxy (unsigned char x, unsigned char y, unsigned char length);
; void cclear (unsigned char length);
;
.export _cclearxy, _cclear
.import popa, _gotoxy, cputdirect
.importzp tmp1
_cclearxy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cclear
_cclear:
cmp #0 ; Is the length zero?
beq L9 ; Jump if done
sta tmp1
L1: lda #$20 ; Blank - screen code
jsr cputdirect ; Direct output
dec tmp1
bne L1
L9: rts

25
libsrc/apple2/cgetc.s Normal file
View File

@ -0,0 +1,25 @@
;;
;; Kevin Ruland
;;
;; char cgetc (void);
;;
;; If open_apple key is pressed then the high-bit of the
;; key is set.
.export _cgetc
.include "apple2.inc"
_cgetc:
lda KEY_STROBE
bpl _cgetc ; if < 128, no key pressed
;; At this time, the high bit of the key pressed
;; is set
sta CLEAR_KEY_STROBE; clear keyboard strobe
bit OPEN_APPLE ; check if OpenApple is down
bmi pressed
and #$7F ; If not down, then clear high bit
pressed:
ldx #0
rts

30
libsrc/apple2/chline.s Normal file
View File

@ -0,0 +1,30 @@
;
; Ullrich von Bassewitz, 08.08.1998
;
; void chlinexy (unsigned char x, unsigned char y, unsigned char length);
; void chline (unsigned char length);
;
.export _chlinexy, _chline
.import popa, _gotoxy, cputdirect
.importzp tmp1
_chlinexy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length
_chline:
cmp #0 ; Is the length zero?
beq L9 ; Jump if done
sta tmp1
L1: lda #$2D ; Horizontal line, screen code
jsr cputdirect ; Direct output
dec tmp1
bne L1
L9: rts

10
libsrc/apple2/clrscr.s Normal file
View File

@ -0,0 +1,10 @@
;;
;; Kevin Ruland
;;
;; void clrscr (void);
.export _clrscr
.include "apple2.inc"
_clrscr = HOME

20
libsrc/apple2/color.s Normal file
View File

@ -0,0 +1,20 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _textcolor, _bgcolor, _bordercolor
.import return0, _revers
.include "apple2.inc"
_textcolor = _revers
_bgcolor = return0
_bordercolor = return0

85
libsrc/apple2/cputc.s Normal file
View File

@ -0,0 +1,85 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export _cputcxy, _cputc
.export _gotoxy, cputdirect
.export newline, putchar
.import popa
.include "apple2.inc"
; Plot a character - also used as internal function
_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy
pla ; Restore C
_cputc:
cmp #$0D ; Test for \r = carrage return
bne L1
lda #$00 ; Goto left edge of screen
sta CH
rts ; That's all we do
L1:
cmp #$0A ; Test for \n = line feed
beq newline
cputdirect:
jsr putchar
;; Bump to next column
inc CH
lda CH
cmp MAX_X
bne return
lda #$00
sta CH
return:
rts
putchar:
ora #$80 ; Turn on high bit
and TEXTTYP ; Apply normal, inverse, flash
ldy CH
ldx RD80COL ; In 80 column mode?
bpl col40 ; No, in 40 cols
pha
tya
lsr ; Div by 2
tay
pla
bcs col40 ; odd cols go in 40 col memory
sta PG2ON
col40: sta (BASL),Y
sta PG2OFF
rts
newline:
lda CH
pha
inc CV
lda CV
cmp MAX_Y
bne L2
lda #$00
sta CV
L2:
jsr VTABZ
pla
sta CH
rts
_gotoxy:
sta CV ; Store Y
jsr VTABZ
jsr popa ; Get X
sta CH ; Store X
rts

112
libsrc/apple2/crt0.s Normal file
View File

@ -0,0 +1,112 @@
;
; Startup code for cc65 (Apple2 version)
;
; This must be the *first* file on the linker command line
;
.export _exit
.import __hinit
.import zerobss, push0, doatexit
.import _main
.include "apple2.inc"
; ------------------------------------------------------------------------
; Define and export the ZP variables for the C64 runtime
.exportzp sp, sreg, regsave
.exportzp ptr1, ptr2, ptr3, ptr4
.exportzp tmp1, tmp2, tmp3, tmp4
.exportzp regbank, zpspace
; These zero page entries overlap with the sweet-16 registers.
; must be changed if sweet-16 is to be supported
sp = $00 ; stack pointer
sreg = $02 ; secondary register/high 16 bit for longs
regsave = $04 ; slot to save/restore (E)AX into
ptr1 = $08 ;
ptr2 = $0A
ptr3 = $0C
ptr4 = $0E
tmp1 = $10
tmp2 = $11
tmp3 = $12
tmp4 = $13
regbank = $14 ; 6 byte register bank
zpspace = $1A ; Zero page space allocated
; ------------------------------------------------------------------------
; Actual code
ldy #zpspace-1
L1: lda sp,y
sta zpsave,y ; Save the zero page locations we need
dey
bpl L1
; Clear the BSS data
jsr zerobss
; Save system stuff and setup the stack
tsx
stx spsave ; Save the system stack ptr
lda #<TOPMEM
sta sp
lda #>TOPMEM
sta sp+1 ; Set argument stack ptr
; Initialize the heap
jsr __hinit
; Initialize conio stuff
lda #$ff
sta TEXTTYP
; Set up to use Apple ROM $C000-$CFFF
;; sta USEROM
; Pass an empty command line
jsr push0 ; argc
jsr push0 ; argv
ldy #4 ; Argument size
jsr _main ; call the users code
; fall thru to exit...
_exit:
lda #$ff
sta TEXTTYP
jsr doatexit ; call exit functions
ldx spsave
txs ; Restore stack pointer
; Copy back the zero page stuff
ldy #zpspace-1
L2: lda zpsave,y
sta sp,y
dey
bpl L2
; Reset changed vectors, back to basic
jmp RESTOR
.data
zpsave: .res zpspace
.bss
spsave: .res 1

309
libsrc/apple2/ctype.s Normal file
View File

@ -0,0 +1,309 @@
;
; Ullrich von Bassewitz, 02.06.1998
;
; Character specification table.
;
; The tables are readonly, put them into the code segment
.code
; Value that must be added to an upper case char to make it lower case
; char (example: for ASCII, this must be $E0).
.export __cdiff
__cdiff:
.byte $E0
; The following 256 byte wide table specifies attributes for the isxxx type
; of functions. Doing it by a table means some overhead in space, but it
; has major advantages:
;
; * It is fast. If it were'nt for the slow parameter passing of cc65, one
; could even define macros for the isxxx functions (this is usually
; done on other platforms).
;
; * It is highly portable. The only unportable part is the table itself,
; all real code goes into the common library.
;
; * We save some code in the isxxx functions.
;
;
; Bit assignments:
;
; 0 - Lower case char
; 1 - Upper case char
; 2 - Numeric digit
; 3 - Hex digit (both, lower and upper)
; 4 - Control character
; 5 - The space character itself
; 6 - Other whitespace (that is: '\f', '\n', '\r', '\t' and '\v')
; 7 - Space or tab character
.export __ctype
__ctype:
.byte $10 ; 0/00 ___ctrl_@___
.byte $10 ; 1/01 ___ctrl_A___
.byte $10 ; 2/02 ___ctrl_B___
.byte $10 ; 3/03 ___ctrl_C___
.byte $10 ; 4/04 ___ctrl_D___
.byte $10 ; 5/05 ___ctrl_E___
.byte $10 ; 6/06 ___ctrl_F___
.byte $10 ; 7/07 ___ctrl_G___
.byte $10 ; 8/08 ___ctrl_H___
.byte $D0 ; 9/09 ___ctrl_I___
.byte $50 ; 10/0a ___ctrl_J___
.byte $50 ; 11/0b ___ctrl_K___
.byte $50 ; 12/0c ___ctrl_L___
.byte $50 ; 13/0d ___ctrl_M___
.byte $10 ; 14/0e ___ctrl_N___
.byte $10 ; 15/0f ___ctrl_O___
.byte $10 ; 16/10 ___ctrl_P___
.byte $10 ; 17/11 ___ctrl_Q___
.byte $10 ; 18/12 ___ctrl_R___
.byte $10 ; 19/13 ___ctrl_S___
.byte $10 ; 20/14 ___ctrl_T___
.byte $10 ; 21/15 ___ctrl_U___
.byte $10 ; 22/16 ___ctrl_V___
.byte $10 ; 23/17 ___ctrl_W___
.byte $10 ; 24/18 ___ctrl_X___
.byte $10 ; 25/19 ___ctrl_Y___
.byte $10 ; 26/1a ___ctrl_Z___
.byte $10 ; 27/1b ___ctrl_[___
.byte $10 ; 28/1c ___ctrl_\___
.byte $10 ; 29/1d ___ctrl_]___
.byte $10 ; 30/1e ___ctrl_^___
.byte $10 ; 31/1f ___ctrl_____
.byte $A0 ; 32/20 ___SPACE___
.byte $00 ; 33/21 _____!_____
.byte $00 ; 34/22 _____"_____
.byte $00 ; 35/23 _____#_____
.byte $00 ; 36/24 _____$_____
.byte $00 ; 37/25 _____%_____
.byte $00 ; 38/26 _____&_____
.byte $00 ; 39/27 _____'_____
.byte $00 ; 40/28 _____(_____
.byte $00 ; 41/29 _____)_____
.byte $00 ; 42/2a _____*_____
.byte $00 ; 43/2b _____+_____
.byte $00 ; 44/2c _____,_____
.byte $00 ; 45/2d _____-_____
.byte $00 ; 46/2e _____._____
.byte $00 ; 47/2f _____/_____
.byte $0C ; 48/30 _____0_____
.byte $0C ; 49/31 _____1_____
.byte $0C ; 50/32 _____2_____
.byte $0C ; 51/33 _____3_____
.byte $0C ; 52/34 _____4_____
.byte $0C ; 53/35 _____5_____
.byte $0C ; 54/36 _____6_____
.byte $0C ; 55/37 _____7_____
.byte $0C ; 56/38 _____8_____
.byte $0C ; 57/39 _____9_____
.byte $00 ; 58/3a _____:_____
.byte $00 ; 59/3b _____;_____
.byte $00 ; 60/3c _____<_____
.byte $00 ; 61/3d _____=_____
.byte $00 ; 62/3e _____>_____
.byte $00 ; 63/3f _____?_____
.byte $00 ; 64/40 _____@_____
.byte $0A ; 65/41 _____A_____
.byte $0A ; 66/42 _____B_____
.byte $0A ; 67/43 _____C_____
.byte $0A ; 68/44 _____D_____
.byte $0A ; 69/45 _____E_____
.byte $0A ; 70/46 _____F_____
.byte $02 ; 71/47 _____G_____
.byte $02 ; 72/48 _____H_____
.byte $02 ; 73/49 _____I_____
.byte $02 ; 74/4a _____J_____
.byte $02 ; 75/4b _____K_____
.byte $02 ; 76/4c _____L_____
.byte $02 ; 77/4d _____M_____
.byte $02 ; 78/4e _____N_____
.byte $02 ; 79/4f _____O_____
.byte $02 ; 80/50 _____P_____
.byte $02 ; 81/51 _____Q_____
.byte $02 ; 82/52 _____R_____
.byte $02 ; 83/53 _____S_____
.byte $02 ; 84/54 _____T_____
.byte $02 ; 85/55 _____U_____
.byte $02 ; 86/56 _____V_____
.byte $02 ; 87/57 _____W_____
.byte $02 ; 88/58 _____X_____
.byte $02 ; 89/59 _____Y_____
.byte $02 ; 90/5a _____Z_____
.byte $00 ; 91/5b _____[_____
.byte $00 ; 92/5c _____\_____
.byte $00 ; 93/5d _____]_____
.byte $00 ; 94/5e _____^_____
.byte $00 ; 95/5f _UNDERLINE_
.byte $00 ; 96/60 ___grave___
.byte $09 ; 97/61 _____a_____
.byte $09 ; 98/62 _____b_____
.byte $09 ; 99/63 _____c_____
.byte $09 ; 100/64 _____d_____
.byte $09 ; 101/65 _____e_____
.byte $09 ; 102/66 _____f_____
.byte $01 ; 103/67 _____g_____
.byte $01 ; 104/68 _____h_____
.byte $01 ; 105/69 _____i_____
.byte $01 ; 106/6a _____j_____
.byte $01 ; 107/6b _____k_____
.byte $01 ; 108/6c _____l_____
.byte $01 ; 109/6d _____m_____
.byte $01 ; 110/6e _____n_____
.byte $01 ; 111/6f _____o_____
.byte $01 ; 112/70 _____p_____
.byte $01 ; 113/71 _____q_____
.byte $01 ; 114/72 _____r_____
.byte $01 ; 115/73 _____s_____
.byte $01 ; 116/74 _____t_____
.byte $01 ; 117/75 _____u_____
.byte $01 ; 118/76 _____v_____
.byte $01 ; 119/77 _____w_____
.byte $01 ; 120/78 _____x_____
.byte $01 ; 121/79 _____y_____
.byte $01 ; 122/7a _____z_____
.byte $00 ; 123/7b _____{_____
.byte $00 ; 124/7c _____|_____
.byte $00 ; 125/7d _____}_____
.byte $00 ; 126/7e _____~_____
.byte $40 ; 127/7f ____DEL____
.byte $00 ; 128/80 ___________
.byte $00 ; 129/81 ___________
.byte $00 ; 130/82 ___________
.byte $00 ; 131/83 ___________
.byte $00 ; 132/84 ___________
.byte $00 ; 133/85 ___________
.byte $00 ; 134/86 ___________
.byte $00 ; 135/87 ___________
.byte $00 ; 136/88 ___________
.byte $00 ; 137/89 ___________
.byte $00 ; 138/8a ___________
.byte $00 ; 139/8b ___________
.byte $00 ; 140/8c ___________
.byte $00 ; 141/8d ___________
.byte $00 ; 142/8e ___________
.byte $00 ; 143/8f ___________
.byte $00 ; 144/90 ___________
.byte $00 ; 145/91 ___________
.byte $00 ; 146/92 ___________
.byte $10 ; 147/93 ___________
.byte $00 ; 148/94 ___________
.byte $00 ; 149/95 ___________
.byte $00 ; 150/96 ___________
.byte $00 ; 151/97 ___________
.byte $00 ; 152/98 ___________
.byte $00 ; 153/99 ___________
.byte $00 ; 154/9a ___________
.byte $00 ; 155/9b ___________
.byte $00 ; 156/9c ___________
.byte $00 ; 157/9d ___________
.byte $00 ; 158/9e ___________
.byte $00 ; 159/9f ___________
.byte $00 ; 160/a0 ___________
.byte $00 ; 161/a1 ___________
.byte $00 ; 162/a2 ___________
.byte $00 ; 163/a3 ___________
.byte $00 ; 164/a4 ___________
.byte $00 ; 165/a5 ___________
.byte $00 ; 166/a6 ___________
.byte $00 ; 167/a7 ___________
.byte $00 ; 168/a8 ___________
.byte $00 ; 169/a9 ___________
.byte $00 ; 170/aa ___________
.byte $00 ; 171/ab ___________
.byte $00 ; 172/ac ___________
.byte $00 ; 173/ad ___________
.byte $00 ; 174/ae ___________
.byte $00 ; 175/af ___________
.byte $00 ; 176/b0 ___________
.byte $00 ; 177/b1 ___________
.byte $00 ; 178/b2 ___________
.byte $00 ; 179/b3 ___________
.byte $00 ; 180/b4 ___________
.byte $00 ; 181/b5 ___________
.byte $00 ; 182/b6 ___________
.byte $00 ; 183/b7 ___________
.byte $00 ; 184/b8 ___________
.byte $00 ; 185/b9 ___________
.byte $00 ; 186/ba ___________
.byte $00 ; 187/bb ___________
.byte $00 ; 188/bc ___________
.byte $00 ; 189/bd ___________
.byte $00 ; 190/be ___________
.byte $00 ; 191/bf ___________
.byte $02 ; 192/c0 ___________
.byte $02 ; 193/c1 ___________
.byte $02 ; 194/c2 ___________
.byte $02 ; 195/c3 ___________
.byte $02 ; 196/c4 ___________
.byte $02 ; 197/c5 ___________
.byte $02 ; 198/c6 ___________
.byte $02 ; 199/c7 ___________
.byte $02 ; 200/c8 ___________
.byte $02 ; 201/c9 ___________
.byte $02 ; 202/ca ___________
.byte $02 ; 203/cb ___________
.byte $02 ; 204/cc ___________
.byte $02 ; 205/cd ___________
.byte $02 ; 206/ce ___________
.byte $02 ; 207/cf ___________
.byte $02 ; 208/d0 ___________
.byte $02 ; 209/d1 ___________
.byte $02 ; 210/d2 ___________
.byte $02 ; 211/d3 ___________
.byte $02 ; 212/d4 ___________
.byte $02 ; 213/d5 ___________
.byte $02 ; 214/d6 ___________
.byte $02 ; 215/d7 ___________
.byte $02 ; 216/d8 ___________
.byte $02 ; 217/d9 ___________
.byte $02 ; 218/da ___________
.byte $02 ; 219/db ___________
.byte $02 ; 220/dc ___________
.byte $02 ; 221/dd ___________
.byte $02 ; 222/de ___________
.byte $00 ; 223/df ___________
.byte $01 ; 224/e0 ___________
.byte $01 ; 225/e1 ___________
.byte $01 ; 226/e2 ___________
.byte $01 ; 227/e3 ___________
.byte $01 ; 228/e4 ___________
.byte $01 ; 229/e5 ___________
.byte $01 ; 230/e6 ___________
.byte $01 ; 231/e7 ___________
.byte $01 ; 232/e8 ___________
.byte $01 ; 233/e9 ___________
.byte $01 ; 234/ea ___________
.byte $01 ; 235/eb ___________
.byte $01 ; 236/ec ___________
.byte $01 ; 237/ed ___________
.byte $01 ; 238/ee ___________
.byte $01 ; 239/ef ___________
.byte $01 ; 240/f0 ___________
.byte $01 ; 241/f1 ___________
.byte $01 ; 242/f2 ___________
.byte $01 ; 243/f3 ___________
.byte $01 ; 244/f4 ___________
.byte $01 ; 245/f5 ___________
.byte $01 ; 246/f6 ___________
.byte $01 ; 247/f7 ___________
.byte $01 ; 248/f8 ___________
.byte $01 ; 249/f9 ___________
.byte $01 ; 250/fa ___________
.byte $01 ; 251/fb ___________
.byte $01 ; 252/fc ___________
.byte $01 ; 253/fd ___________
.byte $01 ; 254/fe ___________
.byte $00 ; 255/ff ___________

30
libsrc/apple2/cvline.s Normal file
View File

@ -0,0 +1,30 @@
;
; Ullrich von Bassewitz, 08.08.1998
;
; void cvlinexy (unsigned char x, unsigned char y, unsigned char length);
; void cvline (unsigned char length);
;
.export _cvlinexy, _cvline
.import popa, _gotoxy, putchar, newline
.importzp tmp1
_cvlinexy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cvline
_cvline:
cmp #0 ; Is the length zero?
beq L9 ; Jump if done
sta tmp1
L1: lda #$7C ; Vertical bar
jsr putchar ; Write, no cursor advance
jsr newline ; Advance cursor to next line
dec tmp1
bne L1
L9: rts

18
libsrc/apple2/kbhit.s Normal file
View File

@ -0,0 +1,18 @@
;;
;; Kevin Ruland
;;
;; int kbhit (void);
;;
.export _kbhit
.import return0, return1
.include "apple2.inc"
_kbhit:
bit KEY_STROBE ; Reading strobe checks for keypress
bmi L1 ; if KEY_STROBE > 127 key was pressed
jmp return0
L1:
jmp return1

52
libsrc/apple2/read.s Normal file
View File

@ -0,0 +1,52 @@
;
; Ullrich von Bassewitz, 30.05.1998
;
; int read (int fd, void* buf, int count);
;
; THIS IS A HACK!
;
.export _read
.import popax, _cputc
.importzp ptr1, ptr2, ptr3
.include "apple2.inc"
_read: jsr popax ; get count
sta ptr2
stx ptr2+1 ; save it for later
jsr popax ; get buf
sta ptr1
stx ptr1+1
jsr popax ; get fd and discard it
lda #0
sta ptr3
sta ptr3+1 ; set count
L1: lda ptr2
ora ptr2+1 ; count zero?
beq L9
jsr RDKEY
and #$7f ; clear high bit.
pha
jsr _cputc
pla
ldy #0 ; offset into string
sta (ptr1),y ; save char
inc ptr1
bne L2
inc ptr1+1
L2: inc ptr3 ; increment count
bne L3
inc ptr3+1
L3: cmp #$0D ; CR?
bne L1
; Done, return the count
L9: lda ptr3
ldx ptr3+1
rts

25
libsrc/apple2/revers.s Normal file
View File

@ -0,0 +1,25 @@
;;
;; Kevin Ruland
;;
;; unsigned char __fastcall__ revers (unsigned char onoff)
;;
.export _revers
.include "apple2.inc"
_revers:
ldy TEXTTYP ; Stash old value
and #$FF ; Test for any bit
bne reverse ; Nothing set
lda #$FF
reverse:
ora #$3F
sta TEXTTYP
tya ; What was the old value?
eor #$FF ; Normal = $FF, Reverse = $3F
beq L2
lda #01
L2:
rts

18
libsrc/apple2/where.s Normal file
View File

@ -0,0 +1,18 @@
;; Keivn Ruland
;;
;; unsigned char wherex( void );
;; unsigned char wherey( void );
.export _wherex, _wherey
.include "apple2.inc"
_wherex:
lda CH
rts
_wherey:
lda CV
rts

53
libsrc/apple2/write.s Normal file
View File

@ -0,0 +1,53 @@
;;
;; Kevin Ruland
;;
;; int write (int fd, const void* buf, int count);
;;
;; for now will only write to fd = stdout
;;
.export _write
.import popax
.importzp ptr1, ptr2, ptr3
.include "apple2.inc"
_write:
jsr popax ; get count
sta ptr2
stx ptr2+1 ; save for later
sta ptr3
sta ptr3+1 ; save for result
jsr popax ; get buf
sta ptr1
stx ptr1+1
jsr popax ; get fd and discard
L1: lda ptr2
ora ptr2+1 ; count zero?
beq L9
ldy #0
lda (ptr1),y
cmp #$0A ; Check for \n = Crtl-j
bne rawout
lda #$0D ; Issue cr
rawout:
ora #$80
jsr COUT
inc ptr1
bne L2
inc ptr1+1
L2: lda ptr2
bne L3
dec ptr2
dec ptr2+1
jmp L1
L3: dec ptr2
jmp L1
; No error, return count
L9: lda ptr3
ldx ptr3+1
rts

32
libsrc/atari/Makefile Normal file
View File

@ -0,0 +1,32 @@
#
# makefile for CC65 Atari runtime library
#
ATARIDEFS = -DDIRECT_SCREEN
.SUFFIXES: .o .s .c
%.o: %.c
@echo $<
@$(CC) $(CFLAGS) $(ATARIDEFS) $<
@$(AS) -o $@ $(AFLAGS) $(*).s
%.o: %.s
@echo $<
@$(AS) -g -o $@ $(AFLAGS) $(ATARIDEFS) $<
C_OBJS =
S_OBJS = crt0.o kbhit.o conio.o clrscr.o cputc.o ctype.o chline.o cvline.o \
color.o gotoxy.o cclear.o revers.o readjoy.o break.o where.o write.o \
gotox.o gotoy.o savevec.o rwcommon.o cgetc.o read.o getargs.o close.o \
open.o oserror.o fdtable.o
all: $(C_OBJS) $(S_OBJS)
clean:
@rm -f $(C_OBJS:.c=.s)
@rm -f $(C_OBJS)
@rm -f $(S_OBJS)
@rm -f crt0.o

1028
libsrc/atari/atari.inc Normal file

File diff suppressed because it is too large Load Diff

106
libsrc/atari/break.s Normal file
View File

@ -0,0 +1,106 @@
;
; Christian Groessler, 27-Feb-2000
;
; void set_brk (unsigned Addr);
; void reset_brk (void);
;
.export _set_brk, _reset_brk
.export _brk_a, _brk_x, _brk_y, _brk_sr, _brk_pc
.import _atexit
.include "atari.inc"
.bss
_brk_a: .res 1
_brk_x: .res 1
_brk_y: .res 1
_brk_sr: .res 1
_brk_pc: .res 2
oldvec: .res 2 ; Old vector
.data
uservec: jmp $FFFF ; Patched at runtime
.code
; Set the break vector
.proc _set_brk
sta uservec+1
stx uservec+2 ; Set the user vector
lda oldvec
ora oldvec+1 ; Did we save the vector already?
bne L1 ; Jump if we installed the handler already
lda VBREAK
sta oldvec
lda VBREAK+1
sta oldvec+1 ; Save the old vector
lda #<_reset_brk
ldx #>_reset_brk
jsr _atexit ; Install an exit handler
L1: lda #<brk_handler ; Set the break vector to our routine
sta VBREAK
lda #>brk_handler
sta VBREAK+1
rts
.endproc
; Reset the break vector
.proc _reset_brk
lda oldvec
sta VBREAK
lda oldvec+1
sta VBREAK+1
rts
.endproc
; Break handler, called if a break occurs
.proc brk_handler
sty _brk_y
stx _brk_x
pla
sta _brk_a
pla
and #$EF ; Clear break bit
sta _brk_sr
pla ; PC low
sec
sbc #2 ; Point to start of brk
sta _brk_pc
pla ; PC high
sbc #0
sta _brk_pc+1
jsr uservec ; Call the user's routine
lda _brk_pc+1
pha
lda _brk_pc
pha
lda _brk_sr
pha
ldx _brk_x
ldy _brk_y
lda _brk_a
rti ; Jump back...
.endproc

34
libsrc/atari/cclear.s Normal file
View File

@ -0,0 +1,34 @@
;
; Ullrich von Bassewitz, 08.08.1998
;
; void cclearxy (unsigned char x, unsigned char y, unsigned char length);
; void cclear (unsigned char length);
;
.export _cclearxy, _cclear
.import popa, _gotoxy, cputdirect
.importzp tmp1
_cclearxy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length and run into _cclear
_cclear:
cmp #0 ; Is the length zero?
beq L9 ; Jump if done
sta tmp1
.ifdef DIRECT_SCREEN
L1: lda #0 ; Blank - screen code
.else
L1: lda #$20 ; Blank
.endif
jsr cputdirect ; Direct output
dec tmp1
bne L1
L9: rts

17
libsrc/atari/cgetc.s Normal file
View File

@ -0,0 +1,17 @@
;
; get a kbd char.
;
; char cgetc(void)
;
.include "atari.inc"
.export _cgetc
_cgetc:
lda KEYBDV+5
pha
lda KEYBDV+4
pha
rts
ldx #0
rts

34
libsrc/atari/chline.s Normal file
View File

@ -0,0 +1,34 @@
;
; Ullrich von Bassewitz, 08.08.1998
;
; void chlinexy (unsigned char x, unsigned char y, unsigned char length);
; void chline (unsigned char length);
;
.export _chlinexy, _chline
.import popa, _gotoxy, cputdirect
.importzp tmp1
_chlinexy:
pha ; Save the length
jsr popa ; Get y
jsr _gotoxy ; Call this one, will pop params
pla ; Restore the length
_chline:
cmp #0 ; Is the length zero?
beq L9 ; Jump if done
sta tmp1
.ifdef DIRECT_SCREEN
L1: lda #$12+64 ; Horizontal line, screen code
.else
L1: lda #$12 ; Horizontal line
.endif
jsr cputdirect ; Direct output
dec tmp1
bne L1
L9: rts

36
libsrc/atari/close.s Normal file
View File

@ -0,0 +1,36 @@
;
; Christian Groessler, May-2000
;
; int close(int fd);
;
.include "atari.inc"
.export _close
.import __do_oserror,popax,__oserror
.import fdtoiocb_down,__inviocb
.proc _close
jsr popax
jsr fdtoiocb_down ; get iocb index into X and decr. usage count
bmi inverr
bne ok ; not last one -> don't close yet
; asl a
; asl a
; asl a
; asl a
; tax
lda #CLOSE
sta ICCOM,x
jsr CIOV
bpl ok
jmp __do_oserror
ok: ldx #0
stx __oserror ; clear system specific error code
txa
rts
inverr: jmp __inviocb
.endproc

47
libsrc/atari/clrscr.s Normal file
View File

@ -0,0 +1,47 @@
;
; Christian Groessler, Apr-2000
;
; void clrscr (void);
;
.export _clrscr
.include "atari.inc"
.ifdef DIRECT_SCREEN
.importzp ptr1
_clrscr:lda SAVMSC ; screen memory
sta ptr1
lda SAVMSC+1
clc
adc #>(40*24)
sta ptr1+1
lda #0 ; screen code of space char
ldy #<(40*24) ; 40x24: size of default atari screen
ldx #>(40*24)
_clr1: sta (ptr1),y
dey
bne _clr1
sta (ptr1),y
dex
bmi done
ldy ptr1+1
dey
sty ptr1+1
ldy #255
jmp _clr1
done: sta COLCRS
sta ROWCRS
rts
.else
.import putchar
_clrscr:
lda #ATCLR
jmp putchar
.endif

33
libsrc/atari/color.s Normal file
View File

@ -0,0 +1,33 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _textcolor, _bgcolor, _bordercolor
.include "atari.inc"
_textcolor:
ldx COLOR1 ; get old value
sta COLOR1 ; set new value
txa
rts
_bgcolor:
ldx COLOR2 ; get old value
sta COLOR2 ; set new value
txa
rts
_bordercolor:
ldx COLOR4 ; get old value
sta COLOR4 ; set new value
txa
rts

20
libsrc/atari/conio.s Normal file
View File

@ -0,0 +1,20 @@
;
; Christian Groessler
;
; Low level stuff for screen output/console input
;
.export initconio
.import xsize, ysize, plot
.include "atari.inc"
.code
initconio:
ldx #40
ldy #24
stx xsize
sty ysize
rts

Some files were not shown because too many files have changed in this diff Show More