Jump to content

  •  

  • Photo

    The VDP Questions Topic


    • This topic is locked This topic is locked
    37 replies to this topic

    #1 MarkeyJester

    MarkeyJester

      4 Super Emeralds

    • Pro User
    • 1830 posts
    • Gender:Male

    Posted 20 July 2010 - 06:13 PM

    The VDP (Video Display Processor) Questions Topic

    Welcome to the thread for VDP related questions, if you have a question referring to VDP specifically, then check this thread first to see if your question has already been asked before, if not, then ask away, and we will try our best to explain how and why it works and hopefully answer your question.

    The main function of this thread is to provide a record of information regarding the Megadrive/Genesis's VDP, that way should a question arise about the VDP, we'll have the answer already jotted down in a hard format that's easy enough to read.

    Do not ask questions that are related to hacking in general, we're trying to keep this directed at VDP only.

    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.

    The hyphen character (a.k.a. " - ") will be used to represent null bits (In other words, if you see the " - " character, it means " 0 ")

    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).
    • 0

    #2 tristanseifert

    tristanseifert

      I make... THINGS!

    • Member
    • 372 posts
    • Gender:Male
    • Location:Austin, TX

    Posted 20 July 2010 - 06:58 PM

    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.

    Edited by theocas, 20 July 2010 - 07:01 PM.

    • 0

    #3 MarkeyJester

    MarkeyJester

      4 Super Emeralds

    • Pro User
    • 1830 posts
    • Gender:Male

    Posted 20 July 2010 - 07:13 PM

    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).
    • 0

    #4 tristanseifert

    tristanseifert

      I make... THINGS!

    • Member
    • 372 posts
    • Gender:Male
    • Location:Austin, TX

    Posted 20 July 2010 - 07:16 PM

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

    Ah, thanks for clearing that up for me.
    • 0

    #5 tristanseifert

    tristanseifert

      I make... THINGS!

    • Member
    • 372 posts
    • Gender:Male
    • Location:Austin, TX

    Posted 29 July 2010 - 09:49 PM

    OK, I have a new question. All objects that show graphics on the screen/level have a bit of code code like
    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.
    • 0

    #6 Selbi

    Selbi

      Tief.Tiefer

    • Pro User
    • 1847 posts
    • Gender:Male
    • Location:L√ľneburg, Germany

    Posted 29 July 2010 - 10:00 PM

    The VRAM address (for example $A820 for shields) devided by $20 (or 32 in decimal). Our the example would give $541.
    • 0

    #7 MarkeyJester

    MarkeyJester

      4 Super Emeralds

    • Pro User
    • 1830 posts
    • Gender:Male

    Posted 29 July 2010 - 11:27 PM

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

    #8 OrdosAlpha

    OrdosAlpha

      Battle to the death on the big bridge, bitch?

    • Administrator
    • 1515 posts
    • Gender:Male
    • Location:Glasgow, Scotland

    Posted 29 July 2010 - 11:38 PM

    What's a VDP?

    *runs*

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

    #9 tristanseifert

    tristanseifert

      I make... THINGS!

    • Member
    • 372 posts
    • Gender:Male
    • Location:Austin, TX

    Posted 30 July 2010 - 12:55 PM

    What's a VDP?

    *runs*

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

    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.

    Edited by theocas, 30 July 2010 - 03:21 PM.

    • 0

    #10 OrdosAlpha

    OrdosAlpha

      Battle to the death on the big bridge, bitch?

    • Administrator
    • 1515 posts
    • Gender:Male
    • Location:Glasgow, Scotland

    Posted 30 July 2010 - 01:45 PM

    Morons. I know what the VDP is and what it does. And have done for quite a few years.
    • 0

    #11 MarkeyJester

    MarkeyJester

      4 Super Emeralds

    • Pro User
    • 1830 posts
    • Gender:Male

    Posted 30 July 2010 - 01:47 PM

    What's a VDP?

    *runs*

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

    I'm pretty sure most of us know what the VDP is and what it does, but allow me to explain...

    He was being sarcastic.

    The VDP stands for Video Display Processor...

    As written in the topic title and the first post.

    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.

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

    The VDP also handles sprites, which can use one of the 4 pallet lines. These sprites can be placed anywhere on the screen, and can animate.

    They cannot animate and is not a feature of the VDP, that's done via 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, which tell it where to place tiles that have been loaded into VRAM.

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

    #12 SpadeAX

    SpadeAX

      Sir Awesome

    • Member
    • 177 posts
    • Gender:Male
    • Location:The UK
    • Interests:Whatever seems to inspire me.

    Posted 30 July 2010 - 01:54 PM

    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*
    • 0

    #13 tristanseifert

    tristanseifert

      I make... THINGS!

    • Member
    • 372 posts
    • Gender:Male
    • Location:Austin, TX

    Posted 30 July 2010 - 03:23 PM

    Morons. I know what the VDP is and what it does. And have done for quite a few years.

    Thanks for the nice reply. [/sarcasm] I explained it in detail for some other people, and I thought it was a serious question.

    Edited by theocas, 30 July 2010 - 08:33 PM.

    • 0

    #14 Selbi

    Selbi

      Tief.Tiefer

    • Pro User
    • 1847 posts
    • Gender:Male
    • Location:L√ľneburg, Germany

    Posted 30 July 2010 - 03:43 PM

    Morons. I know what the VDP is and what it does. And have done for quite a few years.

    Thanks for the nice reply. I tired to explain it best I could for other people, but you are like 'Morons blah blah blah' and that really pisses me off. Just because you know what the VDP is doesn't mean everyone knows what it is and what it does.

    It's because Ordos made an obvious joke and you thought it was a serious question.
    • 0

    #15 MarkeyJester

    MarkeyJester

      4 Super Emeralds

    • Pro User
    • 1830 posts
    • Gender:Male

    Posted 02 August 2010 - 04:25 PM

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

    Register 00 (80) - "Mode Register 1":

    This register has two known functions:

    000X 01Y0

    X = enable or disable the "Horizontal Interrupt" (0 = disable/1 = enable)
    Y = enable or disable the "Horizontal/Vertical Counter" (1 = disable/0 = enable)

    If X is enabled, then while the interrupts are turned on via MC68 (move #$2300,sr) then the horizontal blanking routines will function.

    I'm not sure on Y I'm afraid, I lack the information on that register's usage, if anyone has this information, then please share it.


    Register 01 (81) - "Mode Register 2":

    This register has four known functions:

    0WXY Z100

    W = enable or disable the "Display" (0 = disable/1 = enable)
    X = enable or disable the "Vertical Interrupt" (0 = disable/1 = enable)
    Y = enable or disable "DMA" (Direct Memory Access) (0 = disable/1 = enable)
    Z = Vertical Display Mode (0 = V 28 Cell PAL or NTSC Mode/1 = V 30 Cell NTSC mode)

    If W is disabled, non of the changes you make for display will present on screen (Though certain things like the palette still display).
    If X is enabled, then while the interrupts are turned on via MC68 (move #$2300,sr) then the vertical blanking routines will function.
    If Y is enabled, Direct Memory Access can be used (Will explain more about this later)
    If Z is set 0, you have what the PAL screens usually get (shorter/wider screens). while set 1, you'll get NTSC stretched screen (This is an assumption based on the info I've read, may need confirming).


    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.

    Register 02 (82) - "Map Plane A Location":

    "YY"

    YY = the V-Ram location divided by 400 (Hex).

    Say for example, we wanted set the V-Ram location for Map Plane A to "C000", we take "C000" and divide it by "400", this becomes 30, so YY would equal 30. (You can only set to V-Ram locations that are a multiple of 400)


    Register 03 (83) - "Map Plane Window Location":

    "YY"

    YY = the V-Ram location divided by 400 (Hex).

    Say for example, we wanted set the V-Ram location for Map Plane Window to "F000", we take "F000" and divide it by "400", this becomes 3C, so YY would equal 3C. (You can only set to V-Ram locations that are a multiple of 400)


    Register 04 (84) - "Map Plane B Location":

    "YY"

    YY = the V-Ram location divided by 2000 (Hex).

    Say for example, we wanted set the V-Ram location for Map Plane B to "E000", we take "E000" and divide it by "2000", this becomes 07, so YY would equal 07. (You can only set to V-Ram locations that are a multiple of 2000)


    Register 05 (85) - "Sprite Table Location":

    "YY"

    YY = the V-Ram location divided by 200 (Hex).

    Say for example, we wanted set the V-Ram location for Map Plane Window to "D800", we take "D800" and divide it by "200", this becomes 6C, so YY would equal 6C. (You can only set to V-Ram locations that are a multiple of 200)


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

    #16 MarkeyJester

    MarkeyJester

      4 Super Emeralds

    • Pro User
    • 1830 posts
    • Gender:Male

    Posted 04 August 2010 - 05:56 AM

    Sorry I'm a few hours late, here we go!

    Register 06 (86) - "Unknown/Unused Register":

    There are a few of these that appear to have no functional use with the Genesis/Megadrive, there's no documentation on these unused registers.


    Register 07 (87) - "Backdrop Colour Register":

    "XY"

    X = The palette line set
    Y = The colour in palette line X set

    You'll notice that the Genesis/Megadrive has a backdrop colour, this is a colour that presents under the transparent tiles if nothing is present, it also presents the colour of the boarder too.

    XY can be seen as basically a colour ID to set, Sonic games tend to be set to 20, which most who have edited a sonic level will know that it's the 20th colour (a.k.a the third palette line, 1st colour).


    Register 08 (88) - "Unknown/Unused Register":

    Same as register 86...


    Register 09 (89) - "Unknown/Unused Register":

    Same as register 86...


    Register 0A (8A) - "Horizontal Interrupt Register":

    [NOTE: X must be enabled on register 00 (80) otherwise this has no use]

    "YY"

    YY = the number of horizontal lines to wait before running the horizontal blanking routines, this can be used to set the special water line effect that sonic games usually have, though timing is crucial.


    Register 0B (8B) - "Mode Register 3":

    0000 WXYZ

    W = enable or disable "External Interrupts" (0 = disable/1 = enable)
    X = Vertical Scroll Mode (Deformation)
    Y = Horizontal Scroll Mode (Bit 1) (Deformation)
    Z = Horizontal Scroll Mode (Bit 2) (Deformation)

    W is something I am not sure on, and I don't feel it's a good idea to throw my theory into this without checking (Anyone have an answer?)

    If X is clear (bit 0), then the first long-word data in the "VS-Ram" will control the entire vertical scrolling of the screen (First word = FG Y scroll/Second word = BG Y scroll), if however it is set (bit 1), then each long-word data in the "VS-Ram" will represent what each 16 (10 hex) pixels will scroll vertically by, an example of this would be in Sonic 3 (Marble Garden Zone act 2) where robotnik would plow his drilling device into the ground, and would slice/break up the ground vertically into sections and move down.

    Y and Z bits are used together respectively.

    If YZ is 00, then the first long-word data in the "HS-Ram" will control the entire horizontal scrolling of the screen (First word = FG X scroll/Second word = BG X scroll).

    If YZ is 10, then each long-word data in the "HS-Ram" will represent what each 8 pixels will scroll horizontally by.

    If YZ is 11, then each long-word data in the "HS-Ram" will represent what each 1 pixel line will scroll horizontally by.

    YZ being set to 01 is prohibited, so don't bother.

    Think of this register as being used to determin how deformation should be used (how it should slice up the background/foreground for neat effects).


    Register 0C (8C) - "Mode Register 4":

    J000 XYZK

    J & K = Horizontal Cell Mode (0 = 32 Cells/1 = 40 Cells) (NOTE: Both J and K must be set to the same value according to certain documents)
    X = enable or disable "Shadow and Hi-lighting" (0 = disable/1 = enable)
    Y = Interlace mode (Bit 1)
    Z = Interlace mode (Bit 2)

    Y and Z bits are used together respectively.

    If YZ is 00, the no interlace is set.

    If YZ is 01, the interlace is set.

    If YZ is 11, the interlace is set for double resolution.

    YZ being set to 10 is prohibited, so don't bother.




    Register 0D (8D) - "Horizontal Scroll Table Location (HS-Ram)":

    "YY"

    YY = the V-Ram location divided by 400 (Hex).

    Say for example, we wanted set the V-Ram location for Horizontal Scroll Table to "DC00", we take "DC00" and divide it by "400", this becomes 37, so YY would equal 37. (You can only set to V-Ram locations that are a multiple of 400)


    Register 0E (8E) - "Unknown/Unused Register":

    Same as register 86...


    Register 0F (8F) - "Auto-Increment Register":

    "YY"

    YY = the number of bytes for the VDP to increment by.

    This is an important register and useful too, some of you who have move data to V-Ram may have noticed that the location seems to automatically advance itself, as seen in an example way back...

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


    This register determins how many bytes to advance the VDP's location (pointer) by when one of the move commands you see above have executed, NOTE: the above is moving a long-word, but the VDP processes a word at a time, so setting this register to 02 should be used for the above example if you want the correct normal incrementing amount.


    Register 10 (90) - "Map Plane Size":

    00WX 00YZ

    W and X bits are used together respectively, and so are Y and Z bits.

    Now the way to understand this is by seeing a graphical example:

    Posted Image

    The red and green squares represent the Map Planes, while the blue rectangle represents the screen, here's the rule, the screen can move anywhere within the plane area (The red square), if the screen crosses any of the red lines, the other side of the plane will present, basically looping/wrapping itself.

    If the screen goes out one side, it'll enter the other side is the simplest way to put it.

    This register controls how big the plane size is.

    If WX is 00, then the vertical plane size is 32 cells/tiles big (32 x 8 pixels).
    If WX is 01, then the vertical plane size is 64 cells/tiles big (64 x 8 pixels).
    If WX is 11, then the vertical plane size is 128 cells/tiles big (128 x 8 pixels).

    10 is prohibited for WX.

    If YZ is 00, then the horizontal plane size is 32 cells/tiles big (32 x 8 pixels).
    If YZ is 01, then the horizontal plane size is 64 cells/tiles big (64 x 8 pixels).
    If YZ is 11, then the horizontal plane size is 128 cells/tiles big (128 x 8 pixels).

    10 is prohibited for YZ too.

    No matter what size you have the planes, they will always wrap in a loop should the screen advance out of the boundary area.


    Stopping again for the night, will continue sometime later on this evening.
    • 0

    #17 MarkeyJester

    MarkeyJester

      4 Super Emeralds

    • Pro User
    • 1830 posts
    • Gender:Male

    Posted 14 August 2010 - 10:38 PM

    And.. continuing...

    Register 11 (91) - "Window Horizontal Position":

    This is for controlling the X position of the Window plane.

    D00M MMMM

    D = The direction in which the plane is moved (0 = Left side/1 = Right side)
    MMMMM = The number of tiles/cells to move the plane in the direction of "D"

    There is a side note to this, the Window plane will mask the FG plane, any FG tiles that are under the Window plane's mappings will become masked (invisible), even when the Window plane is mapping a transparent tile, the FG tile still becomes masked.


    Register 12 (92) - "Window Vertical Position":

    Similar to register 11 (91), but for the Y position of the Window plane.

    D00M MMMM

    D = The direction in which the plane is moved (0 = Upper side/1 = Down side)
    MMMMM = The number of tiles/cells to move the plane in the direction of "D"

    The same note with register 11 (91)

    the Window plane will mask the FG plane, any FG tiles that are under the Window plane's mappings will become masked (invisible), even when the Window plane is mapping a transparent tile, the FG tile still becomes masked.


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

    Register 13 (93) - "DMA Transfer Size (Lower Byte --00)":

    This sets the size (the number of bytes to transfer), to set the size:

    XXXX = Size

    Divide XXXX by 2:

    XXXX / 2 = AABB

    BB = the data to move to this register.

    So for example, if XXXX is 0280, 0280 / 2 = 0140, so you move 40 to this register.


    Register 14 (94) - "DMA Transfer Size (Upper Byte 00--)":

    This sets the size (the number of bytes to transfer), to set the size:

    XXXX = Size

    Divide XXXX by 2:

    XXXX / 2 = AABB

    AA = the data to move to this register.

    So for example, if XXXX is 0280, 0280 / 2 = 0140, so you move 01 to this register.

    Both this register and the one previously, will take both individually, the 01 and the 40, patch them together 0140, and multiply by 2, 0280. The size will be specified.


    Next the source registers...

    Register 15 (95) - "DMA Transfer Source (Low Byte ----00)":

    This sets the source (the location to transfer the data from), to set the source location:

    --XXXXXX = Location

    Divide --XXXXXX by 2:

    --XXXXXX / 2 = --AABBCC

    CC = the data to move to this register.

    So for example, if --XXXXXX is --FFD000 (Ram location), --FFD000 / 2 = --7FE800, so you move 00 to this register.


    Register 16 (96) - "DMA Transfer Source (Mid Byte --00--)":

    This sets the source (the location to transfer the data from), to set the source location:

    --XXXXXX = Location

    Divide --XXXXXX by 2:

    --XXXXXX / 2 = --AABBCC

    BB = the data to move to this register.

    So for example, if --XXXXXX is --FFD000 (Ram location), --FFD000 / 2 = --7FE800, so you move E8 to this register.


    Register 17 (97) - "DMA Transfer Source (Hi- Byte 00----)":

    This sets the source (the location to transfer the data from), to set the source location:

    --XXXXXX = Location

    Divide --XXXXXX by 2:

    --XXXXXX / 2 = --AABBCC

    AA = the data to move to this register.

    So for example, if --XXXXXX is --FFD000 (Ram location), --FFD000 / 2 = --7FE800, so you move 7F to this register.

    Note: AA has a special function, break it up into bits, the two most significant bits (XY00 0000) has special functions:

    If XY is 00 or 01, then normal DMA transfer is ran, nothing special.
    If XY is 10, then V-Ram fill is enabled, and the V-Ram destination specified will be set to one value only, basically filling the area with one value.
    If XY is 11, then V-Ram copy is enabled, though I haven't used this nor have much info on it myself, anyone with the info is welcome to explain.


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

    #18 Hanoch

    Hanoch

      5 Chaos Emeralds

    • Pro User
    • 310 posts
    • Gender:Male
    • Location:Israel

    Posted 14 August 2010 - 11:23 PM

    Oh I think get what the window plane is....

    Posted Image

    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?

    Edited by Hanoch, 15 August 2010 - 06:32 AM.

    • 0




    0 user(s) are reading this topic

    0 members, 0 guests, 0 anonymous users