VDP Debug Register - $C0001C

For anything related to VDP (plane, color, sprite, tiles)

Moderators: BigEvilCorporation, Mask of Destiny

tristanseifert
Interested
Posts: 35
Joined: Tue Sep 06, 2011 2:16 am
Location: /dev/sa0
Contact:

VDP Debug Register - $C0001C

Post by tristanseifert » Fri Jul 27, 2012 7:06 am

Cross-posted from Sonic Retro


The Mega Drive has a 16-bit register at memory location $C0001C (Appears to be mirrored at $C0001E) which controls and disables various features of the VDP (Video Display Processor) and was probably used as a debugging aide during the design of the VDP. During a recent IRC conversation, this subject came up and I decided to research a little more into it. I wrote this programme that lets you set individual bits of the register and view what they do to the VDP. This is what that programme looks like with none of the bits activated (at which point it plays a square wave over the PSG channel 1 — this is so the effect of bit 9 can be heard. Note that the corruption on the first line of text is caused by the VDP after setting a specific bit):

Image

With this tool running on hardware (You can run it on an emulator, but none of the bits will have any effect) I was able to decode what the different bits meant and did on my Model 1 VA5 NTSC Mega Drive with a Sega CD attached (No difference was observed with it removed):

Bit 14 set = Sprites hidden (perhaps part of a 'debug mode' register)
Bit 13 set = Sprites hidden (perhaps part of a 'debug mode' register)
Bit 12 set = Sprites hidden (perhaps part of a 'debug mode' register)
Bit 9 set = PSG disabled
Bit 8 set = BG layer hidden, dots at top of screen, line at right and sprites hidden (besides artefact of one all the way to the right.)
Bit 7 set = FG starts using an odd tile for everything, BG uses odd palette - possibly reading corrupt data.
Bit 6 set = Display is disabled
Bit 5 set = Some sort of grid pattern, all planes seemingly hidden (Causes some brokenness in A plane at $C000)
Bits 7 and 8 set = Garbles FG and sprites.
Bits 15, 14 and 8 set = BG hidden as well as sprites disappear.


A video of the programme on my VA 5 MD1 can be watched here.

I'm interested in seeing if other models of the MD (and other VDP chips) deal with these modes differently — so if you've got a flashcart, please try setting the bits on your hardware and report back what happened, as well as your hardware version and VA revision. You can download the ROM here.

Lastly, I'd like to thank Jorge and Tiido for giving me the idea to toy around with this by suggesting I figure out if the VDP has more access cycles in one line if a specific plane was disabled. And I also apologise for the shitty quality of the video — my composite cable disappeared and my capture card likes being an asshat.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Fri Jul 27, 2012 8:02 pm

My CDX and Model 2 Genesis seem to do the same thing. One thing I noticed that you didn't mention is that setting either bit 10 or 11 makes a click to the audio when the bit toggles (0 to 1 or 1 to 0).

tristanseifert
Interested
Posts: 35
Joined: Tue Sep 06, 2011 2:16 am
Location: /dev/sa0
Contact:

Post by tristanseifert » Fri Jul 27, 2012 9:49 pm

Chilly Willy wrote:My CDX and Model 2 Genesis seem to do the same thing. One thing I noticed that you didn't mention is that setting either bit 10 or 11 makes a click to the audio when the bit toggles (0 to 1 or 1 to 0).
I never managed to hear that one - probably a side effect of me doing this late at night =P

I just tried it and you are right - there is a little click.

LocalH
Very interested
Posts: 152
Joined: Tue Dec 19, 2006 5:04 pm

Post by LocalH » Sat Jul 28, 2012 12:17 am

As I also wrote over at Retro, I wonder if the click could be abused (like on the Apple II) to generate basic tones or maybe even sample output, without touching the Z80 bus? Not sure how useful it'd be but it was sure useful on the 1MHz 6502, so maybe with a 7MHz 68000 (as well as DMA) it might be useful for something.

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sat Jul 28, 2012 12:50 am

LocalH wrote:As I also wrote over at Retro, I wonder if the click could be abused (like on the Apple II) to generate basic tones or maybe even sample output, without touching the Z80 bus? Not sure how useful it'd be but it was sure useful on the 1MHz 6502, so maybe with a 7MHz 68000 (as well as DMA) it might be useful for something.
Yeah, there's actually a mod player for the PC that uses the keyboard speaker in the PC for output... 1 bit is all you need if it's a high enough frequency. Simple PWM output. There were a few Atari 8-bit programs that used the keyboard speaker for output as well (mainly ports of Apple II games).

At the very least, two more square wave outputs would be handy for music.

LocalH
Very interested
Posts: 152
Joined: Tue Dec 19, 2006 5:04 pm

Post by LocalH » Sat Jul 28, 2012 1:07 am

<offtopic>
Yeah, I remember one of those players well, it was called Inertia Player. I remember taking MODs I had on my Amiga into school and playing them on school PCs and then telling everyone how much shit they sounded like on a PC lol

sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

Post by sega16 » Sat Jul 28, 2012 2:00 am

I remember sound driver for pc speaker I had an old windows 3.1.1 laptop and that was the only way (I don't remember if it had audio out this was long time ago) to get sound from the computer it also had a monchorme screen but I remember for a fact that it had a vga out. It is amazing how much technology has advanced.

tristanseifert
Interested
Posts: 35
Joined: Tue Sep 06, 2011 2:16 am
Location: /dev/sa0
Contact:

Post by tristanseifert » Sat Jul 28, 2012 2:55 am

LocalH wrote:As I also wrote over at Retro, I wonder if the click could be abused (like on the Apple II) to generate basic tones or maybe even sample output, without touching the Z80 bus? Not sure how useful it'd be but it was sure useful on the 1MHz 6502, so maybe with a 7MHz 68000 (as well as DMA) it might be useful for something.
I don't believe that you can DMA to that area in memory — only to VRAM, CRAM or VSRAM, but this can probably be abused and still leave some CPU time free, similar to how the 68k writing DAC samples to the YM2612 works.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Mon Jul 30, 2012 9:46 am

Hey, awesome test ROM! I've done some very primitive testing on the VDP test register as well. I don't have access to my test notes right now, but I know I've observed effects from a few of the bits you don't have listed. One of the lowest bits disables horizontal interrupts when set, and another bit seems to mess with DMA operation in some way. I'll post which bits when I can check my notes.

tristanseifert
Interested
Posts: 35
Joined: Tue Sep 06, 2011 2:16 am
Location: /dev/sa0
Contact:

Post by tristanseifert » Mon Jul 30, 2012 2:24 pm

Nemesis wrote:Hey, awesome test ROM! I've done some very primitive testing on the VDP test register as well. I don't have access to my test notes right now, but I know I've observed effects from a few of the bits you don't have listed. One of the lowest bits disables horizontal interrupts when set, and another bit seems to mess with DMA operation in some way. I'll post which bits when I can check my notes.
Thanks! I don't use DMA in that ROM itself, but I did try setting bits in a ROM with them and did observe that it appeared to only do DMA every two cycles. I haven't managed to get the HInts to die off from settings a bit — I use HInt to write CRAM dots for debugging purposes. The ROM has been updated to display those pink CRAM dots now.

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Mon Jul 30, 2012 7:58 pm

Nice test ROM.

For completeness, here are the notes I saved from Charles McDonald old website, which should more or less cover the same bits and might be interesting to compare with your findings.
After some testing, it turns out that the unused VDP address $C0001C
(mirrored at $C0001E) controls how the VDP generates the display.

Specifically, it allows layers to be turned on and off, it affects how
high priority sprites or tiles are interpreted, and it seems to change
how layers are combined together.

No games use this register to my knowledge, maybe it was left in for
testing or debugging purposes by the VDP manufacturer. This was all
checked on an original model Genesis, the register may not be present
or behave differently in later versions of the VDP hardware.

Here's the layout of $C0001C/$C0001E:

MSB LSB
-gfe ---d cba- ----

Notes:

Unmarked bits have no effect.
Anything pertaining to plane A also applies to the window layer.
Any description about color intensity changes is only valid when
the VDP is in shadow/hilight mode.

a = Display garbage (bad pattern data) on all background rows
and for the sprites.

b = Turn display off (background and sprites)
Display is filled with background color.
CRAM data is randomly corrupted as long as this bit is set.

c = Turn display off (background only)
In shadow/hilight mode, high priority tiles are also invisble
but are drawn in the regular normal intensity backdrop color,
while low priority tiles are drawn in the half intensity
backdrop color.
Transparent pixels in high priority sprites are also filled
with the normal intensity backdrop color, so sprites have
a tile shaped outline around them.
It seems like either underlying pixels from the background
are visible through shadow/hilight pixels in sprites, but
the colors are wrong. (as if they were logically OR'd with
the sprite pixels, as both layers can be seen)
CRAM data is randomly corrupted as long as this bit is set.

** When 'c' and 'b' are set, the background layers are invisible,
but sprites are not. All sprites, regardless of priority,
have a tile shaped outline around them that is drawn in some
color other than the backdrop color. (can't exactly tell)

d = When set, garbage is displayed in the top and bottom border areas.
Plane B is disabled, only plane A is visible.
All sprites are drawn in the regular intensity backdrop color.
High priority plane B tiles are drawn in the regular intensity
background color, low priority plane B tiles are drawn in the
half intensity backdrop color.

g,f,e = All bits turn off sprites when set.
If bit 'd' is set, bit 'e' changes the garbage data printed
in the border areas.

Bits b,c,d have effects when combined, as the following table
shows. Some of this information is a rehash of what was explained
above. Bits g,f,e will turn off sprites in all cases. (unless they
are already off to begin with)

Notes:
RI = regular intensity backdrop color
HI = half intensity backdrop color
A,B,S = Plane A, plane B, sprite layer

b c d Effect
----- ------
0 0 0 Display shown normally
0 0 1 B and S off, high priority pixels from B and S drawn in RI
0 1 0 A and B off, high priority pixels from A and S drawn in RI, sprites
have tile-shaped outline in RI.
0 1 1 Plane A pixels seem to be OR'd with plane B pixels, and the
output is OR'd with the sprite pixels.
1 0 0 A, B, and S off
1 0 1 B and S off, shadow/hilight mode off
1 1 0 A and B off, sprites have tile shaped outline in unknown color.
1 1 1 A and S off, shadow/hilight mode off

In mode 4, the same results apply with the following exceptions:

- Shadow/hilight processing is always off

- Anything that enables plane B seems to turn on a second graphics
layer, which is identical to plane A with garbage data. (so the VDP
can't really create two playfields in mode 4, but it does seem
to try to re-use plane A with bad graphics)
The settings which seem to enable plane B are when
bits b,c,d are 1,1,1, and and 0,1,1.

- The leftmost 8 pixels show a lot of garbage data when some of the
bits are set. (seems unrelated to sprites or background)
Earlier it was discovered that the VDP doesn't draw the background
tile in the left 8 pixels when the lower 3 bits of the horizontal
scroll value are not equal to zero, it shows garbage data that seems
to be based on the sprite positions. Also, this can be seen in the
rightmost 8 columns if you enable 40-cell mode while in mode 4, so
the resulting display is 320x192.

I also have some kind of web page (newreg.htm) with in-game pictures of Ecco with the bit patterns forced to various values but I am not sure how it would be best to upload it. It's available in the techdoc package I'm hosting here:

http://genplus-gx.googlecode.com/files/gen_tech.zip

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Tue Jul 31, 2012 1:52 am

Here are my raw testing notes that I made a few months back. I've only experimented with the test register once so far, and I did it by using a Pro Action Replay 2 to patch the VINT routine for a game (Sonic 2 in this case), so I could flick the switch on the PAR and enable the test register change at any point during gameplay. I did this to try and observe effects of the test register during real-world usage of the VDP, to try and find effects from other bits of the test register not described in the document published by Charles MacDonald.

My testing was brief and limited, so I don't think I can add a lot, but here's what I've written down. Everything in this document could be incorrect in some way, it's based on my first impressions and guesses.
Sonic 2 (VInt patch):
00007A:0080
000080:33FC
000082:0100 (This is the data to write to test register)
000084:00C0
000086:001C
000088:4EF8
00008A:0408

MSB LSB
-gfe ---d cba- -!!-

No noticeable effect:
-[0001][0004][0010][0200][0400][0800][8000]

[0002](?):
-When we toggle this on, something very weird happens. The VDP locks up hard, the system can't be reset, and we see what appears to be the palette contents? or something at least, dumped out to the display. It kind of looks like the CRAM data is rotated through some sort of regular cycle, as if each address in CRAM is being shifted over every pixel. We see CRAM flicker bands on the screen along the access slot lines as if the CRAM is being constantly written to.
-Has also been seen to statically freeze the VDP, where the frame is steady and unchanging with a corrupted palette shown, but no variation between frames. This only seems to happen in 2 player sonic 2 mode. We have done some more investigation, and it appears that this setting under interlace mode 2 causes two different fields to be output, but these fields are both stable across each frame, so the frame itself appears static. Without interlacing enabled however, the fields change each frame. I suspect this is happening because whatever this option is doing is expecting one field to be a single line shorter than the other. This is why we see an apparent vertical scrolling effect on the junk in the border areas.
-It could be that setting this bit inadvertantly triggers some kind of DMA transfer to CRAM. Since CRAM was probably the last thing written to at the time, this is suspicious. We should do more testing on this behaviour. There may be something here we can use to probe DMA behaviour in otherwise impossible to test cases.
-Note that it is quite possible that this bit forces the M1 DMA enable bit in register 1 to be always set, which is causing a lock-up due to DMA unintentionally firing.

[0008](?):
-When this is enabled, it appears to interfere with horizontal interrupts. The 2-player splitscreen in sonic 2 has the top half of the screen broken, and the level runs at half the correct speed, as if it's missing a vertical interrupt. Aquatic ruin has the underwater palette active for the entire level with some flickering to the normal palette, again with it running slower than normal.
-Perhaps this disables horizontal interrupts? Or perhaps it causes them to fire on every line?

[0020](a):
-Very weird. It may be that this bit forces the VDP into mode 4 graphics mode? It looks a bit like mode 4 from memory.

[0040](b):
-The entire display appears to always be filled with the background colour
-From the notes Charles wrote about this bit, it sounds likely that this actually has the effect of forcing the "display enable" bit to false, meaning free access to VRAM should be allowed while this bit is set.

[0080](c):
-Sprite layer is active and functioning as normal. No other layers visible.
-Actually, more complicated. Most of the screen is black, but the background colour isn't black. Regions of the background can be seen somehow masked by layer A, but only in blocks where sprite pixels appear, but are transparent. Very odd.

[0100](d):
-Prevents the "Display Enable" register from forcing the backdrop to be output. Can be observed in sonic 2 2 player mode, where the display is disabled mid-frame. With this flag set, randomly changing junk is output in this region of the frame instead.
-The "garbage" in the horizontal overscan is actually sprite data!
-Enabling this setting disables the background masking in the border areas. The result of this is that whatever data is moving over the bus at the time is rendered to the screen.
-In the case of horizontal overscan during the active screen area, we first of all see the full pattern data for scrolled layer blocks, eg, in the case of H40 mode, 41 blocks are always visible, and those 41 blocks scroll across the physical play area.
-Outside the region where the scrolled playfield is being shown on the line, we see the actual sprite pixels being sent to the analog output circuit. Sprite pattern data starts in the column immediately following the end of the scrolled layer pattern data.
-Sprite pattern data is sent in order of sprite priority on the line, not the order it appears on the screen.
-No gaps appear between sprite pixel data in the sent stream. Sprite pattern data is sent back-to-back.
-Sprite pattern data is not sent mirrored, even if it is displayed mirrored. The pattern data is always sent the correct order.
-If no sprite pattern data exists on a line, that line moves the exact same sprite pattern data over the bus as the previous line. Note that this happens over just the line, so the last line is repeated down until the next line that has sprite data, appearing as one big line or smear vertically with the same pattern data.
-When the sprite pattern data is output in this manner, it affects the way sprites are displayed on the screen. The sprite priority, present status, and color palette selection still seem to apply, but the actual sprite pattern data isn't used. The effect this has is to make the outline of the sprite visible, while changing the active palette in the area where it should be for layer A.
-Layer B seems to be disabled
-The top and bottom border regions are displaying unidentified data, appears to be coming from layer a or b mapping data?

[1000](e):
-All sprites disabled. If [0100](d) is enabled too, no sprite data is shown in overscan either.
-Sprite data appears to be output in vertical overscan regions. Looks like it's sprite mapping data rather than pixel data that's being output?

[2000](f):
-All sprites disabled. If [0100](d) is enabled however, the sprite data is correctly shown in the overscan region as if this bit had not been set. If g or e is set though, the data no longer appears in overscan.

[4000](g):
-Appears to be the same in every way as [1000](e).

mikejmoffitt
Very interested
Posts: 86
Joined: Fri Sep 25, 2015 4:16 pm

Re: VDP Debug Register - $C0001C

Post by mikejmoffitt » Tue Oct 13, 2015 7:18 am

I played with bit 0x0100 tonight before I saw this thread, so here are my notes on it which mostly line up with yours. I have a little more insight (I think) on why sprites look the way they do:

Testing hardware is a VA3 USA Genesis, and a Sega CDX. Results are nearly identical.

Existing documentation is sparse. md.squee.co says "When set, the BG layer is hidden, dots appear at top of screen as well as a line line at the right right and sprites are hidden."

That's not quite true, from what I can tell. Notes:

-Tile priority, shadow/highlight features work normally
-Plane A works fine, with left column pre-pixel-0 blanking disabled
-Plane B seems to be almost entirely disabled, but sometimes shows up with a nearly all black palette. Scrolling and plane size seems normal.
-Sprites are not hidden, actually:
-On the right side of the screen are all the line's sprites, maybe in the correct color. If there is a line without a sprite, then the last sprite shown's last row is repeated. I thought this was data fetching for the next line, but it is being rendered at normal width here which would be impossible in that circumstance.
-Where the sprite should be on the screen, it is sort of rendered. However, rather than displaying the color indicated by the sprite's palette and tile data, the sprite's 4-bit palette lookup is ANDed with the one at that location in plane A. The sprite's palette number seems disregarded. I hope this ANDing is done via logic and isn't just a bus conflict, though since the VDP is an NMOS process chip this is not so bad as if data was getting stuck high.
-The above rule happens only when the sprite would normally be displayed. For example, a high priority plane A tile will not be affected by a low priority sprite.

The following notes are differences between the CDX (~MD2 era) and my VA3 Model 1:
-On the model 1, every 8 columns was somewhat flickery. Looks like an open bus or maybe a conflict. On the CDX sprite appearance was totally stable.
-On the model 1, sometimes a color in whatever palette some Plane A tiles are using will get corrupted (visible in my later Sonic 3D shot; one of the green colors is dark red). This happened to me during Toejam and Earl, and the color got set to the same dark red. May differ between one VDP and another.

Of course, I took pictures. I have a video as well, though I'm not sure how instructional it will be:

Sonic 1 Title Screen. 8 pixel column open bus interference is visible here. Sonic's more or less correct rendering is somewhat a coincidence with the palette of the stuff behind him. The ANDing effect is pretty visible here.
Image

Sonic 2. Similar deal.
Image

In-game shot of Sonic 2. Notice Plane B's water reflections showing up as black. Hey, it's not nothing - Plane B isn't truly disabled.
Image

Super Shinobi 2. Can't see Joe, because he's behind the Plane A stuff. Sprite data on the right. I still don't think this is the sprite fetch, because that should be happening much faster than this to be efficient (simply not enough hblank time to grab 320px worth of sprite data)
Image

Sonic 3D menu. Notice how the areas with the sprites has made the background a little "brighter" - actually just changing the palette index.
Image

Sonic 3D in-game. You can see Sonic's sprite on the right side. The "no sprites; repeat last sprite's last line" can be seen with the HUD sprites too.
Image

The palette of the sprite on the right here isn't always the same.
Image

Ristar looks like a wreck.
Image

Aladdin is not as bad as Ristar. Nice big flat areas to see the backdrop through.
Image

Eke
Very interested
Posts: 884
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Re: VDP Debug Register - $C0001C

Post by Eke » Tue Oct 13, 2015 10:51 am

mikejmoffitt wrote:Sprite data on the right. I still don't think this is the sprite fetch, because that should be happening much faster than this to be efficient (simply not enough hblank time to grab 320px worth of sprite data)
It was actually confirmed that all the sprite pattern fetching is done during HBLANK (which starts approx. two columns i.e 16 pixels before the end of active line display) and ends before the next line starts to be displayed. HBLANK is 860 MCLK which gives 50 VRAM access slots in H40 mode and is enough to grab all 320 pixels of sprite data (4 bytes / per access slots = 8 pixels).

See these threads for more infos on timings:

viewtopic.php?f=22&t=851
viewtopic.php?f=22&t=1291

mikejmoffitt
Very interested
Posts: 86
Joined: Fri Sep 25, 2015 4:16 pm

Re: VDP Debug Register - $C0001C

Post by mikejmoffitt » Tue Oct 13, 2015 4:30 pm

I know the fetch is done during HBlank, but I'm saying the sprites on the right side of the screen are not direct artifacts of the fetch because they are being rendered at mclock/4 (in H40). I remember seeing Tiido had visualized the fetches using a probe on VRAM data pins, and they were narrow (as a result of the faster clock).

The more significant thing about what I found is that the sprites are ANDing their pixel index with Plane A, and possibly plane B.

Post Reply