SNES, where to start?

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
User avatar
nicklausw
Posts: 376
Joined: Sat Jan 03, 2015 5:58 pm
Location: ...
Contact:

Re: SNES, where to start?

Post by nicklausw »

Okay, does anyone know how I can:

1. Set the background to be 4bpp?
2. Write to the background?

I'm not really concerned with crazy layers and stuff, unless there's some special reason I should be.
Kannagi
Posts: 100
Joined: Sun May 11, 2014 8:36 am
Location: France

Re: SNES, where to start?

Post by Kannagi »

1. Set the background to be 4bpp?
it depends on the mode.

For example :
Mode 0, 4 BG(1,2,3,4) in 2 bpp
Mode 1, 2 BG(1,2) in 4bpp and 1 BG(3) in 2bpp
2. Write to the background?
Where you want ,simply configure with:
BG1SC,BG2SC,BG3SC,BG4SC ($2107-$210A) for tile
BG12NBA BG34NBA ($210B/$210C) for data


You have to read the documentation, everything is there.
I say this because many SNES option.
User avatar
nicklausw
Posts: 376
Joined: Sat Jan 03, 2015 5:58 pm
Location: ...
Contact:

Re: SNES, where to start?

Post by nicklausw »

Alright, writing to the BG seems simple enough, but when it comes to the modes, how would I actually go about switching to mode 1? tepples' example uses mode 0 I'm pretty sure, so that doesn't really help.

EDIT: I'm stupid...mode 0 seems to suit my needs just fine after all.
Kannagi
Posts: 100
Joined: Sun May 11, 2014 8:36 am
Location: France

Re: SNES, where to start?

Post by Kannagi »

must write on BGMODE ($2105).

Code: Select all

;mode 0
lda #00
sta $2105

;mode 1
lda #01
sta $2105

;mode 1 and BG1 16x16
lda #11
sta $2105
User avatar
dougeff
Posts: 2876
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: SNES, where to start?

Post by dougeff »

Set the mode with register 2105
---- -mmm

Mode 1 and 2 use 4 bpp.

The second part takes about 10 steps to do, and I'm no expert...
-force blank
-put BG tile graphics in VRAM
-put BG tilemap in VRAM
-tell it were the BG graphics are
-tell it were the BG map is
-fill palette
-turn off mosaic
-set scroll
-allow rendering, and set brightness

lda #$1f
sta $212C ;enable main screen

Did I forget anything?
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES, where to start?

Post by Drew Sebastino »

nicklausw wrote:I'm not really concerned with crazy layers and stuff, unless there's some special reason I should be.
I'm not getting it... There are several video modes on the SNES that just arrange how the vram bandwidth is being used. Here's a good link to look at for it: http://wiki.superfamicom.org/snes/show/Backgrounds (some video modes have special properties like column scrolling, like modes 2 and 4). Mode 1 is (by far) the most often used, but Mode 3 is another good one. The major drawback to mode 7 is the fact that there's only one BG layer (the mode 7 plane) and also the fact that there's only 256 tiles to choose from (and no horizontal or vertical flipping).

Assuming you want to use mode 1, do these steps to enable the BG layer: (here's a good link to learn more about these hardware registers: http://wiki.superfamicom.org/snes/show/Registers)

Code: Select all

  lda #$01		;Set video mode 1, )(16 color BG1, 16 color BG2, 4 color BG3) 8x8 tiles (changing bit 5 will make the tiles 16x16) 
  sta $2105

  lda #%??????00	;Set BG1's Tile Map VRAM offset to #%??????>>10 (word address) and the Tile Map size to 32 tiles x 32 tiles (the first 0 doubles the width of the tilemap, the second doubles the height of the tilemap)
  sta $2107

  lda #$0?		;Set BG1's Character VRAM offset to #$?>>12 (word address) (the 0 is for BG2)
  sta $210b

  lda #$01		;Turn on BG1
  sta $212C

God damn, I was writing all this and people beat me to it... :lol:
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SNES, where to start?

Post by tepples »

nicklausw wrote:tepples' example uses mode 0 I'm pretty sure, so that doesn't really help.
I'd make a mode 1 example if I had examples of background artwork that needed mode 1. But my pixel art skills are still very much stuck in the NES/GBC/NGPC days.
dougeff wrote:The second part takes about 10 steps to do, and I'm no expert...
That sounds reasonable. And in fact, all but brightness and mosaic are also things you have to do on the NES as well.
Did I forget anything?
Some time ago, I posted a list of everything you need to do to bring up a picture on the NES PPU or Super NES S-PPU.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES, where to start?

Post by Drew Sebastino »

tepples wrote:I'd make a mode 1 example if I had examples of background artwork that needed mode 1. But my pixel art skills are still very much stuck in the NES/GBC/NGPC days.
I can help there, but no promises. I think mode 0 might be somewhat useful if you have something with very low contrast, like a dark cave
User avatar
dougeff
Posts: 2876
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: SNES, where to start?

Post by dougeff »

Heres a slightly better description of displaying a BG...

$8x to 2100 force blank
$01 to 2105 set mode 1
$00 to 2106 mosaic off (1x1)
2115-9 Put BG graphics and tilemaps in VRAM (or use a DMA transfer)
2107 set BG1 tilemap address and size
(2108 set BG2 tilemap address and size)
210b set BG1/2 graphics address
210d-e set BG1 scroll
(210f-10 set BG2 scroll)

2121-2 write palette

(Optional, display sprites...)
2115-9 Put sprite graphics in VRAM (or use DMA transfer)
2101 set Oam size and VRAM location
2102-4 Put sprite data in OAM

$0f to 2100 enable rendering, full brightness
$1f to 212c, set all to 'main screen'

And I think you need to turn off scanline IRQs...4200

I think window masks and color math are off by default, so you don't have to set them.

Again, I'm new at this, so let me know if I made any mistakes or omissions. Thanks.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES, where to start?

Post by Drew Sebastino »

dougeff wrote:I think window masks and color math are off by default, so you don't have to set them.
Shouldn't everything be off by default? That's what the initialization routine is for.
User avatar
nicklausw
Posts: 376
Joined: Sat Jan 03, 2015 5:58 pm
Location: ...
Contact:

Re: SNES, where to start?

Post by nicklausw »

Okay, so this is what I have so far, and what's happening is that a 5 is displaying on the screen, but:
1. it only appears about half the time in higan?
2. it doesn't seem to use the full palette (can't mode 1 have sixteen colors? It only uses one, even with the palette properly loaded).
EDIT: the full palette is used but while no$sns uses it properly, higan seems to have the colors all weird...

Here's the code for loading all this VRAM stuff:

Code: Select all

; forced blank
  seta8
  lda #$8f
  sta PPUBRIGHT
  
  lda #$01
  sta BGMODE     ; mode 0 (four 2-bit BGs) with 8x8 tiles
  stz BGCHRADDR  ; bg planes 0-1 CHR at $0000
  lda #$4000 >> 13
  sta OBSEL      ; sprite CHR at $4000, sprites are 8x8 and 16x16
  lda #>$6000
  sta NTADDR+0   ; plane 0 nametable at $6000
  sta NTADDR+1   ; plane 1 nametable also at $6000
  
  
  
  ; Copy background palette to the S-PPU.
  ; We perform the copy using DMA (direct memory access), which has
  ; four steps:
  ; 1. Set the destination address in the desired area of memory,
  ;    be it CGRAM (palette), OAM (sprites), or VRAM (tile data and
  ;    background maps).
  ; 2. Tell the DMA controller which area of memory to copy to.
  ; 3. Tell the DMA controller the starting address to copy from.
  ; 4. Tell the DMA controller how big the data is in bytes.
  ; ppu_copy uses the current data bank as the source bank
  ; for the copy, so set the source bank.
  seta8
  stz CGADDR  ; Seek to the start of CGRAM
  setaxy16
  lda #DMAMODE_CGDATA
  ldx #palette & $FFFF
  ldy #palette_size-palette
  jsr ppu_copy
  
  ; Copy background tiles to PPU.
  ; PPU memory is also word addressed because the low and high bytes
  ; are actually on separate SRAM chips.
  ; In background mode 0, all background tiles are 2 bits per pixel,
  ; which take 16 bytes or 8 words per tile.
  setaxy16
  stz PPUADDR  ; we will start video memory at $0000
  lda #DMAMODE_PPUDATA
  ldy #font_size-font
  ldx #font & $FFFF
  jsr ppu_copy
  
  lda #$6000|NTXY(1,1)
  sta PPUADDR
  lda #'5'
  sta PPUDATA
  
  
  seta8
  
  lda #%00000001  ; enable sprites and plane 0
  sta BLENDMAIN
  
  lda #$0F
  sta PPUBRIGHT
  
?forever:
  jmp ?forever
And here's the 'borrowed' initialization code:

Code: Select all

  sei          ; Disable interrupts
  clc          ; Clear carry, used by XCE
  xce          ; Set 65816 native mode
  jmp :+       ; Needed to set K (bank of PC) properly if MODE 21 is ever used;
               ; see official SNES developers docs, "Programming Cautions"

: cld          ; Disable decimal mode
  phk          ; Push K (PC bank)
  plb          ; Pull B (data bank, i.e. data bank now equals PC bank)

  rep #$30     ; A=16, X/Y=16

  ; Note: this should correlate with ZEROPAGE in snes.cfg
  lda #$0000
  tcd          ; Set D = $0000 (direct page)

  ; Note: this should correlate with the top of BSS in snes.cfg
  ldx #$1fff
  txs          ; Set X = $1fff (stack pointer)


; Register initialisation values, per official Nintendo documentation

  sep #$20     ; A=8
  lda #$80
  sta $2100
  stz $2101
  stz $2102
  stz $2103
  stz $2104
  stz $2105
  stz $2106
  stz $2107
  stz $2108
  stz $2109
  stz $210a
  stz $210b
  stz $210c
  stz $210d
  stz $210d
  stz $210e
  stz $210e
  stz $210f
  stz $210f
  stz $2110
  stz $2110
  stz $2111
  stz $2111
  stz $2112
  stz $2112
  stz $2113               
  stz $2113               
  stz $2114
  stz $2114
  lda #$80
  sta $2115
  stz $2116
  stz $2117
  stz $211a
  stz $211b
  lda #$01
  sta $211b
  stz $211c
  stz $211c
  stz $211d
  stz $211d
  stz $211e       
  lda #$01
  sta $211e
  stz $211f
  stz $211f
  stz $2120
  stz $2120
  stz $2121
  stz $2123
  stz $2124
  stz $2125
  stz $2126
  stz $2127
  stz $2128
  stz $2129
  stz $212a
  stz $212b
  stz $212c
  stz $212d
  stz $212e
  stz $212f
  stz $4200
  lda #$ff
  sta $4201
  stz $4202
  stz $4203
  stz $4204
  stz $4205
  stz $4206
  stz $4207
  stz $4208
  stz $4209
  stz $420a
  stz $420b
  stz $420c
  stz $420d

;ClearVram
  LDA #$80
  STA $2115         ;Set VRAM port to word access
  LDX #$1809
  STX $4300         ;Set DMA mode to fixed source, WORD to $2118/9
  LDX #$0000
  STX $2116         ;Set VRAM port address to $0000
  LDX #.LOWORD(zero_fill_byte)
  STX $4302         ;Set source address to $xx:0000
  LDA #.BANKBYTE(zero_fill_byte)
  STA $4304         ;Set source bank
  LDX #$0000
  STX $4305         ;Set transfer size to 65536 bytes
  LDA #$01
  STA $420B         ;Initiate transfer

;ClearPalette
  STZ $2121
  LDX #$0100
ClearPaletteLoop:
  STZ $2122
  STZ $2122
  DEX
  BNE ClearPaletteLoop

  ;**** clear Sprite tables ********

  STZ $2102	;sprites initialized to be off the screen, palette 0, character 0
  STZ $2103
  LDX #$0080
  LDA #$F0

_Loop08:
  STA $2104	;set X = 240
  STA $2104	;set Y = 240
  STZ $2104	;set character = $00
  STZ $2104	;set priority=0, no flips
  DEX
  BNE _Loop08

  LDX #$0020

_Loop09:
  STZ $2104		;set size bit=0, x MSB = 0
  DEX
  BNE _Loop09

  ;**** clear SNES RAM ********

  STZ $2181		;set WRAM address to $000000
  STZ $2182
  STZ $2183

  LDX #$8008
  STX $4300         ;Set DMA mode to fixed source, BYTE to $2180
  LDX #.LOWORD(zero_fill_byte)
  STX $4302         ;Set source offset
  LDA #.BANKBYTE(zero_fill_byte)
  STA $4304         ;Set source bank
  LDX #$0000
  STX $4305         ;Set transfer size to 64KBytes (65536 bytes)
  LDA #$01
  STA $420B         ;Initiate transfer

  LDA #$01          ;now zero the next 64KB (i.e. 128KB total)
  STA $420B         ;Initiate transfer
What all is the deal here, anyway?
User avatar
dougeff
Posts: 2876
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: SNES, where to start?

Post by dougeff »

Is "seta8" (etc) an assembler directive (to assemble in 8/or 16 bit modes)? Because you also need to use SEP and REP to put the processor in the correct mode.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
nicklausw
Posts: 376
Joined: Sat Jan 03, 2015 5:58 pm
Location: ...
Contact:

Re: SNES, where to start?

Post by nicklausw »

Yeah, "seta8" and "setaxy16" are both macros to use SEP and REP to do such.
User avatar
nicklausw
Posts: 376
Joined: Sat Jan 03, 2015 5:58 pm
Location: ...
Contact:

Re: SNES, where to start?

Post by nicklausw »

Update: for the sake of flat out letting you all see what exactly I'm doing, here's a github repo with it all. The makefile should work given that ca65, ld65, bsnes, and superfamicheck are in your path. And you're on linux. Probably not yes to both unless you're lucky. The project can easily be built manually, though. :P
User avatar
dougeff
Posts: 2876
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: SNES, where to start?

Post by dougeff »

I see you are also working on an SNES assembler. Did you know that Disch wrote an SNES assember last year...

http://www.romhacking.net/forum/index.p ... 086.0.html

Also, since you gave us the source code, would you be able to post a link to the compiled .sfc file that you're having trouble with?

I'd like to take a close look at it, make sure you're not getting some kind of assembler error.
nesdoug.com -- blog/tutorial on programming for the NES
Post Reply