-
Notifications
You must be signed in to change notification settings - Fork 2
/
LCDController.ZC
executable file
·152 lines (148 loc) · 4.78 KB
/
LCDController.ZC
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
U0 matchLYC()
{
// LY - LYC Compare
// If LY==LCY
if (memory[0xFF44] == memory[0xFF45]) {
memory[0xFF41] |= 0x04; // set STAT bit 2: LY-LYC coincidence flag
if (LYCMatchTriggerSTAT) {
memory[0xFF0F] |= 0x2; // set IF bit 1
}
} else {
memory[0xFF41] &= 0xFB; // reset STAT bit 2 (LY!=LYC)
}
}
U0 notifyScanline()
{
renderBG_ScanLine;
//renderWIN_ScanLine;
}
U0 scanLineMode0()
{
// H-Blank
if (modeSTAT != 0) {
if (mode0TriggerSTAT || (mode2TriggerSTAT && STATTracker == 0)) {
memory[0xFF0F] |= 0x2; // if STAT bit 3 -> set IF bit1
}
notifyScanline;
STATTracker = 2;
modeSTAT = 0;
}
}
U0 scanLineMode2()
{
// OAM in use
if (modeSTAT != 2) {
if (mode2TriggerSTAT) {
memory[0xFF0F] |= 0x2; // set IF bit 1
}
STATTracker = 1;
modeSTAT = 2;
}
}
U0 scanLineMode3()
{
// OAM in use
if (modeSTAT != 3) {
if (mode2TriggerSTAT && STATTracker == 0) {
memory[0xFF0F] |= 0x2; // set IF bit 1
}
STATTracker = 1;
modeSTAT = 3;
}
}
// Scan Line and STAT Mode Control
U0 scanLine(I64 line)
{
//When turned off = Do nothing!
if (LCDisOn) {
if (line < 143) {
//We're on a normal scan line:
if (LCDTicks < 20) {
scanLineMode2; // mode2: 80 cycles
} else if (LCDTicks < 63) {
scanLineMode3; // mode3: 172 cycles
} else if (LCDTicks < 114) {
scanLineMode0; // mode0: 204 cycles
} else {
//We're on a new scan line:
LCDTicks -= 114;
actualScanLine = ++memory[0xFF44];
matchLYC;
if (STATTracker != 2) {
if (mode0TriggerSTAT) {
memory[0xFF0F] |= 0x2; // set IF bit 1
}
}
STATTracker = 0;
scanLineMode2; // mode2: 80 cycles
if (LCDTicks >= 114) {
//We need to skip 1 or more scan lines:
notifyScanline;
scanLine(actualScanLine); //Scan Line and STAT Mode Control
}
}
} else if (line == 143) {
//We're on the last visible scan line of the LCD screen:
if (LCDTicks < 20) {
scanLineMode2; // mode2: 80 cycles
} else if (LCDTicks < 63) {
scanLineMode3; // mode3: 172 cycles
} else if (LCDTicks < 114) {
scanLineMode0; // mode0: 204 cycles
} else {
//Starting V-Blank:
//Just finished the last visible scan line:
LCDTicks -= 114;
actualScanLine = ++memory[0xFF44];
matchLYC;
if (mode1TriggerSTAT) {
memory[0xFF0F] |= 0x2; // set IF bit 1
}
if (STATTracker != 2) {
if (mode0TriggerSTAT) {
memory[0xFF0F] |= 0x2; // set IF bit 1
}
}
STATTracker = 0;
modeSTAT = 1;
memory[0xFF0F] |= 0x1; // set IF flag 0
//LCD off takes at least 2 frames.
if (drewBlank > 0) {
--drewBlank;
}
if (LCDTicks >= 114) {
//We need to skip 1 or more scan lines:
scanLine(actualScanLine); //Scan Line and STAT Mode Control
}
}
} else if (line < 153) {
//In VBlank
if (LCDTicks >= 114) {
//We're on a new scan line:
LCDTicks -= 114;
actualScanLine = ++memory[0xFF44];
matchLYC;
if (LCDTicks >= 114) {
//We need to skip 1 or more scan lines:
scanLine(actualScanLine); //Scan Line and STAT Mode Control
}
}
} else {
//VBlank Ending (We're on the last actual scan line)
if (memory[0xFF44] == 153) {
memory[0xFF44] = 0; //LY register resets to 0 early.
matchLYC; //LY==LYC Test is early here (Fixes specific one-line glitches (example: Kirby2 intro)).
}
if (LCDTicks >= 114) {
//We reset back to the beginning:
LCDTicks -= 114;
actualScanLine = 0;
scanLineMode2; // mode2: 80 cycles
if (LCDTicks >= 114) {
//We need to skip 1 or more scan lines:
scanLine(actualScanLine); //Scan Line and STAT Mode Control
}
}
}
}
}