From e32535b01667efb46b3d74308bc5ead7b36e46b6 Mon Sep 17 00:00:00 2001 From: Matthew Laux Date: Wed, 3 Aug 2022 01:22:22 -0500 Subject: [PATCH] support x and y flip, try to support 8x16 but i need to change the rendering to per-scanline --- src/cpu.c | 18 ++++++++++++++++++ src/dmg.c | 29 +++++++++++++++++++++-------- src/lcd.h | 5 +++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index d8b912d..6aec086 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -782,6 +782,24 @@ void cpu_step(struct cpu *cpu) cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles; } 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 if (!flag_isset(cpu, FLAG_CARRY)) { cpu->pc = pop(cpu); diff --git a/src/dmg.c b/src/dmg.c index 833d6cf..823746b 100644 --- a/src/dmg.c +++ b/src/dmg.c @@ -188,16 +188,18 @@ struct oam_entry { u8 attrs; }; -// TODO: only ten per scanline, priority +// TODO: only ten per scanline, priority, attributes, move to lcd.c static void render_objs(struct dmg *dmg) { struct oam_entry *oam = (struct oam_entry *) dmg->lcd->oam; 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++) { if (oam->pos_y == 0 || oam->pos_y >= 160) { continue; } - if (oam->pos_x == 0 || oam->pos_y >= 168) { + if (oam->pos_x == 0 || oam->pos_x >= 168) { continue; } @@ -206,17 +208,28 @@ static void render_objs(struct dmg *dmg) off = 160 * lcd_y + lcd_x; int eff_addr = 0x8000 + 16 * oam->tile; - int b, i; - for (b = 0; b < 16; b += 2) { - int data1 = dmg_read(dmg, eff_addr + b); - int data2 = dmg_read(dmg, eff_addr + b + 1); + int b, i, limit = 16; + if (tall) { + limit = 32; + } + 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--) { if (off < 0 || off >= 160 * 144) { // terrible clipping. need to not have an if per-pixel continue; } - dmg->lcd->pixels[off] = ((data1 & (1 << i)) ? 1 : 0) << 1; - dmg->lcd->pixels[off] |= (data2 & (1 << i)) ? 1 : 0; + int use_index = i; + if (oam->attrs & OAM_ATTR_MIRROR_X) { + use_index = 7 - i; + } + dmg->lcd->pixels[off] = ((data1 & (1 << use_index)) ? 1 : 0) << 1; + dmg->lcd->pixels[off] |= (data2 & (1 << use_index)) ? 1 : 0; off++; } off += 152; diff --git a/src/lcd.h b/src/lcd.h index 631b4e4..a3923bd 100644 --- a/src/lcd.h +++ b/src/lcd.h @@ -39,6 +39,11 @@ #define LCDC_WINDOW_TILE_MAP (1 << 6) #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 { u8 oam[0xa0]; u8 regs[0x0c];