Help a beginning coder out?

Strictly for discussing ZSNES development and for submitting code. You can also join us on IRC at irc.libera.chat in #zsnes.
Please, no requests here.

Moderator: ZSNES Mods

Post Reply
Bobbias2.0
Rookie
Posts: 41
Joined: Wed Oct 12, 2005 12:34 am

Help a beginning coder out?

Post by Bobbias2.0 »

Alright, I'm teaching myself some of the nessecary assembly (slowly, but I'm managing) but I'd liek to know if there's anywhere that has some examples of code that say, JUST displays a single sprite, or displays a simple map (specifically, a couple different tiles) and things of this nature.I seem to learn better by taking code, modifying the original, rewriting bits of it to act differently, etc. so I was wondering if I might find some SLIGHTLY more in deapth tutorials/samples. I'd also like to know if there's a reader friendly thing on the assembly for the SNES processor...

Just so you know, I have a basic grasp of the concepts of assembly (well, I'm much better with X86 assembly, but I'll manage once I learn the opcodes for the SNES better.... which is likely to take forever -.-)
Bobbias2.0
Rookie
Posts: 41
Joined: Wed Oct 12, 2005 12:34 am

Post by Bobbias2.0 »

quick addition to the question:
how exactly do all the Branch opcodes work and stuff, I'm pretty n00bish when it comes to assembly, and have no idea how do make conditional jumps, and that sort of stuff here...
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

http://oregonstate.edu/~robinsfr/snes.html

You can start by reading some of the information here.

Branch codes simply change the program counter based on the CPU status flags after an operation.

loop:
lda $23 ;loads Ram address
cmp #$ff ;compares loaded byte to #$ff
bne loop ; branches to loop if contents in accumlator are not equal to $ff. Based on zero flag set by the cmp statement.

end:
rts ;when contents are equal to ff, code execution moves on to this instruction.


That's essentially how they work. BCC and BCS are based on the carry flag after an instruction. There are no rules, you don't HAVE to use a CMP instruction. You can use a branch after ANY instruction so long as the instruction does something with the status flags or else the branch isn't effective.


http://www.slack.net/~ant/nes-emu/6502_tips.txt

This is for NES coding, but it's very similar to SNES coding(most of the same ops) and outlines what I'm trying to say in code better.

Code examples of putting sprites on the screen is actually quite long and you won't find too many of them. I have done this and have some code, but at this stage in the game it isn't going to do much for you.

You need to be familiar with alot of the SNES hardware and registers before it will make any sense.

To display something on the screen, you need to initialize many of the registers, set up the VRAM registers, write some data to VRAM. Set up the palette and tilemap/tiledata. Set the BG and color modes and finally turn the screen on and do your thing.

Here is an example. This will show you how much learning you have yet to do before you're ready to start making any ROMS.

Code: Select all

fade equ $7f3000
pal1 equ $30
pal2 equ $34
scroll equ $36

org $f60000


sep #$20	;8-bit accum
rep #$10	;16-bit reg's
lda #$8f	
sta $2100		;disable screen

stz $210d	;initializes the scroll registers!! 
stz $210d
stz $210e
stz $210e


lda #$01
sta $2105		;set mode 0
lda #$02
sta $210b		;set bg1 tile data address to $2000
lda #$10
sta $2107		;set bg1 tile map address to $1000
lda #$80		;increment after 16-bit write 1 tile
sta $2115		;set vram increment mode
lda #$00
sta $2121   ; Start at color 0.


sta $2121   ; Start at color 0.
lda #$00    ; Color #0 = 00 00 (black).
sta $2122
lda #$00
sta $2122
lda #$1f    ; Color #1 = 00 1F (red).
sta $2122
lda #$00
sta $2122
lda #$00    ; Color #2 = 7C 00 (blue).
sta $2122
lda #$70
sta $2122
lda #$ff    ; Color #3 = 7F FF (white).
sta $2122
lda #$7f
sta $2122
lda #$0d    ; Color #4 = 78 0f (purple).
sta $2122
lda #$78
sta $2122


rep #$20		;16-bit
lda #$2000
sta $2116		;set vram pointer to bg1 tile data
ldx #$0000
ldy #$a000

more:

lda $f60200,x		;test VRAM data

;sep #$20
;jsr vb
;rep #$20

sta $2118		;store in VRAM
inx : inx
dey
cpy #$0000
bne more


lda #$1000		;tile map location
sta $2116		
ldy #$1000
lda #$0000

up:
sta $2118
inc
dey
cpy #$0000
bne up

sep #$20
lda #$01
sta $212c		;enable bg1


lda #$00	
fadein:
jsr vb
sta $2100		;enable screen
ldx #$9fff
up2:
dex
cpx #$0000
bne up2
inc
cmp #$10
bne fadein

lda #$01
sta $4200

lda #$10
sta scroll


jsr vb

joypad:
 lda $4212 
 and #$01  
 bne joypad


lda $4219
and #$10    ; Is the start button pressed?
bne stop    ; Button pressed (bit is 1).
bra joypad

stop:
lda #$0f	

lda #$00
sta pal1

lda #$03    ; Affect planes 0 and 1.
sta pal1
sta $2106
jsr vb
lda pal1
loop:
sta $2106
ldx #$7fff
up4:
dex
cpx #$0000
bne up4
clc
adc #$10
cmp #$F3
bne loop



;fadeout:
;jsr vb
;sta $2100		;enable screen
;ldx #$7fff
;up3:
;dex
;cpx #$0000
;bne up3
;dec
;cmp #$01
;bne fadeout


;bra stop
rtl

vb:
 pha
wait:
 lda $4212
 and #$80
 bne wait
 pla
 rts
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Bobbias2.0
Rookie
Posts: 41
Joined: Wed Oct 12, 2005 12:34 am

Post by Bobbias2.0 »

Thanks for the help, and um... eeep at that code, lol. well, it's nicely organized and isn't as bad as some stuff I've seen... There really do need to be more actual tutorials on how things are done... but I'll manage with what I have. I have some samples that draw some strings to the screen, and do a couple other things, and found some code that is supposed to lpay a specified spc file (basically, you can rip music from a game, and play it in your own easily) and stuff. I'll try to find out how some of the samples work.

EDIT: I guess I shouldn't have double posted there... oh well, and once again, thanks for the help. I'm currently going to try making some basic apps that just manipulate numbers, and program flow and such. then i'll try to figure out the fundamentals of graphics and stuff.
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

A few other helpful tips I can give you.

You'll find many other people initialize alot more registers than I did making the code even larger. During the tests I did during that excersize, those were the minimum amount of registers I needed to initialize to get an image up and running from power on on the REAL SNES(You can get away with even less when running on an emulator).

Initialization can be kind of tricky. It's good practice to initialize ALL the registers on the system, but that's hardly necessary. If you're not going to do them all, keep that in mind for troublehsooting if you run into trouble because it may be as a result of not initializing a register that affects what you are trying to do.

My code was sparesely commented as it wasn't really meant to be a tutorial. If you have any specific questions about some code there, I'll be happy to explain.

It's a good idea to start with manipulation and work up from there. You can use a debugger to see your code being executed and what is actually happening to all the registers. That's extremely useful for somebody learning assembly. Geiger's SNES9x debugger is a good one.

It's also actually a bit more tricky than you might think to make a functional ROM that will run on the SNES or emulator. It needs to have the proper vectors set(especially RESET vector, that's where the code begins execution) at the proper addresses(depending on whether you use Hi-ROM or LoROM etc.)

I didn't demonstrate this in my code because it was a snippet of a hacked start up sequence I made for an existing ROM. All the vectors and addresses were already set.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Bobbias2.0
Rookie
Posts: 41
Joined: Wed Oct 12, 2005 12:34 am

Post by Bobbias2.0 »

Hmm, the one thing I don't quite have a good handle on (information wise) is interrupts and interrupt vectors -.-
I have that Snes9x hack, and it WAS helpful in verifying my BASIC program (first thing I wrote entirely myself) and will definately prove helpful later on as well. I'm currently trying to teach myself the language itself, and get a good handle on it, so I'm using one of those common snesinit includes you see floating around. Don't worry that I won't catch onto many concepts quickly, because if I have one thing that helps me program, it's that I always want to know why something works the way it does, and understand the underlying principles of it, which enables me to understand what is actually being done, as opposed to just knowing "do this and something happens".

hmm, I'd better stop before this changes from mini-rant to a full fledged rant...

But yeah, I have experiance with C++ and Java too, so I'm not entering assembly completely knowledgeless (and I had tried to learn standard X86 assembly earlier as well, and that definately helped.)
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

Bobbias2.0 wrote:knowledgeless
May I suggest 'ignorant' ?
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

Bobbias2.0 wrote:Hmm, the one thing I don't quite have a good handle on (information wise) is interrupts and interrupt vectors -.-
I have that Snes9x hack, and it WAS helpful in verifying my BASIC program (first thing I wrote entirely myself) and will definately prove helpful later on as well. I'm currently trying to teach myself the language itself, and get a good handle on it, so I'm using one of those common snesinit includes you see floating around. Don't worry that I won't catch onto many concepts quickly, because if I have one thing that helps me program, it's that I always want to know why something works the way it does, and understand the underlying principles of it, which enables me to understand what is actually being done, as opposed to just knowing "do this and something happens".

hmm, I'd better stop before this changes from mini-rant to a full fledged rant...

But yeah, I have experiance with C++ and Java too, so I'm not entering assembly completely knowledgeless (and I had tried to learn standard X86 assembly earlier as well, and that definately helped.)
Interrupts are exactly that. Your program is going along fine and all the sudden BAM.. some peice of hardware or trigger goes off that needs the CPU's attention and interrupts the current process.

The CPU says "WTF was that?'.. Finds out it was that caused the interrupt. it finds out the RESET button was pushed. Then the CPU will load the 16-bit 'vector location' and start executing the code there.

Here is more in depth information.
http://www.peekskill.us/project/wikiped ... /Interrupt

http://oregonstate.edu/~robinsfr/docs/e ... 65C816.TXT

This a good document about the 65c816 and SNES. It covers all the Interrupts. The SNES only has 4 possible hardware interrupts and 2 software interrupts(Yes, software can trigger an interrupt as well).

The 'vector locations' are basically another way of saying absolute locations that addresses MUST be at. For example, CPU gets a RESET interrupt. It will ALWAYS grab the address from $FFFC and start program execution at the address pointed to there.

It's the same for the other interrupts, except they point to say $FFEA and grab the address there.

Hope that helps.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
Bobbias2.0
Rookie
Posts: 41
Joined: Wed Oct 12, 2005 12:34 am

Post by Bobbias2.0 »

it does help. I already knew that an interrupt was the whole "hardware event happened, go to this code" and shit, i guess it was more the technical info that I needed in this case, though reading that post will help me out so that I'm not running more on speculation and half-truths and shit. Thanks again for all the help, because I'm seriously interested in getting into the whole homebrew scene.
Post Reply