I didn’t say it is an impossible task. I said you lied when you write tha you use a C compiler to build a identical SNES rom, because it is not possible with a 65816 C compiler. What you are doing is similar to a recomp project, which makes the game unmaintainable.
For example, look at my "fade_update.c" version of your work :
C:
void UpdateBrightness(void)
{
/* ASM: screen.asm @UpdateBrightness */
uint8_t fade = wram_read8(DP_FADE_ACTIVE); /* $4A */
uint8_t bright = wram_read8(DP_SCREEN_BRIGHT); /* $4C */
if (fade & 0x80) {
/* ASM: FadingOut */
/* ASM: lda $4c; beq FadeComplete */
if (bright == 0) {
wram_write8(DP_FADE_ACTIVE, 0);
} else {
/* ASM: lda $4a; and #$1f; sta $10;
* lda $4c; sec; sbc $10; sta $4c */
uint8_t speed = fade & 0x1F;
bright = (uint8_t)(bright - speed);
wram_write8(DP_SCREEN_BRIGHT, bright);
}
} else {
/* ASM: lda $4c; and #$f0; cmp #$f0; beq FadeComplete */
if ((bright & 0xF0) == 0xF0) {
wram_write8(DP_FADE_ACTIVE, 0);
} else if (fade) {
/* ASM: lda $4a; and #$1f; clc; adc $4c; sta $4c */
uint8_t speed = fade & 0x1F;
bright = (uint8_t)(bright + speed);
wram_write8(DP_SCREEN_BRIGHT, bright);
}
}
/* ASM: :lda $4c; lsr4; sta hINIDISP */
bright = wram_read8(DP_SCREEN_BRIGHT);
hw_write(hINIDISP, bright >> 4);
}
For those interested, here is the ASM equivalent :
Code:
.proc UpdateBrightness
lda $4a
bmi FadingOut
lda $4c
and #$f0
cmp #$f0
beq FadeComplete
lda $4a
and #$1f
clc
adc $4c
sta $4c
bra :+
FadingOut:
lda $4c
beq FadeComplete
lda $4a
and #$1f
sta $10
lda $4c
sec
sbc $10
sta $4c
bra :+
FadeComplete:
stz $4a
: lda $4c
lsr4
sta hINIDISP
rts
.endproc ; UpdateBrightness
You can see the difference. Mine has variable names, no goto’s, and easier to modify if needed.
Far from me to prevent you to do your project, you can do whatever you want. Just don’t write fake informations.
Sure it's maybe similar to a recomp in some ways. However at this stage the goal is simply to have as much as possible owned by C while still compiling an identical rom. (and I AM so far compiling an identical rom)
I am not just feeding C into a standard compiler and expecting it to magically produce the original ROM. We are using existing compilers like cc65 and Calypsi where they work, and adding targeted compiler support where needed. For more complex routines, we’re using Clang/LLVM with a custom 65816 backend that understands the game’s register usage, memory banks, flags, stack and calling conventions.
The idea is to compile readable C into the exact same instructions as the original assembly, not just code that behaves similarly. We then build those routines together with the remaining assembly and assets and compare the entire ROM against the original, byte for byte and by hash. We’re not copying the original machine code into the compiler or patching the output to make it match. This is working for some routines already, but we haven’t yet shown that the approach can handle the whole game.
This is mainly for the purpose of cross-referencing.
And as long as I can output an identical rom then I always know the code working as intended.
Once that's done then I will start working on a Decompilation port for MacOS and PC.
This port should have source code that is much more in line with what you'd expect (as this won't need to match the rom)
But I'll use the disassembly and C-code for cross-reference and feed that to Codex.
Then I could have a pretty nice path where each routine is validated against the logic in the already completed work.
This should minimize mistakes and allow me to automate a lot of the work.
Now I am kinda new in the whole recomp and decomp scene, and I do use quite a bit of AI.
But I am not lying to anyone.
The end goal is still ports of Final Fantasy VI with readable and maintainable source code, But I guess my way to get there is different from how you would have done it.