mirror of
https://github.com/irmen/prog8.git
synced 2025-10-25 05:18:38 +00:00
attempt to fix bcd
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user