SNES dev newbie questions

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
juef
Posts: 67
Joined: Thu Jul 15, 2010 8:20 am
Location: Québec, Canada

Re: SNES dev newbie questions

Post by juef »

koitsu: thank you so much for your reply. I do have stz $2121 in Snes_Init but didn't bother recopying the entire contents of the routine as it's mostly the same as in this post, which is a file used by some tutorials I've found...

Oh, I see what you mean for the WaitVBL; I forgot to remove those extra instructions from your above reply in which you polled $4210 rather than wai. As for the stp, thank you, that's interesting. I will probably stick to the loop however as I intend to have a main, endless loop in there eventually.

Still, after making those changes and rechecking everything, I still can't seem to change the color. Any clue on why that wouln't work?

DoNotWant: that would be very kind of you! Here you go.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SNES dev newbie questions

Post by tepples »

Disclaimer: I too am a Super NES noob although with NES experience.
koitsu wrote:You really should turn on NMI when VBlank fires, otherwise your wai in WaitVBL doesn't serve a purpose.
True. But isn't it a good idea to disable NMI during the init code and reenable it afterward to make sure the NMI handler doesn't mess things up?
you could replace that whole thing with just wai ; rts and be done with it
Possibly, although with other things turned on, it might just end up waiting for the scanline number to equal VTIMEL ($4209).
User avatar
benjaminsantiago
Posts: 84
Joined: Mon Jan 20, 2014 9:40 pm
Location: Astoria, NY
Contact:

Re: SNES dev newbie questions

Post by benjaminsantiago »

I've found that leaving register $4200 at zero will work on really lenient emulators like ZSNES, but won't work for BSNES, SNES9x or on the real hardware, had to learn that the HARD way...heheh...sorry. If you play with the interrupt tables and the routines they call, I think you'll have a more intuitive understanding of how they work.

It is also worthwhile to look at the actual SNES Developer manual:
http://www.romhacking.net/documents/226/

It was useful for me trying to do some HSYNC effects that required specific settings, which the SNES DEV Manual covers that were helpful to know. Here is where I got in case you are curious:

https://vimeo.com/85569649

Experiencing some hardware-specific graphic anomalies and I still haven't gotten the counters to work with any specificity (ie setting specific H or V Counter variables), but this seems to be working consistently enough for me.

With regard to changing the color, I believe you do need $2121 before you specify the color. Think about it this way, the SNES needs to know the index of the color that you want to change the value of. Only the zeroth color is the "bg" color unless you create tiles and specify color indices within them. If you were setting the palette you would need to know index number then color. You'd need to stz $2121 each time you try to change the color.

It is for WLA, but check out bazz's code:
http://wiki.superfamicom.org/snes/show/ ... ES+Program

I've done something similar trying to get a "rainbow effect" based on bazz's code. I had to specify stz $2121 each time:

http://instagram.com/p/iXay-ZP9T0

I am at work right now, but I can upload this later if it helps.
User avatar
benjaminsantiago
Posts: 84
Joined: Mon Jan 20, 2014 9:40 pm
Location: Astoria, NY
Contact:

Re: SNES dev newbie questions

Post by benjaminsantiago »

tepples wrote:True. But isn't it a good idea to disable NMI during the init code and reenable it afterward to make sure the NMI handler doesn't mess things up?
I'm not sure all the specifics of how the NMI handler works, but I think it would technically be "okay" if the screen is off and you know you aren't calling any interrupts.

If it was messing things up, I'm sure you'd start to see it in a larger program (ie game)
DoNotWant
Posts: 83
Joined: Sun Sep 30, 2012 3:44 am

Re: SNES dev newbie questions

Post by DoNotWant »

First time using dropbox, so I hope I did this right.
https://www.dropbox.com/s/o7hqzji3d0kl1vz/BASS.rar

Basically, I changed ; to // for comments, changed the header, added a macro, and removed
some stuff. The macro takes a CPU address, which it turns into a ROM address.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: SNES dev newbie questions

Post by koitsu »

tepples wrote:
koitsu wrote:You really should turn on NMI when VBlank fires, otherwise your wai in WaitVBL doesn't serve a purpose.
True. But isn't it a good idea to disable NMI during the init code and reenable it afterward to make sure the NMI handler doesn't mess things up?
Yes, which is why it should be enabled prior to the rest of his routines, which is what my statement was implying. I'm seriously not going to sit around writing code for people. :P
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: SNES dev newbie questions

Post by koitsu »

juef wrote:koitsu: thank you so much for your reply. I do have stz $2121 in Snes_Init but didn't bother recopying the entire contents of the routine as it's mostly the same as in this post, which is a file used by some tutorials I've found...
Look closely at your own code, and slow down. Think slowly.

Code: Select all

Snes_Init

...
lda   #%11100000
sta   $2122
lda   #%00000011
sta   $2122
...
This effectively is setting the RGB value of colour #0 to whatever you've assigned via $2122 (I do not care to decode the BGR values right now, it's not the point). The reason it's affecting colour #0 is because you did stz $2121 in Snes_Init (which is correct/fine).

Now look a few lines forward, where you do this -- WITHOUT setting/touching $2121 prior:

Code: Select all

...
lda   #%00011111
sta   $2122
lda   #%00000000
sta   $2122
...
What this is affecting is colour #1 in the palette, not colour #0 like you might think. This is because you didn't re-set/change $2121.

Basically what I'm saying is this, speaking using code:

Code: Select all

stz $2121    ; Next writes to $2122 affect colour #0

lda #$whatever
sta $2122
lda #$whatever
sta $2122

lda #$whatever  ; These writes affect colour #1
sta $2122
lda #$whatever
sta $2122

lda #$whatever  ; These writes affect colour #2
sta $2122
lda #$whatever
sta $2122

...
Make sense? So you need to set $2121 to the colour you want to modify before touching $2122.
User avatar
juef
Posts: 67
Joined: Thu Jul 15, 2010 8:20 am
Location: Québec, Canada

Re: SNES dev newbie questions

Post by juef »

koitsu wrote:What this is affecting is colour #1 in the palette, not colour #0 like you might think. This is because you didn't re-set/change $2121.
... oh! I had not realized that $2121 incremented after a write... I guess more doc reading is in order. Thank you very much once again for the very helpful reply, I got it working now.
DoNotWant wrote:Basically, I changed ; to // for comments, changed the header, added a macro, and removed
some stuff. The macro takes a CPU address, which it turns into a ROM address.
This does seem to work, thank you!
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: SNES dev newbie questions

Post by koitsu »

juef wrote:... oh! I had not realized that $2121 incremented after a write... I guess more doc reading is in order. Thank you very much once again for the very helpful reply, I got it working now.
Most PPU operations on the SNES work this way (and on the NES too). It's done for good reasons and is a life-saver when needing to send lots of data to the PPU sequentially/linearly. Happy coding!
User avatar
juef
Posts: 67
Joined: Thu Jul 15, 2010 8:20 am
Location: Québec, Canada

Re: SNES dev newbie questions

Post by juef »

Thanks again to everyone, I have been having a lot of fun playing around with SNES code. I was surprised how little time it took to find a case where emulation accuracy mattered! The SNES initialization routine I was using didn't clear VRAM properly, so while most emulators (including bsnes v077 and older) loaded my ROM "beautifully", more recent versions of bsnes/higan and real hardware showed junk aplenty.

Anyway, I have a few more quick questions. I have been trying to implement the most basic detector of MSU1 presence, unsuccessfully so far. Super Road Blaster's source helped a lot, but I'm missing something.
  • byuu's page on MSU1 specifications uses a memory mapping notation ($00-3f,80-bf:2000-2007) I'm not familiar with, despite some Googling. I would greatly appreciate some help with this.
  • Would a simple lda $2002 placed shortly after my SNES initialization routine read the first MSU1 presence identifier, or there is some... special magic to do before?
Thank you very much!
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 521
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: SNES dev newbie questions

Post by Jarhmander »

juef wrote:
  • byuu's page on MSU1 specifications uses a memory mapping notation ($00-3f,80-bf:2000-2007) I'm not familiar with, despite some Googling. I would greatly appreciate some help with this.
Wild guess here, but $00-$3F and $80-$BF looks like bank address (upper 8 bits of 24-bit address).

EDIT: Yes, it is. From fullsnes (nocash):

Code: Select all

Overall Memory Map
  Bank    Offset       Content                                      Speed
  00h-3Fh:0000h-7FFFh  System Area (8K WRAM, I/O Ports, Expansion)  see below
  00h-3Fh:8000h-FFFFh  WS1 LoROM (max 2048 Kbytes) (64x32K)         3.58MHz
     (00h:FFE0h-FFFFh) CPU Exception Vectors (Reset,Irq,Nmi,etc.)   3.58MHz
  40h-7Dh:0000h-FFFFh  WS1 HiROM (max 3968 Kbytes) (62x64K)         3.58MHz
  7Eh-7Fh:0000h-FFFFh  WRAM (Work RAM, 128 Kbytes) (2x64K)          3.58MHz
  80h-BFh:0000h-7FFFh  System Area (8K WRAM, I/O Ports, Expansion)  see below
  80h-BFh:8000h-FFFFh  WS2 LoROM (max 2048 Kbytes) (64x32K)         max 2.68MHz
  C0h-FFh:0000h-FFFFh  WS2 HiROM (max 4096 Kbytes) (64x64K)         max 2.68MHz
The MSU maps in the system area as it should. The $2000-$20FF is unused and free to use by any expansion.
((λ (x) (x x)) (λ (x) (x x)))
User avatar
juef
Posts: 67
Joined: Thu Jul 15, 2010 8:20 am
Location: Québec, Canada

Re: SNES dev newbie questions

Post by juef »

Thank you for your reply! I see that it's indeed unused, but I'm not quite sure if I understand correctly: if $00-$3F and $80-$BF are bank addresses, does that mean that there are actually 128 banks on which the MSU1 registers are mirrored? That sounds quite a lot to me, so I guess I got something wrong.

Also, if $002002-$002008 is a correct address for reading the MSU1 presence identificator, I must be doing something terribly wrong because I couldn't read these bytes correctly to save my life. Aside from Neviksti's InitSNES file, I barely have any code and yet can't manage to read those bytes as identified by snes9x's debugger's RAM viewer. The code below, which basically seems to loop through the 6 bytes to check, is mostly taken from the Super Road Blaster source:

Code: Select all

.define MSU_ID $2002	; 2002-2007 must return "S-MSU1"

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

	Start:
		InitSNES
		
		rep #$31
		sep #$20
		ldx.w #0
		l1:	lda.l MSU_ID,x
			cmp.l msu1HardwareIdentifier,x
			bne NoMSU1
			inx
			cpx #msu1HardwareIdentifier.end-msu1HardwareIdentifier
			bne l1

...

.Section "msu1HardwareString" superfree
	msu1HardwareIdentifier:
		.db "S-MSU1"
	msu1HardwareIdentifier.end:
.ENDS
I have a last question for today. During the InitSNES routine (again from Neviksti), there's STA $420B, which clears some memory by doing a DMA transfer, from what I understand. Somehow, the snes9x debugger tells me that this single instruction clears $002000-$0020FF (among other addresses) completely. If theses addresses are what I think they are, is there any reason for clearing them (aren't they unused?)?.

Thank you again for your help and patience!
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: SNES dev newbie questions

Post by Near »

> if $00-$3F and $80-$BF are bank addresses, does that mean that there are actually 128 banks on which the MSU1 registers are mirrored? That sounds quite a lot to me

Yes, that's how the SNES works. Same deal for all your regular registers, $2100 and such. It's a problem when DBR.d6 is set, eg: lda #$40; pha; plb; stz $2100 <- does not write to display register, as $402100 is not an MMIO region, it's a CART (ROM) address.

> Also, if $002002-$002008 is a correct address for reading the MSU1 presence identificator, I must be doing something terribly wrong because I couldn't read these bytes correctly to save my life.

With higan v094, you need a manifest.bml file to specify that the MSU1 is present. With sd2snes, you need a gamename.msu file to specify that it's present.
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: SNES dev newbie questions

Post by koitsu »

Please just post the code to this InitSNES routine. I'm getting a little tired of it continually coming up in every post without seeing the actual code (not to mention what you brought up initially was called Snes_Init, now you're using something called InitSNES). If I review it and I see nothing wrong with it (going purely off of what official documentation mandates), then I really couldn't care less what an emulator "claims" it's doing in this particular case.
User avatar
juef
Posts: 67
Joined: Thu Jul 15, 2010 8:20 am
Location: Québec, Canada

Re: SNES dev newbie questions

Post by juef »

Thank you byuu, this is very helpful.
koitsu wrote:Please just post the code to this InitSNES routine. I'm getting a little tired of it continually coming up in every post without seeing the actual code (not to mention what you brought up initially was called Snes_Init, now you're using something called InitSNES).
I'm sorry about not having posted it; I had figured the code was generally considered OK since it is used in different tutorials and written by "big names" of emulation, but you're right, that's definitely not a good assumption to make, and switching between the two files can be confusing. I used Snes_Init.asm first from this tutorial, but found it was missing stuff, so I switched to InitSNES.asm from these tutorials. You can download all my current project files here.

Again, I'm sorry for not posting everything before; I thought I'd try to post the most relevant code only so that reading my posts isn't too much of a chore. I'll post the whole thing from now on. Please forgive my language as well, I'm not very used to write in English.
Post Reply