Power C for the Commodore 64(last updated 2010-07-18) |
This page is about the Power C compiler for the Commodore 64. It's one of the best high-level languages available for this machine, with an excellent editor, a compiler, and a linker. Although its dialect is K & R (pre-ANSI) C, it's very capable. An assembler is also available, making it even more useful for large projects (see the links to Transactor articles on linking C and assembly). Further down the page, you'll find a collection of add-on utilities I downloaded from Q-Link back in the day. If you have any questions, you can mail me email me (shadowm at lyonlabs.org).
The Power C Compiler (D64 images)
Power C Tips 'n' Tricks
Power C and Assembly Language
Power C Downloads
You may also find this Power C page interesting. It's from Hannenz, who has written quite a bit of Power C code including ports of common UNIX utilities and his own assembler (a replacement for C-ASSM). He's also got the 128 versions.
Here are D64 images of the Power C diskettes as distributed. There's also a complete copy of the documentation.
side one
side two
manual
(from DLH)
Here are some helpful things I've found while using Power C:
Remember to use old-style function declarations; you will get hard-to-find errors otherwise.
Modern function declaration:
int foo (int bar) {
// clever code here
}
K & R (old-style) function declaration (use for Power C):
int foo (bar)
int bar; {
// clever code here
}
Be careful not to use the same field names in different structures; Power C will confuse them. I recommend using a prefix for each structure field, like this:
struct extMenu {
int emRecno;
char emFlags;
int emFirst;
}
In Power C, you can declare a function with no return value (instead of a void return value). However, if you need to reference the address of such a function later, the compiler won't let you. This won't work:
dispatch() {
/* some code here */
}
widget->wAction = &dispatch;
But it will if you just change the function declaration to
return int.The editor's multiple buffer support can be very useful. If you're working on a large source file and want to print just part of it for study, select the region, then delete it and paste it right back again. Then open another buffer (e.g. hit STOP and enter "go print"), paste the region into it, and print it by hitting STOP and entering "pr".
There appears to be a bug in the compiler: on rare occasions it will just hang during a compile and the machine will have to be restarted; the result will be a couple of splat files with names like XXXTEMP. Make sure you validate the drive your source is on if this happens!
Another rarely-seen bug in the compiler is that he sometimes shows a lower-case 'g' on a line by itself at the end of the source when the compile completes, with an "illegal character" message. Ignore it and compile again.
The trim utility mentioned in the documentation
sounds like a great idea, and I've seen it reduce the size of object
files by 25% or more... but I've also found strange bugs that could
reliably be fixed by recompiling modules without trimming
them. My advice is not to use it; find other ways to optimize your
code (like writing some of the program in assembler using
C-ASSM).
.ref c$funct_init ;linker will resolve
.def funcname ;tell linker our name
parmndx = $4b
data = $4c
c$parms = $033c
funcname jsr c$funct_init
stx parmndx ;index to parameters
lda c$parms,x ;function parameters
sta data
lda c$parms+1,x
sta data+1
;do something interesting with the int...
ldx parmndx
lda data
sta c$parms,x ;return the int
lda data+1
sta c$parms+1,x
rts
You can use the temporary storage areas from $22 - $2a
and $4b - $60 in your function.C-ASSM's expression syntax is unusual compared to that of other Commodore assemblers. For example, say you have a routine to check for numeric characters, and you want to compare to '0' and then to "the character after 9". The code would be:
cmp #'0
bcc notnum
cmp #['9+1]
bcs notnum
...You may be tempted to name assembler modules starting with an
underscore... don't. You'll find later on that you
can't put them into a library using the lib utility!
Symbols starting with underscores (e.g. alternate entry points for
functions that can be called from either C or assembler) are OK,
though: lib doesn't show them when you display the
contents of a library, but trust me, they're there.
Have you wanted to rewrite some of your C code in assembler
only to end up saying to yourself "but I'll need to call
malloc()"? Well, you can. Just bypass the call to
c$funct_init by calling 16 bytes into
malloc's object code, like this:
.ref c$funct_init ;linker will resolve
.ref malloc
parmndx = $4b
jsr c$funct_init
stx parmndx ;index to parameters
;assume amount of memory to allocate is in memsize
lda memsize
sta $4c
lda memsize+1
sta $4d
jsr malloc+16
ldx parmndx
lda c$parms,x
ora c$parms+1,x
beq error ;oops, malloc() returned 0
;use the memory pointer at c$parms,x
memsize .bss 2
You can also call free() from assembler, by
JSRing to free+3. Just bear in mind that
both routines use the temporary storage area, so you may need to save
your local variables before the call and restore them again
afterward. parmndx ($4b), however, is not disturbed when
calling them in this way. (Hint: there's a reverse assembler in the
download section below.)
This is a collection of add-ons for Power C. The files are Commodore
binaries or PETSCII text, and are presented here just as I downloaded
them from Q-Link many years ago. Most of them are ARC files, so you
will need to download that first (just LOAD"ARC250",8 and
RUN). There is a documentation file for ARC as well. In a
few cases, I had hardcopy of the original Q-Link download descriptions
and typed them in by hand (in ASCII).
(See also Hannenz' site, which includes some modern additions.)
ARC archiving utility and shell:
C-Windows by Rubens Abboud (windowing utility that does a custom character set 40 in 64, or 80 columns):
A graphics library by David Kesler and David Brown:
C-ASSM by Mark Rinfret and David Zarling, an assembler (written in C) that creates Power C compatible object files:
ra.arc a reverse assembler (note
that ra depends on openfile.c, found in cassm)
D64 image (de-compressed arc file,
with everything compiled and linked)
original Q-Link download
description
Utilities and replacements for Power C by Adrian Pepper:
newshell.arc source, docs and
executable for a replacement shell (with "exec" scripts)
original Q-Link download
description
A debugger by Alan Yorinks:
Here's something a little more obscure... it's some code I hacked together with help from the guys on the comp.sys.cbm mailing list. It's a machine language routine, meant to be called from a Power C program, that loads and runs a BASIC program.
assembler source (ASCII, Unix-formatted)