alsa.audio: use correct name of libasound so file
[AROS.git] / workbench / hidds / sm502 / hardware.c
blob5f6d176b4e6063c5dcbced32c576c952837970f1
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: sm502 "hardware" functions
6 Lang: English
7 */
9 #include <aros/asmcall.h>
10 #include <aros/debug.h>
11 #include <aros/macros.h>
12 #include <aros/bootloader.h>
13 #include <asm/io.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>
19 #include <oop/oop.h>
20 #include <hidd/pci.h>
22 #include "bitmap.h"
23 #include "sm502gfxclass.h"
24 #include "hardware.h"
26 #include <string.h>
28 /* SM502 registers */
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)
40 ULONG mode;
42 /* Find the first device */
43 if (!Find_PCI_Card(hw)) {
44 D(bug("[SM502] No card found\n"));
45 return FALSE;
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) {
57 hw->disp_width /= 2;
59 if ((mode & 3) == 2) {
60 hw->disp_width /= 4;
63 /* Switch from 32 bit mode */
64 if ((mode & 3) != 2) {
65 int i;
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;
81 hw->redshift = 16;
82 hw->greenmask = 0xff << 16;
83 hw->greenshift = 8;
84 hw->bluemask = 0xff << 24;
85 hw->blueshift = 0;
86 hw->depth = 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,
94 hw->framebuffer));
95 ClearBuffer(hw);
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));
104 return TRUE;
107 void sm502DoRefreshArea(struct SM502_HWData *hwdata, struct BitmapData *data,
108 LONG x1, LONG y1, LONG x2, LONG y2)
110 UBYTE *src, *dst;
111 ULONG srcmod, dstmod;
112 LONG y, w, h;
113 LONG sx, sy;
115 x1 += data->xoffset;
116 y1 += data->yoffset;
117 x2 += data->xoffset;
118 y2 += data->yoffset;
120 /* Clip the rectangle against physical display borders */
121 if ((x1 >= data->disp_width) || (x2 < 1) ||
122 (y1 >= data->disp_height) || (y2 < 1))
123 return;
124 if (x1 < 0)
125 x1 = 0;
126 if (y1 < 0)
127 y1 = 0;
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 */
134 w = x2 - x1;
135 h = y2 - y1;
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.
154 if (!hwdata->owned)
156 RawPutChar(0x03);
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);
168 src += srcmod;
169 dst += dstmod;
172 else
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))
184 AROS_USERFUNC_INIT
186 APTR buf;
187 IPTR size;
188 IPTR Vendor;
189 OOP_Object *driver;
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));
218 AROS_USERFUNC_EXIT
221 static BOOL Find_PCI_Card(struct SM502_HWData *sd)
223 OOP_Object *pci;
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"));
235 if (pci)
237 struct Hook FindHook = {
238 h_Entry: (IPTR (*)())Enumerator,
239 h_Data: sd,
242 struct TagItem Requirements[] = {
243 { tHidd_PCI_VendorID, 0x126f },
244 { tHidd_PCI_ProductID, 0x0501 },
245 { TAG_DONE, 0UL }
248 struct pHidd_PCI_EnumDevices enummsg = {
249 mID: OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_EnumDevices),
250 callback: &FindHook,
251 requirements: (struct TagItem*)&Requirements,
252 }, *msg = &enummsg;
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);
265 ** DACLoad --
266 ** load a palette
268 void DACLoad(struct SM502Gfx_staticdata *xsd, UBYTE *DAC,
269 unsigned char first, int num)
271 int i, n;
272 ULONG mode;
274 mode = smread(&xsd->data, SM502_PDC);
275 if ((mode & 3) != 0)
276 return;
278 n = first * 3;
280 ObtainSemaphore(&xsd->HW_acc);
281 for (i = 0; i < num; i++, n+=3) {
282 ULONG rgb;
284 rgb = (DAC[n+0] << 16) |
285 (DAC[n+1] << 8) |
286 (DAC[n+2] << 0);
287 smwrite(&xsd->data, SM502_PPR + (i << 2), rgb);
289 ReleaseSemaphore(&xsd->HW_acc);
293 ** ClearBuffer --
294 ** clear the screen buffer
296 void ClearBuffer(struct SM502_HWData *data)
298 if (!data->owned)
300 RawPutChar(0x03);
301 data->owned = TRUE;
304 memset(data->framebuffer, 0x55, data->height * data->bytesperline);