Jump to content

jstout

Members
  • Posts

    545
  • Joined

  • Last visited

  • Days Won

    5

Reputation Activity

  1. Upvote
    jstout got a reaction from kamphuna8 in TSBm 1.3: Making your own FACES   
    Here is an example of how the faces are done:
     
    Frank Reich:

    x1C054 $A064 (POINTER) = B9A3
    x1C3C9 $A3B9 (DESIGN) = CC10 CF60 CDCC CEBD CF97 B074
    x1CC20 $AC10 (HAIR) = 700088 704090 710888 710890 7A0080 7A4098 FE
    x1CDDC $ADCC (EARS) = 7A0080 7A4098 380800 384818 3A1000 3A5018 FE
    x1CECD $AEBD (MOUTH) =  221408 225410 FE
    x1CF70 $AF60 (EYES) = 1B0988 1B4990 FE
    x1CFA7 $AF97 (LOWER HEAD) =  021008 025010 071808 075810 FE
    x1D084 $B074 (UPPER HEAD) =  210008 214010 000808 004810 FF

    Format: TILE ROW COLUMN
    *ROW = +00 = NORMAL, +40 = HORIZONTAL MIRROR, +80 = VERTICAL MIRROR, +C0 = HORIZONTAL AND VERTICAL MIRROR
    *COLUMN = +00 = PALETTE 0, +40 = PALETTE 01, +80 = PALETTE 02, +C0 = PALETTE 03
    FE = NEXT
    FF = END
  2. Upvote
    jstout got a reaction from buck in NES Programming Info   
    I'm hoping the links work as this would be cleaner than having a few dozen posts thrown all about.  This is still a work in progress with more in the future and the below files are still subject to changes/improvements as I'm not happy with all of them.  All demos should contain source files for the ca65 assembler and a working rom.  For those that read these please let me know of things that are good, bad, and need much more clarification.

     

    Complete Folder

     

    6502:

    Number Formats

    Registers

    Processor Status Flags

    Opcodes - Transfer Operations

    Opcodes - Other Operations

    Opcodes - Programming Model

    Addressing Modes

    Complete Opcodes

    Basic Math

     

    NES Programming:

    Memory Map

    NES Header

    PPU Registers

    Skeleton ROM

    Palettes            Demo

    Sprites             Demo

    Controllers         Demo

    Backgrounds         Demo

    Scrolling           Demo

    Sprite 0 Hit        Demo

    Animated Sprites    Demo

    Camera Window       Demo

    Collision Detection Demo

    MMC3                Demo
  3. Upvote
    jstout got a reaction from Neerrm in NES Programming Info   
    I'm hoping the links work as this would be cleaner than having a few dozen posts thrown all about.  This is still a work in progress with more in the future and the below files are still subject to changes/improvements as I'm not happy with all of them.  All demos should contain source files for the ca65 assembler and a working rom.  For those that read these please let me know of things that are good, bad, and need much more clarification.

     

    Complete Folder

     

    6502:

    Number Formats

    Registers

    Processor Status Flags

    Opcodes - Transfer Operations

    Opcodes - Other Operations

    Opcodes - Programming Model

    Addressing Modes

    Complete Opcodes

    Basic Math

     

    NES Programming:

    Memory Map

    NES Header

    PPU Registers

    Skeleton ROM

    Palettes            Demo

    Sprites             Demo

    Controllers         Demo

    Backgrounds         Demo

    Scrolling           Demo

    Sprite 0 Hit        Demo

    Animated Sprites    Demo

    Camera Window       Demo

    Collision Detection Demo

    MMC3                Demo
  4. Upvote
    jstout got a reaction from quince3800 in NES Programming Info   
    I'm hoping the links work as this would be cleaner than having a few dozen posts thrown all about.  This is still a work in progress with more in the future and the below files are still subject to changes/improvements as I'm not happy with all of them.  All demos should contain source files for the ca65 assembler and a working rom.  For those that read these please let me know of things that are good, bad, and need much more clarification.

     

    Complete Folder

     

    6502:

    Number Formats

    Registers

    Processor Status Flags

    Opcodes - Transfer Operations

    Opcodes - Other Operations

    Opcodes - Programming Model

    Addressing Modes

    Complete Opcodes

    Basic Math

     

    NES Programming:

    Memory Map

    NES Header

    PPU Registers

    Skeleton ROM

    Palettes            Demo

    Sprites             Demo

    Controllers         Demo

    Backgrounds         Demo

    Scrolling           Demo

    Sprite 0 Hit        Demo

    Animated Sprites    Demo

    Camera Window       Demo

    Collision Detection Demo

    MMC3                Demo
  5. Upvote
    jstout got a reaction from Knobbe in NES Programming Info   
    I'm hoping the links work as this would be cleaner than having a few dozen posts thrown all about.  This is still a work in progress with more in the future and the below files are still subject to changes/improvements as I'm not happy with all of them.  All demos should contain source files for the ca65 assembler and a working rom.  For those that read these please let me know of things that are good, bad, and need much more clarification.

     

    Complete Folder

     

    6502:

    Number Formats

    Registers

    Processor Status Flags

    Opcodes - Transfer Operations

    Opcodes - Other Operations

    Opcodes - Programming Model

    Addressing Modes

    Complete Opcodes

    Basic Math

     

    NES Programming:

    Memory Map

    NES Header

    PPU Registers

    Skeleton ROM

    Palettes            Demo

    Sprites             Demo

    Controllers         Demo

    Backgrounds         Demo

    Scrolling           Demo

    Sprite 0 Hit        Demo

    Animated Sprites    Demo

    Camera Window       Demo

    Collision Detection Demo

    MMC3                Demo
  6. Upvote
    jstout got a reaction from buck in Passing Loft   
    Passing loft is just part of creating the arc you see in the game.  The Arc needs to know other things like velocity to create a pass that will hit the mark.  But if test or watch the video then you'll see the xFF loft is a straight line and the x01 has some upward movement but nothing that would be comical so all the x30 values will look fairly similar.

     

    >http://www.youtube.com/watch?v=KsFvQ8MwaNc
  7. Upvote
    jstout got a reaction from bruddog in A great intro to 6502 Assembly   
    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 =)
  8. Upvote
    jstout got a reaction from Knobbe in Passing Loft   
    Passing loft is just part of creating the arc you see in the game.  The Arc needs to know other things like velocity to create a pass that will hit the mark.  But if test or watch the video then you'll see the xFF loft is a straight line and the x01 has some upward movement but nothing that would be comical so all the x30 values will look fairly similar.

     

    >http://www.youtube.com/watch?v=KsFvQ8MwaNc
  9. Upvote
    jstout got a reaction from GameplayLoop in A great intro to 6502 Assembly   
    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 =)
  10. Upvote
    jstout got a reaction from bruddog in QB and Punt Returner Ball Control   
    I've learned more about the code since then.  The original code is below:
    x2869E:    LDY #$08             ; PLAYER ID INDEX    LDA ($AE),Y         ; PLAYER ID    TAX    LDA $70    AND #$1C    CMP #$10    BCS @TACKLED    CMP #$08    BCS @KR_PR          ; KR/PR    TXA    EOR $70    BMI @QB_OL_PR    TXA    AND #$0F             ; PLAYER #    BEQ @QB_OL_PR       ; QB    CMP #$06    BCS @QB_OL_PR       ; OL    TXA    JSR L_DD8D    JMP @SKILL          ; SKILL PLAYER@KR_PR:    CMP #$0A    BCS @QB_OL_PR       ; PR EXIT    ORA #$10             ; GET KR ID    STA $45    TXA    AND #$80    ORA $45    JSR L_DD98@SKILL:    LDY #$86             ; GET PLAYER BALL CONTROL    JSR L_DDAA    TAY    LDA $3D                 ; RANDOM    CMP BALL_CONTROL_VALUES,Y    ; BALL CONTROL SKILL    BCS @TACKLED             ; TACKLED?    JMP @FUMBLED             ; FUMBLED@QB_OL_PR:    LDA $3D                ; RANDOM    CMP #$0C             ; 44 SKILL    BCS @TACKLED             ; TACKLED?@FUMBLED:                 ; FUMBLE ROUTINE    LDY #$01    LDA ($AE),Y    AND #$DF    STA ($AE),Y    JSR L_21_BA47    JMP L_21_85A6@TACKLED:                 ; TACKLED ROUTINE    LDA $71    ORA #$80    STA $71    JMP L_21_85A6BALL_CONTROL_VALUES:.BYTE $12,$11,$10,$0F,$0E,$0D,$0C,$0B,$0A,$09,$08,$07,$06,$05,$04,$03The hack posted here uses the first lines LDY #$08 as the PRs skill index (which was 56 skill) for the CMP BALL_CONTROL_VALUES,Y line.  The QB kept the branch listed about for the skill value.
     
    Its quite possible to hack this using tables for a team's QB and PR ball control value.  Or even to have the PR use their own ball control skill.
  11. Upvote
    jstout got a reaction from quince3800 in QB and Punt Returner Ball Control   
    I've learned more about the code since then.  The original code is below:
    x2869E:    LDY #$08             ; PLAYER ID INDEX    LDA ($AE),Y         ; PLAYER ID    TAX    LDA $70    AND #$1C    CMP #$10    BCS @TACKLED    CMP #$08    BCS @KR_PR          ; KR/PR    TXA    EOR $70    BMI @QB_OL_PR    TXA    AND #$0F             ; PLAYER #    BEQ @QB_OL_PR       ; QB    CMP #$06    BCS @QB_OL_PR       ; OL    TXA    JSR L_DD8D    JMP @SKILL          ; SKILL PLAYER@KR_PR:    CMP #$0A    BCS @QB_OL_PR       ; PR EXIT    ORA #$10             ; GET KR ID    STA $45    TXA    AND #$80    ORA $45    JSR L_DD98@SKILL:    LDY #$86             ; GET PLAYER BALL CONTROL    JSR L_DDAA    TAY    LDA $3D                 ; RANDOM    CMP BALL_CONTROL_VALUES,Y    ; BALL CONTROL SKILL    BCS @TACKLED             ; TACKLED?    JMP @FUMBLED             ; FUMBLED@QB_OL_PR:    LDA $3D                ; RANDOM    CMP #$0C             ; 44 SKILL    BCS @TACKLED             ; TACKLED?@FUMBLED:                 ; FUMBLE ROUTINE    LDY #$01    LDA ($AE),Y    AND #$DF    STA ($AE),Y    JSR L_21_BA47    JMP L_21_85A6@TACKLED:                 ; TACKLED ROUTINE    LDA $71    ORA #$80    STA $71    JMP L_21_85A6BALL_CONTROL_VALUES:.BYTE $12,$11,$10,$0F,$0E,$0D,$0C,$0B,$0A,$09,$08,$07,$06,$05,$04,$03The hack posted here uses the first lines LDY #$08 as the PRs skill index (which was 56 skill) for the CMP BALL_CONTROL_VALUES,Y line.  The QB kept the branch listed about for the skill value.
     
    Its quite possible to hack this using tables for a team's QB and PR ball control value.  Or even to have the PR use their own ball control skill.
  12. Upvote
    jstout got a reaction from quince3800 in Possible to "swap" PC and PA?? (NES TSB)   
    Change x29FEC from x87 to x88 and change the x88 to x87 in the PC/PA hack to reverse the values.  Or you can flip the ratings for all the QBs.

  13. Upvote
    jstout got a reaction from GameplayLoop in Possible to "swap" PC and PA?? (NES TSB)   
    Change x29FEC from x87 to x88 and change the x88 to x87 in the PC/PA hack to reverse the values.  Or you can flip the ratings for all the QBs.

  14. Upvote
    jstout got a reaction from buck in Possible to "swap" PC and PA?? (NES TSB)   
    Change x29FEC from x87 to x88 and change the x88 to x87 in the PC/PA hack to reverse the values.  Or you can flip the ratings for all the QBs.

  15. Upvote
    jstout got a reaction from Knobbe in A great intro to 6502 Assembly   
    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
     
  16. Upvote
    jstout got a reaction from GameplayLoop in sorting Receiving stats by yards instead of catches   
    Try changing x304F1 from 08 to 09

  17. Upvote
    jstout got a reaction from buck in sorting Receiving stats by yards instead of catches   
    Try changing x304F1 from 08 to 09

  18. Upvote
    jstout got a reaction from buck in Text Editing Alphabet   
    xXX = %76543210 (Listing Bit Numbers)
    x55 = %01010101
    (%00 = Palette 0, %01 = Palette 1, %10 = Palette 2, %11 = Palette 3)
     
    An attribute byte = 4x4 Tiles (32 pixels x 32 pixels) with each Palette Block = 2x2 Tiles (16 pixels x 16 pixels)
    [ ][ ][ ][ ]
    [ ][ ][ ][ ]
    [ ][ ][ ][ ]
    [ ][ ][ ][ ]
     
    The Top Left 2x2 uses bits 10
    The Top Right 2x2 uses bits 32
    The Bottom Left 2x2 uses bits 54
    The Bottom Right 2x2 uses bits 76
     
    So x55 has all 4 Palette Blocks %01 = Palette 1
  19. Upvote
    jstout got a reaction from DFM in TSBm 1.3: Making your own FACES   
    I wouldn't say that is entirely right.  The high 2 bits control mirroring and the low 6 bits control the row as %VHRRRRRR (V = Vertical Mirror, H = Horizontal Mirror, R = Row).

     

    So:

    x00-x3F = Set Tile Normally (Row 00 to 3F)

    x40-x7F = Set Tile with Horizontal Mirror (Row 00-3F)

    x80-xBF = Set Tile with Vertical Mirror (Row 00-3F)

    xC0-xFF = Set Tile with Horizontal and Vertical Mirror (Row 00-3F)
  20. Upvote
    jstout got a reaction from Knobbe in TSBm 1.3: Making your own FACES   
    I wouldn't say that is entirely right.  The high 2 bits control mirroring and the low 6 bits control the row as %VHRRRRRR (V = Vertical Mirror, H = Horizontal Mirror, R = Row).

     

    So:

    x00-x3F = Set Tile Normally (Row 00 to 3F)

    x40-x7F = Set Tile with Horizontal Mirror (Row 00-3F)

    x80-xBF = Set Tile with Vertical Mirror (Row 00-3F)

    xC0-xFF = Set Tile with Horizontal and Vertical Mirror (Row 00-3F)
  21. Upvote
    jstout got a reaction from keithisgood in TSBm 1.3: Making your own FACES   
    Here is an example of how the faces are done:
     
    Frank Reich:

    x1C054 $A064 (POINTER) = B9A3
    x1C3C9 $A3B9 (DESIGN) = CC10 CF60 CDCC CEBD CF97 B074
    x1CC20 $AC10 (HAIR) = 700088 704090 710888 710890 7A0080 7A4098 FE
    x1CDDC $ADCC (EARS) = 7A0080 7A4098 380800 384818 3A1000 3A5018 FE
    x1CECD $AEBD (MOUTH) =  221408 225410 FE
    x1CF70 $AF60 (EYES) = 1B0988 1B4990 FE
    x1CFA7 $AF97 (LOWER HEAD) =  021008 025010 071808 075810 FE
    x1D084 $B074 (UPPER HEAD) =  210008 214010 000808 004810 FF

    Format: TILE ROW COLUMN
    *ROW = +00 = NORMAL, +40 = HORIZONTAL MIRROR, +80 = VERTICAL MIRROR, +C0 = HORIZONTAL AND VERTICAL MIRROR
    *COLUMN = +00 = PALETTE 0, +40 = PALETTE 01, +80 = PALETTE 02, +C0 = PALETTE 03
    FE = NEXT
    FF = END
  22. Upvote
    jstout got a reaction from DFM in TSBm 1.3: Making your own FACES   
    Here is an example of how the faces are done:
     
    Frank Reich:

    x1C054 $A064 (POINTER) = B9A3
    x1C3C9 $A3B9 (DESIGN) = CC10 CF60 CDCC CEBD CF97 B074
    x1CC20 $AC10 (HAIR) = 700088 704090 710888 710890 7A0080 7A4098 FE
    x1CDDC $ADCC (EARS) = 7A0080 7A4098 380800 384818 3A1000 3A5018 FE
    x1CECD $AEBD (MOUTH) =  221408 225410 FE
    x1CF70 $AF60 (EYES) = 1B0988 1B4990 FE
    x1CFA7 $AF97 (LOWER HEAD) =  021008 025010 071808 075810 FE
    x1D084 $B074 (UPPER HEAD) =  210008 214010 000808 004810 FF

    Format: TILE ROW COLUMN
    *ROW = +00 = NORMAL, +40 = HORIZONTAL MIRROR, +80 = VERTICAL MIRROR, +C0 = HORIZONTAL AND VERTICAL MIRROR
    *COLUMN = +00 = PALETTE 0, +40 = PALETTE 01, +80 = PALETTE 02, +C0 = PALETTE 03
    FE = NEXT
    FF = END
  23. Upvote
    jstout got a reaction from buck in TSBm 1.3: Making your own FACES   
    Here is an example of how the faces are done:
     
    Frank Reich:

    x1C054 $A064 (POINTER) = B9A3
    x1C3C9 $A3B9 (DESIGN) = CC10 CF60 CDCC CEBD CF97 B074
    x1CC20 $AC10 (HAIR) = 700088 704090 710888 710890 7A0080 7A4098 FE
    x1CDDC $ADCC (EARS) = 7A0080 7A4098 380800 384818 3A1000 3A5018 FE
    x1CECD $AEBD (MOUTH) =  221408 225410 FE
    x1CF70 $AF60 (EYES) = 1B0988 1B4990 FE
    x1CFA7 $AF97 (LOWER HEAD) =  021008 025010 071808 075810 FE
    x1D084 $B074 (UPPER HEAD) =  210008 214010 000808 004810 FF

    Format: TILE ROW COLUMN
    *ROW = +00 = NORMAL, +40 = HORIZONTAL MIRROR, +80 = VERTICAL MIRROR, +C0 = HORIZONTAL AND VERTICAL MIRROR
    *COLUMN = +00 = PALETTE 0, +40 = PALETTE 01, +80 = PALETTE 02, +C0 = PALETTE 03
    FE = NEXT
    FF = END
  24. Upvote
    jstout got a reaction from DFM in Trying to explain the concept of RS RP and MS to malferds...   
    Here is the straight up data and how it works.

    Here is the default skill chart:


    Skill RS RP MS*
    6 0E 0D 15/25
    13 0F 0C 16/26
    19 10 0B 17/27
    25 11 0A 18/28
    31 12 09 19/29
    38 13 08 1A/2A
    44 14 07 1B/2B
    50 15 06 1C/2C
    56 16 05 1D/2D
    63 17 04 1E/2E
    69 18 03 1F/2F
    75 19 03 20/30
    81 1A 02 21/31
    88 1B 02 22/32
    94 1C 01 23/33
    100 1D 01 24/34
    *Offense/Defense


    When a player is standing still he has zero speed. Once he moves his speed is equal to RS and his RP starts. Every player cycle, RP is decreased by 1 and when his RP is equal to 0 then his RS is increased by 1 and RP restarts. With each RS increase the player will speed up. Once RS is equal or greater to MS then the player stops accelerating.

    RS Chart is x2BE84 to x2BE93
    RP Chart is x2BE74 to x2BE83
    MS Chart is x3DFDF to x3DFEE (Offense)
    MS Chart is x3DFEF to x3DFFE (Defense)
  25. Upvote
    jstout got a reaction from tiredtonsofclay in Editing Large Helmets   
    I didn't see any documentation on editing the large helmets in Tecmo Super Bowl for the NES so here is some basic info. Some knowledge of hexidecimal is helpful here.

    I'll start with the locations of where the logos are told to be placed.

    Team Offset Pointer
    Buffalo x1008C C0A6
    Indianapolis x1008A B2A6
    Miami x1008E CEA6
    New England x10090 DCA6
    NY Jets x10072 F3A5
    Cincinnati x10074 01A6
    Cleveland x10076 0FA6
    Houston x10078 1DA6
    Pittsburgh x1007A 2BA6
    Denver x1007C 39A6
    Kansas City x1007E 47A6
    LA Raiders x10092 EAA6
    San Diego x10094 F8A6
    Seattle x10084 88A6
    Washington x1009A 22A7
    NY Giants x10088 A4A6
    Philadelphia x10096 06A7
    Phoenix x10098 14A7
    Dallas x10086 96A6
    Chicago x1009C 30A7
    Detroit x1009E 3EA7
    Green Bay x100A0 4CA7
    Minnesota x100A2 5AA7
    Tampa Bay x100A4 68A7
    San Francisco x100AC A0A7
    LA Rams x100A8 84A7
    New Orleans x100AA 92A7
    Atlanta x100A6 76A7

    Example: Lets swap Buffalo and Indianapolis. At x1008A, put C0 A6 B2 A6. The Buffalo and Indianapolis logos should have been switched. Go ahead and put it back now.

    Thats not really what we are looking for so lets move on to what is being pointed to.

    I'll use Cleveland and Houston for later examples so lets calculate their offset. Cleveland 0FA6, ("0F" + 10) ("A6" + 60) = 1F 06, then swap and add a x1 for x1061F. Same for Houston and you get x1062D.

    Cleveland points to the line:
    F6 70 FF FF FF FC 08 F8 36 42 92 22 AB 17
    Houston points to the line:
    F6 70 FF FF FF FC 09 F8 37 3A 92 2B AB 17

    From here what we are interested in is Cleveland's "36 42 92 22" and Houston's "37 3A 92 2B". The first hex moves the teams logo up and down. The second hex moves the teams logo left and right. The final two hexes direct us to the design of the logo.

    Example: Lets move Houston's logo. Change "37 3A 92 2B" to 30 30 92 2B. Houston's logo should be almost off the helmet now. Go ahead and put it back now.

    Thats a little useful but we want the actual design so lets find that location. For Cleveland 92 22, ("92" + 90) ("22" + 10) = 1232, add a x1 to that a we have x11232. Same for Houston and we get x1123B.

    Houston's logo has more data so lets check that out. The line directed from above will be:
    9F 39 1E 3D 34 01 36 05 3C 80 39 1F 3D 35 01 37 05 3D 81 05 39 FF

    Now the helmets are drawn on a grid, main columns are 9E 9F 80 81 82 but a few logos have been moved so far right like Cleveland that 9B 9C 9D could be used. The main rows are 39 3D 01 05 09 0D 11 or by using 79 7D 41 45 49 4D 51 the tiles will be mirrored. Now we know the grid numbers lets read Houston's logo.

    Column 9F Row 39 Place Tile 1E, Row 3D Place Tile 34, Row 01 Place Tile 36, Row 05 Place Tile 3C, Column 80 Row 39 Place Tile 1F, Row 3D Place Tile 35, Row 01 Place Tile 37, Row 05 Place Tile 3D, Column 81 Row 05 Place Tile 39 and Stop using FF

    Looking at a more advanced design like:
    9E 3D 00 01 02 05 08 9F 3D 01 01 03 05 09 80 3D 04 01 06 05 0C FC 36 81 3D 0A FF
    Everything is going smooth until you reach the FC. FC tells it the following locations (Column 81 Row 3D Tile 0A) will be shifted to place 36. I haven't tested the shifts thoroughly yet.

    Example: Lets change Houston's logo. Replace their line with:
    9E 3D 1E 01 34 05 36 9F 3D 1F 01 35 05 37 80 3D 39 01 3C 05 3D FF. The logo should have the base legs to the right of the upper section. Go ahead and put it back after you looked.

    Ok, that was great but many of you now want to know if you can use tiles from other teams especially if they go unused.

    Example: Lets take a tile away from Cleveland and give the rom space to Houston and at the same time use a tile from Indianapolis. At x11232, change the line to:
    9F 3D 3B 80 3D 3E FF 9F 09 1E 39 09
    Those paying real attention would have noticed that the location of Houston's starting point changed. We need to go back above to x1062D and edit our direction spot to "92 29". Go ahead and put it back when done.

    Now to edit the colors. Starting at x23D79 is 30 16 12 10 30 30 12 26 which is the colors of Buffalo. The first three colors are the helmet palette, the next two are the facemask palette, and the final three are the logo palette. Teams will be in order from Buffalo to Atlanta.

    Well thats the basics on editing the large helmets. The big trick seems to be planning the rom space and selecting the proper tiles to get placed.

    Unfortunately, since I've been busy I've yet to find how some teams like Cincinnati and the LA Rams get the background objects on their helmets (Cincinnati's stripes for example) or how the tiles get numbered for the helmets. But I'm sure this is enough info for now.
×
×
  • Create New...