/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide 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 dpavlin 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