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