1
+ #include " ppu.h"
2
+
3
+ Ppu::Ppu (Memory& memory) : memory(memory) { }
4
+
5
+ void Ppu::cycle (long cycles)
6
+ {
7
+ if (!memory.readIORegisterBit (LCD_STATUS, LCD_ENABLE)) return ;
8
+
9
+ cycleCount += cycles;
10
+ uint8_t currentMode =
11
+ memory.readIORegisterBit (LCD_CONTROL, LCD_MODE_HIGH) << 1
12
+ & memory.readIORegisterBit (LCD_CONTROL, LCD_MODE_LOW);
13
+
14
+ switch (currentMode)
15
+ {
16
+ case MODE_OAM:
17
+ if (!cycleCount >= CYCLES_PER_OAMSEARCH) return ;
18
+
19
+ // Nothing to do in this stage besides switching into the next mode
20
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_HIGH, 1 );
21
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_LOW, 1 );
22
+ cycleCount = cycleCount % CYCLES_PER_OAMSEARCH;
23
+ break ;
24
+ case MODE_TRANSFER:
25
+ if (!cycleCount >= CYCLES_PER_TRANSFER) return ;
26
+
27
+ // LYC? HBLANK INTERRUPT?
28
+
29
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_HIGH, 0 );
30
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_LOW, 0 );
31
+ cycleCount = cycleCount % CYCLES_PER_TRANSFER;
32
+ break ;
33
+ case MODE_HBLANK:
34
+ if (!cycleCount >= CYCLES_PER_HBLANK) return ;
35
+ memory.write (LCD_Y, memory.read (LCD_Y) + 1 );
36
+ // HBLANK INTERRUPT?
37
+ // DRAW Line on Screen
38
+ // Enter V-BLANK
39
+ if (memory.read (LCD_Y) < 144 )
40
+ {
41
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_HIGH, 0 );
42
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_LOW, 1 );
43
+ }
44
+ // Enter OAM again
45
+ else
46
+ {
47
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_HIGH, 1 );
48
+ memory.writeIORegisterBit (LCD_CONTROL, LCD_MODE_LOW, 0 );
49
+ }
50
+ cycleCount = cycleCount % CYCLES_PER_HBLANK;
51
+ break ;
52
+ case MODE_VBLANK:
53
+ if (!cycleCount >= CYCLES_PER_VBLANK) return ;
54
+ // SET V INTERRUPT
55
+
56
+ cycleCount = cycleCount % CYCLES_PER_VBLANK;
57
+ break ;
58
+ }
59
+ }
0 commit comments