]> git.sesse.net Git - pistorm/blob - platforms/amiga/rtg/rtg_driver_amiga/pigfx-2.c
Fix iRTG BlitTemplate add iRTG BlitPattern support
[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 #ifndef IRTG
556     if (!r || !t) return;
557     if (w < 1 || h < 1) return;
558
559     WRITELONG(RTG_ADDR2, (unsigned long)r->Memory);
560
561     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
562     WRITESHORT(RTG_X1, x);
563     WRITESHORT(RTG_X2, w);
564     WRITESHORT(RTG_X3, t->XOffset);
565     WRITESHORT(RTG_Y1, y);
566     WRITESHORT(RTG_Y2, h);
567     WRITESHORT(RTG_Y3, 0);
568
569     if ((unsigned long)t->Memory > CHIP_RAM_SIZE) {
570         WRITELONG(RTG_ADDR1, (unsigned long)t->Memory);
571     }
572     else {
573         unsigned long dest = CARD_SCRATCH;
574         memcpy((unsigned char *)dest, t->Memory, (t->BytesPerRow * h));
575         WRITELONG(RTG_ADDR1, (unsigned long)dest);
576         WRITELONG(RTG_ADDR3, (unsigned long)t->Memory);
577     }
578
579     WRITELONG(RTG_RGB1, t->FgPen);
580     WRITELONG(RTG_RGB2, t->BgPen);
581
582     WRITESHORT(RTG_X4, r->BytesPerRow);
583     WRITESHORT(RTG_X5, t->BytesPerRow);
584
585     WRITEBYTE(RTG_U81, mask);
586     WRITEBYTE(RTG_U82, t->DrawMode);
587     WRITESHORT(RTG_COMMAND, RTGCMD_BLITTEMPLATE);
588 #else
589     IWRITECMD(RTGCMD_BLITTEMPLATE);
590 #endif
591 }
592
593 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)) {
594 #ifndef IRTG
595     if (!r || !p) return;
596     if (w < 1 || h < 1) return;
597
598     WRITELONG(RTG_ADDR2, (unsigned long)r->Memory);
599
600     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
601     WRITESHORT(RTG_X1, x);
602     WRITESHORT(RTG_X2, w);
603     WRITESHORT(RTG_X3, p->XOffset);
604     WRITESHORT(RTG_Y1, y);
605     WRITESHORT(RTG_Y2, h);
606     WRITESHORT(RTG_Y3, p->YOffset);
607
608     if ((unsigned long)p->Memory > CHIP_RAM_SIZE) {
609         WRITELONG(RTG_ADDR1, (unsigned long)p->Memory);
610     }
611     else {
612         unsigned long dest = CARD_SCRATCH;
613         memcpy((unsigned char *)dest, p->Memory, (2 * (1 << p->Size)));
614         WRITELONG(RTG_ADDR1, (unsigned long)dest);
615     }
616
617     WRITELONG(RTG_RGB1, p->FgPen);
618     WRITELONG(RTG_RGB2, p->BgPen);
619
620     WRITESHORT(RTG_X4, r->BytesPerRow);
621     WRITESHORT(RTG_X5, (1 << p->Size));
622
623     WRITEBYTE(RTG_U81, mask);
624     WRITEBYTE(RTG_U82, p->DrawMode);
625     WRITEBYTE(RTG_U83, (1 << p->Size));
626     WRITESHORT(RTG_COMMAND, RTGCMD_BLITPATTERN);
627 #else
628     IWRITECMD(RTGCMD_BLITPATTERN);
629 #endif
630 }
631
632 void DrawLine (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Line *l), __REGD0(UBYTE mask), __REGD7(RGBFTYPE format)) {
633 #ifndef IRTG
634     if (!r || !b) return;
635
636     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
637
638     WRITELONG(RTG_RGB1, l->FgPen);
639     WRITELONG(RTG_RGB2, l->BgPen);
640
641     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]);
642
643     WRITESHORT(RTG_X1, l->X);
644     WRITESHORT(RTG_X2, l->dX);
645     WRITESHORT(RTG_Y1, l->Y);
646     WRITESHORT(RTG_Y2, l->dY);
647
648     WRITESHORT(RTG_X3, l->Length);
649     WRITESHORT(RTG_Y3, l->LinePtrn);
650
651     WRITESHORT(RTG_X4, r->BytesPerRow);
652     WRITESHORT(RTG_X5, l->PatternShift);
653
654     WRITEBYTE(RTG_U81, mask);
655     WRITEBYTE(RTG_U82, l->DrawMode);
656     WRITEBYTE(RTG_U83, l->pad);
657     WRITESHORT(RTG_COMMAND, RTGCMD_DRAWLINE);
658 #else
659     IWRITECMD(RTGCMD_DRAWLINE);
660 #endif
661 }
662
663 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)) {
664     if (!b || !r)
665         return;
666
667     //uint32_t plane_size = bm->BytesPerRow * bm->Rows;
668
669     uint32_t template_addr = CARD_SCRATCH;
670
671     uint16_t plane_mask = mask;
672     uint8_t ff_mask = 0x00;
673     uint8_t cur_plane = 0x01;
674
675     uint16_t line_size = (w >> 3) + 2;
676     uint32_t output_plane_size = line_size * h;
677     //uint16_t x_offset = (x >> 3);
678
679     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
680     WRITELONG(RTG_ADDR2, template_addr);
681     WRITESHORT(RTG_X4, r->BytesPerRow);
682     WRITESHORT(RTG_X5, line_size);
683     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[r->RGBFormat]);
684
685     WRITEBYTE(RTG_U81, mask);
686     WRITEBYTE(RTG_U82, minterm);
687
688     for (int16_t i = 0; i < bm->Depth; i++) {
689         uint16_t x_offset = (x >> 3);
690         if ((uint32_t)bm->Planes[i] == 0xFFFFFFFF) {
691             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
692             memset(dest, 0xFF, output_plane_size);
693         }
694         else if (bm->Planes[i] != NULL) {
695             uint8_t* bmp_mem = (uint8_t*)bm->Planes[i] + (y * bm->BytesPerRow) + x_offset;
696             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
697             for (int16_t y_line = 0; y_line < h; y_line++) {
698                 memcpy(dest, bmp_mem, line_size);
699                 dest += line_size;
700                 bmp_mem += bm->BytesPerRow;
701             }
702         }
703         else {
704             plane_mask &= (cur_plane ^ 0xFF);
705         }
706         cur_plane <<= 1;
707         template_addr += output_plane_size;
708     }
709
710     WRITESHORT(RTG_X1, (x & 0x07));
711     WRITESHORT(RTG_X2, dx);
712     WRITESHORT(RTG_X3, w);
713     WRITESHORT(RTG_Y1, 0);
714     WRITESHORT(RTG_Y2, dy);
715     WRITESHORT(RTG_Y3, h);
716
717     WRITESHORT(RTG_U1, (plane_mask << 8 | ff_mask));
718     WRITEBYTE(RTG_U83, bm->Depth);
719
720     WRITESHORT(RTG_COMMAND, RTGCMD_P2C);
721 }
722
723 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)) {
724     if (!b || !r)
725         return;
726
727     //uint32_t plane_size = bm->BytesPerRow * bm->Rows;
728
729     uint32_t template_addr = CARD_SCRATCH;
730
731     uint16_t plane_mask = mask;
732     uint8_t ff_mask = 0x00;
733     uint8_t cur_plane = 0x01;
734
735     uint16_t line_size = (w >> 3) + 2;
736     uint32_t output_plane_size = line_size * h;
737     //uint16_t x_offset = (x >> 3);
738
739     WRITELONG(RTG_ADDR1, (unsigned long)r->Memory);
740     WRITELONG(RTG_ADDR2, template_addr);
741     WRITESHORT(RTG_X4, r->BytesPerRow);
742     WRITESHORT(RTG_X5, line_size);
743     WRITESHORT(RTG_FORMAT, rgbf_to_rtg[r->RGBFormat]);
744
745     WRITEBYTE(RTG_U81, mask);
746     WRITEBYTE(RTG_U82, minterm);
747
748     memcpy((uint8_t*)((uint32_t)template_addr), clut->Colors, (256 << 2));
749     template_addr += (256 << 2);
750
751     for (int16_t i = 0; i < bm->Depth; i++) {
752         uint16_t x_offset = (x >> 3);
753         if ((uint32_t)bm->Planes[i] == 0xFFFFFFFF) {
754             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
755             memset(dest, 0xFF, output_plane_size);
756         }
757         else if (bm->Planes[i] != NULL) {
758             uint8_t* bmp_mem = (uint8_t*)bm->Planes[i] + (y * bm->BytesPerRow) + x_offset;
759             uint8_t* dest = (uint8_t*)((uint32_t)template_addr);
760             for (int16_t y_line = 0; y_line < h; y_line++) {
761                 memcpy(dest, bmp_mem, line_size);
762                 dest += line_size;
763                 bmp_mem += bm->BytesPerRow;
764             }
765         }
766         else {
767             plane_mask &= (cur_plane ^ 0xFF);
768         }
769         cur_plane <<= 1;
770         template_addr += output_plane_size;
771     }
772
773     WRITESHORT(RTG_X1, (x & 0x07));
774     WRITESHORT(RTG_X2, dx);
775     WRITESHORT(RTG_X3, w);
776     WRITESHORT(RTG_Y1, 0);
777     WRITESHORT(RTG_Y2, dy);
778     WRITESHORT(RTG_Y3, h);
779
780     WRITESHORT(RTG_U1, (plane_mask << 8 | ff_mask));
781     WRITEBYTE(RTG_U83, bm->Depth);
782
783     WRITESHORT(RTG_COMMAND, RTGCMD_P2D);
784 }
785
786 void SetSprite (__REGA0(struct BoardInfo *b), __REGD0(BOOL what), __REGD7(RGBFTYPE format)) {
787     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITE);
788 }
789
790 void SetSpritePosition (__REGA0(struct BoardInfo *b), __REGD0(WORD x), __REGD1(WORD y), __REGD7(RGBFTYPE format)) {
791     WRITESHORT(RTG_X1, x);
792     WRITESHORT(RTG_Y1, y);
793
794     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITEPOS);
795 }
796
797 void SetSpriteImage (__REGA0(struct BoardInfo *b), __REGD7(RGBFTYPE format)) {
798     WRITESHORT(RTG_X1, b->XOffset);
799     WRITESHORT(RTG_Y1, b->YOffset);
800     WRITEBYTE(RTG_U81, b->MouseWidth);
801     WRITEBYTE(RTG_U82, b->MouseHeight);
802
803     uint8_t* dest = (uint8_t*)((uint32_t)CARD_SCRATCH);
804     uint8_t* src = (uint8_t *)b->MouseImage;
805     uint16_t data_size = ((b->MouseWidth >> 3) * 2) * (b->MouseHeight);
806
807     if (b->MouseWidth > 16) src += 8;
808     else src += 4;
809
810     memcpy(dest, src, data_size);
811
812     WRITELONG(RTG_ADDR2, CARD_SCRATCH);
813
814     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITEIMAGE);
815 }
816
817 void SetSpriteColor (__REGA0(struct BoardInfo *b), __REGD0(UBYTE idx), __REGD1(UBYTE R), __REGD2(UBYTE G), __REGD3(UBYTE B), __REGD7(RGBFTYPE format)) {
818     WRITEBYTE(RTG_U81, R);
819     WRITEBYTE(RTG_U82, G);
820     WRITEBYTE(RTG_U83, B);
821     WRITEBYTE(RTG_U84, idx);
822
823     WRITESHORT(RTG_COMMAND, RTGCMD_SETSPRITECOLOR);
824 }
825
826 static uint32_t device_vectors[] = {
827     (uint32_t)OpenLib,
828     (uint32_t)CloseLib,
829     (uint32_t)ExpungeLib,
830     0,
831     (uint32_t)FindCard,
832     (uint32_t)InitCard,
833     -1
834 };
835
836 struct InitTable
837 {
838     ULONG LibBaseSize;
839     APTR  FunctionTable;
840     APTR  DataTable;
841     APTR  InitLibTable;
842 };
843
844 const uint32_t auto_init_tables[4] = {
845     sizeof(struct Library),
846     (uint32_t)device_vectors,
847     0,
848     (uint32_t)InitLib,
849 };