Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions src/cpu/cpu650x.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,15 @@ uint8_t cpu_mem[65536];
__stack_data; \
})

/* Read-Modify-Write: some instructions perform a dummy write of the
* unmodified value before writing the modified one, strobing the address
* twice. This might affect memory-mapped I/O devices.
*/
#define RMW_WRITE(addr, current, value) do {\
sbus_write(addr, current); \
sbus_write(addr, value); \
} while (0)

/** Check and perform conditional branch (relative jump) */
#define COND_BRANCH(cond) do {\
uint16_t addr; \
Expand Down Expand Up @@ -268,18 +277,21 @@ static void AND(void)

static void ASL(void)
{
uint8_t orig;

if (addrmode == mIMP) {
SET_PFLAG(CPU.P.flags.C, (CPU.A & 0x80) != 0);
CPU.A = (CPU.A << 1) & 0xfe;
SET_PFLAG(CPU.P.flags.N, (CPU.A & 0x80) != 0);
SET_PFLAG(CPU.P.flags.Z, CPU.A == 0);
} else {
FETCH_DATA();
orig = fetched_data;
SET_PFLAG(CPU.P.flags.C, (fetched_data & 0x80) != 0);
fetched_data = (fetched_data << 1) & 0xfe;
SET_PFLAG(CPU.P.flags.N, (fetched_data & 0x80) != 0);
SET_PFLAG(CPU.P.flags.Z, fetched_data == 0);
sbus_write(fetched_addr, fetched_data);
RMW_WRITE(fetched_addr, orig, fetched_data);
}
}

Expand Down Expand Up @@ -413,8 +425,8 @@ static void DEC(void)
uint8_t res;

FETCH_DATA();
res = fetched_data - 1;
sbus_write(fetched_addr, res);
res = fetched_data - 1;
RMW_WRITE(fetched_addr, fetched_data, res);
SET_PFLAG(CPU.P.flags.N, (res & 0x80) != 0);
SET_PFLAG(CPU.P.flags.Z, res == 0);
}
Expand Down Expand Up @@ -447,7 +459,7 @@ static void INC(void)

FETCH_DATA();
res = fetched_data + 1;
sbus_write(fetched_addr, res);
RMW_WRITE(fetched_addr, fetched_data, res);
SET_PFLAG(CPU.P.flags.N, (res & 0x80) != 0);
SET_PFLAG(CPU.P.flags.Z, res == 0);
}
Expand Down Expand Up @@ -509,18 +521,21 @@ static void LDY(void)

static void LSR(void)
{
uint8_t orig;

if (addrmode == mIMP) {
SET_PFLAG(CPU.P.flags.C, (CPU.A & 0x1) != 0);
CPU.A = ((CPU.A >> 1) & 0x7f);
CPU.P.flags.N = 0;
SET_PFLAG(CPU.P.flags.Z, CPU.A == 0);
} else {
FETCH_DATA();
orig = fetched_data;
SET_PFLAG(CPU.P.flags.C, (fetched_data & 0x1) != 0);
fetched_data = ((fetched_data >> 1) & 0x7f);
CPU.P.flags.N = 0;
SET_PFLAG(CPU.P.flags.Z, fetched_data == 0);
sbus_write(fetched_addr, fetched_data);
RMW_WRITE(fetched_addr, orig, fetched_data);
}
}

Expand Down Expand Up @@ -561,6 +576,7 @@ static void PLP(void)

static void ROL(void)
{
uint8_t orig;
uint8_t tmp = CPU.P.flags.C;

if (addrmode == mIMP) {
Expand All @@ -570,16 +586,18 @@ static void ROL(void)
SET_PFLAG(CPU.P.flags.Z, CPU.A == 0);
} else {
FETCH_DATA();
orig = fetched_data;
SET_PFLAG(CPU.P.flags.C, (fetched_data & 0x80) != 0);
fetched_data = ((fetched_data << 1) & 0xfe) | tmp;
SET_PFLAG(CPU.P.flags.N, (fetched_data & 0x80) != 0);
SET_PFLAG(CPU.P.flags.Z, fetched_data == 0);
sbus_write(fetched_addr, fetched_data);
RMW_WRITE(fetched_addr, orig, fetched_data);
}
}

static void ROR(void)
{
uint8_t orig;
uint8_t tmp = CPU.P.flags.C;

if (addrmode == mIMP) {
Expand All @@ -589,12 +607,13 @@ static void ROR(void)
SET_PFLAG(CPU.P.flags.Z, CPU.A == 0);
} else {
FETCH_DATA();
orig = fetched_data;
SET_PFLAG(CPU.P.flags.C, (fetched_data & 0x1) != 0);
fetched_data = ((fetched_data >> 1) & 0x7f)
| ((tmp << 7) & 0x80);
CPU.P.flags.N = tmp;
SET_PFLAG(CPU.P.flags.Z, fetched_data == 0);
sbus_write(fetched_addr, fetched_data);
RMW_WRITE(fetched_addr, orig, fetched_data);
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/romdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ int load_rom(const char *pathname, rom_t **rom)
romf->chr_size = romf->header->chr_size * (8 * 1024);
} else {
if (romf->header->flag9.nes.prgrom_size < 0xf) {
/* Size in 16 KB units: MSB nibble (flag9) + LSB byte */
romf->prg_size =
((romf->header->flag9.nes.prgrom_size << 4) & 0xf0) |
(romf->header->prg_size & 0x0f);
((romf->header->flag9.nes.prgrom_size << 8) & 0xf00) |
romf->header->prg_size;
romf->prg_size *= (16 * 1024);
} else {
/* Get exponent and multiplier */
Expand All @@ -111,9 +112,10 @@ int load_rom(const char *pathname, rom_t **rom)
}

if (romf->header->flag9.nes.chrrom_size < 0xf) {
/* Size in 8 KB units: MSB nibble (flag9) + LSB byte */
romf->chr_size =
((romf->header->flag9.nes.chrrom_size << 4) & 0xf0) |
(romf->header->prg_size & 0x0f);
((romf->header->flag9.nes.chrrom_size << 8) & 0xf00) |
romf->header->chr_size;
romf->chr_size *= (8 * 1024);
} else {
/* Get exponent and multiplier */
Expand Down Expand Up @@ -142,7 +144,7 @@ int load_rom(const char *pathname, rom_t **rom)
romf->mapper = ((romf->header->flag7.ines.mapper << 4) & 0xf0) |
(romf->header->flag6.nes.mapper & 0xf);
} else {
romf->mapper = ((romf->header->flag8.raw << 8) & 0xff00) |
romf->mapper = ((romf->header->flag8.nes.mapper << 8) & 0xf00) |
((romf->header->flag7.nes.mapper << 4) & 0xf0) |
(romf->header->flag6.nes.mapper & 0xf);
}
Expand Down
Loading