mirror of
				https://github.com/irmen/prog8.git
				synced 2025-10-31 00:16:08 +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 | 		pla             ; read status register | ||||||
| 		and  #%00000100 | 		and  #%00000100 | ||||||
| 		sta  _had_irqd | 		sta  _had_irqd | ||||||
| 		sei				; disable interrupts because of bcd math |  | ||||||
| 		sed				; switch to decimal mode | 		sed				; switch to decimal mode | ||||||
| 		lda  #0				; ensure the result is clear | 		lda  #0				; ensure the result is clear | ||||||
| 		sta  bcdbuff+0 | 		sta  bcdbuff+0 | ||||||
| @@ -341,6 +340,7 @@ _irq_handler_init | |||||||
| 		dex | 		dex | ||||||
| 		dex | 		dex | ||||||
| 		dex | 		dex | ||||||
|  | 		cld | ||||||
| 		rts | 		rts | ||||||
|  |  | ||||||
| _irq_handler_end | _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 |             var lo = (A and 0x0f) + (operand and 0x0f) + if (Status.C) 1 else 0 | ||||||
|             if (lo and 0xff > 9) lo += 6 |             if (lo and 0xff > 9) lo += 6 | ||||||
|             var hi = (A shr 4) + (operand shr 4) + if (lo > 15) 1 else 0 |             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 |             if (hi and 0xff > 9) hi += 6 | ||||||
|             val result = lo and 0x0f or (hi shl 4) |             A = lo and 0x0f or (hi shl 4) and 0xff | ||||||
|             A = result and 0xff |  | ||||||
|             Status.C = hi > 15 |             Status.C = hi > 15 | ||||||
|             Status.Z = A == 0 |             Status.Z = A == 0 | ||||||
|             Status.V = false  // BCD never sets overflow flag |  | ||||||
|             Status.N = false  // BCD is never negative on NMOS 6502 (bug) |  | ||||||
|         } else { |         } else { | ||||||
|             // normal add |             // normal add | ||||||
|             val result = A + operand + if (Status.C) 1 else 0 |             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() { |     private fun iSbc() { | ||||||
|         val operand = getFetched() |  | ||||||
|         if (Status.D) { |         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 |             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 |             if (hi and 0x10 != 0) hi -= 6 | ||||||
|             val result = lo and 0x0f or ((hi shl 4) and 0xff) |             A = lo and 0x0f or (hi shl 4) and 0xff | ||||||
|             Status.C = hi and 255 < 15 |             Status.C = hi and 0xff < 15 | ||||||
|             Status.Z = result == 0 |             Status.V = false  // BCD never sets overflow flag | ||||||
|             Status.V = false // BCD never sets overflow flag |             Status.Z = A==0 | ||||||
|             Status.N = false // BCD is never negative on NMOS 6502 (bug) |             Status.N = (A and 0b10000000) != 0 | ||||||
|             A = result and 255 |  | ||||||
|         } else { |         } else { | ||||||
|             // normal sub |             // normal sub | ||||||
|             val invertedOperand = operand xor 255 |             val invertedOperand = getFetched() xor 255 | ||||||
|             val result = A + invertedOperand + if (Status.C) 1 else 0 |             val result = A + invertedOperand + if (Status.C) 1 else 0 | ||||||
|             Status.C = result > 255 |             Status.C = result > 255 | ||||||
|             Status.V = (A xor invertedOperand) and (A xor result) and 0x0080 != 0 |             Status.V = (A xor invertedOperand) and (A xor result) and 0x0080 != 0 | ||||||
|   | |||||||
| @@ -505,11 +505,10 @@ abstract class TestCommon6502 { | |||||||
|         mpu.step() |         mpu.step() | ||||||
|         assertEquals(0x0002, mpu.PC) |         assertEquals(0x0002, mpu.PC) | ||||||
|         assertEquals(0x80, mpu.A) |         assertEquals(0x80, mpu.A) | ||||||
|         assertTrue(mpu.Status.N) |  | ||||||
|         assertTrue(mpu.Status.V) |  | ||||||
|         assertFalse(mpu.Status.Z) |  | ||||||
|         assertFalse(mpu.Status.C) |         assertFalse(mpu.Status.C) | ||||||
|  |         assertFalse(mpu.Status.Z) | ||||||
|  |         assertTrue(mpu.Status.V) | ||||||
|  |         assertTrue(mpu.Status.N) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -547,14 +546,13 @@ abstract class TestCommon6502 { | |||||||
|         assertEquals(0x0004, mpu.PC) |         assertEquals(0x0004, mpu.PC) | ||||||
|         assertEquals(0x93, mpu.A) |         assertEquals(0x93, mpu.A) | ||||||
|         assertFalse(mpu.Status.N) |         assertFalse(mpu.Status.N) | ||||||
|         assertTrue(mpu.Status.V) |  | ||||||
|         assertFalse(mpu.Status.Z) |         assertFalse(mpu.Status.Z) | ||||||
|         assertTrue(mpu.Status.C) |         assertTrue(mpu.Status.C) | ||||||
|  |         assertTrue(mpu.Status.V) | ||||||
|         // ADC Absolute, X-Indexed |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // ADC Absolute, X-Indexed | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     fun test_adc_bcd_off_abs_x_carry_clear_in_accumulator_zeroes() { |     fun test_adc_bcd_off_abs_x_carry_clear_in_accumulator_zeroes() { | ||||||
|  |  | ||||||
| @@ -5696,10 +5694,10 @@ abstract class TestCommon6502 { | |||||||
|         mpu.step() |         mpu.step() | ||||||
|         assertEquals(0x0002, mpu.PC) |         assertEquals(0x0002, mpu.PC) | ||||||
|         assertEquals(0x9a, mpu.A) |         assertEquals(0x9a, mpu.A) | ||||||
|         assertTrue(mpu.Status.N) |  | ||||||
|         assertFalse(mpu.Status.V) |  | ||||||
|         assertFalse(mpu.Status.Z) |         assertFalse(mpu.Status.Z) | ||||||
|         assertTrue(mpu.Status.C) |         assertTrue(mpu.Status.C) | ||||||
|  |         assertFalse(mpu.Status.V) | ||||||
|  |         assertTrue(mpu.Status.N) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -5715,17 +5713,18 @@ abstract class TestCommon6502 { | |||||||
|         mpu.step() |         mpu.step() | ||||||
|         assertEquals(0x0002, mpu.PC) |         assertEquals(0x0002, mpu.PC) | ||||||
|         assertEquals(0x99, mpu.A) |         assertEquals(0x99, mpu.A) | ||||||
|         assertTrue(mpu.Status.N) |  | ||||||
|         assertFalse(mpu.Status.V) |  | ||||||
|         assertFalse(mpu.Status.Z) |         assertFalse(mpu.Status.Z) | ||||||
|         assertFalse(mpu.Status.C) |         assertFalse(mpu.Status.C) | ||||||
|  |         assertFalse(mpu.Status.V) | ||||||
|  |         assertTrue(mpu.Status.N) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     fun test_sbc_bcd_on_immediate_20_minus_0a_carry_unset() { |     fun test_sbc_bcd_on_immediate_20_minus_0a_carry_unset() { | ||||||
|         mpu.Status.D = true |         mpu.Status.D = true | ||||||
|  |         mpu.Status.C = false | ||||||
|         mpu.A = 0x20 |         mpu.A = 0x20 | ||||||
|         // $0000 SBC #$00 |         // $0000 SBC #$0a | ||||||
|         writeMem(memory, 0x0000, listOf(0xe9, 0x0a)) |         writeMem(memory, 0x0000, listOf(0xe9, 0x0a)) | ||||||
|         mpu.step() |         mpu.step() | ||||||
|         assertEquals(0x0002, mpu.PC) |         assertEquals(0x0002, mpu.PC) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user