** New Frontiers in VIC-Hires-Graphics, Part 7

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
tokra
Vic 20 Scientist
Posts: 1123
Joined: Tue Apr 27, 2010 5:32 pm
Location: Scheessel, Germany

** New Frontiers in VIC-Hires-Graphics, Part 7

Post by tokra »

This part explains how the resolution of 208x256 was realized, that is used in MAXIGRAFIK. I've finished the first prototype that displays this resolution on June, 23rd, but now you have something much better with the BASIC-extension Mike wrote for it to be able to use this to the fullest (which I hope you will!)

Once the 208x248 resolution was done I realized that this was the best that could be done with the current concept: the raster time was used up nearly completely and the other idea of precalculating the display-routine for each image also fell through because of raster timing. If only I had more raster time, I could increase the resolution... but where to get it?

Then it dawned on me: Operations in the zero-page take one less cycle than to other pages, for example:

lda #$01
sta $1000

uses 2+4=6 cycles. While

lda #$01
sta $00

only uses 2+3=5 cycles. So if I could put as much as possible of the graphics data into the zero page I would save 256 cyles for each full zero page. I realized this would mean a lot more splits, but I started calculating: A double-character line of 208x16 takes up 416 bytes - of which 256 would be in the zero-page and another 160 in page 1. So I would need to overwrite these 416 bytes as often as possible while making sure not to display exactly these bytes while I'm doing the updates. Updating those 416 bytes takes 2240 cycles. Displaying one raster line takes the VIC 71 cycles in PAL. Which means I needed at least 2240/71=31,55 lines in between 208x16 zones to do the updates. This got me excited, since 31,55 is very close to 32 and I can only display multiples of 16 due to the double-character mode anyway. The fit was just too good to be true. I crunched the numbers some more and after some trial and error came up with the following layout:

Code: Select all

AAAAAAAAAAAAAAAABBBBBBBBBB  16-1
AAAAAAAAAAAAAAAABBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCC  32-1
CCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDEEEEEEEEEE  16-2
DDDDDDDDDDDDDDDDEEEEEEEEEE
FFFFFFFFFFFFFFFFFFFFFFFFFF  32-2
FFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFF
GGGGGGGGGGGGGGGGHHHHHHHHHH  16-3
GGGGGGGGGGGGGGGGHHHHHHHHHH
IIIIIIIIIIIIIIIIIIIIIIIIII  32-3
IIIIIIIIIIIIIIIIIIIIIIIIII
IIIIIIIIIIIIIIIIIIIIIIIIII
IIIIIIIIIIIIIIIIIIIIIIIIII
JJJJJJJJJJJJJJJJKKKKKKKKKK  16-4
JJJJJJJJJJJJJJJJKKKKKKKKKK
LLLLLLLLLLLLLLLLLLLLLLLLLL  32-4
LLLLLLLLLLLLLLLLLLLLLLLLLL
LLLLLLLLLLLLLLLLLLLLLLLLLL
LLLLLLLLLLLLLLLLLLLLLLLLLL
MMMMMMMMMMMMMMMMNNNNNNNNNN  16-5
MMMMMMMMMMMMMMMMNNNNNNNNNN
OOOOOOOOOOOOOOOOOOOOOOOOOO  16-6
OOOOOOOOOOOOOOOOOOOOOOOOOO
PPPPPPPPPPPQQQQQQQQQQQTTTT  32-5
PPPPPPPPPPPQQQQQQQQQQQTTTT
RRRRRRRRRRRSSSSSSSSSSSTTTT
RRRRRRRRRRRSSSSSSSSSSSTTTT
The areas 16-1 to 16-5 are switched around in the zero-page while the 32-x areas are displayed. 16-6 resides flat from $01a0-$033f with no switching. Areas 32-2 to 32-4 are flat as well, while areas 32-1 and 32-5 area switched against each other. 32-1 is updated while the raster beam has finished displaying the graphics and 32-5 is updated during the 16-x areas. The 32-5 is heavily fragmented as each 16-x area only leaves 16x71 = 1136 cycles for updates. With each byte update using 6 cycles this means only about 189 bytes may be updated. I'm updating up to 22 chars (=176 bytes this way) during each 16-x area. Maybe my comments from the source-code make it a little clearer:

Code: Select all

; Raster-Split-Hires - True 208 * 256 pixels
; only for PAL-VIC 20
; Video-Ram Top: 4096-4511 = 416 double height chars
; Char-Ram  Top: 4512-8191 ($11a0-$1e9f) = 3328 Byte
; (208 * 128 res - split to 4x 208*32 res - top area switched around 2 times)
; 
; Low 1k Char-Ram: 0-831 ($0000-$033f) = 832 Byte
; (208 * 32 res - split to 2x 208x16 res - top area switched around 5 times)
; mapped to ($2000-$233f) = (8192-9023) Char 0-51


; 56blanklineswitch       -> fill 32-1switch 1/2 - routine: write321
; 208x16 16-1switch       -> fill 32-1switch 2/2 - routine: write321
; 208x32 32-1switch       -> fill 16-2switch     - routine: write162
; 208x16 16-2switch       -> fill 32-5switch 1/5 - routine: write3251
; 208x32 32-2 $14e0-$181f -> fill 16-3switch     - routine: write163
; 208x16 16-3switch       -> fill 32-5switch 2/5 - routine: write3252
; 208x32 32-3 $1820-$1b5f -> fill 16-4switch     - routine: write164
; 208x16 16-4switch       -> fill 32-5switch 3/5 - routine: write3253
; 208x32 32-4 $1b60-$1e9f -> fill 16-5switch     - routine: write165
; 208x16 16-5switch       -> fill 32-5switch 4/5 - routine: write3254
; 208x16 16-6 $21a0-$233f -> fill 32-5switch 5/5 - routine: write3255
; 208x32 32-5switch       -> fill 16-1switch     - routine: write161
;
; 5 areas of 208x16 (16-1 to 16-5) reside in the zero-page allowing for faster lda #xx sta $yy writes (2240 cycles per area = 256 * 5 + 160 * 6) = 11200 cycles
; 2 areas of 208x32 (32-1 and 32-5) are switched as well = (4992 cycles per area = 832 * 6) = 9984 cycles
; total 21184 cycles leaving 968 cycles. 
In the end everything fit nicely, I had just enough raster time for the updates in the zero-page and other areas to allow for the bigger resolution. The biggest pain was adjusting when exactly an area can be started to be updated to make sure the VIC has displayed the graphics-data before it can be overwritten with new information for the next appearance. The CPU and the VIC really need to work hand in hand for this to work. And all of this happens 50 times each second!

I realize this post is highly technical, but I wouldn't have been able to come up with it if other technical documentation wasn't posted online as well. Especially Marko Makela's Making stable raster routines has been a big help in understanding how the VIC works, how many cycles a line needs and how many lines a picture has for the VIC. So, if anyone has questions regarding this or - even better - own ideas go ahead and post them, even if you may think they are stupid at first.

Oh, BTW: I have Part 8 already prepared... ;-)
Post Reply