1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-30 05:30:41 +00:00

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.
This commit is contained in:
Sidney Cadot 2024-12-19 23:13:20 +01:00
parent c52d7b27e6
commit 8cb941985d
2 changed files with 10 additions and 14 deletions

View File

@ -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)); \

View File

@ -37,6 +37,8 @@
#define _6502_H
#include <stdint.h>
/*****************************************************************************/
/* 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 */