Author Topic: SNES Assembly Help  (Read 3008 times)

0 Members and 1 Guest are viewing this topic.

Offline akaitora

  • Newbie
  • *
  • Posts: 1
  • NEO newbie
SNES Assembly Help
« on: July 19, 2012, 07:53:37 AM »
So I wrote the following code to basically fill the screen with 8x8 water looking tiles to simulate an ocean.
Every 7 Vblanks, I go through and swap out the tiles to make it look like the water is animating.  However I am noticing that not all the tiles are being swapped.  Do you guys see anything wrong with my code?

Code: [Select]
;------------------------------------------------------------------------
;- DmaTest1
;- Written By: Brandon Fogerty
;- Special Thanks to Neviksti
;------------------------------------------------------------------------

;=== Include MemoryMap, VectorTable, HeaderInfo ===
.INCLUDE "Header.inc"

;=== Include Library Routines & Macros ===
.INCLUDE "InitSNES.asm"

;=== Global Variables ===

.DEFINE MapX $18
.DEFINE MapY $20

.DEFINE TileCounter 1
.DEFINE OffX $0400
.DEFINE WaterVar    1
.DEFINE VBlankTicks 1
.DEFINE ForceDraw   0


;============================================================================
;LoadPalette - Macro that loads palette information into CGRAM
;----------------------------------------------------------------------------
; In: SRC_ADDR -- 24 bit address of source data,
;     START -- Color # to start on,
;     SIZE -- # of COLORS to copy
;----------------------------------------------------------------------------
; Out: None
;----------------------------------------------------------------------------
; Modifies: A,X
; Requires: mem/A = 8 bit, X/Y = 16 bit
;----------------------------------------------------------------------------
.MACRO LoadPalette
    lda #\2
    sta $2121       ; Start at START color
    lda #:\1        ; Using : before the parameter gets its bank.
    ldx #\1         ; Not using : gets the offset address.
    ldy #(\3 * 2)   ; 2 bytes for every color
    jsr DMAPalette
.ENDM

.MACRO LoadBlockToVRAM
ldx #\2 ; DEST
stx $2116
lda #:\1 ; Source Bank
ldx #\1         ; SRC Offset
ldy #\3 ; Size
jsr LoadToVRAM
.ENDM

.MACRO Stall5
wai
wai
wai
wai
wai
.ENDM

.MACRO Stall7
wai
wai
wai
wai
wai
wai
wai
.ENDM

.MACRO CreateWater

ldx #$0400
stx OffX

lda #\1
sta TileCounter

jsr GenerateMap

.ENDM


;==============================================================================
; main
;==============================================================================

.BANK 0 SLOT 0
.ORG 0
.SECTION "MainCode"

Main:
InitializeSNES

lda $4200 ; Enable nmi and joypad control (Bit 8 and 0)
ora #%10000001
sta $4200

LoadPalette BG_Palette, 0, 4
; $0040 = 8 * 2 * numOfTiles
; 2 = color depth in bits #%0011 is 4
LoadBlockToVRAM Tiles, $0000, $0040

CreateWater 1
jsr SetupVideo


forever:

Stall7
CreateWater 2
lda #$0F ;Turn on screen, full brightness
    sta $2100
   
    Stall7
CreateWater 1
lda #$0F ;Turn on screen, full brightness
    sta $2100

jmp forever

VBlank:

lda $4210 ;clear NMI Flag

      RTI

SetupVideo:
lda #$00
sta $2105

lda #$04
sta $2107


stz $210B

lda #$01
sta $212C

lda #$0F
sta $2100

rts

LoadToVRAM:
stx $4302
sty $4305
sta $4304

lda #01
sta $4300
lda #$18
sta $4301

lda #$01
sta $420B

rts

;============================================================================
; DMAPalette -- Load entire palette using DMA
;----------------------------------------------------------------------------
; In: A:X  -- points to the data
;      Y   -- Size of data
;----------------------------------------------------------------------------
; Out: None
;----------------------------------------------------------------------------
; Modifies: none
;----------------------------------------------------------------------------
DMAPalette:
; Handle Variables
stx $4302 ; source address offset
sty $4305 ; # of bytes to transfer
sta $4304 ; Source bank

stz $4300 ; Normal DMA Transfer Mode
lda #$22
sta $4301 ; Destination in VRAM

lda #01
sta $420B ; Start DMA Channel 0 Transfer

    rts         ; return from subroutine


GenerateMap:

rep #%00110000 ; Make A and X/Y 16 bit

ldx OffX
stx $2116
lda TileCounter
sta $2118

TileSwap:
inc TileCounter
lda TileCounter
cmp #3
bne MapSwap
lda #1
sta TileCounter

MapSwap:
inc OffX
lda OffX
cmp #$0400 + 1024;896 ; This number could be 400 which requires 16 bit
bne GenerateMap

Done:
sep #%00100000 ; When done, set A back to 8 bit
rep #%00010000

rts

.ENDS



.Bank 1 SLOT 0
.ORG 0
.SECTION "TileData"
.INCLUDE "tiles.inc"
.ENDS



Offline mic_

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 632
Re: SNES Assembly Help
« Reply #1 on: July 19, 2012, 04:42:08 PM »
Without having looked that carefully at the code I'd guess that you're running out of vblank time. On an NTSC SNES you've got about 6500 CPU cycles during vblank IIRC (assuming SlowROM timing). For a full 256x224 NTSC screen that gives you about 7 cycles per tile to update the tilemap.

My suggestion would be to generate the new tilemap in RAM during the active display period and copying it to VRAM using DMA during the next vblank.