Jump to content

A great intro to 6502 Assembly


Recommended Posts

Great responses guys. FTR, this runs on my iPad too. Nice little script...

I would pay money for a legit class that taught 6502 and how to apply it to NES games.

Jstout could teach it :)

 

If there is enough people wanting to learn 6502 / NES programming then I could do this.

Link to comment
Share on other sites

Wow. Count me in. Possible topics:

How to use fceux to your advantage (debugging, etc).

How to find stuff in RAM and ROM (not just pattern matching

I think the reason i see a need for this is because while there are a lot of tuts on the net, I learn more from firing questions at jstout and for my learning style, I benefit from having a resource who had been there before that i can ask questions of. I want something that specifically focuses on hacking the nes. Lots of 6502 out there but not as much well-written stuff as it applies to the NES and hacking it.

Anyways, not sure how such a project would work, but I'm in either way.

Link to comment
Share on other sites

Im down. Been learning boat loads. Really reading stuff on vram. Pallet loading and graphic loading is my main interests.

And I agree with TecmoTurd, I use a debugger quite a bit. But I know im not using it to its fullest. Mainly just shift through RAM and see whats there.

Edited by drunken_honkey
Link to comment
Share on other sites

I thought about all the common topics/issues with the NES and created the list below with the | being related and/or advanced topics.  The 6502 section is general assembly knowledge allowing people to read and write code.  The NES Programming section is a how and why things are done (could create a game, low-level hacking is limited but might explain how things are stored, high-level hacking will understand reasoning and allow practical applications outside of code snippets) and likely contain code examples.  The FCEUX Hacking section would describe how to use the various features in the emulator and likely contain simple examples (the problem here is sometimes things just aren't simple to find or change).

 

Did I miss anything people want to know about?  Is this overkill of what people want to know about?  And more importantly are there more than 2-3 people even interested in this?

 

6502:

NUMBER FORMATS
REGISTERS
ADDRESSING MODES
PROCESSOR STATUS FLAGS
OPCODES
BASIC MATH             | 16-BIT OPERATIONS, FIXED POINT

NES PROGRAMMING:
MEMORY MAPS
PPU REGISTERS
SKELETON ROM
GAME LOOP              | GAME STATES, MULTITASK
PALETTE                | FADE
SPRITES                | METASPRITES, ANIMATION, COLLISION DETECTION
CONTROLLER
BACKGROUND             | METATILES, COMPRESSION
SCROLL                 | CAMERA
SPRITE 0 HIT
MMC3 MEMORY MAPPER
SOUND                  | DMC, SOUND ENGINE

FCEUX HACKING:
HEX EDITOR             | CORRUPTION, FONT TABLES, CODE INSERTION
PPU VIEWER
NAME TABLE VIEWER
CODE/DATA LOGGER       | FILE COMPARE
CHEAT SEARCH
DEBUGGER               | CONDITIONS
TRACE LOGGER
SAVE STATES

 

Link to comment
Share on other sites

I think beyond these outlined topics perhaps walking through the thought or actual process of creating say the grapple hack would be useful as that would incorporate a lot of the topics in a concrete example. 


 


Like the logic for me would go something like.


 


1. How does one find where the code concerning grapples is in the rom using the FCEUX debugger. Explain logic, tips, etc.


2. How does one decipher what the code is actually doing? 


3. Tips regarding creating new code.  


Link to comment
Share on other sites

I think beyond these outlined topics perhaps walking through the thought or actual process of creating say the grapple hack would be useful as that would incorporate a lot of the topics in a concrete example. 

 

Like the logic for me would go something like.

 

1. How does one find where the code concerning grapples is in the rom using the FCEUX debugger. Explain logic, tips, etc.

2. How does one decipher what the code is actually doing? 

3. Tips regarding creating new code.  

 

I was intrigued as most wanted a hacking front to back example.  The grappling hack was involved with only light complications.  I spent much much much longer writing this all out then actually going through the steps this morning.  This definitely needs some cleanup and only you guys can tell me if I need to dumb it down more or if I was babying you too much at times but this will give an idea of the steps I followed that you can replicate.  Feedback will improve this too as I tried to get this done as fast as possible without detailing every last exact button name to press (just told to do it).

 

The FCEUX Save State and the Code/Data logs I remembered to save are attached so you can see what I saw with them.  I'm using FCEUX 2.2.1, http://www.fceux.com/web/home.html, and the original TSB rom.  So here it goes hoping all this text fits and I already know my clean looking notepad format will be ripped to shreds in the post =)  I'll probably created a new topic when all the other stuff is created or more ready to go than this so its easily found in one place.

 

ManVsGrappleFiles.zip

 

GOAL: Improve Man vs Com Grappling

KNOW: Pressing buttons on controller helps determines grapple winner. High HP popcorns opponent.  Com can't use a controller to press buttons.

START: Find the Man Presses.

HOW:

   A. Find the controller RAM storage then using the storage to count presses

   B. Find when it counts presses

We'll attempt with Option B as it would be the quickest method if found.

--------------------

GOAL: Find the press counter

Step 1. Get a save state just before a grapple occurs so we can reload and test over and over again.

Step 2. Open the Code/Data Logger and hit Start.

Step 3. Run winning a grapple then pause the emulator and then run losing a grapple (no presses) then pause the emulator then pause the Code/Data Logger.

Step 4. Pause the emulator during a grapple and open the Cheats...

1. In the Cheat Search hit Reset

2. Presses could be counted up (highest value) or down (first to a certain number). Logically we expect up.

3. Hit 00 Known Value = 639 Possibilities

4. Unpause grapple then repause during grapple. (If Grapple is done then reload save state to get back into grapple)

5. Hit 00 Known Value = 636 Possibilities

6. Unpause grapple, press A Button, then repause during grapple. (If Grapple is done then reload save state to get back into grapple then hit A Button)

7. Hit Greater Than = 51 Possibilites

8. Unpause grapple, press A Button, then repause during grapple. (If Grapple is done then reload save state to get back into grapple then hit A Button twice)

9. Hit Greater Than = 3 Possibilites (only $03BC == 02 so we expect this to be the location)

Step 5. We are looking for press confirmaton. In the Debugger, Add Breakpoint with Address: 03BC and Write

1. Reload the Save State

2. Determine the breakpoints by writing down each location and hitting run to find the next until grapple finishes then pause

3. Repeat 1 and 2 hitting the A button during the grapple

At Contact: x2826A 0A:825A:91 AE     STA ($AE),Y @ $03BC [A = 00] This should be the press reset

At Press:   x28285 0A:8275:91 AE     STA ($AE),Y @ $03BC [A = 01] This should be the press storage

Step 6. Gather some information off these breakpoints.

1. Double-click on the 3BC breakpoint to disable

2. Add Breakpoint with Address: 825A and Execute

3. Add Breakpoint with Address: 8275 and Execute

4. Open the Trace Logger and have it start logging in the window

5. Reload the Save State and enter the grapple

Trace Logger:

      $DAC1:A0 07     LDY #$07                           A:00 X:00 Y:05 S:39 P:nvUBdiZC

      $DAC3:B1 AE     LDA ($AE),Y @ $0606 = #$82         A:00 X:00 Y:07 S:39 P:nvUBdizC

      $DAC5:48        PHA                                A:82 X:00 Y:07 S:39 P:NvUBdizC

      $DAC6:88        DEY                                A:82 X:00 Y:07 S:38 P:NvUBdizC

      $DAC7:B1 AE     LDA ($AE),Y @ $0605 = #$55         A:82 X:00 Y:06 S:38 P:nvUBdizC

      $DAC9:48        PHA                                A:55 X:00 Y:06 S:38 P:nvUBdizC

      $DACA:60        RTS (from $DACB) ----------------- A:55 X:00 Y:06 S:37 P:nvUBdizC

      $8256:A9 00     LDA #$00                           A:55 X:00 Y:06 S:39 P:nvUBdizC        ; RESET PRESS COUNTER

      $8258:A0 1D     LDY #$1D                           A:00 X:00 Y:06 S:39 P:nvUBdiZC

Breakpoint 1 Hit at $825A: $825A:EC--X-

6. Change 825A Breakpoint Addresss to 8256

7. Stop the Trace Logger

8. Copy Code from the Debugger using 8256 and 8275 and label the obvious

 0A:8256:A9 00     LDA #$00                ; RESET PRESS VALUE

 0A:8258:A0 1D     LDY #$1D                ; #$1D INDEX to PRESS COUNTER

 0A:825A:91 AE     STA ($AE),Y @ $03BC            ; $AE = POINTER, $03BC = PRESS COUNTER

 0A:825C:A0 01     LDY #$01

 0A:825E:B1 AE     LDA ($AE),Y @ $03A0

 0A:8260:29 40     AND #$40

 0A:8262:F0 16     BEQ $827A

 0A:8264:A9 01     LDA #$01

 0A:8266:20 CB DA  JSR $DACB

 0A:8269:20 08 A1  JSR $A108                ; COUNT?

 0A:826C:10 F6     BPL $8264

 0A:826E:A0 1D     LDY #$1D                ; INDEX TO PRESS COUNTER

 0A:8270:B1 AE     LDA ($AE),Y @ $03BC            ; LOAD PRESS COUNTER

 0A:8272:18        CLC

 0A:8273:69 01     ADC #$01                ; ADD 1 TO PRESS COUNTER

 0A:8275:91 AE     STA ($AE),Y @ $03BC            ; STORE PRESSES

 0A:8277:4C 64 82  JMP $8264                ; REPEAT AT $8264

Step 7. Determine when the press counter is used (exluding the read to store the counter we found above)

1. Add Breakpoint with Address: 03BC and Read with Condition: P != #8270

2. Reload the Save State and enter the grapple

At End: x284F6 0A:84E6:B1 AE     LDA ($AE),Y @ $03BC This should be read for the press winner

3. Reset Code/Data Logger then hit Start.  Win a grapple and Lose a Grapple as above.

4. Copy Code from Debugger (with help from Code/Data Logger spotting the entry point) and label the obvious

*In the Hex Editor, using the View Menu set to ROM File (Code/Data Logger makes Data Blue, Code Gold, Code and Data Green, Unused Black)

 0A:84DC:20 4C B1  JSR $B14C

 0A:84DF:A9 40     LDA #$40

 0A:84E1:20 CB DA  JSR $DACB

 0A:84E4:A0 1D     LDY #$1D                ; PRESS COUNTER INDEX

 0A:84E6:B1 AE     LDA ($AE),Y @ $03BC            ; LOAD PRESS COUNTER

 0A:84E8:C9 02     CMP #$02

 0A:84EA:90 0D     BCC $84F9                ; LESS THAN 2 PRESSES?

; GREATER THAN OR EQUAL TO 2 PRESSES

 0A:84EC:20 90 B1  JSR $B190

 0A:84EF:A0 81     LDY #$81

 0A:84F1:A2 85     LDX #$85

 0A:84F3:20 C9 B1  JSR $B1C9

 0A:84F6:4C 23 87  JMP $8723                ; EXIT

; LESS THAN 2 PRESSES

 0A:84F9:20 90 B1  JSR $B190

 0A:84FC:A0 22     LDY #$22

 0A:84FE:A2 87     LDX #$87

 0A:8500:20 C9 B1  JSR $B1C9

 0A:8503:A9 01     LDA #$01

 0A:8505:20 CB DA  JSR $DACB

 0A:8508:4C 51 85  JMP $8551                ; EXIT

5. When we force to $84F9 by either NOP or JMP (refer to the 6502 opcodes for these values), quick testing shows Player 1 always loses the grapple

6. When we force to $84EC by NOP, quick testing shows Player 1 always wins the grapple

We found our grapple section we need to edit but we are lacking all the info we what to use.

--------------------

GOAL 2: We want to include HP so we need to find if its already loaded for our use

KNOW: High HP popcorns opponent.  Each Player has a section containing important game info.  Its well documented and easy to find regardless so my Save State player QB Bills HP: x3011 2nd Nibble

START: HP of our player

Step 1. Add a Breakpoint for HP

1. Address: 9001 and Read with Condition: $9001 == #11

2. Address: B001 and Read with Condition: $B001 == #11

*We don't know if x3011 is in the $8000 or $A000 Bank so we set both.

3. Disable prior breakpoints

4. Determine the breakpoints by writing down each location and hitting run between the play call screen and game screen

First Hit:  x3DDEB >0F:DDDB:B1 3E     LDA ($3E),Y @ $B001 = #$11

Second Hit: x3DDEB >0F:DDDB:B1 3E     LDA ($3E),Y @ $B001 = #$11

5. Do it again but in the Debugger hit Step Into after hit to determine how its used

First Step Into:

>0F:DDDB:B1 3E     LDA ($3E),Y @ $B001

 0F:DDDD:B0 04     BCS $DDE3

 0F:DDDF:4A        LSR

 0F:DDE0:4A        LSR

 0F:DDE1:4A        LSR

 0F:DDE2:4A        LSR

 0F:DDE3:29 0F     AND #$0F

 0F:DDE5:85 3E     STA $003E                ; FIRST NIBBLE

Second Step Into:

>0F:DDDB:B1 3E     LDA ($3E),Y @ $B001

 0F:DDDD:B0 04     BCS $DDE3

 0F:DDE3:29 0F     AND #$0F

 0F:DDE5:85 3E     STA $003E                ; SECOND NIBBLE

6. Add Breakpoint with Address: 3E and Read and Write but disable it

7. Wait until second breakpoint and enable the 3E breakpoint then hit run

x3DE0E 0F:DDFE:65 3E     ADC $003E Adding our value to something

x3DDC8 0F:DDB8:85 3E     STA $003E Removes our number and quick inspection of debugger shows its creating a pointer

8. In the Debugger seek to DDFE and copy the code until the exit.

 0F:DDE7:A5 45     LDA $0045

 0F:DDE9:4A        LSR

 0F:DDEA:4A        LSR

 0F:DDEB:A8        TAY

 0F:DDEC:28        PLP

 0F:DDED:B0 06     BCS $DDF5

 0F:DDEF:B9 03 65  LDA $6503,Y

 0F:DDF2:4C F8 DD  JMP $DDF8

 0F:DDF5:B9 08 66  LDA $6608,Y

 0F:DDF8:A6 45     LDX $0045

 0F:DDFA:20 40 DE  JSR $DE40

 0F:DDFD:18        CLC

 0F:DDFE:65 3E     ADC $003E

 0F:DE00:38        SEC

 0F:DE01:E9 01     SBC #$01

 0F:DE03:B0 02     BCS $DE07

 0F:DE05:A9 00     LDA #$00

 0F:DE07:C9 10     CMP #$10

 0F:DE09:90 02     BCC $DE0D

 0F:DE0B:A9 0F     LDA #$0F

 0F:DE0D:A8        TAY

 0F:DE0E:A6 44     LDX $0044

 0F:DE10:20 E3 D8  JSR $D8E3

 0F:DE13:98        TYA

 0F:DE14:60        RTS -------------------------------    ; EXIT

9. Add a Breakpoint at Address: DE14 and Execute but disable

10. Do 6 and 7 again but also enable the DE14 breakpoint.

11. At the DE14 breakpoint, use the debugger Step Into storing the code until values are gone then label the obvious

 0F:DDE7:A5 45     LDA $0045

 0F:DDE9:4A        LSR

 0F:DDEA:4A        LSR

 0F:DDEB:A8        TAY

 0F:DDEC:28        PLP

 0F:DDED:B0 06     BCS $DDF5

 0F:DDEF:B9 03 65  LDA $6503,Y @ $6503

 0F:DDF2:4C F8 DD  JMP $DDF8

 0F:DDF5:B9 08 66  LDA $6608,Y @ $6608

 0F:DDF8:A6 45     LDX $0045

 0F:DDFA:20 40 DE  JSR $DE40                ; GET CONDITIONAL BOOSTS

 0F:DDFD:18        CLC

 0F:DDFE:65 3E     ADC $003E                ; ADD HP

 0F:DE00:38        SEC

 0F:DE01:E9 01     SBC #$01                ; SUBTRACT 1

 0F:DE03:B0 02     BCS $DE07                ; NEGATIVE VALUE?

 0F:DE05:A9 00     LDA #$00                ; SET TO 0 IF NEGATIVE

 0F:DE07:C9 10     CMP #$10

 0F:DE09:90 02     BCC $DE0D                ; ABOVE MAX?

 0F:DE0B:A9 0F     LDA #$0F                ; SET TO MAX IF TOO LARGE

 0F:DE0D:A8        TAY                    ; FINAL HP TO Y

 0F:DE0E:A6 44     LDX $0044

 0F:DE10:20 E3 D8  JSR $D8E3

 0F:DE13:98        TYA                    ; FINAL HP TO A

 0F:DE14:60        RTS -------------------------------

 0D:86B4:AA        TAX                    ; FINAL HP TO X (NOTE FINAL HP IS IN A, X, Y)

 0D:86B5:60        RTS -------------------------------

 0D:8675:AA        TAX                    ; SET HP AS INDEX FOR TABLE

 0D:8676:BD EF DF  LDA $DFEF,X @ $DFF0            ; GET HP VALUE FROM TABLE

 0D:8679:A0 1C     LDY #$1C                ; HP VALUE INDEX

 0D:867B:91 40     STA ($40),Y @ $03BB            ; STORE HP VALUE

... CONTINUE ELIMINATES FINAL HP IN REGISTERS A,X,Y

Step 2. Add a breakpoint for the new HP location we found

1. Delete the 9001, B001, 3E, DE14 breakpoints

2. Add a breakpoint for Address: 03BB and Read and Write

4. Enable the breakpoints at 8256 and 8275 (We know the HP has to be checked first)

5. Pause the emulator and reset the Code/Data Logger hit Run

6. Reload our save state just before the grapple and record the breakpoints for $03BB

At Contact: x284D9 0A:84C9:B1 AE     LDA ($AE),Y @ $03BB    Read HP for Popcorn Check

7. Pause the Code/Data Logger

8. Reload before the grapple until breakpoint and copy Code from Debugger (with help from Code/Data Logger spotting the entry point) and label the obvious

 0A:84C7:A0 1C     LDY #$1C                ; HP VALUE INDEX

 0A:84C9:B1 AE     LDA ($AE),Y @ $03BB            ; MAN HP VALUE ($AE is MAN POINTER)

 0A:84CB:38        SEC

 0A:84CC:F1 3E     SBC ($3E),Y @ $061B            ; SUBTRACT COM HP VALUE ($3E is COM POINTER; $61B ADDRESS - #$1C INDEX = $05FF POINTER)

 0A:84CE:90 04     BCC $84D4                ; MAN LESS THAN COM HP VALUE?

; MAN MORE THAN COM HP VALUE

 0A:84D0:C9 20     CMP #$20

 0A:84D2:B0 18     BCS $84EC                ; MAN MORE THAN COM HP VALUE BY x20+ (THIS HEADS STRAIGHT TO WIN GRAPPLE)

; MAN LESS THAN COM HP VALUE

 0A:84D4:20 36 B1  JSR $B136

 0A:84D7:A9 01     LDA #$01

 0A:84D9:20 CB DA  JSR $DACB

; We know the following code here is the Man vs Com press check from above

 0A:84DC:20 4C B1  JSR $B14C

 0A:84DF:A9 40     LDA #$40

 0A:84E1:20 CB DA  JSR $DACB

 0A:84E4:A0 1D     LDY #$1D                ; PRESS COUNTER INDEX

 0A:84E6:B1 AE     LDA ($AE),Y @ $03BC            ; LOAD PRESS COUNTER

 0A:84E8:C9 02     CMP #$02

 0A:84EA:90 0D     BCC $84F9                ; LESS THAN 2 PRESSES?

; GREATER THAN OR EQUAL TO 2 PRESSES

 0A:84EC:20 90 B1  JSR $B190

 0A:84EF:A0 81     LDY #$81

 0A:84F1:A2 85     LDX #$85

 0A:84F3:20 C9 B1  JSR $B1C9

 0A:84F6:4C 23 87  JMP $8723                ; EXIT

; LESS THAN 2 PRESSES

 0A:84F9:20 90 B1  JSR $B190

 0A:84FC:A0 22     LDY #$22

 0A:84FE:A2 87     LDX #$87

 0A:8500:20 C9 B1  JSR $B1C9

 0A:8503:A9 01     LDA #$01

 0A:8505:20 CB DA  JSR $DACB

 0A:8508:4C 51 85  JMP $8551                ; EXIT

Step 3. Find the Com Pointer creation

1. Add a breakpoint of Address: 3E to 3F and Write with Condition: A == #FF (From the Pointer calculation of $05FF above). We'll change A to X then Y if the most common A isn't correct.

2. Reset the Trace Logger and hit Start in the window

3. Reload before the grapple until we reach our beginning breakpoint of 84C7 then label the obvious

      $832E:20 90 B1  JSR $B190                          A:2D X:07 Y:03 S:39 P:nvUBdizC ; GET COM POINTER

      $B190:A0 1E     LDY #$1E                           A:2D X:07 Y:03 S:37 P:nvUBdizC ; INDEX

      $B192:B1 AE     LDA ($AE),Y @ $03BD = #$FF         A:2D X:07 Y:1E S:37 P:nvUBdizC    ; FROM MAN PLAYER

Breakpoint 5 Hit at $B194: $003E-003F:EC-W-- Condition:A == #FF

      $B194:85 3E     STA $003E = #$4A                   A:FF X:07 Y:1E S:37 P:NvUBdizC ; COM POINTER LO

      $B196:C8        INY                                A:FF X:07 Y:1E S:37 P:NvUBdizC ; NEXT INDEX

      $B197:B1 AE     LDA ($AE),Y @ $03BE = #$05         A:FF X:07 Y:1F S:37 P:nvUBdizC ; FROM MAN PLAYER

      $B199:85 3F     STA $003F = #$B2                   A:05 X:07 Y:1F S:37 P:nvUBdizC ; COM POINTER HI

      $B19B:60        RTS (from $B190) ----------------- A:05 X:07 Y:1F S:37 P:nvUBdizC ; EXIT

      $8331:A0 01     LDY #$01                           A:05 X:07 Y:1F S:39 P:nvUBdizC

      $8333:B1 AE     LDA ($AE),Y @ $03A0 = #$60         A:05 X:07 Y:01 S:39 P:nvUBdizC

      $8335:29 40     AND #$40                           A:60 X:07 Y:01 S:39 P:nvUBdizC

      $8337:F0 0C     BEQ $8345                          A:40 X:07 Y:01 S:39 P:nvUBdizC

      $8339:B1 3E     LDA ($3E),Y @ $0600 = #$80         A:40 X:07 Y:01 S:39 P:nvUBdizC

      $833B:29 40     AND #$40                           A:80 X:07 Y:01 S:39 P:NvUBdizC

      $833D:F0 03     BEQ $8342                          A:00 X:07 Y:01 S:39 P:nvUBdiZC

      $8342:4C C7 84  JMP $84C7                          A:00 X:07 Y:01 S:39 P:nvUBdiZC ; JUMP TO GRAPPLE ROUTINE

Breakpoint 4 Hit at $84C7: $84C7:EC--X-

Now he have the Pointer for the Man and Com players with their HP values

--------------------

GOAL: Write the Improvement Code with the knowledge we acquired

KNOW: $3B-$3D are Random Values

START: Write it in notepad

Step 1. Write the code out

 0A:84C7:A0 1C     LDY #$1C                ; HP VALUE INDEX

 0A:84C9:B1 AE     LDA ($AE),Y @ $03BB            ; MAN HP VALUE ($AE is MAN POINTER)

 0A:84CB:38        SEC

 0A:84CC:F1 3E     SBC ($3E),Y @ $061B            ; SUBTRACT COM HP VALUE ($3E is COM POINTER; $61B ADDRESS - #$1C INDEX = $05FF POINTER)

 0A:84CE:90 04     BCC $84D4                ; MAN LESS THAN COM HP VALUE?

; MAN MORE THAN COM HP VALUE

 0A:84D0:C9 20     CMP #$20

 0A:84D2:B0 18     BCS $84EC                ; MAN MORE THAN COM HP VALUE BY x20+ (THIS HEADS STRAIGHT TO WIN GRAPPLE)

; MAN LESS THAN COM HP VALUE

 0A:84D4:20 36 B1  JSR $B136

 0A:84D7:A9 01     LDA #$01

 0A:84D9:20 CB DA  JSR $DACB

 0A:84DC:20 4C B1  JSR $B14C

 0A:84DF:A9 40     LDA #$40

 0A:84E1:20 CB DA  JSR $DACB

         A0 1C     LDY #$1C                ; HP INDEX

         B1 AE     LDA ($AE),Y                ; LOAD MAN HP

         4A        LSR

         4A        LSR

         4A        LSR

         C8        INY                    ; PRESS INDEX

         18        CLC

         71 AE     ADC ($AE),Y                ; HP/8 + PRESS

         91 AE     STA ($AE),Y                ; STORE IN MAN PRESS COUNTER

         20 90 B1  JSR $B190                ; LOAD COM POINTER

         A0 1C     LDY #$1C                ; HP INDEX

         B1 3E     LDA ($3E),Y                ; LOAD COM HP

         4A        LSR

         4A        LSR

         4A        LSR

         C8        INY

         91 3E     STA ($3E),Y                ; STORE HP/8 IN COM PRESS COUNTER

         A5 3D     LDA $003D                ; RANDOM NUMBER

         29 0F     AND #$0F                ; MAKE RANDOM x0-F

         18        CLC

         71 3E     ADC ($3E),Y                ; HP/8 + RANDOM

         91 3E     STA ($3E),Y                ; STORE IN COM PRESS COUNTER

         B1 AE     LDA ($AE),Y                ; LOAD MAN PRESS COUNTER

         D1 3E     CMP ($3E),Y                ; COMPARE WITH COM PRESS COUNTER

 0A:84EA:90 0D     BCC $84F9                ; LESS THAN COM?

; GREATER THAN OR EQUAL TO COM PRESSES

 0A:84EC:20 90 B1  JSR $B190

 0A:84EF:A0 81     LDY #$81

 0A:84F1:A2 85     LDX #$85

 0A:84F3:20 C9 B1  JSR $B1C9

 0A:84F6:4C 23 87  JMP $8723                ; EXIT

; LESS THAN COM PRESSES

 0A:84F9:20 90 B1  JSR $B190

 0A:84FC:A0 22     LDY #$22

 0A:84FE:A2 87     LDX #$87

 0A:8500:20 C9 B1  JSR $B1C9

 0A:8503:A9 01     LDA #$01

 0A:8505:20 CB DA  JSR $DACB

 0A:8508:4C 51 85  JMP $8551                ; EXIT

Step 2. Insert the Code

1. Open the Hex Editor

2. Using the debugger, Add a breakpoint with Address: 84E4 and Execute and Disable the other breakpoints

3. Reload and run until breakpoint

4. In the debugger, Seek To 9FFF and scroll up searching for empty space (not enough there)

5. In the debugger, Seek To BFFF and scroll up searching for empty space (we have room where these FFs are)

*Its usually a good idea to leave the first FF unless you know its not used but in this case I'm starting at the start of a fresh line

6. Type in our code so it fits.

At x284F4:

20 40 BF  JSR $BF40        ; NEW MAN VS CPU GRAPPLING CODE

At x2BF50:

MAN VS CPU GRAPPLING:

A0 1C     LDY #$1C        ; HP INDEX

B1 AE     LDA ($AE),Y        ; LOAD MAN HP

4A        LSR

4A        LSR

4A        LSR

C8        INY            ; PRESS INDEX

18        CLC

71 AE     ADC ($AE),Y        ; HP/8 + PRESS

91 AE     STA ($AE),Y        ; STORE IN MAN PRESS COUNTER

20 90 B1  JSR $B190        ; LOAD COM POINTER

A0 1C     LDY #$1C        ; HP INDEX

B1 3E     LDA ($3E),Y        ; LOAD COM HP

4A        LSR

4A        LSR

4A        LSR

C8        INY

91 3E     STA ($3E),Y        ; STORE HP/8 IN COM PRESS COUNTER

A5 3D     LDA $003D        ; RANDOM NUMBER

29 0F     AND #$0F        ; MAKE RANDOM x0-F

18        CLC

71 3E     ADC ($3E),Y        ; HP/8 + RANDOM

91 3E     STA ($3E),Y        ; STORE IN COM PRESS COUNTER

; RETURN TO NORMAL

B1 AE     LDA ($AE),Y        ; LOAD MAN PRESS COUNTER AS BEFORE

60        RTS

At x284E5

; RETURN HERE

EA        NOP

D1 3E     CMP ($3E),Y        ; REPLACE CMP #$02 with COM PRESS COUNTER

Step 3. Test the game to make sure everything works and the inserted code never gets swapped out when its needed

--------------------

Repeat with a Man vs Man grapple to determine if the same code or new code but I'll leave that to you to work on your skills =)

Link to comment
Share on other sites

  • 2 weeks later...
  • 7 months later...

I wish I could get a better handle on this. Maybe I'm just too spoiled by modern day debuggers where you see where you're currently at in the code while viewing what's going on on the screen.  It's an exercise in frustration just to figure out where in the code you are at at any given time to me. I'm pretty good at figuring out patterns and putting the puzzle together once I have some sort of reference point ,but I'm like selecting players and changing screens, seeing no indication that anything is happening in the active debug window.


Edited by Dusto
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...