Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/gameboy/lcd/mmio/mmio.cpp
2 views
1
#ifdef LCD_CPP
2
3
unsigned LCD::vram_addr(uint16 addr) const {
4
return (status.vram_bank * 0x2000) + (addr & 0x1fff);
5
}
6
7
uint8 LCD::mmio_read(uint16 addr) {
8
if(addr >= 0x8000 && addr <= 0x9fff) return vram[vram_addr(addr)];
9
if(addr >= 0xfe00 && addr <= 0xfe9f) return oam[addr & 0xff];
10
11
if(addr == 0xff40) { //LCDC
12
return (status.display_enable << 7)
13
| (status.window_tilemap_select << 6)
14
| (status.window_display_enable << 5)
15
| (status.bg_tiledata_select << 4)
16
| (status.bg_tilemap_select << 3)
17
| (status.ob_size << 2)
18
| (status.ob_enable << 1)
19
| (status.bg_enable << 0);
20
}
21
22
if(addr == 0xff41) { //STAT
23
unsigned mode;
24
if(status.ly >= 144) mode = 1; //Vblank
25
else if(status.lx < 80) mode = 2; //OAM
26
else if(status.lx < 252) mode = 3; //LCD
27
else mode = 0; //Hblank
28
29
return (status.interrupt_lyc << 6)
30
| (status.interrupt_oam << 5)
31
| (status.interrupt_vblank << 4)
32
| (status.interrupt_hblank << 3)
33
| ((status.ly == status.lyc) << 2)
34
| (mode << 0);
35
}
36
37
if(addr == 0xff42) { //SCY
38
return status.scy;
39
}
40
41
if(addr == 0xff43) { //SCX
42
return status.scx;
43
}
44
45
if(addr == 0xff44) { //LY
46
return status.ly;
47
}
48
49
if(addr == 0xff45) { //LYC
50
return status.lyc;
51
}
52
53
if(addr == 0xff47) { //BGP
54
return (bgp[3] << 6)
55
| (bgp[2] << 4)
56
| (bgp[1] << 2)
57
| (bgp[0] << 0);
58
}
59
60
if(addr == 0xff48) { //OBP0
61
return (obp[0][3] << 6)
62
| (obp[0][2] << 4)
63
| (obp[0][1] << 2)
64
| (obp[0][0] << 0);
65
}
66
67
if(addr == 0xff49) { //OBP1
68
return (obp[1][3] << 6)
69
| (obp[1][2] << 4)
70
| (obp[1][1] << 2)
71
| (obp[1][0] << 0);
72
}
73
74
if(addr == 0xff4a) { //WY
75
return status.wy;
76
}
77
78
if(addr == 0xff4b) { //WX
79
return status.wx;
80
}
81
82
if(addr == 0xff69) { //BGPD
83
return bgpd[status.bgpi];
84
}
85
86
if(addr == 0xff6b) { //OBPD
87
return obpd[status.obpi];
88
}
89
90
return 0x00;
91
}
92
93
void LCD::mmio_write(uint16 addr, uint8 data) {
94
if(addr >= 0x8000 && addr <= 0x9fff) { vram[vram_addr(addr)] = data; return; }
95
if(addr >= 0xfe00 && addr <= 0xfe9f) { oam[addr & 0xff] = data; return; }
96
97
if(addr == 0xff40) { //LCDC
98
if(status.display_enable == false && (data & 0x80)) {
99
status.lx = 0; //unverified behavior; fixes Super Mario Land 2 - Tree Zone
100
}
101
102
status.display_enable = data & 0x80;
103
status.window_tilemap_select = data & 0x40;
104
status.window_display_enable = data & 0x20;
105
status.bg_tiledata_select = data & 0x10;
106
status.bg_tilemap_select = data & 0x08;
107
status.ob_size = data & 0x04;
108
status.ob_enable = data & 0x02;
109
status.bg_enable = data & 0x01;
110
return;
111
}
112
113
if(addr == 0xff41) { //STAT
114
status.interrupt_lyc = data & 0x40;
115
status.interrupt_oam = data & 0x20;
116
status.interrupt_vblank = data & 0x10;
117
status.interrupt_hblank = data & 0x08;
118
return;
119
}
120
121
if(addr == 0xff42) { //SCY
122
status.scy = data;
123
return;
124
}
125
126
if(addr == 0xff43) { //SCX
127
status.scx = data;
128
return;
129
}
130
131
if(addr == 0xff44) { //LY
132
status.ly = 0;
133
return;
134
}
135
136
if(addr == 0xff45) { //LYC
137
status.lyc = data;
138
return;
139
}
140
141
if(addr == 0xff47) { //BGP
142
bgp[3] = (data >> 6) & 3;
143
bgp[2] = (data >> 4) & 3;
144
bgp[1] = (data >> 2) & 3;
145
bgp[0] = (data >> 0) & 3;
146
return;
147
}
148
149
if(addr == 0xff48) { //OBP0
150
obp[0][3] = (data >> 6) & 3;
151
obp[0][2] = (data >> 4) & 3;
152
obp[0][1] = (data >> 2) & 3;
153
obp[0][0] = (data >> 0) & 3;
154
return;
155
}
156
157
if(addr == 0xff49) { //OBP1
158
obp[1][3] = (data >> 6) & 3;
159
obp[1][2] = (data >> 4) & 3;
160
obp[1][1] = (data >> 2) & 3;
161
obp[1][0] = (data >> 0) & 3;
162
return;
163
}
164
165
if(addr == 0xff4a) { //WY
166
status.wy = data;
167
return;
168
}
169
170
if(addr == 0xff4b) { //WX
171
status.wx = data;
172
return;
173
}
174
175
if(addr == 0xff4f) { //VBK
176
status.vram_bank = data & 1;
177
return;
178
}
179
180
if(addr == 0xff68) { //BGPI
181
status.bgpi_increment = data & 0x80;
182
status.bgpi = data & 0x3f;
183
return;
184
}
185
186
if(addr == 0xff69) { //BGPD
187
bgpd[status.bgpi] = data;
188
if(status.bgpi_increment) status.bgpi++;
189
return;
190
}
191
192
if(addr == 0xff6a) { //OBPI
193
status.obpi_increment = data & 0x80;
194
status.obpi = data & 0x3f;
195
}
196
197
if(addr == 0xff6b) { //OBPD
198
obpd[status.obpi] = data;
199
if(status.obpi_increment) status.obpi++;
200
}
201
}
202
203
#endif
204
205