2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: sm502 "hardware" functions
9 #include <aros/asmcall.h>
10 #include <aros/debug.h>
11 #include <aros/macros.h>
12 #include <aros/bootloader.h>
14 #include <proto/bootloader.h>
15 #include <proto/exec.h>
16 #include <proto/oop.h>
17 #include <utility/hooks.h>
18 #include <utility/tagitem.h>
23 #include "sm502gfxclass.h"
29 #define SM502_PDC 0x080000 /* Panel Display Control */
30 #define SM502_PCK 0x080008 /* Panel Color Key */
31 #define SM502_PFBO 0x080010 /* Panel FB Offset */
32 #define SM502_PFBW 0x080014 /* Panel FB Width */
33 #define SM502_PFBH 0x080018 /* Panel FB Height */
34 #define SM502_PPR 0x080400 /* Panel Palette RAM */
36 static BOOL
Find_PCI_Card(struct SM502_HWData
*hw
);
38 BOOL
initSM502GfxHW(struct SM502_HWData
*hw
)
42 /* Find the first device */
43 if (!Find_PCI_Card(hw
)) {
44 D(bug("[SM502] No card found\n"));
48 hw
->disp_width
= (smread(hw
, SM502_PFBO
) >> 16) & 0x3fff;
49 hw
->disp_height
= (smread(hw
, SM502_PFBH
) >> 16) & 0x0fff;
50 hw
->xoffset
= smread(hw
, SM502_PFBW
) & 0xfff;
51 hw
->yoffset
= smread(hw
, SM502_PFBH
) & 0xfff;
52 hw
->bytesperline
= smread(hw
, SM502_PFBO
) & 0x3fff;
53 mode
= smread(hw
, SM502_PDC
);
55 /* Convert display width from bytes to pixels */
56 if ((mode
& 3) == 1) {
59 if ((mode
& 3) == 2) {
63 /* Switch from 32 bit mode */
64 if ((mode
& 3) != 2) {
67 mode
= (mode
& ~3) | 2;
68 smwrite(hw
, SM502_PDC
, mode
);
69 smwrite(hw
, SM502_PCK
, 0);
70 hw
->bytesperline
= ((hw
->disp_width
* 4) + 127) & ~127;
71 smwrite(hw
, SM502_PFBO
, (hw
->bytesperline
<< 16) | (hw
->bytesperline
));
72 for (i
= 0; i
< 256; i
++)
73 smwrite(hw
, SM502_PPR
+ (i
<< 2), 0x00000000);
77 /* Setup the current video parameters */
78 hw
->bitsperpixel
= 32;
79 hw
->bytesperpixel
= 4;
80 hw
->redmask
= 0xff << 8;
82 hw
->greenmask
= 0xff << 16;
84 hw
->bluemask
= 0xff << 24;
88 hw
->width
= hw
->disp_width
- hw
->xoffset
;
89 hw
->height
= hw
->disp_height
- hw
->yoffset
;
90 hw
->palettewidth
= (hw
->depth
== 8) ? 256 : 0;
92 D(bug("[SM502] HwInit: Clearing %d kB of framebuffer at 0x%08x",
93 hw
->height
* hw
->bytesperline
>> 10,
96 D(bug("[SM502] HwInit: Linear framebuffer at 0x%08x\n",hw
->framebuffer
));
97 D(bug("[SM502] HwInit: Screenmode %dx%dx%d\n",hw
->width
,hw
->height
,hw
->depth
));
98 D(bug("[SM502] HwInit: Masks R %08x<<%2d G %08x<<%2d B %08x<<%2d\n",
99 hw
->redmask
, hw
->redshift
,
100 hw
->greenmask
, hw
->greenshift
,
101 hw
->bluemask
, hw
->blueshift
));
102 D(bug("[SM502] HwInit: PaletteWidth %d\n", hw
->palettewidth
));
103 D(bug("[sm502] HwInit: BytesPerPixel %d\n", hw
->bytesperpixel
));
107 void sm502DoRefreshArea(struct SM502_HWData
*hwdata
, struct BitmapData
*data
,
108 LONG x1
, LONG y1
, LONG x2
, LONG y2
)
111 ULONG srcmod
, dstmod
;
120 /* Clip the rectangle against physical display borders */
121 if ((x1
>= data
->disp_width
) || (x2
< 1) ||
122 (y1
>= data
->disp_height
) || (y2
< 1))
128 if (x2
> data
->disp_width
)
129 x2
= data
->disp_width
;
130 if (y2
> data
->disp_height
)
131 y2
= data
->disp_height
;
133 /* Calculate width and height */
136 /* Jump back to bitmap coordinatess (adjusted) */
137 sx
= x1
- data
->xoffset
;
138 sy
= y1
- data
->yoffset
;
140 w
*= data
->bytesperpix
;
142 srcmod
= data
->bytesperline
;
143 dstmod
= hwdata
->bytesperline
;
145 src
= data
->VideoData
+ sy
* data
->bytesperline
+ sx
* data
->bytesperpix
;
146 dst
= hwdata
->framebuffer
+ y1
* hwdata
->bytesperline
+ x1
* hwdata
->bytesperpixel
;
149 * Disable screen debug output if not done yet.
150 * TODO: develop some mechanism to tell kernel that we actually
151 * didn't change the mode, so upon warm reboot it can reuse
152 * the framebuffer for debug output.
157 hwdata
->owned
= TRUE
;
161 ** common sense assumption: memcpy can't possibly be faster than CopyMem[Quick]
163 if ((srcmod
!= dstmod
) || (srcmod
!= w
))
165 for(y
= 0; y
< h
; y
++)
167 CopyMem(src
, dst
, w
);
174 /* this is a plain total fast rulez copy */
175 CopyMem(src
, dst
, w
*h
);
179 AROS_UFH3(void, Enumerator
,
180 AROS_UFHA(struct Hook
*, hook
, A0
),
181 AROS_UFHA(OOP_Object
*, pciDevice
, A2
),
182 AROS_UFHA(APTR
, message
, A1
))
190 struct pHidd_PCIDriver_MapPCI mappci
,*msg
= &mappci
;
191 struct SM502_HWData
*sd
= hook
->h_Data
;
193 D(bug("[SM502] Enumerator: Found device\n"));
195 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&driver
);
196 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_VendorID
, &Vendor
);
198 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, (APTR
)&buf
);
199 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size0
, &size
);
201 mappci
.mID
= OOP_GetMethodID(IID_Hidd_PCIDriver
, moHidd_PCIDriver_MapPCI
);
202 mappci
.PCIAddress
= buf
;
203 mappci
.Length
= size
;
204 sd
->framebuffer
= (APTR
)OOP_DoMethod(driver
, (OOP_Msg
)msg
);
206 D(bug("[SM502] Got framebuffer @ %x (size=%x)\n", sd
->framebuffer
, size
));
208 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base1
, (APTR
)&buf
);
209 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size1
, &size
);
211 mappci
.mID
= OOP_GetMethodID(IID_Hidd_PCIDriver
, moHidd_PCIDriver_MapPCI
);
212 mappci
.PCIAddress
= buf
;
213 mappci
.Length
= size
;
214 sd
->mmio
= (APTR
)OOP_DoMethod(driver
, (OOP_Msg
)msg
);
216 D(bug("[SM502] Got mmio regs @ %x (size=%x)\n", sd
->mmio
, size
));
221 static BOOL
Find_PCI_Card(struct SM502_HWData
*sd
)
225 D(bug("[SM502] Find_PCI_Card\n"));
227 sd
->framebuffer
= sd
->mmio
= NULL
;
228 sd
->pciDeviceAttrBase
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
229 if (sd
->pciDeviceAttrBase
)
231 pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
233 D(bug("[SM502] Creating PCI object\n"));
237 struct Hook FindHook
= {
238 h_Entry
: (IPTR (*)())Enumerator
,
242 struct TagItem Requirements
[] = {
243 { tHidd_PCI_VendorID
, 0x126f },
244 { tHidd_PCI_ProductID
, 0x0501 },
248 struct pHidd_PCI_EnumDevices enummsg
= {
249 mID
: OOP_GetMethodID(IID_Hidd_PCI
, moHidd_PCI_EnumDevices
),
251 requirements
: (struct TagItem
*)&Requirements
,
253 D(bug("[SM502] Calling search Hook\n"));
254 OOP_DoMethod(pci
, (OOP_Msg
)msg
);
255 OOP_DisposeObject(pci
);
258 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
261 return (sd
->framebuffer
!= NULL
&& sd
->mmio
!= NULL
);
268 void DACLoad(struct SM502Gfx_staticdata
*xsd
, UBYTE
*DAC
,
269 unsigned char first
, int num
)
274 mode
= smread(&xsd
->data
, SM502_PDC
);
280 ObtainSemaphore(&xsd
->HW_acc
);
281 for (i
= 0; i
< num
; i
++, n
+=3) {
284 rgb
= (DAC
[n
+0] << 16) |
287 smwrite(&xsd
->data
, SM502_PPR
+ (i
<< 2), rgb
);
289 ReleaseSemaphore(&xsd
->HW_acc
);
294 ** clear the screen buffer
296 void ClearBuffer(struct SM502_HWData
*data
)
304 memset(data
->framebuffer
, 0x55, data
->height
* data
->bytesperline
);