Users browsing this thread: 1 Guest(s)
Attempting to create a new event command

#1
Posts: 1,633
Threads: 56
Thanks Received: 13
Thanks Given: 84
Joined: Apr 2014
Reputation: 12
Status
Atma
Hi! Hello

I was trying to write some asm code:

command A3: AA BB CC CC CC

That should allow me to read any battle var value AA(the ones that keep the value even after battle) and so compare it with CMP BB.
After CMP, if the result is greater or equal, it branches to CC CC CC
Else it returns.

While i believe i have already created the right code, i didn't understand how to use CC CC CC input value to jump when the check is true Sad
I tried to check the code of other event command checks but it's messy...
This would be the perfect moment to receive an hint. Wink


THE GREATEST CHALLENGE OF ALL TIMES AWAITS:
http://www.ff6hacking.com/forums/showthr...p?tid=2593
DO YOU HAVE WHAT IT TAKES TO SLAY A GOD?
------------------------------------------------------------------------
Tenkarider's project #2 is started: FF6 Curse of the Madsiur Joke (CotMJ)
http://www.ff6hacking.com/forums/showthr...p?tid=2755
What happens when Madsiur tweaks your account? This full game hack will show that!
  Find
Quote  

#2
Posts: 127
Threads: 8
Thanks Received: 21
Thanks Given: 12
Joined: Jan 2012
Reputation: 13
Status
None
if the check results in a branch. The routine will jump to the specified address CC CC CC and continue running from that location.

Otherwise it continues to the next line (byte/operator).

CC CC CC will be little endian value, this means the least significant value is first. So consider CC CC CC as C1 C2 C3 then the address will be reversed: $C3C2C1. Addresses in ASM refer to the snes bank addresses not the ROM address so make sure to add the header (+$200) if you have one and subtract $C00000 to get the ROM location of a pointer.

So for example:

Pointer to Character Portraits: $ED1D00 (would show up as 00 1D ED)

Location in a headered ROM: $ED1D00 - $C00000 + $000200 = $2D1F00 (in the ROM)
  Find
Quote  

#3
Posts: 1,633
Threads: 56
Thanks Received: 13
Thanks Given: 84
Joined: Apr 2014
Reputation: 12
Status
Atma
Yeah, i know that...
What i'm not sure about is right the jump command to CC CC CC: i usually write a constant value as input for the jump... how do you insert as parameter CC CC CC in the jump command input?


THE GREATEST CHALLENGE OF ALL TIMES AWAITS:
http://www.ff6hacking.com/forums/showthr...p?tid=2593
DO YOU HAVE WHAT IT TAKES TO SLAY A GOD?
------------------------------------------------------------------------
Tenkarider's project #2 is started: FF6 Curse of the Madsiur Joke (CotMJ)
http://www.ff6hacking.com/forums/showthr...p?tid=2755
What happens when Madsiur tweaks your account? This full game hack will show that!
  Find
Quote  

#4
Posts: 676
Threads: 44
Thanks Received: 26
Thanks Given: 21
Joined: Jan 2015
Reputation: 11
Status
Zombie
If your custom command mimics gen action C0 (at C0/B2C8) Then after the command, and the val to check you enter the destination, in reverse, as m06 said. The command should be set up to check var then read the following code as an address.

In other words, why would you need a jump command during usage of the custom command. That should already be set up in the custom code. Or am I on the entirly wrong planet?


The only true wisdom is knowing you know nothing.
  Find
Quote  

#5
Posts: 1,633
Threads: 56
Thanks Received: 13
Thanks Given: 84
Joined: Apr 2014
Reputation: 12
Status
Atma
My custom event is based mainly on B7 B8 and/or B9 event commands, which deals with battle variables... but instead of their bits. i want to get the value of the chosen battle var.
I already done the checks: i reached the following point:
CMP BB;
The next step should be BMI(branch if minus)... if i do the branch(few bytes), then i return and do nothing;
If i don't branch, then it's greater or equal: now it's the time of doing a long JMP to anywhere i want, that's the problem... i cannot write a static value of CC CC CC for the JMP, if i do that, then i'd jump always in the same place Laugh
I need of a dynamic value, that depends on the input value... you can't just load up $ED $EE and $EF (used to store the value of 3rd, 4th and 5th arguments) inside the JMP command... you must make them become a single value... how? that's the thread question.

Meanwhile i tried to search the answer in Madsiur's custom event 83 readme... and there i'm pretty sure there's the answer, and it should be inside this piece of code:
Code:
F1/A049        C2 21            REP #$21
F1/A04B        A5 E5            LDA $E5            (Load low and middle byte of currnt offset)
F1/A04D        69 05 00          ADC #$0005        (Command + parameters length)
F1/A050        85 E5            STA $E5            (Save in $E5)
F1/A052        7B              TDC             (Transfer D to C)
F1/A053        E2 20            SEP #$20          (8 bit accum./memory)
F1/A055        65 E7            ADC $E7            (Add to A $E7)
F1/A057        85 E7            STA $E7            (Store A in $E7)
F1/A059        5C 6D 9A C0     JMP $C09A6D        (Make a 5 bytes jump from the command number in the event)
F1/A05D        C2 20            REP #$20          (16 bit accum./memory)
F1/A05F        A6 EC            LDX $EC            (Load parameter 2 and 3)
F1/A061        86 E5            STX $E5            (store the low and middle byte of the offset in $E5)
F1/A063        E2 20            SEP #$20        (8 bit accum./memory)
F1/A065        A5 EE            LDA $EE            (Load parameter 4)
F1/A067        18              CLC                (clear carry)
F1/A068        69 CA            ADC #$CA        (Add #$CA to the high byte of the offset)
F1/A06A        85 E7            STA $E7            (Stre high byte of the offset in $E7)
F1/A06C        5C 6D 9A C0      JMP $C09A6D        (Make the event branching/jumping effective)

Unfortunately i don't understand some step of this code... for example i noticed his 3 input bytes for the JMP: he stores them in $E5, $E6 and $E7 and makes somehow their sum into a single value... still not figured out how it comes out a 6 byte value...
Finally the JMP to $C09A6D... where is the code jumping, and what's in that place of the code? (obviously this last question is aimed to Madsiur)
I'd like to have a detailed explaination on how this piece of code works...
Another question: is this code easily portable and reusable for other event commands?


THE GREATEST CHALLENGE OF ALL TIMES AWAITS:
http://www.ff6hacking.com/forums/showthr...p?tid=2593
DO YOU HAVE WHAT IT TAKES TO SLAY A GOD?
------------------------------------------------------------------------
Tenkarider's project #2 is started: FF6 Curse of the Madsiur Joke (CotMJ)
http://www.ff6hacking.com/forums/showthr...p?tid=2755
What happens when Madsiur tweaks your account? This full game hack will show that!
  Find
Quote  

#6
Posts: 676
Threads: 44
Thanks Received: 26
Thanks Given: 21
Joined: Jan 2015
Reputation: 11
Status
Zombie
I think I know the answer to one of those, maybe two, but I need a computer first. Gimmie an hour


The only true wisdom is knowing you know nothing.
  Find
Quote  

#7
Posts: 127
Threads: 8
Thanks Received: 21
Thanks Given: 12
Joined: Jan 2012
Reputation: 13
Status
None
I think what you're asking about is creating pointer tables or data tables and using a lookup index? If so your index or parameter would be loaded to X or Y with LDX or LDY and then you get the value from the table to A with LDA $table_start, X

If you don't want to create a data table you can use a series of compares and branches.
So you load the index or parameter to A and do a series of CMP for each value available.
Code:
LDA $parameter
CMP #$00
BEQ $where_to_go_when_zero
CMP #$01
BEQ $where_to_go_when_one
CMP #$02
BEQ $where_to_go_when_two

This works like a switch statement or series of else-if statements in higher level languages.

-----

Regarding memory each slot in the memory is one byte so $E5 can only hold one byte, to make 16-bit, word pointers we need 2 bytes so that would be stored at two memory locations $E5 and $E6 for instance. And so for 24-bit, long pointers we need 3 bytes, hence, $E5, $E6, $E7 - However! It may be confusing that the registers in the CPU can actually hold 16-bit, word, 2 bytes at once. If they have been set to do so with REP, SEP commands.

In the code you pasted $E5 and $E6 are loaded at the same time with LDA $E5 (where the A register is set to 16-bit with REP #$21).

ADC then adds 5 to the current value and sets the carry flag if the value goes above FFFF (important to note)

Then we store the word $E5 and $E6 together with STA $E5

TDC basically just sets A to 0

SEP #$20 now a is 8-bit again holds only 1 byte.

ADC $E7 adds $E7 to zero, so it's like loading $E7 but, because we are adding we check the carry flag and if it is set $E7 gets incremented by one. This is how the carry flag is used to perform addition over multiple bytes.

from F1/A05D it's basically the same thing but setting the values directly from the event parameters.

If you don't need to branch with your event command I recommend this exit:

Code:
A9 01        LDA #$01    (advance the script 1 place)    
4C 5C 9B     JMP $9B5C    (standard exit)

The routine at $9B5C does the same as you posted above but adds A to the $E5-$E7 pointer:

Code:
C0/9B5C:    18          CLC         (Called from various, below)
C0/9B5D:    65E5        ADC $E5        (Add event command size in bytes to current pointer)
C0/9B5F:    85E5        STA $E5        (Write new pointer)
C0/9B61:    A5E6        LDA $E6
C0/9B63:    6900        ADC #$00    (carry overflow to high byte)
C0/9B65:    85E6        STA $E6
C0/9B67:    A5E7        LDA $E7
C0/9B69:    6900        ADC #$00    (carry overflow to bank byte)
C0/9B6B:    85E7        STA $E7
C0/9B6D:    4C6D9A      JMP $9A6D    (General Actions: Branch Exit)

This routine also jumps to $9A6D that routine basically runs the event command at $E5-$E7 and in this way parses the event script.
  Find
Quote  

#8
Posts: 676
Threads: 44
Thanks Received: 26
Thanks Given: 21
Joined: Jan 2015
Reputation: 11
Status
Zombie
Ha! I did know part of it! SEP and REP, 8-bit/16-bit how many values it loads at once... I just drive to slow and could have never explained it as pretty as m06 does.

That being said, that code at $9A6D, it kinda makes sense how it works, but I'd be guessing the whole way. By the way, where is this "Madsiur's custom event 83 readme"? I need to save that one.

As far as portable and reusable: Yeah, long as you treat it as an event command.

Code:
F1/A049        C2 21            REP #$21
F1/A04B        A5 E5            LDA $E5            (Load low and middle byte of currnt offset) (Load the location of where the command was used?)
F1/A04D        69 05 00          ADC #$0005        (Command + parameters length)(Account for length of command in order to return to byte after in the event of return)
F1/A050        85 E5            STA $E5            (Save in $E5)(Save the address for no-jump/return)
F1/A052        7B              TDC             (Transfer D to C)
F1/A053        E2 20            SEP #$20          (8 bit accum./memory)
F1/A055        65 E7            ADC $E7            (Add to A $E7)
F1/A057        85 E7            STA $E7            (Store A in $E7)
F1/A059        5C 6D 9A C0     JMP $C09A6D        (Make a 5 bytes jump from the command number in the event)(Failed check,continue with normal script)
F1/A05D        C2 20            REP #$20          (16 bit accum./memory)
F1/A05F        A6 EC            LDX $EC            (Load parameter 2 and 3)
F1/A061        86 E5            STX $E5            (store the low and middle byte of the offset in $E5)(Load the desired JMP address "/0000" if check OK)
F1/A063        E2 20            SEP #$20        (8 bit accum./memory)
F1/A065        A5 EE            LDA $EE            (Load parameter 4) (Load "00/" of desired JMP address)
F1/A067        18              CLC                (clear carry)
F1/A068        69 CA            ADC #$CA        (Add #$CA to the high byte of the offset) (Add CA to the high byte of address like other event commands)
F1/A06A        85 E7            STA $E7            (Store high byte of the offset in $E7)
F1/A06C        5C 6D 9A C0      JMP $C09A6D        (Make the event branching/jumping effective)

Least that's what I see it doing. Still don't fully get the "exit" though. Please correct me if I'm wrong, it has been known to happen. (The added comments to that block of code is what I'm talking about btw)


The only true wisdom is knowing you know nothing.
  Find
Quote  

#9
Posts: 1,633
Threads: 56
Thanks Received: 13
Thanks Given: 84
Joined: Apr 2014
Reputation: 12
Status
Atma
Quite enlightening...
Maaaaaaaaybe $E5 $E6 and $E7 are used as passive parameters of the dynamic value to use for the jump(or for continue in the case the check is false)
Now i'd like to understand why/how a JMP to itself allows the command to do something so much elaborate.
The other question is... if $E5-7 values have a so much important role, then why in the RAM map document they're not even mentioned?!? Surprised

I'm gonna try to do something with those new info... we'll see what happens.

PS. Madsiur's custom event 83 is inside this site, among hack patches, i believe...

____________________________________


Ok, i finished... the good new is that the game won't crash when i use the command, the problem is that it always returns false... Sad
Here's the code i wrote:
Code:
C0/D613: A6 EB        LDX $EB     (First byte for FC)
C0/D615: 20 45 D6    JSR $D645   ($EB = variable #X)
C0/D618: A5 EB        LDA $EB  (after the JSR the n. of the var is changed into its value)
C0/D61A: C5 EC        CMP $EC
C0/D61C: 30 13          BMI             (Branch if AA value < BB)

C0/D61E: C2 20            REP #$20          (16 bit accum./memory)
C0/D620: A6 ED            LDX $ED            (Load parameter 3 and 4)
C0/D622: 86 E5            STX $E5            (store the low and middle byte of the offset in $E5)
C0/D624: E2 20            SEP #$20        (8 bit accum./memory)
C0/D626: A5 EF            LDA $EF            (Load parameter 5)
C0/D628: 18                      CLC                (clear carry)
C0/D629: 69 CA            ADC #$CA        (Add #$CA to the high byte of the offset)
C0/D62B: 85 E7            STA $E7            (Stre high byte of the offset in $E7)
C0/D62D: 5C 6D 9A C0      JMP $C09A6D        (Make the event branching/jumping effective)
C0/D631: C2 21            REP #$21
C0/D633: A5 E5            LDA $E5            (Load low and middle byte of current offset)
C0/D635: 69 06 00          ADC #$0006        (Command + parameters length)
C0/D638: 85 E5            STA $E5            (Save in $E5)
C0/D63A: 7B                      TDC             (Transfer D to C)
C0/D63B: E2 20            SEP #$20          (8 bit accum./memory)
C0/D63D: 65 E7            ADC $E7            (Add to A $E7)
C0/D63F: 85 E7            STA $E7            (Store A in $E7)
C0/D641: 5C 6D 9A C0     JMP $C09A6D        (Make a 6 bytes jump from the command number in the event)


C0/D645: 48            PHA
C0/D646: E0 24        CPX #$24
C0/D648: B0 05        BCS $D64F  
C0/D64A: BD B0 3E   LDA $3EB0,X
C0/D64D: 80 03        BRA $D652
C0/D64F: B9 AC 3D   LDA $3DAC,Y
C0/D652: 85 EB        STA $EB
C0/D654: 68            PLA
C0/D655: 18            CLC
C0/D656: 60            RTS


This is the code i tested for see if that works:
Code:
003F0200:  A3 04 32 0B 00 35   //  if battle var 04 >= 50 then jump to 3F020B  
                B2 BA BD 00          // calls whatever command
                FE                        // return
003F020B:  A3 04 64 18 00 35   //  if battle var 04 >= 100 then jump to 3F0218
                F4 1F                    // whatever sound
                4B 00 40               // message 0
                BB                       // whatever command
                FE                       // return
003F0218:   A3 04 96 25 00 35 // if battle var 04 >= 150 then jump to 3F0225
                 F4 B8
                 4B 01 40             // message 1
                 BB
                 FE
003F0225:   A3 04 C8 32 00 35 // if battle var 04 >= 200 then jump to 3F0232
                F4 E1
                4B 02 40              // message 2
                BB
                FE
003F0232:  A3 04 FF 3F 00 35  // if battle var 04 >=  then jump to 3F020B
                F4 D0
                4B 03 40              // message 3
                BB
                FE
003F023F    F4 E1
                91
                F4 D0
                91
                F0 2C
                92
                F0 2F
                4B 04 40   // message 4
                BB
                FE

I start a battle, var 04 chances its value and then battle ends: after the battle this code above is triggered... and always returns false.
Could you try to figure out if i missed something?


THE GREATEST CHALLENGE OF ALL TIMES AWAITS:
http://www.ff6hacking.com/forums/showthr...p?tid=2593
DO YOU HAVE WHAT IT TAKES TO SLAY A GOD?
------------------------------------------------------------------------
Tenkarider's project #2 is started: FF6 Curse of the Madsiur Joke (CotMJ)
http://www.ff6hacking.com/forums/showthr...p?tid=2755
What happens when Madsiur tweaks your account? This full game hack will show that!
  Find
Quote  

#10
Posts: 676
Threads: 44
Thanks Received: 26
Thanks Given: 21
Joined: Jan 2015
Reputation: 11
Status
Zombie
I don't have a debugger at work (not sure why, I should have) but that'd be the best suggestion I've got.

Set a break at C0/D613 then step through it line by line to make sure the checked values are being loaded properly. If it is acting like an always false check with no crash, its either running the wrong thing with no visual result, or its being bypassed entirely, somehow.


The only true wisdom is knowing you know nothing.
  Find
Quote  



Forum Jump:

Users browsing this thread: 1 Guest(s)


Theme by Madsiur2017Custom Graphics by JamesWhite