blob: 651f97f7666f2c8d7eaf9d347c997fbac4df936d [file] [log] [blame]
swissChili6c61a792020-07-28 16:29:20 -07001#pragma once
2
3#include <stdint.h>
swissChili6264a3b2020-07-30 19:02:07 -07004#include <stdbool.h>
5
6#define REGISTERS R(A) R(X) R(Y) R(SP)
swissChili6c61a792020-07-28 16:29:20 -07007
8enum // Registers
9{
swissChili6264a3b2020-07-30 19:02:07 -070010 A, X, Y, SP
swissChili6c61a792020-07-28 16:29:20 -070011};
12
13enum // Flags
14{
15 CARRY = 1 << 0,
16 ZERO = 1 << 1,
17 NO_INT = 1 << 2,
18 DECIMAL = 1 << 3,
19 BREAK = 1 << 4,
20 UNUSED = 1 << 5,
21 OVERFLW = 1 << 6,
22 NEGATIV = 1 << 7,
23};
24
25enum // Address Modes
26{
27 AM_ACC, // Accumulator implied as operand
28 AM_IMP, // Implied operand
29 AM_IMM, // Immediate operand (8 bit)
30 AM_ABS, // Absolute operand (16 bit)
31 AM_ZP, // Zero-page operand
32 AM_REL, // Relative operand (signed 8 bit)
33 AM_IND, // Absolute indirect operand (16 bit address of 16 bit address)
34 AM_AX, // Absolute indexed with X
35 AM_AY, // Absolute indexed with Y
36 AM_ZPX, // Zero-page indexed with X
37 AM_ZPY, // Zero-page indexed with Y
38 AM_ZIX, // Zero-page indexed indirect (zp,x)
39 AM_ZIY, // Zero-page indirect indexed (zp),y
40};
41
42enum // Opcodes
43{
44 LDA,
45 LDX,
46 LDY,
47 STA,
48 STX,
49 STY,
50 ADC,
51 SBC,
52 INC,
53 INX,
54 INY,
55 DEC,
56 DEX,
57 DEY,
58 ASL,
59 LSR,
60 ROL,
61 ROR,
62 AND,
63 ORA,
64 EOR,
65 CMP,
66 CPX,
67 CPY,
68 BIT,
69 BCC,
70 BCS,
71 BNE,
72 BEQ,
73 BPL,
74 BMI,
75 BVC,
76 BVS,
77 TAX,
78 TXA,
79 TAY,
80 TYA,
81 TSX,
82 TXS,
83 PHA,
84 PLA,
85 PHP,
86 PLP,
87 JMP,
88 JSR,
89 RTS,
90 RTI,
91 CLC,
92 SEC,
93 CLD,
94 SED,
95 CLI,
96 SEI,
97 CLV,
98 BRK,
99 NOP,
100};
101
swissChili710d18d2020-07-29 19:43:20 -0700102enum // Fetch flags
103{
104 FETCH_NO_INDIRECTION = 1, // Do not follow indirection (used for disassembly)
105};
106
swissChili6264a3b2020-07-30 19:02:07 -0700107// Status register
108typedef struct __attribute__((packed))
109{
110 bool negative : 1;
111 bool overflow : 1;
112 bool unused : 1;
113 bool break_ : 1;
114 bool decimal : 1;
115 bool no_int : 1;
116 bool zero : 1;
117 bool carry : 1;
118} status_t;
119
swissChili6c61a792020-07-28 16:29:20 -0700120// Emulator instance, create with new_cpu()
121typedef struct
122{
swissChili6264a3b2020-07-30 19:02:07 -0700123 uint8_t regs[4]; // A, X, Y, SP registers
swissChili6c61a792020-07-28 16:29:20 -0700124 uint16_t pc;
swissChili6264a3b2020-07-30 19:02:07 -0700125 status_t status;
swissChili6c61a792020-07-28 16:29:20 -0700126 uint8_t *mem;
swissChili6264a3b2020-07-30 19:02:07 -0700127 bool running;
swissChili6c61a792020-07-28 16:29:20 -0700128} cpu_t;
129
130// Argument type, includes both pointer and its value
131typedef struct
132{
133 uint16_t val; // Value at pointer (used by most instructions)
134 uint16_t ptr; // Pointer (used by jumps, etc)
135} arg_t;
136
137cpu_t new_cpu();
swissChili6264a3b2020-07-30 19:02:07 -0700138void step(cpu_t *cpu);
swissChili6c61a792020-07-28 16:29:20 -0700139void free_cpu(cpu_t *cpu);
140void die(const char *message);
141void disas(cpu_t *cpu);