/[pearpc]/src/io/graphic/gcard.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/io/graphic/gcard.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 12711 byte(s)
import upstream CVS
1 /*
2 * PearPC
3 * gcard.cc
4 *
5 * Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <cstdlib>
22 #include <cstring>
23
24 #include "debug/tracers.h"
25 #include "system/display.h"
26 #include "system/arch/sysendian.h"
27 #include "tools/snprintf.h"
28 #include "cpu/cpu.h"
29 #include "io/pic/pic.h"
30 #include "gcard.h"
31
32 struct VMode {
33 int width, height, bytesPerPixel;
34 };
35
36 static VMode stdVModes[] = {
37 {width: 640, height: 480, bytesPerPixel: 2},
38 {width: 640, height: 480, bytesPerPixel: 4},
39 {width: 800, height: 600, bytesPerPixel: 2},
40 {width: 800, height: 600, bytesPerPixel: 4},
41 {width: 1024, height: 768, bytesPerPixel: 2},
42 {width: 1024, height: 768, bytesPerPixel: 4},
43 {width: 1152, height: 864, bytesPerPixel: 2},
44 {width: 1152, height: 864, bytesPerPixel: 4},
45 {width: 1280, height: 720, bytesPerPixel: 2},
46 {width: 1280, height: 720, bytesPerPixel: 4},
47 {width: 1280, height: 768, bytesPerPixel: 2},
48 {width: 1280, height: 768, bytesPerPixel: 4},
49 {width: 1280, height: 960, bytesPerPixel: 2},
50 {width: 1280, height: 960, bytesPerPixel: 4},
51 {width: 1280, height: 1024, bytesPerPixel: 2},
52 {width: 1280, height: 1024, bytesPerPixel: 4},
53 {width: 1360, height: 768, bytesPerPixel: 2},
54 {width: 1360, height: 768, bytesPerPixel: 4},
55 {width: 1600, height: 900, bytesPerPixel: 2},
56 {width: 1600, height: 900, bytesPerPixel: 4},
57 {width: 1600, height: 1024, bytesPerPixel: 2},
58 {width: 1600, height: 1024, bytesPerPixel: 4},
59 {width: 1600, height: 1200, bytesPerPixel: 2},
60 {width: 1600, height: 1200, bytesPerPixel: 4},
61 };
62
63 static Container *gGraphicModes;
64
65 PCI_GCard::PCI_GCard()
66 :PCI_Device("pci-graphic", 0x00, 0x07)
67 {
68 mIORegSize[0] = 0x800000;
69 mIORegType[0] = PCI_ADDRESS_SPACE_MEM_PREFETCH;
70
71 // mConfig[0x00] = 0x02; // vendor ID
72 // mConfig[0x01] = 0x10;
73 // mConfig[0x02] = 0x45; // unit ID
74 // mConfig[0x03] = 0x52;
75 mConfig[0x00] = 0x66; // vendor ID
76 mConfig[0x01] = 0x66;
77 mConfig[0x02] = 0x66; // unit ID
78 mConfig[0x03] = 0x66;
79
80 mConfig[0x08] = 0x00; // revision
81 mConfig[0x09] = 0x00;
82 mConfig[0x0a] = 0x00;
83 mConfig[0x0b] = 0x03;
84
85 mConfig[0x0e] = 0x00; // header-type
86
87 assignMemAddress(0, IO_GCARD_FRAMEBUFFER_PA_START);
88
89 mConfig[0x3c] = IO_PIC_IRQ_GCARD;
90 mConfig[0x3d] = 1;
91 mConfig[0x3e] = 0;
92 mConfig[0x3f] = 0;
93 }
94
95 bool PCI_GCard::readDeviceMem(uint r, uint32 address, uint32 &data, uint size)
96 {
97 IO_GRAPHIC_TRACE("read %d, %08x, %d\n", r, address, size);
98 data = 0;
99 return true;
100 }
101
102 bool PCI_GCard::writeDeviceMem(uint r, uint32 address, uint32 data, uint size)
103 {
104 IO_GRAPHIC_TRACE("write %d, %08x, %08x, %d\n", r, address, data, size);
105 return true;
106 }
107
108 #define MAYBE_PPC_HALF_TO_BE(a) ppc_half_from_LE(a)
109 #define MAYBE_PPC_WORD_TO_BE(a) ppc_word_from_LE(a)
110 #define MAYBE_PPC_DWORD_TO_BE(a) ppc_dword_from_LE(a)
111
112 /*#define MAYBE_PPC_HALF_TO_BE(a) (a)
113 #define MAYBE_PPC_WORD_TO_BE(a) (a)
114 #define MAYBE_PPC_DWORD_TO_BE(a) (a)*/
115
116 void FASTCALL gcard_write_1(uint32 addr, uint32 data)
117 {
118 addr -= IO_GCARD_FRAMEBUFFER_PA_START;
119 *(uint8*)(gFrameBuffer+addr) = data;
120 damageFrameBuffer(addr);
121 }
122
123 void FASTCALL gcard_write_2(uint32 addr, uint32 data)
124 {
125 addr -= IO_GCARD_FRAMEBUFFER_PA_START;
126 *(uint16*)(gFrameBuffer+addr) = MAYBE_PPC_HALF_TO_BE(data);
127 damageFrameBuffer(addr);
128 }
129
130 void FASTCALL gcard_write_4(uint32 addr, uint32 data)
131 {
132 addr -= IO_GCARD_FRAMEBUFFER_PA_START;
133 *(uint32*)(gFrameBuffer+addr) = MAYBE_PPC_WORD_TO_BE(data);
134 damageFrameBuffer(addr);
135 }
136
137 void FASTCALL gcard_write_8(uint32 addr, uint64 data)
138 {
139 addr -= IO_GCARD_FRAMEBUFFER_PA_START;
140 *(uint64*)(gFrameBuffer+addr) = MAYBE_PPC_DWORD_TO_BE(data);
141 damageFrameBuffer(addr);
142 }
143
144 void FASTCALL gcard_write_16(uint32 addr, uint128 *data)
145 {
146 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
147 #if HOST_ENDIANESS == HOST_ENDIANESS_LE
148 uint8 *src = (uint8 *)data;
149
150 for (int i=0; i<16; i++) {
151 gFrameBuffer[addr+15-i] = src[i];
152 }
153 #elif HOST_ENDIANESS == HOST_ENDIANESS_BE
154 memmove(gFrameBuffer+addr, data, 16);
155 #else
156 #error Unsupported endianess
157 #endif
158 //*(uint64*)(gFrameBuffer+addr) = MAYBE_PPC_DWORD_TO_BE(data->h);
159 //*(uint64*)(gFrameBuffer+addr+8) = MAYBE_PPC_DWORD_TO_BE(data->l);
160 damageFrameBuffer(addr);
161 }
162
163 void FASTCALL gcard_write_16_native(uint32 addr, uint128 *data)
164 {
165 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
166
167 memmove(gFrameBuffer+addr, data, 16);
168
169 damageFrameBuffer(addr);
170 }
171
172 void FASTCALL gcard_read_1(uint32 addr, uint32 &data)
173 {
174 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
175 data = (*(uint8*)(gFrameBuffer+addr));
176 }
177
178 void FASTCALL gcard_read_2(uint32 addr, uint32 &data)
179 {
180 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
181 data = MAYBE_PPC_HALF_TO_BE(*(uint16*)(gFrameBuffer+addr));
182 }
183
184 void FASTCALL gcard_read_4(uint32 addr, uint32 &data)
185 {
186 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
187 data = MAYBE_PPC_WORD_TO_BE(*(uint32*)(gFrameBuffer+addr));
188 }
189
190 void FASTCALL gcard_read_8(uint32 addr, uint64 &data)
191 {
192 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
193 data = MAYBE_PPC_DWORD_TO_BE(*(uint64*)(gFrameBuffer+addr));
194 }
195
196 void FASTCALL gcard_read_16(uint32 addr, uint128 *data)
197 {
198 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
199 #if HOST_ENDIANESS == HOST_ENDIANESS_LE
200 uint8 *store = (uint8 *)data;
201
202 for (int i=0; i<16; i++) {
203 store[i] = gFrameBuffer[addr+15-i];
204 }
205 #elif HOST_ENDIANESS == HOST_ENDIANESS_BE
206 memmove(data, gFrameBuffer+addr, 16);
207 #else
208 #error Unsupported endianess
209 #endif
210 //data->h = MAYBE_PPC_DWORD_TO_BE(*(uint64*)(gFrameBuffer+addr));
211 //data->l = MAYBE_PPC_DWORD_TO_BE(*(uint64*)(gFrameBuffer+addr+8));
212 }
213
214 void FASTCALL gcard_read_16_native(uint32 addr, uint128 *data)
215 {
216 addr-= IO_GCARD_FRAMEBUFFER_PA_START;
217
218 memmove(data, gFrameBuffer+addr, 16);
219 }
220
221 static bool gVBLon = false;
222 static int gCurrentGraphicMode;
223
224 void gcard_raise_interrupt()
225 {
226 if (gVBLon) pic_raise_interrupt(IO_PIC_IRQ_GCARD);
227 }
228
229 void gcard_osi(int cpu)
230 {
231 IO_GRAPHIC_TRACE("osi: %d\n", ppc_cpu_get_gpr(cpu, 5));
232 switch (ppc_cpu_get_gpr(cpu, 5)) {
233 case 4:
234 // cmount
235 return;
236 case 28: {
237 // set_vmode
238 uint vmode = ppc_cpu_get_gpr(cpu, 6)-1;
239 if (vmode > gGraphicModes->count() || ppc_cpu_get_gpr(cpu, 7)) {
240 ppc_cpu_set_gpr(cpu, 3, 1);
241 return;
242 }
243 DisplayCharacteristics *chr = (DisplayCharacteristics *)(*gGraphicModes)[vmode];
244 IO_GRAPHIC_TRACE("set mode %d\n", vmode);
245 if (gDisplay->changeResolution(*chr)) {
246 ppc_cpu_set_gpr(cpu, 3, 0);
247 gcard_set_mode(*chr);
248 } else {
249 ppc_cpu_set_gpr(cpu, 3, 1);
250 }
251 return;
252 }
253 case 29: {
254 /*
255 typedef struct osi_get_vmode_info {
256 short num_vmodes;
257 short cur_vmode; // 1,2,...
258 short num_depths;
259 short cur_depth_mode; // 0,1,2,...
260 short w,h;
261 int refresh; // Hz/65536
262
263 int depth;
264 short row_bytes;
265 short offset;
266 } osi_get_vmode_info_t;
267 */
268 // get_vmode_info
269 int vmode = ppc_cpu_get_gpr(cpu, 6) - 1;
270 int depth_mode = ppc_cpu_get_gpr(cpu, 7);
271 if (vmode == -1) {
272 vmode = gCurrentGraphicMode;
273 depth_mode = ((DisplayCharacteristics *)(*gGraphicModes)[vmode])->bytesPerPixel*8;
274 }
275 if (vmode > (int)gGraphicModes->count() || vmode < 0) {
276 ppc_cpu_set_gpr(cpu, 3, 1);
277 return;
278 }
279 DisplayCharacteristics *chr = ((DisplayCharacteristics *)(*gGraphicModes)[vmode]);
280 ppc_cpu_set_gpr(cpu, 3, 0);
281 ppc_cpu_set_gpr(cpu, 4, (gGraphicModes->count()<<16) | (vmode+1));
282 ppc_cpu_set_gpr(cpu, 5, (1<<16) | 0);
283 ppc_cpu_set_gpr(cpu, 6, (chr->width << 16) | chr->height);
284 ppc_cpu_set_gpr(cpu, 7, chr->vsyncFrequency << 16);
285 ppc_cpu_set_gpr(cpu, 8, chr->bytesPerPixel*8);
286 ppc_cpu_set_gpr(cpu, 9, ((chr->scanLineLength)<<16) | 0);
287 return;
288 }
289 case 31:
290 // set_video_power
291 ppc_cpu_set_gpr(cpu, 3, 0);
292 return;
293 case 39:
294 IO_GRAPHIC_TRACE("video_ctrl: %d\n", ppc_cpu_get_gpr(cpu, 6));
295 // video_ctrl
296 switch (ppc_cpu_get_gpr(cpu, 6)) {
297 case 0:
298 gVBLon = false;
299 break;
300 case 1:
301 gVBLon = true;
302 break;
303 default:
304 IO_GRAPHIC_ERR("39\n");
305 }
306 ppc_cpu_set_gpr(cpu, 3, 0);
307 return;
308 case 47:
309 // printf("%c\n", gCPU.gpr[6]);
310 return;
311 case 59: {
312 // set_color
313 uint32 r7 = ppc_cpu_get_gpr(cpu, 7);
314 gDisplay->setColor(ppc_cpu_get_gpr(cpu, 6), MK_RGB((r7>>16)&0xff, (r7>>8)&0xff, r7&0xff));
315 ppc_cpu_set_gpr(cpu, 3, 0);
316 return;
317 }
318 case 64: {
319 // get_color
320 RGB c = gDisplay->getColor(ppc_cpu_get_gpr(cpu, 6));
321 ppc_cpu_set_gpr(cpu, 3, (RGB_R(c) << 16) | (RGB_G(c) << 8) | (RGB_B(c)));
322 return;
323 }
324 case 116:
325 // hardware_cursor_bla
326 // SINGLESTEP("hw cursor!! %d, %d, %d\n", gCPU.gpr[6], gCPU.gpr[7], gCPU.gpr[8]);
327 IO_GRAPHIC_TRACE("hw cursor!! %d, %d, %d\n", ppc_cpu_get_gpr(cpu, 6), ppc_cpu_get_gpr(cpu, 7), ppc_cpu_get_gpr(cpu, 8));
328 gDisplay->setHWCursor(ppc_cpu_get_gpr(cpu, 6), ppc_cpu_get_gpr(cpu, 7), ppc_cpu_get_gpr(cpu, 8), NULL);
329 return;
330 }
331 IO_GRAPHIC_ERR("unknown osi function\n");
332 }
333
334 /*
335 * displayCharacteristicsFromString tries to create a(n unfinished) characteristic
336 * from a String of the form [0-9]+x[0-9]+x(15|32)(@[0-9]+)?
337 */
338
339 bool displayCharacteristicsFromString(DisplayCharacteristics &aChar, const String &s)
340 {
341 String width, height, depth;
342 String tmp, tmp2;
343 if (!s.leftSplit('x', width, tmp)) return false;
344 if (!width.toInt(aChar.width)) return false;
345 if (!tmp.leftSplit('x', height, tmp2)) return false;
346 if (!height.toInt(aChar.height)) return false;
347 if (tmp2.leftSplit('@', depth, tmp)) {
348 if (!depth.toInt(aChar.bytesPerPixel)) return false;
349 if (!tmp.toInt(aChar.vsyncFrequency)) return false;
350 } else {
351 aChar.vsyncFrequency = -1;
352 if (!tmp2.toInt(aChar.bytesPerPixel)) return false;
353 }
354 aChar.scanLineLength = -1;
355 aChar.redShift = -1;
356 aChar.redSize = -1;
357 aChar.greenShift = -1;
358 aChar.greenSize = -1;
359 aChar.blueShift = -1;
360 aChar.blueSize = -1;
361 return true;
362 }
363
364 void gcard_add_characteristic(const DisplayCharacteristics &aChar)
365 {
366 if (!gcard_supports_characteristic(aChar)) {
367 DisplayCharacteristics *chr = new DisplayCharacteristics;
368 *chr = aChar;
369 gGraphicModes->insert(chr);
370 }
371 }
372
373 bool gcard_supports_characteristic(const DisplayCharacteristics &aChar)
374 {
375 return gGraphicModes->contains(&aChar);
376 }
377
378 /*
379 * gcard_finish_characteristic will fill out all fields
380 * of aChar that aren't initialized yet (set to -1).
381 */
382 bool gcard_finish_characteristic(DisplayCharacteristics &aChar)
383 {
384 if (aChar.width == -1 || aChar.height == -1 || aChar.bytesPerPixel == -1) return false;
385 if (aChar.vsyncFrequency == -1) aChar.vsyncFrequency = 60;
386 if (aChar.scanLineLength == -1) aChar.scanLineLength = aChar.width * aChar.bytesPerPixel;
387 switch (aChar.bytesPerPixel) {
388 case 2:
389
390 if (aChar.redShift == -1) aChar.redShift = 10;
391 if (aChar.redSize == -1) aChar.redSize = 5;
392 if (aChar.greenShift == -1) aChar.greenShift = 5;
393 if (aChar.greenSize == -1) aChar.greenSize = 5;
394 if (aChar.blueShift == -1) aChar.blueShift = 0;
395 if (aChar.blueSize == -1) aChar.blueSize = 5;
396 break;
397 case 4:
398 if (aChar.redShift == -1) aChar.redShift = 16;
399 if (aChar.redSize == -1) aChar.redSize = 8;
400 if (aChar.greenShift == -1) aChar.greenShift = 8;
401 if (aChar.greenSize == -1) aChar.greenSize = 8;
402 if (aChar.blueShift == -1) aChar.blueShift = 0;
403 if (aChar.blueSize == -1) aChar.blueSize = 8;
404 break;
405 default:
406 return false;
407 }
408 return true;
409 }
410
411 bool gcard_set_mode(DisplayCharacteristics &mode)
412 {
413 uint tmp = gGraphicModes->getObjIdx(gGraphicModes->find(&mode));
414 if (tmp == InvIdx) {
415 return false;
416 } else {
417 gCurrentGraphicMode = tmp;
418 return true;
419 }
420 }
421
422 void gcard_init_modes()
423 {
424 gGraphicModes = new Array(true);
425 for (uint i=0; i < (sizeof stdVModes / sizeof stdVModes[0]); i++) {
426 DisplayCharacteristics chr;
427 chr.width = stdVModes[i].width;
428 chr.height = stdVModes[i].height;
429 chr.bytesPerPixel = stdVModes[i].bytesPerPixel;
430 chr.scanLineLength = -1;
431 chr.vsyncFrequency = -1;
432 chr.redShift = -1;
433 chr.redSize = -1;
434 chr.greenShift = -1;
435 chr.greenSize = -1;
436 chr.blueShift = -1;
437 chr.blueSize = -1;
438 gcard_finish_characteristic(chr);
439 gcard_add_characteristic(chr);
440 }
441 }
442
443 void gcard_init_host_modes()
444 {
445 Array modes(true);
446 gDisplay->getHostCharacteristics(modes);
447 foreach (DisplayCharacteristics, chr, modes, {
448 gcard_finish_characteristic(*chr);
449 gcard_add_characteristic(*chr);
450 });
451 }
452
453 void gcard_init()
454 {
455 gPCI_Devices->insert(new PCI_GCard());
456 }
457
458 void gcard_done()
459 {
460 }
461
462 void gcard_init_config()
463 {
464 }

  ViewVC Help
Powered by ViewVC 1.1.26