[cpu.c] Add JMP(6C) IND addressing mode exception

As some may know (I didn't), when doing JMP(6C) on an address
    like 0xXXFF (X may be any, let Y = X+1), JMP composes the
    final address by reading the lsb from 0xXXFF and the msb from
    0xXX00 instead of 0xXY00, as would be logical. JMP doesn't use
    carry and as such can't pass over to the next page, and when
    incrementing the argumental address (0xXXFF) the msb stays put.

    I did now know about any of this, and this is a pretty monumental
    exception, I feel more documentation should be written about this,
    I only randomly stumbled upon this on 6502.org
main
Joaquin 3 years ago
parent 6700e183e6
commit cf5b2613c6
Signed by: puly
GPG Key ID: 9E9299CD96C65EC6
  1. 4
      bus.c
  2. 28
      cpu.c

@ -39,7 +39,7 @@ void bus_write8(word address, word data){
address = mapper_resolve_write(address, data); //a lot of regions on the NES bus are mirrored/synced, this just ensures we are always writing to the parent region, not to a empty cloned one address = mapper_resolve_write(address, data); //a lot of regions on the NES bus are mirrored/synced, this just ensures we are always writing to the parent region, not to a empty cloned one
#ifdef DEBUG #ifdef DEBUG
printf("\nwrite-ram 0x%04X at 0x%04X\n; old_val 0x%04X", data, address, bus_read8(address)); printf("\nwrite-ram at 0x%04X val = 0x%04X\n; old_val 0x%04X", address, data, bus_read8(address));
#endif #endif
bus[address] = (unsigned char)data; bus[address] = (unsigned char)data;
@ -133,7 +133,7 @@ int main(int argc, char * argv[]){
PClogFILE = fopen("PClogFILE", "w"); PClogFILE = fopen("PClogFILE", "w");
#endif #endif
for(long iterations = 0; iterations != 3500; iterations++){ for(long iterations = 0; iterations != 9000; iterations++){
#ifdef DEBUG #ifdef DEBUG
fprintf(PClogFILE, "%4X\n", cpu->PC); fprintf(PClogFILE, "%4X\n", cpu->PC);

28
cpu.c

@ -96,10 +96,30 @@ busTransaction ABSY(CPU * __restrict__ cpu, word bytes){
busTransaction IND(CPU * __restrict__ cpu, word bytes){ busTransaction IND(CPU * __restrict__ cpu, word bytes){
busTransaction x; busTransaction x;
x.address = bus_read16(bytes); x.address = bus_read16(bytes);
//BAD CODE INCOMING:
//ok so there is an exception JMP(6C) makes that, from the way I
//wrote this code architecturally, I can't solve in an organic way
//other than making an exception right here, in the IND addresing mode
//that is used exclusively by JMP(6C) and nothing else, this sucks I know
//I'll try to find a smoother fix in the near future.
//The exception being that, when reading the value stored in bytes, it doesn't
//use carry, so for example for 0x02FF it doesnt read the 16 bit value in (0x02FF and 0x300),
//but rather (0x02FF and 0x0200), on the same page, since it cant carry over to the next page
//do not ask how long it took to find info about this, I feel this shouldn't really be
//brushed over so carelessly
//Signed, Joaquin
if((bytes & 0x00FF) == 0xFF){
x.address = bus_read8(bytes) | (bus_read8(bytes - 0xFF) << 8);
}
x.value = bus_read8(x.address); x.value = bus_read8(x.address);
#ifdef DEBUG #ifdef DEBUG
printf("\nIND: X>ADDRESS %04X | X>VALUE %04X | BYTES %04X | BUS_READ8(BYTES) %04X | BUS_READ16{BYTES} %04X | BUS_READ8(BYTES+1) %04X | BUS_READ8(BYTES-1) %04X | DEBUGREAD_BYTES+1 %04X\n", x.address, x.value, bytes, bus_read8(bytes), bus_read16(bytes), bus_read8(bytes + 1), bus_read8(bytes - 1), debug_read_do_not_use_pls(bytes+1)); printf("\nIND: X>ADDRESS %04X | X>VALUE %04X | BYTES %04X | BUS_READ8(BYTES) %04X | BUS_READ16{BYTES} %04X | BUS_READ8(BYTES+1) %04X | BUS_READ8(BYTES-1) %04X | BUS_READ8(BYTES - 0xFF) %04X\n", x.address, x.value, bytes, bus_read8(bytes), bus_read16(bytes), bus_read8(bytes + 1), bus_read8(bytes - 1), bus_read8(bytes - 0xFF));
#endif #endif
return x; return x;
@ -474,6 +494,12 @@ void JMP(CPU * __restrict__ cpu, word bytes, busTransaction (*addressing)(CPU *,
busTransaction x = addressing(cpu, bytes); //check line 85 for details busTransaction x = addressing(cpu, bytes); //check line 85 for details
cpu->PC = x.address; cpu->PC = x.address;
cpu->pcNeedsInc = false; cpu->pcNeedsInc = false;
//Part of the code for this opcode that manages the scenario in which we read from 0xXXFF
//(scenario in which we read the msb from 0xXX00, not 0xXY00, as would be logical, because
//JMP doesnt use carry and as such can't read from the next page) is regrettably written directly
//in the IND function that is only used by JMP(6C) because including it here would've overly complicated
//for no reason, look at the IND function for further detailing
} }
void LDA(CPU * cpu, word bytes, busTransaction (*addressing)(CPU *, word) ){ void LDA(CPU * cpu, word bytes, busTransaction (*addressing)(CPU *, word) ){

Loading…
Cancel
Save