home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
64'er
/
64ER_CD.iso
/
utilpc
/
cc64
/
cc64.doc
< prev
next >
Wrap
Text File
|
1994-10-06
|
12KB
|
241 lines
About cc64
----------
cc64 is a small C compiler for the C-64. The current version V0.3 is
still in beta test stage. The same applies to the text editor peddi,
version 0.1.
cc64 and peddi may be freely copied, providing that this documentation
is passed along as well.
cc64 and peddi both come with ABSOLUTELY NO WARRANTY. I will take no
responsibility for any damage resulting in any way from the use of
cc64 or peddi.
What is there
-------------
cc64 comes as three programs:
peddi0.1 -- a small text editor
cc64v0,3 -- the compiler
cc64v0.3pe -- compiler and editor together in one program
They're all written in FORTH and compiled around a 60 blocks long
FORTH kernel. Then there is
c-charset -- load it ,8,1 and activate it with SYS52027. It will patch
a few ASCII characters such as braces and backslash into the 64's
charset. It will be re-activated each time peddi or cc64v0.3pe is started.
bl02.x -- The base library, assembler source, object code, static
variable initialization and header file. See library description below.
io.c/o/i/h -- an extended library giving access to the 64's basic i/o
calls. On the distribution disk it is present compiled with an
out-of-date base library. Change the #include statement at the
beginning into #include <bl02.h> and recompile it before use.
t3.c -- a little test program. Will not compile properly because of
the static variable i declared in the beginning. Just remove that
declaration and it should compile correctly and run "hello, world".
How to use it
-------------
As said, cc64 and peddi are written in FORTH. After starting them
You'll get an OK prompt, and HELP will list You the availible commands.
Some commands require numeric parameters; those must be entered _before_
the command. We're FORTH, so we're RPN (reversed polish notation). The
commands are:
help -- list all commands
cc file.c -- start the compiler for the program file.c
ed file -- edit file
cat file -- type the contents of file on the screen
dos -- read and print the floppy's error channel
dos xxx -- send the command xxx to the floppy
dir -- list the directory
mem -- show the compiler's memory setup
xxx set-himem -- set the limit of the compiler's memory to xxx. Don't
change this to a value greater than $cbd0 if You want to use
c-charset. xxx may be a decimal number or a hex number,
preceeded by a $
xxx set-heap -- sets the heap to xxx links. For each function in a C
program that is used before it is defined (a prototype must
exist before the first call) one link is needed.
xxx set-hash -- sets the hash table size for global symbols. Needs at
least one element per global symbol in a C program. Should
be sized a bit generous otherwise hashing will be inefficient.
xxx set-symtab -- sets the symbol table size (used both for local and
global symbols). Must be increased if You run into a Symbol
table overflow error.
xxx set-code -- sets the size of the code buffer. The code for any C
function being compiled must fit into this buffer. Otherwise
You get a function too long error. Then increase the code
buffer size or split the long function up in two or more.
The size of the static buffer is determined by the remaining memory.
This size is not critical. It should be positive, though. :)
xxx yyy set-stacks -- sets the size of data and return stack and
resets the system. The stacks'size determine the maximum
depth of arithmetic expressions and the maximum number of
nested compound statements the compiler can handle. Stack
overflows are checked; I hope those checks are reliable.
If the compiler should behave strangely on a complicated
(i.e. deeply nested) expression RELOAD IT FROM DISK and set
the stack sizes to higher values.
saveall name -- saves the complete compiler together with its actual
memory settings.
bye -- leave to basic
Peddi - how to use
------------------
Peddi is a small full screen, scrolling PETSCII editor. No limit in line
length (exept memory). Memory overflow is signalled by a double flash
of the screen border.
You call peddi with
ed filename
The peddi key bindings:
cursor keys - as usual
return - split line
shift-return - goto begin of next line
del - del left of cursor or join lines
inst - insert a blank line
home - redraw screen
clr - kill line
F1 - 20 lines up
F7 - 20 lines down
ctrl-a - begin of line
ctrl-e - end of line
ctrl-d - del under cursor
ctrl-@ - del to cursor
ctrl-^ - del from cursor
ctrl-p - clear line
ctrl-w - save text
ctrl-x - exit and save text
ctrl-c - quit without saving
Known bugs
----------
Just one, though a pretty bad one. The linker cannot handle static
variables so far. So only programs which just use local automatic
variables are compiled correctly. I'll fix that as soon as I can.
Please report any other bugs You find to me. Mail to zem@iwm.fhg.de
Code layout and library concept
-------------------------------
Since I didn't want to write a symbolic linker cc64 uses a library
concept different from that of normal C compilers. It is more like
that of Turbo Pascal 3.0: The code is compiled next to a fixed runtime
module. But You can choose which module You want and extend any
existing module.
The selection of the module to use is done by a special preprocessor
command: #special cc64
It must appear in a program before the first code or variable is
generated and is usually the first command in the library's header
file. So all You have to do is to include the header file of the
module/library You want to use. Put this #include as the first
statement in Your programs.
For those interested in the technical details: The #special cc64
command tells the compiler the addresses of the software stack pointer
and an additional zero page pointer the compiled code shall use, then
the library's first address, the address of the jumplist described
below, the library's last address + 1, the first address and the last
address + 1 of the library's static variables, and the name of the
library without extension (i.e. bl02 in case of the base library on
the distribution disk). This way the compiler is completely flexible
concerning the surrounding in which the compiled code shall run, and
by creation of a suitable runtime library it is no problem to create
programs which will run in the 64's BASIC memory (as bl02 does), or
use all memory from $0801 to $d000, or just $c000 to $d000, or run on
any other 6502-based computer.
If You want to write Your own base library, this is what You must know:
Th compiler accesses the library via a jumplist. This list has the
following structure:
jumplist
main.adr .word 0 ; Here the main()-function's address is inserted
; by the compiler. The lib's init routine should
; call main() by a jmp (main.adr)
code.last .word 0 ; At these addresses the compiler places the last
init.first .word 0 ; address + 1 of the generated code and the first
init.last .word 0 ; address and the last address + 1 of the static
; variables. Statics are allocated from the end of the used memory
; downwards. The statics' initialization values are stored by the
; compiler from code.last and in reversed order. Your initialization
; routine should copy (code.last) to (init.last) - 1, (code.last) + 1 to
; (init.last) - 2 and so an. Mark: there may be no static variables,
; then init.first will be equal to init.last.
jmp (zp) ; Just have this explicitly standing here; it is
; used to emulate jsr (zp). zp is the second zero
; page pointer used by the compiler.
jmp switch ; Is called with a/x containing a 16 bit value.
; Following the calling jsr-instruction is a data
; structure described below containing values
; and addresses to jump to if a/x matches a value.
; The switch routine should find that data
; structure and jump to the corresponding
; address if a/x matches a value in the list.
; If no value matches it should jump behind the list.
jmp mult ; Should multiply (signed) the content of a/x
; (a:lo-byte, x:hi-byte) with the integer in zp/zp+1
; leaving the result in a/x.
jmp divmod ; Should divide (signed) zp/zp+1 by a/x, leaving
; the result in a/x and the remainder in zp/zp+1.
jmp shl ; Should arithmetically shift left a/x by y bits.
jmp shr ; Should arithmetically shift right a/x by y bits.
This jumplist may be positioned anywhere in the library; it's address
must be told to the compiler with the described #special command.
The Your library should have a init routine which finally will call
the program's main()-function. In which way this routine is called is up
to You. bl02 uses a BASIC line to start init. If You want programs to
run in $c000-$d000, You might want init to stand at the beginning of
the library so You can call Your programs with SYS49152.
However, the init routine should do two things before calling main()
with a jmp (main.adr) instruction. It should copy the static
variables' initialization values to the variables' actual addresses as
described above. And it should set the software stack pointer to an
initial value. The software stack is used for the allocation of local
variables and grows to high addresses. Its stack pointer therefore
should be set either to the code.last address or to
code.last + init.last - init.first, i.e. behind the statics'
initialization values. The former gives more memory for local
variables, but the software stack will destroy the init values. bl02
employs the latter alternative.
Supported subset of the C language
----------------------------------
cc64 is based on the old K&R standard. No ANSI, sorry. There are,
however, some restrictions. Only int and char as basic data types are
supported. No structs, no unions, only one level of pointer (nothing
like char **p). No type casts. No goto. #define can only give a
numeric value to a macro. No proper text substitution. No macros with
parameters. No #undef. No #ifdef/#ifndef. No typedef, no enum. That's
it, I think.
C extensions
------------
There are two non-standard declaration forms in cc64. They both
include an operator, /= and *=.
With /= an explicit value is assigned to a symbol, e.g.
extern int i /= 0x9ffe ;
extern char fgetc() /= 0xa02 ;
They usually are not used explicitly in programs but appear in library
header files (see below).
cc64 supports a special kind of functions. They only take one argument
and can be called very fast without any software stack manipulation,
just with the parameter in a/x. They will normally be written in
assembler and are declared with *=, e.g.
extern char getchar() *= 0xffcf ;
Such standard functions can be included in a base library.
There's one problem. If You put a standard function's address into a
function pointer and call the function pointer, the parameter won't be
passed properly. This will probably be dealt with in the next compiler
version. Btw, I'd like any comments if You consider this necessary.
The solution would disable such elegant declarations as of getchar()
above.
Building libraries
------------------
Base libraries can easily be expanded with C code. If You compile a C
file which contains no main() function then a new library is
generated. A header file is automatically generated with a
#special cc64 line and declarations of all C functions compiled. The
new library can be used as a new base library, and all contained C
functions can be used.
So, I hope that's enough. Have fun with cc64, and don't hesitate to
contact me if any problems, bugs or questions arise.
Philip Zembrod, zem@iwm.fhg.de