attempt to fix bcd

This commit is contained in:
Irmen de Jong
2019-09-05 21:38:40 +02:00
parent e46982f652
commit adfddddac6
3 changed files with 27 additions and 28 deletions

View File

@@ -102,7 +102,6 @@ asmsub uword2bcd (uword value @ AY) clobbers(A,Y) {
pla ; read status register
and #%00000100
sta _had_irqd
sei ; disable interrupts because of bcd math
sed ; switch to decimal mode
lda #0 ; ensure the result is clear
sta bcdbuff+0
@@ -341,6 +340,7 @@ _irq_handler_init
dex
dex
dex
cld
rts
_irq_handler_end

View File

@@ -702,13 +702,12 @@ class Cpu6502(private val illegalInstrsAllowed: Boolean) : BusComponent(), ICpu
var lo = (A and 0x0f) + (operand and 0x0f) + if (Status.C) 1 else 0
if (lo and 0xff > 9) lo += 6
var hi = (A shr 4) + (operand shr 4) + if (lo > 15) 1 else 0
Status.N = (hi and 8) != 0 // strange... other sources say "BCD is never negative on NMOS 6502 (bug)"
Status.V = ((((hi shl 4) xor A) and 0x80) !=0) && ((A xor operand) and 0x80)==0 // strange... other sources say "V is never set in BCD mode"
if (hi and 0xff > 9) hi += 6
val result = lo and 0x0f or (hi shl 4)
A = result and 0xff
A = lo and 0x0f or (hi shl 4) and 0xff
Status.C = hi > 15
Status.Z = A == 0
Status.V = false // BCD never sets overflow flag
Status.N = false // BCD is never negative on NMOS 6502 (bug)
} else {
// normal add
val result = A + operand + if (Status.C) 1 else 0
@@ -990,21 +989,22 @@ class Cpu6502(private val illegalInstrsAllowed: Boolean) : BusComponent(), ICpu
}
private fun iSbc() {
val operand = getFetched()
if (Status.D) {
var lo = (A and 0x0f) - (operand and 0x0f) - if (Status.C) 0 else 1
val operand = getFetched()
var lo: Int
var hi: Int
lo = (A and 0x0f) - (operand and 0x0f) - if (Status.C) 0 else 1
if (lo and 0x10 != 0) lo -= 6
var hi = (A shr 4) - (operand shr 4) - if (lo and 0x10 != 0) 1 else 0
hi = (A shr 4) - (operand shr 4) - if (lo and 0x10 != 0) 1 else 0
if (hi and 0x10 != 0) hi -= 6
val result = lo and 0x0f or ((hi shl 4) and 0xff)
Status.C = hi and 255 < 15
Status.Z = result == 0
Status.V = false // BCD never sets overflow flag
Status.N = false // BCD is never negative on NMOS 6502 (bug)
A = result and 255
A = lo and 0x0f or (hi shl 4) and 0xff
Status.C = hi and 0xff < 15
Status.V = false // BCD never sets overflow flag
Status.Z = A==0
Status.N = (A and 0b10000000) != 0
} else {
// normal sub
val invertedOperand = operand xor 255
val invertedOperand = getFetched() xor 255
val result = A + invertedOperand + if (Status.C) 1 else 0
Status.C = result > 255
Status.V = (A xor invertedOperand) and (A xor result) and 0x0080 != 0

View File

@@ -505,11 +505,10 @@ abstract class TestCommon6502 {
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(0x80, mpu.A)
assertTrue(mpu.Status.N)
assertTrue(mpu.Status.V)
assertFalse(mpu.Status.Z)
assertFalse(mpu.Status.C)
assertFalse(mpu.Status.Z)
assertTrue(mpu.Status.V)
assertTrue(mpu.Status.N)
}
@Test
@@ -547,14 +546,13 @@ abstract class TestCommon6502 {
assertEquals(0x0004, mpu.PC)
assertEquals(0x93, mpu.A)
assertFalse(mpu.Status.N)
assertTrue(mpu.Status.V)
assertFalse(mpu.Status.Z)
assertTrue(mpu.Status.C)
// ADC Absolute, X-Indexed
assertTrue(mpu.Status.V)
}
// ADC Absolute, X-Indexed
@Test
fun test_adc_bcd_off_abs_x_carry_clear_in_accumulator_zeroes() {
@@ -5696,10 +5694,10 @@ abstract class TestCommon6502 {
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(0x9a, mpu.A)
assertTrue(mpu.Status.N)
assertFalse(mpu.Status.V)
assertFalse(mpu.Status.Z)
assertTrue(mpu.Status.C)
assertFalse(mpu.Status.V)
assertTrue(mpu.Status.N)
}
@Test
@@ -5715,17 +5713,18 @@ abstract class TestCommon6502 {
mpu.step()
assertEquals(0x0002, mpu.PC)
assertEquals(0x99, mpu.A)
assertTrue(mpu.Status.N)
assertFalse(mpu.Status.V)
assertFalse(mpu.Status.Z)
assertFalse(mpu.Status.C)
assertFalse(mpu.Status.V)
assertTrue(mpu.Status.N)
}
@Test
fun test_sbc_bcd_on_immediate_20_minus_0a_carry_unset() {
mpu.Status.D = true
mpu.Status.C = false
mpu.A = 0x20
// $0000 SBC #$00
// $0000 SBC #$0a
writeMem(memory, 0x0000, listOf(0xe9, 0x0a))
mpu.step()
assertEquals(0x0002, mpu.PC)