Dizzy611 / DancingMadFF6

An MSU-1 modification for Final Fantasy 6
Other
25 stars 1 forks source link

Fading needs to be implemented. #5

Open Dizzy611 opened 7 years ago

Dizzy611 commented 7 years ago

This is the bug that is currently the biggest blocker for release. Fading would need to be done during the NMI, and while I have code to hook the NMI I have not, as of the current done any further code as far as tracking fading.

A user on Qhimm has provided a potential NMI routine for this but I have not had the chance to test it. He claimed it caused hangs/lag.

Dizzy611 commented 7 years ago

This NMI stuff is honestly kind of over my head. So I really need help with this, especially given how limited my time is as of late.

Below is the provided code from the Qhimm/RHDN user Madsiur. Thanks again for your help.


    rep #$20
    pha
    lda fadeCount
    beq .CallNMI
    dec
    sta fadeCount
    clc
    rep #$20
    lda fadeVolume
    adc fadeStep
    sta fadeVolume
    sep #$20
    lda fadeVolume+1
    sta MSU_AUDIO_VOLUME
edale2 commented 6 years ago

Was looking around at various bugfix patches for FFVI, and spotted this one: http://assassin17.brinkster.net/patches.htm#anchor39 It's for an equipment glitch that's related to NMI's.

I figured if you have to play with the NMI's to get fading working, this bugfix patch might be necessary to include (testing would be needed to see if your NMI changes trigger this bug).

ghost commented 4 years ago

I am not sure if this is still on your mind. nmi hook is really simple. E.g., rev1: The nmi routine is this

$00/FF10 5C 00 15 00 JMP $001500[$00:1500]   A:0001 
$00/1500 5C A7 0B C1 JMP $C10BA7[$C1:0BA7]   A:0001 
$C1/0BA7 08          PHP                     A:0001 X:0550 Y:7ACE 
$C1/0BA8 C2 30       REP #$30                A:0001 
$C1/0BAA 48          PHA                     A:0001 
$C1/0BAB DA          PHX                     A:0001 
$C1/0BAC 5A          PHY                     A:0001 
$C1/0BAD 8B          PHB                     A:0001 
$C1/0BAE 0B          PHD                     A:0001 
$C1/0BAF A2 00 00    LDX #$0000              A:0001 
$C1/0BB2 DA          PHX                     A:0001 
$C1/0BB3 2B          PLD                     A:0001 
$C1/0BB4 7B          TDC                     A:0001 
$C1/0BB5 E2 20       SEP #$20                
$C1/0BB7 AF 10 42 00 LDA $004210[$00:4210]   A:0000 
$C1/0BBB A5 46       LDA $46    [$00:0046]   A:0082 

So hook at $c1/0BB7

You furthermore need these two flags (instead of 7f/fffX you can of course use any free ram): e.g.: 7FFFF2: volume flag Store FF here when writing to $2006

7FFFF3: fade flag. This one is set through ingame commands, hook there and give it a value. E.g.: 01: fade out, 02: fade full

MSU code:

LDA #$ff
STA $2006
STA $7FFFF2 ; volume flag set to FF
LDA #$00
STA $7FFFF3 ; erase fade flag at this point

When fade command is executed ingame hook there (some value is written to $214x or some ram (e.g., Zelda, ALTTP the fade commands were F1-F3 to $2140)). If a fade out command is written, additional write: LDA #$01 STA $7FFFF3 If a fade Full command is written, additional write: LDA #$02 STA $7FFFF3 (you can alter the code of course with #$03 for fade half or whatever is needed more.

Additional nmi hook:

nmi hook:
org $C10BB7
JSL nmi

org $"some freespace"
nmi:
LDA $004210 ; native code (4210 is read only to erase the counter I think, no need to pha or anything)
LDA $7FFFF3; check fadeflag
BNE $01
RTL   ; since nmi is frequently executed you want to return early if it is 00
cmp #$01
beq fadeOut
cmp #$02
beq fadeFull
LDA #$00 ; catch error if it has a value you do not want
STA $7FFFF3
RTL

fadeOut:
lda $7FFFF2 ; volume value
CMP #$00
BEQ endFadeOut
dec  ; the number of decs influences the fade out speed
dec
dec
cmp #$10 ; when hit 10, mute
bcs $06
endFadeOut:
lda #$00
sta $7FFFF3 ;erase fade flag
sta $002006 ;new volume level !24 bit, since it is also sta $004210 instead sta $4210 in the hook
sta $7FFFF2 ; new volume level
RTL

fadeFull:
lda $7FFFF2
CMP #$ff    ;final level?
BEQ endFadeFull
inc ; the number of incs influences the fade up speed
inc
inc
cmp #$fb ; when fb or greater set to max
bcc $08
endFadeFull:
lda #$00
sta $7FFFF3 ;erase fade flag
LDA #$FF
sta $002006 ;new volume level !24 bit, since it is also sta $004210 instead sta $4210 in the hook
sta $7FFFF2 ;new volume level
RTL

If you experience problems, pm me at zeldix ;)

Dizzy611 commented 4 years ago

I'm unsure how helpful any of this very, very basic information is going to be. I'm aware of all of it, and other people have tried. The issue is that the NMI for FF6 does not really have the room for a routine like the above. Attempting to fit said causes graphical or input issues or freezing as code that should have been executed during NMI leaks outside of vblank.

ghost commented 2 years ago

Is this still an issue? If you want I could try to help you... but I have problems with compiling and understanding your code. But the reason why it didn't work in the past hooking the nmi is probably that you need to execute the nmi hook in ram:

I'd hook here: $7E/723B E2 20 SEP #$20
$7E/723D AD 10 42 LDA $4210

At the boot of the rom you need to write the nmi-handler code into ram. I do not know where free ram is but 7e5000 looks good.

1) So, at 0x3138F ($C3/138F): SEP #$20 : LDA $4210 I'd hook to unused ram block JSL 7E5000 NOP

2) Write the nmiHandler code for fading you need to execute in ram to some free space, e.g., 0x12fe00

3) Now the trick is to transfer this code block at 0x12fe00 ($D2/FE00) to ram $7e5000. You can hook somewhere when the rom boots and write this code: ; PHA, PHX, PHY if needed to get restored, depends on your hook

PHB PHP REP #$30 LDA #$02FF ; transfer $300 bytes, give more if you need LDX #$FE00 ; rom origin address $(D2)FD00 LDY #$5000 ; ram destination address ($(7E)5000 MVN $D27E ; bank D2 -> 7E PLP PLB RTL

If you execute the nmi handler in ram should solve the problem, I e.g. had a similar problem in star fox.