mirror of
https://github.com/mlaux/gb6.git
synced 2024-09-28 16:54:24 +00:00
Compare commits
No commits in common. "b0147a60d4cd354288160df99496a45fc8f597d7" and "4cde94d2847715b8b630d695f826679eb76882fa" have entirely different histories.
b0147a60d4
...
4cde94d284
@ -26,9 +26,11 @@ int emulator_main(int argc, char *argv[])
|
|||||||
|
|
||||||
lcd_new(&lcd);
|
lcd_new(&lcd);
|
||||||
|
|
||||||
|
// 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, &lcd);
|
dmg_new(&dmg, &cpu, &rom, &lcd);
|
||||||
cpu.dmg = &dmg;
|
cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
|
||||||
// cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
|
|
||||||
|
|
||||||
cpu.pc = 0x100;
|
cpu.pc = 0x100;
|
||||||
|
|
||||||
|
@ -152,9 +152,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
lcd_new(&lcd);
|
lcd_new(&lcd);
|
||||||
|
|
||||||
|
// 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, &lcd);
|
dmg_new(&dmg, &cpu, &rom, &lcd);
|
||||||
cpu.dmg = &dmg;
|
cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
|
||||||
// cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
|
|
||||||
|
|
||||||
cpu.pc = 0x100;
|
cpu.pc = 0x100;
|
||||||
|
|
||||||
|
44
src/cpu.c
44
src/cpu.c
@ -2,10 +2,20 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "dmg.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "instructions.h"
|
#include "instructions.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;
|
||||||
|
}
|
||||||
|
|
||||||
int flag_isset(struct cpu *cpu, int flag)
|
int flag_isset(struct cpu *cpu, int flag)
|
||||||
{
|
{
|
||||||
return (cpu->f & flag) != 0;
|
return (cpu->f & flag) != 0;
|
||||||
@ -56,7 +66,7 @@ void cpu_panic(struct cpu *cpu)
|
|||||||
|
|
||||||
static inline u8 read8(struct cpu *cpu, u16 address)
|
static inline u8 read8(struct cpu *cpu, u16 address)
|
||||||
{
|
{
|
||||||
return dmg_read(cpu->dmg, address);
|
return cpu->mem_read(cpu->mem_model, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u16 read16(struct cpu *cpu, u16 address)
|
static inline u16 read16(struct cpu *cpu, u16 address)
|
||||||
@ -68,12 +78,12 @@ static inline u16 read16(struct cpu *cpu, u16 address)
|
|||||||
|
|
||||||
static inline void write8(struct cpu *cpu, u16 address, u8 data)
|
static inline void write8(struct cpu *cpu, u16 address, u8 data)
|
||||||
{
|
{
|
||||||
dmg_write(cpu->dmg, address, data);
|
cpu->mem_write(cpu->mem_model, address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void write16(struct cpu *cpu, u16 address, u16 data)
|
static inline void write16(struct cpu *cpu, u16 address, u16 data)
|
||||||
{
|
{
|
||||||
dmg_write(cpu->dmg, address, data);
|
cpu->mem_write(cpu->mem_model, address, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inc_with_carry(struct cpu *regs, u8 *reg)
|
static void inc_with_carry(struct cpu *regs, u8 *reg)
|
||||||
@ -483,15 +493,15 @@ static u16 check_interrupts(struct cpu *cpu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 enabled = dmg_read(cpu->dmg, 0xffff);
|
u16 enabled = cpu->mem_read(cpu->mem_model, 0xffff);
|
||||||
u16 requested = dmg_read(cpu->dmg, 0xff0f);
|
u16 requested = cpu->mem_read(cpu->mem_model, 0xff0f);
|
||||||
|
|
||||||
for (k = 0; k < NUM_INTERRUPTS; k++) {
|
for (k = 0; k < NUM_INTERRUPTS; k++) {
|
||||||
int check = 1 << k;
|
int check = 1 << k;
|
||||||
if ((enabled & check) && (requested & check)) {
|
if ((enabled & check) && (requested & check)) {
|
||||||
// clear request flag for this interrupt and disable all further
|
// clear request flag for this interrupt and disable all further
|
||||||
// interrupts until service routine executes EI or RETI
|
// interrupts until service routine executes EI or RETI
|
||||||
dmg_write(cpu->dmg, 0xff0f, requested & ~check);
|
cpu->mem_write(cpu->mem_model, 0xff0f, requested & ~check);
|
||||||
cpu->interrupt_enable = 0;
|
cpu->interrupt_enable = 0;
|
||||||
return handlers[k];
|
return handlers[k];
|
||||||
}
|
}
|
||||||
@ -512,7 +522,7 @@ void cpu_step(struct cpu *cpu)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 opc = dmg_read(cpu->dmg, cpu->pc);
|
u8 opc = cpu->mem_read(cpu->mem_model, cpu->pc);
|
||||||
#ifdef GB6_DEBUG
|
#ifdef GB6_DEBUG
|
||||||
printf("0x%04x %s\n", cpu->pc, instructions[opc].format);
|
printf("0x%04x %s\n", cpu->pc, instructions[opc].format);
|
||||||
#endif
|
#endif
|
||||||
@ -782,24 +792,6 @@ void cpu_step(struct cpu *cpu)
|
|||||||
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xd4: // CALL NC, u16
|
|
||||||
temp16 = read16(cpu, cpu->pc);
|
|
||||||
cpu->pc += 2;
|
|
||||||
if (!flag_isset(cpu, FLAG_CARRY)) {
|
|
||||||
push(cpu, cpu->pc);
|
|
||||||
cpu->pc = temp16;
|
|
||||||
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0xdc: // CALL C, u16
|
|
||||||
temp16 = read16(cpu, cpu->pc);
|
|
||||||
cpu->pc += 2;
|
|
||||||
if (flag_isset(cpu, FLAG_CARRY)) {
|
|
||||||
push(cpu, cpu->pc);
|
|
||||||
cpu->pc = temp16;
|
|
||||||
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0xd0: // RET NC
|
case 0xd0: // RET NC
|
||||||
if (!flag_isset(cpu, FLAG_CARRY)) {
|
if (!flag_isset(cpu, FLAG_CARRY)) {
|
||||||
cpu->pc = pop(cpu);
|
cpu->pc = pop(cpu);
|
||||||
|
21
src/cpu.h
21
src/cpu.h
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
struct dmg;
|
|
||||||
|
|
||||||
struct cpu
|
struct cpu
|
||||||
{
|
{
|
||||||
u8 a;
|
u8 a;
|
||||||
@ -20,18 +18,17 @@ struct cpu
|
|||||||
u32 cycle_count;
|
u32 cycle_count;
|
||||||
u8 interrupt_enable;
|
u8 interrupt_enable;
|
||||||
|
|
||||||
struct dmg *dmg;
|
u8 (*mem_read)(void *, u16);
|
||||||
// u8 (*mem_read)(void *, u16);
|
void (*mem_write)(void *, u16, u8);
|
||||||
// void (*mem_write)(void *, u16, u8);
|
void *mem_model;
|
||||||
// void *mem_model;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// void cpu_bind_mem_model(
|
void cpu_bind_mem_model(
|
||||||
// struct cpu *cpu,
|
struct cpu *cpu,
|
||||||
// void *mem_model,
|
void *mem_model,
|
||||||
// u8 (*mem_read)(void *, u16),
|
u8 (*mem_read)(void *, u16),
|
||||||
// void (*mem_write)(void *, u16, u8)
|
void (*mem_write)(void *, u16, u8)
|
||||||
// );
|
);
|
||||||
|
|
||||||
void cpu_step(struct cpu *cpu);
|
void cpu_step(struct cpu *cpu);
|
||||||
int flag_isset(struct cpu *cpu, int flag);
|
int flag_isset(struct cpu *cpu, int flag);
|
||||||
|
32
src/dmg.c
32
src/dmg.c
@ -188,18 +188,16 @@ struct oam_entry {
|
|||||||
u8 attrs;
|
u8 attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: only ten per scanline, priority, attributes, move to lcd.c
|
// TODO: only ten per scanline, priority
|
||||||
static void render_objs(struct dmg *dmg)
|
static void render_objs(struct dmg *dmg)
|
||||||
{
|
{
|
||||||
struct oam_entry *oam = (struct oam_entry *) dmg->lcd->oam;
|
struct oam_entry *oam = (struct oam_entry *) dmg->lcd->oam;
|
||||||
int k, lcd_x, lcd_y, off;
|
int k, lcd_x, lcd_y, off;
|
||||||
int tall = lcd_isset(dmg->lcd, REG_LCDC, LCDC_OBJ_SIZE);
|
|
||||||
|
|
||||||
for (k = 0; k < 40; k++, oam++) {
|
for (k = 0; k < 40; k++, oam++) {
|
||||||
if (oam->pos_y == 0 || oam->pos_y >= 160) {
|
if (oam->pos_y == 0 || oam->pos_y >= 160) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (oam->pos_x == 0 || oam->pos_x >= 168) {
|
if (oam->pos_x == 0 || oam->pos_y >= 168) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,31 +206,17 @@ static void render_objs(struct dmg *dmg)
|
|||||||
|
|
||||||
off = 160 * lcd_y + lcd_x;
|
off = 160 * lcd_y + lcd_x;
|
||||||
int eff_addr = 0x8000 + 16 * oam->tile;
|
int eff_addr = 0x8000 + 16 * oam->tile;
|
||||||
int b, i, limit = 16;
|
int b, i;
|
||||||
if (tall) {
|
for (b = 0; b < 16; b += 2) {
|
||||||
limit = 32;
|
int data1 = dmg_read(dmg, eff_addr + b);
|
||||||
}
|
int data2 = dmg_read(dmg, eff_addr + b + 1);
|
||||||
for (b = 0; b < limit; b += 2) {
|
|
||||||
int use_tile = b;
|
|
||||||
if (oam->attrs & OAM_ATTR_MIRROR_Y) {
|
|
||||||
use_tile = (limit - 2) - b;
|
|
||||||
}
|
|
||||||
int data1 = dmg_read(dmg, eff_addr + use_tile);
|
|
||||||
int data2 = dmg_read(dmg, eff_addr + use_tile + 1);
|
|
||||||
for (i = 7; i >= 0; i--) {
|
for (i = 7; i >= 0; i--) {
|
||||||
if (off < 0 || off >= 160 * 144) {
|
if (off < 0 || off >= 160 * 144) {
|
||||||
// terrible clipping. need to not have an if per-pixel
|
// terrible clipping. need to not have an if per-pixel
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int use_index = i;
|
dmg->lcd->pixels[off] = ((data1 & (1 << i)) ? 1 : 0) << 1;
|
||||||
if (oam->attrs & OAM_ATTR_MIRROR_X) {
|
dmg->lcd->pixels[off] |= (data2 & (1 << i)) ? 1 : 0;
|
||||||
use_index = 7 - i;
|
|
||||||
}
|
|
||||||
int color = ((data1 & (1 << use_index)) ? 1 : 0) << 1
|
|
||||||
| ((data2 & (1 << use_index)) ? 1 : 0);
|
|
||||||
if (color) {
|
|
||||||
dmg->lcd->pixels[off] = color;
|
|
||||||
}
|
|
||||||
off++;
|
off++;
|
||||||
}
|
}
|
||||||
off += 152;
|
off += 152;
|
||||||
|
@ -7,18 +7,18 @@
|
|||||||
|
|
||||||
void lcd_set_bit(struct lcd *lcd, u16 addr, u8 bit)
|
void lcd_set_bit(struct lcd *lcd, u16 addr, u8 bit)
|
||||||
{
|
{
|
||||||
lcd_write(lcd, addr, lcd_read(lcd, addr) | bit);
|
lcd_write(lcd, addr, lcd_read(lcd, addr) | (1 << bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_clear_bit(struct lcd *lcd, u16 addr, u8 bit)
|
void lcd_clear_bit(struct lcd *lcd, u16 addr, u8 bit)
|
||||||
{
|
{
|
||||||
lcd_write(lcd, addr, lcd_read(lcd, addr) & ~bit);
|
lcd_write(lcd, addr, lcd_read(lcd, addr) & ~(1 << bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
int lcd_isset(struct lcd *lcd, u16 addr, u8 bit)
|
int lcd_isset(struct lcd *lcd, u16 addr, u8 bit)
|
||||||
{
|
{
|
||||||
u8 val = lcd_read(lcd, addr);
|
u8 val = lcd_read(lcd, addr);
|
||||||
return val & bit;
|
return val & (1 << bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lcd_set_mode(struct lcd *lcd, int mode)
|
void lcd_set_mode(struct lcd *lcd, int mode)
|
||||||
|
15
src/lcd.h
15
src/lcd.h
@ -23,11 +23,11 @@
|
|||||||
|
|
||||||
#define REG_LCD_LAST REG_WX
|
#define REG_LCD_LAST REG_WX
|
||||||
|
|
||||||
#define STAT_FLAG_MATCH (1 << 2)
|
#define STAT_FLAG_MATCH 2
|
||||||
#define STAT_INTR_SOURCE_HBLANK (1 << 3)
|
#define STAT_INTR_SOURCE_HBLANK 3
|
||||||
#define STAT_INTR_SOURCE_VBLANK (1 << 4)
|
#define STAT_INTR_SOURCE_VBLANK 4
|
||||||
#define STAT_INTR_SOURCE_MODE2 (1 << 5)
|
#define STAT_INTR_SOURCE_MODE2 5
|
||||||
#define STAT_INTR_SOURCE_MATCH (1 << 6)
|
#define STAT_INTR_SOURCE_MATCH 6
|
||||||
|
|
||||||
|
|
||||||
#define LCDC_ENABLE_BG (1 << 0)
|
#define LCDC_ENABLE_BG (1 << 0)
|
||||||
@ -39,11 +39,6 @@
|
|||||||
#define LCDC_WINDOW_TILE_MAP (1 << 6)
|
#define LCDC_WINDOW_TILE_MAP (1 << 6)
|
||||||
#define LCDC_ENABLE (1 << 7)
|
#define LCDC_ENABLE (1 << 7)
|
||||||
|
|
||||||
#define OAM_ATTR_PALETTE (1 << 4)
|
|
||||||
#define OAM_ATTR_MIRROR_X (1 << 5)
|
|
||||||
#define OAM_ATTR_MIRROR_Y (1 << 6)
|
|
||||||
#define OAM_ATTR_BEHIND_BG (1 << 7)
|
|
||||||
|
|
||||||
struct lcd {
|
struct lcd {
|
||||||
u8 oam[0xa0];
|
u8 oam[0xa0];
|
||||||
u8 regs[0x0c];
|
u8 regs[0x0c];
|
||||||
|
44
src/mbc.c
44
src/mbc.c
@ -6,6 +6,16 @@
|
|||||||
#include "dmg.h"
|
#include "dmg.h"
|
||||||
#include "rom.h"
|
#include "rom.h"
|
||||||
|
|
||||||
|
static int mbc_noop_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mbc_noop_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mbc1_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data)
|
static int mbc1_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data)
|
||||||
{
|
{
|
||||||
if (addr >= 0x4000 && addr <= 0x7fff) {
|
if (addr >= 0x4000 && addr <= 0x7fff) {
|
||||||
@ -50,29 +60,35 @@ static int mbc1_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mbc mbc_noop = {
|
||||||
|
mbc_noop_read,
|
||||||
|
mbc_noop_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mbc mbc1 = {
|
||||||
|
mbc1_read,
|
||||||
|
mbc1_write,
|
||||||
|
};
|
||||||
|
|
||||||
struct mbc *mbc_new(int type)
|
struct mbc *mbc_new(int type)
|
||||||
{
|
{
|
||||||
static struct mbc mbc;
|
switch (type) {
|
||||||
if (type > 3) {
|
case 0:
|
||||||
return NULL;
|
return &mbc_noop;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
return &mbc1;
|
||||||
}
|
}
|
||||||
mbc.type = type;
|
return NULL;
|
||||||
|
|
||||||
return &mbc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbc_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data)
|
int mbc_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data)
|
||||||
{
|
{
|
||||||
if (mbc->type == 0) {
|
return mbc->read_fn(mbc, dmg, addr, out_data);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return mbc1_read(mbc, dmg, addr, out_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mbc_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data)
|
int mbc_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data)
|
||||||
{
|
{
|
||||||
if (mbc->type == 0) {
|
return mbc->write_fn(mbc, dmg, addr, data);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return mbc1_write(mbc, dmg, addr, data);
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
struct dmg;
|
struct dmg;
|
||||||
|
|
||||||
struct mbc {
|
struct mbc {
|
||||||
|
int (*read_fn)(struct mbc *, struct dmg *, u16, u8 *);
|
||||||
|
int (*write_fn)(struct mbc *, struct dmg *, u16, u8);
|
||||||
int type;
|
int type;
|
||||||
int rom_bank;
|
int rom_bank;
|
||||||
int ram_bank;
|
int ram_bank;
|
||||||
@ -14,10 +16,7 @@ struct mbc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mbc *mbc_new(int type);
|
struct mbc *mbc_new(int type);
|
||||||
|
|
||||||
// set *out_data and return 1 if handled, return 0 for base dmg behavior
|
|
||||||
int mbc_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data);
|
int mbc_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data);
|
||||||
// return 1 if handled, return 0 for base dmg behavior
|
|
||||||
int mbc_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data);
|
int mbc_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.9)
|
|||||||
|
|
||||||
include_directories(../src)
|
include_directories(../src)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "-O3")
|
set(CMAKE_CXX_FLAGS "-O3")
|
||||||
|
|
||||||
add_application(Emulator
|
add_application(Emulator
|
||||||
../src/bootstrap.c
|
../src/bootstrap.c
|
||||||
|
@ -59,18 +59,18 @@ Rect offscreenRect = { 0, 0, 144, 160 };
|
|||||||
|
|
||||||
BitMap offscreenBmp;
|
BitMap offscreenBmp;
|
||||||
|
|
||||||
int execTime;
|
int lastTicks;
|
||||||
|
|
||||||
void Render(void)
|
void Render(void)
|
||||||
{
|
{
|
||||||
// long k = 0, dst, bit;
|
long k = 0, dst, bit;
|
||||||
// for (dst = 0; dst < 20 * 144; dst++) {
|
for (dst = 0; dst < 20 * 144; dst++) {
|
||||||
// for (bit = 7; bit >= 0; bit--) {
|
for (bit = 7; bit >= 0; bit--) {
|
||||||
// offscreen[dst] |= lcd.pixels[k++];
|
offscreen[dst] |= lcd.pixels[k++];
|
||||||
// offscreen[dst] <<= 1;
|
offscreen[dst] <<= 1;
|
||||||
// }
|
}
|
||||||
// dst++;
|
dst++;
|
||||||
// }
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
offscreen[dst] = lcd.pixels[k++] << 7;
|
offscreen[dst] = lcd.pixels[k++] << 7;
|
||||||
@ -83,32 +83,16 @@ void Render(void)
|
|||||||
offscreen[dst] |= lcd.pixels[k++];
|
offscreen[dst] |= lcd.pixels[k++];
|
||||||
*/
|
*/
|
||||||
SetPort(g_wp);
|
SetPort(g_wp);
|
||||||
// CopyBits(&offscreenBmp, &g_wp->portBits, &offscreenRect, &offscreenRect, srcCopy, NULL);
|
CopyBits(&offscreenBmp, &g_wp->portBits, &offscreenRect, &offscreenRect, srcCopy, NULL);
|
||||||
|
|
||||||
EraseRect(&g_wp->portRect);
|
//EraseRect(&g_wp->portRect);
|
||||||
MoveTo(10, 180);
|
// MoveTo(10, 160);
|
||||||
char debug[128];
|
// char debug[128];
|
||||||
double ms = execTime / 600.0;
|
// sprintf(debug, "PC: %04x", cpu.pc);
|
||||||
sprintf(debug, "10000 in %d ticks, %.2f ms per instruction", execTime, ms);
|
// C2PStr(debug);
|
||||||
C2PStr(debug);
|
// DrawString(debug);
|
||||||
DrawString(debug);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 417 ticks
|
|
||||||
// 10000 instructions
|
|
||||||
|
|
||||||
// 0.0417 tick per instruction
|
|
||||||
// 1/60 second per tick
|
|
||||||
// 0.000695 second per instruction
|
|
||||||
// 0.695 ms per instruction
|
|
||||||
|
|
||||||
// REAL GB:
|
|
||||||
// 4194304 Hz
|
|
||||||
// 1048576 NOPs per second
|
|
||||||
// 174763 CALL 16s per second
|
|
||||||
// 0.001 ms per NOP
|
|
||||||
// 0.006 ms per CALL 16
|
|
||||||
|
|
||||||
void StartEmulation(void)
|
void StartEmulation(void)
|
||||||
{
|
{
|
||||||
g_wp = NewWindow(0, &windowBounds, WINDOW_TITLE, true,
|
g_wp = NewWindow(0, &windowBounds, WINDOW_TITLE, true,
|
||||||
@ -204,7 +188,7 @@ void ShowAboutBox(void)
|
|||||||
// DrawDialog(dp);
|
// DrawDialog(dp);
|
||||||
// while(!GetNextEvent(mDownMask, &e));
|
// while(!GetNextEvent(mDownMask, &e));
|
||||||
// while(WaitMouseUp());
|
// while(WaitMouseUp());
|
||||||
|
|
||||||
DisposeDialog(dp);
|
DisposeDialog(dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,26 +264,25 @@ int main(int argc, char *argv[])
|
|||||||
int executed;
|
int executed;
|
||||||
int paused = 0;
|
int paused = 0;
|
||||||
int pause_next = 0;
|
int pause_next = 0;
|
||||||
|
|
||||||
InitEverything();
|
InitEverything();
|
||||||
|
|
||||||
lcd_new(&lcd);
|
lcd_new(&lcd);
|
||||||
dmg_new(&dmg, &cpu, &rom, &lcd);
|
dmg_new(&dmg, &cpu, &rom, &lcd);
|
||||||
cpu.dmg = &dmg;
|
cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
|
||||||
// cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
|
|
||||||
|
|
||||||
cpu.pc = 0x100;
|
cpu.pc = 0x100;
|
||||||
|
|
||||||
|
int start = TickCount();
|
||||||
while(g_running) {
|
while(g_running) {
|
||||||
if (emulationOn) {
|
if (emulationOn) {
|
||||||
int k;
|
|
||||||
int start = TickCount();
|
|
||||||
for (k = 0; k < 10000; k++) {
|
|
||||||
dmg_step(&dmg);
|
dmg_step(&dmg);
|
||||||
}
|
int now = TickCount();
|
||||||
execTime = TickCount() - start;
|
if (now > lastTicks + 100) {
|
||||||
emulationOn = false;
|
lastTicks = now;
|
||||||
Render();
|
Render();
|
||||||
|
}
|
||||||
|
if (Button()) g_running = false;
|
||||||
} else {
|
} else {
|
||||||
if(WaitNextEvent(everyEvent, &evt, 0, 0) != nullEvent) {
|
if(WaitNextEvent(everyEvent, &evt, 0, 0) != nullEvent) {
|
||||||
if (IsDialogEvent(&evt)) {
|
if (IsDialogEvent(&evt)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user