2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
5 Desc: VESA Gfx hardware support functions
11 #include <aros/asmcall.h>
12 #include <aros/debug.h>
13 #include <aros/macros.h>
14 #include <aros/bootloader.h>
16 #include <proto/bootloader.h>
17 #include <proto/exec.h>
18 #include <proto/oop.h>
19 #include <utility/hooks.h>
20 #include <utility/tagitem.h>
24 #include "vesagfx_intern.h"
25 #include "vesagfx_hidd.h"
29 static void Find_PCI_Card(struct HWData
*sd
);
31 BOOL
initVesaGfxHW(struct HWData
*data
)
33 struct BootLoaderBase
*BootLoaderBase
;
36 if ((BootLoaderBase
= OpenResource("bootloader.resource")))
38 D(bug("[Vesa] Init: Bootloader.resource opened\n"));
40 if ((vi
= (struct VesaInfo
*)GetBootInfo(BL_Video
)))
42 D(bug("[Vesa] Init: Got Vesa structure from resource\n"));
43 if (vi
->ModeNumber
== 3)
45 D(bug("[Vesa] Init: Textmode was specified. Aborting\n"));
49 data
->width
= vi
->XSize
; data
->height
= vi
->YSize
;
50 data
->bitsperpixel
= data
->depth
= vi
->BitsPerPixel
;
51 data
->bytesperline
= vi
->BytesPerLine
;
54 data
->redmask
= vi
->Masks
[VI_Red
];
55 data
->greenmask
= vi
->Masks
[VI_Green
];
56 data
->bluemask
= vi
->Masks
[VI_Blue
];
57 data
->redshift
= vi
->Shifts
[VI_Red
];
58 data
->greenshift
= vi
->Shifts
[VI_Green
];
59 data
->blueshift
= vi
->Shifts
[VI_Blue
];
63 /* Fake masks to allow this mode to be displayed */
64 data
->redmask
= 0xff0000;
65 data
->greenmask
= 0xff00;
66 data
->bluemask
= 0xff;
71 data
->framebuffer
= vi
->FrameBuffer
;
72 data
->palettewidth
= vi
->PaletteWidth
;
73 if (data
->palettewidth
> 8)
74 data
->palettewidth
= 8;
76 if (!data
->framebuffer
)
78 if (!data
->framebuffer
) {
79 D(bug("[Vesa] HwInit: Framebuffer not found\n"));
85 data
->bytesperpixel
= 4;
87 else if (data
->depth
> 16)
89 data
->bytesperpixel
= 3;
91 else if (data
->depth
> 8)
93 data
->bytesperpixel
= 2;
97 data
->bytesperpixel
= 1;
99 D(bug("[Vesa] HwInit: Clearing %d kB of framebuffer at 0x%08x"
100 " size %d kB\n", data
->height
* data
->bytesperline
>> 10,
101 data
->framebuffer
, vi
->FrameBufferSize
));
103 D(bug("[Vesa] HwInit: Linear framebuffer at 0x%08x\n",data
->framebuffer
));
104 D(bug("[Vesa] HwInit: Screenmode %dx%dx%d\n",data
->width
,data
->height
,data
->depth
));
105 D(bug("[Vesa] HwInit: Masks R %08x<<%2d G %08x<<%2d B %08x<<%2d\n",
106 data
->redmask
, data
->redshift
,
107 data
->greenmask
, data
->greenshift
,
108 data
->bluemask
, data
->blueshift
));
109 D(bug("[Vesa] HwInit: PaletteWidth %d\n", data
->palettewidth
));
110 D(bug("[vesa] HwInit: BytesPerPixel %d\n", data
->bytesperpixel
));
116 bug("[Vesa] HwInit: No Vesa information from the bootloader. Failing\n");
120 void vesaDoRefreshArea(struct HWData
*hwdata
, struct VESAGfxBitMapData
*data
,
121 LONG x1
, LONG y1
, LONG x2
, LONG y2
)
124 ULONG srcmod
, dstmod
;
125 LONG y
, w
, h
, sx
, sy
;
132 /* Clip the rectangle against physical display borders */
133 if ((x1
>= data
->disp_width
) || (x2
< 1) ||
134 (y1
>= data
->disp_height
) || (y2
< 1))
140 if (x2
> data
->disp_width
)
141 x2
= data
->disp_width
;
142 if (y2
> data
->disp_height
)
143 y2
= data
->disp_height
;
145 /* Calculate width and height */
149 /* Jump back to bitmap coordinates (adjusted) */
150 sx
= x1
- data
->xoffset
;
151 sy
= y1
- data
->yoffset
;
153 w
*= data
->bytesperpix
;
155 srcmod
= data
->bytesperline
;
156 dstmod
= hwdata
->bytesperline
;
158 src
= data
->VideoData
+ sy
* data
->bytesperline
+ sx
* data
->bytesperpix
;
159 dst
= hwdata
->framebuffer
+ y1
* hwdata
->bytesperline
+ x1
* hwdata
->bytesperpixel
;
162 * Disable screen debug output if not done yet.
163 * TODO: develop some mechanism to tell kernel that we actually
164 * didn't change the mode, so upon warm reboot it can reuse
165 * the framebuffer for debug output.
170 hwdata
->owned
= TRUE
;
174 ** common sense assumption: memcpy can't possibly be faster than CopyMem[Quick]
176 if ((srcmod
!= dstmod
) || (srcmod
!= w
))
178 for(y
= 0; y
< h
; y
++)
180 CopyMem(src
, dst
, w
);
187 /* this is a plain total fast rulez copy */
188 CopyMem(src
, dst
, w
*h
);
192 AROS_UFH3(void, Enumerator
,
193 AROS_UFHA(struct Hook
*, hook
, A0
),
194 AROS_UFHA(OOP_Object
*, pciDevice
, A2
),
195 AROS_UFHA(APTR
, message
, A1
))
203 struct pHidd_PCIDriver_MapPCI mappci
,*msg
= &mappci
;
204 struct HWData
*sd
= hook
->h_Data
;
206 D(bug("[VESAGfx] Enumerator: Found device\n"));
208 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&driver
);
209 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_VendorID
, &Vendor
);
210 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, (APTR
)&buf
);
211 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size0
, &size
);
213 /* BIOS of S3 video cards may forget to set up linear framebuffer start address.
214 Here we do this manually.
215 This thing was looked up in x.org S3 driver source code. Applicable to all S3 cards. */
216 if (Vendor
== PCI_VENDOR_S3
) {
217 outb(0x59, vgaIOBase
+ 4);
218 outb((IPTR
)buf
>> 24, vgaIOBase
+ 5);
219 outb(0x5A, vgaIOBase
+ 4);
220 outb((IPTR
)buf
>> 16, vgaIOBase
+ 5);
223 mappci
.mID
= OOP_GetMethodID(IID_Hidd_PCIDriver
, moHidd_PCIDriver_MapPCI
);
224 mappci
.PCIAddress
= buf
;
225 mappci
.Length
= size
;
226 sd
->framebuffer
= (APTR
)OOP_DoMethod(driver
, (OOP_Msg
)msg
);
228 D(bug("[VESAGfx] Got framebuffer @ %x (size=%x)\n", sd
->framebuffer
, size
));
233 static void Find_PCI_Card(struct HWData
*sd
)
237 D(bug("[VESAGfx] Find_PCI_Card\n"));
239 sd
->pciDeviceAttrBase
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
240 if (sd
->pciDeviceAttrBase
)
242 pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
244 D(bug("[VESAGfx] Creating PCI object\n"));
248 struct Hook FindHook
= {
249 h_Entry
: (IPTR (*)())Enumerator
,
253 struct TagItem Requirements
[] = {
254 { tHidd_PCI_Interface
, 0x00 },
255 { tHidd_PCI_Class
, 0x03 },
256 { tHidd_PCI_SubClass
, 0x00 },
260 struct pHidd_PCI_EnumDevices enummsg
= {
261 mID
: OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
263 requirements
: (struct TagItem
*)&Requirements
,
265 D(bug("[VESAGfx] Calling search Hook\n"));
266 OOP_DoMethod(pci
, (OOP_Msg
)msg
);
267 OOP_DisposeObject(pci
);
270 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
276 ** load palette registers
278 void DACLoad(struct VESAGfx_staticdata
*xsd
, UBYTE
*DAC
,
279 unsigned char first
, int num
)
285 ObtainSemaphore(&xsd
->HW_acc
);
287 for (i
=0; i
<num
*3; i
++)
289 outb(DAC
[n
++], 0x3C9);
291 ReleaseSemaphore(&xsd
->HW_acc
);
296 ** clear the screen buffer
298 void ClearBuffer(struct HWData
*data
)
308 p
= (IPTR
*)data
->framebuffer
;
309 limit
= (IPTR
*)((IPTR
)p
+ data
->height
* data
->bytesperline
);