Re: [cc65] c64 kernal 02 vs. 03

From: Thomas Giesel <>
Date: 2009-09-26 14:46:14
Hi all,

> From my (still incomplete) analysis, I think this fix is only needed
> if you output the backspace. Feel free to proove me wrong. ;)

Maybe you didn't see the example program yesterday, which also crashs on
02 kernals without using a backspace. After having slept enough, let me
do the complete analysis:

Let's have a look at one of the bad scenarious again:

    for (;;)
        cputcxy(39, 5, '*');

This moves the cursor to the last coloumn of a line and prints a
character. This leads to a movement of the cursor to the next line,
which is fine normally. The next loop sets the cursor back and repeats
the stuff. After a few loops the I/O memory behind the color RAM gets
overwritten, e.g. CIA $dc00 etc.

Why does this happen with 02 kernals? It's easy to explain, once the
reason was found. Lets have a look what cputcxy does:

Check libsrc/c64/putc.s and libsrc/cbm/gotoxy.s.

First it calls _gotoxy, this functions writes the cursor position (39,5)
to the right zeropage locations CURS_X = $d3 and CURS_Y = $d6. Then it
jumps to "plot", which is in putc.s. This function gets the cursor
coordinated into the X/Y registers and calls the kernal vector $fff0
(set cursor position). 

Now follow the call chain in the Kernal: $fff0 => $e56c. Here we see
the difference between the two kernals.

The 03 kernal calculates, among others, the screen pointer at $d1/$d2,
this is done by calling a function at $e9f0. Finally it jumps to $ea24
to calculate the Color RAM pointer $f3/$f4.

The 02 kernel DOES NOT calculate the color RAM pointer when being
called at $fff0! It calculates the screen pointer only.

Now lets go back to the libsrc. Our state is now that on a 03 kernal
the color ram pointer and the screen pointer are in sync, while on
a 02 kernal the Color RAM pointer hasn't been updated.

After a few checks the label "putchar" is called. This functions writes
the character to the current screen pointer and the color to the
current Color RAM pointer (which is out of sync on a 02 kernal).

After this is done the code at label "advance" finds out that we are
on the last coloumn and branches to "newline". This code adds the line
length XSIZE to the color RAM pointer.

There's nothing wrong with adding XSIZE at this point. But because in
the test program above the Color RAM pointer is NEVER correctly
updated, it goes higher and higher until it reaches other I/O memory.

How to fix this? I'm still not sure about the best way, these are my
ideas at the moment:

1) Call $ea24 from "plot" to make sure the color RAM pointer gets
   - That's not an official kernal entry, does it work on other kernals
     (e.g. Jiffy and many other modified kernels)?

2) Check all of the callers which call $ea24
   Maybe there's one we can use from an official kernal entry point?

3) Put the code from $ea24 into libsrc directly
   - Only a few bytes, should be okay to add it to "plot" at

Which of these ways is your preference? I tend to 3).

We also should check other functions of c64.lib regarding this issue.

btw: The 02 Kernal can be found more often than I thought, many older
board revisions have this kernal.



To unsubscribe from the list send mail to with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Sat Sep 26 14:46:23 2009

This archive was generated by hypermail 2.1.8 : 2009-09-26 14:46:25 CEST