mirror of https://github.com/mlaux/gb6.git
fix mbc1, start scrolling routine - it's slow
This commit is contained in:
parent
03ef4d1116
commit
f4ca6cf847
|
@ -13,6 +13,7 @@ extern "C" {
|
|||
#include "cpu.h"
|
||||
#include "rom.h"
|
||||
#include "lcd.h"
|
||||
#include "instructions.h"
|
||||
}
|
||||
|
||||
static const char *A_FORMAT = "A: 0x%02x";
|
||||
|
@ -24,8 +25,10 @@ static const char *H_FORMAT = "H: 0x%02x";
|
|||
static const char *L_FORMAT = "L: 0x%02x";
|
||||
static const char *SP_FORMAT = "SP: 0x%02x";
|
||||
static const char *PC_FORMAT = "PC: 0x%02x";
|
||||
static const char *INSN_FORMAT = "Next instruction: %s";
|
||||
|
||||
unsigned char output_image[256 * 256 * 4];
|
||||
unsigned char visible_pixels[160 * 144 * 4];
|
||||
unsigned char vram_tiles[256 * 96 * 4];
|
||||
|
||||
struct key_input {
|
||||
|
@ -75,6 +78,17 @@ void convert_output(struct lcd *lcd) {
|
|||
output_image[out_index++] = 255;
|
||||
}
|
||||
}
|
||||
out_index = 0;
|
||||
for (y = 0; y < 144; y++) {
|
||||
for (x = 0; x < 160; x++) {
|
||||
int val = lcd->pixels[y * 160 + x];
|
||||
int fill = default_palette[val];
|
||||
visible_pixels[out_index++] = fill;
|
||||
visible_pixels[out_index++] = fill;
|
||||
visible_pixels[out_index++] = fill;
|
||||
visible_pixels[out_index++] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void convert_vram(struct dmg *dmg) {
|
||||
|
@ -194,6 +208,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
// setup output
|
||||
GLuint texture = make_output_texture();
|
||||
GLuint vis_texture = make_output_texture();
|
||||
GLuint vram_texture = make_output_texture();
|
||||
|
||||
editor.ReadFn = read_mem;
|
||||
|
@ -276,6 +291,9 @@ int main(int argc, char *argv[])
|
|||
ImGui::SameLine();
|
||||
ImGui::Text(PC_FORMAT, dmg.cpu->pc);
|
||||
|
||||
u8 opc = dmg_read(&dmg, dmg.cpu->pc);
|
||||
ImGui::Text(INSN_FORMAT, instructions[opc].format);
|
||||
|
||||
ImGui::Checkbox("Z", &z_flag);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("N", &n_flag);
|
||||
|
@ -302,10 +320,10 @@ int main(int argc, char *argv[])
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
convert_output(dmg.lcd);
|
||||
{
|
||||
ImGui::Begin("Output");
|
||||
|
||||
convert_output(dmg.lcd);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, output_image);
|
||||
ImGui::Image((void*)(intptr_t) texture, ImVec2(512, 512));
|
||||
|
@ -313,6 +331,16 @@ int main(int argc, char *argv[])
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::Begin("LCD");
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, vis_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 160, 144, 0, GL_RGBA, GL_UNSIGNED_BYTE, visible_pixels);
|
||||
ImGui::Image((void*)(intptr_t) vis_texture, ImVec2(320, 288));
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::Begin("VRAM");
|
||||
|
||||
|
|
25
src/cpu.c
25
src/cpu.c
|
@ -269,7 +269,8 @@ static void add(struct cpu *cpu, u8 value, int with_carry)
|
|||
{
|
||||
u8 sum_trunc;
|
||||
int sum_full = cpu->a + value;
|
||||
if (with_carry && flag_isset(cpu, FLAG_CARRY)) {
|
||||
int carry = (with_carry && flag_isset(cpu, FLAG_CARRY)) ? 1 : 0;
|
||||
if (carry) {
|
||||
sum_full++;
|
||||
}
|
||||
sum_trunc = (u8) sum_full;
|
||||
|
@ -279,12 +280,12 @@ static void add(struct cpu *cpu, u8 value, int with_carry)
|
|||
clear_flag(cpu, FLAG_ZERO);
|
||||
}
|
||||
clear_flag(cpu, FLAG_SIGN);
|
||||
if (sum_full > sum_trunc) {
|
||||
if (sum_full > 0xff) {
|
||||
set_flag(cpu, FLAG_CARRY);
|
||||
} else {
|
||||
clear_flag(cpu, FLAG_CARRY);
|
||||
}
|
||||
if (((cpu->a & 0xf) + (value & 0xf)) & 0x10) {
|
||||
if (((cpu->a & 0xf) + (value & 0xf) + carry) & 0x10) {
|
||||
set_flag(cpu, FLAG_HALF_CARRY);
|
||||
} else {
|
||||
clear_flag(cpu, FLAG_HALF_CARRY);
|
||||
|
@ -296,10 +297,11 @@ static void subtract(struct cpu *cpu, u8 value, int with_carry, int just_compare
|
|||
{
|
||||
u8 sum_trunc;
|
||||
int sum_full = cpu->a - value;
|
||||
if (with_carry && flag_isset(cpu, FLAG_CARRY)) {
|
||||
int carry = (with_carry && flag_isset(cpu, FLAG_CARRY)) ? 1 : 0;
|
||||
if (carry) {
|
||||
sum_full--;
|
||||
}
|
||||
sum_trunc = (u8) (sum_full & 0xff);
|
||||
sum_trunc = (u8) sum_full;
|
||||
if (!sum_trunc) {
|
||||
set_flag(cpu, FLAG_ZERO);
|
||||
} else {
|
||||
|
@ -508,9 +510,6 @@ static u16 check_interrupts(struct cpu *cpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
void cpu_step(struct cpu *cpu)
|
||||
{
|
||||
u8 temp;
|
||||
|
@ -570,6 +569,13 @@ void cpu_step(struct cpu *cpu)
|
|||
cpu->a = rotate_right(cpu, cpu->a);
|
||||
break;
|
||||
|
||||
case 0x37: // SCF
|
||||
set_flag(cpu, FLAG_CARRY);
|
||||
break;
|
||||
case 0x3f: // CCF
|
||||
clear_flag(cpu, FLAG_CARRY);
|
||||
break;
|
||||
|
||||
// incs and decs
|
||||
case 0x03: write_bc(cpu, read_bc(cpu) + 1); break;
|
||||
case 0x04: inc_with_carry(cpu, &cpu->b); break;
|
||||
|
@ -864,7 +870,7 @@ void cpu_step(struct cpu *cpu)
|
|||
break;
|
||||
|
||||
case 0xde: // SBC A, u8
|
||||
subtract(cpu, read8(cpu, cpu->pc), 0, 1);
|
||||
subtract(cpu, read8(cpu, cpu->pc), 1, 0);
|
||||
cpu->pc++;
|
||||
break;
|
||||
|
||||
|
@ -992,6 +998,7 @@ void cpu_step(struct cpu *cpu)
|
|||
break;
|
||||
case 0xf1: // POP AF
|
||||
write_af(cpu, pop(cpu));
|
||||
cpu->f &= 0xf0;
|
||||
break;
|
||||
case 0xf2: // LD A,(C)
|
||||
cpu->a = read8(cpu, 0xff00 + cpu->c);
|
||||
|
|
24
src/dmg.c
24
src/dmg.c
|
@ -67,13 +67,12 @@ u8 dmg_read(void *_dmg, u16 address)
|
|||
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;
|
||||
printf("RAM bank not handled by MBC\n");
|
||||
return 0xff;
|
||||
} else if (address < 0xe000) {
|
||||
return dmg->main_ram[address - 0xc000];
|
||||
} else if (lcd_is_valid_addr(address)) {
|
||||
|
@ -182,6 +181,23 @@ static void render_background(struct dmg *dmg, int lcdc)
|
|||
}
|
||||
}
|
||||
|
||||
static void scroll(struct dmg *dmg)
|
||||
{
|
||||
int scroll_y = lcd_read(dmg->lcd, REG_SCY);
|
||||
int scroll_x = lcd_read(dmg->lcd, REG_SCX);
|
||||
|
||||
int lines;
|
||||
for (lines = 0; lines < 144; lines++) {
|
||||
int src_y = (scroll_y + lines) & 0xff;
|
||||
int cols;
|
||||
for (cols = 0; cols < 160; cols++) {
|
||||
int src_off = (src_y << 8) + ((scroll_x + cols) & 0xff);
|
||||
|
||||
dmg->lcd->pixels[lines * 160 + cols] = dmg->lcd->buf[src_off];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct oam_entry {
|
||||
u8 pos_y;
|
||||
u8 pos_x;
|
||||
|
@ -272,6 +288,8 @@ void dmg_step(void *_dmg)
|
|||
render_objs(dmg);
|
||||
}
|
||||
|
||||
scroll(dmg);
|
||||
|
||||
// now copy 256x256 buf to 160x144 based on window registers
|
||||
lcd_copy(dmg->lcd);
|
||||
lcd_draw(dmg->lcd);
|
||||
|
|
|
@ -19,7 +19,10 @@ static int mbc_noop_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data)
|
|||
static int mbc1_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data)
|
||||
{
|
||||
if (addr >= 0x4000 && addr <= 0x7fff) {
|
||||
int use_bank = mbc->rom_bank || 1;
|
||||
int use_bank = mbc->rom_bank;
|
||||
if (!use_bank) {
|
||||
use_bank = 1;
|
||||
}
|
||||
*out_data = dmg->rom->data[0x4000 * use_bank + (addr & 0x3fff)];
|
||||
return 1;
|
||||
} else if (addr >= 0xa000 && addr <= 0xbfff) {
|
||||
|
|
Loading…
Reference in New Issue