The VDP Questions Topic

Discussion in 'Discussion & Q&A' started by MarkeyJester, Jul 20, 2010.

Thread Status:
Not open for further replies.
  1. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    A starting topic is at hand:


    Setting the VDP on a Megadrive/Genesis.


    The Megadrive/Genesis has a 16-bit processor that can perform 32-bit operations, this allows us to move a long-word of data to the VDP ports, the VDP ports are mapped to the MC68 memory map location from 00C00000 to 00C00007, 00C00000 to 00C00003 is the "VDP Data Port" (Long-word) and 00C00004 to 00C00007 is the "VDP Address Port" (Long-word).


    The VDP has it's own memory map space for V-Ram, this opens up a lot of memory map space for the MC68000 for other operations (Mainly for devices that may be used for the Megadrive/Genesis). What this means is that if we want to move data to the VDP's ram space, we need to tell the VDP, where we're moving the data to, and what that data is.

    We start with a long-word of data, this will be moved to the "VDP Address Port" (00C00004):


    40000000 as an example.


    Now to understand exactly how this works, we need to break the long-word up into bits:



    RRAA AAAA AAAA AAAA ---- ---- RRRR --AA



    The - are to remain blank (0), first let's look at the A's:



    --DC BA98 7654 3210 ---- ---- ---- --FE



    The A's are the "Address" or the location where we're dumping or reading the data in V-Ram, arrange them:



    FEDC BA98 7654 3210



    Then read in hex insted of bits and you have the V-Ram location you want to write to or read from, let's now look at the R's:



    10-- ---- ---- ---- ---- ---- 5432 ----



    Each R number represents the code/settings for the VDP, it tells the VDP what it's doing with the location:


    If all R's are 0, then V-Ram read mode is set.


    If R's 1 to 5 are 0, but R 0 is 1, then V-Ram write mode is set.


    If R's 0, 1, 2, 4 and 5 are 0, but R 3 is 1, then C-Ram read mode is set.


    If R's 2 to 5 are 0, but R's 0 and 1 are 1, then C-Ram write mode is set.


    If R's 0, 1, 3, 4 and 5 are 0, but R 2 is 1, then VS-Ram read mode is set.


    If R's 1, 3, 4 and 5 are 0, but R's 0 and 2 are 1, then VS-Ram write mode is set.


    V-Ram (Video) read mode, the data in V-Ram at location "AAAA AAAA AAAA AAAA" will be present in "00C00000".


    V-Ram (Video) write mode, the data you move to "00C00000" will be moved to location "AAAA AAAA AAAA AAAA" in V-Ram.


    C-Ram (Colour) read mode, the data in C-Ram at location "AAAA AAAA AAAA AAAA" will be present in "00C00000".


    C-Ram (Colour) write mode, the data you move to "00C00000" will be moved to location "AAAA AAAA AAAA AAAA" in C-Ram.


    VS-Ram (Vertical Scroll) read mode, the data in VS-Ram at location "AAAA AAAA AAAA AAAA" will be present in "00C00000".


    VS-Ram (Vertical Scroll) write mode, the data you move to "00C00000" will be moved to location "AAAA AAAA AAAA AAAA" in VS-Ram.


    And that is the basic principle, so let's say I want to mode art to V-Ram location F000:



    F000 = 1111 0000 0000 0000 (a.k.a. "AAAA AAAA AAAA AAAA").



    Arrange it correctly:



    --11 0000 0000 0000 ---- ---- ---- --11



    Now we need to set V-Ram write mode, so R's 1 to 5 will be set 0 and R 0 will be set 1:



    01-- ---- ---- ---- ---- ---- 0000 ----



    Put the location and settings together:



    0111 0000 0000 0000 ---- ---- 0000 --11



    Convert to hexadecimal:



    70000003



    And there's the value to move to the "VDP Address Port" (00C00004):



    move.l #$70000003,($C00004).l



    Next, move your data (word or long-word at a time) to "00C00000", though make sure register 8F of the VDP is set auto increment (Which in Sonic games it usually already is set so no need to worry).
     
    Last edited by a moderator: Nov 20, 2010
  2. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    Ah, thanks for the tutorial Markey. So let me ask something - when you do this:



    move.l #$70000003,($C00004).l



    Could I just load a uncompressed art into a0 for example, and then do a move from a0 to $C00004? I guess some example code would be fine now (this has nemesis compressed data, but isn't the same?):




    move.l #$42000000,($C00004).l ; Set Write Pointer to VRAM Adress $420 * $20


    lea (Menu_Font).l,a0 ; Load Menu Font into a0


    bsr.w NemDec ; Decompress Nemesis Data in a0 and then write to VDP



    I know this works, but I commented it a bit to help people trying to write data artwork to the VDP. Hope this helps someone here.
     
    Last edited by a moderator: Jul 20, 2010
  3. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    No, to load "uncompressed data" without the need to decompress, set the VDP location and mode in ($C00004) then move the data a long-word or word at a time directly to ($C00000):



    move.l #$40000000,($C00004).l ; Set VDP to V-Ram write mode at location 0000
    lea (Uncompressed).l,a0 ; load uncompressed art location to a0


    move.l (a0)+,($C00000).l ; dump the first 8 pixels to V-Ram


    move.l (a0)+,($C00000).l ; dump the second 8 pixels to V-Ram


    move.l (a0)+,($C00000).l ; dump the third 8 pixels to V-Ram


    etc...



    The nemesis decompression algorithm is designed to decompressed the data in sections then dump the uncompressed data to V-Ram automatically (in other words, it does it for you).
     
  4. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    Ah, thanks for clearing that up for me.
     
  5. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    OK, I have a new question. All objects that show graphics on the screen/level have a bit of code code like


    Code:
    move.w  #$????,$02(a0)
    
    where ???? is some kind of offset the object loads its artwork from. How do I figure out/calculate this offset? I ask because I wrote an object that doesn't really work.
     
  6. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,429
    Location:
    Northern Germany
    The VRAM address (for example $A820 for shields) devided by $20 (or 32 in decimal). Our the example would give $541.
     
  7. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    It's not actually a division of 20 per se, it's more of the tile ID number in V-Ram of which happens to obviously be a division of 20 (size of a single tile), this is a "Map ID" and is used for sprites and map planes:


    XYZZ


    YZZ is broken into bits: ABBB BBBB BBBB


    B = the tile ID (or V-Ram location divided by 20 if you'd prefer)


    A = the mirror flag, if clear (bit 0), the "map tile"/"sprite" is normal, if set (bit 1), the "map tile"/"sprite" is mirrored.


    X is broken into bits: PCCF


    P = the plane flag, if clear (bit 0), the "map tile"/"sprite" is low plane, if set (bit 1), the "map tile"/"sprite" is high plane.


    CC = the palette line flag:


    00 = line 0


    01 = line 1


    10 = line 2


    11 = line 3


    F = the flip flag, if clear (bit 0), the "map tile"/"sprite" is normal, if set (bit 1), the "map tile"/"sprite" is flipped.


    Also, pinning this topic, as it's a useful record of information in which we can link to for future reference.
     
    Last edited by a moderator: Jul 30, 2010
  8. OrdosAlpha

    OrdosAlpha RIGHT! Naebody move! Root Admin

    Joined:
    Aug 5, 2007
    Messages:
    1,793
    Location:
    Glasgow, Scotland
    What's a VDP?


    *runs*


    Seriously, this is quite interesting. I may even learn more than basic M68k ASM now.
     
  9. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    I'm pretty sure most of us know what the VDP is and what it does, but allow me to explain. The VDP stands for Video Display Processor, and it produces the images that appear on your TV's screen. It has 64 KB of dedicated RAM that only it can access - all writes and reads have to go through the VDP as the VRAM is not part of the M68K's adress space. The VDP has another area of RAM called CRAM. This area is able to hold 4, 16 color pallets, where each pallet has a transparent color, and 15 colors. Each color can be chosen from a range of 512 colors. The VDP is only able to display 64 on-screen colors at a time, but it is possible to display more by using programming tricks. The selection of colors can be extended to 1,536 by using the Shadow/Highlight mode. The VDP also handles sprites, which can use one of the 4 pallet lines. The VDP also has a third dedicated RAM space for the Vertical Scroll Table, and this area of RAM is commonly called VSRAM. These sprites can be placed anywhere on the screen, and can be animated by the software. The only limit is that you can not have more than 80 sprites on-screen, or other sprites with a less priority will get dropped to save, as drawing and producing the video signal has to happen during a very small window of time. The VDP also supports Mappings, also known as Map Planes, which tell it where to place tiles that have been loaded into VRAM.
     
    Last edited by a moderator: Jul 30, 2010
  10. OrdosAlpha

    OrdosAlpha RIGHT! Naebody move! Root Admin

    Joined:
    Aug 5, 2007
    Messages:
    1,793
    Location:
    Glasgow, Scotland
    Morons. I know what the VDP is and what it does. And have done for quite a few years.
     
  11. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    He was being sarcastic.

    As written in the topic title and the first post.

    Correct, it also has another dedicated ram space for the Vertical Scroll table, VS-Ram.

    They cannot animate and is not a feature of the VDP, that's done via software.

    Known as map planes. Thanks for helping detail information about the megadrive's VDP, but please get the one or two facts right before presenting it publically.
     
    Last edited by a moderator: Jul 30, 2010
  12. MrSpade

    MrSpade It's meant to be Mr_Spad3 but y'know... Member

    Joined:
    Dec 5, 2009
    Messages:
    172
    Location:
    The UK
    When I get off my lazy ass, and start to work on my hack again, (Which will happen, just not sure when. =P) I definitely will find this topic useful.


    *Bookmarks Page*
     
  13. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    Thanks for the nice reply. [/sarcasm] I explained it in detail for some other people, and I thought it was a serious question.
     
    Last edited by a moderator: Jul 30, 2010
  14. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,429
    Location:
    Northern Germany
    It's because Ordos made an obvious joke and you thought it was a serious question.
     
  15. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Today I'm taking the time to explain how to manipulate the VDP registers, and will explain what operation each register will perform, this can be useful information if you want to really go above and beyond, and attempt to do things that may seem difficult from a premade engine (such as sonic disassemblies).


    Manipulating VDP Registers:


    Accessing the registers can be done by a word or long-word value being move directly to the VDP address port:



    move.w #$XXYY,($C00004).l
    move.l #$XXYYXXYY,($C00004).l



    The command moving a word of data can set one register, while moving a long-word can set two. The format is as followed:


    XX = Register to send data to (Plus 80)


    YY = The data to send to that register


    There are 17 (Hex) registers you can access from 00 to 17, each one is responsible for a certain useful task, let's say we want to write FF to register 03, we add 80 to 03 (this becomes 83), followed by the value being moved to that register (FF):



    move.w #$83FF,($C00004).l



    It's a very simple process to write to the registers and in the end is just common sense, but what do each of the registers do? what are their purposes? well, allow me to provide an explained list.


    Understanding VDP Registers:


    When explaining bits:


    0 = Bit should remain 0


    1 = Bit should remain 1


    Other symbols = Will be explained


    I'll put these in quotes so it's easier to see, also note, some of this information MAY be inaccurate...

    The next set of registers are to set V-Ram locations of things like the sprite table, map planes, etc. Firstly a little explaination, the VDP as explained before has a dedicated memory space for V-Ram (Video "art tiles"), VS-Ram (Vertical Scroll) and C-Ram (Colour), but not for HS (Horizontal Scroll), Sprite Table, Scroll Table, Map Plane A, Map Plane B and the Window Plane. The downside is, these have to use a space in V-Ram so that means less space for art tiles, but the up-side is, you get to specify where in V-Ram the VDP has to read them.


    For example, I could decide to have the VDP read Map Plane A data from V-Ram location E000 or the Sprite Table data from V-Ram location F800, etc. This allows for a more flexible setout and allows you to decide which one would suit your needs better.

    Now I'm gonna stop right there for the mean time with just those first 6 registers, tomorrow I'll explain more registers and we'll progress slowly, this'll give some of you time to absorb this information without your head exploding.
     
  16. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Sorry I'm a few hours late, here we go!



    Stopping again for the night, will continue sometime later on this evening.
     
  17. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    And.. continuing...

    DMA - Direct Memory Access


    This is a very useful function that allows for fast and effective memory transfers to the VDP's ram spaces, let me see how I can explain this, as seen before in this thread, we've moved data to V-Ram manually, telling the MC68 to move word by word or long-word by long-word of data to the VDP ports, this can take time, what DMA attempts to do, is tell the VDP where the data is, how big it is, and where to move it to, once you've given this information, the VDP will move the data from the source to it's destination insted of the MC68.


    The MC68 stops (hulted) while the VDP transfers the data from the MC68 memory space, and when finished, starts the MC68 again, however, this method is approximately two times faster than the MC68 manually transfering it (DURING THE VERTICAL INTERRUPT ONLY, during normal display the transfer speed is the same as MC68 manual transfer).


    These next set of registers will deal with DMA settings, first, the size registers...

    Next the source registers...

    Now, once you've specified the data above, to the 5 registers, it won't begin until the final piece of data is given, the destination. To set the destination requires only a V-ram, C-Ram or VS-Ram location moved to the VDP address port, but arranged as explained before.


    So let's say we're writing it to the beginning of V-Ram: 40000000, we'll need to set the 5th R bit (Check the first post for more information), this will set the value as: 40000080, that bit will tell the VDP that this info being moved to the VDP address port is for the DMA. Once this last bit of information is moved to the address port, DMA transfer will begin.


    Let's set it up:



    move.w #$9340,($C00004).l ; Lower byte size
    move.w #$9401,($C00004).l ; Upper byte size


    move.w #$9500,($C00004).l ; Lower byte source


    move.w #$96E8,($C00004).l ; Mid byte source


    move.w #$977F,($C00004).l ; Upper byte source


    move.w #$4000,($C00004).l ; Destination


    move.w #$0080,($C00004).l ; ''



    And there we are, of course, we could optmise it a bit:



    lea ($C00004).l,a0 ; load VDP address port location to a0
    move.l #$93409401,(a0) ; Lower byte size & Upper byte size


    move.l #$950096E8,(a0) ; Lower byte source & Mid byte source


    move.w #$977F,(a0) ; Upper byte source


    move.l #$40000080,(a0) ; Destination



    And that's it about registers for now, I've explained it the best I can to my own knowledge, as said before, some of this information MAY be inaccurate, but I don't think I've come accross any problems myself.
     
    Last edited by a moderator: Mar 6, 2011
  18. Hanoch

    Hanoch Well-Known Member Member

    Joined:
    Aug 3, 2008
    Messages:
    312
    Location:
    Israel
    Oh I think get what the window plane is....


    [​IMG]


    The lava is on the high plane, the platform is a sprite, but its overlapping the lava thats in high plane, therefore its in the foreground (like the metalstuff in slz).


    But the window plane is the items displayed while in debug mode, like the ring. The window plane acttually takes whatever is on the high plane, and puts it on the stuff that are on the foreground. Is it right?
     
    Last edited by a moderator: Aug 15, 2010
  19. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Wrong, that is not the Window plane, that's an FG plane tile set high plane via the most significant bit.


    PCCF MLLL LLLL LLLL


    L = Tile ID


    M = Mirror flag


    F = Flip flag


    CC = Palette line


    P = plane


    And the debug items are sprites.


    The Window plane is different, it masks the low AND high plane tiles in the FG, and is not used in Sonic 1. A good example of it used would be Sonic Crackers, when the game is paused, that Yellow bar appears, THAT is the window plane, it remains in place, while the FG is free to move, but it masks the FG where ever a tile in the Window plane is set.
     
    Last edited by a moderator: Aug 15, 2010
  20. Hanoch

    Hanoch Well-Known Member Member

    Joined:
    Aug 3, 2008
    Messages:
    312
    Location:
    Israel
    Wait a minute, there are sprites, and they have high priority and low priority. The FG graphics are in plane A (above the background) and has low plane or high plane graphics (High plane always overlaps the sprites). All objects are in the foreground, but some objects can overlap the FG tiles too (like in sonic 2 where sonic passes a path swapper he can switch between high and low planes) So the platform is using this to be above the lava, right?


    And the ring from debug mode also sets itself to high plane, but since its a sprite it only overlaps other sprites, like the platform. But there is a lava behind that platform, so the ring is behind the lava, and above the platform, thats why it uses the lava graphics.


    How does it overlap the platform, but it doesn't overlap the lava or the high plane tiles? That is confusing.


    Could you also explain how ShowVDPGraphics work? And there are a few stuff I dont understand, like the variable that has $8ADF and then gets moved to a6 ($F624) why is that?
     
    Last edited by a moderator: Aug 18, 2010
Thread Status:
Not open for further replies.