During the developement of a new game [Original Link (DE): http://blog.c128.net/archives/442 ; (bad) translation (EN): http://translate.google.de/translate?u=http%3A%2F%2Fblog.c128.net%2Farchives%2F442&sl=de&tl=en&hl=&ie=UTF-8 ] I found a mystery as I tried to activate my own 40 column charset with hires graphic on. The result of manipulating the VIC directly (read $d018, select bits, write $d018) was a total desaster. The C128 crashed (the VICE emulator didn't do that). Manipulation of the "zeropage" mirror register of the VIC however works fine.
The following code shows the problem:
1 printpeek(dec("d018"))
2 printpeek(dec("d018"))
3 graphic1,0
4 printpeek(dec("d018"))
5 printpeek(dec("d018"))
6 printpeek(dec("d018"))
7 graphic0
run
21
21
21
121
121
ready.
My question, why crashed* the (original) C128?
And what the f*** is the origin of the "121"?
Regards
WTE
* the crash takes place after reading the ("wrong" value) 121, manipulation of some bits and storing a ("wrong") 121 (instead of 25) to $d018 and the mirror byte!
Since you obviously haven't turned off the C128's own screen handling routine, the C128 will store to $d018 every raster interrupt. When you switch graphics modes in line 3, the C128 probably sets up a new value (i.e. 121) to be written to $d018 every raster interrupt.
It's not surprising that you get some kind of error when you try to write both to the shadow register and to $d018. As long as the C128's own screen handler is active you should never write directly to $d018. That's why there is a shadow register. See Christian Johansson's excellent C128 assembly programming article (http://commodore64.se/wiki/index.php/Commodore_128_assembly_programming).
When running the program you posted in VICE, I get the same output as you did, although I get 121 the last three times, which would be after the graphics mode change. That's probably as it should be.
...you obviously haven't turned off the C128's own screen handlingroutine
correct!
the C128 will store to $d018 every raster interrupt. When youswitch graphics modes in line 3, the C128 probably sets up a new value(i.e. 121) to be written to $d018 every raster interrupt.
so far so good (that's what I understand after my experiment)
But where does this 121 come from? I couldn't find the related code in the "screen handler". And why crashed the C128 after "poking" 121 to the mirror register of $d018 (and - I forgot to say - pressing RETURN several times)?
Regards WTE
Decimal +121 = Hexadecimal $79 = Binary %0111_1001. The upper nibble (%0111) tells VIC to fetch text / bitmap_color from $1c00 and the lower nibble (%1001) tells VIC to fetch char_defs / bitmap_pixels from $2000.
Note: the lowest bit is ignored and assumed zero even though reading register will return lowest bit as one... so read will give +121 but the real value is decimal +120 = hex $78... low nibble of 8 means data at $2000 / $6000 / $a000 / $e000 (depending on VIC bank).
Just multiply "real" low nibble (in this case 8, not 9) by hex value $0400 (by decimal 1024). In this case, 8 * 1024 = 8192 (hexadecimal $2000). That is where VIC will look for bitmap / font_data.
Hopefully this helps, if not let me know and I will try to clarify...