Help a beginning coder out?
Moderator: ZSNES Mods
-
- Rookie
- Posts: 41
- Joined: Wed Oct 12, 2005 12:34 am
Help a beginning coder out?
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 -.-)
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 -.-)
-
- Rookie
- Posts: 41
- Joined: Wed Oct 12, 2005 12:34 am
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
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.
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.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
-
- Rookie
- Posts: 41
- Joined: Wed Oct 12, 2005 12:34 am
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.
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.
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
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.
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.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
-
- Rookie
- Posts: 41
- Joined: Wed Oct 12, 2005 12:34 am
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.)
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.)
-
- ZSNES Shake Shake Prinny
- Posts: 5632
- Joined: Wed Jul 28, 2004 4:15 pm
- Location: PAL50, dood !
May I suggest 'ignorant' ?Bobbias2.0 wrote:knowledgeless
皆黙って俺について来い!!
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
Code: Select all
<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
-
- Romhacking God
- Posts: 922
- Joined: Wed Jul 28, 2004 11:27 pm
- Contact:
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.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.)
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.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
-
- Rookie
- Posts: 41
- Joined: Wed Oct 12, 2005 12:34 am
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.