diff options
author | StapleButter <thetotalworm@gmail.com> | 2017-01-18 04:03:19 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2017-01-18 04:03:19 +0100 |
commit | d30e6956fa59182a23941a535d5f6c2bf515918a (patch) | |
tree | b4526c883a33f53579647faf6aa0f6c594ef2881 | |
parent | bff3a92cc02b6a7270b87f02d6f6ebd322a5ecb5 (diff) |
skeleton for 2D GPU
-rw-r--r-- | DMA.cpp | 2 | ||||
-rw-r--r-- | GPU.cpp | 773 | ||||
-rw-r--r-- | GPU.h | 67 | ||||
-rw-r--r-- | GPU2D.cpp | 726 | ||||
-rw-r--r-- | GPU2D.h | 49 | ||||
-rw-r--r-- | NDS.cpp | 239 | ||||
-rw-r--r-- | main.cpp | 4 | ||||
-rw-r--r-- | melonDS.depend | 27 |
8 files changed, 1062 insertions, 825 deletions
@@ -86,6 +86,8 @@ void DMA::WriteCnt(u32 val) if ((StartMode & 0x7) == 0) Start(); + else + printf("SPECIAL ARM%d DMA%d START MODE %02X\n", CPU?7:9, Num, StartMode); } } @@ -0,0 +1,773 @@ +/* + Copyright 2016-2017 StapleButter + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include <stdio.h> +#include <string.h> +#include "NDS.h" +#include "GPU.h" + + +namespace GPU +{ + +#define LINE_CYCLES (355*6 * 2) +#define FRAME_CYCLES (LINE_CYCLES * 263) + +u16 VCount; + +u16 DispStat[2], VMatch[2]; + +u8 Palette[2*1024]; +u8 OAM[2*1024]; + +u8 VRAM_A[128*1024]; +u8 VRAM_B[128*1024]; +u8 VRAM_C[128*1024]; +u8 VRAM_D[128*1024]; +u8 VRAM_E[ 64*1024]; +u8 VRAM_F[ 16*1024]; +u8 VRAM_G[ 16*1024]; +u8 VRAM_H[ 32*1024]; +u8 VRAM_I[ 16*1024]; +u8* VRAM[9] = {VRAM_A, VRAM_B, VRAM_C, VRAM_D, VRAM_E, VRAM_F, VRAM_G, VRAM_H, VRAM_I}; + +u8 VRAMCNT[9]; +u8 VRAMSTAT; + +u8* VRAM_ABG[128]; +u8* VRAM_AOBJ[128]; +u8* VRAM_BBG[128]; +u8* VRAM_BOBJ[128]; +u8* VRAM_LCD[128]; +u8* VRAM_ARM7[2]; + +u16 Framebuffer[256*192*2]; + +GPU2D* GPU2D_A; +GPU2D* GPU2D_B; + + +void Init() +{ + GPU2D_A = new GPU2D(0); + GPU2D_B = new GPU2D(1); +} + +void Reset() +{ + VCount = 0; + + DispStat[0] = 0; + DispStat[1] = 0; + VMatch[0] = 0; + VMatch[1] = 0; + + memset(Palette, 0, 2*1024); + memset(OAM, 0, 2*1024); + + memset(VRAM_A, 0, 128*1024); + memset(VRAM_B, 0, 128*1024); + memset(VRAM_C, 0, 128*1024); + memset(VRAM_D, 0, 128*1024); + memset(VRAM_E, 0, 64*1024); + memset(VRAM_F, 0, 16*1024); + memset(VRAM_G, 0, 16*1024); + memset(VRAM_H, 0, 32*1024); + memset(VRAM_I, 0, 16*1024); + + memset(VRAMCNT, 0, 9); + VRAMSTAT = 0; + + memset(VRAM_ABG, 0, sizeof(u8*)*128); + memset(VRAM_AOBJ, 0, sizeof(u8*)*128); + memset(VRAM_BBG, 0, sizeof(u8*)*128); + memset(VRAM_BOBJ, 0, sizeof(u8*)*128); + memset(VRAM_LCD, 0, sizeof(u8*)*128); + memset(VRAM_ARM7, 0, sizeof(u8*)*2); + + for (int i = 0; i < 256*192*2; i++) + { + Framebuffer[i] = 0x7FFF; + } + + GPU2D_A->Reset(); + GPU2D_B->Reset(); + + GPU2D_A->SetFramebuffer(&Framebuffer[0*192]); + GPU2D_B->SetFramebuffer(&Framebuffer[256*192]); +} + + +// VRAM mapping shit. +// TODO eventually: work out priority orders in case of overlaps. there _are_ games that map overlapping banks. + +void MapVRAM_AB(u32 bank, u8 cnt) +{ + u8 oldcnt = VRAMCNT[bank]; + VRAMCNT[bank] = cnt; + + if (oldcnt == cnt) return; + + u8 oldofs = (oldcnt >> 3) & 0x3; + u8 ofs = (cnt >> 3) & 0x3; + + u8* vram = VRAM[bank]; + + if (oldcnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (oldcnt & 0x3) + { + case 0: + vrammap = &VRAM_LCD[bank<<3]; + break; + + case 1: + vrammap = &VRAM_ABG[oldofs<<3]; + break; + + case 2: + oldofs &= 0x1; + vrammap = &VRAM_AOBJ[oldofs<<3]; + break; + + case 3: + // not mapped to memory + break; + } + + if (vrammap) + { + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap = NULL; + } + } + + if (cnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (cnt & 0x3) + { + case 0: + vrammap = &VRAM_LCD[bank<<3]; + break; + + case 1: + vrammap = &VRAM_ABG[ofs<<3]; + break; + + case 2: + ofs &= 0x1; + vrammap = &VRAM_AOBJ[ofs<<3]; + break; + + case 3: + // not mapped to memory + break; + } + + if (vrammap) + { + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap = vram; + } + } +} + +void MapVRAM_CD(u32 bank, u8 cnt) +{ + u8 oldcnt = VRAMCNT[bank]; + VRAMCNT[bank] = cnt; + + VRAMSTAT &= ~(1 << (bank-2)); + + if (oldcnt == cnt) return; + + u8 oldofs = (oldcnt >> 3) & 0x7; + u8 ofs = (cnt >> 3) & 0x7; + + u8* vram = VRAM[bank]; + + if (oldcnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (oldcnt & 0x7) + { + case 0: + vrammap = &VRAM_LCD[bank<<3]; + break; + + case 1: + vrammap = &VRAM_ABG[oldofs<<3]; + break; + + case 2: + oldofs &= 0x1; + VRAM_ARM7[oldofs] = NULL; + break; + + case 3: + // not mapped to memory + break; + + case 4: + if (bank == 2) + vrammap = &VRAM_BBG[0]; + else + vrammap = &VRAM_BOBJ[0]; + break; + } + + if (vrammap) + { + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap = NULL; + } + } + + if (cnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (cnt & 0x7) + { + case 0: + vrammap = &VRAM_LCD[bank<<3]; + break; + + case 1: + vrammap = &VRAM_ABG[ofs<<3]; + break; + + case 2: + ofs &= 0x1; + VRAM_ARM7[ofs] = vram; + VRAMSTAT |= (1 << (bank-2)); + break; + + case 3: + // not mapped to memory + break; + + case 4: + if (bank == 2) + vrammap = &VRAM_BBG[0]; + else + vrammap = &VRAM_BOBJ[0]; + break; + } + + if (vrammap) + { + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap++ = vram; vram += 0x4000; + *vrammap = vram; + } + } +} + +void MapVRAM_E(u32 bank, u8 cnt) +{ + u8 oldcnt = VRAMCNT[bank]; + VRAMCNT[bank] = cnt; + + if (oldcnt == cnt) return; + + u8 oldofs = (oldcnt >> 3) & 0x7; + u8 ofs = (cnt >> 3) & 0x7; + + u8* vram = VRAM[bank]; + + if (oldcnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (oldcnt & 0x7) + { + case 0: + VRAM_LCD[0x20] = NULL; + VRAM_LCD[0x21] = NULL; + VRAM_LCD[0x22] = NULL; + VRAM_LCD[0x23] = NULL; + break; + + case 1: + vrammap = &VRAM_ABG[0]; + break; + + case 2: + vrammap = &VRAM_AOBJ[0]; + break; + + case 3: + // not mapped to memory + break; + + case 4: + // BG EXTPAL -- TODO + break; + + case 5: + // OBJ EXTPAL -- TODO + break; + } + + if (vrammap) + { + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap = NULL; + } + } + + if (cnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (cnt & 0x7) + { + case 0: + VRAM_LCD[0x20] = &vram[0x0000]; + VRAM_LCD[0x21] = &vram[0x4000]; + VRAM_LCD[0x22] = &vram[0x8000]; + VRAM_LCD[0x23] = &vram[0xC000]; + break; + + case 1: + vrammap = &VRAM_ABG[0]; + break; + + case 2: + vrammap = &VRAM_AOBJ[0]; + break; + + case 3: + // not mapped to memory + break; + + case 4: + // BG EXTPAL -- TODO + break; + + case 5: + // OBJ EXTPAL -- TODO + break; + } + + if (vrammap) + { + *vrammap++ = &vram[0x0000]; + *vrammap++ = &vram[0x4000]; + *vrammap++ = &vram[0x8000]; + *vrammap++ = &vram[0xC000]; + *vrammap++ = &vram[0x0000]; + *vrammap++ = &vram[0x4000]; + *vrammap++ = &vram[0x8000]; + *vrammap = &vram[0xC000]; + } + } +} + +void MapVRAM_FG(u32 bank, u8 cnt) +{ + u8 oldcnt = VRAMCNT[bank]; + VRAMCNT[bank] = cnt; + + if (oldcnt == cnt) return; + + u8 oldofs = (oldcnt >> 3) & 0x7; + u8 ofs = (cnt >> 3) & 0x7; + + u8* vram = VRAM[bank]; + bank -= 5; + + if (oldcnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (oldcnt & 0x7) + { + case 0: + VRAM_LCD[0x24 + bank] = NULL; + break; + + case 1: + vrammap = &VRAM_ABG[(oldofs & 0x1) | ((oldofs & 0x2) << 1)]; + break; + + case 2: + vrammap = &VRAM_AOBJ[(oldofs & 0x1) | ((oldofs & 0x2) << 1)]; + break; + + case 3: + // not mapped to memory + break; + + case 4: + // BG EXTPAL TODO + break; + + case 5: + // OBJ EXTPAL TODO + break; + } + + if (vrammap) + { + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap = NULL; + } + } + + if (cnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (cnt & 0x7) + { + case 0: + VRAM_LCD[0x24 + bank] = vram; + break; + + case 1: + vrammap = &VRAM_ABG[(ofs & 0x1) | ((ofs & 0x2) << 1)]; + break; + + case 2: + vrammap = &VRAM_AOBJ[(ofs & 0x1) | ((ofs & 0x2) << 1)]; + break; + + case 3: + // not mapped to memory + break; + + case 4: + // BG EXTPAL TODO + break; + + case 5: + // OBJ EXTPAL TODO + break; + } + + if (vrammap) + { + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap = vram; + } + } +} + +void MapVRAM_H(u32 bank, u8 cnt) +{ + u8 oldcnt = VRAMCNT[bank]; + VRAMCNT[bank] = cnt; + + if (oldcnt == cnt) return; + + u8 oldofs = (oldcnt >> 3) & 0x7; + u8 ofs = (cnt >> 3) & 0x7; + + u8* vram = VRAM[bank]; + + if (oldcnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (oldcnt & 0x3) + { + case 0: + VRAM_LCD[0x26] = NULL; + VRAM_LCD[0x27] = NULL; + break; + + case 1: + vrammap = &VRAM_BBG[0x00]; + break; + + case 2: + // BG EXTPAL TODO + break; + } + + if (vrammap) + { + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap = NULL; + } + } + + if (cnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (cnt & 0x3) + { + case 0: + VRAM_LCD[0x26] = &vram[0x0000]; + VRAM_LCD[0x27] = &vram[0x4000]; + break; + + case 1: + vrammap = &VRAM_BBG[0x00]; + break; + + case 2: + // BG EXTPAL TODO + break; + } + + if (vrammap) + { + *vrammap++ = &vram[0x0000]; + *vrammap++ = &vram[0x4000]; + *vrammap++ = &vram[0x0000]; + *vrammap++ = &vram[0x4000]; + *vrammap++ = &vram[0x0000]; + *vrammap++ = &vram[0x4000]; + *vrammap++ = &vram[0x0000]; + *vrammap = &vram[0x4000]; + } + } +} + +void MapVRAM_I(u32 bank, u8 cnt) +{ + u8 oldcnt = VRAMCNT[bank]; + VRAMCNT[bank] = cnt; + + if (oldcnt == cnt) return; + + u8 oldofs = (oldcnt >> 3) & 0x7; + u8 ofs = (cnt >> 3) & 0x7; + + u8* vram = VRAM[bank]; + bank -= 5; + + if (oldcnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (oldcnt & 0x3) + { + case 0: + VRAM_LCD[0x28] = NULL; + break; + + case 1: + vrammap = &VRAM_BBG[0x02]; + break; + + case 2: + vrammap = &VRAM_BOBJ[0x00]; + break; + + case 3: + // not mapped to memory + break; + } + + if (vrammap) + { + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap++ = NULL; + *vrammap = NULL; + } + } + + if (cnt & (1<<7)) + { + u8** vrammap = NULL; + + switch (cnt & 0x3) + { + case 0: + VRAM_LCD[0x28] = vram; + break; + + case 1: + vrammap = &VRAM_BBG[0x02]; + break; + + case 2: + vrammap = &VRAM_BOBJ[0x00]; + break; + + case 3: + // not mapped to memory + break; + } + + if (vrammap) + { + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap++ = vram; + *vrammap = vram; + } + } +} + + +void DrawScanline(u32 screen, u32 line) +{ + u16* dst = &Framebuffer[256 * ((192*screen) + line)]; + + if (screen==0) + { + u16* src = &((u16*)VRAM_A)[256*line]; + for (int i = 0; i < 256; i++) + dst[i] = src[i]; + } + else + { + for (int i = 0; i < 256; i++) + dst[i] = 0x7FFF; + } +} + + +void StartFrame() +{ + StartScanline(0); +} + +void StartScanline(u32 line) +{ + VCount = line; + + if (line == VMatch[0]) + { + DispStat[0] |= (1<<2); + + if (DispStat[0] & (1<<5)) NDS::TriggerIRQ(0, NDS::IRQ_VCount); + } + else + DispStat[0] &= ~(1<<2); + + if (line == VMatch[1]) + { + DispStat[1] |= (1<<2); + + if (DispStat[1] & (1<<5)) NDS::TriggerIRQ(1, NDS::IRQ_VCount); + } + else + DispStat[1] &= ~(1<<2); + + if (line < 192) + { + // draw + DrawScanline(0, line); + DrawScanline(1, line); + + NDS::ScheduleEvent(LINE_CYCLES, StartScanline, line+1); + } + else if (line == 262) + { + // frame end + + DispStat[0] &= ~(1<<0); + DispStat[1] &= ~(1<<0); + } + else + { + if (line == 192) + { + // VBlank + DispStat[0] |= (1<<0); + DispStat[1] |= (1<<0); + + if (DispStat[0] & (1<<3)) NDS::TriggerIRQ(0, NDS::IRQ_VBlank); + if (DispStat[1] & (1<<3)) NDS::TriggerIRQ(1, NDS::IRQ_VBlank); + } + + NDS::ScheduleEvent(LINE_CYCLES, StartScanline, line+1); + } +} + + +void SetDispStat(u32 cpu, u16 val) +{ + val &= 0xFFB8; + DispStat[cpu] &= 0x0047; + DispStat[cpu] |= val; + + VMatch[cpu] = (val >> 8) | ((val & 0x80) << 1); + + if (val & 0x10) printf("!! HBLANK ENABLED\n"); +} + +} @@ -0,0 +1,67 @@ +/* + Copyright 2016-2017 StapleButter + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef GPU_H +#define GPU_H + +#include "GPU2D.h" + +namespace GPU +{ + +extern u16 VCount; + +extern u16 DispStat[2]; + +extern u8 VRAMCNT[9]; +extern u8 VRAMSTAT; + +extern u8 Palette[2*1024]; +extern u8 OAM[2*1024]; + +extern u8* VRAM_ABG[128]; +extern u8* VRAM_AOBJ[128]; +extern u8* VRAM_BBG[128]; +extern u8* VRAM_BOBJ[128]; +extern u8* VRAM_LCD[128]; +extern u8* VRAM_ARM7[2]; + +extern u16 Framebuffer[256*192*2]; + +extern GPU2D* GPU2D_A; +extern GPU2D* GPU2D_B; + + +void Init(); +void Reset(); + +void MapVRAM_AB(u32 bank, u8 cnt); +void MapVRAM_CD(u32 bank, u8 cnt); +void MapVRAM_E(u32 bank, u8 cnt); +void MapVRAM_FG(u32 bank, u8 cnt); +void MapVRAM_H(u32 bank, u8 cnt); +void MapVRAM_I(u32 bank, u8 cnt); + +void StartFrame(); +void StartScanline(u32 line); + +void SetDispStat(u32 cpu, u16 val); + +} + +#endif @@ -17,742 +17,82 @@ */ #include <stdio.h> -#include <string.h> #include "NDS.h" +#include "GPU.h" #include "GPU2D.h" -namespace GPU2D +GPU2D::GPU2D(u32 num) { - -#define LINE_CYCLES (355*6 * 2) -#define FRAME_CYCLES (LINE_CYCLES * 263) - -u16 VCount; - -u16 DispStat[2], VMatch[2]; - -u8 Palette[2*1024]; -u8 OAM[2*1024]; - -u8 VRAM_A[128*1024]; -u8 VRAM_B[128*1024]; -u8 VRAM_C[128*1024]; -u8 VRAM_D[128*1024]; -u8 VRAM_E[ 64*1024]; -u8 VRAM_F[ 16*1024]; -u8 VRAM_G[ 16*1024]; -u8 VRAM_H[ 32*1024]; -u8 VRAM_I[ 16*1024]; -u8* VRAM[9] = {VRAM_A, VRAM_B, VRAM_C, VRAM_D, VRAM_E, VRAM_F, VRAM_G, VRAM_H, VRAM_I}; - -u8 VRAMCNT[9]; -u8 VRAMSTAT; - -u8* VRAM_ABG[128]; -u8* VRAM_AOBJ[128]; -u8* VRAM_BBG[128]; -u8* VRAM_BOBJ[128]; -u8* VRAM_LCD[128]; -u8* VRAM_ARM7[2]; - -u16 Framebuffer[256*192*2]; - - -void Reset() -{ - VCount = 0; - - DispStat[0] = 0; - DispStat[1] = 0; - VMatch[0] = 0; - VMatch[1] = 0; - - memset(Palette, 0, 2*1024); - memset(OAM, 0, 2*1024); - - memset(VRAM_A, 0, 128*1024); - memset(VRAM_B, 0, 128*1024); - memset(VRAM_C, 0, 128*1024); - memset(VRAM_D, 0, 128*1024); - memset(VRAM_E, 0, 64*1024); - memset(VRAM_F, 0, 16*1024); - memset(VRAM_G, 0, 16*1024); - memset(VRAM_H, 0, 32*1024); - memset(VRAM_I, 0, 16*1024); - - memset(VRAMCNT, 0, 9); - VRAMSTAT = 0; - - memset(VRAM_ABG, 0, sizeof(u8*)*128); - memset(VRAM_AOBJ, 0, sizeof(u8*)*128); - memset(VRAM_BBG, 0, sizeof(u8*)*128); - memset(VRAM_BOBJ, 0, sizeof(u8*)*128); - memset(VRAM_LCD, 0, sizeof(u8*)*128); - memset(VRAM_ARM7, 0, sizeof(u8*)*2); - - for (int i = 0; i < 256*192*2; i++) - { - Framebuffer[i] = (i>=256*192)?0x03E0:0x7C00; - } + Num = num; } - -// VRAM mapping shit. -// TODO eventually: work out priority orders in case of overlaps. there _are_ games that map overlapping banks. - -void MapVRAM_AB(u32 bank, u8 cnt) +GPU2D::~GPU2D() { - u8 oldcnt = VRAMCNT[bank]; - VRAMCNT[bank] = cnt; - - if (oldcnt == cnt) return; - - u8 oldofs = (oldcnt >> 3) & 0x3; - u8 ofs = (cnt >> 3) & 0x3; - - u8* vram = VRAM[bank]; - - if (oldcnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (oldcnt & 0x3) - { - case 0: - vrammap = &VRAM_LCD[bank<<3]; - break; - - case 1: - vrammap = &VRAM_ABG[oldofs<<3]; - break; - - case 2: - oldofs &= 0x1; - vrammap = &VRAM_AOBJ[oldofs<<3]; - break; - - case 3: - // not mapped to memory - break; - } - - if (vrammap) - { - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap = NULL; - } - } - - if (cnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (cnt & 0x3) - { - case 0: - vrammap = &VRAM_LCD[bank<<3]; - break; - - case 1: - vrammap = &VRAM_ABG[ofs<<3]; - break; - - case 2: - ofs &= 0x1; - vrammap = &VRAM_AOBJ[ofs<<3]; - break; - - case 3: - // not mapped to memory - break; - } - - if (vrammap) - { - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap = vram; - } - } } -void MapVRAM_CD(u32 bank, u8 cnt) +void GPU2D::Reset() { - u8 oldcnt = VRAMCNT[bank]; - VRAMCNT[bank] = cnt; - - VRAMSTAT &= ~(1 << (bank-2)); - - if (oldcnt == cnt) return; - - u8 oldofs = (oldcnt >> 3) & 0x7; - u8 ofs = (cnt >> 3) & 0x7; - - u8* vram = VRAM[bank]; - - if (oldcnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (oldcnt & 0x7) - { - case 0: - vrammap = &VRAM_LCD[bank<<3]; - break; - - case 1: - vrammap = &VRAM_ABG[oldofs<<3]; - break; - - case 2: - oldofs &= 0x1; - VRAM_ARM7[oldofs] = NULL; - break; - - case 3: - // not mapped to memory - break; - - case 4: - if (bank == 2) - vrammap = &VRAM_BBG[0]; - else - vrammap = &VRAM_BOBJ[0]; - break; - } - - if (vrammap) - { - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap = NULL; - } - } - - if (cnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (cnt & 0x7) - { - case 0: - vrammap = &VRAM_LCD[bank<<3]; - break; - - case 1: - vrammap = &VRAM_ABG[ofs<<3]; - break; - - case 2: - ofs &= 0x1; - VRAM_ARM7[ofs] = vram; - VRAMSTAT |= (1 << (bank-2)); - break; - - case 3: - // not mapped to memory - break; - - case 4: - if (bank == 2) - vrammap = &VRAM_BBG[0]; - else - vrammap = &VRAM_BOBJ[0]; - break; - } - - if (vrammap) - { - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap++ = vram; vram += 0x4000; - *vrammap = vram; - } - } + // } -void MapVRAM_E(u32 bank, u8 cnt) +void GPU2D::SetFramebuffer(u16* buf) { - u8 oldcnt = VRAMCNT[bank]; - VRAMCNT[bank] = cnt; - - if (oldcnt == cnt) return; - - u8 oldofs = (oldcnt >> 3) & 0x7; - u8 ofs = (cnt >> 3) & 0x7; - - u8* vram = VRAM[bank]; - - if (oldcnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (oldcnt & 0x7) - { - case 0: - VRAM_LCD[0x20] = NULL; - VRAM_LCD[0x21] = NULL; - VRAM_LCD[0x22] = NULL; - VRAM_LCD[0x23] = NULL; - break; - - case 1: - vrammap = &VRAM_ABG[0]; - break; - - case 2: - vrammap = &VRAM_AOBJ[0]; - break; - - case 3: - // not mapped to memory - break; - - case 4: - // BG EXTPAL -- TODO - break; - - case 5: - // OBJ EXTPAL -- TODO - break; - } - - if (vrammap) - { - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap = NULL; - } - } - - if (cnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (cnt & 0x7) - { - case 0: - VRAM_LCD[0x20] = &vram[0x0000]; - VRAM_LCD[0x21] = &vram[0x4000]; - VRAM_LCD[0x22] = &vram[0x8000]; - VRAM_LCD[0x23] = &vram[0xC000]; - break; - - case 1: - vrammap = &VRAM_ABG[0]; - break; - - case 2: - vrammap = &VRAM_AOBJ[0]; - break; - - case 3: - // not mapped to memory - break; - - case 4: - // BG EXTPAL -- TODO - break; + // framebuffer is 256x192 16bit. + // might eventually support other framebuffer types/sizes + Framebuffer = buf; +} - case 5: - // OBJ EXTPAL -- TODO - break; - } - if (vrammap) - { - *vrammap++ = &vram[0x0000]; - *vrammap++ = &vram[0x4000]; - *vrammap++ = &vram[0x8000]; - *vrammap++ = &vram[0xC000]; - *vrammap++ = &vram[0x0000]; - *vrammap++ = &vram[0x4000]; - *vrammap++ = &vram[0x8000]; - *vrammap = &vram[0xC000]; - } - } +u8 GPU2D::Read8(u32 addr) +{ + printf("!! GPU2D READ8 %08X\n", addr); } -void MapVRAM_FG(u32 bank, u8 cnt) +u16 GPU2D::Read16(u32 addr) { - u8 oldcnt = VRAMCNT[bank]; - VRAMCNT[bank] = cnt; - - if (oldcnt == cnt) return; - - u8 oldofs = (oldcnt >> 3) & 0x7; - u8 ofs = (cnt >> 3) & 0x7; - - u8* vram = VRAM[bank]; - bank -= 5; - - if (oldcnt & (1<<7)) + switch (addr & 0x00000FFF) { - u8** vrammap = NULL; - - switch (oldcnt & 0x7) - { - case 0: - VRAM_LCD[0x24 + bank] = NULL; - break; - - case 1: - vrammap = &VRAM_ABG[(oldofs & 0x1) | ((oldofs & 0x2) << 1)]; - break; - - case 2: - vrammap = &VRAM_AOBJ[(oldofs & 0x1) | ((oldofs & 0x2) << 1)]; - break; - - case 3: - // not mapped to memory - break; - - case 4: - // BG EXTPAL TODO - break; - - case 5: - // OBJ EXTPAL TODO - break; - } - - if (vrammap) - { - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap = NULL; - } - } - - if (cnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (cnt & 0x7) - { - case 0: - VRAM_LCD[0x24 + bank] = vram; - break; - - case 1: - vrammap = &VRAM_ABG[(ofs & 0x1) | ((ofs & 0x2) << 1)]; - break; - - case 2: - vrammap = &VRAM_AOBJ[(ofs & 0x1) | ((ofs & 0x2) << 1)]; - break; - - case 3: - // not mapped to memory - break; - - case 4: - // BG EXTPAL TODO - break; - - case 5: - // OBJ EXTPAL TODO - break; - } - - if (vrammap) - { - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap = vram; - } + // } } -void MapVRAM_H(u32 bank, u8 cnt) +u32 GPU2D::Read32(u32 addr) { - u8 oldcnt = VRAMCNT[bank]; - VRAMCNT[bank] = cnt; - - if (oldcnt == cnt) return; - - u8 oldofs = (oldcnt >> 3) & 0x7; - u8 ofs = (cnt >> 3) & 0x7; - - u8* vram = VRAM[bank]; - - if (oldcnt & (1<<7)) + switch (addr & 0x00000FFF) { - u8** vrammap = NULL; - - switch (oldcnt & 0x3) - { - case 0: - VRAM_LCD[0x26] = NULL; - VRAM_LCD[0x27] = NULL; - break; - - case 1: - vrammap = &VRAM_BBG[0x00]; - break; - - case 2: - // BG EXTPAL TODO - break; - } - - if (vrammap) - { - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap = NULL; - } + // } - if (cnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (cnt & 0x3) - { - case 0: - VRAM_LCD[0x26] = &vram[0x0000]; - VRAM_LCD[0x27] = &vram[0x4000]; - break; - - case 1: - vrammap = &VRAM_BBG[0x00]; - break; - - case 2: - // BG EXTPAL TODO - break; - } - - if (vrammap) - { - *vrammap++ = &vram[0x0000]; - *vrammap++ = &vram[0x4000]; - *vrammap++ = &vram[0x0000]; - *vrammap++ = &vram[0x4000]; - *vrammap++ = &vram[0x0000]; - *vrammap++ = &vram[0x4000]; - *vrammap++ = &vram[0x0000]; - *vrammap = &vram[0x4000]; - } - } + return Read16(addr) | (Read16(addr+2) << 16); } -void MapVRAM_I(u32 bank, u8 cnt) +void GPU2D::Write8(u32 addr, u8 val) { - u8 oldcnt = VRAMCNT[bank]; - VRAMCNT[bank] = cnt; - - if (oldcnt == cnt) return; - - u8 oldofs = (oldcnt >> 3) & 0x7; - u8 ofs = (cnt >> 3) & 0x7; - - u8* vram = VRAM[bank]; - bank -= 5; - - if (oldcnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (oldcnt & 0x3) - { - case 0: - VRAM_LCD[0x28] = NULL; - break; - - case 1: - vrammap = &VRAM_BBG[0x02]; - break; - - case 2: - vrammap = &VRAM_BOBJ[0x00]; - break; - - case 3: - // not mapped to memory - break; - } - - if (vrammap) - { - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap++ = NULL; - *vrammap = NULL; - } - } - - if (cnt & (1<<7)) - { - u8** vrammap = NULL; - - switch (cnt & 0x3) - { - case 0: - VRAM_LCD[0x28] = vram; - break; - - case 1: - vrammap = &VRAM_BBG[0x02]; - break; - - case 2: - vrammap = &VRAM_BOBJ[0x00]; - break; - - case 3: - // not mapped to memory - break; - } - - if (vrammap) - { - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap++ = vram; - *vrammap = vram; - } - } + printf("!! GPU2D WRITE8 %08X %02X\n", addr, val); } - -void DrawScanline(u32 screen, u32 line) +void GPU2D::Write16(u32 addr, u16 val) { - u16* dst = &Framebuffer[256 * ((192*screen) + line)]; - - if (screen==0) - { - u16* src = &((u16*)VRAM_A)[256*line]; - for (int i = 0; i < 256; i++) - dst[i] = src[i]; - } - else + switch (addr & 0x00000FFF) { - for (int i = 0; i < 256; i++) - dst[i] = 0x7FFF; + // } } - -void StartFrame() -{ - StartScanline(0); -} - -void StartScanline(u32 line) +void GPU2D::Write32(u32 addr, u32 val) { - VCount = line; - - if (line == VMatch[0]) - { - DispStat[0] |= (1<<2); - - if (DispStat[0] & (1<<5)) NDS::TriggerIRQ(0, NDS::IRQ_VCount); - } - else - DispStat[0] &= ~(1<<2); - - if (line == VMatch[1]) - { - DispStat[1] |= (1<<2); - - if (DispStat[1] & (1<<5)) NDS::TriggerIRQ(1, NDS::IRQ_VCount); - } - else - DispStat[1] &= ~(1<<2); - - if (line < 192) - { - // draw - DrawScanline(0, line); - DrawScanline(1, line); - - NDS::ScheduleEvent(LINE_CYCLES, StartScanline, line+1); - } - else if (line == 262) + switch (addr & 0x00000FFF) { - // frame end - - DispStat[0] &= ~(1<<0); - DispStat[1] &= ~(1<<0); + // } - else - { - if (line == 192) - { - // VBlank - DispStat[0] |= (1<<0); - DispStat[1] |= (1<<0); - - if (DispStat[0] & (1<<3)) NDS::TriggerIRQ(0, NDS::IRQ_VBlank); - if (DispStat[1] & (1<<3)) NDS::TriggerIRQ(1, NDS::IRQ_VBlank); - } - NDS::ScheduleEvent(LINE_CYCLES, StartScanline, line+1); - } + Write16(addr, val&0xFFFF); + Write16(addr+2, val>>16); } -void SetDispStat(u32 cpu, u16 val) +void GPU2D::DrawScanline(u32 line) { - val &= 0xFFB8; - DispStat[cpu] &= 0x0047; - DispStat[cpu] |= val; - - VMatch[cpu] = (val >> 8) | ((val & 0x80) << 1); - - if (val & 0x10) printf("!! HBLANK ENABLED\n"); -} - + // } @@ -19,43 +19,28 @@ #ifndef GPU2D_H #define GPU2D_H -namespace GPU2D +class GPU2D { +public: + GPU2D(u32 num); + ~GPU2D(); -extern u16 VCount; + void Reset(); -extern u16 DispStat[2]; + void SetFramebuffer(u16* buf); -extern u8 VRAMCNT[9]; -extern u8 VRAMSTAT; + u8 Read8(u32 addr); + u16 Read16(u32 addr); + u32 Read32(u32 addr); + void Write8(u32 addr, u8 val); + void Write16(u32 addr, u16 val); + void Write32(u32 addr, u32 val); -extern u8 Palette[2*1024]; -extern u8 OAM[2*1024]; + void DrawScanline(u32 line); -extern u8* VRAM_ABG[128]; -extern u8* VRAM_AOBJ[128]; -extern u8* VRAM_BBG[128]; -extern u8* VRAM_BOBJ[128]; -extern u8* VRAM_LCD[128]; -extern u8* VRAM_ARM7[2]; - -extern u16 Framebuffer[256*192*2]; - - -void Reset(); - -void MapVRAM_AB(u32 bank, u8 cnt); -void MapVRAM_CD(u32 bank, u8 cnt); -void MapVRAM_E(u32 bank, u8 cnt); -void MapVRAM_FG(u32 bank, u8 cnt); -void MapVRAM_H(u32 bank, u8 cnt); -void MapVRAM_I(u32 bank, u8 cnt); - -void StartFrame(); -void StartScanline(u32 line); - -void SetDispStat(u32 cpu, u16 val); - -} +private: + u32 Num; + u16* Framebuffer; +}; #endif @@ -23,7 +23,7 @@ #include "CP15.h" #include "DMA.h" #include "FIFO.h" -#include "GPU2D.h" +#include "GPU.h" #include "SPI.h" #include "Wifi.h" @@ -126,6 +126,7 @@ void Init() IPCFIFO9 = new FIFO(16); IPCFIFO7 = new FIFO(16); + GPU::Init(); SPI::Init(); Reset(); @@ -245,7 +246,7 @@ void Reset() for (i = 0; i < 8; i++) DMAs[i]->Reset(); memset(DMA9Fill, 0, 4*4); - GPU2D::Reset(); + GPU::Reset(); SPI::Reset(); Wifi::Reset(); @@ -278,7 +279,7 @@ void RunFrame() fnum++; //printf("frame %d\n", fnum); - GPU2D::StartFrame(); + GPU::StartFrame(); while (Running && framecycles>0) { @@ -762,7 +763,7 @@ u8 ARM9Read8(u32 addr) return ARM9IORead8(addr); case 0x05000000: - return *(u8*)&GPU2D::Palette[addr & 0x7FF]; + return *(u8*)&GPU::Palette[addr & 0x7FF]; case 0x06000000: { @@ -770,11 +771,11 @@ u8 ARM9Read8(u32 addr) u8* vram = NULL; switch (addr & 0x00E00000) { - case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break; - case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break; - case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break; - case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break; - case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break; + case 0x00000000: vram = GPU::VRAM_ABG[chunk]; break; + case 0x00200000: vram = GPU::VRAM_AOBJ[chunk]; break; + case 0x00400000: vram = GPU::VRAM_BBG[chunk]; break; + case 0x00600000: vram = GPU::VRAM_BOBJ[chunk]; break; + case 0x00800000: vram = GPU::VRAM_LCD[chunk]; break; } if (vram) return *(u8*)&vram[addr & 0x3FFF]; @@ -782,7 +783,7 @@ u8 ARM9Read8(u32 addr) return 0; case 0x07000000: - return *(u8*)&GPU2D::OAM[addr & 0x7FF]; + return *(u8*)&GPU::OAM[addr & 0x7FF]; } printf("unknown arm9 read8 %08X\n", addr); @@ -817,7 +818,7 @@ u16 ARM9Read16(u32 addr) return ARM9IORead16(addr); case 0x05000000: - return *(u16*)&GPU2D::Palette[addr & 0x7FF]; + return *(u16*)&GPU::Palette[addr & 0x7FF]; case 0x06000000: { @@ -825,11 +826,11 @@ u16 ARM9Read16(u32 addr) u8* vram = NULL; switch (addr & 0x00E00000) { - case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break; - case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break; - case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break; - case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break; - case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break; + case 0x00000000: vram = GPU::VRAM_ABG[chunk]; break; + case 0x00200000: vram = GPU::VRAM_AOBJ[chunk]; break; + case 0x00400000: vram = GPU::VRAM_BBG[chunk]; break; + case 0x00600000: vram = GPU::VRAM_BOBJ[chunk]; break; + case 0x00800000: vram = GPU::VRAM_LCD[chunk]; break; } if (vram) return *(u16*)&vram[addr & 0x3FFF]; @@ -837,7 +838,7 @@ u16 ARM9Read16(u32 addr) return 0; case 0x07000000: - return *(u16*)&GPU2D::OAM[addr & 0x7FF]; + return *(u16*)&GPU::OAM[addr & 0x7FF]; } printf("unknown arm9 read16 %08X\n", addr); @@ -887,7 +888,7 @@ u32 ARM9Read32(u32 addr) return ARM9IORead32(addr); case 0x05000000: - return *(u32*)&GPU2D::Palette[addr & 0x7FF]; + return *(u32*)&GPU::Palette[addr & 0x7FF]; case 0x06000000: { @@ -895,11 +896,11 @@ u32 ARM9Read32(u32 addr) u8* vram = NULL; switch (addr & 0x00E00000) { - case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break; - case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break; - case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break; - case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break; - case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break; + case 0x00000000: vram = GPU::VRAM_ABG[chunk]; break; + case 0x00200000: vram = GPU::VRAM_AOBJ[chunk]; break; + case 0x00400000: vram = GPU::VRAM_BBG[chunk]; break; + case 0x00600000: vram = GPU::VRAM_BOBJ[chunk]; break; + case 0x00800000: vram = GPU::VRAM_LCD[chunk]; break; } if (vram) return *(u32*)&vram[addr & 0x3FFF]; @@ -907,7 +908,7 @@ u32 ARM9Read32(u32 addr) return 0; case 0x07000000: - return *(u32*)&GPU2D::OAM[addr & 0x7FF]; + return *(u32*)&GPU::OAM[addr & 0x7FF]; } printf("unknown arm9 read32 %08X | %08X %08X %08X\n", addr, ARM9->R[15], ARM9->R[12], ARM9Read32(0x027FF820)); @@ -979,7 +980,7 @@ void ARM9Write16(u32 addr, u16 val) return; case 0x05000000: - *(u16*)&GPU2D::Palette[addr & 0x7FF] = val; + *(u16*)&GPU::Palette[addr & 0x7FF] = val; return; case 0x06000000: @@ -988,11 +989,11 @@ void ARM9Write16(u32 addr, u16 val) u8* vram = NULL; switch (addr & 0x00E00000) { - case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break; - case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break; - case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break; - case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break; - case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break; + case 0x00000000: vram = GPU::VRAM_ABG[chunk]; break; + case 0x00200000: vram = GPU::VRAM_AOBJ[chunk]; break; + case 0x00400000: vram = GPU::VRAM_BBG[chunk]; break; + case 0x00600000: vram = GPU::VRAM_BOBJ[chunk]; break; + case 0x00800000: vram = GPU::VRAM_LCD[chunk]; break; } if (vram) *(u16*)&vram[addr & 0x3FFF] = val; @@ -1000,7 +1001,7 @@ void ARM9Write16(u32 addr, u16 val) return; case 0x07000000: - *(u16*)&GPU2D::OAM[addr & 0x7FF] = val; + *(u16*)&GPU::OAM[addr & 0x7FF] = val; return; } @@ -1036,7 +1037,7 @@ void ARM9Write32(u32 addr, u32 val) return; case 0x05000000: - *(u32*)&GPU2D::Palette[addr & 0x7FF] = val; + *(u32*)&GPU::Palette[addr & 0x7FF] = val; return; case 0x06000000: @@ -1045,11 +1046,11 @@ void ARM9Write32(u32 addr, u32 val) u8* vram = NULL; switch (addr & 0x00E00000) { - case 0x00000000: vram = GPU2D::VRAM_ABG[chunk]; break; - case 0x00200000: vram = GPU2D::VRAM_AOBJ[chunk]; break; - case 0x00400000: vram = GPU2D::VRAM_BBG[chunk]; break; - case 0x00600000: vram = GPU2D::VRAM_BOBJ[chunk]; break; - case 0x00800000: vram = GPU2D::VRAM_LCD[chunk]; break; + case 0x00000000: vram = GPU::VRAM_ABG[chunk]; break; + case 0x00200000: vram = GPU::VRAM_AOBJ[chunk]; break; + case 0x00400000: vram = GPU::VRAM_BBG[chunk]; break; + case 0x00600000: vram = GPU::VRAM_BOBJ[chunk]; break; + case 0x00800000: vram = GPU::VRAM_LCD[chunk]; break; } if (vram) *(u32*)&vram[addr & 0x3FFF] = val; @@ -1057,7 +1058,7 @@ void ARM9Write32(u32 addr, u32 val) return; case 0x07000000: - *(u32*)&GPU2D::OAM[addr & 0x7FF] = val; + *(u32*)&GPU::OAM[addr & 0x7FF] = val; return; } @@ -1093,7 +1094,7 @@ u8 ARM7Read8(u32 addr) case 0x06800000: { u32 chunk = (addr >> 17) & 0x1; - u8* vram = GPU2D::VRAM_ARM7[chunk]; + u8* vram = GPU::VRAM_ARM7[chunk]; if (vram) return *(u8*)&vram[addr & 0x3FFF]; } @@ -1134,7 +1135,7 @@ u16 ARM7Read16(u32 addr) case 0x06800000: { u32 chunk = (addr >> 17) & 0x1; - u8* vram = GPU2D::VRAM_ARM7[chunk]; + u8* vram = GPU::VRAM_ARM7[chunk]; if (vram) return *(u16*)&vram[addr & 0x3FFF]; } @@ -1177,7 +1178,7 @@ u32 ARM7Read32(u32 addr) case 0x06800000: { u32 chunk = (addr >> 17) & 0x1; - u8* vram = GPU2D::VRAM_ARM7[chunk]; + u8* vram = GPU::VRAM_ARM7[chunk]; if (vram) return *(u32*)&vram[addr & 0x3FFF]; } @@ -1214,7 +1215,7 @@ void ARM7Write8(u32 addr, u8 val) case 0x06800000: { u32 chunk = (addr >> 17) & 0x1; - u8* vram = GPU2D::VRAM_ARM7[chunk]; + u8* vram = GPU::VRAM_ARM7[chunk]; if (vram) *(u8*)&vram[addr & 0x3FFF] = val; } @@ -1255,7 +1256,7 @@ void ARM7Write16(u32 addr, u16 val) case 0x06800000: { u32 chunk = (addr >> 17) & 0x1; - u8* vram = GPU2D::VRAM_ARM7[chunk]; + u8* vram = GPU::VRAM_ARM7[chunk]; if (vram) *(u16*)&vram[addr & 0x3FFF] = val; } @@ -1292,7 +1293,7 @@ void ARM7Write32(u32 addr, u32 val) case 0x06800000: { u32 chunk = (addr >> 17) & 0x1; - u8* vram = GPU2D::VRAM_ARM7[chunk]; + u8* vram = GPU::VRAM_ARM7[chunk]; if (vram) *(u32*)&vram[addr & 0x3FFF] = val; } @@ -1311,20 +1312,29 @@ u8 ARM9IORead8(u32 addr) { case 0x04000208: return IME[0]; - case 0x04000240: return GPU2D::VRAMCNT[0]; - case 0x04000241: return GPU2D::VRAMCNT[1]; - case 0x04000242: return GPU2D::VRAMCNT[2]; - case 0x04000243: return GPU2D::VRAMCNT[3]; - case 0x04000244: return GPU2D::VRAMCNT[4]; - case 0x04000245: return GPU2D::VRAMCNT[5]; - case 0x04000246: return GPU2D::VRAMCNT[6]; + case 0x04000240: return GPU::VRAMCNT[0]; + case 0x04000241: return GPU::VRAMCNT[1]; + case 0x04000242: return GPU::VRAMCNT[2]; + case 0x04000243: return GPU::VRAMCNT[3]; + case 0x04000244: return GPU::VRAMCNT[4]; + case 0x04000245: return GPU::VRAMCNT[5]; + case 0x04000246: return GPU::VRAMCNT[6]; case 0x04000247: return WRAMCnt; - case 0x04000248: return GPU2D::VRAMCNT[7]; - case 0x04000249: return GPU2D::VRAMCNT[8]; + case 0x04000248: return GPU::VRAMCNT[7]; + case 0x04000249: return GPU::VRAMCNT[8]; case 0x04000300: return PostFlag9; } + if (addr >= 0x04000000 && addr < 0x04000060) + { + return GPU::GPU2D_A->Read8(addr); + } + if (addr >= 0x04001000 && addr < 0x04001060) + { + return GPU::GPU2D_B->Read8(addr); + } + printf("unknown ARM9 IO read8 %08X\n", addr); return 0; } @@ -1333,8 +1343,8 @@ u16 ARM9IORead16(u32 addr) { switch (addr) { - case 0x04000004: return GPU2D::DispStat[0]; - case 0x04000006: return GPU2D::VCount; + case 0x04000004: return GPU::DispStat[0]; + case 0x04000006: return GPU::VCount; case 0x040000E0: return ((u16*)DMA9Fill)[0]; case 0x040000E2: return ((u16*)DMA9Fill)[1]; @@ -1377,6 +1387,15 @@ u16 ARM9IORead16(u32 addr) case 0x04000304: return PowerControl9; } + if (addr >= 0x04000000 && addr < 0x04000060) + { + return GPU::GPU2D_A->Read16(addr); + } + if (addr >= 0x04001000 && addr < 0x04001060) + { + return GPU::GPU2D_B->Read16(addr); + } + printf("unknown ARM9 IO read16 %08X\n", addr); return 0; } @@ -1385,7 +1404,7 @@ u32 ARM9IORead32(u32 addr) { switch (addr) { - case 0x04000004: return GPU2D::DispStat[0] | (GPU2D::VCount << 16); + case 0x04000004: return GPU::DispStat[0] | (GPU::VCount << 16); case 0x040000B0: return DMAs[0]->SrcAddr; case 0x040000B4: return DMAs[0]->DstAddr; @@ -1445,6 +1464,15 @@ u32 ARM9IORead32(u32 addr) return IPCFIFO7->Peek(); } + if (addr >= 0x04000000 && addr < 0x04000060) + { + return GPU::GPU2D_A->Read32(addr); + } + if (addr >= 0x04001000 && addr < 0x04001060) + { + return GPU::GPU2D_B->Read32(addr); + } + printf("unknown ARM9 IO read32 %08X\n", addr); return 0; } @@ -1464,16 +1492,16 @@ void ARM9IOWrite8(u32 addr, u8 val) case 0x04000208: IME[0] = val & 0x1; return; - case 0x04000240: GPU2D::MapVRAM_AB(0, val); return; - case 0x04000241: GPU2D::MapVRAM_AB(1, val); return; - case 0x04000242: GPU2D::MapVRAM_CD(2, val); return; - case 0x04000243: GPU2D::MapVRAM_CD(3, val); return; - case 0x04000244: GPU2D::MapVRAM_E(4, val); return; - case 0x04000245: GPU2D::MapVRAM_FG(5, val); return; - case 0x04000246: GPU2D::MapVRAM_FG(6, val); return; + case 0x04000240: GPU::MapVRAM_AB(0, val); return; + case 0x04000241: GPU::MapVRAM_AB(1, val); return; + case 0x04000242: GPU::MapVRAM_CD(2, val); return; + case 0x04000243: GPU::MapVRAM_CD(3, val); return; + case 0x04000244: GPU::MapVRAM_E(4, val); return; + case 0x04000245: GPU::MapVRAM_FG(5, val); return; + case 0x04000246: GPU::MapVRAM_FG(6, val); return; case 0x04000247: MapSharedWRAM(val); return; - case 0x04000248: GPU2D::MapVRAM_H(7, val); return; - case 0x04000249: GPU2D::MapVRAM_I(8, val); return; + case 0x04000248: GPU::MapVRAM_H(7, val); return; + case 0x04000249: GPU::MapVRAM_I(8, val); return; case 0x04000300: if (PostFlag9 & 0x01) val |= 0x01; @@ -1481,6 +1509,17 @@ void ARM9IOWrite8(u32 addr, u8 val) return; } + if (addr >= 0x04000000 && addr < 0x04000060) + { + GPU::GPU2D_A->Write8(addr, val); + return; + } + if (addr >= 0x04001000 && addr < 0x04001060) + { + GPU::GPU2D_B->Write8(addr, val); + return; + } + printf("unknown ARM9 IO write8 %08X %02X\n", addr, val); } @@ -1488,7 +1527,7 @@ void ARM9IOWrite16(u32 addr, u16 val) { switch (addr) { - case 0x04000004: GPU2D::SetDispStat(0, val); return; + case 0x04000004: GPU::SetDispStat(0, val); return; case 0x04000100: Timers[0].Reload = val; return; case 0x04000102: TimerStart(0, val); return; @@ -1530,24 +1569,24 @@ void ARM9IOWrite16(u32 addr, u16 val) case 0x04000208: IME[0] = val & 0x1; return; case 0x04000240: - GPU2D::MapVRAM_AB(0, val & 0xFF); - GPU2D::MapVRAM_AB(1, val >> 8); + GPU::MapVRAM_AB(0, val & 0xFF); + GPU::MapVRAM_AB(1, val >> 8); return; case 0x04000242: - GPU2D::MapVRAM_CD(2, val & 0xFF); - GPU2D::MapVRAM_CD(3, val >> 8); + GPU::MapVRAM_CD(2, val & 0xFF); + GPU::MapVRAM_CD(3, val >> 8); return; case 0x04000244: - GPU2D::MapVRAM_E(4, val & 0xFF); - GPU2D::MapVRAM_FG(5, val >> 8); + GPU::MapVRAM_E(4, val & 0xFF); + GPU::MapVRAM_FG(5, val >> 8); return; case 0x04000246: - GPU2D::MapVRAM_FG(6, val & 0xFF); + GPU::MapVRAM_FG(6, val & 0xFF); MapSharedWRAM(val >> 8); return; case 0x04000248: - GPU2D::MapVRAM_H(7, val & 0xFF); - GPU2D::MapVRAM_I(8, val >> 8); + GPU::MapVRAM_H(7, val & 0xFF); + GPU::MapVRAM_I(8, val >> 8); return; case 0x04000280: DivCnt = val; StartDiv(); return; @@ -1560,6 +1599,17 @@ void ARM9IOWrite16(u32 addr, u16 val) case 0x04000304: PowerControl9 = val; return; } + if (addr >= 0x04000000 && addr < 0x04000060) + { + GPU::GPU2D_A->Write16(addr, val); + return; + } + if (addr >= 0x04001000 && addr < 0x04001060) + { + GPU::GPU2D_B->Write16(addr, val); + return; + } + printf("unknown ARM9 IO write16 %08X %04X\n", addr, val); } @@ -1632,20 +1682,20 @@ void ARM9IOWrite32(u32 addr, u32 val) case 0x04000214: IF[0] &= ~val; return; case 0x04000240: - GPU2D::MapVRAM_AB(0, val & 0xFF); - GPU2D::MapVRAM_AB(1, (val >> 8) & 0xFF); - GPU2D::MapVRAM_CD(2, (val >> 16) & 0xFF); - GPU2D::MapVRAM_CD(3, val >> 24); + GPU::MapVRAM_AB(0, val & 0xFF); + GPU::MapVRAM_AB(1, (val >> 8) & 0xFF); + GPU::MapVRAM_CD(2, (val >> 16) & 0xFF); + GPU::MapVRAM_CD(3, val >> 24); return; case 0x04000244: - GPU2D::MapVRAM_E(4, val & 0xFF); - GPU2D::MapVRAM_FG(5, (val >> 8) & 0xFF); - GPU2D::MapVRAM_FG(6, (val >> 16) & 0xFF); + GPU::MapVRAM_E(4, val & 0xFF); + GPU::MapVRAM_FG(5, (val >> 8) & 0xFF); + GPU::MapVRAM_FG(6, (val >> 16) & 0xFF); MapSharedWRAM(val >> 24); return; case 0x04000248: - GPU2D::MapVRAM_H(7, val & 0xFF); - GPU2D::MapVRAM_I(8, (val >> 8) & 0xFF); + GPU::MapVRAM_H(7, val & 0xFF); + GPU::MapVRAM_I(8, (val >> 8) & 0xFF); return; case 0x04000290: DivNumerator[0] = val; StartDiv(); return; @@ -1654,6 +1704,17 @@ void ARM9IOWrite32(u32 addr, u32 val) case 0x0400029C: DivDenominator[1] = val; StartDiv(); return; } + if (addr >= 0x04000000 && addr < 0x04000060) + { + GPU::GPU2D_A->Write32(addr, val); + return; + } + if (addr >= 0x04001000 && addr < 0x04001060) + { + GPU::GPU2D_B->Write32(addr, val); + return; + } + printf("unknown ARM9 IO write32 %08X %08X\n", addr, val); } @@ -1668,7 +1729,7 @@ u8 ARM7IORead8(u32 addr) case 0x04000208: return IME[1]; - case 0x04000240: return GPU2D::VRAMSTAT; + case 0x04000240: return GPU::VRAMSTAT; case 0x04000241: return WRAMCnt; case 0x04000300: return PostFlag7; @@ -1691,8 +1752,8 @@ u16 ARM7IORead16(u32 addr) { switch (addr) { - case 0x04000004: return GPU2D::DispStat[1]; - case 0x04000006: return GPU2D::VCount; + case 0x04000004: return GPU::DispStat[1]; + case 0x04000006: return GPU::VCount; case 0x04000100: return Timers[4].Counter; case 0x04000102: return Timers[4].Control; @@ -1739,7 +1800,7 @@ u32 ARM7IORead32(u32 addr) { switch (addr) { - case 0x04000004: return GPU2D::DispStat[1] | (GPU2D::VCount << 16); + case 0x04000004: return GPU::DispStat[1] | (GPU::VCount << 16); case 0x040000B0: return DMAs[4]->SrcAddr; case 0x040000B4: return DMAs[4]->DstAddr; @@ -1847,7 +1908,7 @@ void ARM7IOWrite16(u32 addr, u16 val) { switch (addr) { - case 0x04000004: GPU2D::SetDispStat(1, val); return; + case 0x04000004: GPU::SetDispStat(1, val); return; case 0x04000100: Timers[4].Reload = val; return; case 0x04000102: TimerStart(4, val); return; @@ -19,7 +19,7 @@ #include <stdio.h> #include <windows.h> #include "NDS.h" -#include "GPU2D.h" +#include "GPU.h" HINSTANCE instance; @@ -150,7 +150,7 @@ int main() NDS::RunFrame(); HDC dc = GetDC(melon); - SetDIBitsToDevice(dc, 0, 0, 256, 384, 0, 0, 0, 384, GPU2D::Framebuffer, (BITMAPINFO*)&bmp, DIB_RGB_COLORS); + SetDIBitsToDevice(dc, 0, 0, 256, 384, 0, 0, 0, 384, GPU::Framebuffer, (BITMAPINFO*)&bmp, DIB_RGB_COLORS); UpdateWindow(melon); nframes++; diff --git a/melonDS.depend b/melonDS.depend index 5b57319..076a607 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -1,16 +1,16 @@ # depslib dependency file v1.0 -1484695094 source:c:\documents\sources\melonds\main.cpp +1484707090 source:c:\documents\sources\melonds\main.cpp <stdio.h> <windows.h> "NDS.h" - "GPU2D.h" + "GPU.h" 1484615598 c:\documents\sources\melonds\nds.h "types.h" 1481161027 c:\documents\sources\melonds\types.h -1484702383 source:c:\documents\sources\melonds\nds.cpp +1484708424 source:c:\documents\sources\melonds\nds.cpp <stdio.h> <string.h> "NDS.h" @@ -18,7 +18,7 @@ "CP15.h" "DMA.h" "FIFO.h" - "GPU2D.h" + "GPU.h" "SPI.h" "Wifi.h" @@ -38,7 +38,7 @@ "types.h" "ARM.h" -1484704018 source:c:\documents\sources\melonds\arminterpreter.cpp +1484705417 source:c:\documents\sources\melonds\arminterpreter.cpp <stdio.h> "NDS.h" "CP15.h" @@ -81,13 +81,13 @@ "NDS.h" "SPI.h" -1484517476 source:c:\documents\sources\melonds\gpu2d.cpp +1484708331 source:c:\documents\sources\melonds\gpu2d.cpp <stdio.h> - <string.h> "NDS.h" + "GPU.h" "GPU2D.h" -1481164639 c:\documents\sources\melonds\gpu2d.h +1484707825 c:\documents\sources\melonds\gpu2d.h 1481040524 c:\documents\sources\melonds\wifi.h @@ -103,7 +103,7 @@ 1484612398 c:\documents\sources\melonds\fifo.h "types.h" -1484699433 source:c:\documents\sources\melonds\dma.cpp +1484706353 source:c:\documents\sources\melonds\dma.cpp <stdio.h> "NDS.h" "DMA.h" @@ -111,3 +111,12 @@ 1484698068 c:\documents\sources\melonds\dma.h "types.h" +1484708259 source:c:\documents\sources\melonds\gpu.cpp + <stdio.h> + <string.h> + "NDS.h" + "GPU.h" + +1484708251 c:\documents\sources\melonds\gpu.h + "GPU2D.h" + |