From 2bd8b56bc6f0652533f638aee1c9f78ec10787f0 Mon Sep 17 00:00:00 2001 From: Michel Heily Date: Wed, 6 Nov 2019 00:40:06 +0200 Subject: [PATCH] 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 --- README.md | 3 +++ src/core/arm7tdmi/alu.rs | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cdac0b0..39e6473 100644 --- a/README.md +++ b/README.md @@ -41,3 +41,6 @@ You know what they say, *third time's a charm*. - [GBATEK](http://problemkaputt.de/gbatek.htm) A single webpage written by *no$gba* developer Martin Korth. 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. \ No newline at end of file diff --git a/src/core/arm7tdmi/alu.rs b/src/core/arm7tdmi/alu.rs index 14e3d42..25e54b2 100644 --- a/src/core/arm7tdmi/alu.rs +++ b/src/core/arm7tdmi/alu.rs @@ -274,7 +274,7 @@ impl Core { fn alu_sub_flags(a: i32, b: i32, carry: &mut bool, overflow: &mut bool) -> i32 { let res = a.wrapping_sub(b); - *carry = b <= a; + *carry = (b as u32) <= (a as u32); let (_, would_overflow) = a.overflowing_sub(b); *overflow = would_overflow; res @@ -300,8 +300,8 @@ impl Core { RSB => op2.wrapping_sub(op1), ADD => op1.wrapping_add(op2), ADC => op1.wrapping_add(op2).wrapping_add(C), - SBC => op1.wrapping_sub(op2).wrapping_sub(1 - C), - RSC => op2.wrapping_sub(op1).wrapping_sub(1 - C), + SBC => op1.wrapping_sub(op2.wrapping_add(1 - C)), + RSC => op2.wrapping_sub(op1.wrapping_add(1 - C)), ORR => op1 | op2, MOV => op2, BIC => op1 & (!op2),