Jump to content

Invalid money division discrepancy: Difference between revisions

No edit summary
 
Line 9:
 
===Explanation===
There is no BCD instruction for halving (or shifting) a number in hardware; the game must manually perform long division.<ref>https://github.com/pret/pokered/blob/master/engine/math/bcd.asm</ref> Long division naturally has subtractions inside.
 
In order to perform BCD addition/subtraction, the code first performs regular addition/subtraction in hexadecimal, then relies on the '''DAA''' (Decimal Adjust register A) hardware instruction. This instruction automatically adds/subtracts hex:6 or hex:60 from a byte if the previous addition/subtraction resulted in an invalid digit or involved a carry/borrow. For example:
Line 17:
* hex:10 minus hex:1 normally yields hex:F, but it will also report a borrow. The DAA instruction may ''either'' detect the borrow or notice the invalid digit, and subtract another hex:6 to yield hex:9.
 
Note that in the last case, there is technically no need to look for invalid digits when subtracting, because the only way to get them is through a borrow. Crucially,The itGame isBoy easierhardware to ignoreignores invalid digits whenfor manufacturing hardware (circuitry)subtraction, but it is easier to detect the invalid digits anyway when emulating hardware. (The3DS's emulator maylooks say "detect allat invalid digits" instead of "detect invalid digits only whenfor adding"subtraction.) This difference in behavior ultimately leads to the inconsistency in thismoney articlediscrepancy.
 
Finally, the GameDAA Boy hardwareinstruction only supportsworks adding/subtractingon one byte at a time, forso BCD valuesaddition/subtraction must be done one byte at a time. In order to handle more than one byte, the code uses the "add with carry" and "subtract with carry" operations, which report to the CPU if a carry/borrow occurs and automatically add/subtract 1 from the result if the previous add/subtract with carry operation reported a carry/borrow. For example:
* In order to perform hex:1000 minus hex:222, the code must first subtract the rightmost bytes (hex:00 minus hex:22 yielding hex:DE). DAA then turns this into hex:78, then it reports a carry/borrow.
* The code then subtracts the leftmost bytes (hex:10 minus hex:2 yielding hex:E), then 1 is automatically subtracted due to the above "subtract with carry" reporting a borrow, then DAA turns the hex:D into hex:7.
Cookies help us deliver our services. By using our services, you agree to our use of cookies.