+  RHDN Forum Archive
|-+  Romhacking
| |-+  General Romhacking
| | |-+  New to ASM, not new to programming...
Pages: [1]
Author Topic: New to ASM, not new to programming...  (Read 705 times)
vglover
Guest
« on: January 09, 2007, 12:52:44 pm »

Well, I have some knowledge of programing languages (PHP,MySQL,HTML,CSS) and now I want to learn Asembly. I know a little of hexadecimal (how to convert to decimal without using a calculator). And I decieded I want to learn ASM, atleast for NES or GB games.

I have read tutorials but they are no help. What I want to know how to do is:

1.  Find level data, know where are levels located etc... on games.
2.  Know how to expand a rom, add extra content to it. (On GB, I read on NES is almost impossible).


Yeah, not to much. If its possible I want to do that on the GameBoy, but I am ok with NES/SNES.
Ryusui
Guest
« Reply #1 on: January 09, 2007, 03:24:26 pm »

Some programming languages are called ASM.
ASM is not exactly a programming language.


Forgive the Homestar Runner joke, but it's basically true: ASM is not so much a language as a catch-all term for the myriad sets of processor-specific operation mnemonics. Like programming languages in the higher-level sense, basically all forms of ASM can do similar things, just with slightly different syntax and semantics, but in this case, ASM translates directly into machine code. All a basic assembler really does is turn the little leet-speak abbreviations like MOV or LDA or ASL into the equivalent numbers the processor (or emulator thereof) comprehends. It's really kinda cool when you get down to it. My earliest ASM hacks involved hand-assembled machine code.

Now, if you've found general ASM tutorials but they didn't help, that's because ASM knowhow (which is readily retooled for different platforms) is separate from hardware knowhow. That is, you can write a program in ASM, but that doesn't mean you know how to access the graphics hardware or memory mappers or joystick inputs or anything on an actual system. And we've got documents for that sort of thing.

Anyways, here's what you want to look for.

1. This will involve a debugger. I recommend FCEUXD for NES games, BGB for Game Boy, VBA-SDL-H used in tandem with VBA for GBA titles, and Geiger's SNES9X Tracer used alongside vSNES for SNES games. The first step, or so I figure it, is to set a breakpoint on where the tile map data is stored. If you don't know what a tile map is, I suggest you brush up on the basics of game system graphics. If you don't know what a breakpoint is, you need to brush up on the basics of software debugging. Anyways, once you've figured out what instruction writes the map data to VRAM, work backwards from there and find out where the map data is coming from to begin with. That's your start. No clue as to the rest; I've never had reason to do it myself. ^_^;

2. On NES, it's crazy-hell. On GB and SNES, it's much simpler, although only "easy" should the stars align just right. And on GBA, it's a freakin' no-brainer. See, what the NES, GB and SNES have in common is that they can only see a small "window" of a game ROM at a time. Those windows are called "banks". Now, NES games have a bunch of different mappers that are used to determine which memory addresses come out to which ROM addresses at a given time, and expanding a ROM usually involves reprogramming a game to use a different mapper. Yes, "reprogramming". On GB and SNES, it's the same thing, except there are only a handful of different mappers for GB, only two real ones for SNES, and none of them have the issue that kills expansion on the NES: the hardware expects the "PRG ROM" to be located in a certain place, and changing the size means changing the PRG's position and everything that points to it. So anyways, you can change a GB or SNES ROM's size without having to rewrite the whole freakin' game, but getting the game to recognize your new data can be trying: in all three cases, you will likely have to add code to store the current bank, change it to point to your new data, then restore the original bank after you're done. On GBA...well, the entire ROM can be addressed at once, so no more banks! Woo-ha!

Hope this is some help.

Some programming languages are talkin' animals.
ASM will get what it deserves.
creaothceann
Guest
« Reply #2 on: January 09, 2007, 03:38:00 pm »

Btw. a tilemap is just a 2-dimensional table in memory (e.g. Video RAM) that stores the attributes of each tile in a background layer. (For example,  the SNES has support for 4 background layers.)

The attributes can decide the tile index, the tile's section of the global palette, if the tile is horz./vert. mirrored and so on. Tiles are stored in VRAM and can be in various color depths (bitplanes).
KingMike
Guest
« Reply #3 on: January 09, 2007, 04:28:30 pm »

For the NES, you only have to change the mapper if the ROM was already at the limit.
To expand PRG, you have to double the PRG-ROM size, but it has to be added before the last 16KB of PRG.
(might be 8 on some mappers, but I move the last 16KB to be safe).
(so if the game had 128KB of PRG, I'd copy the 128KB of PRG (just to be safe), then I'd put in 112KB of blank space, followed by the last 16KB of PRG (again, to be safe).
The NES doesn't know the data's moved, since most mappers expect the last 8 or 16KB of CPU address space to represent the last 8 or 16KB of the PRG ROM. And the rest of the data hasn't moved.
I've swapped banks I was in before, just have to realize where you are relative to the current bank, and continue your code in the same position in the new bank.
So, like if STA $8000 is the code to swap a PRG bank, and the command STA $8000 is $500 bytes into the bank A, and you are swapping bank B in, you'll want to continue your code at $503 bytes into bank B.
Trouble is finding a place where you can safely insert a 5-byte long bankswap command (typically a 2 byte LOAD followed by a 3 byte STORE) (and the game may also store a variable that says what ROM bank is stored in each swappable bank)

(only exeptions I've seen are Namcot 106 (mapper #19), which expects extra ROM space at the beginning for some reason, and if expanding a MMC1 (mapper #1) PRG ROM to 512KB or more. With more than 256KB PRG, all bankswaps will be relative a 256KB portion of the ROM. So you'll have to write to an extra register to set which 256KB chunk is "active".
vglover
Guest
« Reply #4 on: January 09, 2007, 05:25:18 pm »

Hmm, I didn't get all that, just some parts... But now I know what things do I need to mess with to do stuff.

So for example, when I'm on level 1 of a game, the data of where are the tiles located, level offset,etc will be stored on the VRAM of the game? So all I do is, check from where is the data comming and I have the offsets of where are levels located?

And for expanding, I really hoped adding a lot of 00's would work Wink

Man I wish ASM was *english*, like PHP...

EDIT: OMG, that really works Cheesy. I already know where the speed of the time in wario land 3 is!! ^_^ I changed a value and now the timer goes faster.. ^_^.

EDIT2: Ok, I think I am getting this. Now I was able to add another item box on the first level of wario land 3, but, it acts as an empty tile and disappears when I leave the screen, I did that by looking at the VRAM and editing with a hex editor, so, do I need to do something else before I can make it act as a block? Is that data stored somewhere else?
« Last Edit: January 09, 2007, 05:52:56 pm by vglover »
creaothceann
Guest
« Reply #5 on: January 09, 2007, 06:24:30 pm »

Quote from: vglover on January 09, 2007, 05:25:18 pm
So for example, when I'm on level 1 of a game, the data of where are the tiles located, level offset,etc will be stored on the VRAM of the game? So all I do is, check from where is the data comming and I have the offsets of where are levels located?

Actually, games store the level map in their own format somewhere in the ROM.


Quote from: vglover on January 09, 2007, 05:25:18 pm
Now I was able to add another item box on the first level of wario land 3, but, it acts as an empty tile and disappears when I leave the screen, I did that by looking at the VRAM and editing with a hex editor, so, do I need to do something else before I can make it act as a block? Is that data stored somewhere else?

I think you just changed the tilemap in VRAM. Sort of like changing a game's geometry data in the graphics card's VRAM, but not on disk. As soon as it gets reloaded, your changes will be overwritten.
vglover
Guest
« Reply #6 on: January 09, 2007, 06:28:04 pm »

Ok, so what exactly do I need to edit to change the level objects? I now know is in the rom, the debugger tells me from where its reading the data or something but, it wont help. Also, on the VRAM viewer it says something of "Tile address: 0:92D0"
And a "Map address" I edited the map address because it was simpler but the tile address, I dont get that, is it "92D0" only?
RedComet
Guest
« Reply #7 on: January 09, 2007, 06:53:32 pm »

You'll have to use BSNES v0.13 (it's on the site in the utilities section) for setting a breakpoint in VRAM. Does anyone know how to set a VRAM breakpoint in Geiger's SNES9X?
KingMike
Guest
« Reply #8 on: January 09, 2007, 10:33:58 pm »

Quote from: vglover on January 09, 2007, 06:28:04 pm
Ok, so what exactly do I need to edit to change the level objects? I now know is in the rom, the debugger tells me from where its reading the data or something but, it wont help. Also, on the VRAM viewer it says something of "Tile address: 0:92D0"
And a "Map address" I edited the map address because it was simpler but the tile address, I dont get that, is it "92D0" only?

You mentioned Wario Land 3... so GB.
On GB, if it reports $0:92D0 as the address it's read from, that is somewhere in VRAM.
This is a basic memory map of the GB. (what each of the 65,536 possible addresses the GB CPU can reference means)
$0000 - $3FFF = First 16KB of ROM.
$4000 - $7FFF = Switchable ROM bank(s).
$8000 - $9FFF = VRAM
$A000 - $BFFF = cart RAM (?)
$C000 - $DFFF = system RAM
$E000 - $FFEF = mirror of system RAM, I think this supposed to be assumed undefined.
$FF00 - $FFFF = hardware I/O

(memory maps will vary greatly with the system)
Here's NES:
$0000-$07FF = system RAM
$2000-$2007 = video I/O (VRAM is indirectly accessed by reading/writing to addresses in this range)
$4000-$4017 = sound, controller I/O
$6000-$7FFF = usually refers to cart RAM
$8000-$FFFF = 32KB ROM
(other areas should be presumed undefined)
(on NES, games with more than 32KB ROM will use a cart board that will partition that space into 2, 3, or 4 pieces, and switch which part of the ROM is accessed.)
(as you can see, it'd be a good idea to focus on one system)
Ryusui
Guest
« Reply #9 on: January 09, 2007, 11:11:41 pm »

Note also that while every possible address on GB can be used, the same cannot be said for the NES (or SNES, IIRC).
Disch
Guest
« Reply #10 on: January 10, 2007, 01:44:47 am »

Also note that even the NES's memory map is not carved in stone (as $4020 and up can be controlled/altered by the mapper).  So the memory map as well as expansion rules may vary on the NES.  Though the info KingMike gave you is the case 99% of the time.
vglover
Guest
« Reply #11 on: January 10, 2007, 08:21:05 am »

Maybe I forgot to menction, but I have no idea what a breakpoint is ;_; Any tutorials or docs made about that?
RedComet
Guest
« Reply #12 on: January 10, 2007, 08:34:07 am »

http://www.gamedev.net/reference/programming/features/debugging/

It's not for ASM specifically, but the concepts are the same.
Nightcrawler
Guest
« Reply #13 on: January 10, 2007, 09:33:07 am »

Quote from: RedComet on January 09, 2007, 06:53:32 pm
You'll have to use BSNES v0.13 (it's on the site in the utilities section) for setting a breakpoint in VRAM. Does anyone know how to set a VRAM breakpoint in Geiger's SNES9X?

No. I don't think you can in Geiger's. I usually scan a trace file for loading the VRAM source offset before a manual VRAM transfer or DMA register setup for VRAM transfer.

Generally though, I don't need to look for things getting stuck in VRAM too often. I usually have figured out a RAM location or ROM location of the source data.
Ryusui
Guest
« Reply #14 on: January 10, 2007, 02:22:59 pm »

A breakpoint is a debugging tool where you set the program to halt execution when certain conditions are met. A good debugger will have both execution breakpoints (i.e. halt on a specified instruction) as well as memory breakpoints (halt when a certain memory address is read from or written to; some debuggers will also allow you to specify a particular value, or a range of addresses).

Basically, you use them when you know the game does something, but you don't know how it does it. Sort of like the shoemaker rigging a security camera to trigger when somebody steps on the bench, allowing him to catch the elves in the act. >_>
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC