Commodore 128 Alive!

Commodore 128 => 128 programmers => Topic started by: wte on March 23, 2010, 08:40 AM

Title: VIC register mystery
Post by: wte on March 23, 2010, 08:40 AM
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!
Title: Re: VIC register mystery
Post by: bacon on March 25, 2010, 07:48 PM
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.
Title: Re: VIC register mystery
Post by: wte on March 27, 2010, 09:52 AM
...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
Title: Re: VIC register mystery
Post by: Hydrophilic on May 06, 2010, 09:29 PM
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...
EhPortal 1.34 © 2025, WebDev