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:
parent
c52d7b27e6
commit
8cb941985d
@ -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)); \
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user