📜 ⬆️ ⬇️

Hacking Dendy Games. On the example of Road Fighter

I want to talk about the principle of hacking toys for the game console Dendy (it’s also the Nintendo Entertainment System, it’s also Famicom, it’s 100,500 Chinese clones, hereafter just NES).
Hacking (or rather modding, but the term “ROMhacking” is more common in the emuscene) of the game will consist in partially disassembling the game code and writing your own small code. In principle, ROMhacking hardly differs from the usual “cracking” of programs or writing trainers for games.
The victim will be a small toy, a frequenter of the Chinese cartridges of the multiplayer 9999999 in 1, the game Road Fighter.

This is a fairly simple race, takes up little space and is ideal for experiments. In this game it is possible to move the car only left or right across the screen. Gameplayno is justified, but I want something more. To begin, I will introduce the ability to move our race car back and forth.
So, for this we need:
Rum file and compiler can be taken at the link at the end of the article.

When we stocked up the tools and the prepared ones themselves, it would not hurt to understand some of the intricacies of the architecture of the NES console. There is enough documentation both on the processor and on the device, so I’ll briefly touch on the main points. The next paragraph of the text can be skipped.
The processor 6502 is 8-bit, but has a 16-bit address bus and can work with the address range 0h-FFFFh. In this case, the first 7FFh bytes (2KB) are allocated to RAM, then some specific things follow, and the code itself is assigned a range of 8000h-FFFFh (32KB). If the code of the game does not fit into the indicated volume, a special mechanism is used - “mappers”. Mappers have the ability to switch sections of code in the address space of the processor. That is, temporarily replacing one section of code with another, thereby loading the necessary data ... Mappers operate with memory blocks ("banks") of 16 KB each. Technically, mappers are chips on a cartridge board, and do not have reflections in the ROM file itself.

Step number one. Expanding the ROM file.
')
So, we start the FCEUX emulator, load our patient and go to the Help-> Message Log menu.
We see about the following:

PRG ROM: 1 x 16KiB
CHR ROM: 1 x 8KiB
..
Mapper #: 0
..


Road Fighter rum has a volume of 24KB, of which 16KB is allocated to PRG-ROM (code and data) and 8KB to CHR-ROM (graphics), and also uses a zero mapper (i.e., no mapper). As you can see, ROM can be easily expanded by adding another memory bank to 16KB. This is necessary for what would be where to add our code.
First, open the built-in Hex Editor from the Debug menu. Go to the address of $ 8000, and then to the address of $ C000 and see that they contain the same data. Moreover, the data is mirrored in the range of $ 8000- $ C000 (you can easily make sure of it if you put the breakpoint on this range, it will never work). Now open ROM in any hex editor and edit the title, it has the following format:

0-3 "NES^Z" "^Z" = 0x1A
4 16 PRG.
5 8 CHR.
6 7-4 4 - ROM.
- 3 1 4- VRAM.
- 2 1 512- $7000-$71FF.
- 1 1 SRAM $6000-$7FFF.
- 0 1 , 0 .
7 7-4 4 ROM.
- 3-1 , 0!
- 0 1 VS.
8 8 RAM.
- .NES, 1x8 RAM
- 0.
9 7-1 , 0.
- 0 1 PAL, NTSC.
10-15 , 0!


We set the number of PRG banks equal to two. Next we paste (but do not overwrite!) Into the file an empty block of 16KB (4000h) in size immediately after the header. Now the file should weigh 40KB.

Step number two. We are looking for data.

Now we need to find the cell in the RAM responsible for the Y coordinate of the car and the cell with the key pressed code. This can be done using the RAM Search tool built into the emulator (Tools menu). In our case, it will be enough to run the emulator HEX Editor, and view the first 100h bytes with your eyes. The processor has special “short instructions” for quick access to this range, so frequently used data is located here. If you simultaneously open the main emulator window and the Hex Editor window, and click “left / right” (just do not forget to set up the control), then you can see that several cells change accordingly. We need 07h - the key code and 65h - the X coordinate. It is logical to assume that the Y coordinate is near the X coordinate, change cell 66h to an arbitrary number and voila - the car has moved along the Y axis. You can also freeze the cell editor for the duration of tests C8h, it stores the amount of fuel.

Step number three. We do a sidebar of the code and put a stub.

Knowing the addresses of the desired variables, you can already write your code, but for now we don’t know where to call it. We put the bricpoint on the record, on cell 65h (through the context menu in hex or through the debugger), move the game to the left / right and the debugger window should open with the following code:

01:D52B:E6 65 INC $0065 = #$64
01:D52D:60 RTS
01:D52E:C6 65 DEC $0065 = #$64
01:D530:60 RTS


The debugger may occasionally distort commands, so if you scroll up the debugger window, some commands will not be displayed correctly. Having scrolled the code up a bit, or having reached the RTS step by step, we will reach the address from where the call key code check procedure and the subsequent movement of the car are called:

01:D4D0:20 D9 D4 JSR $D4D9
01:D4D3:20 E1 D4 JSR $D4E1
01:D4D6:4C E9 D4 JMP $D4E9


Replace JSR $ D4D9 with your own procedure call — JSR $ 8000. To do this, simply click on the strip to the left of the command address, and drive the desired command into the inline assembler. Using step-by-step debugging, let's move on to the address of $ 8000, and put a stub in the form of a cut-out JSR and the subsequent RTS from our procedure:

00:8000:20 D9 D4 JSR $D4D9
00:8003:60 RTS


Step number four. We write the code and insert it into the ROM.

Create a text file RoadFighter.asm and enter into it such a simple code:

$=$8000

LDA $07
AND #$04
BEQ checkUp
BNE backward:

checkUp:
LDA $0007
AND #$08
BEQ exitInject

forward:
LDA $66
CMP #$50 ;
BMI exitInject
DEC $0066
JMP exitInject

backward:
LDA $66
CMP #$B0
BPL exitInject
INC $0066

exitInject:
JSR $D4D9
RTS


Now run the compiler with the parameters “-l roadFighter”. The output will be a listing file and a binary. Open the binary and copy its contents to ROM Road Fighter at offset 10h.

Step number five. Fini-ta-la.

If everything is done correctly, then by running the modified ROM in the emulator, we will be able to move our race car forward and backward, thereby making it easier to push innocuous and not very typewriters on the track (and for their destruction points are given!).
Archive with compiler, source, original rum and modified rum - RoadFighterModSource.zip (people)
RoadFighterModSource.zip (megaupload)

Source: https://habr.com/ru/post/126720/


All Articles