mirror of
https://github.com/mlaux/gb6.git
synced 2024-09-28 01:54:29 +00:00
Compare commits
4 Commits
0351226479
...
580c349fc7
Author | SHA1 | Date | |
---|---|---|---|
|
580c349fc7 | ||
|
6ab729f377 | ||
|
bbb398f524 | ||
|
bc980ec1e5 |
@ -27,7 +27,6 @@ static const char *PC_FORMAT = "PC: 0x%02x";
|
|||||||
|
|
||||||
unsigned char output_image[256 * 256 * 4];
|
unsigned char output_image[256 * 256 * 4];
|
||||||
unsigned char vram_tiles[256 * 96 * 4];
|
unsigned char vram_tiles[256 * 96 * 4];
|
||||||
unsigned char full_address_space[0x10000];
|
|
||||||
|
|
||||||
struct key_input {
|
struct key_input {
|
||||||
int scancode;
|
int scancode;
|
||||||
@ -60,13 +59,15 @@ GLuint make_output_texture() {
|
|||||||
return image_texture;
|
return image_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char default_palette[] = { 0, 0x55, 0xaa, 0xff };
|
||||||
|
|
||||||
void convert_output(struct lcd *lcd) {
|
void convert_output(struct lcd *lcd) {
|
||||||
int x, y;
|
int x, y;
|
||||||
int out_index = 0;
|
int out_index = 0;
|
||||||
for (y = 0; y < 256; y++) {
|
for (y = 0; y < 256; y++) {
|
||||||
for (x = 0; x < 256; x++) {
|
for (x = 0; x < 256; x++) {
|
||||||
int val = lcd->buf[y * 256 + x];
|
int val = lcd->buf[y * 256 + x];
|
||||||
int fill = 255 - val * 85;
|
int fill = default_palette[val];
|
||||||
//int fill = val ? 255 : 0;
|
//int fill = val ? 255 : 0;
|
||||||
output_image[out_index++] = fill;
|
output_image[out_index++] = fill;
|
||||||
output_image[out_index++] = fill;
|
output_image[out_index++] = fill;
|
||||||
@ -103,12 +104,14 @@ void convert_vram(struct dmg *dmg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_memory_editor(struct dmg *dmg)
|
static ImU8 read_mem(const ImU8* data, size_t off)
|
||||||
{
|
{
|
||||||
int k;
|
return dmg_read((void *) data, (u16) off);
|
||||||
for (k = 0; k < 0x10000; k++) {
|
}
|
||||||
full_address_space[k] = dmg_read(dmg, k);
|
|
||||||
}
|
static void write_mem(ImU8 *data, size_t off, ImU8 d)
|
||||||
|
{
|
||||||
|
dmg_write(data, (u16) off, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main code
|
// Main code
|
||||||
@ -193,6 +196,9 @@ int main(int argc, char *argv[])
|
|||||||
GLuint texture = make_output_texture();
|
GLuint texture = make_output_texture();
|
||||||
GLuint vram_texture = make_output_texture();
|
GLuint vram_texture = make_output_texture();
|
||||||
|
|
||||||
|
editor.ReadFn = read_mem;
|
||||||
|
editor.WriteFn = write_mem;
|
||||||
|
|
||||||
// for flag checkboxes
|
// for flag checkboxes
|
||||||
bool z_flag = false;
|
bool z_flag = false;
|
||||||
bool n_flag = false;
|
bool n_flag = false;
|
||||||
@ -318,10 +324,7 @@ int main(int argc, char *argv[])
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_memory_editor(&dmg);
|
editor.DrawWindow("Memory", &dmg, 0x10000, 0x0000);
|
||||||
|
|
||||||
editor.DrawWindow("Memory", full_address_space, 0x10000, 0x0000);
|
|
||||||
editor.DrawWindow("ROM", dmg.rom->data, 0x8000, 0);
|
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
110
src/cpu.c
110
src/cpu.c
@ -164,11 +164,55 @@ static u8 rrc(struct cpu *cpu, u8 val)
|
|||||||
|
|
||||||
static u8 shift_left(struct cpu *cpu, u8 value)
|
static u8 shift_left(struct cpu *cpu, u8 value)
|
||||||
{
|
{
|
||||||
return 0;
|
int result = value << 1;
|
||||||
|
if (result == 0) {
|
||||||
|
set_flag(cpu, FLAG_ZERO);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_ZERO);
|
||||||
|
}
|
||||||
|
if (value & 0x80) {
|
||||||
|
set_flag(cpu, FLAG_CARRY);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_CARRY);
|
||||||
|
}
|
||||||
|
clear_flag(cpu, FLAG_SIGN);
|
||||||
|
clear_flag(cpu, FLAG_HALF_CARRY);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 shift_right(struct cpu *cpu, u8 value)
|
static u8 shift_right(struct cpu *cpu, u8 value)
|
||||||
{
|
{
|
||||||
|
int result = (signed) value >> 1;
|
||||||
|
if (result == 0) {
|
||||||
|
set_flag(cpu, FLAG_ZERO);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_ZERO);
|
||||||
|
}
|
||||||
|
if (value & 0x1) {
|
||||||
|
set_flag(cpu, FLAG_CARRY);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_CARRY);
|
||||||
|
}
|
||||||
|
clear_flag(cpu, FLAG_SIGN);
|
||||||
|
clear_flag(cpu, FLAG_HALF_CARRY);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 srl(struct cpu *cpu, u8 value)
|
||||||
|
{
|
||||||
|
int result = value >> 1;
|
||||||
|
if (result == 0) {
|
||||||
|
set_flag(cpu, FLAG_ZERO);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_ZERO);
|
||||||
|
}
|
||||||
|
if (value & 0x1) {
|
||||||
|
set_flag(cpu, FLAG_CARRY);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_CARRY);
|
||||||
|
}
|
||||||
|
clear_flag(cpu, FLAG_SIGN);
|
||||||
|
clear_flag(cpu, FLAG_HALF_CARRY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +412,7 @@ static void extended_insn(struct cpu *cpu, u8 insn)
|
|||||||
shift_left,
|
shift_left,
|
||||||
shift_right,
|
shift_right,
|
||||||
swap,
|
swap,
|
||||||
shift_right // TODO SRL
|
srl,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GB6_DEBUG
|
#ifdef GB6_DEBUG
|
||||||
@ -462,6 +506,9 @@ void cpu_step(struct cpu *cpu)
|
|||||||
write_bc(cpu, read16(cpu, cpu->pc));
|
write_bc(cpu, read16(cpu, cpu->pc));
|
||||||
cpu->pc += 2;
|
cpu->pc += 2;
|
||||||
break;
|
break;
|
||||||
|
case 0x02: // LD (BC), A
|
||||||
|
write8(cpu, read_bc(cpu), cpu->a);
|
||||||
|
break;
|
||||||
case 0x0f: // RRCA
|
case 0x0f: // RRCA
|
||||||
cpu->a = rrc(cpu, cpu->a);
|
cpu->a = rrc(cpu, cpu->a);
|
||||||
break;
|
break;
|
||||||
@ -515,8 +562,8 @@ void cpu_step(struct cpu *cpu)
|
|||||||
case 0x2d: dec_with_carry(cpu, &cpu->l); break;
|
case 0x2d: dec_with_carry(cpu, &cpu->l); break;
|
||||||
|
|
||||||
case 0x33: cpu->sp++; break;
|
case 0x33: cpu->sp++; break;
|
||||||
case 0x34: temp = read8(cpu, read_hl(cpu)); inc_with_carry(cpu, &temp); break;
|
case 0x34: temp = read8(cpu, read_hl(cpu)); inc_with_carry(cpu, &temp); write8(cpu, read_hl(cpu), temp); break;
|
||||||
case 0x35: temp = read8(cpu, read_hl(cpu)); dec_with_carry(cpu, &temp); break;
|
case 0x35: temp = read8(cpu, read_hl(cpu)); dec_with_carry(cpu, &temp); write8(cpu, read_hl(cpu), temp); break;
|
||||||
|
|
||||||
case 0x3b: cpu->sp--; break;
|
case 0x3b: cpu->sp--; break;
|
||||||
case 0x3c: inc_with_carry(cpu, &cpu->a); break;
|
case 0x3c: inc_with_carry(cpu, &cpu->a); break;
|
||||||
@ -593,7 +640,7 @@ void cpu_step(struct cpu *cpu)
|
|||||||
case 0x6e: cpu->l = read8(cpu, read_hl(cpu)); break;
|
case 0x6e: cpu->l = read8(cpu, read_hl(cpu)); break;
|
||||||
case 0x6f: cpu->l = cpu->a; break;
|
case 0x6f: cpu->l = cpu->a; break;
|
||||||
|
|
||||||
// dest = *HL
|
// dest is *HL
|
||||||
case 0x70: write8(cpu, read_hl(cpu), cpu->b); break;
|
case 0x70: write8(cpu, read_hl(cpu), cpu->b); break;
|
||||||
case 0x71: write8(cpu, read_hl(cpu), cpu->c); break;
|
case 0x71: write8(cpu, read_hl(cpu), cpu->c); break;
|
||||||
case 0x72: write8(cpu, read_hl(cpu), cpu->d); break;
|
case 0x72: write8(cpu, read_hl(cpu), cpu->d); break;
|
||||||
@ -658,6 +705,9 @@ void cpu_step(struct cpu *cpu)
|
|||||||
write8(cpu, read_hl(cpu), cpu->a);
|
write8(cpu, read_hl(cpu), cpu->a);
|
||||||
write_hl(cpu, read_hl(cpu) - 1);
|
write_hl(cpu, read_hl(cpu) - 1);
|
||||||
break;
|
break;
|
||||||
|
case 0x39: // ADD HL, SP
|
||||||
|
add16(cpu, cpu->sp);
|
||||||
|
break;
|
||||||
case 0xc0: // RET NZ
|
case 0xc0: // RET NZ
|
||||||
if (!flag_isset(cpu, FLAG_ZERO)) {
|
if (!flag_isset(cpu, FLAG_ZERO)) {
|
||||||
cpu->pc = pop(cpu);
|
cpu->pc = pop(cpu);
|
||||||
@ -684,6 +734,30 @@ void cpu_step(struct cpu *cpu)
|
|||||||
case 0xc3: // JP a16
|
case 0xc3: // JP a16
|
||||||
cpu->pc = read16(cpu, cpu->pc);
|
cpu->pc = read16(cpu, cpu->pc);
|
||||||
break;
|
break;
|
||||||
|
case 0xc4: // CALL NZ, u16
|
||||||
|
temp16 = read16(cpu, cpu->pc);
|
||||||
|
cpu->pc += 2;
|
||||||
|
if (!flag_isset(cpu, FLAG_ZERO)) {
|
||||||
|
push(cpu, cpu->pc);
|
||||||
|
cpu->pc = temp16;
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xcc: // CALL Z, u16
|
||||||
|
temp16 = read16(cpu, cpu->pc);
|
||||||
|
cpu->pc += 2;
|
||||||
|
if (flag_isset(cpu, FLAG_ZERO)) {
|
||||||
|
push(cpu, cpu->pc);
|
||||||
|
cpu->pc = temp16;
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xd0: // RET NC
|
||||||
|
if (!flag_isset(cpu, FLAG_CARRY)) {
|
||||||
|
cpu->pc = pop(cpu);
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0xd2: // JP NC,a16
|
case 0xd2: // JP NC,a16
|
||||||
temp16 = read16(cpu, cpu->pc);
|
temp16 = read16(cpu, cpu->pc);
|
||||||
cpu->pc += 2;
|
cpu->pc += 2;
|
||||||
@ -692,6 +766,12 @@ 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 0xd8: // RET C
|
||||||
|
if (flag_isset(cpu, FLAG_CARRY)) {
|
||||||
|
cpu->pc = pop(cpu);
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x80: add(cpu, cpu->b, 0); break;
|
case 0x80: add(cpu, cpu->b, 0); break;
|
||||||
case 0x81: add(cpu, cpu->c, 0); break;
|
case 0x81: add(cpu, cpu->c, 0); break;
|
||||||
@ -736,6 +816,16 @@ void cpu_step(struct cpu *cpu)
|
|||||||
case 0x9e: subtract(cpu, read8(cpu, read_hl(cpu)), 1, 0); break;
|
case 0x9e: subtract(cpu, read8(cpu, read_hl(cpu)), 1, 0); break;
|
||||||
case 0x9f: subtract(cpu, cpu->a, 1, 0); break;
|
case 0x9f: subtract(cpu, cpu->a, 1, 0); break;
|
||||||
|
|
||||||
|
case 0xd6: // SUB A, u8
|
||||||
|
subtract(cpu, read8(cpu, cpu->pc), 0, 0);
|
||||||
|
cpu->pc++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xde: // SBC A, u8
|
||||||
|
subtract(cpu, read8(cpu, cpu->pc), 0, 1);
|
||||||
|
cpu->pc++;
|
||||||
|
break;
|
||||||
|
|
||||||
// AND
|
// AND
|
||||||
case 0xa0: and(cpu, cpu->b); break;
|
case 0xa0: and(cpu, cpu->b); break;
|
||||||
case 0xa1: and(cpu, cpu->c); break;
|
case 0xa1: and(cpu, cpu->c); break;
|
||||||
@ -793,6 +883,9 @@ void cpu_step(struct cpu *cpu)
|
|||||||
case 0xf7: push(cpu, cpu->pc); cpu->pc = 0x30; break;
|
case 0xf7: push(cpu, cpu->pc); cpu->pc = 0x30; break;
|
||||||
case 0xff: push(cpu, cpu->pc); cpu->pc = 0x38; break;
|
case 0xff: push(cpu, cpu->pc); cpu->pc = 0x38; break;
|
||||||
|
|
||||||
|
case 0x27: // DAA
|
||||||
|
break;
|
||||||
|
|
||||||
case 0x76: // HALT
|
case 0x76: // HALT
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -866,6 +959,13 @@ void cpu_step(struct cpu *cpu)
|
|||||||
case 0xf5: // PUSH AF
|
case 0xf5: // PUSH AF
|
||||||
push(cpu, read_af(cpu));
|
push(cpu, read_af(cpu));
|
||||||
break;
|
break;
|
||||||
|
case 0xf8: // LD HL, SP+i8
|
||||||
|
write_hl(cpu, cpu->sp + (signed) read8(cpu, cpu->pc));
|
||||||
|
cpu->pc++;
|
||||||
|
break;
|
||||||
|
case 0xf9: // LD SP, HL
|
||||||
|
cpu->sp = read_hl(cpu);
|
||||||
|
break;
|
||||||
case 0xfa: // LD A,(u16)
|
case 0xfa: // LD A,(u16)
|
||||||
cpu->a = read8(cpu, read16(cpu, cpu->pc));
|
cpu->a = read8(cpu, read16(cpu, cpu->pc));
|
||||||
cpu->pc += 2;
|
cpu->pc += 2;
|
||||||
|
41
src/dmg.c
41
src/dmg.c
@ -86,7 +86,7 @@ u8 dmg_read(void *_dmg, u16 address)
|
|||||||
// not sure about any of this yet
|
// not sure about any of this yet
|
||||||
// commented out bc of memory view window
|
// commented out bc of memory view window
|
||||||
// fprintf(stderr, "don't know how to read 0x%04x\n", address);
|
// fprintf(stderr, "don't know how to read 0x%04x\n", address);
|
||||||
return 0;
|
return 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +119,8 @@ void dmg_write(void *_dmg, u16 address, u8 data)
|
|||||||
} else if (address >= 0xff80 && address <= 0xfffe) {
|
} else if (address >= 0xff80 && address <= 0xfffe) {
|
||||||
dmg->zero_page[address - 0xff80] = data;
|
dmg->zero_page[address - 0xff80] = data;
|
||||||
} else if (address == 0xff00) {
|
} else if (address == 0xff00) {
|
||||||
dmg->joypad_selected = data & (1 << 4);
|
dmg->joypad_selected = !(data & (1 << 4));
|
||||||
dmg->action_selected = data & (1 << 5);
|
dmg->action_selected = !(data & (1 << 5));
|
||||||
} else if (address == 0xff0f) {
|
} else if (address == 0xff0f) {
|
||||||
dmg->interrupt_requested = data;
|
dmg->interrupt_requested = data;
|
||||||
} else if (address == 0xffff) {
|
} else if (address == 0xffff) {
|
||||||
@ -144,22 +144,33 @@ void dmg_step(void *_dmg)
|
|||||||
cpu_step(dmg->cpu);
|
cpu_step(dmg->cpu);
|
||||||
|
|
||||||
// each line takes 456 cycles
|
// each line takes 456 cycles
|
||||||
if (dmg->cpu->cycle_count - dmg->last_lcd_update >= 456) {
|
|
||||||
|
int cycle_diff = dmg->cpu->cycle_count - dmg->last_lcd_update;
|
||||||
|
|
||||||
|
if (cycle_diff >= 456) {
|
||||||
dmg->last_lcd_update = dmg->cpu->cycle_count;
|
dmg->last_lcd_update = dmg->cpu->cycle_count;
|
||||||
int next_scanline = lcd_step(dmg->lcd);
|
int next_scanline = lcd_step(dmg->lcd);
|
||||||
|
|
||||||
// update LYC
|
// update LYC
|
||||||
if (next_scanline == lcd_read(dmg->lcd, REG_LYC)) {
|
if (next_scanline == lcd_read(dmg->lcd, REG_LYC)) {
|
||||||
lcd_set_bit(dmg->lcd, REG_STAT, STAT_FLAG_MATCH);
|
lcd_set_bit(dmg->lcd, REG_STAT, STAT_FLAG_MATCH);
|
||||||
dmg_request_interrupt(dmg, INT_LCDSTAT);
|
if (lcd_isset(dmg->lcd, REG_STAT, STAT_INTR_SOURCE_MATCH)) {
|
||||||
|
dmg_request_interrupt(dmg, INT_LCDSTAT);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
lcd_clear_bit(dmg->lcd, REG_STAT, STAT_FLAG_MATCH);
|
lcd_clear_bit(dmg->lcd, REG_STAT, STAT_FLAG_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (next_scanline >= 144 && next_scanline < 154) {
|
||||||
|
lcd_set_mode(dmg->lcd, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (next_scanline == 144) {
|
if (next_scanline == 144) {
|
||||||
// vblank has started, draw all the stuff from ram into the lcd
|
// vblank has started, draw all the stuff from ram into the lcd
|
||||||
dmg_request_interrupt(dmg, INT_VBLANK);
|
dmg_request_interrupt(dmg, INT_VBLANK);
|
||||||
dmg_request_interrupt(dmg, INT_SERIAL);
|
if (lcd_isset(dmg->lcd, REG_STAT, STAT_INTR_SOURCE_VBLANK)) {
|
||||||
|
dmg_request_interrupt(dmg, INT_LCDSTAT);
|
||||||
|
}
|
||||||
|
|
||||||
int lcdc = lcd_read(dmg->lcd, REG_LCDC);
|
int lcdc = lcd_read(dmg->lcd, REG_LCDC);
|
||||||
int bg_base = (lcdc & LCDC_BG_TILE_MAP) ? 0x9c00 : 0x9800;
|
int bg_base = (lcdc & LCDC_BG_TILE_MAP) ? 0x9c00 : 0x9800;
|
||||||
@ -186,8 +197,8 @@ void dmg_step(void *_dmg)
|
|||||||
int data1 = dmg_read(dmg, eff_addr + b);
|
int data1 = dmg_read(dmg, eff_addr + b);
|
||||||
int data2 = dmg_read(dmg, eff_addr + b + 1);
|
int data2 = dmg_read(dmg, eff_addr + b + 1);
|
||||||
for (i = 7; i >= 0; i--) {
|
for (i = 7; i >= 0; i--) {
|
||||||
dmg->lcd->buf[off] = ((data1 & (1 << i)) ? 1 : 0);// << 1;
|
dmg->lcd->buf[off] = ((data1 & (1 << i)) ? 1 : 0) << 1;
|
||||||
//dmg->lcd->buf[off] |= (data1 & (1 << i)) ? 1 : 0;
|
dmg->lcd->buf[off] |= (data2 & (1 << i)) ? 1 : 0;
|
||||||
off++;
|
off++;
|
||||||
}
|
}
|
||||||
off += 248;
|
off += 248;
|
||||||
@ -199,5 +210,19 @@ void dmg_step(void *_dmg)
|
|||||||
lcd_copy(dmg->lcd);
|
lcd_copy(dmg->lcd);
|
||||||
lcd_draw(dmg->lcd);
|
lcd_draw(dmg->lcd);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
int scan = lcd_read(dmg->lcd, REG_LY);
|
||||||
|
if (scan < 144) {
|
||||||
|
if (cycle_diff < 80) {
|
||||||
|
lcd_set_mode(dmg->lcd, 2);
|
||||||
|
} else if (cycle_diff < 230) {
|
||||||
|
// just midpoint between 168 to 291, todo improve
|
||||||
|
lcd_set_mode(dmg->lcd, 3);
|
||||||
|
} else {
|
||||||
|
lcd_set_mode(dmg->lcd, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// in vblank. mode should stay as 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
12
src/lcd.c
12
src/lcd.c
@ -15,6 +15,18 @@ void lcd_clear_bit(struct lcd *lcd, u16 addr, u8 bit)
|
|||||||
lcd_write(lcd, addr, lcd_read(lcd, addr) & ~(1 << bit));
|
lcd_write(lcd, addr, lcd_read(lcd, addr) & ~(1 << bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lcd_isset(struct lcd *lcd, u16 addr, u8 bit)
|
||||||
|
{
|
||||||
|
u8 val = lcd_read(lcd, addr);
|
||||||
|
return val & (1 << bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcd_set_mode(struct lcd *lcd, int mode)
|
||||||
|
{
|
||||||
|
u8 val = lcd_read(lcd, REG_STAT);
|
||||||
|
lcd_write(lcd, REG_STAT, (val & 0xfc) | mode);
|
||||||
|
}
|
||||||
|
|
||||||
void lcd_new(struct lcd *lcd)
|
void lcd_new(struct lcd *lcd)
|
||||||
{
|
{
|
||||||
lcd->buf = malloc(256 * 256);
|
lcd->buf = malloc(256 * 256);
|
||||||
|
@ -24,6 +24,11 @@
|
|||||||
#define REG_LCD_LAST REG_WX
|
#define REG_LCD_LAST REG_WX
|
||||||
|
|
||||||
#define STAT_FLAG_MATCH 2
|
#define STAT_FLAG_MATCH 2
|
||||||
|
#define STAT_INTR_SOURCE_HBLANK 3
|
||||||
|
#define STAT_INTR_SOURCE_VBLANK 4
|
||||||
|
#define STAT_INTR_SOURCE_MODE2 5
|
||||||
|
#define STAT_INTR_SOURCE_MATCH 6
|
||||||
|
|
||||||
|
|
||||||
#define LCDC_ENABLE_BG (1 << 0)
|
#define LCDC_ENABLE_BG (1 << 0)
|
||||||
#define LCDC_ENABLE_OBJ (1 << 1)
|
#define LCDC_ENABLE_OBJ (1 << 1)
|
||||||
@ -50,6 +55,8 @@ void lcd_put_pixel(struct lcd *lcd, u8 x, u8 y, u8 value);
|
|||||||
|
|
||||||
void lcd_set_bit(struct lcd *lcd, u16 addr, u8 bit);
|
void lcd_set_bit(struct lcd *lcd, u16 addr, u8 bit);
|
||||||
void lcd_clear_bit(struct lcd *lcd, u16 addr, u8 bit);
|
void lcd_clear_bit(struct lcd *lcd, u16 addr, u8 bit);
|
||||||
|
int lcd_isset(struct lcd *lcd, u16 addr, u8 bit);
|
||||||
|
void lcd_set_mode(struct lcd *lcd, int mode);
|
||||||
|
|
||||||
// i feel like i'm going to need to call this every cycle and update regs
|
// i feel like i'm going to need to call this every cycle and update regs
|
||||||
int lcd_step(struct lcd *lcd);
|
int lcd_step(struct lcd *lcd);
|
||||||
|
Loading…
Reference in New Issue
Block a user