From 787214ef44319d5845ab346fd7c193462d034890 Mon Sep 17 00:00:00 2001 From: slack Date: Sun, 29 Jun 2008 03:30:27 +0200 Subject: [PATCH] More video code --- GBMemory.h | 1 + GBVideo.cc | 92 ++++++++++++++++++++++++++++++++++++++++++++++++------ GBVideo.h | 6 ++++ Makefile | 2 +- util.h | 31 ++++++++++++++++++ 5 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 util.h diff --git a/GBMemory.h b/GBMemory.h index 55563f1..56bd570 100644 --- a/GBMemory.h +++ b/GBMemory.h @@ -24,6 +24,7 @@ class GBIO static const u16 OBP0 = 0xFF48; // Object Pallete 0 data(R/W) static const u16 OBP1 = 0xFF49; // Object Pallete 1 data(R/W) static const u16 DMA = 0xFF46; // DMA Transfer & Start addr (W) + static const u16 IF = 0xFF0F; // Interrupt flag (R/W) u8 read(int addr) const; void write(int addr, u8 value); diff --git a/GBVideo.cc b/GBVideo.cc index 2789af8..86521de 100644 --- a/GBVideo.cc +++ b/GBVideo.cc @@ -1,5 +1,7 @@ #include "GBVideo.h" - +#include "gbcore.h" +#include "util.h" + GBVideo::GBVideo(GameBoy *core): display(0), core(core) @@ -20,22 +22,38 @@ GBVideo::~GBVideo() u8 GBVideo::read_VRAM (int addr) const { - return VRAM[addr-VRAM_BASE]; + int STAT = memory.read(GBIO::STAT); + if ((STAT & 3) == 3) + return 0xFF; // VRAM access disabled + else + return VRAM[addr-VRAM_BASE]; } u8 GBVideo::read_OAM (int addr) const { - return OAM[addr-OAM_BASE]; + int STAT = memory.read(GBIO::STAT); + if ((STAT & 3) >= 2) + return 0xFF; // OAM access disabled + else + return OAM[addr-OAM_BASE]; } void GBVideo::write_VRAM(int addr, u8 value) { - VRAM[addr-VRAM_BASE] = value; + int STAT = memory.read(GBIO::STAT); + if ((STAT & 3) == 3) + return; // VRAM access disabled + else + VRAM[addr-VRAM_BASE] = value; } void GBVideo::write_OAM (int addr, u8 value) { - OAM[addr-OAM_BASE] = value; + int STAT = memory.read(GBIO::STAT); + if ((STAT & 3) >= 2) + return; // OAM access disabled + else + OAM[addr-OAM_BASE] = value; } void GBVideo::update() @@ -46,12 +64,68 @@ void GBVideo::update() //70224 clks.) // // sequence: - // 2: 80 clocks \ - // 3: 172 clocks |-> for each one of the 144 lines - // 0: 204 clocks (HBlank) / + // 2: 80 clocks (reading OAM) | + // 3: 172 clocks (reading OAM+VRAM) |-> for each one of the 144 lines + // 0: 204 clocks (HBlank) | // 1: 4560 clocks -> VBlank - + // + // mode 2 starts at 0, 456, 912... + // mode 3 starts at 80, 536, 992... + // mode 0 starts at 252, 708, 1164... + // vblank starts at 65664 + + int STAT = core->memory.read(GBIO::STAT); + int LYC = core->memory.read(GBIO::LYC); + int LY = core->memory.read(GBIO::LY); + int t = core->cycle_count % 70224; + if (t >= 65665) + { + if (t == 65665 && check_bit(STAT,4)) + core->irq(GameBoy::IRQ_VBLANK); + + // preserve bits 3-6, set mode to 1 (VBlank) and coincidence to 0 + STAT = (STAT&0xF8) | 1; + } + else + { + LY = t/456; + int hline_t = t%456; + if (LY == LYC) + { + STAT = set_bit(STAT, 2); // set coincidence flag + if (hline_t == 0 && check_bit(STAT, 6)) + core->irq(GameBoy::IRQ_LCD_STAT); + } + + if (hline_t < 80) + { + if (hline_t == 0 && check_bit(STAT, 5)) + core->irq(GameBoy::IRQ_LCD_STAT); + + // preserve bits 2-6, set mode 2 + STAT = (STAT&0xFC) | 2; + } + else if (hline_t < 252) + { + // preserve bits 2-6, set mode 3 + STAT = (STAT&0xFC) | 3; + } + else + { + // HBlank (preserve bits 2-6, mode = 0) + STAT = (STAT&0xFC); + if (hline_t == 252 && check_bit(STAT, 3)) + core->irq(GameBoy::IRQ_LCD_STAT); + } + + } + + core->memory.write(GBIO::LY, LY); + core->memory.write(GBIO::STAT, STAT); + + // Draw the background + } diff --git a/GBVideo.h b/GBVideo.h index 8e35bed..63c8d75 100644 --- a/GBVideo.h +++ b/GBVideo.h @@ -1,6 +1,11 @@ +#ifndef GBVIDEO_H +#define GBVIDEO_H + #include "GBMemory.h" #include "SDL.h" +class GameBoy; + class GBVideo { SDL_Surface *display; @@ -35,4 +40,5 @@ class GBVideo }; +#endif diff --git a/Makefile b/Makefile index dabd46a..927c588 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ all: tests tests: tests/test_gbrom tests/test_core -GBVideo.o: GBVideo.cc GBVideo.h Logger.h +GBVideo.o: GBVideo.cc GBVideo.h Logger.h util.h g++ $(CXXFLAGS) -c -o $@ $< GBMemory.o: GBMemory.cc GBMemory.h Logger.h diff --git a/util.h b/util.h new file mode 100644 index 0000000..65a551f --- /dev/null +++ b/util.h @@ -0,0 +1,31 @@ +#ifndef UTIL_H +#define UTIL_H + +#include "sized_types.h" + +uint32 set_bit(uint32 pos, uint32 val) +{ + uint32 mask = 1<