2 Copyright © 1995-2017, 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
;
52 data
->redmask
= vi
->Masks
[VI_Red
];
53 data
->greenmask
= vi
->Masks
[VI_Green
];
54 data
->bluemask
= vi
->Masks
[VI_Blue
];
55 data
->redshift
= vi
->Shifts
[VI_Red
];
56 data
->greenshift
= vi
->Shifts
[VI_Green
];
57 data
->blueshift
= vi
->Shifts
[VI_Blue
];
58 data
->framebuffer
= vi
->FrameBuffer
;
59 data
->palettewidth
= vi
->PaletteWidth
;
61 if (!data
->framebuffer
)
63 if (!data
->framebuffer
) {
64 D(bug("[Vesa] HwInit: Framebuffer not found\n"));
70 data
->bytesperpixel
= 4;
72 else if (data
->depth
> 16)
74 data
->bytesperpixel
= 3;
76 else if (data
->depth
> 8)
78 data
->bytesperpixel
= 2;
82 data
->bytesperpixel
= 1;
84 D(bug("[Vesa] HwInit: Clearing %d kB of framebuffer at 0x%08x"
85 " size %d kB\n", data
->height
* data
->bytesperline
>> 10,
86 data
->framebuffer
, vi
->FrameBufferSize
));
88 D(bug("[Vesa] HwInit: Linear framebuffer at 0x%08x\n",data
->framebuffer
));
89 D(bug("[Vesa] HwInit: Screenmode %dx%dx%d\n",data
->width
,data
->height
,data
->depth
));
90 D(bug("[Vesa] HwInit: Masks R %08x<<%2d G %08x<<%2d B %08x<<%2d\n",
91 data
->redmask
, data
->redshift
,
92 data
->greenmask
, data
->greenshift
,
93 data
->bluemask
, data
->blueshift
));
94 D(bug("[Vesa] HwInit: PaletteWidth %d\n", data
->palettewidth
));
95 D(bug("[vesa] HwInit: BytesPerPixel %d\n", data
->bytesperpixel
));
101 bug("[Vesa] HwInit: No Vesa information from the bootloader. Failing\n");
105 void vesaDoRefreshArea(struct HWData
*hwdata
, struct VESAGfxBitMapData
*data
,
106 LONG x1
, LONG y1
, LONG x2
, LONG y2
)
109 ULONG srcmod
, dstmod
;
110 LONG y
, w
, h
, sx
, sy
;
117 /* Clip the rectangle against physical display borders */
118 if ((x1
>= data
->disp_width
) || (x2
< 1) ||
119 (y1
>= data
->disp_height
) || (y2
< 1))
125 if (x2
> data
->disp_width
)
126 x2
= data
->disp_width
;
127 if (y2
> data
->disp_height
)
128 y2
= data
->disp_height
;
130 /* Calculate width and height */
134 /* Jump back to bitmap coordinates (adjusted) */
135 sx
= x1
- data
->xoffset
;
136 sy
= y1
- data
->yoffset
;
138 w
*= data
->bytesperpix
;
140 srcmod
= data
->bytesperline
;
141 dstmod
= hwdata
->bytesperline
;
143 src
= data
->VideoData
+ sy
* data
->bytesperline
+ sx
* data
->bytesperpix
;
144 dst
= hwdata
->framebuffer
+ y1
* hwdata
->bytesperline
+ x1
* hwdata
->bytesperpixel
;
147 * Disable screen debug output if not done yet.
148 * TODO: develop some mechanism to tell kernel that we actually
149 * didn't change the mode, so upon warm reboot it can reuse
150 * the framebuffer for debug output.
155 hwdata
->owned
= TRUE
;
159 ** common sense assumption: memcpy can't possibly be faster than CopyMem[Quick]
161 if ((srcmod
!= dstmod
) || (srcmod
!= w
))
163 for(y
= 0; y
< h
; y
++)
165 CopyMem(src
, dst
, w
);
172 /* this is a plain total fast rulez copy */
173 CopyMem(src
, dst
, w
*h
);
177 AROS_UFH3(void, Enumerator
,
178 AROS_UFHA(struct Hook
*, hook
, A0
),
179 AROS_UFHA(OOP_Object
*, pciDevice
, A2
),
180 AROS_UFHA(APTR
, message
, A1
))
188 struct pHidd_PCIDriver_MapPCI mappci
,*msg
= &mappci
;
189 struct HWData
*sd
= hook
->h_Data
;
191 D(bug("[VESAGfx] Enumerator: Found device\n"));
193 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&driver
);
194 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_VendorID
, &Vendor
);
195 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, (APTR
)&buf
);
196 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size0
, &size
);
198 /* BIOS of S3 video cards may forget to set up linear framebuffer start address.
199 Here we do this manually.
200 This thing was looked up in x.org S3 driver source code. Applicable to all S3 cards. */
201 if (Vendor
== PCI_VENDOR_S3
) {
202 outb(0x59, vgaIOBase
+ 4);
203 outb((IPTR
)buf
>> 24, vgaIOBase
+ 5);
204 outb(0x5A, vgaIOBase
+ 4);
205 outb((IPTR
)buf
>> 16, vgaIOBase
+ 5);
208 mappci
.mID
= OOP_GetMethodID(IID_Hidd_PCIDriver
, moHidd_PCIDriver_MapPCI
);
209 mappci
.PCIAddress
= buf
;
210 mappci
.Length
= size
;
211 sd
->framebuffer
= (APTR
)OOP_DoMethod(driver
, (OOP_Msg
)msg
);
213 D(bug("[VESAGfx] Got framebuffer @ %x (size=%x)\n", sd
->framebuffer
, size
));
218 static void Find_PCI_Card(struct HWData
*sd
)
222 D(bug("[VESAGfx] Find_PCI_Card\n"));
224 sd
->pciDeviceAttrBase
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
225 if (sd
->pciDeviceAttrBase
)
227 pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
229 D(bug("[VESAGfx] Creating PCI object\n"));
233 struct Hook FindHook
= {
234 h_Entry
: (IPTR (*)())Enumerator
,
238 struct TagItem Requirements
[] = {
239 { tHidd_PCI_Interface
, 0x00 },
240 { tHidd_PCI_Class
, 0x03 },
241 { tHidd_PCI_SubClass
, 0x00 },
245 struct pHidd_PCI_EnumDevices enummsg
= {
246 mID
: OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
248 requirements
: (struct TagItem
*)&Requirements
,
250 D(bug("[VESAGfx] Calling search Hook\n"));
251 OOP_DoMethod(pci
, (OOP_Msg
)msg
);
252 OOP_DisposeObject(pci
);
255 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
263 void DACLoad(struct VESAGfx_staticdata
*xsd
, UBYTE
*DAC
,
264 unsigned char first
, int num
)
270 ObtainSemaphore(&xsd
->HW_acc
);
272 for (i
=0; i
<num
*3; i
++)
274 outb(DAC
[n
++], 0x3C9);
276 ReleaseSemaphore(&xsd
->HW_acc
);
281 ** clear the screen buffer
283 void ClearBuffer(struct HWData
*data
)
293 p
= (IPTR
*)data
->framebuffer
;
294 limit
= (IPTR
*)((IPTR
)p
+ data
->height
* data
->bytesperline
);