Regarding my stat screen mod shown above, it does in fact use almost all of the unused data immediately after the menu display data - 0xde68 through 0xe2ff gets used. Hacks that add new options to the customization screen would likely have used that particular ROM region, which would create a conflict.
When I eventually release that mod for public use (atm it's a The Lunarian Shuffle exclusive), I'll be releasing the ASM as well as the raw data, so someone who needs an option screen hack as well and knows what they're doing could offload some of the subroutines and data to another section of the ROM - expanding the ROM by one bank would work, if nothing else.
In other news, I think I'll add an option to fix various stat glitches, including this one, the permanence of Long Range (looks like Dragoon ZERO already tackled this one), the Adamant armor permanent weaknesses glitch, and the failure of enemies to load the evasion and magic evasion they are supposed to have.
Edit: turns out the Adamant armor problem wasn't too hard to fix.
Here is the root of the Adamant unequipping problem. It loads extreme resistances, and if it finds any, it sets the opposites, plus the "extreme" flag, into the extreme weaknesses byte.
However, the game does nothing whatsoever if it finds no extreme weaknesses, thus leaving the old values there!
$03/9a78 ldy #$0026
$03/9a7b lda ($80),y << Loads extreme resistances
$03/9a7d sta $a9
$03/9a7f jsr $9da8 << This subroutine picks opposite elements: Fire and Ice are swapped, as are Holy and Darkness.
$03/9a82 beq $9a8b << This will fire if there was no Holy, Dark, Ice, or Fire stuff in the resistances
$03/9a84 ldy #$0021
$03/9a87 ora #$80 << Throw in an "extreme" flag. I actually don't know if this does anything.
$03/9a89 sta ($80),y << Here is where it gets set.
$03/9a8b ldy #$0022 << Destination of the branch; goes on to edit other stuff.
So, in cases where beq fires, what we want to do is put a 0 into the extreme weakness flag. This can be achieved by simply rearranging the commands as follows:
Subroutine $9da8 does not touch Y, so loading Y earlier is fine. The only thing the game now skips when there are no extreme weaknesses to write is OR-ing in the "extremeness" flag.
TL;DR: apply this code to 0x19a7f on an unheadered, v1.1 ROM:
A0 21 00 20 A8 9D F0 02 09 80 91 80
Edit 2: And while we're at it, making enemy evasion work wasn't too hard once I figured out enough about what the game was actually doing.
NOTE: This might make the game a lot harder! I'm not really sure just how big the impact of enemies having their intended evasion is. Future releases of the game consistently chose not to restore this evasion, which might suggest that it would have been overbearing.
The culprit this time appears to be a simple typo by Square in the battle loading routine. Essentially the same typo is made in the physical as well as magical defense loading routines. Here's the erroneous physical one:
$03/90ce lda $291c
$03/90d1 sta $2028,x
$03/90d4 lda $291d
$03/90d7 sta $202a,x << Oops!
$03/90da lda $291e
$03/90dd sta $202a,x
And here's magic evade:
$03/90e6 lda $291c
$03/90e9 sta $2022,x
$03/90ec lda $291d
$03/90ef sta $2024,x << Oops!
$03/90f2 lda $291e
$03/90f5 sta $2024,x
The byte order goes evade multiplier, evade rate, then defense. The middle byte is being written on the last byte, then immediately overwritten by the correct last byte, leaving every enemy without its proper evade rate, although they do have the correct evade multiplier.
The code we want is:
$03/90d7 sta $2029,x
$03/90ef sta $2023,x
The fix to this, then is only two bytes. On an unheadered v1.1 US ROM, the bytes to change are:
0x190d8 = 0x29
0x190f0 = 0x23