Sega Megadrive - sprite flipping on the fly, major confusion!

Discussion in 'Sega Discussion' started by Headcrab, May 23, 2012.

  1. Headcrab

    Headcrab (BigEvilCorporation)

    Joined:
    Dec 21, 2011
    Messages:
    246
    Likes Received:
    67
    Hi all.

    I'm at my wits end with this one! I'm trying to flip a sprite at runtime, by changing the 5th byte in my sprite descriptor struct (live in VRAM).

    My sprite:

    RunningManSprite:
    dc.w 0x0080 ; Y coord (+ 128)
    dc.b RunningManDimentions ; Width (bits 0-1) and height (bits 2-3) in tiles
    dc.b 0x00 ; Index of next sprite (linked list)
    dc.b 0x40 ; H/V flipping (bits 3/4), palette index (bits 5-6), priority (bit 7)
    dc.b RunningManTileID ; Index of first tile
    dc.w 0x0080 ; X coord (+ 128)



    Upload to VRAM (sprite desc. table at 0xE400):

    vdp_write_sprite_table equ 0x60000003

    LoadSpriteTables:
    ; a0 - Sprite data address
    ; d0 - Number of sprites

    move.l #vdp_write_sprite_table, vdp_control

    subq.b #0x1, d0 ; Minus 1 for counter
    @AttrCopy:
    move.l (a0)+, vdp_data
    move.l (a0)+, vdp_data
    dbra d0, @AttrCopy

    rts


    lea RunningManSprite, a0 ; Sprite table data
    move.w #0x1, d0 ; 1 sprite
    jsr LoadSpriteTables



    So... to flip the sprite horizontally, I need to set bit 3 in byte 5. Surely I can just set the VRAM address to 0x60040003 and push 0x48?
    move.l #0x60040003, vdp_control
    move.b #0x48, vdp_data




    But the sprite disappears completely. I've been scratching my head and poking around various things for hours now. Can anyone spot anything blindingly obvious?

    Thanks
     
  2. Nemesis

    Nemesis Robust Member

    Joined:
    Mar 22, 2007
    Messages:
    248
    Likes Received:
    79
    You can't do 8-bit writes to the VDP control/data ports. Well, you can, but it doesn't do what you think it should do. The M68000 has a 16-bit data bus. If you do a word write, it performs a single 16-bit bus operation. If you perform a long write, it performs two 16-bit bus operations, one for each 16-bit half of the 32-bit value. If you perform an 8-bit write, it performs a 16-bit bus operation with the 8-bit value mirrored in both the upper and lower 8-bits of the 16-bit data value, and sets the UDS/LDS lines to indicate whether the 8-bit write it targetted at either the upper or the lower half of the 23-bit target address (LSB is dropped). The thing is, the VDP doesn't use the UDS/LDS lines in its address decoding. When you perform an 8-bit write to the VDP, say, with 0x48 like you did above, what the VDP actually sees is a 16-bit write of 0x4848. If you perform a word-wide write instead, targetted at an even VRAM address, you'll get the result you want. This will of course mean that you'll need to write the contents of byte 6 along with byte 5.
     
    Last edited: May 23, 2012
  3. Headcrab

    Headcrab (BigEvilCorporation)

    Joined:
    Dec 21, 2011
    Messages:
    246
    Likes Received:
    67
    Yes! Perfect, thank you so much. I'm sure I read that somewhere when I was starting out, it's just hit me. Anyway it's working fine now.
     
sonicdude10
Draft saved Draft deleted
Insert every image as a...
  1.  0%

Share This Page