daniilS
busy trying to do stuff not done yet
- 409
- Posts
- 11
- Years
- Seen Jan 29, 2024
Try setting 0x8002 to 0xFF. See if it turns shiny. Lets continue this discussion in the ASM help thread or something. We're kind of de-railing on this thread's purpose. At any rate, this is a problem with something in your ROM/execution rather than the routines. I have this routine setup in my ROM, and I've used similar for chain fishing which as worked fine.
I'm not denying that my execution is screwing up, it's just that I've looked it over a million times and can't find where.
Anyways, I wrote in a NPC that set 0x8002 to 0xFF, still no shinies. So that confirms something is wrong in the first two codes and not shiny charm I suppose. Since the RNG is literally just compiling a code, I don't see what could go wrong there. So it must be the shiny encounter code. Did you take a look at the code I posted in the other thread?
ldr r0, =(0x20370BC) @0x8002 is shiny flag
ldrb r0, [r0]
cmp r0, #0xFF
ldr r0, =(0x20370BC) @0x8002 is shiny flag
ldrh r0, [r0]
cmp r0, #0xFF
ldr r0, =(0x20370BC) @set back to 0x0 because ...
mov r1, #0x0
strb r1, [r0]
ldr r0, =(0x20370BC) @set back to 0x0 because ....
mov r1, #0x0
strh r1, [r0]
Yes, I've seen it and it looks right to me :x
Hmm, it's possible that the variable byte reading/storing might be causing the bugs you're experiencing. Try these steps.
In Shiny Generator change
intoCode:ldr r0, =(0x20370BC) @0x8002 is shiny flag ldrb r0, [r0] cmp r0, #0xFF
Code:ldr r0, =(0x20370BC) @0x8002 is shiny flag ldrh r0, [r0] cmp r0, #0xFF
and
intoCode:ldr r0, =(0x20370BC) @set back to 0x0 because ... mov r1, #0x0 strb r1, [r0]
Code:ldr r0, =(0x20370BC) @set back to 0x0 because .... mov r1, #0x0 strh r1, [r0]
Still no dice...
This is frustrating. All of the right offsets and pointers are in the right places correct? Because if it's not that at this point then I'm beyond puzzled.
Yeah, without debugging myself, I can't draw any other reasons why yours isn't working. Just to check, you are using English U.S FireRed BPRE ROM right?
After my problem I was trying to think of a way around it.
I stumbled across this ASM routine for naming the rival - and thought it might be useful to make a similar routine to name the player, whilst avoiding the pop-up start menu.
Would it be hard to alter this to change the [player] name rather than [rival]?
.text
.align 2
.thumb
.thumb_func
main:
push {r0-r4, lr}
ldr r0, =(0x80568E0 +1) @callback routine; script continuer
str r0, [SP, #0x4]
ldr r1, =(0x300500C)
ldr r1, [r1]
mov r0, #0x0
mov r2, #0x0
mov r3, #0x0
@setting lastresult to 0x0, you'll see soon why
ldr r4, =(0x20370D0)
strb r0, [r4]
ldr r4, =(0x809D954 +1)
bl linker
checkValidName:
ldr r0, =(0x300500C)
ldr r0, [r0]
ldrb r0, [r0]
cmp r0, #0xFF
beq invalid
cmp r0, #0x0
beq invalid
done:
pop {r0-r4, pc}
invalid:
@Here, whoever owns the original routine assigns a default name.
@you can either loop back, assign a default name...or even better
@set a variable to flag that the name was invalid, and in the script prompt again
ldr r0, =(0x20370D0) @lastresult will be set to 0x1
mov r1, #0x1
strb r1, [r1]
pop {r0-r4, pc}
linker:
bx r4
.align 2
Does someone know the offset of the routine which calculates the damages in a battle ? Thanks !
How well would knowledge of another assembly language transfer over? I am pretty good at 6502 Assembly but I am really dreading having to relearn assembly for a whole new system..
About 90% of the raw ASM is the same, there are some conceptually different things going on. For example, there aren't any builtin "print" style functions (except the BIOS functions swi) and functions in general are called a little differently. Also "lda" ect is not used. I would argue the actual ASM isn't hard, the hard parts are conceptual walls which need to be conquered. You need to get used to and learn how to write code that won't break the current ROM's infrastructure, and you need to acquire some good debugging/research sense.
So to answer your question, the transition isn't hard language wise (I started ASM with MIPS), but conceptually there's a lot changing when you're editing existing code mechanics.
Hello, FBI.
Could you tell me something about how to use these 3 functions:
1.swi
2.ldmia
3.stmia
Thank you greatly.
@example of a memory copy
ldr r0, source
ldr r1, destination
ldmia r0! {r2-r6} @loads 5 words from memory locations in r2-r6. Increments r0.
stmia r1!, {r2-r6} @Similar to previous, but stores
@note that high registers can't be used in these
@also note the syntax, from GBATEK:
@
STMIA Rb!,{Rlist}
LDMIA Rb!,{Rlist}
@rb = Base register
@Rlist = register list ; same syntax as push/pop instructions
@GBATEK also states that these are aliases to POP and PUSH. You can read in detail there~
SWI is short for software interrupt. It's basically like a table (not really, but a good way to think about what it is like) of functions which are built in. You call these functions by using SWI #0xValue to do a specific BIOS function call. Some common ones are CPU_Memset, memcpy and a few mathamatical ones (there are even some for TAN/SIN/COS functions as well as simple division!).
ldmia and stmia are basically multiple load/store operations (like a looped ldr and str). It's a useful way to save OPcodes and trivial operations thereby boosting efficiency. The syntax is a little wierd in comparison to other OPCodes, but once you understand how it works it's simple.
Code:@example of a memory copy ldr r0, source ldr r1, destination ldmia r0! {r2-r6} @loads 5 words from memory locations in r2-r6. Increments r0. stmia r1!, {r2-r6} @Similar to previous, but stores @note that high registers can't be used in these @also note the syntax, from GBATEK: @ STMIA Rb!,{Rlist} LDMIA Rb!,{Rlist} @rb = Base register @Rlist = register list ; same syntax as push/pop instructions @GBATEK also states that these are aliases to POP and PUSH. You can read in detail there~
Thank you for your reply. I have now developed a basic idea of swi and I've found something about it in gbatek. But there's many "swi XXh" there, I really don't know which of them can be used in thumb and I also don't know if the input and output should be hex numbers.
Something more about ldmia and stmia:
For a simple example:
........
ldr r0, ramoffset
........
ldmia r0!, {r2-r6}
........
.align 2
ramoffset:
.word 0xXXXXXXXX
Would the 5 words in r2-r6 be stored into the ram offset loaded previously in r0? If right, how will the 5 words be stored?
Another question: What is "increment r0"?
I've read your reply carefully, but still not clear about them, sorry.
r0 = pointer to some area in RAM
rlist = [r2, r3, r4, r5, r6]
for rX in rlist:
ldr rX, [r0]
add r0, r0, #0x4 @next word
https://problemkaputt.de/gbatek.htm#biosfunctions
I think the "h" means halfword (don't quote me on that). You just care about the index value before the "h" anyways, so it doesn't really matter for our uses.
In your example, ldmia will store r0s contents inside the listed registers. However, r2's contents will not match r3s or any other registers because we're increment r0 = r0 + 4 bytes for each register. Think of it like this:
Code:r0 = pointer to some area in RAM rlist = [r2, r3, r4, r5, r6] for rX in rlist: ldr rX, [r0] add r0, r0, #0x4 @next word
Clearly, rX != r(X +1) because r0 + 4(Y) != r0 +4X for all X, Y EN | X != Y.
I feel like you're going about this in the wrong order here though. You're trying to understand concepts/commands that (from what I can tell, without offence) are too early for you to be analyzing. Have you read through the beginner/intermediate ASM tutorials around these forums and are able to replicate their teachings in accurate efficiency? I think that completing all, if not most, of the existing tutorials is the first step. These kinds of technical details can probably be avoided during the early stage. Look at SWI after you've learned function calls in ASM and function calls in the ROM in general. Look at LDMIA/STMIA after you've understood how looping works in ASM and perhaps the difference between loading contents of an address vs applying math to the address itself (they're two simple things that I notice are often leading to confusions). Basically, stick to the basics before attempting the understand harder things.
........
ldr r0, ramoffset
........
ldmia r0!, {r2-r6}
........
.align 2
ramoffset:
.word 0x02000000
All of them are available in thumb mode unless stated otherwise (divARM for example is ARM obviously, and the ones marked as NDS aren't GBA)Haha, thank you for your reply.
I think you misunderstood my meaning. (Maybe that's because I don't use English in my daily life so I cannot convey my meaning)
For the swi case, I thought that h means hex as no$gba showed "h" this when debugging..... My question is that do all these functions all available in thumb? (Maybe I didn't convey my meaning clearly)
For the basic things, I've read JPAN's tutorial and some other tutorials (some not in this forum). I think I've known some basic things and I can write some functions in the ROM and as I've read JPAN's tutorial, I know how loop works from his simple "deleting pokemon" function. (Of course, I'm still a newbie, but not such new XD)
For ldmia and stmia, I think I know it this time.
Still for this example:
Code:........ ldr r0, ramoffset ........ ldmia r0!, {r2-r6} ........ .align 2 ramoffset: .word 0x02000000
If at 0x02000000 stores [WORD 1][WORD 2]...[WORD 5]...
then r2 will be WORD 1
......
r6 will be WORD 5
RIGHT?