snes assembly - beginnings, a few questions (wla-65816)

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

I started trying to write something on the SNES and I have some questions:

Following the example of the VRAM map (https://nesdoug.com/2020/05/16/backgrounds/), I decided to make an identical one and I don't know how to set the TileSet 2BPP address for BGR3 in MODE1 to $ 3000 ??

VRAM MAP
$0000 4bpp BG tiles (768 of them)
$3000 2bpp BG tiles (512 of them) ; ???????
$4000 4bpp sprite tiles (512 of them)
$6000 layer 1 map (up to 2 screens)
$6800 layer 2 map (up to 2 screens)
$7000 layer 3 map (up to 2 screens)
$7800 layer 4 map (up to 2 screens)

From what I noticed, this is setting the TileMap base address for BGR3:

LDA #%00000011 ; writing $03 set $6000 VRAM addres, %0000 = $0000, %0001 = $2000, %0010 = $4000
STA $210C

But how do I set a $ 3000 address here?

Another question is how to read LOW / HIGH byte from label address (variable in frame or label in ROM) in WLA-DX?

In the case of a label in RAM, this is not a problem, because you can enter the address manually (e.g. $ 1C00)
sample code sending oam buffer to OAM:

Code: Select all


OAM_BUFFER: .res 512		; low table (wram $1C00)
OAM_BUFFER2: .res 32		; high table

(...)

	LDX #$0000
	STX $2102						; OAM address

	STZ $4300						; transfer mode 0 = 1 register write once

	LDA #4							; $2104 oam data
	STA $4301						; destination, oam data

;	LDX #$00
;	STX $4302						; source LOW (LOW/HIGH/BANK-> $4302/$4303/$4304) - adres 00x1C00
;	LDA #$00
;	STA $4303						; source HIGH
;	LDA #$00
;	STA $4304						; source BANK

	LDX #$1C00
	STX $4302

;	LDX #$20
;	STX $4305						; length LOW (LOW/HIGH/BANK-> $4305/$4306/$4307) - adres 00x0220 (#544)
;	LDX #$02
;	STX $4305						; length HIGHT (LOW/HIGH/BANK-> $4305/$4306/$4307)
;	LDX #$00
;	STX $4305						; length BANK (LOW/HIGH/BANK-> $4305/$4306/$4307)

	LDX #544
	STX $4305						; length (LOW/HIGH/BANK-> $4305/$4306/$4307)

	LDA #1
	STA $420B						; Start dma, channel 0

ca65:

Code: Select all

LDX #.loword(OAM_BUFFER)
STX $4302				; source (H/L $4302/$4303)

LDA #^OAM_BUFFER
STA $4304				; bank
How to read it in WLA?

Code: Select all


	LDA #<OAM_BUFFER						; get LO
	STA $4302
;	LDA #>OAM_BUFFER						; get HIGH (IN 16-BIT MODE A - I don't have to read HIGH anymore?)
;	STA $4303
	LDA #$00						; bank 00 (set manually - I don't know how to read the bank from this label?)
	STA $4304

Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by Oziphantom »

tile sets are 4K word aligned($1000), so to set it to $3000 you should set it to $03. Note that if you are using MESEN-S it always reports addresses in bytes not words and that will trip you up a lot. i.e $3000 word is $6000 byte.

WLA-DX uses the "standard" format for lo, hi which is

Code: Select all

< = Lo byte
> = hi byte
: = bank
but as far as I know doesn't have a word split feature.
So you get the low word you force the instruction to 16bits

Code: Select all

LDX.W #OAM_BUFFER
STX $4302
LDA #:OAM_BUFFER
STA $4304
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

Ok everything is clear, both MESEN-S and BSNES-PLUS show VRAM address in the range 0000-FFFF ... :) I didn't pay attention to it.

Quick question: Can joypad registers be read outside the VBLANK (NMI), e.g. in the CPU loop? In the example tutorials, I always see the joypad reading code in VBlank.
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by Pokun »

The quickest method to read joypads is using the auto-reading function which always happens in vblank.
But you can also read manually using $4016 and $4017. This works exactly like on the NES.
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

I don't know if I'm doing it correctly, but it works - even it seems too simple and doesn't read $ 4016 at all ...? That's all it takes to read the pads ??

Code: Select all

ram:

	JOYPAD1L	DB				; BIT7 <- A, X, L, R, ?, ?, ?, ? <- BIT0
	JOYPAD1H	DB				; BIT7 <- B, Y, Select, Start, Up, Down, Left, Right <- BIT0


enable pad:

	LDA #%10000001					; Enable NMI and Enable Joypad
	STA $4200


main game loop:

	LDA $4218
	STA JOYPAD1L
	LDA $4219
	STA JOYPAD1H

example read UP:

	LDA JOYPAD1H
	AND #%00001000
	BEQ noUP

	; move thing up

noUP:
0x4218 Joypad 1 Data (Low Byte) abcd0000 a = Button A b = X c = L d = R
0x421a Joypad 2 Data (Low Byte)
0x421c Joypad 3 Data (Low Byte)
0x421e Joypad 4 Data (Low Byte)
0x4219 Joypad 1 Data (High Byte) abcdefgh a = B b = Y c = Select d = Start efgh = Up/Dn/Lt/Rt
0x421b Joypad 2 Data (High Byte)
0x421d Joypad 3 Data (High Byte)
0x421f Joypad 4 Data (High Byte)
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by Pokun »

Yeah that looks right to me. That's what is called auto-reading. You enable it by setting bit 0 of $4200 and it will automatically read the controllers every vblank and store the results in $4218 (controller 1), $421A (controller 2), $421C (controller 3) and $421E (controller 4).

You can use 16-bit access so you don't have to read and write twice per controller.

Code: Select all

ram:
	JOYPAD1	DB 2				;16-bit RAM register for all buttons

main:
;Index registers must be set to 16-bit.
	LDX $4218
	STX JOYPAD1
You may also want to add this:

Code: Select all

wait:
  lda $4212
  and #$01
  bne wait       ;wait until controller auto-read is complete
  
  ldx $4218
  stx JOYPAD1    ;read controller 1
  ldx $421A
  stx JOYPAD2    ;read controller 2
This is to make sure that the auto-reading hardware had time to finish reading the controllers in last vblank.


$4016 and $4017 are only used if you don't want to use auto-reading for any reason. It might be necessary if you use some special peripheral, but normally you shouldn't need to bother. Let the hardware do it for you.
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

Ok, I thought bit0 was generally JoyPad Enable, which is sometimes confusingly labeled "Jopad / JoyPad Enable" and actually means "Auto-Read JoyPad Enable".
0x4200 NMI, V / H Count, and Joypad Enable a0bc000d a = NMI b = V-Count c = H-Count d = Joypad

Out of curiosity, I am interested in the manual reading.
I read 4016 - the code works, it reads some buttons (B, Y, Select, Start, Up, Down, Left, Right <- Bit0) - the question is how the rest is read, because 4016 is one byte, not two and I wonder how read the other buttons? (Unless the 4017 is not just a Pad2 reading but is an extension of the 4016?)

Code: Select all

PadButtons			DB		; Bit7 <- B, Y, Select, Start, Up, Down, Left, Right <- Bit0
PadButtons_Held			DB
PadButtons_Press		DB

Code: Select all

	LDA PadButtons
	STA PadButtons_Held

	LDA #$01
	STA $4016
	LDA #$00
	STA $4016

	LDX #$08

ReadPadLoop:

	LDA $4016
	LSR A
	ROL PadButtons
	DEX
	BNE ReadPadLoop

	LDA PadButtons	
	EOR PadButtons_Held
	AND PadButtons
	STA PadButtons_Press
Oziphantom
Posts: 1565
Joined: Tue Feb 07, 2017 2:03 am

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by Oziphantom »

you need to loop 16 times well only 12 actually I guess not just 8 as per the NES.
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

Please correct me if I understand correctly - For example, I have MODE1, BG1 / BG2, I have 4bpp and BG2 in 2bpp - BG3 uses the same color palettes as BG1 / 2 but only the first 4 colors? When planning to use a BG3 as background, do I have to remember that its colors should be set in the first colors of each palette?

Is it possible for MODE1 BG3 to be visible before BG1 / 2, i.e. to have a higher priority? I thought bit3 $ 2105 would control this, but it doesn't.
0x2105 BG Mode and Tile Size Setting abcdefff abcd = BG tile size (4321): 0 = 8x8 1 = 16x16, e = BG 3 High Priority, f = BG Mode
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by Pokun »

No that sounds wrong to me.
Mode 1 implies 4bpp for BG1 and BG2 while BG3 is 2bpp.
In Mode 1, BG1 and BG2 both uses the whole 128 color BG palette (8 subpalettes which each has 15 colors + transparent), while BG3 only uses the first 32 colors of the BG palette (8 subpalettes which each has 3 colors + transparent). So all 3 backgrounds have overlapping colors with each others.

Bit 3 of $2105 should give BG3 priority over the other two, are you sure it doesn't? BG3 is typically used as a HUD by the use of this flag.
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

As for BG1, BG2 in 4bpp, I know that you can use 8 sub-palettes, 16 colors per one (I omit color 0). Apparently, I misunderstood how the BG3 palette works in 2bpp because I thought it also uses 8 sub-palettes but only the initial 4 colors of each (excluding color 0).

So BG3 (2bpp) uses "TWO" whole sub-palettes (32 colors) - divided into four parts of 4 colors each? (32 divided into 4, so for one TILE you can choose 4 "four color" palettes) ?
Pokun
Posts: 2681
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by Pokun »

No, BG3 uses 8 sub-palettes with 4 colors each (or rather 3 colors + transparent of course) like I said.
4 x 8 = 32

I think your definition of sub-palette might be different from mine. What I mean by sub-palette changes with bit depth. Since Mode 1 BG3 uses a bit depth of 2bpp, it uses 4-color sub-palettes instead of the 16-color sub-palettes that BG1 and BG2 uses in Mode 1 since their bit depth are 4bpp.
A sub-palette is thus whatever the number of colors that a single character uses for the same BG layer.

If you are talking in terms of 16-color sized sub-palettes, then yes you could say BG3 uses 2 of them, but remember that a BG3 character can only use 4 colors since it's 2bpp (just like on NES).
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

What I mean:

4BPP PAL0 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
4BPP PAL1 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
4BPP PAL2 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
4BPP PAL3 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
4BPP PAL4 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
4BPP PAL5 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
4BPP PAL6 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
4BPP PAL7 - COL00,COL01,COL02,COL03,COL04,COL05,COL06,COL07,COL08,COL09,COL10,COK11,COL12,COL13,COL14,COL15
This is 8 Sub-Palettes for BG1/BG2 when there are 4bpp in MODE1

Now, when I want to set a pallet for BG3 2bpp Tiles, I use 8 palettes:

2BPP PAL0 COL00,COL01,COL02,COL03 - The first 4bpp Palette divided into 4 2bpp (COL00,04,08,12,16 - will be COLOR 0)
2BPP PAL1 COL04,COL05,COL06,COL07
2BPP PAL2 COL08,COL09,COL10,COL11
2BPP PAL3 COL12,COL13,COL14,COL15
2BPP PAL4 COL00,COL01,COL02,COL03 - Second 4bpp Palette divided into 4 2bpp (like abowe COL00,04,08,12,16 - will be COLOR 0)
2BPP PAL5 COL04,COL05,COL06,COL07
2BPP PAL6 COL08,COL09,COL10,COL11
2BPP PAL7 COL12,COL13,COL14,COL15

I don't know if I understood correctly
Last edited by sdm on Sun Mar 20, 2022 2:01 am, edited 1 time in total.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by dougeff »

Bit 3 of $2105 should give BG3 priority over the other two, are you sure it doesn't? BG3 is typically used as a HUD by the use of this flag.
You also need to set the priority bit on the individual tiles on the BG3 map. (Only the tiles you want in front of everything else)
nesdoug.com -- blog/tutorial on programming for the NES
sdm
Posts: 412
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: snes assembly - beginnings, a few questions (wla-65816)

Post by sdm »

That's right. Thanks. Now it is working.


In 16-bit A mode, will Carry jump to AddrHI automatically in this case? :

Code: Select all

AddrLO	DB                  ; wram
AddrHI 	DB

	REP #$20						; Sets A to 16-bit mode

	LDA AddrLO						; carry will jump into AddrHI increasing its value? (when the addition exceeds the 1-byte value)
	CLC
	ADC temp
	STA AddrLO

;	LDA AddrHI						; 6502
;	ADC #0
;	STA AddrHI

	SEP #$20
I'd like to make sure: about addressing - does LONG mean 24-bit 00x0000 a not-LONG 16-bit addressing 0000 ??

Code: Select all

Indirect, Y

LDA ($12), Y – same as Indirect, but the indirect address is added to the Y register to get a final address to load to A from.

Indirect Long, Y

LDA [$12], Y – same as Indirect Long, but the indirect long address is added to the Y register to get a final address to load to A from.
Post Reply