added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / common / hidd.nvidia / nvidiaclass.c
blob203184676d4cd6a56c83ee4291ce6d193f1bfffd
1 /*
2 Copyright © 2004-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: NVidia gfx class
6 Lang: English
7 */
9 #include <exec/types.h>
10 #include <exec/memory.h>
12 #include <hidd/hidd.h>
13 #include <hidd/graphics.h>
15 #include <proto/exec.h>
16 #include <proto/oop.h>
17 #include <proto/utility.h>
19 #include "nv.h"
20 #include "nv_dma.h"
22 #define DEBUG 0
23 #include <aros/debug.h>
25 #define _sd (&((LIBBASETYPEPTR)cl->UserData)->sd)
27 #undef HiddPCIDeviceAttrBase
28 #undef HiddGfxAttrBase
29 #undef HiddPixFmtAttrBase
30 #undef HiddSyncAttrBase
31 #undef HiddBitMapAttrBase
32 #define HiddPCIDeviceAttrBase (_sd->pciAttrBase)
33 #define HiddNVidiaBitMapAttrBase (_sd->nvBitMapAttrBase)
34 #define HiddBitMapAttrBase (_sd->bitMapAttrBase)
35 #define HiddPixFmtAttrBase (_sd->pixFmtAttrBase)
36 #define HiddGfxAttrBase (_sd->gfxAttrBase)
37 #define HiddSyncAttrBase (_sd->syncAttrBase)
39 /* Class methods */
41 VOID NV__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
43 ULONG idx;
44 BOOL found = FALSE;
45 if (IS_GFX_ATTR(msg->attrID, idx))
47 switch (idx)
49 case aoHidd_Gfx_SupportsHWCursor:
50 *msg->storage = (IPTR)TRUE;
51 found = TRUE;
52 break;
54 case aoHidd_Gfx_DPMSLevel:
55 *msg->storage = _sd->dpms;
56 found = TRUE;
57 break;
61 if (!found)
62 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
64 return;
67 VOID NV__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
69 ULONG idx;
70 struct TagItem *tags, *tag;
72 tags = msg->attrList;
74 while ((tag = NextTagItem(&tags)))
76 if (IS_GFX_ATTR(tag->ti_Tag, idx))
78 switch(idx)
80 case aoHidd_Gfx_DPMSLevel:
81 LOCK_HW
83 DPMS(_sd, tag->ti_Data);
84 _sd->dpms = tag->ti_Data;
86 UNLOCK_HW
87 break;
92 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
95 #define MAKE_SYNC(name,clock,hdisp,hstart,hend,htotal,vdisp,vstart,vend,vtotal,descr) \
96 struct TagItem sync_ ## name[]={ \
97 { aHidd_Sync_PixelClock, clock*1000 }, \
98 { aHidd_Sync_HDisp, hdisp }, \
99 { aHidd_Sync_HSyncStart, hstart }, \
100 { aHidd_Sync_HSyncEnd, hend }, \
101 { aHidd_Sync_HTotal, htotal }, \
102 { aHidd_Sync_VDisp, vdisp }, \
103 { aHidd_Sync_VSyncStart, vstart }, \
104 { aHidd_Sync_VSyncEnd, vend }, \
105 { aHidd_Sync_VTotal, vtotal }, \
106 { aHidd_Sync_Description, (IPTR)descr}, \
107 { TAG_DONE, 0UL }}
109 OOP_Object *NV__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
111 struct TagItem pftags_24bpp[] = {
112 { aHidd_PixFmt_RedShift, 8 }, /* 0 */
113 { aHidd_PixFmt_GreenShift, 16 }, /* 1 */
114 { aHidd_PixFmt_BlueShift, 24 }, /* 2 */
115 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
116 { aHidd_PixFmt_RedMask, 0x00ff0000 }, /* 4 */
117 { aHidd_PixFmt_GreenMask, 0x0000ff00 }, /* 5 */
118 { aHidd_PixFmt_BlueMask, 0x000000ff }, /* 6 */
119 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
120 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
121 { aHidd_PixFmt_Depth, 24 }, /* 9 */
122 { aHidd_PixFmt_BytesPerPixel, 4 }, /* 10 */
123 { aHidd_PixFmt_BitsPerPixel, 24 }, /* 11 */
124 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_BGR032 }, /* 12 Native */
125 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
126 { TAG_DONE, 0UL }
129 struct TagItem pftags_16bpp[] = {
130 { aHidd_PixFmt_RedShift, 16 }, /* 0 */
131 { aHidd_PixFmt_GreenShift, 21 }, /* 1 */
132 { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
133 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
134 { aHidd_PixFmt_RedMask, 0x0000f800 }, /* 4 */
135 { aHidd_PixFmt_GreenMask, 0x000007e0 }, /* 5 */
136 { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
137 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
138 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
139 { aHidd_PixFmt_Depth, 16 }, /* 9 */
140 { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
141 { aHidd_PixFmt_BitsPerPixel, 16 }, /* 11 */
142 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB16_LE }, /* 12 */
143 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
144 { TAG_DONE, 0UL }
147 struct TagItem pftags_15bpp[] = {
148 { aHidd_PixFmt_RedShift, 17 }, /* 0 */
149 { aHidd_PixFmt_GreenShift, 22 }, /* 1 */
150 { aHidd_PixFmt_BlueShift, 27 }, /* 2 */
151 { aHidd_PixFmt_AlphaShift, 0 }, /* 3 */
152 { aHidd_PixFmt_RedMask, 0x00007c00 }, /* 4 */
153 { aHidd_PixFmt_GreenMask, 0x000003e0 }, /* 5 */
154 { aHidd_PixFmt_BlueMask, 0x0000001f }, /* 6 */
155 { aHidd_PixFmt_AlphaMask, 0x00000000 }, /* 7 */
156 { aHidd_PixFmt_ColorModel, vHidd_ColorModel_TrueColor }, /* 8 */
157 { aHidd_PixFmt_Depth, 15 }, /* 9 */
158 { aHidd_PixFmt_BytesPerPixel, 2 }, /* 10 */
159 { aHidd_PixFmt_BitsPerPixel, 15 }, /* 11 */
160 { aHidd_PixFmt_StdPixFmt, vHidd_StdPixFmt_RGB15_LE }, /* 12 */
161 { aHidd_PixFmt_BitMapType, vHidd_BitMapType_Chunky }, /* 15 */
162 { TAG_DONE, 0UL }
165 MAKE_SYNC(640x480_60, 25174,
166 640, 656, 752, 800,
167 480, 490, 492, 525,
168 "NVIDIA:640x480");
170 MAKE_SYNC(800x600_56, 36000, // 36000
171 800, 824, 896, 1024,
172 600, 601, 603, 625,
173 "NVIDIA:800x600");
175 MAKE_SYNC(1024x768_60, 65000, //78654=60kHz, 75Hz. 65000=50kHz,62Hz
176 1024, 1048, 1184, 1344,
177 768, 771, 777, 806,
178 "NVIDIA:1024x768");
180 MAKE_SYNC(1152x864_60, 80000,
181 1152, 1216, 1328, 1456,
182 864, 870, 875, 916,
183 "NVIDIA:1152x864");
185 MAKE_SYNC(1280x1024_60, 107991,
186 1280, 1328, 1440, 1688,
187 1024, 1025, 1028, 1066,
188 "NVIDIA:1280x1024");
190 MAKE_SYNC(1600x1200_60, 155982,
191 1600, 1632, 1792, 2048,
192 1200, 1210, 1218, 1270,
193 "NVIDIA:1600x1200");
195 struct TagItem modetags[] = {
196 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_24bpp },
197 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_16bpp },
198 { aHidd_Gfx_PixFmtTags, (IPTR)pftags_15bpp },
199 { aHidd_Gfx_SyncTags, (IPTR)sync_640x480_60 },
200 { aHidd_Gfx_SyncTags, (IPTR)sync_800x600_56 },
201 { aHidd_Gfx_SyncTags, (IPTR)sync_1024x768_60 },
202 { aHidd_Gfx_SyncTags, (IPTR)sync_1152x864_60 },
203 { aHidd_Gfx_SyncTags, (IPTR)sync_1280x1024_60 },
204 { aHidd_Gfx_SyncTags, (IPTR)sync_1600x1200_60 },
206 { TAG_DONE, 0UL }
209 struct TagItem mytags[] = {
210 { aHidd_Gfx_ModeTags, (IPTR)modetags },
211 { TAG_MORE, (IPTR)msg->attrList }
214 struct pRoot_New mymsg;
216 mymsg.mID = msg->mID;
217 mymsg.attrList = mytags;
219 msg = &mymsg;
221 EnterFunc(bug("[NVidia] nv::new()\n"));
223 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
224 if (o)
226 _sd->nvobject = o;
229 return o;
232 OOP_Object *NV__Hidd_Gfx__NewBitMap(OOP_Class *cl, OOP_Object *o,
233 struct pHidd_Gfx_NewBitMap *msg)
235 BOOL displayable, framebuffer;
236 OOP_Class *classptr = NULL;
237 struct TagItem mytags[2];
238 struct pHidd_Gfx_NewBitMap mymsg;
240 /* Displayable bitmap ? */
241 displayable = GetTagData(aHidd_BitMap_Displayable, FALSE, msg->attrList);
242 framebuffer = GetTagData(aHidd_BitMap_FrameBuffer, FALSE, msg->attrList);
244 D(bug("[NVidia] NewBitmap: framebuffer=%d, displayable=%d\n", framebuffer, displayable));
246 if (framebuffer)
248 /* If the user asks for a framebuffer map we must ALLWAYS supply a class */
249 classptr = _sd->onbmclass;
251 else if (displayable)
253 classptr = _sd->onbmclass; //offbmclass;
255 else
257 HIDDT_ModeID modeid;
259 For the non-displayable case we can either supply a class ourselves
260 if we can optimize a certain type of non-displayable bitmaps. Or we
261 can let the superclass create on for us.
263 The attributes that might come from the user deciding the bitmap
264 pixel format are:
265 - aHidd_BitMap_ModeID: a modeid. create a nondisplayable
266 bitmap with the size and pixelformat of a gfxmode.
267 - aHidd_BitMap_StdPixFmt: a standard pixelformat as described in
268 hidd/graphics.h
269 - aHidd_BitMap_Friend: if this is supplied and none of the two above
270 are supplied, then the pixel format of the created bitmap
271 will be the same as the one of the friend bitmap.
273 These tags are listed in prioritized order, so if
274 the user supplied a ModeID tag, then you should not care about StdPixFmt
275 or Friend. If there is no ModeID, but a StdPixFmt tag supplied,
276 then you should not care about Friend because you have to
277 create the correct pixelformat. And as said above, if only Friend
278 is supplied, you can create a bitmap with same pixelformat as Frien
282 modeid = (HIDDT_ModeID)GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
283 if (vHidd_ModeID_Invalid != modeid) {
284 /* User supplied a valid modeid. We can use our offscreen class */
285 classptr = _sd->onbmclass;
286 } else {
287 /* We may create an offscreen bitmap if the user supplied a friend
288 bitmap. But we need to check that he did not supplied a StdPixFmt
290 HIDDT_StdPixFmt stdpf;
291 stdpf = (HIDDT_StdPixFmt)GetTagData(aHidd_BitMap_StdPixFmt, vHidd_StdPixFmt_Unknown, msg->attrList);
292 if (vHidd_StdPixFmt_Plane == stdpf) {
293 classptr = _sd->planarbmclass;
295 else if (vHidd_StdPixFmt_Unknown == stdpf) {
296 /* No std pixfmt supplied */
297 OOP_Object *friend;
299 /* Did the user supply a friend bitmap ? */
300 friend = (OOP_Object *)GetTagData(aHidd_BitMap_Friend, 0, msg->attrList);
301 if (NULL != friend) {
302 OOP_Object * gfxhidd;
303 /* User supplied friend bitmap. Is the friend bitmap a
304 NVidia Gfx hidd bitmap ? */
305 OOP_GetAttr(friend, aHidd_BitMap_GfxHidd, (APTR)&gfxhidd);
306 if (gfxhidd == o) {
307 /* Friend was NVidia hidd bitmap. Now we can supply our own class */
308 classptr = _sd->offbmclass;
315 D(bug("classptr = %p\n", classptr));
316 /* Do we supply our own class ? */
317 if (NULL != classptr) {
318 /* Yes. We must let the superclass not that we do this. This is
319 done through adding a tag in the frot of the taglist */
320 mytags[0].ti_Tag = aHidd_BitMap_ClassPtr;
321 mytags[0].ti_Data = (IPTR)classptr;
322 mytags[1].ti_Tag = TAG_MORE;
323 mytags[1].ti_Data = (IPTR)msg->attrList;
325 /* Like in Gfx::New() we init a new message struct */
326 mymsg.mID = msg->mID;
327 mymsg.attrList = mytags;
329 /* Pass the new message to the superclass */
330 msg = &mymsg;
333 return (OOP_Object*)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
336 OOP_Object *NV__Hidd_Gfx__Show(OOP_Class *cl, OOP_Object *o,
337 struct pHidd_Gfx_Show *msg)
339 OOP_Object *fb = NULL;
340 if (msg->bitMap)
342 nvBitMap *bm = OOP_INST_DATA(OOP_OCLASS(msg->bitMap), msg->bitMap);
344 if (bm->state)
346 /* Suppose bm has properly allocated state structure */
347 if (bm->fbgfx)
349 bm->usecount++;
351 LOCK_HW
353 LoadState(_sd, bm->state);
354 DPMS(_sd, _sd->dpms);
356 fb = bm->BitMap;
357 NVShowHideCursor(_sd, _sd->Card.cursorVisible);
359 UNLOCK_HW
364 if (!fb)
365 fb = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
367 return fb;
370 VOID NV__Hidd_Gfx__CopyBox(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_CopyBox *msg)
372 ULONG mode = GC_DRMD(msg->gc);
373 IPTR src=0, dst=0;
375 /* Check whether we can get Drawable attribute of our nVidia class */
376 OOP_GetAttr(msg->src, aHidd_nvBitMap_Drawable, &src);
377 OOP_GetAttr(msg->dest, aHidd_nvBitMap_Drawable, &dst);
379 if (!dst || !src)
381 /* No. One of the bitmaps is not nVidia bitmap */
382 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
384 else
386 /* Yes. Get the instance data of both bitmaps */
387 nvBitMap *bm_src = OOP_INST_DATA(OOP_OCLASS(msg->src), msg->src);
388 nvBitMap *bm_dst = OOP_INST_DATA(OOP_OCLASS(msg->dest), msg->dest);
390 /* Case -1: (To be fixed) one of the bitmaps have chunky outside GFX mem */
391 if (!bm_src->fbgfx || !bm_dst->fbgfx)
393 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
395 /* Case 0: one of bitmaps is 8bpp, whereas the other is TrueColor one */
396 else if ((bm_src->depth <= 8 || bm_dst->depth <= 8) &&
397 (bm_src->depth != bm_dst->depth))
399 /* Unsupported case */
400 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
401 return;
403 /* Case 1: both bitmaps have the same depth - use Blit engine */
404 else if (bm_src->depth == bm_dst->depth)
406 LOCK_MULTI_BITMAP
407 LOCK_BITMAP_BM(bm_src)
408 LOCK_BITMAP_BM(bm_dst)
409 UNLOCK_MULTI_BITMAP
411 LOCK_HW
413 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
414 _sd->gpu_busy = TRUE;
416 NVSetRopSolid(_sd, mode, ~0 << bm_src->depth);
418 if (bm_dst->surface_format != _sd->surface_format)
420 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
421 NVDmaNext(&_sd->Card, bm_dst->surface_format);
422 _sd->surface_format = bm_dst->surface_format;
423 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
425 if ((bm_dst->pitch != _sd->dst_pitch) || (bm_src->pitch != _sd->src_pitch))
427 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
428 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | bm_src->pitch);
429 _sd->src_pitch = bm_src->pitch;
430 _sd->dst_pitch = bm_dst->pitch;
431 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
433 if (bm_src->framebuffer != _sd->src_offset)
435 NVDmaStart(&_sd->Card, SURFACE_OFFSET_SRC, 1);
436 NVDmaNext(&_sd->Card, bm_src->framebuffer);
437 _sd->src_offset = bm_src->framebuffer;
438 // D(bug("[NVidia] src_offset=%p\n", _sd->src_offset));
440 if (bm_dst->framebuffer != _sd->dst_offset)
442 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
443 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
444 _sd->dst_offset = bm_dst->framebuffer;
445 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
448 NVDmaStart(&_sd->Card, BLIT_POINT_SRC, 3);
449 NVDmaNext(&_sd->Card, (msg->srcY << 16) | (msg->srcX & 0xffff));
450 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX & 0xffff));
451 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width & 0xffff));
453 NVDmaKickoff(&_sd->Card);
454 //NVSync(_sd);
456 UNLOCK_HW
458 UNLOCK_BITMAP_BM(bm_src)
459 UNLOCK_BITMAP_BM(bm_dst)
462 else /* Case 2: different bitmaps. use Stretch engine */
464 LOCK_MULTI_BITMAP
465 LOCK_BITMAP_BM(bm_src)
466 LOCK_BITMAP_BM(bm_dst)
467 UNLOCK_MULTI_BITMAP
469 LOCK_HW
471 _sd->Card.DMAKickoffCallback = NVDMAKickoffCallback;
472 _sd->gpu_busy = TRUE;
474 if ((bm_dst->surface_format != _sd->surface_format) && bm_dst->depth != 15)
477 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
478 NVDmaNext(&_sd->Card, bm_dst->surface_format);
479 _sd->surface_format = bm_dst->surface_format;
480 // D(bug("[NVidia] surface_format <- %d\n", _sd->surface_format));
483 if (bm_dst->depth == 15)
485 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
486 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH15);
487 _sd->surface_format = SURFACE_FORMAT_DEPTH16;
490 if (bm_dst->pitch != _sd->dst_pitch)
492 NVDmaStart(&_sd->Card, SURFACE_PITCH, 1);
493 NVDmaNext(&_sd->Card, (bm_dst->pitch << 16) | _sd->src_pitch);
494 _sd->dst_pitch = bm_dst->pitch;
495 // D(bug("[NVidia] pitch <- %08x\n", (_sd->dst_pitch << 16) | _sd->src_pitch));
498 if (bm_dst->framebuffer != _sd->dst_offset)
500 NVDmaStart(&_sd->Card, SURFACE_OFFSET_DST, 1);
501 NVDmaNext(&_sd->Card, bm_dst->framebuffer);
502 _sd->dst_offset = bm_dst->framebuffer;
503 // D(bug("[NVidia] dst_offset=%p\n", _sd->dst_offset));
506 NVDmaStart(&_sd->Card, RECT_SOLID_COLOR, 1);
507 NVDmaNext(&_sd->Card, 0);
509 NVDmaStart(&_sd->Card, STRETCH_BLIT_FORMAT, 1);
510 switch (bm_src->depth)
512 case 15:
513 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH15);
514 break;
515 case 16:
516 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH16);
517 break;
518 case 24:
519 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH24);
520 break;
521 default:
522 NVDmaNext(&_sd->Card, STRETCH_BLIT_FORMAT_DEPTH8);
523 break;
526 NVDmaStart(&_sd->Card, STRETCH_BLIT_CLIP_POINT, 6);
527 NVDmaNext(&_sd->Card, 0x00000000); // dst_CLip
528 NVDmaNext(&_sd->Card, 0xffffffff); // dst_Clip
529 NVDmaNext(&_sd->Card, (msg->destY << 16) | (msg->destX));// dst_y | dst_x
530 NVDmaNext(&_sd->Card, (msg->height << 16)| (msg->width));// dst_h | dst_w
531 NVDmaNext(&_sd->Card, 1 << 20); // src_w / dst_w 1:1
532 NVDmaNext(&_sd->Card, 1 << 20); // src_h / dst_h 1:1
534 NVDmaStart(&_sd->Card, STRETCH_BLIT_SRC_SIZE, 4);
535 NVDmaNext(&_sd->Card, (msg->height << 16) | (msg->width));// src_h | src_w
536 NVDmaNext(&_sd->Card,
537 (STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE << 24) | // BILINEAR | _POINT_SAMPLE
538 (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER << 16) |
539 (bm_src->pitch)); // src_pitch
540 NVDmaNext(&_sd->Card, bm_src->framebuffer); // src_offset
541 NVDmaNext(&_sd->Card, ((msg->srcY << 20) & 0xffff0000)
542 | ((msg->srcX << 4) & 0xffff)); // src_y | src_x
544 NVDmaKickoff(&_sd->Card);
546 if (bm_dst->depth == 15)
548 NVDmaStart(&_sd->Card, SURFACE_FORMAT, 1);
549 NVDmaNext(&_sd->Card, SURFACE_FORMAT_DEPTH16);
551 //NVSync(_sd);
553 UNLOCK_HW
555 UNLOCK_BITMAP_BM(bm_src)
556 UNLOCK_BITMAP_BM(bm_dst)
560 D(bug("[NVidia] CopyBox(src(%p,%d:%d@%d),dst(%p,%d:%d@%d),%d:%d\n",
561 bm_src->framebuffer,msg->srcX,msg->srcY,bm_src->depth,
562 bm_dst->framebuffer,msg->destX,msg->destY,bm_dst->depth,
563 msg->width, msg->height));
565 bm_src->usecount++;
566 bm_dst->usecount++;
570 #define ToRGB555(c) \
571 (((c & 0xf80000) >> 9) | ((c & 0xf800) >> 6) | ((c & 0xf8) >> 3) | 0x8000)
573 #define ToRGB8888(alp,c) ((c) | ((alp) << 24))
575 static void TransformCursor(struct staticdata *);
577 BOOL NV__Hidd_Gfx__SetCursorShape(OOP_Class *cl, OOP_Object *o, struct pHidd_Gfx_SetCursorShape *msg)
579 // bug("SetCursorShape %p\n", msg->shape);
580 // return OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
581 if (msg->shape == NULL)
583 NVShowHideCursor(_sd, 0);
584 _sd->Card.cursorVisible = 0;
586 else
588 OOP_Object *pfmt;
589 OOP_Object *colormap;
590 HIDDT_StdPixFmt pixfmt;
591 HIDDT_Color color;
593 ULONG width, height, x, y;
594 ULONG maxw,maxh;
596 ULONG *curimg = (ULONG*)((IPTR)_sd->Card.CursorStart + (IPTR)_sd->Card.FrameBuffer);
598 struct pHidd_BitMap_GetPixel __gp = {
599 mID: OOP_GetMethodID(IID_Hidd_BitMap, moHidd_BitMap_GetPixel)
600 }, *getpixel = &__gp;
602 struct pHidd_ColorMap_GetColor __gc = {
603 mID: OOP_GetMethodID(IID_Hidd_ColorMap, moHidd_ColorMap_GetColor),
604 colorReturn: &color,
605 }, *getcolor = &__gc;
607 OOP_GetAttr(msg->shape, aHidd_BitMap_Width, &width);
608 OOP_GetAttr(msg->shape, aHidd_BitMap_Height, &height);
609 OOP_GetAttr(msg->shape, aHidd_BitMap_PixFmt, (APTR)&pfmt);
610 OOP_GetAttr(pfmt, aHidd_PixFmt_StdPixFmt, &pixfmt);
611 OOP_GetAttr(msg->shape, aHidd_BitMap_ColorMap, (APTR)&colormap);
613 if (_sd->Card.alphaCursor)
615 if (width > 64) width = 64;
616 if (height > 64) height = 64;
618 maxw = 64;
619 maxh = 64;
621 else
623 if (width > 32) width = 32;
624 if (height > 32) height = 32;
626 maxw = 32;
627 maxh = 32;
630 LOCK_HW
632 for (x = 0; x < maxw*maxh; x++)
633 curimg[x] = 0;
635 for (y = 0; y < height; y++)
637 for (x = 0; x < width; x++)
639 HIDDT_Pixel pixel;
640 getpixel->x = x;
641 getpixel->y = y;
642 pixel = OOP_DoMethod(msg->shape, (OOP_Msg)getpixel);
644 if (pixfmt == vHidd_StdPixFmt_LUT8)
646 getcolor->colorNo = pixel;
647 OOP_DoMethod(colormap, (OOP_Msg)getcolor);
648 pixel = ((color.red << 8) & 0xff0000) |
649 ((color.green) & 0x00ff00) |
650 ((color.blue >> 8) & 0x0000ff);
652 curimg[maxw*2+3] = pixel ? 0x50000000 : 0x00000000;
653 if (pixel)
654 *curimg++ = pixel;
655 else curimg++;
658 for (x=width; x < maxw; x++, curimg++)
659 if (*curimg!=0x50000000) *curimg = 0;
662 for (y=height; y < maxh; y++)
663 for (x=0; x < maxw; x++)
664 { if (*curimg!=0x50000000) *curimg = 0; curimg++; }
666 UNLOCK_HW
669 TransformCursor(_sd);
670 return TRUE;
673 VOID NV__Hidd_Gfx__SetCursorVisible(OOP_Class *cl, OOP_Object *o,
674 struct pHidd_Gfx_SetCursorVisible *msg)
676 NVShowHideCursor(_sd, msg->visible);
677 _sd->Card.cursorVisible = msg->visible;
680 VOID NV__Hidd_Gfx__SetCursorPos(OOP_Class *cl, OOP_Object *o,
681 struct pHidd_Gfx_SetCursorPos *msg)
683 _sd->Card.PRAMDAC[0x0300 / 4] = (msg->y << 16) | (msg->x & 0xffff);
685 /* Class related functions */
687 #undef _sd
688 #define _sd sd
690 static void TransformCursor(struct staticdata *sd)
692 ULONG *tmp = AllocPooled(sd->memPool, 4 * 64 * 64);
693 ULONG dwords,i;
694 ULONG *curimg = (ULONG*)((IPTR)sd->Card.CursorStart + (IPTR)sd->Card.FrameBuffer);
697 if (sd->Card.alphaCursor)
699 dwords = 64*64;
700 for (i=0; i < dwords; i++)
702 UBYTE alp;
703 if (curimg[i] == 0) alp = 0;
704 else alp = 0xe0;
706 if (curimg[i] == 0x50000000) ((ULONG*)tmp)[i] = ToRGB8888(0x50,0);
707 else ((ULONG*)tmp)[i] = ToRGB8888(alp, curimg[i]);
710 else
712 dwords = (32*32) >> 1;
714 for(i=0; i < dwords; i++)
716 if (!curimg[i]) ((UWORD*)tmp)[i] = 0;
717 else ((UWORD*)tmp)[i] = ToRGB555(curimg[i]);
721 LOCK_HW
723 for (i=0; i < dwords; i++)
724 sd->Card.CURSOR[i] = tmp[i];
726 UNLOCK_HW
728 FreePooled(sd->memPool, tmp, 4*64*64);
733 Allocates some memory area on GFX card, which may be sufficient for bitmap
734 with given size and depth. The must_have bit may be defined but doesn't
735 have to. If it is TRUE, the allocator will do everything to get the memory -
736 eg. it will throw other bitmaps away from it or it will shift them within
737 GFX memory
740 IPTR AllocBitmapArea(struct staticdata *sd, ULONG width, ULONG height,
741 ULONG bpp, BOOL must_have)
743 IPTR result;
745 LOCK_HW
747 Forbid();
748 result = (IPTR)Allocate(sd->CardMem, ((width * bpp + 63) & ~63) * height);
749 Permit();
751 D(bug("[NVidia] AllocBitmapArea(%dx%d@%d) = %p\n",
752 width, height, bpp, result));
754 If Allocate failed, make the 0xffffffff as return. If it succeeded, make
755 the memory pointer relative to the begin of GFX memory
757 if (result == 0) --result;
758 else result -= (IPTR)sd->Card.FrameBuffer;
760 UNLOCK_HW
762 /* Generic thing. Will be extended later */
763 return result;
766 VOID FreeBitmapArea(struct staticdata *sd, IPTR bmp, ULONG width, ULONG height,
767 ULONG bpp)
769 APTR ptr = (APTR)(bmp + sd->Card.FrameBuffer);
771 LOCK_HW
773 D(bug("[NVidia] FreeBitmapArea(%p,%dx%d@%d)\n",
774 bmp, width, height, bpp));
776 Forbid();
777 Deallocate(sd->CardMem, ptr, ((width * bpp + 63) & ~63) * height);
778 Permit();
780 UNLOCK_HW