revert between 56095 -> 55830 in arch
[AROS.git] / rom / hidds / vesagfx / vesagfx_support.c
blobe5a9d1851e2eae368cbd02eba154d1b7dfcd6c94
1 /*
2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: VESA Gfx hardware support functions
6 Lang: English
7 */
9 #define DEBUG 0
11 #include <aros/asmcall.h>
12 #include <aros/debug.h>
13 #include <aros/macros.h>
14 #include <aros/bootloader.h>
15 #include <asm/io.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>
21 #include <oop/oop.h>
22 #include <hidd/pci.h>
24 #include "vesagfx_intern.h"
25 #include "vesagfx_hidd.h"
27 #include <string.h>
29 static void Find_PCI_Card(struct HWData *sd);
31 BOOL initVesaGfxHW(struct HWData *data)
33 struct BootLoaderBase *BootLoaderBase;
34 struct VesaInfo *vi;
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"));
46 return FALSE;
49 data->width = vi->XSize; data->height = vi->YSize;
50 data->bitsperpixel = data->depth = vi->BitsPerPixel;
51 data->bytesperline = vi->BytesPerLine;
52 if (data->depth > 8)
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];
61 else
63 /* Fake masks to allow this mode to be displayed */
64 data->redmask = 0xff0000;
65 data->greenmask = 0xff00;
66 data->bluemask = 0xff;
67 data->redshift = 16;
68 data->greenshift = 8;
69 data->blueshift = 0;
71 data->framebuffer = vi->FrameBuffer;
72 data->palettewidth = vi->PaletteWidth;
73 if (data->palettewidth > 8)
74 data->palettewidth = 8;
76 if (!data->framebuffer)
77 Find_PCI_Card(data);
78 if (!data->framebuffer) {
79 D(bug("[Vesa] HwInit: Framebuffer not found\n"));
80 return FALSE;
83 if (data->depth > 24)
85 data->bytesperpixel = 4;
87 else if (data->depth > 16)
89 data->bytesperpixel = 3;
91 else if (data->depth > 8)
93 data->bytesperpixel = 2;
95 else
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));
102 ClearBuffer(data);
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));
111 return TRUE;
116 bug("[Vesa] HwInit: No Vesa information from the bootloader. Failing\n");
117 return FALSE;
120 void vesaDoRefreshArea(struct HWData *hwdata, struct VESAGfxBitMapData *data,
121 LONG x1, LONG y1, LONG x2, LONG y2)
123 UBYTE *src, *dst;
124 ULONG srcmod, dstmod;
125 LONG y, w, h, sx, sy;
127 x1 += data->xoffset;
128 y1 += data->yoffset;
129 x2 += data->xoffset;
130 y2 += data->yoffset;
132 /* Clip the rectangle against physical display borders */
133 if ((x1 >= data->disp_width) || (x2 < 1) ||
134 (y1 >= data->disp_height) || (y2 < 1))
135 return;
136 if (x1 < 0)
137 x1 = 0;
138 if (y1 < 0)
139 y1 = 0;
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 */
146 w = x2 - x1;
147 h = y2 - y1;
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.
167 if (!hwdata->owned)
169 RawPutChar(0x03);
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);
181 src += srcmod;
182 dst += dstmod;
185 else
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))
197 AROS_USERFUNC_INIT
199 APTR buf;
200 IPTR size;
201 IPTR Vendor;
202 OOP_Object *driver;
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));
230 AROS_USERFUNC_EXIT
233 static void Find_PCI_Card(struct HWData *sd)
235 OOP_Object *pci;
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"));
246 if (pci)
248 struct Hook FindHook = {
249 h_Entry: (IPTR (*)())Enumerator,
250 h_Data: sd,
253 struct TagItem Requirements[] = {
254 { tHidd_PCI_Interface, 0x00 },
255 { tHidd_PCI_Class, 0x03 },
256 { tHidd_PCI_SubClass, 0x00 },
257 { TAG_DONE, 0UL }
260 struct pHidd_PCI_EnumDevices enummsg = {
261 mID: OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_EnumDevices),
262 callback: &FindHook,
263 requirements: (struct TagItem*)&Requirements,
264 }, *msg = &enummsg;
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);
275 ** DACLoad --
276 ** load palette registers
278 void DACLoad(struct VESAGfx_staticdata *xsd, UBYTE *DAC,
279 unsigned char first, int num)
281 int i, n;
283 n = first * 3;
285 ObtainSemaphore(&xsd->HW_acc);
286 outb(first, 0x3C8);
287 for (i=0; i<num*3; i++)
289 outb(DAC[n++], 0x3C9);
291 ReleaseSemaphore(&xsd->HW_acc);
295 ** ClearBuffer --
296 ** clear the screen buffer
298 void ClearBuffer(struct HWData *data)
300 IPTR *p, *limit;
302 if (!data->owned)
304 RawPutChar(0x03);
305 data->owned = TRUE;
308 p = (IPTR *)data->framebuffer;
309 limit = (IPTR *)((IPTR)p + data->height * data->bytesperline);
310 while (p < limit)
311 *p++ = 0;