gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Self-modifying code framework?

#171702 - Pate - Tue Dec 15, 2009 6:53 am

Hi!

In my DSx86 emulator I could really use self-modifying code to speed up some things. The problem is, I haven't been able to get self-modifying code to work realiably. It seems to work for a few seconds, and then DSx86 crashes.

I was wondering, have some of you used self-modifying code (running in ITCM), and what exactly is needed to make this reliable? I think the ARM ARM states that an implementation-specific CPU pipeline flushing is needed before the instruction pointer accesses the self-modified code, but what might this implementation-specific thing be on NDS?

Thanks!

Pate
_________________

#171703 - sverx - Tue Dec 15, 2009 9:47 am

I guess you should invalidate ARM9 instruction cache... libnds has IC_InvalidateAll() (or IC_InvalidateRange(const void *base, u32 size); ) function for instance...

#171704 - Pate - Tue Dec 15, 2009 10:20 am

Hmm.. My code that I want to change is in ITCM, which I thought does not use the instruction cache?

Pate
_________________

#171705 - sverx - Tue Dec 15, 2009 10:32 am

Oh, right :| **!

#171706 - kusma - Tue Dec 15, 2009 11:48 am

In that case, the only thing I can think of is making sure you don't modify the next couple of instructions (that is, don't modify PC+4 and PC+8 in ARM mode, or PC+2 and PC+4 in THUMB mode), since they are already fetched from memory. Do note that ARM9 has a longer than 3 stage pipeline, but I do believe it does some stalling to emulate the ARM7 (and earlier) behavior.

#171707 - Pate - Tue Dec 15, 2009 12:32 pm

Ok.. In that case it looks like the problem is not directly Self-Modifying-Code -related. What I attempted to do was simply to change the immediate value of an instruction, and I couldn't understand why it would crash.

This is the code:
Code:

#if SELFMODTEST
    ldrb    r0,[r12],#1            @ Load opcode byte to r0, increment r12 by 1
    mov     r2,r3               @ Clear segment override, r2 = r3 = physical DS:0000
    .global IRQ_SM
IRQ_SM:   
    and     r1, r0, #0xFF         @ AND the opcode value with the IRQFlag value, result is either just the opcode or 0
#else
    ldr     r1,[sp, #SP_IRQFLAG]   @ Get the IRQFlag value (set to 0 if we need to handle an IRQ, else 0xFF)
    ldrb    r0,[r12],#1            @ Load opcode byte to r0, increment r12 by 1
    mov     r2,r3               @ Clear segment override, r2 = r3 = physical DS:0000
    and     r1, r0               @ AND the opcode value with the IRQFlag value, result is either just the opcode or 0
#endif   


I store (in a real timer interrupt handler) 0 to the immediate byte at IRQ_SM when I want to handle an IRQ, and store 0xFF there when I want to continue normally.

It was some time ago when I last tested this, perhaps I just need to try again.

Pate
_________________

#171709 - FluBBa - Tue Dec 15, 2009 4:57 pm

How does the code look like that actually modifies the instruction?
_________________
I probably suck, my not is a programmer.

#171710 - Pate - Tue Dec 15, 2009 7:26 pm

Like this:

Code:

#define   IRQ_ON      #0
#define   IRQ_OFF      #0xFF

#if SELFMODTEST
   ldr      r1, =IRQ_SM
   mov      r0, IRQ_OFF
   strb   r0, [r1]
#endif

...

#if SELFMODTEST
   ldr      r1, =IRQ_SM
   mov      r0, IRQ_ON
   strb   r0, [r1]
#endif   



I believe I checked that the low byte of the opcode contains the immediate value, so I only change that.

Pate
_________________

#171712 - Dwedit - Tue Dec 15, 2009 11:16 pm

I used a lot of SMC in early working versions of Goomba Color DS, and I never hit any crashes. I have no idea what's going on here.

The code looks correct (although, I would never include a # for a number in a define, it just looks wrong in the code).

Only other things I can think of are whether they are in the same source file, and the address used is correct. Or maybe there is some completely other unrelated bug showing up. Maybe add some nops to see if the size difference is triggering a bug or something.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#171715 - Pate - Wed Dec 16, 2009 6:03 am

Okay, thanks for the info!

Yeah, I'll need to change that # character, I don't know why I originally did it that way, I've had to change it in most of my other defines (as I needed to perform arithmetic operations with the defines).

It's good to know that the basic idea I have for SMC is sound, and the problem must be elsewhere in the code. I don't then spend time looking into the wrong things.

Thanks!

Pate
_________________