2017-01-03 19:39:48 +00:00
|
|
|
#include <stdint.h>
|
2017-01-07 21:25:34 +00:00
|
|
|
#include <stdbool.h>
|
2017-01-03 19:39:48 +00:00
|
|
|
|
2017-01-08 16:28:13 +00:00
|
|
|
#define CPU_FREQ 4e6 // 4Mhz
|
|
|
|
#define STEP_DURATION 10e6 // 10ms
|
2017-01-03 19:39:48 +00:00
|
|
|
#define ONE_SECOND 1e9
|
|
|
|
#define NUM_MODES 13
|
|
|
|
|
|
|
|
#define NMI_VEC 0xFFFA
|
|
|
|
#define RST_VEC 0xFFFC
|
|
|
|
#define IRQ_VEC 0xFFFE
|
|
|
|
|
|
|
|
uint8_t memory[1<<16];
|
|
|
|
uint8_t A;
|
|
|
|
uint8_t X;
|
|
|
|
uint8_t Y;
|
|
|
|
uint16_t PC;
|
|
|
|
uint8_t SP; // points to first empty stack location
|
|
|
|
|
2017-01-03 20:18:36 +00:00
|
|
|
void * read_addr;
|
|
|
|
void * write_addr;
|
2017-01-03 19:39:48 +00:00
|
|
|
|
|
|
|
struct StatusBits{
|
2017-01-07 21:25:34 +00:00
|
|
|
bool carry:1; // bit 0
|
|
|
|
bool zero:1;
|
|
|
|
bool interrupt:1;
|
|
|
|
bool decimal:1;
|
|
|
|
bool brk:1; // "break" is a reserved word :(
|
|
|
|
bool unused:1;
|
|
|
|
bool overflow:1;
|
|
|
|
bool sign:1; // bit 7
|
2017-01-03 19:39:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
union StatusReg { // this means we can access the status register as a byte, or as individual bits.
|
|
|
|
struct StatusBits bits;
|
|
|
|
uint8_t byte;
|
|
|
|
};
|
|
|
|
|
|
|
|
union StatusReg SR;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
ACC,
|
|
|
|
ABS,
|
|
|
|
ABSX,
|
|
|
|
ABSY,
|
|
|
|
IMM,
|
|
|
|
IMPL,
|
|
|
|
IND,
|
|
|
|
XIND,
|
|
|
|
INDY,
|
|
|
|
REL,
|
|
|
|
ZP,
|
|
|
|
ZPX,
|
|
|
|
ZPY
|
|
|
|
} Mode;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
char * mnemonic;
|
|
|
|
void (*function)();
|
|
|
|
Mode mode;
|
2017-01-08 16:28:13 +00:00
|
|
|
uint8_t cycles;
|
2017-01-03 19:39:48 +00:00
|
|
|
} Instruction;
|
|
|
|
|
|
|
|
Instruction instructions[0x100];
|
|
|
|
|
|
|
|
void init_tables();
|
|
|
|
|
|
|
|
void reset_cpu();
|
|
|
|
|
|
|
|
int load_rom(char * filename);
|
|
|
|
|
2017-01-08 16:28:13 +00:00
|
|
|
int step_cpu();
|