65/cpu.h
2020-03-11 17:50:45 -05:00

123 lines
3.4 KiB
C

#pragma once
#include"65.h"
#include"rom.h"
#include"ram.h"
#include"cpu.h"
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<string.h>
// 1975, baby!
// This 6502 implementation is LITTLE-ENDIAN
// and also assumes host machine is
// LITTLE-ENDIAN as well!
typedef struct ram_t ram_t;
typedef struct cpu_t
{
uint16_t pc; // Program counter
uint8_t a; // Accumulator
uint8_t x;
uint8_t y;
union // Status register
{
uint8_t reg; // Entire 8-bit register
struct
{
int8_t n:1; // Negative
int8_t v:1; // Overflow
int8_t _:1; // Ignored
int8_t b:1; // Break
int8_t d:1; // Decimal (BCD)
int8_t i:1; // Interrupt (enable/disable)
int8_t z:1; // Zero
int8_t c:1; // Carry
}bits; // Access individual bit flags
}sr;
uint8_t sp; // Stack pointer
}cpu_t;
// Micro-instructions ---------------------------
// Ex: lda $1f : lda( fetch() )
#ifdef __cpu
# undef __cpu
#endif
// General purpose "micro-insns"/macros
#define __cpu cpu
#define incpc() (__cpu->pc+=1)
#define fetch() (ram->ram[cpu_fetch(__cpu)]) // Get immediate binary value
#define fetch16() ( fetch() | (fetch()<<8) ) // Get immediate 16-bit binary value
#define deref(x) (ram_indirect_address(ram,x))
// Addressing mode "micro-insns"
#define imm fetch
#define imm16 fetch16 // Get immediate 16-bit binary value
//#define zp fetch // Get value at $0000 + x
//#define ab imm16 // Get 16-bit address
// Peek (without fetching)
#define imm_pk(x) (ram->ram[__cpu->pc+x]) // Peek immediate
#define imm16_pk(x) ( imm_pk(x) | (imm_pk(x+1)<<8) )// Peek immediate 16-bit
// Move micro-insns
#define lda(x) (__cpu->a=(x))
#define ldx(m) (__cpu->x=m)
#define ldy(x) (__cpu->y=(x))
#define ldpc(x) (__cpu->pc=(x))
#define nop()
#define brk()
#define sta(x) (ram->ram[x]=__cpu->a)
#define stx(z) (ram->ram[z]=__cpu->x)
#define sty(z) (ram->ram[z]=__cpu->y)
// Arithmetic micro-insns
#define adc(x) (cpu_adc(__cpu,x))
#define sbc(x) (cpu_sbc(__cpu,x))
// TODO AND is not always for accumulator
#define and(x) (__cpu->a &= (x))
#define eor(x) (__cpu->a ^= (x))
#define ora(x) (__cpu->a |= (x))
#define asl(x) (ram_asl(ram,(x)))
#define lsr(x) (ram_lsr(ram,(x)))
//#define asl(z) (z = z << 1)
//#define lsr(z) (z = z >> 1)
// Stack micro-insns
#define push16(x) (cpu_push16(__cpu,ram,(x)))
#define pull16(x) (cpu_pull16(__cpu,ram,(x)))
#define push(x) (cpu_push(__cpu,ram,(x)))
#define pull(x) (cpu_pull(__cpu,ram,(x)))
// Comparison
#define cmp(x,y) (cpu_cmp(cpu,(x),(y)))
#define bit(x) ()
// Status register micro-insns
#define sr_n(x) (__cpu->sr.bits.n=(x<0)) // Negative
#define sr_v(x) (__cpu->sr.bits.v=?) // Overflow
#define sr_b(x) (__cpu->sr.bits.b=?) // Break
#define sr_d(x) (__cpu->sr.bits.d=?) // Decimal (BCD)
#define sr_i(x) (__cpu->sr.bits.i=x) // Interrupt (enable/disable)
#define sr_z(x) (__cpu->sr.bits.z=(x==0)) // Zero
#define sr_c(x) (__cpu->sr.bits.c=?) // Carry
#define sr_nz(x) do{ uint16_t m=(x); sr_n(m); sr_z(m); }while(0)
// ----------------------------------------------
cpu_t*cpu_init(void);
void cpu_exec(cpu_t*cpu,ram_t*ram);
uint16_t cpu_fetch(cpu_t*cpu);
uint8_t cpu_adc(cpu_t*cpu,uint8_t x);
uint8_t cpu_sbc(cpu_t*cpu,uint8_t x);
uint8_t cpu_assign(cpu_t*cpu,uint8_t x);
void cpu_push16(cpu_t*cpu,ram_t*ram,uint16_t d);
void cpu_pull16(cpu_t*cpu,ram_t*ram,uint16_t*d);
void cpu_push(cpu_t*cpu,ram_t*ram,uint8_t d);
void cpu_pull(cpu_t*cpu,ram_t*ram,uint8_t*d);
void cpu_cmp(cpu_t*cpu,uint8_t x,uint8_t y);