-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathppu.c
77 lines (60 loc) · 2.13 KB
/
ppu.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "global.h"
#include "rsp.h"
#include "hwdefs.h"
#include "config.h"
#include "logger.h"
#include <libdragon.h>
typedef struct { // Extends ppuInterface
union {
u32 Settings[8];
struct {
uintptr_t VRamAddress;
uintptr_t HRamAddress;
uintptr_t OAMAddress;
uintptr_t OutBuffer;
Rectangle Screen;
uintptr_t FrameBuffer[2];
};
};
} PpuInterface;
extern void* __safe_buffer[];
PpuInterface* ppuInterface;
void ppuInit(PlayerState* state) {
Rectangle screen = {};
getScreenPosition(0, &screen);
ppuInterface = allocRspInterface(sizeof(PpuInterface));
ppuInterface->Screen = (Rectangle) { screen.Left, screen.Top, 320, 2 };
ppuInterface->VRamAddress = (uintptr_t) state->EmulationState.VRAM;
ppuInterface->HRamAddress = (uintptr_t) state->EmulationState.HRAM;
ppuInterface->OAMAddress = (uintptr_t) state->EmulationState.OAM;
ppuInterface->OutBuffer = (uintptr_t)state->EmulationState.TextureBuffer;
ppuInterface->FrameBuffer[0] = (uintptr_t) (__safe_buffer[0]);
ppuInterface->FrameBuffer[1] = (uintptr_t) (__safe_buffer[1]);
data_cache_hit_writeback(ppuInterface, sizeof(PpuInterface));
prepareMicrocode(UCODE_DMG_PPU);
setDataReady(false);
run_ucode();
}
void ppuStep(PlayerState* state) {
if (state->EmulationState.lcd_entered_hblank) {
if (state->EmulationState.CurrentLine >= GB_LCD_HEIGHT) { // VBlank
return;
}
#ifdef FRAMES_TO_SKIP
if ((state->Meta.FrameCount + 1) % (FRAMES_TO_SKIP + 1)) {
return;
}
#endif
data_cache_hit_writeback(state->EmulationState.OAM, OAM_SIZE);
data_cache_hit_writeback(state->EmulationState.HRAM, HRAM_SIZE);
if (state->EmulationState.isVramDirty) {
data_cache_hit_writeback(state->EmulationState.VRAM, VRAM_BANK_SIZE);
state->EmulationState.isVramDirty = false;
}
// Let the RSP finish its current job.
#ifdef LOCK_CPU_TO_PPU
while(isRspBusy());
#endif
setDataReady(true);
}
}