2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
5 Desc: vesa "hardware" 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>
25 #include "vesagfxclass.h"
30 static void Find_PCI_Card(struct HWData
*sd
);
32 BOOL
initVesaGfxHW(struct HWData
*data
)
34 struct BootLoaderBase
*BootLoaderBase
;
37 if ((BootLoaderBase
= OpenResource("bootloader.resource")))
39 D(bug("[Vesa] Init: Bootloader.resource opened\n"));
41 if ((vi
= (struct VesaInfo
*)GetBootInfo(BL_Video
)))
43 D(bug("[Vesa] Init: Got Vesa structure from resource\n"));
44 if (vi
->ModeNumber
== 3)
46 D(bug("[Vesa] Init: Textmode was specified. Aborting\n"));
50 data
->width
= vi
->XSize
; data
->height
= vi
->YSize
;
51 data
->bitsperpixel
= data
->depth
= vi
->BitsPerPixel
;
52 data
->bytesperline
= vi
->BytesPerLine
;
53 data
->redmask
= vi
->Masks
[VI_Red
];
54 data
->greenmask
= vi
->Masks
[VI_Green
];
55 data
->bluemask
= vi
->Masks
[VI_Blue
];
56 data
->redshift
= vi
->Shifts
[VI_Red
];
57 data
->greenshift
= vi
->Shifts
[VI_Green
];
58 data
->blueshift
= vi
->Shifts
[VI_Blue
];
59 data
->framebuffer
= vi
->FrameBuffer
;
60 data
->palettewidth
= vi
->PaletteWidth
;
62 if (!data
->framebuffer
)
64 if (!data
->framebuffer
) {
65 D(bug("[Vesa] HwInit: Framebuffer not found\n"));
71 data
->bytesperpixel
= 4;
73 else if (data
->depth
> 16)
75 data
->bytesperpixel
= 3;
77 else if (data
->depth
> 8)
79 data
->bytesperpixel
= 2;
83 data
->bytesperpixel
= 1;
85 D(bug("[Vesa] HwInit: Clearing %d kB of framebuffer at 0x%08x"
86 " size %d kB\n", data
->height
* data
->bytesperline
>> 10,
87 data
->framebuffer
, vi
->FrameBufferSize
));
89 D(bug("[Vesa] HwInit: Linear framebuffer at 0x%08x\n",data
->framebuffer
));
90 D(bug("[Vesa] HwInit: Screenmode %dx%dx%d\n",data
->width
,data
->height
,data
->depth
));
91 D(bug("[Vesa] HwInit: Masks R %08x<<%2d G %08x<<%2d B %08x<<%2d\n",
92 data
->redmask
, data
->redshift
,
93 data
->greenmask
, data
->greenshift
,
94 data
->bluemask
, data
->blueshift
));
95 D(bug("[Vesa] HwInit: PaletteWidth %d\n", data
->palettewidth
));
96 D(bug("[vesa] HwInit: BytesPerPixel %d\n", data
->bytesperpixel
));
102 bug("[Vesa] HwInit: No Vesa information from the bootloader. Failing\n");
106 void vesaDoRefreshArea(struct HWData
*hwdata
, struct BitmapData
*data
,
107 LONG x1
, LONG y1
, LONG x2
, LONG y2
)
110 ULONG srcmod
, dstmod
;
111 LONG y
, w
, h
, sx
, sy
;
118 /* Clip the rectangle against physical display borders */
119 if ((x1
>= data
->disp_width
) || (x2
< 1) ||
120 (y1
>= data
->disp_height
) || (y2
< 1))
126 if (x2
> data
->disp_width
)
127 x2
= data
->disp_width
;
128 if (y2
> data
->disp_height
)
129 y2
= data
->disp_height
;
131 /* Calculate width and height */
135 /* Jump back to bitmap coordinates (adjusted) */
136 sx
= x1
- data
->xoffset
;
137 sy
= y1
- data
->yoffset
;
139 w
*= data
->bytesperpix
;
141 srcmod
= data
->bytesperline
;
142 dstmod
= hwdata
->bytesperline
;
144 src
= data
->VideoData
+ sy
* data
->bytesperline
+ sx
* data
->bytesperpix
;
145 dst
= hwdata
->framebuffer
+ y1
* hwdata
->bytesperline
+ x1
* hwdata
->bytesperpixel
;
148 * Disable screen debug output if not done yet.
149 * TODO: develop some mechanism to tell kernel that we actually
150 * didn't change the mode, so upon warm reboot it can reuse
151 * the framebuffer for debug output.
156 hwdata
->owned
= TRUE
;
160 ** common sense assumption: memcpy can't possibly be faster than CopyMem[Quick]
162 if ((srcmod
!= dstmod
) || (srcmod
!= w
))
164 for(y
= 0; y
< h
; y
++)
166 CopyMem(src
, dst
, w
);
173 /* this is a plain total fast rulez copy */
174 CopyMem(src
, dst
, w
*h
);
178 AROS_UFH3(void, Enumerator
,
179 AROS_UFHA(struct Hook
*, hook
, A0
),
180 AROS_UFHA(OOP_Object
*, pciDevice
, A2
),
181 AROS_UFHA(APTR
, message
, A1
))
189 struct pHidd_PCIDriver_MapPCI mappci
,*msg
= &mappci
;
190 struct HWData
*sd
= hook
->h_Data
;
192 D(bug("[VESA] Enumerator: Found device\n"));
194 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&driver
);
195 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_VendorID
, &Vendor
);
196 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, (APTR
)&buf
);
197 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size0
, &size
);
199 /* BIOS of S3 video cards may forget to set up linear framebuffer start address.
200 Here we do this manually.
201 This thing was looked up in x.org S3 driver source code. Applicable to all S3 cards. */
202 if (Vendor
== PCI_VENDOR_S3
) {
203 outb(0x59, vgaIOBase
+ 4);
204 outb((IPTR
)buf
>> 24, vgaIOBase
+ 5);
205 outb(0x5A, vgaIOBase
+ 4);
206 outb((IPTR
)buf
>> 16, vgaIOBase
+ 5);
209 mappci
.mID
= OOP_GetMethodID(IID_Hidd_PCIDriver
, moHidd_PCIDriver_MapPCI
);
210 mappci
.PCIAddress
= buf
;
211 mappci
.Length
= size
;
212 sd
->framebuffer
= (APTR
)OOP_DoMethod(driver
, (OOP_Msg
)msg
);
214 D(bug("[VESA] Got framebuffer @ %x (size=%x)\n", sd
->framebuffer
, size
));
219 static void Find_PCI_Card(struct HWData
*sd
)
223 D(bug("[VESA] Find_PCI_Card\n"));
225 sd
->pciDeviceAttrBase
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
226 if (sd
->pciDeviceAttrBase
)
228 pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
230 D(bug("[VESA] Creating PCI object\n"));
234 struct Hook FindHook
= {
235 h_Entry
: (IPTR (*)())Enumerator
,
239 struct TagItem Requirements
[] = {
240 { tHidd_PCI_Interface
, 0x00 },
241 { tHidd_PCI_Class
, 0x03 },
242 { tHidd_PCI_SubClass
, 0x00 },
246 struct pHidd_PCI_EnumDevices enummsg
= {
247 mID
: OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
249 requirements
: (struct TagItem
*)&Requirements
,
251 D(bug("[VESA] Calling search Hook\n"));
252 OOP_DoMethod(pci
, (OOP_Msg
)msg
);
253 OOP_DisposeObject(pci
);
256 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
264 void DACLoad(struct VesaGfx_staticdata
*xsd
, UBYTE
*DAC
,
265 unsigned char first
, int num
)
271 ObtainSemaphore(&xsd
->HW_acc
);
273 for (i
=0; i
<num
*3; i
++)
275 outb(DAC
[n
++], 0x3C9);
277 ReleaseSemaphore(&xsd
->HW_acc
);
282 ** clear the screen buffer
284 void ClearBuffer(struct HWData
*data
)
294 p
= (IPTR
*)data
->framebuffer
;
295 limit
= (IPTR
*)((IPTR
)p
+ data
->height
* data
->bytesperline
);