News:

11 March 2016 - Forum Rules

Main Menu

Super Nintendo Programming graphical anomalies

Started by benjaminshinobi, February 02, 2012, 03:24:39 PM

Previous topic - Next topic

benjaminshinobi

Hey! I'm trying to re-acquaint myself with Super Nintendo/65816 programming and I'm getting a weird graphical anomaly.

Here is the intended image:


Here is what I am getting:


Here is the code, that creates the tilemap

    ; load tilemap data
;-----------------------------------------------------
    lda #$80
    sta $2115 ;<-- set video mode. inc address after $2119 (for words)

    ldx #$0400
    stx $2116
   
;load y with 0 and load each word
;of the background into VRAM.
ldy #$0000

; 32 x 32 = 0x400
ldx #$0400

tilemap_loop:
    sty $2118 ;<--- put into VRAM
dex
iny
cpx #$0000
bne tilemap_loop
;-----------------------------------------------------


It looks like it only creates an anomalous tile as a new row is created (ie every 32 tiles). Here's another image where I had part of the face showing and you can see that there are less weird tiles:



Here I am only trying to load 28 rows (244 pixels/screen height)

The only thing I am thinking is that some bit is being set/added when you get to 32, but it doesn't really make sense since it is only 6 bits...
I've gotten this to work without any weird tiles when I just would repeat the same tile which is why I am guessing it is related to the incrementing.

(ps these are based on bazz's tutorials)

LostTemplar

Are you waiting for v-blank? As far as I know, when you access VRAM the PPU can't read from it, thus resulting in garbage data when it tries to get the next tile to output. This might explain the weird behaviour.


LostTemplar

Try inserting something like this before tilemap_loop:


vbl:    lda $4212       ; vblank flag (bit 7)
        bpl vbl

benjaminshinobi

I didn't see any difference with inserting the VBLANK code but I'm not sure if I'm doing it correctly. Tried it in various places.

But just as proof I guess this code (just outputting one tile)


; load tilemap data
;-----------------------------------------------------
    lda #$80
    sta $2115 ;<-- set video mode. inc address after $2119 (for words)

    ldx #$0400
    stx $2116
   
;load y with 0 and load each word
;of the background into VRAM.
ldy #$0151;<--- arbitrary tile

; 32 x 32 = 0x400
ldx #$0400

tilemap_loop:
    sty $2118 ;<--- put into VRAM
dex
;iny         ;<--- just print the same tile
cpx #$0000
bne tilemap_loop
;-----------------------------------------------------


and gets this (no garbage, plus in my first post you can see that the tiles don't have garbage in the last picture are the correct tiles for that row):




LostTemplar

#5
What emulator are you using for testing? Did you try vSNES to look at VRAM (does the tilemap get corrupted or the tiles themselves)?

EDIT: Guessing from the corrupted tiles, it might seem that part of the tilemap overrides the tiles to be displayed (the pixels follow an increasing bit pattern). Your tilemap address should probably be higher. I have no idea why the corruption would start in the second row, though. Should be the third row if your tile base is at 0x0000 and your tilemap at 0x0800, as your code suggests (one 4bpp row takes 32 * 8 * 4 = 0x400 bytes, thus it should be the third row that is corrupted - unless I am making some mistake).

benjaminshinobi

I'm on ZSNES. I was thinking I need some kind of debugging to actually know what is going on. I will check it out in vSNES

LostTemplar

FYI, I just edited my post (again ;)) if you didn't notice. But looking at VRAM with vSNES should definitely give you some insight.

benjaminshinobi

#8
I have to work on/do some other stuff and remove my mind off of this for a little bit (it seems usually just doing something else with a problem like this counterintuitively works sometimes). I just tried another image (as I was hoping maybe it was some fluke with PCX2SNES or something) and that didn't work either...
I'll report back with whatever happens with vSNES/looking at VRAM.
I thought I knew what I was doing but the creation/manipulation of the tilemap is a bit confusing to me...
I know I've gotten this to work before...but it was a long time ago (a computer / hard drive crash or two ago) when I found these tutorials on this site called SNES Lobby...I'm not sure if they are archived any where haven't been able to find them...and I was using x816 (using wla now)


February 02, 2012, 07:00:23 PM - (Auto Merged - Double Posts are not allowed before 7 days.)

found the old SNES Lobby stuff:

http://web.archive.org/web/20030812024533/http://filebox.vt.edu/users/rogrubb3/SNESDev/

I'll probably try to mirror it on a live site and also see how they did their tilemap stuff.

Azkadellia

Quote from: benjaminshinobi on February 02, 2012, 05:43:24 PM
I'm on ZSNES. ...

There's part of your problem. ZSNES is bottom tier. bsnes, snes9x 1.53, or snesgt are far superior.
Current Projects: On hold indefinitely.
I do the Twitter thing now: https://twitter.com/MistressSaeko (expect lots of game streaming announcements)
Mistress of the RHDN Discord server.

KingMike

Also, you should use the DMA registers to transfer data instead of writing to the write registers directly.
It will finish much faster than any manual loop will, which is important because you only have limited VBlank time.
"My watch says 30 chickens" Google, 2018

benjaminshinobi

#11
Quote from: KingMike on February 02, 2012, 07:17:38 PM
Also, you should use the DMA registers to transfer data instead of writing to the write registers directly.
It will finish much faster than any manual loop will, which is important because you only have limited VBlank time.

I didn't want to put too much code because usually when I see that in forums I don't even read it, but I am loading the palette and tiles via DMA transfer (bazz has some nice macro's for this).

I got it to work! The issue was what LostTemplar suggested above. I didn't specify the address of the tile map correctly (the original example I pulled from only had two tiles, so I was writing over the tile data)



February 02, 2012, 09:28:49 PM - (Auto Merged - Double Posts are not allowed before 7 days.)

Quote from: Azkadellia on February 02, 2012, 07:14:49 PM
There's part of your problem. ZSNES is bottom tier. bsnes, snes9x 1.53, or snesgt are far superior.

I feel you, I honestly haven't programmed 65816 ASM or needed debugging tools so I just got ZSNES. I'm sure other emulators have nice options, but the screen cap / movie recording features and how they are implemented is nice, to me anyway.

Azkadellia

Current Projects: On hold indefinitely.
I do the Twitter thing now: https://twitter.com/MistressSaeko (expect lots of game streaming announcements)
Mistress of the RHDN Discord server.


benjaminshinobi

Hey I know this post is old, but I lost the old version a while ago along with a hard drive :'( but have been getting into this stuff again.

Anyway, I came across the same issue

As said previously in the thread, they are based on bazz's tutorials, and use wla-65816 for compiling.

All it really does is add a tile map that takes up the full screen, that is just 1, 2, 3, 4...etc. rather than a "real" tile map.

Nothing special, but there are a few tricky points with not overwriting the tilemap, actually converting the graphic that may frustrate some people.

It should be relatively well commented, but isn't super optimized yet. (I made an .inc that has some of the registers labeled, but didn't go all the way with it yet, and didn't use the macro that bazz made to load the tilemap it is still just a routine)

There is a 4bpp and 8bpp version and it does scrolling as well.

I put it on my google drive here:
https://drive.google.com/file/d/0B4wfhZPgSasGYUw0bl9qSFdENTQ/edit?usp=sharing

and here it is working on a real system (famiclone, but I am pretty sure it will probably work fine on a real SNES as well):
http://instagram.com/p/jVBH3JP9ZQ/