mirror of https://github.com/mlaux/gb6.git
initial commit
This commit is contained in:
commit
3e264da356
|
@ -0,0 +1 @@
|
|||
*.swp
|
|
@ -0,0 +1,80 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "types.h"
|
||||
|
||||
void cpu_bind_mem_model(
|
||||
struct cpu *cpu,
|
||||
void *mem_model,
|
||||
u8 (*mem_read)(void *, u16),
|
||||
void (*mem_write)(void *, u16, u8)
|
||||
) {
|
||||
cpu->mem_model = mem_model;
|
||||
cpu->mem_read = mem_read;
|
||||
cpu->mem_write = mem_write;
|
||||
}
|
||||
|
||||
static inline u16 read_af(struct cpu *cpu)
|
||||
{
|
||||
return cpu->a << 8 | cpu->f;
|
||||
}
|
||||
|
||||
static inline u16 read_bc(struct cpu *cpu)
|
||||
{
|
||||
return cpu->b << 8 | cpu->c;
|
||||
}
|
||||
|
||||
static inline u16 read_de(struct cpu *cpu)
|
||||
{
|
||||
return cpu->d << 8 | cpu->e;
|
||||
}
|
||||
|
||||
static inline u16 read_hl(struct cpu *cpu)
|
||||
{
|
||||
return cpu->h << 8 | cpu->l;
|
||||
}
|
||||
|
||||
static inline void write_af(struct cpu *cpu, int value)
|
||||
{
|
||||
cpu->a = value >> 8;
|
||||
cpu->f = value & 0xff;
|
||||
}
|
||||
|
||||
static inline void write_bc(struct cpu *cpu, int value)
|
||||
{
|
||||
cpu->b = value >> 8;
|
||||
cpu->c = value & 0xff;
|
||||
}
|
||||
|
||||
static inline void write_de(struct cpu *cpu, int value)
|
||||
{
|
||||
cpu->d = value >> 8;
|
||||
cpu->e = value & 0xff;
|
||||
}
|
||||
|
||||
static inline void write_hl(struct cpu *cpu, int value)
|
||||
{
|
||||
cpu->h = value >> 8;
|
||||
cpu->l = value & 0xff;
|
||||
}
|
||||
|
||||
void cpu_panic(struct cpu *cpu)
|
||||
{
|
||||
printf("a=%02x f=%02x b=%02x c=%02x\n", cpu->a, cpu->f, cpu->b, cpu->c);
|
||||
printf("d=%02x e=%02x h=%02x l=%02x\n", cpu->d, cpu->e, cpu->h, cpu->l);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void cpu_step(struct cpu *cpu)
|
||||
{
|
||||
u8 opc = cpu->mem_read(cpu->mem_model, cpu->pc);
|
||||
switch (opc) {
|
||||
case 0: // NOP
|
||||
cpu->pc++;
|
||||
break;
|
||||
default:
|
||||
printf("unknown opcode %02x\n", opc);
|
||||
cpu_panic(cpu);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef _CPU_H
|
||||
#define _CPU_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct cpu
|
||||
{
|
||||
u8 a;
|
||||
u8 f;
|
||||
u8 b;
|
||||
u8 c;
|
||||
u8 d;
|
||||
u8 e;
|
||||
u8 h;
|
||||
u8 l;
|
||||
u16 sp;
|
||||
u16 pc;
|
||||
|
||||
u8 (*mem_read)(void *, u16);
|
||||
void (*mem_write)(void *, u16, u8);
|
||||
void *mem_model;
|
||||
};
|
||||
|
||||
void cpu_bind_mem_model(
|
||||
struct cpu *cpu,
|
||||
void *mem_model,
|
||||
u8 (*mem_read)(void *, u16),
|
||||
void (*mem_write)(void *, u16, u8)
|
||||
);
|
||||
|
||||
void cpu_step(struct cpu *cpu);
|
||||
|
||||
#define FLAG_Z(cpu) ((cpu)->f >> 7 & 1)
|
||||
#define FLAG_N(cpu) ((cpu)->f >> 6 & 1)
|
||||
#define FLAG_H(cpu) ((cpu)->f >> 5 & 1)
|
||||
#define FLAG_C(cpu) ((cpu)->f >> 4 & 1)
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
#include "cpu.h"
|
||||
#include "rom.h"
|
||||
#include "dmg.h"
|
||||
#include "types.h"
|
||||
|
||||
void dmg_new(struct dmg *dmg, struct cpu *cpu, struct rom *rom)
|
||||
{
|
||||
dmg->cpu = cpu;
|
||||
dmg->rom = rom;
|
||||
}
|
||||
|
||||
u8 dmg_read(void *_dmg, u16 address)
|
||||
{
|
||||
struct dmg *dmg = (struct dmg *) _dmg;
|
||||
if (address < 0x4000) {
|
||||
return dmg->rom->data[address];
|
||||
} else if (address < 0x8000) {
|
||||
// TODO switchable rom bank
|
||||
return dmg->rom->data[address];
|
||||
} else if (address < 0xa000) {
|
||||
return dmg->video_ram[address - 0x8000];
|
||||
} else if (address < 0xc000) {
|
||||
// TODO switchable ram bank
|
||||
return 0;
|
||||
} else if (address < 0xe000) {
|
||||
return dmg->main_ram[address - 0xc000];
|
||||
} else {
|
||||
// not sure about any of this yet
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void dmg_write(void *_dmg, u16 address, u8 data)
|
||||
{
|
||||
struct dmg *dmg = (struct dmg *) _dmg;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef _DMG_H
|
||||
#define _DMG_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "rom.h"
|
||||
|
||||
struct dmg {
|
||||
struct cpu *cpu;
|
||||
struct rom *rom;
|
||||
u8 main_ram[0x2000];
|
||||
u8 video_ram[0x2000];
|
||||
};
|
||||
|
||||
void dmg_new(struct dmg *dmg, struct cpu *cpu, struct rom *rom);
|
||||
|
||||
u8 dmg_read(void *dmg, u16 address);
|
||||
void dmg_write(void *dmg, u16 address, u8 data);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "dmg.h"
|
||||
#include "cpu.h"
|
||||
#include "rom.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct cpu cpu;
|
||||
struct rom rom;
|
||||
struct dmg dmg;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("no rom specified\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!rom_load(&rom, argv[1])) {
|
||||
printf("error loading rom\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// this might be too much abstraction but it'll let me
|
||||
// test the cpu, rom, and dmg independently and use the cpu
|
||||
// for other non-GB stuff
|
||||
dmg_new(&dmg, &cpu, &rom);
|
||||
cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
|
||||
|
||||
cpu.pc = 0x100;
|
||||
|
||||
while (1) {
|
||||
cpu_step(&cpu);
|
||||
}
|
||||
|
||||
rom_free(&rom);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "rom.h"
|
||||
#include "types.h"
|
||||
|
||||
int rom_load(struct rom *rom, const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
int len;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
len = ftell(fp);
|
||||
rewind(fp);
|
||||
|
||||
rom->type = 0; // TODO read type from cart
|
||||
rom->data = malloc(len);
|
||||
if (fread(rom->data, 1, len, fp) < len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rom_free(struct rom *rom)
|
||||
{
|
||||
free(rom->data);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _ROM_H
|
||||
#define _ROM_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct rom {
|
||||
int type;
|
||||
u8 *data;
|
||||
};
|
||||
|
||||
|
||||
int rom_load(struct rom *rom, const char *filename);
|
||||
|
||||
void rom_free(struct rom *rom);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _TYPES_H
|
||||
#define _TYPES_H
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue