2019-04-27 10:43:15 +00:00
|
|
|
#include "memory.h"
|
|
|
|
|
2019-04-27 11:57:47 +00:00
|
|
|
byte fetch_byte(State6502* state) {
|
|
|
|
return state->memory[state->pc++];
|
|
|
|
}
|
|
|
|
|
|
|
|
word fetch_word(State6502* state) {
|
|
|
|
byte low = fetch_byte(state);
|
|
|
|
byte high = fetch_byte(state);
|
|
|
|
word result = (high << 8) | low;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word read_word(State6502 * state, word address) {
|
|
|
|
return state->memory[address] | state->memory[address + 1] << 8;
|
2019-04-27 10:43:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word read_word_wrap(State6502 * state, word address) {
|
|
|
|
word address_low = address;
|
|
|
|
//page wraparound
|
|
|
|
word address_high = (address_low & 0xFF) == 0xFF ? address - 0xFF : address_low + 1;
|
|
|
|
return state->memory[address_low] | state->memory[address_high] << 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
word get_address_zero_page(State6502 * state) {
|
2019-04-27 11:57:47 +00:00
|
|
|
return fetch_byte(state);
|
2019-04-27 10:43:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_zero_page(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//8 bit addressing, only the first 256 bytes of the memory
|
|
|
|
return state->memory[get_address_zero_page(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_zero_page_x(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//address is zero page, so wraparound byte
|
2019-04-27 11:57:47 +00:00
|
|
|
byte address = fetch_byte(state) + state->x;
|
2019-04-27 10:43:15 +00:00
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_zero_page_x(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
return state->memory[get_address_zero_page_x(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_zero_page_y(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//address is zero page, so wraparound byte
|
2019-04-27 11:57:47 +00:00
|
|
|
byte address = fetch_byte(state) + state->y;
|
2019-04-27 10:43:15 +00:00
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_zero_page_y(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
return state->memory[get_address_zero_page_y(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_absolute(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//absolute indexed, 16 bits
|
2019-04-27 11:57:47 +00:00
|
|
|
word address = fetch_word(state);
|
2019-04-27 10:43:15 +00:00
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_absolute(State6502 * state)
|
2019-04-27 10:43:15 +00:00
|
|
|
{
|
|
|
|
//absolute indexed, 16 bits
|
|
|
|
return state->memory[get_address_absolute(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_absolute_x(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//absolute added with the contents of x register
|
2019-04-27 11:57:47 +00:00
|
|
|
word address = fetch_word(state) + state->x;
|
2019-04-27 10:43:15 +00:00
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_absolute_x(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
return state->memory[get_address_absolute_x(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_absolute_y(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//absolute added with the contents of x register
|
2019-04-27 11:57:47 +00:00
|
|
|
word address = fetch_word(state) + state->y;
|
2019-04-27 10:43:15 +00:00
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_absolute_y(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//absolute added with the contents of y register
|
|
|
|
return state->memory[get_address_absolute_y(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_indirect_jmp(State6502 * state) {
|
2019-04-27 11:57:47 +00:00
|
|
|
word indirect_address = fetch_word(state);
|
2019-05-07 19:04:04 +00:00
|
|
|
//AN INDIRECT JUMP MUST NEVER USE A VECTOR BEGINNING ON THE LAST BYTE OF A PAGE
|
|
|
|
return read_word_wrap(state, indirect_address);
|
2019-04-27 10:43:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_indirect_x(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//pre-indexed indirect with the X register
|
|
|
|
//zero-page address is added to x register
|
2019-04-27 11:57:47 +00:00
|
|
|
byte indirect_address = fetch_byte(state) + state->x;
|
2019-04-27 10:43:15 +00:00
|
|
|
//pointing to address of a word holding the address of the operand
|
2019-05-07 19:04:04 +00:00
|
|
|
word address = read_word_wrap(state, indirect_address);
|
2019-04-27 10:43:15 +00:00
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_indirect_x(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//pre-indexed indirect with the X register
|
|
|
|
return state->memory[get_address_indirect_x(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_indirect_y(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
//post-indexed indirect
|
|
|
|
//zero-page address as an argument
|
2019-04-27 11:57:47 +00:00
|
|
|
byte indirect_address = fetch_byte(state);
|
2019-04-27 10:43:15 +00:00
|
|
|
//the address and the following byte is read as a word, adding Y register
|
2019-05-07 19:44:37 +00:00
|
|
|
word address = read_word_wrap(state, indirect_address) + state->y;
|
2019-04-27 10:43:15 +00:00
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
byte get_byte_indirect_y(State6502 * state) {
|
2019-04-27 10:43:15 +00:00
|
|
|
return state->memory[get_address_indirect_y(state)];
|
|
|
|
}
|
|
|
|
|
2019-05-07 19:04:04 +00:00
|
|
|
word get_address_relative(State6502 * state) {
|
2019-04-27 11:57:47 +00:00
|
|
|
int8_t address = (int8_t)fetch_byte(state);
|
2019-04-27 10:43:15 +00:00
|
|
|
return state->pc + address;
|
|
|
|
}
|