VIC register mystery

Started by wte, March 23, 2010, 08:40 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

wte

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!

bacon

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.

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.
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.

wte

...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

Hydrophilic

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...
I'm kupo for kupo nuts!