Page 1 of 1

core bug in RSBS and RSCS instructions

Posted: Fri Feb 01, 2013 9:19 am
by abhoriel

I'm writing a GBA emulator for fun, and was testing my own core against VBA-M's

 

I found a bug in the ARM mode RSBS and RSCS instructions, in that they set the flags wrongly. They are set wrongly according to the ARM architecture documentation, and I have tested VBA-M against real hardware (a nintendoDS in GBA mode), and have found the flags to be set differently.

 

I'm using VBA-M 1.8.0.1138, compiled from the source available from the download page.

 

for example:

 

Code: Select all

mov r0, #0x80000000
mov r1, #0x00000001
rsb r0, r0, r1

 

on real hardware, the result is 0x80000001 and flags should be 0x90000001f (N..V..)

in VBA-M, the result is 0x80000001 and flags are 0x8000001f (N.C...)

 

the issue can be fixed with the following patch for VBA-M's C core:

Code: Select all

--- GBA-arm.cpp.old	2013-02-01 13:34:42.591850606 +0000
+++ GBA-arm.cpp	2013-02-01 14:01:38.395172242 +0000
@@ -951,9 +951,9 @@
#endif
#ifndef OP_RSB
 #define OP_RSB \
-    u32 lhs = reg[(opcode>>16)&15].I;                   \
-    u32 rhs = value;                                    \
-    u32 res = rhs - lhs;                                \
+    u32 lhs = value;                                    \
+    u32 rhs = reg[(opcode>>16)&15].I;                   \
+    u32 res = lhs - rhs;                                \
    reg[dest].I = res;
#endif
#ifndef OP_RSBS
@@ -991,9 +991,9 @@
#endif
#ifndef OP_RSC
 #define OP_RSC \
-    u32 lhs = reg[(opcode>>16)&15].I;                   \
-    u32 rhs = value;                                    \
-    u32 res = rhs - lhs - !((u32)C_FLAG);               \
+    u32 lhs = value;                                    \
+    u32 rhs = reg[(opcode>>16)&15].I;                   \
+    u32 res = lhs - rhs - !((u32)C_FLAG);               \
    reg[dest].I = res;
#endif
#ifndef OP_RSCS

 

I have not tested the asm core, and haven't even bothered to read the source. When enabled, it will not compile on my machine, but it is possible that the bug is present there too.

 

If anyone wants to test the issue themselves, here is the code I used. I will attach a pre-compiled ROM for testing too. [.gba files cannot be uploaded, perhaps for good reason - you will have to compile this yourself if you want to test it]

 

main.c

Code: Select all

#include 
#include 
#include 
#include 

#define GET_BIT(x, b) ((x) & (1 << (b)))

u32 testFunc(u32 a, u32 b);

int main() {
   u32 flags;

irqInit();
irqEnable(IRQ_VBLANK);
consoleInit(0, 4, 0, NULL, 0, 15);

BG_COLORS[0] = RGB5(0, 0, 0);
BG_COLORS[241] = RGB5(31, 31, 31);
REG_DISPCNT = MODE_0 | BG0_ON;

   u32 v1 = 0x80000000;
   u32 v2 = 0x00000001;

   printf("test: rsbs %08x, %08x\n", v1, v2);

   flags = testFunc(v1, v2);

   printf("flags: %08x (", flags);

   printf("%c", GET_BIT(flags, 31) ? 'N' : '.');
   printf("%c", GET_BIT(flags, 30) ? 'Z' : '.');
   printf("%c", GET_BIT(flags, 29) ? 'C' : '.');
   printf("%c", GET_BIT(flags, 28) ? 'V' : '.');
   printf("%c", GET_BIT(flags, 27) ? 'Q' : '.');
   printf("%c", GET_BIT(flags, 5) ? 'T' : '.');
   printf(")\n");
   return 0;
}

 

asm.s

Code: Select all

.arch armv4t

.section .iwram, "ax", %progbits @ use fast 32k RAM for ARM code
.align 2

.global testFunc
testFunc:
   rsbs r0, r0, r1
   mrs r0, cpsr
   bx lr

 

regards,


core bug in RSBS and RSCS instructions

Posted: Fri Feb 15, 2013 10:28 pm
by AdamN

instruction bug is critical as it could leads to other bugs, i hope someone could fix it, including the asm one [img]<fileStore.core_Emoticons>/emoticons/smile.png[/img]/emoticons/smile@2x.png 2x" width="20" height="20" />

 

the last time i found a flag bug it was causing flickering in vrally3 but i forgot which instruction :msn_embarrassed: i wonder if it's the same instruction, i only remember the fix was for asm


core bug in RSBS and RSCS instructions

Posted: Sat Feb 16, 2013 12:51 am
by Squall Leonhart

zero flag

 

bugs in the CPP core are usually not present in asm.