From 8cb941985dec9d7cf275fa29a0ceb0b45da75b3c Mon Sep 17 00:00:00 2001 From: Sidney Cadot Date: Thu, 19 Dec 2024 23:13:20 +0100 Subject: [PATCH] sim65: tighten 6502 register types After a lot of preparatory work, we are now in position to finally tighten the types of the 6502 registers defined in the CPURegs struct of sim65. All registers were previously defined as bare 'unsigned', leading to subtle bugs where the bits beyond the 8 or 16 "true" bits in the register could become non-zero. Tightening the types of the registers to uint8_t and uint16_t as appropriate gets rid of these subtle bugs once and for all, assisted by the semantics of C when assigning an unsigned value to an unsigned type with less bits: the high-order bits are simply discarded, which is precisely what we'd want to happen. This change cleans up a lot of spurious failures of sim65 against the 65x02 test-set. For the 6502 and 65C02, we're now *functionally* compliant. For timing (i.e., clock cycle counts for each instruction), some work remains. --- src/sim65/6502.c | 10 ++-------- src/sim65/6502.h | 14 ++++++++------ 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/sim65/6502.c b/src/sim65/6502.c index cb3270185..8b16da2b8 100644 --- a/src/sim65/6502.c +++ b/src/sim65/6502.c @@ -664,15 +664,12 @@ static unsigned HaveIRQRequest; /* ADC, binary mode (6502 and 65C02) */ -/* TODO: once the Regs fields are properly sized, get rid of the - * "& 0xff" in the Regs.AC asignment. - */ #define ADC_BINARY_MODE(v) \ do { \ const uint8_t op = v; \ const uint8_t OldAC = Regs.AC; \ bool carry = GET_CF(); \ - Regs.AC = (OldAC + op + carry) & 0xff; \ + Regs.AC = (OldAC + op + carry); \ const bool NV = Regs.AC >= 0x80; \ carry = OldAC + op + carry >= 0x100; \ SET_SF(NV); \ @@ -1027,15 +1024,12 @@ static unsigned HaveIRQRequest; TEST_ZF (Val) /* SBC, binary mode (6502 and 65C02) */ -/* TODO: once the Regs fields are properly sized, get rid of the - * "& 0xff" in the Regs.AC asignment. - */ #define SBC_BINARY_MODE(v) \ do { \ const uint8_t op = v; \ const uint8_t OldAC = Regs.AC; \ const bool borrow = !GET_CF(); \ - Regs.AC = (OldAC - op - borrow) & 0xff; \ + Regs.AC = (OldAC - op - borrow); \ const bool NV = Regs.AC >= 0x80; \ SET_SF(NV); \ SET_OF(((OldAC >= 0x80) ^ NV) & ((op < 0x80) ^ NV)); \ diff --git a/src/sim65/6502.h b/src/sim65/6502.h index b6b621823..0f4d066d0 100644 --- a/src/sim65/6502.h +++ b/src/sim65/6502.h @@ -37,6 +37,8 @@ #define _6502_H +#include + /*****************************************************************************/ /* Data */ @@ -57,12 +59,12 @@ extern CPUType CPU; /* 6502 CPU registers */ typedef struct CPURegs CPURegs; struct CPURegs { - unsigned AC; /* Accumulator */ - unsigned XR; /* X register */ - unsigned YR; /* Y register */ - unsigned SR; /* Status register */ - unsigned SP; /* Stackpointer */ - unsigned PC; /* Program counter */ + uint8_t AC; /* Accumulator */ + uint8_t XR; /* X register */ + uint8_t YR; /* Y register */ + uint8_t SR; /* Status register */ + uint8_t SP; /* Stackpointer */ + uint16_t PC; /* Program counter */ }; /* Current CPU registers */