Sei sulla pagina 1di 7

,--------------------------------. | ASM Hacking for Dummies - v1.0 | | by SysTEm[id] | | http://id.dragonfire.net | `--------------------------------' Table of Contents -------------------------------------------------------------------------1.0 2.0 3.0 4.

0 4.1 5.0 5.1 5.2 6.0 6.1 7.0 8.0 9.0 9.1 Introduction About the 65c816 Language Structure Expanding a ROM Chart of ROM sizes in Mbits Pointer Structure LoRom Address Equation Pointer Equations Title Screen Replacement Programs to Use A Simple Fadeout Routine Where to Get Needed Tools Credits Document Information

Appendix A - 65c816 Instruction Set & Syntax -------------------------------------------------------------------------1.0 Introduction This document was written for the aspiring ROM hacker with little to no experience in 65c816 programming. The basics have been thouroughly covered and I believe this should prove a significant aid to anyone interested in 65c816 ROM hacking. Hopefully this proves true. If you benefit from this document or have suggestions for changes to make to it, please eMail me at shadow@chan.co.jp with your comments. In the end, you the user determines the future of this document. For updates to this document check http://id.dragonfire.net/ ... Unless of course it is now the year 2001 and this has become another document floating around on an FTP with some author nobody knows what happened to. Then yer up shit creek :-) -------------------------------------------------------------------------2.0 About the 65c816 This processor was Nintendo's pride and joy for quite a few years. Basically, it is an upgrade to the good ole 6502 processor used in such popular systems as the NES and the Commodore Amiga. The main feature added was 24 bit addressing but the processor also supported a whole slew of new instructions and lots of other fetures you don't need to know about. Basically, this little guy chugged along at a whopping 2.68Mhz, not even as fast as the Sega Genesis though a couple years later. But the main power was it's ability to display 256 colors in four different layers on screen at a time. That and a lot of other super-neat things helped it in competeing on the 16-bit market and earn a place in all our hearts.

-------------------------------------------------------------------------3.0 Language Structure Well, time to make things get very very ugly. I'm sure you all are used to things like QBasic or C where you get to type in commands like; 10 Print "Hello World!" or cout<<"Hello World!"<<endl; well not so in the wonderus world of assembler. We don't have all those luxuries. But here's what we do have. Lots and lots of code that will make you scream in agony. For example; jmp $ff00 This line would jump to whatever code is at 0xff00 and being executing it. So say at 0xff00 you have something like; ldx #$2b60 lda #$20 ldx #$9200 This basically grabs the first 1104 bytes at 0x200092, a LoRom address (see later about this), and chunks it into the VRAM. When you break up the code and look at what each section does by itself, it's really not that hard to understand. Now hopefully this gives you some vague idea of how the language is set up. -------------------------------------------------------------------------4.0 Expanding a ROM I'm sure you've all heard of this many many times. About how such and such ROM was expanded to hold the complete script, etc. Expanding a rom is a very simple process. Look at what the size of your ROM is. All expanding it is is padding it to the next size with empty bits. First, open up msdos prompt and go to whatever directory you have ucon.exe in. Type; ucon o [rom file] at the prompt. When the blue screen comes up, check how many Mbits the ROM is in size. The chart following this section will tell you which size to choose and what to pad to. If the screen also tells you the ROM is LoRom, you must remember to include 32k empty banks off 00's in the expanded reigon. LoRom games are stored with one page of data, one empty page. So break up what you're storing in the end. If you flood into a blank page, the emulator generally sees it as a HiRom game, in which case ever single pointer in the game will point to the wrong place and it'll be all messed up. Other than that, simply follow the padding chart below. -------------------------------------------------------------------------4.1 Chart of ROM sizes in Mbits For whatever size yours is in Mbits, you want to pad to the next higher size or whatever the ending hex bit should be. For example, if you're doing a 4.00 Mbit ROM, you want to fill 0x801f0 to 0x1001f0 with empty bits to pad it to 8.00 Mbits.

,-Size-------,-End Bit--. | 4.00 Mbit | 0x0801f0 | | 8.00 Mbit | 0x1001f0 | | 12.00 Mbit | 0x1801f0 | | 16.00 Mbit | 0x2001f0 | | 20.00 Mbit | 0x2801f0 | | 24.00 Mbit | 0x3001f0 | | 32.00 Mbit | 0x4001f0 | | 48.00 Mbit | 0x6001f0 | `------------'----------' Note: This chart already alots for a $200 bit header in the rom. If you are operating on a rom with no header, subtract $200 from the address. -------------------------------------------------------------------------5.0 Pointer Structure A pointer is not strictly text related as the MadHacker's Guide would lead one to believe. Pointers themselves tend to come in three forms: a table in which three digits of offsets are specified, jumps to another section of the ROM and a series of statements too load data from another section of the ROM. All of these are pointers. For example, in your standard RPG, the text for the game will probably have each offset stored in a pointer table. Whatever the offset in the hex editor is, subtract $200 and you'll get the one the ROM is operating on (unless it's LoRom which is covered below). So, say some sleepy drunk in town says "...*gurgle*...{stopbit}". Well, most likely the pointer is going to that first ".". For the sake of simplicity, lets pretend that it's offset is 0xabcdef. From that point, click Find and choose up and search for $efcd. In pointers, the bits are ALWAYS reversed, so instead of searching for $abcdef, you look for $efcdab. Which leaves the question of where did $ab go? In most pointer tables, a page number is pre-specified elsewhere in the ROM and it looks within either that page or the page the table is in. So you may wanna check when you find $efcd if the next bit happens to be $ab. If it is, you're in luck :-) Now you can change pages as you please. The next type is jumps. This is very commonly used in intros but seldom used in games. But basically, the code in assembler would be; at offset 0xabcd jmp $ff00 at offset 0xff00 .dcb "Text junk here." jmp $ff04 This would jump the rom from 0xabcd to 0xff00 and execute whatever junk is there till it hits the end which jumps it back to 0xff04 (three bytes added to alot for first jump). This is easy to hack. Just make it jump to some spot way out in the padding and have that jump back to where it would have gone. The .dcb is just a simple psudo-op to chunk out "Text junk here." according to the ROM's font table. Next us is loading statements. You often find these used in title screens and the like. Basically, it would go something like this; ldx #$abcd lda #$ab ldx #$f001 This is really simple. Your first line makes x big enough to hold whatever

it's gonna grab. The second opens up page ab, and the third grabs the first $abcd bytes at address $f001 in page ab. So then you'll have junk elsewhere to process this data. This is generally how tile screens get chunked into the VRAM, etc. Just change where the info is going and the size of it to account for your new stuff and you'll be all set. -------------------------------------------------------------------------5.1 LoRom Address Equation You have seen twice now in this doc notations about LoRom address. LoRom games have 32k hunks of empty bits between pages, so when you hack a LoRom address, you need to account for that. in other words, you follow a simple equation. In the case of $081fdc, that is the address seen in a hex editor. Here is the process performed. First, subtract $200 to account for the header. This will give you $081ddc. Now, you must first evaluate the page number. Open up WinCalc (calc.exe) and switch to hex mode (you must be in scientific mode). Punch in 081ddc then hit / (divide) by 8000. This will give you two digits, 10. This address is in page 10. Now wen need to evaluate where in page 10 is it, so hit clear. Now, punch in 81ddc and this time, hit Mod and punch in 8000. Theis will give you four digits, 1ddc. Bingo. Your LoRom address is 0x101ddc. If you are working on a LoRom game, guess what, you get to do that for EVERY pointer! Wai! Wai!!! (not) -------------------------------------------------------------------------5.2 Pointer Equations Some games involve pointer equations. In such a case, instead of having a normal pointer, you need to add or subtract and extra amount from the address. You will need to do some asm hacking I can't possibly cover in this doc to find it. Sorry I can't help with this one. -------------------------------------------------------------------------6.0 Title Screen Replacement When you run your GIF through GIF2SOPT it will chunk out three files. Unless you're coding you own game you only need the .set file. Whatever is in this file, stick it somewhere where you have open space (NOT IN ONE OF THE BLANK BANKS IF IT'S A LOROM GAME!!!). Then just look around in a sprite editor to see where the current title screen data starts. Take that offset and open up hex workshop. Subtract $200 and look for it reversed (all address are stored as backwards bits, abcd = cdab). When you find it, it will probably be something like a2 cd ab. a2 is the opcode for LDX #$abcd. You will only search for the last four digits because the page number is specified in an earlier statement (eg lda #$20). If you must change the page, back it up from there and look for whatever the firs two bits of the location were, but if it was a current bank call, you're screwed. -------------------------------------------------------------------------6.1 Programs to Use

I reccomend GIF2SOPT as it allows you to convert 16 or 256 color GIF files into fully optimized SNES format data. It should be a 256x256 GIF in order to be used. But if your game blanks the bottom or side row of the title screen (eg the Final Fantasy games), you may need to make it 248x248 pixels. -------------------------------------------------------------------------7.0 A Simple Fadeout Routine This is a very very simple fadeout routine. You don't need to know how it works mainly since I don't wanna explain it. fadeout LDY #$000f ; $0f y-reg loop LDX #$0006 ; $06 x-reg DEY ; y=y-1 STY $2100 wait LDA $4210 ; vertical blank active? AND #$80 BEQ wait ; if no wait DEX ; if yes CPX #$0000 BNE wait ; if x<>0 wait CPY #$0000 ; x=0 BNE loop ; if y<>1 loop LDX #$00cf dark LDA $4210 ; vertical blank active? AND #$80 BEQ dark ; if no, do dark DEX CPX #$0000 BNE dark ; if x<>0 then dark This is closely based off of one of BeXXX's examples for a fadeout. But instead of drunked german notation, it has fairly understandable english notation so hopefully youc an now see the logic of this. Basically it's a looping routine that keeps decreasing the lightness to dark untill the screen is blanked. -------------------------------------------------------------------------8.0 Where to Get Needed Tools I have a wide selection of tools at my webpage in the 65c816 section. http://id.dragonfire.net/ You can also get many things in terri public ftp. ftp://teeri.oulu.fi/pub/console/nintendo/ -------------------------------------------------------------------------9.0 Credits The following people have contributed to this text (whether they know it or not). Many many thanks go out to them. ,----------------------------------------------------------------------.

| Neill Corlett - reminded me of the lorom equation one time when I | | forgot it | | Frank Hughes - tons of help and elpaling back when I was working on | | Ranma | | Jeremy Chadwick - putting up with my stupid questions back when I | | was first learning | | Carnivore - made a super-keen instruction -> ouput table I use | | Amalgam - making sure this was semi-comprehensible | `----------------------------------------------------------------------' -------------------------------------------------------------------------9.1 Document Information Questions, comments or complaints can be sent to me via eMail at shadow@chan.co. jp. Copyright c 1999 SysTEm[id]. All rights reserved. Last updated Sunday, April 25, 1999 -------------------------------------------------------------------------Appendix A - 65c816 Instruction Set & Syntax OpCode Description Syntax --------------------------------------------------SEP Set Bits in P sep #$30 ADC Add With Carry adc #$12 AND Logical AND and #$12 BIT Bit Test bit #$12 CMP Compare Accumulator cmp #$12 CPX Compare X Register cpx #$12 CPY Compare Y Register cpy #$12 DEC Decrement Accumulator or Memory dec $12 EOR Exclusive OR Accumulator eor #$12 INC Increment Accumulator or Memory inc $12 LDA Load Accumulator lda $12 LDX Load X Register ldx #$12 LDY Load Y Register ldy #$12 ORA Logical OR Accumulator ora #$12 ROL Rotate Left Acc or Mem rol $12 ROR Rotate Right Acc or Mem ror $12 SBC Subtract With Carry sbc #$12 STA Store Accumulator sta $12 STZ Store X Register stx $12 STY Store Y Register sty $12 CLR Store a 0 into Memory clr $12 BCC Branch if Carry Clear bcc $601e5 BCS Branch if Carry Set bcs $601e5 BEQ Branch if Equal beq $601e5 BMI Branch if Minus bmi $601e5 BNE Branch if Not Equal bne $601e5 BPL Branch if Plus bpl $601e5 BRA Branch Always bra $601e5 BVC Branch if Overflow Clear bvc $601e5 BVS Branch if Overflow Set bvs $601e5 CLC Clear the Carry Flag clc CLD Clear the Decimal Flag cld CLI Clear the Interrupt Flag cli DEX Decrement X Register dex

DEY INX INY NOP PLA PLP PLX PLY SED SEI TAX TAY TSX TXA TXS TXY TYA XCE BRK CSP JMP JSR MVN MVP RTI RTL RTS HLT WAI SWA

Decrement Y Register Increment X Register Increment Y Register No Operation Pop Accumulator Pop P Pop X Register Pop Y Register Set Decimal Flag Set Interrupt Flag Transfer Accumulator to X Transfer Accumulator to Y Transfer S to X Transfer X to Accumulator Transfer X to S Transfer X to Y Transfer Y to Accumulator Exchange Carry w/ Emulation Bit Break Point Instruction Call System Procedure Jump to New Location Jump to Subroutine Block Move (decrement) Block Move (increment) Return From Interrupt Return From Long Subroutine Return From Short Subroutine Halt the Clock Wait for Interrupt Swap Accumulator

dey inx iny nop pla plp plx ply sed sri tax tay tsx txa txs txy tya xce brk csp jmp jsr mvn mvp rti rtl rts hlt wai swa

#$12 #$12 $1234 $1234 $1234 $1234

I know this list is missing a lot of instructions, this is just the list of instructions I know for certain is supported by all the assemblers out there. Sorry to tell you but there is even more to learn. Hope this helps you to make sense out of some of assembler mess early on in the document.

Potrebbero piacerti anche