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