#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define OPNAME(opcode) [opcode] = #opcode
#define CPS 0x00
#define ADC 0x01
#define PHP 0x08
#define PHA 0x09
#define PHY 0x0A
#define PHX 0x0C
#define JMP 0x10
#define SBC 0x11
#define PLP 0x18
#define PLA 0x19
#define PLY 0x1A
#define PLX 0x1C
#define JSR 0x20
#define AND 0x21
#define ANY 0x22
#define AAY 0x23
#define ANX 0x24
#define AAX 0x25
#define STT 0x28
#define BPO 0x30
#define ORA 0x31
#define ORY 0x32
#define OAY 0x33
#define ORX 0x34
#define OAX 0x35
#define SEI 0x38
#define BNG 0x40
#define XOR 0x41
#define XRY 0x42
#define XAY 0x43
#define XRX 0x44
#define XAX 0x45
#define CLI 0x48
#define BCS 0x50
#define LSL 0x51
#define SEC 0x58
#define STA 0x5B
#define STY 0x5D
#define STX 0x5E
#define BCC 0x60
#define LSR 0x61
#define CLC 0x68
#define LDA 0x69
#define LDY 0x6A
#define LDX 0x6C
#define BEQ 0x70
#define ROL 0x71
#define SSP 0x78
#define BNE 0x80
#define ROR 0x81
#define CSP 0x88
#define BVS 0x90
#define MUL 0x91
#define SEV 0x98
#define BVC 0xA0
#define DIV 0xA1
#define CLV 0xA8
#define RTS 0xB0
#define CMP 0xB1
#define CPY 0xB2
#define CAY 0xB3
#define CPX 0xB4
#define CAX 0xB5
#define ENT 0xB8
#define RTI 0xC0
#define INC 0xC1
#define INY 0xC2
#define IAY 0xC3
#define INX 0xC4
#define IAX 0xC5
#define DEC 0xD1
#define DEY 0xD2
#define DAY 0xD3
#define DEX 0xD4
#define DAX 0xD5
#define NOP 0xE8
#define BRK 0xF8
#define C ((uint64_t)1 << 0)
#define Z ((uint64_t)1 << 1)
#define I ((uint64_t)1 << 2)
#define S ((uint64_t)1 << 3)
#define V ((uint64_t)1 << 6)
#define N ((uint64_t)1 << 7)
#define STK_STADDR 0x010000
struct sux;
uint8_t *addr;
struct sux {
uint64_t ps;
uint64_t a[8], y[8], x[8];
uint64_t pc[8];
uint16_t sp;
uint8_t crt;
uint8_t c[8], z[8], i[8], s[8], v[8], n[8];
};
static const char *opname[0x100] = {
OPNAME(CPS),
[ADC] = "ADC #",
[0x03] = "ADC a",
[0x05] = "ADC zm",
OPNAME(PHP),
OPNAME(PHA),
OPNAME(PHY),
OPNAME(PHX),
OPNAME(JMP),
[SBC] = "SBC #",
[0x13] = "SBC a",
[0x15] = "SBC zm",
OPNAME(PLP),
OPNAME(PLA),
OPNAME(PLY),
OPNAME(PLX),
OPNAME(JSR),
[AND] = "AND #",
[ANY] = "ANY #",
OPNAME(AAY),
[ANX] = "ANX #",
OPNAME(AAX),
OPNAME(STT),
[0x29] = "AND a",
[0x2B] = "AND zm",
OPNAME(BPO),
[ORA] = "ORA #",
[ORY] = "ORY #",
OPNAME(OAY),
[ORX] = "ORX #",
OPNAME(OAX),
OPNAME(SEI),
[0x39] = "ORA a",
[0x3B] = "ORA zm",
OPNAME(BNG),
[XOR] = "XOR #",
[XRY] = "XRY #",
OPNAME(XAY),
[XRX] = "XRX #",
OPNAME(XAX),
OPNAME(CLI),
[0x49] = "XOR a",
[0x4B] = "XOR zm",
OPNAME(BCS),
[LSL] = "LSL #",
[0x52] = "ANY a",
[0x53] = "LSL a",
[0x54] = "ANX a",
[0x55] = "LSL zm",
OPNAME(SEC),
[0x59] = "LDA a",
[0x5A] = "LDY a",
[STA] = "STA a",
[0x5C] = "LDX a",
[STY] = "STY a",
[STX] = "STX a",
OPNAME(BCC),
[LSR] = "LSR #",
[0x62] = "ORY a",
[0x63] = "LSR a",
[0x64] = "ORX a",
[0x65] = "LSR zm",
OPNAME(CLC),
[LDA]= "LDA #",
[LDY]= "LDY #",
[LDX]= "LDX #",
OPNAME(BEQ),
[ROL] = "ROL #",
[0x72] = "XRY a",
[0x73] = "ROL a",
[0x74] = "XRX a",
[0x75] = "ROL zm",
OPNAME(SSP),
[0x79] = "LDA zm",
[0x7A] = "LDY zm",
[0x7B] = "STA zm",
[0x7C] = "LDX zm",
[0x7D] = "STY zm",
[0x7E] = "STX zm",
OPNAME(BNE),
[ROR] = "ROR #",
[0x82] = "ANY zm",
[0x83] = "ROR a",
[0x84] = "ANX zm",
[0x85] = "ROR zm",
OPNAME(CSP),
[0x89] = "LDA zm, x",
[0x8A] = "LDY zm, x",
[0x8B] = "STA zm, x",
[0x8D] = "STY zm, x",
OPNAME(BVS),
[MUL] = "MUL #",
[0x92] = "ORY zm",
[0x93] = "MUL a",
[0x94] = "ORX zm",
[0x95] = "MUL zm",
OPNAME(SEV),
[0x99] = "LDA zm, y",
[0x9B] = "LDX zm, y",
[0x9C] = "STA zm, y",
[0x9E] = "STX zm, y",
OPNAME(BVC),
[DIV] = "DIV #",
[0xA2] = "XRY zm",
[0xA3] = "DIV a",
[0xA4] = "XRX zm",
[0xA5] = "DIV zm",
OPNAME(CLV),
OPNAME(RTS),
[CMP] = "CMP #",
[CPY] = "CPY #",
OPNAME(CAY),
[CPX] = "CPX #",
OPNAME(CAX),
OPNAME(ENT),
OPNAME(RTI),
[INC] = "INC A",
OPNAME(INY),
OPNAME(IAY),
OPNAME(INX),
OPNAME(IAX),
[DEC] = "DEC A",
OPNAME(DEY),
OPNAME(DAY),
OPNAME(DEX),
OPNAME(DAX),
[0xE1] = "INC a",
[0xE2] = "CPY a",
[0xE3] = "INC zm",
[0xE4] = "CPX a",
[0xE5] = "CMP a",
OPNAME(NOP),
[0xF1] = "DEC a",
[0xF2] = "CPY zm",
[0xF3] = "DEC zm",
[0xF4] = "CPX zm",
[0xF4] = "CMP zm",
OPNAME(BRK),
};
extern void adc(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void sbc(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void mul(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void divd(struct sux *cpu, uint64_t adr, uint8_t thread);
extern uint64_t and(struct sux *cpu, uint64_t value, uint8_t thread);
extern void and_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread);
extern uint64_t or(struct sux *cpu, uint64_t value, uint8_t thread);
extern void or_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread);
extern uint64_t xor(struct sux *cpu, uint64_t value, uint8_t thread);
extern void xor_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread);
extern void rol(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void ror(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void lsl(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void lsr(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void inc(struct sux *cpu, uint64_t *reg, uint8_t thread);
extern void inc_addr(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void dec(struct sux *cpu, uint64_t *reg, uint8_t thread);
extern void dec_addr(struct sux *cpu, uint64_t adr, uint8_t thread);
extern void stt(struct sux *cpu, uint8_t value);
extern void ent(struct sux *cpu, uint8_t value);
extern void ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread);
extern void st(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread);
extern void push(struct sux *cpu, uint8_t value);
extern uint8_t pull(struct sux *cpu);
extern void cmp_addr(struct sux *cpu, uint64_t reg, uint64_t adr, uint8_t thread);
extern void cmp(struct sux *cpu, uint64_t reg1, uint64_t reg2, uint8_t thread);
extern void bfs(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread);
extern void bfc(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread);
extern void setps(struct sux *cpu, uint8_t thread);
extern uint64_t immaddr(struct sux *cpu, uint8_t thread, uint8_t size);
extern uint64_t absaddr(struct sux *cpu, uint8_t thread);
extern uint32_t zeromtx(struct sux *cpu, uint8_t thread);
extern uint32_t zeromx(struct sux *cpu, uint8_t thread);
extern uint32_t zeromy(struct sux *cpu, uint8_t thread);