Working on my emulator. I'm trying to make my instructions require the correct amount of cycles. Tell me if the following is correct.
Let's say the instruction is LDA, Absolute X addressing.
After I ingest the LSB of the address, I just check if (LSB + X) > 0xff, and if it is, I add a cycle.
Sound good?
EDIT: I realize my math isn't taking the LSB wrapping around into account. Assume my code does.
EDIT: Is the carry flag a better way to check?
EDIT:Never mind concerning the carry flag. I forgot the carry flag only changes when I tell it to (which I will in this case of course).
Check my understanding of page crossing w/indexed addressing
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Check my understanding of page crossing w/indexed addres
Dan Moos wrote:
I forgot the carry flag only changes when I tell it to (which I will in this case of course).
Regarding page-crossing indexing, the cycle counts do typically increase by one, but I seem to remember an exception or two, where the non-page-crossing timing was the same as the page-crossing timing for certain instructions. I'm link-challenged at the moment, so someone please correct me if I'm wrong.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: Check my understanding of page crossing w/indexed addres
> I just check if (LSB + X) > 0xff, and if it is, I add a cycle.
Sounds right to me - you will of course need to be sure about signedness and byte-sizedness of your inputs there. What you're looking for is a carry from the LSB of the effective address to the MSB. (Which is unrelated to the C bit of your model.) Another way to do that, perhaps, is to see if the MSB in is different from the MSB out. Much depends on the data types in your code, as to what is efficient and maintainable.
Sounds right to me - you will of course need to be sure about signedness and byte-sizedness of your inputs there. What you're looking for is a carry from the LSB of the effective address to the MSB. (Which is unrelated to the C bit of your model.) Another way to do that, perhaps, is to see if the MSB in is different from the MSB out. Much depends on the data types in your code, as to what is efficient and maintainable.
Re: Check my understanding of page crossing w/indexed addres
Here's the actual code I've come up with:
seems to work. Cycle(1) advances the PC and puts it on the address bus. Cycle(0) does nothing (for now).
Code: Select all
//LDA Absolute, X. 3 bytes 4 cycles (+1 if page cross)
if (Address_Mode == ABSOLUTE_X) {
uint8_t MSB, LSB, LSB_Temp;
cycle(1);
LSB_Temp = DataBus ;
LSB = DataBus + X;
cycle(1);
MSB = DataBus;
if (LSB < LSB_Temp) { //add cycle if page crossed
MSB++;
cycle(0);
}
cycle(0);
AddressBus = (MSB << 8) | LSB;
A = Memory[AddressBus];
if (A == 0)
PS |= ZERO_FLAG;
else
PS &= ~(ZERO_FLAG);
if (A & 0b10000000)
PS |= NEGATIVE_FLAG;
else
PS &= ~(NEGATIVE_FLAG);
cycle(1);
}-
White Flame
- Posts: 704
- Joined: 24 Jul 2012
Re: Check my understanding of page crossing w/indexed addres
Probably the best reference for writing accurate NMOS 6502 emulators is 64doc. It'll step through what goes on every single cycle of an instruction, and you can simplify from there if you're just going for total number of cycles. For instance, LDA abs,X does a redundant read if a page boundary is crossed by the indexing:
Also, computing the N & Z flags are pretty much always done together, so creating an inline function or macro for computing those two is useful.
Code: Select all
Absolute indexed addressing
Read instructions (LDA, LDX, LDY, EOR, AND, ORA, ADC, SBC, CMP, BIT,
LAX, LAE, SHS, NOP)
# address R/W description
--- --------- --- ------------------------------------------
1 PC R fetch opcode, increment PC
2 PC R fetch low byte of address, increment PC
3 PC R fetch high byte of address,
add index register to low address byte,
increment PC
4 address+I* R read from effective address,
fix the high byte of effective address
5+ address+I R re-read from effective address
Notes: I denotes either index register (X or Y).
* The high byte of the effective address may be invalid
at this time, i.e. it may be smaller by $100.
+ This cycle will be executed only if the effective address
was invalid during cycle #4, i.e. page boundary was crossed.