Fix that DAMN bug.

Long story short, I've been hunting this bug for a while now.
While passing armwresteler tests, I still had an emulation bug which
causeed libgcc's iprintf to produce bugged strings.

In order to find it, I've used https://github.com/fleroviux/NanoboyAdvance/
And patched it to produce a formatted log of every step of the execution
of iprintf:
{OPCODE} {PC} {R0} {R1} ... {R14} {FLAGS}
Did the same on my emulator and searched for differences.

Found out the a "CMP r3, #0x0" instruction turned off the carry flag
when it shouldn't. Found this sad function, the check I'm using for
carry flag is meaningless when done on signed integers. :sigh:


Former-commit-id: 871d2581921796dae9bf4f5fdaa45c6ad46aebec
This commit is contained in:
Michel Heily 2019-11-06 00:40:06 +02:00
parent 7cc1a50d12
commit 2bd8b56bc6
2 changed files with 6 additions and 3 deletions

View file

@ -41,3 +41,6 @@ You know what they say, *third time's a charm*.
- [GBATEK](http://problemkaputt.de/gbatek.htm) - [GBATEK](http://problemkaputt.de/gbatek.htm)
A single webpage written by *no$gba* developer Martin Korth. A single webpage written by *no$gba* developer Martin Korth.
This page has pretty much everything. Seriously, it's the best. This page has pretty much everything. Seriously, it's the best.
- [NanoboyAdvance](https://github.com/fleroviux/NanoboyAdvance)]
A GameBoy Advance emulator written in C++17 by a nice person called fleroviux.
I've used this emulator to search for a tough bug in mine.

View file

@ -274,7 +274,7 @@ impl Core {
fn alu_sub_flags(a: i32, b: i32, carry: &mut bool, overflow: &mut bool) -> i32 { fn alu_sub_flags(a: i32, b: i32, carry: &mut bool, overflow: &mut bool) -> i32 {
let res = a.wrapping_sub(b); let res = a.wrapping_sub(b);
*carry = b <= a; *carry = (b as u32) <= (a as u32);
let (_, would_overflow) = a.overflowing_sub(b); let (_, would_overflow) = a.overflowing_sub(b);
*overflow = would_overflow; *overflow = would_overflow;
res res
@ -300,8 +300,8 @@ impl Core {
RSB => op2.wrapping_sub(op1), RSB => op2.wrapping_sub(op1),
ADD => op1.wrapping_add(op2), ADD => op1.wrapping_add(op2),
ADC => op1.wrapping_add(op2).wrapping_add(C), ADC => op1.wrapping_add(op2).wrapping_add(C),
SBC => op1.wrapping_sub(op2).wrapping_sub(1 - C), SBC => op1.wrapping_sub(op2.wrapping_add(1 - C)),
RSC => op2.wrapping_sub(op1).wrapping_sub(1 - C), RSC => op2.wrapping_sub(op1.wrapping_add(1 - C)),
ORR => op1 | op2, ORR => op1 | op2,
MOV => op2, MOV => op2,
BIC => op1 & (!op2), BIC => op1 & (!op2),