|
Post by willymanilly on Oct 17, 2018 14:53:56 GMT
Ah, thanks for the observation regarding register 7. I noticed this myself but had no explanation. Your idea of mering two frames would only be useful for expanding the 8x1-mode for PAL I guess? Another thing: Why do you think interlace-text-mode with attributes has graphics corruption? I noticed I can get rid of this with value 0 to register 36. But since interlace is essentially just two fields, why should each rasterline need more time than non-interlace mode? Yes, I agree. Only PAL would really benefit from 2 frames merged.
Regarding interlaced text mode, it is essential 2 fields being weaved into one frame. However there are less free cycles to buffer both character and attribute data. From my observations using my vdc raster split test program, I've concluded so far for every line where character data is displayed:- - Fetch bitmap information for each column (register 1 value + 1). I've only tested this with a horizontal display of 80 so far.
- Refresh DRAM (register 36)
For a standard line this means at least 86 cycles are required for each scan line in the screen display area. The remaining cycles are used for buffering character and attribute data for the next character row. For PAL using a horizontal total value of 127 this means there are 128-86 = 42 free cycles. 42 x 8 = 336. The buffering for 80 characters with attribute data is 81(extra character fetched for smooth scroll I'm guessing) + 4 additional cycles. Multiply that by 2 for the character and attribute byte and total cycles required is 170. 170 is less than 336 so there will be no issues with displaying non interlaced multicolor text mode.
However for interlaced text mode you only have 4 scan lines for each field to buffer character and attribute data which means you have 42 x 4 = 168. That is not enough to fetch all attribute data. The glitch can be seen using the X128 VDC TESTER available from the VICE test repository when switching 80 column text mode with attributes on to interlaced mode (see attached Single Pixel Intelaced image). It's even more noticeable in double pixel mode (see attached Double Pixel Intelaced image) where I'm assuming there are even less free cycles to fetch all the character and attribute data. Interlaced text modes without attributes off show fine because those modes only need to buffer character data.
Note multicolor bitmaps only need to buffer attribute data so have more free cycles. Your 8 x 1 mode requires to fetch 60 bitmap + buffer 60 attribute bytes per line and a few additional cycles per line where graphics is drawn so the horizontal resolution cannot be easily increased in standard PAL or NTSC modes.
The numbers I have used are not exact but a pretty close to what I've observed so far with the VDC split test program and I've only included them as an example of concept. My preliminary implementation of this behaviour into Z64K produces similar results to real hardware. I haven't released any of this yet because it is something I'm still testing as part of fine tuning the VDC busy status flag behavior.
Single Pixel
Single Pixel Interlaced
Double Pixel
Double Pixel Intelaced
|
|
|
Post by tokra on Oct 17, 2018 16:31:28 GMT
Thanks, that sheds some light on this issue. I think I get it now. The double-pixel-mode requires setting register 0 to 63 (usually) and this will mean a lot less time to do the buffering. Let me try the calculation based on your (rough) formula: 41 cycles per line for bitmap-information and 5 for DRAM refresh = 46 cycles Using the horizontal value of 63 this means there are 64-46 = 18 free cycles. 18 x 8 = 144. Buffering is (41 + 4) = 45 cycles. Multplied by 2 for character and attribute byte = 90 total cycles. 90 < 144 so double-pixel-mode works Interlace-double-pixel-mode would mean: 18 free cycles x 4 = 72 free cycles. 90 > 72 so this won't work. Standard-size-interlace-mode works if you set register 36 to 0 (you can try by exiting X128 VDC TESTER) and setting the register manually. This works because withouth the DRAM-refreshes you gain some free cycles which means you will go over the 170 cycles required. This formula however doesn't explain why 8x1-interlace-mode won't work. Neither why multicolor bitmaps cannot be larger than 82 chars (same corruption as text-modes larger than 82 chars). Still some mysteries to solve
|
|
|
Post by tokra on Oct 17, 2018 18:29:57 GMT
Testing my new won knowledge, I tried to get double-pixel interlaced text-mode to work. I nearly did Start X128 VDC TESTER and press D and I (to enter double pixel interlaced-mode). Then press ESC to exit that mode and type the following blindly: w=dec("cdcc"):sysw,0,36:sysw,39,1:sysw,41,27:rem I still need to do sysw,225,5 sometimes to get the interlaced lines match up correctly on my TV. This gives you a 39 character-wide double-pixel interlaced mode - just 1 character shy of 40 sadly. It should fit by your formula above, so there's still some extra cycles somewhere...
|
|
|
Post by willymanilly on Oct 17, 2018 23:43:30 GMT
This formula however doesn't explain why 8x1-interlace-mode won't work. Neither why multicolor bitmaps cannot be larger than 82 chars (same corruption as text-modes larger than 82 chars). Still some mysteries to solve Yes, there are still some mysteries to the VDC but we are getting much closer to solving them.
Regarding the 82 char limit, the theory that there is are 2 x 82 byte buffers (1 for character and the other for attribute data) explains why multicolor bitmaps larger than 82 chars doesn't work. All bitmap modes don't require to buffer character data but multicolor bitmap still needs to buffer the attribute/color data. This is why monochrome bitmaps are not restricted by the 82 char limit but also explains why multicolor bitmaps does have that restriction.
I'm guessing the engineers for the VDC created it to primarily support 40 and 80 column modes. For 40 column mode it would require a buffer size of 41, the extra value being to accomodate smooth scrolling. Multiply this by 2 for 80 column mode and you get 82. As shown in the VDC horizontal display greater than 82 thread, the buffer overflows when horizontal display exceeds 82 and overwrites starting in position 1 of the second buffer (screen position 42).
In theory 8 x 1 interlace mode should work in theory assuming the image data is in the correct locations for each field. Are you able to provide any examples of where you tried to get this working?
|
|
|
Post by tokra on Oct 19, 2018 11:50:22 GMT
I tried 8x1-interlace-mode (see attached), but the results are strange to say the least. First, it only "works" with a char-width not higher than 50. And then you still get blank lines in between the lines that have the color of the text-screen before you start the program (even though VDC-RAM is deleted completely within the program). Try playing with the value of variable P in the program where the video- and attribute-RAM is set. Attachments:vdc81inter5.prg (476 B)
|
|
|
Post by willymanilly on Oct 20, 2018 7:16:22 GMT
I tried 8x1-interlace-mode (see attached), but the results are strange to say the least. First, it only "works" with a char-width not higher than 50. And then you still get blank lines in between the lines that have the color of the text-screen before you start the program (even though VDC-RAM is deleted completely within the program). Try playing with the value of variable P in the program where the video- and attribute-RAM is set. Cool. I'll check it out when I get a spare moment and let you know if I have any luck.
|
|
|
Post by willymanilly on Oct 21, 2018 23:41:23 GMT
I haven't had much time to play around with this but I've suspection the VDC is skipping every second line of color information for interlaced images which fits the model I use in Z64K. This means interlaced VDC images would need twice the memory for the color data. A work around I guess to avoid wasted memory usage would be to use the interlaced sync mode and change the attribute and display memory starting addresses before each field. There are other oddities I discovered when running on real hardware I need to do some research on as well. Even though the VDC memory is cleared I don't think the character and attribute buffers are. I haven't tested any of this so these are only theories at this stage...
|
|
|
Post by willymanilly on Nov 3, 2018 22:38:16 GMT
I've done quite a few updates to Z64K that fixes a lot of the quirks when register 9 (character total vertical height) is set to 0.
Some things I've noticed are: - The value in register 6 (Vertical displayed) is totally ignored when register 9 is set to 0. VBLANK is instead set at the screen row 1 less than the value in register 4
- If register 9 is switched from 0 to a value greater that 0, if the screen row count is less than register 6, VBLANK is trigger at the correct register 6 value as normal. Otherwise it is triggered at the value in register 4. VDC version of Risen from Oblivion uses the CIA timer to change register 9 back to 1 before the value in register 6. note: RFO method shifts the attribute latch by a value of 3. I'm not totally sure why yet.
- To avoid the character line counter overflow, delay setting register 9 to 0 by X number of scan lines where X is the existing register 9 value. RFO uses this as method as well.
- The new value in register 9 is only applied when the screen row count is less than the value in register 6.
I've got an extensive number of test programs that proves all this. Rather than flooding this thread with a whole heap of screenshots, programs and source code, I will work on collating the tests in a single standalone program. Happy to also zip up what I have in the mean time if anybody wants to have a look now at the programs I used.
|
|
|
Post by willymanilly on Nov 4, 2018 10:31:03 GMT
It might be a while before I get the chance to revisit this so I've attached are all the relevant test programs I've used to come to the above conclusions. I will still be online but won't have access to my real C128D to test with for a couple of weeks while I'm on a road trip to Queensland.
I have not cleaned up the source code or put many comments into yet but feel free to ask any questions on how the programs work in the mean time.
In a nutshell the programs do the following.
- VDC81 - Change register 9 to 0 immediately after VBLANK is cleared and set it back to a number greater than 0 when VBLANK is set.
- VDC81delay - Wait variable number of scanlines (see source) after VBLANK is cleared before changing register 9 to a value of 0. Register 9 is changed back to a value great than zero as soon as VBLANK is set.
- VDC81d2 - Sames as VDCdelay except more focus on changing register 6. Register 6 has no effect on results.
Attachments:vdc81.zip (511 KB)
|
|
|
Post by jmpff3d on Nov 4, 2018 15:55:55 GMT
EDIT :: Looks like the Commodore screen ROM routines already provide the functions below at WRITEREG ($CDCC) and READREG ($CDDA) ! ... Whoops ! Thanks to Strobey for the reminder ! ****
While you superhumans explore VDC at higher levels, rest of us may have to get up to speed in painful ways.
Fortunately, Compute! magazine provided a good starting point for experimenting from BASIC, as seen below:
** Easier experimenting with VDC from BASIC v7 **
0 rem machine code below, in handy data statements, this code must be installed before the other sample programs can run 10 fori=3072to3114:readb$:pokei,dec(b$):nexti 20 data a0,00,8c,00,ff,8d,00,d6,2c,00,d6,10,fb,8e,01,d6,60,a9,00,8d,00 30 data ff,20,0c,af,a5,16,8d,00,d6,2c,00,d6,10,fb,ac,01,d6,a9,00,4c,03,af
; this here is originally from Compute's 128 Programmer's Guide, bytes should be a one to one match with data statements above a f0c00 a0 00 ldy #$00 ; register write routine starts here a f0c02 8c 00 ff sty $ff00 ; select bank 15 a f0c05 8d 00 d6 sta $d600 ; store register number in $d600 a f0c08 2c 00 d6 bit $d600 ; wait for high bit to be set a f0c0b 10 fb bpl $0c08 ; keep looping back until bit is set a f0c0d 8e 01 d6 stx $d601 ; store data in $d601 once wait is over a f0c10 60 rts ; return from subroutine a f0c11 a9 00 lda #$00 ; register read routine starts here a f0c13 8d 00 ff sta $ff00 ; select bank 15 a f0c16 20 0c af jsr $af0c ; convert FAC1 to $16 and $17 a f0c19 a5 16 lda $16 ; get register number a f0c1b 8d 00 d6 sta $d600 ; store register number in $d600 a f0c1e 2c 00 d6 bit $d600 ; wait for high bit to be set a f0c21 10 fb bpl $0c1e ; keep looping back until bit is set a f0c23 ac 01 d6 ldy $d601 ; read data from $d601 into y register a f0c26 a9 00 lda #$00 ; zero out a register a f0c28 4c 03 af jmp $af03 ; convert y and a to FAC1 and exit
Once the preceding ML program is in memory, you can write to any 8563 control with a SYS command in this form:
SYS 3072, register number, data
The register number should be a number from 0 to 36, corresponding to the register you want to affect, and data should be the number you want to put in that location. For example, this next command puts a one in register 11 (cursor end scan line control) to change the cursor from a box to an overscore:
SYS 3072, 11, 1
To read an 8563 register with this ML routine, use the command A=USR (register number) Before issuing a USR command, however, you must change the vector at locations 4633-4634 ($1219-$121A) to point to the right part of the ML routine, as shown in line 10 of the next program. The rest of the program reads and displays all the 8563 registers.
10 poke4633,17:poke4634,12 20 fora=0to36:print usr(a):next:rem reads up to 8563 VDC limit, 8568 VDC has at least one more register --
Test programs to be run with machine code from the top of this text. **
10 rem moving the 80-column screen - w a s d keys 20 x=102:y=29:ad=3072 30 getkeya$:ifa$="s"theny=y+1:goto70 40 ifa$="w"theny=y-1:goto70 50 ifa$="d"thenx=x+1:goto70 60 ifa$="a"thenx=x-1:goto70 70 sysad,2,x:sysad,7,y:goto30
10 rem moving the underline 20 ad=3072:scnclr:for a=1to10:printchr$(18);"this is strange...":next 30 fora=7to0 step -1 40 sysad,29,a:next:goto30
10 rem oversize characters 20 ad=3072:bank15:fast:scnclr 30 sysad,9,15:sysad,6,12:sysad,4,15:sysad,5,6:sysad,7,15:sysad,23,16:sysad,18,32:sysad,19,0 40 fora=53248to53759:bank14:ac=peek(a):bank15:sysad,ac,31:sysad,31,ac:next:sysad,11,14:scnclr:poke228,11
I hope I didn't generate any errors in typing this stuff up. My copy of the relevant book is a bit faded.
Cheers !
|
|