]> git.sesse.net Git - pistorm/blob - platforms/amiga/rtg/rtg_driver_amiga/pigfx-2.c
Fix P96 2.1E(?) issues
[pistorm] / platforms / amiga / rtg / rtg_driver_amiga / pigfx-2.c
1 // SPDX-License-Identifier: MIT
2
3 // PiStorm RTG driver, VBCC edition.
4 // Based in part on the ZZ9000 RTG driver.
5
6 #include <proto/exec.h>
7 #include <proto/expansion.h>
8 #include <proto/dos.h>
9 #include <proto/intuition.h>
10 #include <proto/input.h>
11 #include <exec/types.h>
12 #include <exec/memory.h>
13 #include <exec/libraries.h>
14 #include <exec/execbase.h>
15 #include <exec/resident.h>
16 #include <exec/initializers.h>
17 #include <clib/debug_protos.h>
18 #include <devices/inputevent.h>
19 #include <string.h>
20 #include <stdint.h>
21 #include "boardinfo.h"
22 #include "../rtg_enums.h"
23
24 #define STR(s) #s
25 #define XSTR(s) STR(s)
26
27
28 #define CHECKRTG *((unsigned short *)(CARD_OFFSET))
29
30 #define CARD_OFFSET   0x70000000
31 #define IRTGCMD_OFFSET   0x70000060
32 #define CARD_REGSIZE  0x00010000
33 #define CARD_MEMSIZE  0x02000000 // 32MB "VRAM"
34 #define CARD_SCRATCH  0x72010000
35
36 #define WRITESHORT(cmd, val) *(unsigned short *)((unsigned long)(CARD_OFFSET+cmd)) = val;
37 #define WRITELONG(cmd, val) *(unsigned long *)((unsigned long)(CARD_OFFSET+cmd)) = val;
38 #define WRITEBYTE(cmd, val) *(unsigned char *)((unsigned long)(CARD_OFFSET+cmd)) = val;
39
40 #define READSHORT(cmd, var) var = *(volatile unsigned short *)(CARD_OFFSET + cmd);
41 #define READLONG(cmd, var) var = *(volatile unsigned long *)(CARD_OFFSET + cmd);
42
43 #define RTG_DEBUGME(val) *(volatile unsigned long *)((unsigned long)(CARD_OFFSET+RTG_DEBUGME)) = val;
44 //#define RTG_DEBUGME(...)
45 #define IWRITECMD(val) *(volatile unsigned short *)(IRTGCMD_OFFSET) = val;
46
47 #define CHIP_RAM_SIZE 0x00200000 // Chip RAM offset, 2MB
48
49 struct GFXBase {
50     struct Library libNode;
51     BPTR segList;
52     struct ExecBase* sysBase;
53     struct ExpansionBase* expansionBase;
54 };
55
56 #define __saveds__
57 #define kprintf(...)
58
59 struct ExecBase *SysBase;
60
61 int FindCard(__REGA0(struct BoardInfo* b));
62 int InitCard(__REGA0(struct BoardInfo* b));
63
64 void SetDAC (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format));
65 void SetGC (__REGA0(struct BoardInfo *b), __REGA1(struct ModeInfo *mode_info), __REGD0(BOOL border));
66 void SetColorArray (__REGA0(struct BoardInfo *b), __REGD0(UWORD start), __REGD1(UWORD num));
67 void SetPanning (__REGA0(struct BoardInfo *b), __REGA1(UBYTE *addr), __REGD0(UWORD width), __REGD1(WORD x_offset), __REGD2(WORD y_offset), __REGD7(RGBFTYPE format));
68 UWORD SetSwitch (__REGA0(struct BoardInfo *b), __REGD0(UWORD enabled));
69 UWORD SetDisplay (__REGA0(struct BoardInfo *b), __REGD0(UWORD enabled));
70
71 UWORD CalculateBytesPerRow (__REGA0(struct BoardInfo *b), __REGD0(UWORD width), __REGD7(RGBFTYPE format));
72 APTR CalculateMemory (__REGA0(struct BoardInfo *b), __REGA1(unsigned long addr), __REGD7(RGBFTYPE format));
73 ULONG GetCompatibleFormats (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format));
74
75 LONG ResolvePixelClock (__REGA0(struct BoardInfo *b), __REGA1(struct ModeInfo *mode_info), __REGD0(ULONG pixel_clock), __REGD7(RGBFTYPE format));
76 ULONG GetPixelClock (__REGA0(struct BoardInfo *b), __REGA1(struct ModeInfo *mode_info), __REGD0(ULONG index), __REGD7(RGBFTYPE format));
77 void SetClock (__REGA0(struct BoardInfo *b));
78
79 void SetMemoryMode (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format));
80 void SetWriteMask (__REGA0(struct BoardInfo *b), __REGD0(UBYTE mask));
81 void SetClearMask (__REGA0(struct BoardInfo *b), __REGD0(UBYTE mask));
82 void SetReadPlane (__REGA0(struct BoardInfo *b), __REGD0(UBYTE plane));
83
84 void WaitVerticalSync (__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle));
85 BOOL GetVSyncState(__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle));
86
87 void FillRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(ULONG color), __REGD5(UBYTE mask), __REGD7(RGBFTYPE format));
88 void InvertRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(UBYTE mask), __REGD7(RGBFTYPE format));
89 void BlitRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD dx), __REGD3(WORD dy), __REGD4(WORD w), __REGD5(WORD h), __REGD6(UBYTE mask), __REGD7(RGBFTYPE format));
90 void BlitRectNoMaskComplete (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *rs), __REGA2(struct RenderInfo *rt), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD dx), __REGD3(WORD dy), __REGD4(WORD w), __REGD5(WORD h), __REGD6(UBYTE minterm), __REGD7(RGBFTYPE format));
91 void BlitTemplate (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Template *t), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(UBYTE mask), __REGD7(RGBFTYPE format));
92 void BlitPattern (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Pattern *p), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(UBYTE mask), __REGD7(RGBFTYPE format));
93 void DrawLine (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Line *l), __REGD0(UBYTE mask), __REGD7(RGBFTYPE format));
94
95 void BlitPlanar2Chunky (__REGA0(struct BoardInfo *b), __REGA1(struct BitMap *bm), __REGA2(struct RenderInfo *r), __REGD0(SHORT x), __REGD1(SHORT y), __REGD2(SHORT dx), __REGD3(SHORT dy), __REGD4(SHORT w), __REGD5(SHORT h), __REGD6(UBYTE minterm), __REGD7(UBYTE mask));
96 void BlitPlanar2Direct (__REGA0(struct BoardInfo *b), __REGA1(struct BitMap *bmp), __REGA2(struct RenderInfo *r), __REGA3(struct ColorIndexMapping *clut), __REGD0(SHORT x), __REGD1(SHORT y), __REGD2(SHORT dx), __REGD3(SHORT dy), __REGD4(SHORT w), __REGD5(SHORT h), __REGD6(UBYTE minterm), __REGD7(UBYTE mask));
97
98 void SetSprite (__REGA0(struct BoardInfo *b), __REGD0(BOOL what), __REGD7(RGBFTYPE format));
99 void SetSpritePosition (__REGA0(struct BoardInfo *b), __REGD0(WORD x), __REGD1(WORD y), __REGD7(RGBFTYPE format));
100 void SetSpriteImage (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format));
101 void SetSpriteColor (__REGA0(struct BoardInfo *b), __REGD0(UBYTE idx), __REGD1(UBYTE R), __REGD2(UBYTE G), __REGD3(UBYTE B), __REGD7(RGBFTYPE format));
102
103 #define DEVICE_VERSION 43
104 #define DEVICE_REVISION 20
105 #define DEVICE_PRIORITY 0
106 #define DEVICE_ID_STRING "PiGFX " XSTR(DEVICE_VERSION) "." XSTR(DEVICE_REVISION) " " DEVICE_DATE
107 #define DEVICE_NAME "pigfx.card"
108 #define DEVICE_DATE "(29 May 2021)"
109
110
111 int __attribute__((no_reorder)) _start()
112 {
113         return -1;
114 }
115
116 asm("romtag:                                    \n"
117         "       dc.w    "XSTR(RTC_MATCHWORD)"   \n"
118         "       dc.l    romtag                  \n"
119         "       dc.l    endcode                 \n"
120         "       dc.b    "XSTR(RTF_AUTOINIT)"    \n"
121         "       dc.b    "XSTR(DEVICE_VERSION)"  \n"
122         "       dc.b    "XSTR(NT_LIBRARY)"      \n"
123         "       dc.b    "XSTR(DEVICE_PRIORITY)" \n"
124         "       dc.l    _device_name            \n"
125         "       dc.l    _device_id_string       \n"
126         "       dc.l    _auto_init_tables       \n"
127         "endcode:                               \n");
128
129 char device_name[] = DEVICE_NAME;
130 char device_id_string[] = DEVICE_ID_STRING;
131
132 __saveds struct GFXBase* OpenLib(__REGA6(struct GFXBase *gfxbase));
133 BPTR __saveds CloseLib(__REGA6(struct GFXBase *gfxbase));
134 BPTR __saveds ExpungeLib(__REGA6(struct GFXBase *exb));
135 ULONG ExtFuncLib(void);
136 __saveds struct GFXBase* InitLib(__REGA6(struct ExecBase *sysbase),
137                                                                  __REGA0(BPTR seglist),
138                                                                  __REGD0(struct GFXBase *exb));
139
140 #define CLOCK_HZ 100000000
141
142 static struct GFXBase *_gfxbase;
143 const char *gfxname = "PiStorm RTG";
144 char dummies[128];
145
146 __saveds struct GFXBase* __attribute__((used)) InitLib(__REGA6(struct ExecBase *sysbase),
147                                                        __REGA0(BPTR seglist),
148                                                        __REGD0(struct GFXBase *exb))
149 {
150     _gfxbase = exb;
151     SysBase = *(struct ExecBase **)4L;
152     return _gfxbase;
153 }
154
155 __saveds struct GFXBase* __attribute__((used)) OpenLib(__REGA6(struct GFXBase *gfxbase))
156 {
157     gfxbase->libNode.lib_OpenCnt++;
158     gfxbase->libNode.lib_Flags &= ~LIBF_DELEXP;
159
160     return gfxbase;
161 }
162
163 BPTR __saveds __attribute__((used)) CloseLib(__REGA6(struct GFXBase *gfxbase))
164 {
165     gfxbase->libNode.lib_OpenCnt--;
166
167     if (!gfxbase->libNode.lib_OpenCnt) {
168         if (gfxbase->libNode.lib_Flags & LIBF_DELEXP) {
169             return (ExpungeLib(gfxbase));
170         }
171     }
172     return 0;
173 }
174
175 BPTR __saveds __attribute__((used)) ExpungeLib(__REGA6(struct GFXBase *exb))
176 {
177     BPTR seglist;
178     struct ExecBase *SysBase = *(struct ExecBase **)4L;
179
180     if(!exb->libNode.lib_OpenCnt) {
181         ULONG negsize, possize, fullsize;
182         UBYTE *negptr = (UBYTE *)exb;
183
184         seglist = exb->segList;
185
186         Remove((struct Node *)exb);
187
188         negsize  = exb->libNode.lib_NegSize;
189         possize  = exb->libNode.lib_PosSize;
190         fullsize = negsize + possize;
191         negptr  -= negsize;
192
193         FreeMem(negptr, fullsize);
194         return(seglist);
195     }
196
197     exb->libNode.lib_Flags |= LIBF_DELEXP;
198     return 0;
199 }
200
201 ULONG ExtFuncLib(void)
202 {
203     return 0;
204 }
205
206 #define LOADLIB(a, b) if ((a = (struct a*)OpenLibrary((STRPTR)b,0L))==NULL) { \
207         kprintf((STRPTR)"Failed to load %s.\n", b); \
208         return 0; \
209     } \
210
211
212 int __attribute__((used)) FindCard(__REGA0(struct BoardInfo* b)) {
213     uint16_t card_check = CHECKRTG;
214     if (card_check != 0xFFCF) {
215         // RTG not enabled
216         return 0;
217     }
218
219     struct IORequest io;
220     if (OpenDevice((STRPTR)"input.device", 0, &io, 0) == 0)
221     {
222         struct Library *InputBase = (struct Library *)io.io_Device;
223         UWORD qual = PeekQualifier();
224         CloseDevice(&io);
225
226         if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
227             return(FALSE);
228     }
229
230     struct ExpansionBase *ExpansionBase = NULL;
231     struct DOSBase *DOSBase = NULL;
232     struct IntuitionBase *IntuitionBase = NULL;
233
234     LOADLIB(ExpansionBase, "expansion.library");
235     LOADLIB(DOSBase, "dos.library");
236     LOADLIB(IntuitionBase, "intuition.library");
237
238     b->MemorySize = CARD_MEMSIZE;
239     b->RegisterBase = (void *)CARD_OFFSET;
240     b->MemoryBase = (void *)(CARD_OFFSET + CARD_REGSIZE);
241
242     return 1;
243 }
244
245 #define HWSPRITE 1
246 #define VGASPLIT (1 << 6)
247 #define FLICKERFIXER (1 << 12)
248 #define INDISPLAYCHAIN (1 << 20)
249 #define DIRECTACCESS (1 << 26)
250
251 int __attribute__((used)) InitCard(__REGA0(struct BoardInfo* b)) {
252     int i;
253     kprintf("Wueh! %ld\n", sizeof(BOOL));
254
255     b->CardBase = (struct CardBase *)_gfxbase;
256     b->ExecBase = SysBase;
257     b->BoardName = "PiStorm RTG";
258     b->BoardType = 14;
259     b->PaletteChipType = PCT_S3ViRGE;
260     b->GraphicsControllerType = GCT_S3ViRGE;
261
262     b->Flags = BIF_INDISPLAYCHAIN | BIF_GRANTDIRECTACCESS | BIF_HARDWARESPRITE | BIF_FLICKERFIXER;
263     b->RGBFormats = 1 | 2 | 512 | 1024 | 2048;
264     b->SoftSpriteFlags = 0;
265     b->BitsPerCannon = 8;
266
267     for(i = 0; i < MAXMODES; i++) {
268         b->MaxHorValue[i] = 8192;
269         b->MaxVerValue[i] = 8192;
270         b->MaxHorResolution[i] = 8192;
271         b->MaxVerResolution[i] = 8192;
272         b->PixelClockCount[i] = 1;
273     }
274
275     b->MemoryClock = CLOCK_HZ;
276
277     //b->AllocCardMem = (void *)NULL;
278     //b->FreeCardMem = (void *)NULL;
279     b->SetSwitch = (void *)SetSwitch;
280     b->SetColorArray = (void *)SetColorArray;
281     b->SetDAC = (void *)SetDAC;
282     b->SetGC = (void *)SetGC;
283     b->SetPanning = (void *)SetPanning;
284     b->CalculateBytesPerRow = (void *)CalculateBytesPerRow;
285     b->CalculateMemory = (void *)CalculateMemory;
286     b->GetCompatibleFormats = (void *)GetCompatibleFormats;
287     b->SetDisplay = (void *)SetDisplay;
288
289     b->ResolvePixelClock = (void *)ResolvePixelClock;
290     b->GetPixelClock = (void *)GetPixelClock;
291     b->SetClock = (void *)SetClock;
292
293     b->SetMemoryMode = (void *)SetMemoryMode;
294     b->SetWriteMask = (void *)SetWriteMask;
295     b->SetClearMask = (void *)SetClearMask;
296     b->SetReadPlane = (void *)SetReadPlane;
297
298     b->WaitVerticalSync = (void *)WaitVerticalSync;
299     //b->SetInterrupt = (void *)NULL;
300
301     //b->WaitBlitter = (void *)NULL;
302
303     //b->ScrollPlanar = (void *)NULL;
304     //b->UpdatePlanar = (void *)NULL;
305
306     b->BlitPlanar2Chunky = (void *)BlitPlanar2Chunky;
307     b->BlitPlanar2Direct = (void *)BlitPlanar2Direct;
308
309     b->FillRect = (void *)FillRect;
310     b->InvertRect = (void *)InvertRect;
311     b->BlitRect = (void *)BlitRect;
312     b->BlitTemplate = (void *)BlitTemplate;
313     b->BlitPattern = (void *)BlitPattern;
314     b->DrawLine = (void *)DrawLine;
315     b->BlitRectNoMaskComplete = (void *)BlitRectNoMaskComplete;
316     //b->EnableSoftSprite = (void *)NULL;
317
318     //b->AllocCardMemAbs = (void *)NULL;
319     //b->SetSplitPosition = (void *)NULL;
320     //b->ReInitMemory = (void *)NULL;
321     //b->WriteYUVRect = (void *)NULL;
322     b->GetVSyncState = (void *)GetVSyncState;
323     //b->GetVBeamPos = (void *)NULL;
324     //b->SetDPMSLevel = (void *)NULL;
325     //b->ResetChip = (void *)NULL;
326     //b->GetFeatureAttrs = (void *)NULL;
327     //b->AllocBitMap = (void *)NULL;
328     //b->FreeBitMap = (void *)NULL;
329     //b->GetBitMapAttr = (void *)NULL;
330
331     b->SetSprite = (void *)SetSprite;
332     b->SetSpritePosition = (void *)SetSpritePosition;
333     b->SetSpriteImage = (void *)SetSpriteImage;
334     b->SetSpriteColor = (void *)SetSpriteColor;
335
336     //b->CreateFeature = (void *)NULL;
337     //b->SetFeatureAttrs = (void *)NULL;
338     //b->DeleteFeature = (void *)NULL;
339
340     return 1;
341 }
342
343 void SetDAC (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format)) {
344     // Used to set the color format of the video card's RAMDAC.
345     // This needs no handling, since the PiStorm doesn't really have a RAMDAC or a video card chipset.
346 }
347
348 void SetGC (__REGA0(struct BoardInfo *b), __REGA1(struct ModeInfo *mode_info), __REGD0(BOOL border)) {
349     b->ModeInfo = mode_info;
350     // Send width, height and format to the RaspberryPi Targetable Graphics.
351     WRITESHORT(RTG_X1, mode_info->Width);
352     WRITESHORT(RTG_Y1, mode_info->Height);
353     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[b->RGBFormat]);
354     WRITESHORT(RTG_COMMAND, RTGCMD_SETGC);
355 }
356
357 int setswitch = -1;
358 UWORD SetSwitch (__REGA0(struct BoardInfo *b), __REGD0(UWORD enabled)) {
359     if (setswitch != enabled) {
360         setswitch = enabled;
361     }
362     
363     WRITEBYTE(RTG_U81, setswitch);
364     WRITESHORT(RTG_X1, setswitch);
365     WRITESHORT(RTG_COMMAND, RTGCMD_SETSWITCH);
366
367     return 1 - enabled;
368 }
369
370 void SetPanning (__REGA0(struct BoardInfo *b), __REGA1(UBYTE *addr), __REGD0(UWORD width), __REGD1(WORD x_offset), __REGD2(WORD y_offset), __REGD7(RGBFTYPE format)) {
371     // Set the panning offset, or the offset used for the current display area on the Pi.
372     // The address needs to have CARD_BASE subtracted from it to be used as an offset on the Pi side.
373 #ifndef IRTG
374     if (!b)
375         return;
376
377     b->XOffset = x_offset;
378     b->YOffset = y_offset;
379
380     WRITELONG(RTG_ADDR1, (unsigned long)addr);
381     WRITESHORT(RTG_X1, width);
382     WRITESHORT(RTG_X2, b->XOffset);
383     WRITESHORT(RTG_Y2, b->YOffset);
384     WRITESHORT(RTG_COMMAND, RTGCMD_SETPAN);
385 #else
386     IWRITECMD(RTGCMD_SETPAN);
387 #endif
388 }
389
390 void SetColorArray (__REGA0(struct BoardInfo *b), __REGD0(UWORD start), __REGD1(UWORD num)) {
391     // Sets the color components of X color components for 8-bit paletted display modes.
392     if (!b->CLUT)
393         return;
394     
395     int j = start + num;
396     
397     for(int i = start; i < j; i++) {
398         //WRITEBYTE(RTG_U82, (unsigned char)b->CLUT[i].Red);
399         //WRITEBYTE(RTG_U83, (unsigned char)b->CLUT[i].Green);
400         //WRITEBYTE(RTG_U84, (unsigned char)b->CLUT[i].Blue);
401         unsigned long xrgb = 0 | (b->CLUT[i].Red << 16) | (b->CLUT[i].Green << 8) | (b->CLUT[i].Blue);
402         WRITEBYTE(RTG_U81, (unsigned char)i);
403         WRITELONG(RTG_RGB1, xrgb);
404         WRITESHORT(RTG_COMMAND, RTGCMD_SETCLUT);
405     }
406 }
407
408 UWORD CalculateBytesPerRow (__REGA0(struct BoardInfo *b), __REGD0(UWORD width), __REGD7(RGBFTYPE format)) {
409     if (!b)
410         return 0;
411
412     UWORD pitch = width;
413
414     switch(format) {
415         default:
416             return pitch;
417         case 0x05: case 0x0A: case 0x0B: case 0x0D:
418             return (width * 2);
419         case 0x08: case 0x09:
420             return (width * 4);
421     }
422 }
423
424 APTR CalculateMemory (__REGA0(struct BoardInfo *b), __REGA1(unsigned long addr), __REGD7(RGBFTYPE format)) {
425     /*if (!b)
426         return (APTR)addr;
427
428     if (addr > (unsigned int)b->MemoryBase && addr < (((unsigned int)b->MemoryBase) + b->MemorySize)) {
429         addr = ((addr + 0x1000) & 0xFFFFF000);
430     }*/
431
432     return (APTR)addr;
433 }
434
435 ULONG GetCompatibleFormats (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format)) {
436     // It is of course compatible with all the formats ever.
437     return 0xFFFFFFFF;
438 }
439
440 //static int display_enabled = 0;
441 UWORD SetDisplay (__REGA0(struct BoardInfo *b), __REGD0(UWORD enabled)) {
442     // Enables or disables the display.
443     WRITEBYTE(RTG_U82, (unsigned char)enabled);
444     WRITESHORT(RTG_COMMAND, RTGCMD_SETDISPLAY);
445
446     return 1;
447 }
448
449 LONG ResolvePixelClock (__REGA0(struct BoardInfo *b), __REGA1(struct ModeInfo *mode_info), __REGD0(ULONG pixel_clock), __REGD7(RGBFTYPE format)) {
450     mode_info->PixelClock = CLOCK_HZ;
451     mode_info->pll1.Clock = 0;
452     mode_info->pll2.ClockDivide = 1;
453
454     return 0;
455 }
456
457 ULONG GetPixelClock (__REGA0(struct BoardInfo *b), __REGA1(struct ModeInfo *mode_info), __REGD0(ULONG index), __REGD7(RGBFTYPE format)) {
458     // Just return 100MHz.
459     return CLOCK_HZ;
460 }
461
462 // None of these five really have to do anything.
463 void SetClock (__REGA0(struct BoardInfo *b)) {
464 }
465
466 void SetMemoryMode (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format)) {
467 }
468
469 void SetWriteMask (__REGA0(struct BoardInfo *b), __REGD0(UBYTE mask)) {
470 }
471
472 void SetClearMask (__REGA0(struct BoardInfo *b), __REGD0(UBYTE mask)) {
473 }
474
475 void SetReadPlane (__REGA0(struct BoardInfo *b), __REGD0(UBYTE plane)) {
476 }
477
478 static uint16_t vblank;
479
480 void WaitVerticalSync (__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle)) {
481     vblank = 0;
482     do {
483         READSHORT(RTG_WAITVSYNC, vblank);
484     } while (!vblank);
485 }
486
487 BOOL GetVSyncState(__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle)) {
488     READSHORT(RTG_INVBLANK, vblank);
489     return vblank;
490 }
491
492 void FillRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(ULONG color), __REGD5(UBYTE mask), __REGD7(RGBFTYPE format)) {
493 #ifndef IRTG
494     if (!r)
495         return;
496
497     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
498     
499     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
500     WRITESHORT(RTG_X1, x);
501     WRITESHORT(RTG_X2, w);
502     WRITESHORT(RTG_Y1, y);
503     WRITESHORT(RTG_Y2, h);
504     WRITELONG(RTG_RGB1, color);
505     WRITESHORT(RTG_X3, r->BytesPerRow);
506     WRITEBYTE(RTG_U81, mask);
507     WRITESHORT(RTG_COMMAND, RTGCMD_FILLRECT);
508 #else
509     IWRITECMD(RTGCMD_FILLRECT);
510 #endif
511 }
512
513 void InvertRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(UBYTE mask), __REGD7(RGBFTYPE format)) {
514 #ifndef IRTG
515     if (!r)
516         return;
517     
518     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
519     
520     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
521     WRITESHORT(RTG_X1, x);
522     WRITESHORT(RTG_X2, w);
523     WRITESHORT(RTG_Y1, y);
524     WRITESHORT(RTG_Y2, h);
525     WRITESHORT(RTG_X3, r->BytesPerRow);
526     WRITEBYTE(RTG_U81, mask);
527     WRITESHORT(RTG_COMMAND, RTGCMD_INVERTRECT);
528 #else
529     IWRITECMD(RTGCMD_INVERTRECT);
530 #endif
531 }
532
533 void BlitRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD dx), __REGD3(WORD dy), __REGD4(WORD w), __REGD5(WORD h), __REGD6(UBYTE mask), __REGD7(RGBFTYPE format)) {
534 #ifndef IRTG    
535     if (!r)
536         return;
537
538     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
539
540     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
541     WRITESHORT(RTG_X1, x);
542     WRITESHORT(RTG_X2, dx);
543     WRITESHORT(RTG_X3, w);
544     WRITESHORT(RTG_Y1, y);
545     WRITESHORT(RTG_Y2, dy);
546     WRITESHORT(RTG_Y3, h);
547     WRITESHORT(RTG_X4, r->BytesPerRow);
548     WRITEBYTE(RTG_U81, mask);
549     WRITESHORT(RTG_COMMAND, RTGCMD_BLITRECT);
550 #else
551     IWRITECMD(RTGCMD_BLITRECT);
552 #endif
553 }
554
555 void BlitRectNoMaskComplete (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *rs), __REGA2(struct RenderInfo *rt), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD dx), __REGD3(WORD dy), __REGD4(WORD w), __REGD5(WORD h), __REGD6(UBYTE minterm), __REGD7(RGBFTYPE format)) {
556 #ifndef IRTG
557     if (!rs || !rt)
558         return;
559
560     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
561     WRITELONG(RTG_ADDR1, (unsigned long)rs->Memory);
562     WRITELONG(RTG_ADDR2, (unsigned long)rt->Memory);
563     WRITESHORT(RTG_X1, x);
564     WRITESHORT(RTG_X2, dx);
565     WRITESHORT(RTG_X3, w);
566     WRITESHORT(RTG_Y1, y);
567     WRITESHORT(RTG_Y2, dy);
568     WRITESHORT(RTG_Y3, h);
569     WRITESHORT(RTG_X4, rs->BytesPerRow);
570     WRITESHORT(RTG_X5, rt->BytesPerRow);
571     WRITEBYTE(RTG_U81, minterm);
572     WRITESHORT(RTG_COMMAND, RTGCMD_BLITRECT_NOMASK_COMPLETE);
573 #else
574     IWRITECMD(RTGCMD_BLITRECT_NOMASK_COMPLETE);
575 #endif
576 }
577
578 void BlitTemplate (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Template *t), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(UBYTE mask), __REGD7(RGBFTYPE format)) {
579 #ifndef IRTG
580     if (!r || !t) return;
581     if (w < 1 || h < 1) return;
582
583     WRITELONG(RTG_ADDR2, (unsigned long)r->Memory);
584
585     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
586     WRITESHORT(RTG_X1, x);
587     WRITESHORT(RTG_X2, w);
588     WRITESHORT(RTG_X3, t->XOffset);
589     WRITESHORT(RTG_Y1, y);
590     WRITESHORT(RTG_Y2, h);
591     WRITESHORT(RTG_Y3, 0);
592
593     if ((unsigned long)t->Memory > CHIP_RAM_SIZE) {
594         WRITELONG(RTG_ADDR1, (unsigned long)t->Memory);
595     }
596     else {
597         unsigned long dest = CARD_SCRATCH;
598         memcpy((unsigned char *)dest, t->Memory, (t->BytesPerRow * h));
599         WRITELONG(RTG_ADDR1, (unsigned long)dest);
600         WRITELONG(RTG_ADDR3, (unsigned long)t->Memory);
601     }
602
603     WRITELONG(RTG_RGB1, t->FgPen);
604     WRITELONG(RTG_RGB2, t->BgPen);
605
606     WRITESHORT(RTG_X4, r->BytesPerRow);
607     WRITESHORT(RTG_X5, t->BytesPerRow);
608
609     WRITEBYTE(RTG_U81, mask);
610     WRITEBYTE(RTG_U82, t->DrawMode);
611     WRITESHORT(RTG_COMMAND, RTGCMD_BLITTEMPLATE);
612 #else
613     IWRITECMD(RTGCMD_BLITTEMPLATE);
614 #endif
615 }
616
617 void BlitPattern (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Pattern *p), __REGD0(WORD x), __REGD1(WORD y), __REGD2(WORD w), __REGD3(WORD h), __REGD4(UBYTE mask), __REGD7(RGBFTYPE format)) {
618 #ifndef IRTG
619     if (!r || !p) return;
620     if (w < 1 || h < 1) return;
621
622     WRITELONG(RTG_ADDR2, (unsigned long)r->Memory);
623
624     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
625     WRITESHORT(RTG_X1, x);
626     WRITESHORT(RTG_X2, w);
627     WRITESHORT(RTG_X3, p->XOffset);
628     WRITESHORT(RTG_Y1, y);
629     WRITESHORT(RTG_Y2, h);
630     WRITESHORT(RTG_Y3, p->YOffset);
631
632     if ((unsigned long)p->Memory > CHIP_RAM_SIZE) {
633         WRITELONG(RTG_ADDR1, (unsigned long)p->Memory);
634     }
635     else {
636         unsigned long dest = CARD_SCRATCH;
637         memcpy((unsigned char *)dest, p->Memory, (2 * (1 << p->Size)));
638         WRITELONG(RTG_ADDR1, (unsigned long)dest);
639     }
640
641     WRITELONG(RTG_RGB1, p->FgPen);
642     WRITELONG(RTG_RGB2, p->BgPen);
643
644     WRITESHORT(RTG_X4, r->BytesPerRow);
645     WRITESHORT(RTG_X5, (1 << p->Size));
646
647     WRITEBYTE(RTG_U81, mask);
648     WRITEBYTE(RTG_U82, p->DrawMode);
649     WRITEBYTE(RTG_U83, (1 << p->Size));
650     WRITESHORT(RTG_COMMAND, RTGCMD_BLITPATTERN);
651 #else
652     IWRITECMD(RTGCMD_BLITPATTERN);
653 #endif
654 }
655
656 void DrawLine (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Line *l), __REGD0(UBYTE mask), __REGD7(RGBFTYPE format)) {
657 #ifndef IRTG
658     if (!r || !b) return;
659
660     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
661
662     WRITELONG(RTG_RGB1, l->FgPen);
663     WRITELONG(RTG_RGB2, l->BgPen);
664
665     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
666
667     WRITESHORT(RTG_X1, l->X);
668     WRITESHORT(RTG_X2, l->dX);
669     WRITESHORT(RTG_Y1, l->Y);
670     WRITESHORT(RTG_Y2, l->dY);
671
672     WRITESHORT(RTG_X3, l->Length);
673     WRITESHORT(RTG_Y3, l->LinePtrn);
674
675     WRITESHORT(RTG_X4, r->BytesPerRow);
676     WRITESHORT(RTG_X5, l->PatternShift);
677
678     WRITEBYTE(RTG_U81, mask);
679     WRITEBYTE(RTG_U82, l->DrawMode);
680     WRITEBYTE(RTG_U83, l->pad);
681     WRITESHORT(RTG_COMMAND, RTGCMD_DRAWLINE);
682 #else
683     IWRITECMD(RTGCMD_DRAWLINE);
684 #endif
685 }
686
687 void BlitPlanar2Chunky (__REGA0(struct BoardInfo *b), __REGA1(struct BitMap *bm), __REGA2(struct RenderInfo *r), __REGD0(SHORT x), __REGD1(SHORT y), __REGD2(SHORT dx), __REGD3(SHORT dy), __REGD4(SHORT w), __REGD5(SHORT h), __REGD6(UBYTE minterm), __REGD7(UBYTE mask)) {
688 // iRTG path disabled for now, since it's really slow, see note in rtg-gfx.c.
689 //#ifndef IRTG    
690     if (!b || !r)
691         return;
692
693     //uint32_t plane_size = bm->BytesPerRow * bm->Rows;
694
695     uint32_t template_addr = CARD_SCRATCH;
696
697     uint16_t plane_mask = mask;
698     uint8_t ff_mask = 0x00;
699     uint8_t cur_plane = 0x01;
700
701     uint16_t line_size = (w >> 3) + 2;
702     uint32_t output_plane_size = line_size * h;
703     //uint16_t x_offset = (x >> 3);
704
705     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
706     WRITELONG(RTG_ADDR2, template_addr);
707     WRITESHORT(RTG_X4, r->BytesPerRow);
708     WRITESHORT(RTG_X5, line_size);
709     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[r->RGBFormat]);
710
711     WRITEBYTE(RTG_U81, mask);
712     WRITEBYTE(RTG_U82, minterm);
713
714     for (int16_t i = 0; i < bm->Depth; i++) {
715         uint16_t x_offset = (x >> 3);
716         if ((uint32_t)bm->Planes[i] == 0xFFFFFFFF) {
717             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
718             memset(dest, 0xFF, output_plane_size);
719         }
720         else if (bm->Planes[i] != NULL) {
721             uint8_t* bmp_mem = (uint8_t*)bm->Planes[i] + (y * bm->BytesPerRow) + x_offset;
722             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
723             for (int16_t y_line = 0; y_line < h; y_line++) {
724                 memcpy(dest, bmp_mem, line_size);
725                 dest += line_size;
726                 bmp_mem += bm->BytesPerRow;
727             }
728         }
729         else {
730             plane_mask &= (cur_plane ^ 0xFF);
731         }
732         cur_plane <<= 1;
733         template_addr += output_plane_size;
734     }
735
736     WRITESHORT(RTG_X1, (x & 0x07));
737     WRITESHORT(RTG_X2, dx);
738     WRITESHORT(RTG_X3, w);
739     WRITESHORT(RTG_Y1, 0);
740     WRITESHORT(RTG_Y2, dy);
741     WRITESHORT(RTG_Y3, h);
742
743     WRITESHORT(RTG_U1, (plane_mask << 8 | ff_mask));
744     WRITEBYTE(RTG_U83, bm->Depth);
745
746     WRITESHORT(RTG_COMMAND, RTGCMD_P2C);
747 //#else
748 //    IWRITECMD(RTGCMD_P2C);
749 //#endif
750 }
751
752 void BlitPlanar2Direct (__REGA0(struct BoardInfo *b), __REGA1(struct BitMap *bm), __REGA2(struct RenderInfo *r), __REGA3(struct ColorIndexMapping *clut), __REGD0(SHORT x), __REGD1(SHORT y), __REGD2(SHORT dx), __REGD3(SHORT dy), __REGD4(SHORT w), __REGD5(SHORT h), __REGD6(UBYTE minterm), __REGD7(UBYTE mask)) {
753     if (!b || !r)
754         return;
755
756     //uint32_t plane_size = bm->BytesPerRow * bm->Rows;
757
758     uint32_t template_addr = CARD_SCRATCH;
759
760     uint16_t plane_mask = mask;
761     uint8_t ff_mask = 0x00;
762     uint8_t cur_plane = 0x01;
763
764     uint16_t line_size = (w >> 3) + 2;
765     uint32_t output_plane_size = line_size * h;
766     //uint16_t x_offset = (x >> 3);
767
768     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
769     WRITELONG(RTG_ADDR2, template_addr);
770     WRITESHORT(RTG_X4, r->BytesPerRow);
771     WRITESHORT(RTG_X5, line_size);
772     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[r->RGBFormat]);
773
774     WRITEBYTE(RTG_U81, mask);
775     WRITEBYTE(RTG_U82, minterm);
776
777     memcpy((uint8_t*)((uint32_t)template_addr), clut->Colors, (256 << 2));
778     template_addr += (256 << 2);
779
780     for (int16_t i = 0; i < bm->Depth; i++) {
781         uint16_t x_offset = (x >> 3);
782         if ((uint32_t)bm->Planes[i] == 0xFFFFFFFF) {
783             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
784             memset(dest, 0xFF, output_plane_size);
785         }
786         else if (bm->Planes[i] != NULL) {
787             uint8_t* bmp_mem = (uint8_t*)bm->Planes[i] + (y * bm->BytesPerRow) + x_offset;
788             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
789             for (int16_t y_line = 0; y_line < h; y_line++) {
790                 memcpy(dest, bmp_mem, line_size);
791                 dest += line_size;
792                 bmp_mem += bm->BytesPerRow;
793             }
794         }
795         else {
796             plane_mask &= (cur_plane ^ 0xFF);
797         }
798         cur_plane <<= 1;
799         template_addr += output_plane_size;
800     }
801
802     WRITESHORT(RTG_X1, (x & 0x07));
803     WRITESHORT(RTG_X2, dx);
804     WRITESHORT(RTG_X3, w);
805     WRITESHORT(RTG_Y1, 0);
806     WRITESHORT(RTG_Y2, dy);
807     WRITESHORT(RTG_Y3, h);
808
809     WRITESHORT(RTG_U1, (plane_mask << 8 | ff_mask));
810     WRITEBYTE(RTG_U83, bm->Depth);
811
812     WRITESHORT(RTG_COMMAND, RTGCMD_P2D);
813 }
814
815 void SetSprite (__REGA0(struct BoardInfo *b), __REGD0(BOOL what), __REGD7(RGBFTYPE format)) {
816     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITE);
817 }
818
819 void SetSpritePosition (__REGA0(struct BoardInfo *b), __REGD0(WORD x), __REGD1(WORD y), __REGD7(RGBFTYPE format)) {
820     WRITESHORT(RTG_X1, x);
821     WRITESHORT(RTG_Y1, y);
822
823     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITEPOS);
824 }
825
826 void SetSpriteImage (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format)) {
827     WRITESHORT(RTG_X1, b->XOffset);
828     WRITESHORT(RTG_Y1, b->YOffset);
829     WRITEBYTE(RTG_U81, b->MouseWidth);
830     WRITEBYTE(RTG_U82, b->MouseHeight);
831
832     uint8_t* dest = (uint8_t*)((uint32_t)CARD_SCRATCH);
833     uint8_t* src = (uint8_t *)b->MouseImage;
834     uint16_t data_size = ((b->MouseWidth >> 3) * 2) * (b->MouseHeight);
835
836     if (b->MouseWidth > 16) src += 8;
837     else src += 4;
838
839     memcpy(dest, src, data_size);
840
841     WRITELONG(RTG_ADDR2, CARD_SCRATCH);
842
843     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITEIMAGE);
844 }
845
846 void SetSpriteColor (__REGA0(struct BoardInfo *b), __REGD0(UBYTE idx), __REGD1(UBYTE R), __REGD2(UBYTE G), __REGD3(UBYTE B), __REGD7(RGBFTYPE format)) {
847     WRITEBYTE(RTG_U81, R);
848     WRITEBYTE(RTG_U82, G);
849     WRITEBYTE(RTG_U83, B);
850     WRITEBYTE(RTG_U84, idx);
851
852     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITECOLOR);
853 }
854
855 static uint32_t device_vectors[] = {
856     (uint32_t)OpenLib,
857     (uint32_t)CloseLib,
858     (uint32_t)ExpungeLib,
859     0,
860     (uint32_t)FindCard,
861     (uint32_t)InitCard,
862     -1
863 };
864
865 struct InitTable
866 {
867     ULONG LibBaseSize;
868     APTR  FunctionTable;
869     APTR  DataTable;
870     APTR  InitLibTable;
871 };
872
873 const uint32_t auto_init_tables[4] = {
874     sizeof(struct Library),
875     (uint32_t)device_vectors,
876     0,
877     (uint32_t)InitLib,
878 };