mirror of
https://github.com/mlaux/gb6.git
synced 2024-06-15 12:29:33 +00:00
Compare commits
3 Commits
9601b9f7da
...
bc3f717285
Author | SHA1 | Date | |
---|---|---|---|
|
bc3f717285 | ||
|
b1dca59463 | ||
|
261bb40563 |
|
@ -11,7 +11,7 @@ execute_process(COMMAND sdl2-config --libs
|
||||||
OUTPUT_VARIABLE SDL_LIBS
|
OUTPUT_VARIABLE SDL_LIBS
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++14 ${SDL_CFLAGS}")
|
set(CMAKE_CXX_FLAGS "-std=c++14 -g -DGB6_DEBUG ${SDL_CFLAGS}")
|
||||||
|
|
||||||
add_executable(gb6
|
add_executable(gb6
|
||||||
../src/bootstrap.c
|
../src/bootstrap.c
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "imgui/imgui_memory_editor.h"
|
#include "imgui/imgui_memory_editor.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
#include <SDL_timer.h>
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
#include <SDL_opengles2.h>
|
#include <SDL_opengles2.h>
|
||||||
#else
|
#else
|
||||||
|
@ -49,6 +50,7 @@ GLuint make_output_texture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char output_image[256 * 256 * 4];
|
unsigned char output_image[256 * 256 * 4];
|
||||||
|
unsigned char vram_tiles[256 * 96 * 4];
|
||||||
|
|
||||||
void convert_output(struct lcd *lcd) {
|
void convert_output(struct lcd *lcd) {
|
||||||
int x, y;
|
int x, y;
|
||||||
|
@ -57,14 +59,41 @@ void convert_output(struct lcd *lcd) {
|
||||||
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 = val ? 255 : 0;
|
int fill = val ? 255 : 0;
|
||||||
output_image[out_index++] = val;
|
output_image[out_index++] = fill;
|
||||||
output_image[out_index++] = val;
|
output_image[out_index++] = fill;
|
||||||
output_image[out_index++] = val;
|
output_image[out_index++] = fill;
|
||||||
output_image[out_index++] = 255;
|
output_image[out_index++] = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void convert_vram(struct dmg *dmg) {
|
||||||
|
int tile_y, tile_x;
|
||||||
|
int off, in;
|
||||||
|
for (tile_y = 0; tile_y < 12; tile_y++) {
|
||||||
|
for (tile_x = 0; tile_x < 32; tile_x++) {
|
||||||
|
off = 256 * 8 * tile_y + 8 * tile_x;
|
||||||
|
in = 16 * (tile_y * 32 + tile_x);
|
||||||
|
int b, i;
|
||||||
|
for (b = 0; b < 16; b += 2) {
|
||||||
|
int data1 = dmg->video_ram[in + b];
|
||||||
|
int data2 = dmg->video_ram[in + b + 1];
|
||||||
|
for (i = 7; i >= 0; i--) {
|
||||||
|
// monochrome for now
|
||||||
|
int fill = (data1 & (1 << i)) ? 255 : 0;
|
||||||
|
vram_tiles[4 * off + 0] = fill;
|
||||||
|
vram_tiles[4 * off + 1] = fill;
|
||||||
|
vram_tiles[4 * off + 2] = fill;
|
||||||
|
vram_tiles[4 * off + 3] = 255;
|
||||||
|
//dmg->lcd->buf[off] |= (data2 & (1 << i)) ? 1 : 0;
|
||||||
|
off++;
|
||||||
|
}
|
||||||
|
off += 248;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char full_address_space[0x10000];
|
char full_address_space[0x10000];
|
||||||
void fill_memory_editor(struct dmg *dmg)
|
void fill_memory_editor(struct dmg *dmg)
|
||||||
{
|
{
|
||||||
|
@ -164,6 +193,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// setup output
|
// setup output
|
||||||
GLuint texture = make_output_texture();
|
GLuint texture = make_output_texture();
|
||||||
|
GLuint vram_texture = make_output_texture();
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
bool z_flag = false;
|
bool z_flag = false;
|
||||||
|
@ -173,8 +203,13 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
unsigned int lastDrawTime = 0, currentTime;
|
||||||
while (!done)
|
while (!done)
|
||||||
{
|
{
|
||||||
|
dmg_step(&dmg);
|
||||||
|
|
||||||
|
currentTime = SDL_GetTicks();
|
||||||
|
if (currentTime >= lastDrawTime + 16) {
|
||||||
// Poll and handle events (inputs, window resize, etc.)
|
// Poll and handle events (inputs, window resize, etc.)
|
||||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||||
|
@ -195,8 +230,6 @@ int main(int argc, char *argv[])
|
||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
dmg_step(&dmg);
|
|
||||||
|
|
||||||
z_flag = flag_isset(dmg.cpu, FLAG_ZERO);
|
z_flag = flag_isset(dmg.cpu, FLAG_ZERO);
|
||||||
n_flag = flag_isset(dmg.cpu, FLAG_SIGN);
|
n_flag = flag_isset(dmg.cpu, FLAG_SIGN);
|
||||||
h_flag = flag_isset(dmg.cpu, FLAG_HALF_CARRY);
|
h_flag = flag_isset(dmg.cpu, FLAG_HALF_CARRY);
|
||||||
|
@ -243,10 +276,20 @@ int main(int argc, char *argv[])
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ImGui::Begin("VRAM");
|
||||||
|
|
||||||
|
convert_vram(&dmg);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, vram_texture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 96, 0, GL_RGBA, GL_UNSIGNED_BYTE, vram_tiles);
|
||||||
|
ImGui::Image((void*)(intptr_t) vram_texture, ImVec2(256, 96));
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
fill_memory_editor(&dmg);
|
fill_memory_editor(&dmg);
|
||||||
|
|
||||||
editor.DrawWindow("Memory", full_address_space, 0x10000, 0x0000);
|
editor.DrawWindow("Memory", full_address_space, 0x10000, 0x0000);
|
||||||
editor.DrawWindow("LCD", dmg.lcd->buf, 0x2000, 0);
|
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
@ -255,6 +298,9 @@ int main(int argc, char *argv[])
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
|
|
||||||
|
lastDrawTime = currentTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rom_free(&rom);
|
rom_free(&rom);
|
||||||
|
|
109
src/cpu.c
109
src/cpu.c
|
@ -110,23 +110,53 @@ static void dec_with_carry(struct cpu *regs, u8 *reg)
|
||||||
|
|
||||||
static u8 rotate_left(struct cpu *regs, u8 reg)
|
static u8 rotate_left(struct cpu *regs, u8 reg)
|
||||||
{
|
{
|
||||||
// copy old leftmost bit to carry flag
|
int old_carry = flag_isset(regs, FLAG_CARRY);
|
||||||
regs->f = (reg & 0x80) >> 3 | (regs->f & ~FLAG_CARRY);
|
// copy old leftmost bit to carry flag, clear Z, N, H
|
||||||
|
regs->f = (reg & 0x80) >> 3;
|
||||||
// rotate
|
// rotate
|
||||||
int result = reg << 1;
|
int result = reg << 1 | old_carry;
|
||||||
// restore leftmost (now rightmost) bit
|
if (!result) set_flag(regs, FLAG_ZERO);
|
||||||
result |= (regs->f & FLAG_CARRY) >> 4;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 rlc(struct cpu *cpu, u8 val)
|
||||||
|
{
|
||||||
|
int old_msb = (val & 0x80) >> 7;
|
||||||
|
int result = (val & 0x7f) << 1 | old_msb;
|
||||||
|
if (!result)
|
||||||
|
set_flag(cpu, FLAG_ZERO);
|
||||||
|
else clear_flag(cpu, FLAG_ZERO);
|
||||||
|
clear_flag(cpu, FLAG_SIGN);
|
||||||
|
clear_flag(cpu, FLAG_HALF_CARRY);
|
||||||
|
if (old_msb)
|
||||||
|
set_flag(cpu, FLAG_CARRY);
|
||||||
|
else clear_flag(cpu, FLAG_CARRY);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 rotate_right(struct cpu *regs, u8 reg)
|
static u8 rotate_right(struct cpu *regs, u8 reg)
|
||||||
{
|
{
|
||||||
// copy old rightmost bit to carry flag
|
int old_carry = flag_isset(regs, FLAG_CARRY) << 7;
|
||||||
regs->f = (reg & 0x01) << 4 | (regs->f & ~FLAG_CARRY);
|
// copy old rightmost bit to carry flag, clear ZNH
|
||||||
|
regs->f = (reg & 0x01) << 4;
|
||||||
// rotate
|
// rotate
|
||||||
int result = reg >> 1;
|
int result = old_carry | reg >> 1;
|
||||||
// restore rightmost bit to left
|
if (!result) set_flag(regs, FLAG_ZERO);
|
||||||
result |= (regs->f & FLAG_CARRY) << 3;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 rrc(struct cpu *cpu, u8 val)
|
||||||
|
{
|
||||||
|
int old_lsb = (val & 1) << 7;
|
||||||
|
int result = old_lsb | (val & 0xfe) >> 1;
|
||||||
|
if (!result)
|
||||||
|
set_flag(cpu, FLAG_ZERO);
|
||||||
|
else clear_flag(cpu, FLAG_ZERO);
|
||||||
|
clear_flag(cpu, FLAG_SIGN);
|
||||||
|
clear_flag(cpu, FLAG_HALF_CARRY);
|
||||||
|
if (old_lsb)
|
||||||
|
set_flag(cpu, FLAG_CARRY);
|
||||||
|
else clear_flag(cpu, FLAG_CARRY);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,10 +232,18 @@ static void subtract(struct cpu *cpu, u8 value, int with_carry, int just_compare
|
||||||
if (with_carry && flag_isset(cpu, FLAG_CARRY)) {
|
if (with_carry && flag_isset(cpu, FLAG_CARRY)) {
|
||||||
sum_full--;
|
sum_full--;
|
||||||
}
|
}
|
||||||
sum_trunc = (u8) sum_full;
|
sum_trunc = (u8) (sum_full & 0xff);
|
||||||
set_flag(cpu, sum_trunc == 0 ? FLAG_ZERO : 0);
|
if (!sum_trunc) {
|
||||||
|
set_flag(cpu, FLAG_ZERO);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_ZERO);
|
||||||
|
}
|
||||||
set_flag(cpu, FLAG_SIGN);
|
set_flag(cpu, FLAG_SIGN);
|
||||||
set_flag(cpu, sum_full < sum_trunc ? FLAG_CARRY : 0);
|
if (sum_full < sum_trunc) {
|
||||||
|
set_flag(cpu, FLAG_CARRY);
|
||||||
|
} else {
|
||||||
|
clear_flag(cpu, FLAG_CARRY);
|
||||||
|
}
|
||||||
// TODO H
|
// TODO H
|
||||||
|
|
||||||
if (!just_compare) {
|
if (!just_compare) {
|
||||||
|
@ -296,10 +334,10 @@ static void extended_insn(struct cpu *cpu, u8 insn)
|
||||||
int reg = insn & 0x7;
|
int reg = insn & 0x7;
|
||||||
|
|
||||||
u8 (*funcs[8])(struct cpu *, u8) = {
|
u8 (*funcs[8])(struct cpu *, u8) = {
|
||||||
|
rlc,
|
||||||
|
rrc,
|
||||||
rotate_left,
|
rotate_left,
|
||||||
rotate_right,
|
rotate_right,
|
||||||
rotate_left, // TODO non-carry version
|
|
||||||
rotate_right,
|
|
||||||
shift_left,
|
shift_left,
|
||||||
shift_right,
|
shift_right,
|
||||||
swap,
|
swap,
|
||||||
|
@ -356,7 +394,7 @@ void cpu_step(struct cpu *cpu)
|
||||||
cpu->pc += 2;
|
cpu->pc += 2;
|
||||||
break;
|
break;
|
||||||
case 0x07: // RLCA
|
case 0x07: // RLCA
|
||||||
cpu->a = rotate_left(cpu, cpu->a);
|
cpu->a = rlc(cpu, cpu->a);
|
||||||
break;
|
break;
|
||||||
case 0x08: // LD (a16),SP
|
case 0x08: // LD (a16),SP
|
||||||
write16(cpu, read16(cpu, cpu->pc), cpu->sp);
|
write16(cpu, read16(cpu, cpu->pc), cpu->sp);
|
||||||
|
@ -544,6 +582,7 @@ void cpu_step(struct cpu *cpu)
|
||||||
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);
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xc9: // RET
|
case 0xc9: // RET
|
||||||
|
@ -561,6 +600,7 @@ void cpu_step(struct cpu *cpu)
|
||||||
case 0xd2: // JP NC,a16
|
case 0xd2: // JP NC,a16
|
||||||
if (flag_isset(cpu, FLAG_CARRY)) {
|
if (flag_isset(cpu, FLAG_CARRY)) {
|
||||||
cpu->pc = read16(cpu, cpu->pc);
|
cpu->pc = read16(cpu, cpu->pc);
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -657,6 +697,18 @@ void cpu_step(struct cpu *cpu)
|
||||||
case 0xc5: // PUSH BC
|
case 0xc5: // PUSH BC
|
||||||
push(cpu, read_bc(cpu));
|
push(cpu, read_bc(cpu));
|
||||||
break;
|
break;
|
||||||
|
case 0xc8: // RET Z
|
||||||
|
if (flag_isset(cpu, FLAG_ZERO)) {
|
||||||
|
cpu->pc = pop(cpu);
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xca: // JP Z, u16
|
||||||
|
if (flag_isset(cpu, FLAG_ZERO)) {
|
||||||
|
cpu->pc = read16(cpu, cpu->pc);
|
||||||
|
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0xcb:
|
case 0xcb:
|
||||||
extended_insn(cpu, read8(cpu, cpu->pc));
|
extended_insn(cpu, read8(cpu, cpu->pc));
|
||||||
cpu->pc++;
|
cpu->pc++;
|
||||||
|
@ -665,13 +717,28 @@ void cpu_step(struct cpu *cpu)
|
||||||
add(cpu, read8(cpu, cpu->pc), 1);
|
add(cpu, read8(cpu, cpu->pc), 1);
|
||||||
cpu->pc++;
|
cpu->pc++;
|
||||||
break;
|
break;
|
||||||
|
case 0xd1: // POP DE
|
||||||
|
write_de(cpu, pop(cpu));
|
||||||
|
break;
|
||||||
|
case 0xd5: // PUSH DE
|
||||||
|
push(cpu, read_de(cpu));
|
||||||
|
break;
|
||||||
case 0xe0: // LD (a8),A
|
case 0xe0: // LD (a8),A
|
||||||
write8(cpu, 0xff00 + read8(cpu, cpu->pc), cpu->a);
|
write8(cpu, 0xff00 + read8(cpu, cpu->pc), cpu->a);
|
||||||
cpu->pc++;
|
cpu->pc++;
|
||||||
break;
|
break;
|
||||||
|
case 0xe1: // POP HL
|
||||||
|
write_hl(cpu, pop(cpu));
|
||||||
|
break;
|
||||||
case 0xe2: // LD (C),A
|
case 0xe2: // LD (C),A
|
||||||
write8(cpu, 0xff00 + cpu->c, cpu->a);
|
write8(cpu, 0xff00 + cpu->c, cpu->a);
|
||||||
break;
|
break;
|
||||||
|
case 0xe5: // PUSH HL
|
||||||
|
push(cpu, read_hl(cpu));
|
||||||
|
break;
|
||||||
|
case 0xe9: // JP HL
|
||||||
|
cpu->pc = read_hl(cpu);
|
||||||
|
break;
|
||||||
case 0xea: // LD (a16),A
|
case 0xea: // LD (a16),A
|
||||||
write8(cpu, read16(cpu, cpu->pc), cpu->a);
|
write8(cpu, read16(cpu, cpu->pc), cpu->a);
|
||||||
cpu->pc += 2;
|
cpu->pc += 2;
|
||||||
|
@ -680,11 +747,21 @@ void cpu_step(struct cpu *cpu)
|
||||||
cpu->a = read8(cpu, 0xff00 + read8(cpu, cpu->pc));
|
cpu->a = read8(cpu, 0xff00 + read8(cpu, cpu->pc));
|
||||||
cpu->pc++;
|
cpu->pc++;
|
||||||
break;
|
break;
|
||||||
|
case 0xf1: // POP AF
|
||||||
|
write_af(cpu, pop(cpu));
|
||||||
|
break;
|
||||||
case 0xf2: // LD A,(C)
|
case 0xf2: // LD A,(C)
|
||||||
cpu->a = read8(cpu, 0xff00 + cpu->c);
|
cpu->a = read8(cpu, 0xff00 + cpu->c);
|
||||||
break;
|
break;
|
||||||
case 0xf3: // DI
|
case 0xf3: // DI
|
||||||
break;
|
break;
|
||||||
|
case 0xf5: // PUSH AF
|
||||||
|
push(cpu, read_af(cpu));
|
||||||
|
break;
|
||||||
|
case 0xfa: // LD A,(u16)
|
||||||
|
cpu->a = read8(cpu, read16(cpu, cpu->pc));
|
||||||
|
cpu->pc += 2;
|
||||||
|
break;
|
||||||
case 0xfb: // EI
|
case 0xfb: // EI
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
30
src/dmg.c
30
src/dmg.c
|
@ -18,9 +18,10 @@ void dmg_new(struct dmg *dmg, struct cpu *cpu, struct rom *rom, struct lcd *lcd)
|
||||||
u8 dmg_read(void *_dmg, u16 address)
|
u8 dmg_read(void *_dmg, u16 address)
|
||||||
{
|
{
|
||||||
struct dmg *dmg = (struct dmg *) _dmg;
|
struct dmg *dmg = (struct dmg *) _dmg;
|
||||||
if (address < 0x100) {
|
// if (address < 0x100) {
|
||||||
return dmg_boot_rom[address];
|
// return dmg_boot_rom[address];
|
||||||
} else if (address < 0x4000) {
|
// } else if (address < 0x4000) {
|
||||||
|
if (address < 0x4000) {
|
||||||
return dmg->rom->data[address];
|
return dmg->rom->data[address];
|
||||||
} else if (address < 0x8000) {
|
} else if (address < 0x8000) {
|
||||||
// TODO switchable rom bank
|
// TODO switchable rom bank
|
||||||
|
@ -68,6 +69,7 @@ void dmg_write(void *_dmg, u16 address, u8 data)
|
||||||
// not sure about any of this yet
|
// not sure about any of this yet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void exit(int);
|
||||||
|
|
||||||
void dmg_step(void *_dmg)
|
void dmg_step(void *_dmg)
|
||||||
{
|
{
|
||||||
|
@ -78,7 +80,8 @@ 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 % 456 == 0) {
|
if (dmg->cpu->cycle_count - dmg->last_lcd_update >= 456) {
|
||||||
|
dmg->last_lcd_update = dmg->cpu->cycle_count;
|
||||||
int next_scanline = lcd_step(dmg->lcd);
|
int next_scanline = lcd_step(dmg->lcd);
|
||||||
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
|
||||||
|
@ -89,11 +92,14 @@ void dmg_step(void *_dmg)
|
||||||
int use_unsigned = lcdc & LCDC_BG_TILE_DATA;
|
int use_unsigned = lcdc & LCDC_BG_TILE_DATA;
|
||||||
int tilebase = use_unsigned ? 0x8000 : 0x9000;
|
int tilebase = use_unsigned ? 0x8000 : 0x9000;
|
||||||
|
|
||||||
printf("base is %04x\n", bg_base);
|
printf("tile map: %04x, tile data: %04x\n", bg_base, tilebase);
|
||||||
|
|
||||||
int k, off = 0;
|
int k = 0, off = 0;
|
||||||
for (k = 0; k < 1024; k++) {
|
int tile_y = 0, tile_x = 0;
|
||||||
int tile = dmg_read(dmg, bg_base + k);
|
for (tile_y = 0; tile_y < 32; tile_y++) {
|
||||||
|
for (tile_x = 0; tile_x < 32; tile_x++) {
|
||||||
|
off = 256 * 8 * tile_y + 8 * tile_x;
|
||||||
|
int tile = dmg_read(dmg, bg_base + (tile_y * 32 + tile_x));
|
||||||
int eff_addr;
|
int eff_addr;
|
||||||
if (use_unsigned) {
|
if (use_unsigned) {
|
||||||
eff_addr = tilebase + 16 * tile;
|
eff_addr = tilebase + 16 * tile;
|
||||||
|
@ -104,12 +110,14 @@ void dmg_step(void *_dmg)
|
||||||
for (b = 0; b < 16; b += 2) {
|
for (b = 0; b < 16; b += 2) {
|
||||||
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 = 0; i < 8; i++) {
|
for (i = 7; i >= 0; i--) {
|
||||||
// monochrome for now
|
// monochrome for now
|
||||||
dmg->lcd->buf[off] |= (data1 & (1 << i)) ? 1 : 0;
|
dmg->lcd->buf[off] = (data1 & (1 << i)) ? 1 : 0;
|
||||||
dmg->lcd->buf[off] |= (data2 & (1 << i)) ? 1 : 0;
|
//dmg->lcd->buf[off] |= (data2 & (1 << i)) ? 1 : 0;
|
||||||
off++;
|
off++;
|
||||||
}
|
}
|
||||||
|
off += 248;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct dmg {
|
||||||
u8 main_ram[0x2000];
|
u8 main_ram[0x2000];
|
||||||
u8 video_ram[0x2000];
|
u8 video_ram[0x2000];
|
||||||
u8 zero_page[0x80];
|
u8 zero_page[0x80];
|
||||||
|
u32 last_lcd_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
void dmg_new(struct dmg *dmg, struct cpu *cpu, struct rom *rom, struct lcd *lcd);
|
void dmg_new(struct dmg *dmg, struct cpu *cpu, struct rom *rom, struct lcd *lcd);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user