From: slack Date: Sat, 12 Jul 2008 18:29:13 +0000 (+0200) Subject: Check if VRAM or OAM are busy before accessing them. X-Git-Tag: v0.1~24 X-Git-Url: http://slack.codemaniacs.com/git/?a=commitdiff_plain;h=8fa672580292224f814e8958029aaa8be6412f93;p=wenboi.git Check if VRAM or OAM are busy before accessing them. Also, cycles_to_next_video_update in core was moved to cycles_to_next_update in video. --- diff --git a/GBVideo.cc b/GBVideo.cc index cbf778d..ac11a1a 100644 --- a/GBVideo.cc +++ b/GBVideo.cc @@ -10,14 +10,17 @@ GBVideo::GBVideo(GameBoy *core): display(0), core(core), + cur_window_line(0), + mode(2), OAM(), + OAM_BUSY(false), + VRAM_BUSY(false), frames_rendered(0), t0(0), t_last_frame(0), oldscreen(0), newscreen(0), - cur_window_line(0), - mode(2), - display_mode(NORMAL) + display_mode(NORMAL), + cycles_until_next_update(0) { SDL_Init(SDL_INIT_VIDEO); display=SDL_SetVideoMode(320,288,32,SDL_SWSURFACE | SDL_DOUBLEBUF); @@ -43,6 +46,11 @@ GBVideo::~GBVideo() delete [] newscreen; } +void GBVideo::reset() +{ + cycles_until_next_update = 0; +} + #if 0 u8 GBVideo::read_VRAM (int addr) const { @@ -118,7 +126,6 @@ u32 GBVideo::update() // mode 0 starts at 252, 708, 1164... // vblank starts at 65664 - int cycles_until_next_update=0; int STAT = core->memory.high[GBMemory::I_STAT]; int LYC = core->memory.high[GBMemory::I_LYC]; int LY = core->memory.high[GBMemory::I_LY]; @@ -128,6 +135,8 @@ u32 GBVideo::update() case 0: // HBlank (preserve bits 2-6, mode = 0) STAT = (STAT&0xFC); + OAM_BUSY = false; + VRAM_BUSY = false; if (check_bit(STAT, 3)) { logger.trace("Requesting IRQ_LCD_STAT -- HBLANK"); @@ -140,6 +149,8 @@ u32 GBVideo::update() mode = 2; break; case 1: + OAM_BUSY = false; + VRAM_BUSY = false; if (LY == 144) { logger.trace("Requesting IRQ_VBLANK"); @@ -200,6 +211,8 @@ u32 GBVideo::update() mode = 1; break; case 2: { + OAM_BUSY = true; + VRAM_BUSY = false; if (LY == LYC) { STAT = set_bit(STAT, 2); // set coincidence flag @@ -224,6 +237,8 @@ u32 GBVideo::update() break; } case 3: + OAM_BUSY = false; + VRAM_BUSY = true; draw(); // preserve bits 2-6, set mode 3 STAT = (STAT&0xFC) | 3; diff --git a/GBVideo.h b/GBVideo.h index c7604a6..6047131 100644 --- a/GBVideo.h +++ b/GBVideo.h @@ -23,9 +23,6 @@ class GBVideo bool operator< (const Sprite& other) const { return (x < other.x); } }; - SDL_Surface *display; - GameBoy *core; - u8 VRAM[8192]; union { u8 raw[160]; @@ -36,6 +33,15 @@ class GBVideo EIGHT_BY_EIGHT=0, EIGHT_BY_SIXTEEN=1, }; + + + SDL_Surface *display; + GameBoy *core; + + u8 cur_window_line; + int mode; + bool OAM_BUSY; + bool VRAM_BUSY; u32 colors[4]; u32 frames_rendered; @@ -43,9 +49,6 @@ class GBVideo u32 t_last_frame; u8 *oldscreen, *newscreen; - u8 cur_window_line; - int mode; - public: enum DisplayMode { NORMAL = 0, @@ -57,19 +60,49 @@ class GBVideo DisplayMode display_mode; public: + int cycles_until_next_update; static const u16 VRAM_BASE = 0x8000; static const u16 OAM_BASE = 0xFE00; GBVideo(GameBoy *core); ~GBVideo(); + void reset(); + // VRAM/OAM access - inline u8 read_VRAM (int addr) const { return VRAM[addr-VRAM_BASE]; } - inline u8 read_OAM (int addr) const { return OAM.raw[addr-OAM_BASE]; } - inline u16 read16_VRAM (int addr) const { return VRAM[addr-VRAM_BASE]+(VRAM[addr-VRAM_BASE+1] << 8); } - inline u16 read16_OAM (int addr) const { return OAM.raw[addr-OAM_BASE]+(OAM.raw[addr-OAM_BASE+1] << 8); } - inline void write_VRAM(int addr, u8 value) { VRAM[addr-VRAM_BASE] = value; } - inline void write_OAM (int addr, u8 value) { OAM.raw[addr-OAM_BASE] = value; } + inline u8 read_VRAM (int addr) const + { + if (!VRAM_BUSY) return VRAM[addr-VRAM_BASE]; + else return 0xFF; + } + + inline u8 read_OAM (int addr) const + { + if (!OAM_BUSY) return OAM.raw[addr-OAM_BASE]; + else return 0xFF; + } + + inline u16 read16_VRAM (int addr) const + { + if (!VRAM_BUSY) return VRAM[addr-VRAM_BASE]+(VRAM[addr-VRAM_BASE+1] << 8); + else return 0xFF; + } + + inline u16 read16_OAM (int addr) const + { + if (!OAM_BUSY) return OAM.raw[addr-OAM_BASE]+(OAM.raw[addr-OAM_BASE+1] << 8); + else return 0xFF; + } + + inline void write_VRAM(int addr, u8 value) + { + if (!VRAM_BUSY) VRAM[addr-VRAM_BASE] = value; + } + + inline void write_OAM (int addr, u8 value) + { + if (!OAM_BUSY) OAM.raw[addr-OAM_BASE] = value; + } // drawing control void draw(); diff --git a/gbcore.cc b/gbcore.cc index 90e40ba..62d72c7 100644 --- a/gbcore.cc +++ b/gbcore.cc @@ -19,7 +19,6 @@ GameBoy::GameBoy(std::string rom_name, GameBoyType type): HALT(0), STOP(0), cycle_count(0), - cycles_until_video_update(0), cycles_until_next_instruction(0), divider_count(0), timer_count(0), @@ -41,9 +40,10 @@ void GameBoy::reset() IME = 1; HALT = 0; cycle_count = 0; - cycles_until_video_update = 0; cycles_until_next_instruction = 0; + video.reset(); + regs.PC = 0x0100; regs.AF = 0x01B0; regs.BC = 0x0013; @@ -1319,9 +1319,9 @@ GameBoy::run_status GameBoy::run_cycle() } // Video - if (cycles_until_video_update <= 0) - cycles_until_video_update = video.update(); - cycles_until_video_update -= CYCLE_STEP; + if (video.cycles_until_next_update <= 0) + video.update(); + video.cycles_until_next_update -= CYCLE_STEP; // Divider divider_count++; diff --git a/gbcore.h b/gbcore.h index d8bf8bb..699e68d 100644 --- a/gbcore.h +++ b/gbcore.h @@ -71,7 +71,6 @@ class GameBoy u8 STOP; // Is the CPU & LCD halted waiting for a keypress? u32 cycle_count; - u32 cycles_until_video_update; u32 cycles_until_next_instruction; u8 divider_count; // resets every 256 cycles, so we don't need a cmp u32 timer_count;