News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Poll

Patching Mysidian Tower Orbs Behavior: http://www.romhacking.net/forum/index.php?topic=29704.msg388989#msg388989

Leave it, flawed as it is; the remakes retained this behavior after all
3 (13.6%)
Keep the random single-character bonus, but remove the 4th character from the RNG
4 (18.2%)
Grant the bonus to all characters, giving them a much-earned buff at this point in the game.
15 (68.2%)

Total Members Voted: 22

Author Topic: Final Fantasy II Restored  (Read 27734 times)

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #120 on: January 21, 2020, 10:24:12 am »
This looks really thorough. I just have to make sense of what's happening here...

We only want the INC to happen on any one of the given counters at any given time, thus why I was thinking of using the subroutine. I can't tell but it seems like this loop increases more than one counter at a time? Sorry, I'm still learning, bear with me. I'm not sure I understand the addresses in the table, either, or if they're just placeholders. Essentially what I need to make the table and indirect addressing routine for was so that I can turn my LDA $7CF3,X and INC $7CF3,X in that subroutine into, say, LDA $01,X and INC $01,X (just as an example, I don't know if those addresses are being used or what).

I'll try to make sense of and play around with this example, but knowing that it would be less than 45 bytes has me convinced that this method is the optimal way to go.

Cyneprepou4uk

  • Sr. Member
  • ****
  • Posts: 325
  • I am the baldest romhacker
    • View Profile
Re: Final Fantasy II Restored
« Reply #121 on: January 21, 2020, 10:31:03 am »
Yes, this loop is for increasing all 6 address at the same time.

For example, we take byte #$04 from the table, add #$01 from player id, and we get LDA $7CF3,X @ $7CF8 (Character #2 spell slot or something)

If you want to increase a single address instead of all, get rid of the loop and load a needed Y value before JSR to this subroutine. For example, if you need to increase "Character black magic use counter", then LDY #$04 + JSR


Quote
if they're just placeholders

Just placeholders. I'm using my own rom which is designed for quick code testing.
« Last Edit: January 21, 2020, 10:45:15 am by Cyneprepou4uk »
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #122 on: January 21, 2020, 11:36:55 am »
Okay, I get it. Let me try doing a mock-up below...

EDIT: Mock-up moved down.
« Last Edit: January 21, 2020, 03:30:56 pm by redmagejoe »

Cyneprepou4uk

  • Sr. Member
  • ****
  • Posts: 325
  • I am the baldest romhacker
    • View Profile
Re: Final Fantasy II Restored
« Reply #123 on: January 21, 2020, 12:15:35 pm »
Should I jump in now or you can handle it yourself?
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #124 on: January 21, 2020, 12:16:46 pm »
Actually, maybe you should. I feel like I may be going down the wrong path here, and I don't want to end up wasting time chasing wild geese when you probably are furrowing your brow at what I'm trying to do right now.
« Last Edit: January 21, 2020, 03:27:14 pm by redmagejoe »

Cyneprepou4uk

  • Sr. Member
  • ****
  • Posts: 325
  • I am the baldest romhacker
    • View Profile
Re: Final Fantasy II Restored
« Reply #125 on: January 21, 2020, 12:22:40 pm »
It looks like you want to use current X instead of adding ID from $009E.

Since you can't add X directly, transfer it to A, then ADC,Y from the table and transfer result back to X.

And don't forget to clear C somewhere before executing addition
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #126 on: January 21, 2020, 03:28:10 pm »
It looks like you want to use current X instead of adding ID from $009E.

Since you can't add X directly, transfer it to A, then ADC,Y from the table and transfer result back to X.

And don't forget to clear C somewhere before executing addition

Oh I actually see what you're saying. I'm doing things the hard way rather than the smart way, plus I'm constrained by the modes available for each instruction. I'll have to take special consideration for spell slots, which already have some funky things done to X, but I'm going to update my mock-up with something a bit more concise...

WIP
Code: [Select]
Fit in 2 bytes for LDA #$?? (offset in bottom code block), try to wiggle 2 bytes in.
Replace INCs in original with JSR to below.

00:8101: 18        CLC
00:8102: 65 9E     ADC $9E        ; adds character ID offset with the offset loaded into A before the JSR
00:8104: AA        TAX            ; put offset into X
00:8105: BD F3 7C  LDA $7CF3,X    ; load value from counter address now modified by counter offset and player id
00:8107: C9 C8     CMP #$C8       ; compare to overflow protection (200)
00:8109: B0 03     BCS $810E      ; skip increasing
00:810B: FE F3 7C  INC $7CF3,X    ; increase value
00:810E: 60        RTS            ; if code is used as a subroutine

0x031478|$0C:$9468:  $7CF3 << $00 ; Character #1 physical attack counter
0x031E68|$0C:$9E58:  $7CF7 << $04 ; Character #1 spell slot #1 battle use counter (this one may cause trouble)
0x03257B|$0C:$A56B:  $7D37 << $40; Character #1 counter for times physically attacked by enemy
0x03261D|$0C:$A60D:  $7D3B << $44; Character #1 counter for times magically attacked by enemy
0x031E75|$0C:$9E65:  $7D3F << $4C; Character #1 black magic use counter
0x031E7A|$0C:$9E6A:  $7D43 << $50; Character #1 white magic use counter

I know there's still a few considerations I need to look at, like how the state of registers or CPU flags will affect things returning from this sub-routine. I also need to take a look at the special case going into the JSR from spell slot use counter... Below is the base code for spell slot use counter.

Code: [Select]
; control flow target (from $9E42)
0x031E56|$0C:$9E46:A5 9E    LDA $9E   
0x031E58|$0C:$9E48:0A      ASL       
0x031E59|$0C:$9E49:0A      ASL       
0x031E5A|$0C:$9E4A:0A      ASL       
0x031E5B|$0C:$9E4B:0A      ASL       
0x031E5C|$0C:$9E4C:85 00    STA $00   
0x031E5E|$0C:$9E4E:A5 54    LDA $54   
0x031E60|$0C:$9E50:0A      ASL       
0x031E61|$0C:$9E51:0A      ASL       
0x031E62|$0C:$9E52:18      CLC       
0x031E63|$0C:$9E53:65 53    ADC $53   
0x031E65|$0C:$9E55:65 00    ADC $00   
0x031E67|$0C:$9E57:AA      TAX       
0x031E68|$0C:$9E58:FE F7 7C INC $7CF7,X ; Character #1 spell slot #1 battle use counter
0x031E6B|$0C:$9E5B:A6 9E    LDX $9E   
0x031E6D|$0C:$9E5D:A0 2A    LDY #$2A   
0x031E6F|$0C:$9E5F:B1 80    LDA ($80),Y
0x031E71|$0C:$9E61:C9 15    CMP #$15   
0x031E73|$0C:$9E63:B0 05    BCS $9E6A 
0x031E75|$0C:$9E65:FE 3F 7D INC $7D3F,X ; Character #1 black magic use counter
0x031E78|$0C:$9E68:D0 03    BNE $9E6D 
; control flow target (from $9E63)
0x031E7A|$0C:$9E6A:FE 43 7D INC $7D43,X ; Character #1 white magic use counter
; control flow target (from $9E68)
0x031E7D|$0C:$9E6D:A0 20    LDY #$20   
0x031E7F|$0C:$9E6F:20 9B 94 JSR $949B 
0x031E82|$0C:$9E72:F0 02    BEQ $9E76 
; control flow target (from $9E21)
0x031E84|$0C:$9E74:C6 9E    DEC $9E   
; control flow target (from $9E00, $9E72)
0x031E86|$0C:$9E76:20 90 9A JSR $9A90 
0x031E89|$0C:$9E79:20 4A 98 JSR $984A 
0x031E8C|$0C:$9E7C:20 3E 9B JSR $9B3E 
0x031E8F|$0C:$9E7F:A9 00    LDA #$00   
0x031E91|$0C:$9E81:8D BA 7C STA $7CBA 
0x031E94|$0C:$9E84:60      RTS

This also shows the pre-JSR code for three of the counters, so this would be a good way for me to figure out where I can find space for the 2-4 bytes I need before the INC I'd be replacing with a JSR. Maybe I should have LDX #$00 along with the LDA #$<offset> going into the JSR for the other 5 counters, and incorporate an addition of X into the routine so that spell slots offsets are properly maintained? I'm not sure if that's possible. I keep ending up with the correct offset in A from the spell slot counter, but because I'm trying to use a single sub-routine, getting my LDA $7CF3,X to essentially be $7CF7,X is a roadblock. I'm trying to figure out how I can add that #$04 when A is $9E + whatever all that math above $9E57 spits out, but I don't know how I can add into the Accumulator the value stored in, say, Y, since ADC uses Y as an offset.

Code: [Select]
Don't remove TAX before JSR, A = $9E + spell offset already. Find way to convert below to allow F3 instead of F7, working in the #$04 somehow. Current layout works if we are only replacing the INC with a JSR to a separate sub-routine listed below. Try to find a way to make it feasible to combine this with the one used for the other 5.

00:8105: BD F7 7C  LDA $7CF7,X    ; load value from counter address now modified by counter offset and player id
00:8107: C9 C8     CMP #$C8       ; compare to overflow protection (200)
00:8109: B0 03     BCS $810E      ; skip increasing
00:810B: FE F7 7C  INC $7CF7,X    ; increase value
00:810E: 60        RTS            ; if code is used as a subroutine
« Last Edit: January 21, 2020, 04:14:55 pm by redmagejoe »

Cyneprepou4uk

  • Sr. Member
  • ****
  • Posts: 325
  • I am the baldest romhacker
    • View Profile
Re: Final Fantasy II Restored
« Reply #127 on: January 21, 2020, 04:08:09 pm »
Code: [Select]
00:8101: 18        CLC
00:8102: 65 9E     ADC $9E
00:8104: A8        TAY

So you've deleted the table and decided to input base offset to the sub itself, yeah, that's much better.

I don't see what is so special about $9E58.

No, wait, I see what it is.

Well, the are several ways to bypass that  :)

Screw this topic with its communication by editing messages. Send a pm or contact me via my site, and we'll figure something out
« Last Edit: January 21, 2020, 04:20:30 pm by Cyneprepou4uk »
iromhacker.ru - NES ROM hacking tutorials for beginners. Please use Google Translate browser extension

Leviathan Mist

  • Jr. Member
  • **
  • Posts: 40
    • View Profile
Re: Final Fantasy II Restored
« Reply #128 on: January 21, 2020, 05:32:13 pm »
Screw this topic with its communication by editing messages. Send a pm or contact me via my site, and we'll figure something out

No, please continue. I'm learning a lot by following the discussion. :)

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #129 on: January 21, 2020, 05:34:46 pm »
No, please continue. I'm learning a lot by following the discussion. :)

It's all good, he gave me some awesome advice (when doesn't Cyne give awesome advice?) and I'm going to post the mock-up here once it's good to go and walk through the suggestions he gave me to improve upon my previous method.

Code: [Select]
0x013B33: 221
0x013D5D: 689
0x015D77: 409
0x03400D: 3
0x0387CB: 69
0x03F75E: 178
0x03F83B: 21
0x03F858: 184
0x03FEFC: 196
0x03FFCD: 3
0x03FFDD: 19

Meanwhile, I decided to take a look at all the blocks of free space available in ROM before we start sticking our patches in them. So let's suppose I wanted to shift a small chunk of game code up 3 bytes, to turn our very last 19-byte region into a 22-byte region... Good idea or bad idea? I see the control flow so in theory, I should be able to chase down anything pointing to that code and amend it, yes?

Code: [Select]
; code -> free
0x03FFCD|$0F:$FFBD:00
; ... skipping $1 00 bytes
0x03FFCF|$0F:$FFBF:00

; free -> code
; call $01:$BFB0
; external control flow target (from $09:$BBB9)
0x03FFD0|$0F:$FFC0:A9 01    LDA #$01   
0x03FFD2|$0F:$FFC2:20 03 FE JSR $FE03  ; swap in PRG bank specified by A
; call to code in a different bank ($01:$BFB0)
0x03FFD5|$0F:$FFC5:20 B0 BF JSR $BFB0 
0x03FFD8|$0F:$FFC8:A9 09    LDA #$09   
0x03FFDA|$0F:$FFCA:4C 03 FE JMP $FE03  ; swap in PRG bank specified by A


; code -> free
0x03FFDD|$0F:$FFCD:00
; ... skipping $11 00 bytes
0x03FFEF|$0F:$FFDF:00



Here we are.

Code: [Select]
0x031478|$0C:$9468:20 4E F8 JSR $F84E ; Character #1 physical attack counter
0x031E68|$0C:$9E58:20 48 F8 JSR $F848 ; Character #1 spell slot #1 battle use counter
0x031E75|$0C:$9E65:20 5A F8 JSR $F85A ; Character #1 black magic use counter
0x031E7A|$0C:$9E6A:20 5E F8 JSR $F85E ; Character #1 white magic use counter
0x032569|$0C:$A559:20 52 F8     JSR $F852 ; Character #1 counter for times physically attacked by enemy
0x03257B|$0C:$A56B:20 56 F8     JSR $F856       ; Character #1 counter for times magically attacked by enemy

0x03F858|$0C:$F848:8A        TXA            ; JSR here from $9E58
0x03F859|$0C:$F849:18        CLC
0x03F85A|$0C:$F84A:69 04     ADC #$04
0x03F85C|$0C:$F84C:D0 15     BNE $F863      ; finish necessary math and jump down to rest of subroutine
0x03F85E|$0C:$F84E:A9 00     LDA #$00       ; JSR here from $9468
0x03F860|$0C:$F850:F0 0E     BEQ $F860
0x03F862|$0C:$F852:A9 40     LDA #$40       ; JSR here from $A559
0x03F864|$0C:$F854:D0 0A     BNE $F860
0x03F866|$0C:$F856:A9 44     LDA #$44       ; JSR here from $A56B
0x03F868|$0C:$F858:D0 06     BNE $F860
0x03F86A|$0C:$F85A:A9 4C     LDA #$4C       ; JSR here from $9E65
0x03F86C|$0C:$F85C:D0 02     BNE $F860
0x03F86E|$0C:$F85E:A9 50     LDA #$50       ; JSR here from $9E6A
0x03F870|$0C:$F860:18        CLC           
0x03F871|$0C:$F861:65 9E     ADC $9E        ; adds character ID offset with the offset loaded into A before the JSR
0x03F873|$0C:$F863:AA        TAX           
0x03F874|$0C:$F864:BD F3 7C  LDA $7CF3,X    ; load value from counter address now modified by counter offset and player id
0x03F877|$0C:$F867:C9 C8     CMP #$C8       ; compare to overflow protection (200)
0x03F879|$0C:$F869:B0 03     BCS $F873      ; skip increasing
0x03F87B|$0C:$F86B:FE F3 7C  INC $7CF3,X    ; increase value
0x03F87E|$0C:$F86E:60        RTS

I have to remember that $A56B and $A60D become $A559 and $A56B with my Enemy Magic-All Firion Spirit fix. I'd rather not make a separate standalone version of the patch as these fixes are intended to be comprehensive and come as a package, so I'll put a note when I put up the counter fix patch to only use it after the Firion Spirit fix.

Basically, to avoid having to try to find space in the game's main code and simply replace the INCs with JSRs, Cyne had the great idea of pointing the JSRs to different parts of the subroutine, and simply having the LDAs for the offsets within the subroutine, using branches to ensure that no more than one ever runs. There's a special case at the top for spell slot uses, since all of the math has already been done for which counter needs to be raised going into the JSR. In this way we can use a single 39-byte subroutine for all our counters, and overflow should no longer occur.

I believe that 120 is the highest you would have to raise a counter in any scenario to max out the potential benefit, be it spell or weapon levels, Spirit Up, Intellect Up, Strength Up, and while I don't know the nuances of Evasion or Magic Defense yet (man I am good at getting distracted from that project!), I can't imagine that you wouldn't gain a level in either from being hit 120 times. So 200 is a generous cap, while being far enough away from 255 that no scenario will possibly lead to overflow.

EDIT: Hmm... crashes when an action is taken. Wish I could figure out what's happening before that point, as when it's crashed, it's locked at an IRQ/BRK vector. Ah, I see... It's jumping to $87C1 in bank 0C. I need it to jump to $87C1 in bank 0E... How do I specify this?
« Last Edit: January 21, 2020, 10:49:51 pm by redmagejoe »

Disch

  • Hero Member
  • *****
  • Posts: 2770
  • NES Junkie
    • View Profile
Re: Final Fantasy II Restored
« Reply #130 on: January 21, 2020, 08:02:27 pm »
So I've only been sparsely paying attention to this conversation, but my understanding is that code is being analyzed largely in-emu and modifications are being done by hand in a hex editor?  No disassembly?

Is this correct?


If so, I might consider making a disassembly if one isn't available.  Not a fully commented one (doing that would take way too long -- the FF1 project spanned years), but a bare-bones functional disassembly should only take a few days.

I don't really want to repeat work that's already been done though, so is there a disassembly already out there that you guys are using?

Also a CDL file would be very useful, but not strictly necessary.  As I've never actually played this game before and know next to nothing about it, I'm not really up to the task of making one myself.  Is there one out there?  And if not, would anyone be willing to make one?

As far as assemblers go, I went with ca65 for the FF1 project because I liked the way it did local symbols and had the most consistent and clear syntax of other assemblers I looked at (and was modern enough to run on my machine at the time -- things like x816 wouldn't even run without an emulator).  Is everyone happy with ca65 or is there another preferred assembler I should shoot for?


(PS:  Thanks to MoN for helping me recover this account!)

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #131 on: January 21, 2020, 08:06:29 pm »
So I've only been sparsely paying attention to this conversation, but my understanding is that code is being analyzed largely in-emu and modifications are being done by hand in a hex editor?  No disassembly?

Is this correct?


If so, I might consider making a disassembly if one isn't available.  Not a fully commented one (doing that would take way too long -- the FF1 project spanned years), but a bare-bones functional disassembly should only take a few days.

I don't really want to repeat work that's already been done though, so is there a disassembly already out there that you guys are using?

Also a CDL file would be very useful, but not strictly necessary.  As I've never actually played this game before and know next to nothing about it, I'm not really up to the task of making one myself.  Is there one out there?  And if not, would anyone be willing to make one?

As far as assemblers go, I went with ca65 for the FF1 project because I liked the way it did local symbols and had the most consistent and clear syntax of other assemblers I looked at (and was modern enough to run on my machine at the time -- things like x816 wouldn't even run without an emulator).  Is everyone happy with ca65 or is there another preferred assembler I should shoot for?


(PS:  Thanks to MoN for helping me recover this account!)

Oh yeah, I put a link to abw's disassembly that he's been updating and I've been using and identifying for him to comment on, and he also has a CDL that he found on that same first page. I'll update my first post to include a link to the CDL. And yeah, I've been doing debugging and patching in a pretty rudimentary way, as you've described. :-[

And whatever tools are most comfortable for you Disch! I'm really humbled to see so many Final Fantasy romhackers peeking into this thread and offering to pitch in. I'm learning, but I feel like what I'd like to do may be more ambitious than my skillset allows. I'll keep doing everything I can to help though, and I'm immensely grateful to any contributions you'd be willing to make! There's going to be a lot of names on this project when it's all said and done. :)
« Last Edit: January 21, 2020, 08:12:39 pm by redmagejoe »

Disch

  • Hero Member
  • *****
  • Posts: 2770
  • NES Junkie
    • View Profile
Re: Final Fantasy II Restored
« Reply #132 on: January 21, 2020, 08:13:36 pm »
Ah!  Shame on me for missing all those links right in the first post!   :thumbsup:

Looks like abw and Jiggers both made disassemblies already -- and Jiggers' even looks to be reassemblable!  So yeah I guess you guys have it covered already.

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #133 on: January 21, 2020, 08:16:00 pm »
I think Jiggers has her hands full though with her own projects, so comments have been going into abw's disassembly, though I'd like to update the GitHub one at some point. I don't know if I have edit permissions though.

Seems I'm at a bit of a conundrum. Apparently I can't use that juicy free space because it's outside of the fixed bank. I'll have to use space that's within $C000-$FFFF, which means that currently I can only use that 184, 196, and the 3 and 19 that abw and I are already trying to use. Which reminds me, did anyone weigh in on shifting that code up three spaces and adjusting pointers accordingly?

I'm going to use 39 bytes at 0x03F858 to 0x03F87E for the combat counters fix.
« Last Edit: January 21, 2020, 08:33:02 pm by redmagejoe »

Disch

  • Hero Member
  • *****
  • Posts: 2770
  • NES Junkie
    • View Profile
Re: Final Fantasy II Restored
« Reply #134 on: January 21, 2020, 08:28:31 pm »
I think Jiggers has her hands full though with her own projects, so comments have been going into abw's disassembly, though I'd like to update the GitHub one at some point. I don't know if I have edit permissions though.

I *THINK* you can fork the repo even without write permissions, and make your changes there.  Then Jiggers (or someone else with write permission) could merge your fork back into the main repo if they want.

I don't really know how to do either of those things offhand, though -- I'd have to look it up  =x

But whatever.  Do things however it is easiest for you   :thumbsup:

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #135 on: January 21, 2020, 09:13:33 pm »
Curious issue... Now the game doesn't break at least, and the counter overflow protection DOES work. However, with spells at least, it appears some other spell counters are raising besides the one being used. I will record my observations while I test. All of these are being done on Firion, and I'm confident the issue will be the same on other characters, but I will test them when I have more room in my RAM watch list.

Spell Slot 1 (Fire) @ $7CF7, then @ $7CF4
Spell Slot 2 (Thunder) @ $7CF8, then @ $7CF5
Spell Slot 3 (Blizzard) @ $7CF9, then @ $7CF6
Spell Slot 4 (Flare) @ $7CFA, then @ $7CFA
Spell Slot 5 (Cure) @ $7CFB, then @ $7CF3

Clearly there are some shenanigans happening here with the spell slot counter code. Could it be that it doesn't handle the carry properly, and as a result, it's wrapping around back to a $7Cxx address when it should be at a $7Dxx address? Did I handle the additions wrong somewhere? I should set some breakpoints and see what exact values I'm getting. It looks like I'm somehow ending up 3 less than my previous value, when it should be tallying black magic or white magic counter at 3F or 43.
« Last Edit: January 21, 2020, 09:26:43 pm by redmagejoe »

abw

  • Sr. Member
  • ****
  • Posts: 344
    • View Profile
Re: Final Fantasy II Restored
« Reply #136 on: January 21, 2020, 10:27:12 pm »
If this does indeed cause a more uniform distribution as opposed to what before could be described as 12.5% (0-63), 37.5% (64-127), 37.5% (128-191), 12.5% (192-255), then it should solve the problem outright. I can't imagine it will harm any other mechanics in the game, as RNG should aim to be uniform anyway in this game's combat systems. Would you like to keep this under review as per your notes about avoiding that free space, or do you want me to slap it on the first post?
The actual distribution was 43/256 (16.8%), 85/256 (33.2%), 85/256 (33.2%), 43/256 (16.8%). Scanning the disassembly for uses of $42 (the RNG LUT index), I see a lot of places where the game sets it to a specific value (e.g. LDA #$08 STA $42), which kind of makes the lookup table not so random anymore, so it's possible there might be deeper RNG issues that simply fixing the overall distribution wouldn't address. Might as well add it to the first post for now; if I get around to analyzing the couple of calls where I can't easily verify that X <= A and find out that assuming the upper bound really is not smaller than the lower bound is safe, then I can make a significant code size reduction later.

Meanwhile, I decided to take a look at all the blocks of free space available in ROM before we start sticking our patches in them.
Caveat emptor: the only reason those blocks are marked as "free" is because I saw a run of identical bytes that hadn't been logged by taotao's CDL file and didn't have any immediately obvious pointers into them. It is in no way a guarantee that they are actually unused, just an educated guess.

Is everyone happy with ca65 or is there another preferred assembler I should shoot for?
For no particularly strong reason, I've been using Asar for generating patches, which I hear is not one of ca65's strong points. Asar's not the greatest for 6502 as it doesn't complain about me accidentally mixing 65816 with 6502 ("INC A" and "BRA" are my weaknesses :P) and disabling its default SNES memory mapping has some unwanted side effects like also disabling bounds checking, so I'm not super attached to it.

P.S. Welcome back!

Which reminds me, did anyone weigh in on shifting that code up three spaces and adjusting pointers accordingly?
If you can find all the pointers, sure, go right ahead. I've automatically labelled all the explicit direct control flow sources/targets and manually identified hopefully most/all of the indirect jumps, but there are some calculated and otherwise sneaky ones in there such as dynamically changing the NMI vector at $0100, pushing a return address before JMP to some routine that ends with RTS, or just plain writing the bytes for JMP $addr to RAM and executing that.

Curious issue... [...] with spells at least, it appears some other spell counters are raising besides the one being used.
One thing to note is that you aren't saving and restoring the registers and processor flags that you're modifying in your new routine. Is that a problem? Well, it depends. When the original code does stuff like this:
Code: [Select]
0x031E68|$0C:$9E58:FE F7 7C INC $7CF7,X ; Character #1 spell slot #1 battle use counter
0x031E6B|$0C:$9E5B:A6 9E    LDX $9E   
0x031E6D|$0C:$9E5D:A0 2A    LDY #$2A   
0x031E6F|$0C:$9E5F:B1 80    LDA ($80),Y
0x031E71|$0C:$9E61:C9 15    CMP #$15   
then it doesn't matter what state you leave A, X, Y, or C/Z in, but when the original code does stuff like this:
Code: [Select]
0x031E75|$0C:$9E65:FE 3F 7D INC $7D3F,X ; Character #1 black magic use counter
0x031E78|$0C:$9E68:D0 03    BNE $9E6D 
then it makes a difference what state you leave Z in. Similarly, when the original code does stuff like this:
Code: [Select]
0x03261D|$0C:$A60D:FE 3B 7D INC $7D3B,X ; Character #1 counter for times magically attacked by enemy
; control flow target (from $A537, $A56E, $A5A2, $A5AB, $A5CA, $A609)
0x032620|$0C:$A610:A0 2B    LDY #$2B   
0x032622|$0C:$A612:91 44    STA ($44),Y
then returning from your new routine with a different value in A than when you entered results in unintentional changes to other things in the game.

redmagejoe

  • Full Member
  • ***
  • Posts: 178
    • View Profile
Re: Final Fantasy II Restored
« Reply #137 on: January 21, 2020, 10:51:47 pm »
The problem was actually that I'm an idiot. I got lost counting bytes and subconsciously shifted to decimal in my head instead of hexadecimal. 60 and 64 should be 5A and 5E, so I was pointing the code in the wrong direction. Also, I'll try to avoid messing with pointers and shifting code around, since it sounds like it could get messy to only give us 3 more contiguous bytes in a space of 19 bytes. Of course we also have those two other large regions to work with.

I'll let you analyze the RNG fix as you see fit before committing it since it sounds like you still have some ideas in mind. Once I test this combat counter overflow protection thoroughly maybe I'll finally be able to sit down and focus on the Evasion / Magic Defense delay.  ;D

Jiggers

  • Sr. Member
  • ****
  • Posts: 305
    • View Profile
    • My Ko-Fi Page
Re: Final Fantasy II Restored
« Reply #138 on: January 22, 2020, 12:30:37 am »
If so, I might consider making a disassembly if one isn't available.  Not a fully commented one (doing that would take way too long -- the FF1 project spanned years), but a bare-bones functional disassembly should only take a few days.

I don't really want to repeat work that's already been done though, so is there a disassembly already out there that you guys are using?

Also a CDL file would be very useful, but not strictly necessary.  As I've never actually played this game before and know next to nothing about it, I'm not really up to the task of making one myself.  Is there one out there?  And if not, would anyone be willing to make one?

As far as assemblers go, I went with ca65 for the FF1 project because I liked the way it did local symbols and had the most consistent and clear syntax of other assemblers I looked at (and was modern enough to run on my machine at the time -- things like x816 wouldn't even run without an emulator).  Is everyone happy with ca65 or is there another preferred assembler I should shoot for?

I would love it if you could take the one I started with and flesh it out more. I spent way too long on just the one and a half banks that actually have code written out--everything else is still in hex blocks! I don't know how to extract the disassembled code and put it in, I was copy-pasting from Mesen's debugger and then doing all kinds of macros to get it looking pretty, then more half-manual macros to fix branch labels, then comparing it 500 times until I fix every minor detail and get a 100% match with the rom... and still end up with a horrible ugly mess. I'd be interested in going through it and commenting and figuring out what things are, but the actual building part was frustrating me too much. Sounds like you'd be a lot more efficient at it!

Unless I was getting frustrated from being exactly as efficient as anyone else would be. :P 

I haven't been keeping up with abw's work to see if its gotten any easier for me to read and copy over to the re-assemble-able version... Still trying to catch up with my work obligations.  :-[ Just really happy to see its careening on ahead with so much work being put into it!
I know exactly what I'm doing. I just don't know what effect it's going to have.

I wrote some NES music! Its a legal ROM file. - I got a Ko-Fi page too.

Disch

  • Hero Member
  • *****
  • Posts: 2770
  • NES Junkie
    • View Profile
Re: Final Fantasy II Restored
« Reply #139 on: January 22, 2020, 03:53:37 am »
I don't know how to extract the disassembled code and put it in, I was copy-pasting from Mesen's debugger and then doing all kinds of macros to get it looking pretty, then more half-manual macros to fix branch labels, then comparing it 500 times until I fix every minor detail and get a 100% match with the rom... and still end up with a horrible ugly mess.

Yeah I probably would have gone the exact opposite way and disassembled the whole ROM as if it were all code, then gone through and replaced data blocks with binary.

BUT, since there's a CDL available, we don't even need to do that.  We can just selectively disassemble the code blocks according to the CDL.  I dunno if there's a usable disassembler available that works with CDLs and is also mapper aware, though, so I'll probably have to just whip something up in Python (which, IIRC, is what I did for FF1).


I hope you're not too offended, but I think it would actually be significantly easier for me to build a new disassembly from scratch than it would be to try to build off of what you have.  :(   And in the process I might be able to make an actually re-usable disassembler.

I'll start on this tomorrow!



EDIT:

Just to verify, after skimming the thread it looks like everyone here is using the Chaos Rush translation.  Is that correct?

Is that what the CDL is built on, too?
« Last Edit: January 22, 2020, 04:26:09 am by Disch »