]> git.sesse.net Git - pistorm/blobdiff - platforms/amiga/rtg/rtg.c
More RTG acceleration, fix everything
[pistorm] / platforms / amiga / rtg / rtg.c
index 8bd437d2f8b2d1f9be8049f8dc9d4c1ff2f37d4e..c31391b02d2c1714ff1f9d26bf151da29cf75fee 100644 (file)
@@ -12,6 +12,7 @@ static uint16_t rtg_x[8], rtg_y[8];
 static uint16_t rtg_user[8];
 static uint16_t rtg_format;
 static uint32_t rtg_address[2];
+static uint32_t rtg_address_adj[2];
 static uint32_t rtg_rgb[2];
 
 static uint8_t display_enabled = 0xFF;
@@ -23,8 +24,8 @@ uint16_t rtg_offset_x, rtg_offset_y;
 
 uint8_t *rtg_mem; // FIXME
 
-uint32_t framebuffer_addr;
-uint32_t framebuffer_addr_adj;
+uint32_t framebuffer_addr = 0;
+uint32_t framebuffer_addr_adj = 0;
 
 static void handle_rtg_command(uint32_t cmd);
 static struct timespec f1, f2;
@@ -150,16 +151,14 @@ void rtg_write(uint32_t address, uint32_t value, uint8_t mode) {
                 switch (address) {
                     case RTG_ADDR1:
                         rtg_address[0] = value;
+                        rtg_address_adj[0] = value - (PIGFX_RTG_BASE + PIGFX_REG_SIZE);
                         break;
                     case RTG_ADDR2:
                         rtg_address[1] = value;
+                        rtg_address_adj[1] = value - (PIGFX_RTG_BASE + PIGFX_REG_SIZE);
                         break;
-                    case RTG_RGB1:
-                        rtg_rgb[0] = value;
-                        break;
-                    case RTG_RGB2:
-                        rtg_rgb[1] = value;
-                        break;
+                    CHKREG(RTG_RGB1, rtg_rgb[0]);
+                    CHKREG(RTG_RGB2, rtg_rgb[1]);
                 }
                 break;
         }
@@ -232,14 +231,23 @@ static void handle_rtg_command(uint32_t cmd) {
         case RTGCMD_BLITRECT:
             rtg_blitrect(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_x[2], rtg_y[2], rtg_x[3], rtg_format, 0xFF);
             break;
+        case RTGCMD_BLITRECT_NOMASK_COMPLETE:
+            rtg_blitrect_nomask_complete(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_x[2], rtg_y[2], rtg_x[3], rtg_x[4], rtg_address[0], rtg_address[1], rtg_display_format, rtg_u8[0]);
+            break;
+        case RTGCMD_BLITPATTERN:
+            rtg_blitpattern(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_address[0], rtg_rgb[0], rtg_rgb[1], rtg_x[3], rtg_display_format, rtg_x[2], rtg_y[2], rtg_u8[0], rtg_u8[1], rtg_u8[2]);
+            return;
+        case RTGCMD_BLITTEMPLATE:
+            rtg_blittemplate(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_address[0], rtg_rgb[0], rtg_rgb[1], rtg_x[3], rtg_x[4], rtg_display_format, rtg_x[2], rtg_u8[0], rtg_u8[1]);
+            break;
     }
 }
 
 void rtg_fillrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color, uint16_t pitch, uint16_t format, uint8_t mask) {
     if (mask) {}
-    uint8_t *dptr = &rtg_mem[framebuffer_addr + (x << format) + (y * pitch)];
-    //printf("FillRect: %d,%d to %d,%d C%.8X, p:%d dp: %d m:%.2X\n", x, y, x+w, y+h, color, pitch, rtg_pitch, mask);
-    //printf("%.8X - %.8X (%p)\n", framebuffer_addr, framebuffer_addr_adj, dptr);
+    uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)];
+    printf("FillRect: %d,%d to %d,%d C%.8X, p:%d dp: %d m:%.2X\n", x, y, x+w, y+h, color, pitch, rtg_pitch, mask);
+    printf("%.8X - %.8X (%p) (%p)\n", framebuffer_addr, rtg_address_adj[0], rtg_mem, dptr);
     switch(format) {
         case RTGFMT_8BIT: {
             //printf("Incoming 8-bit color: %.8X\n", color);
@@ -272,13 +280,14 @@ void rtg_fillrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color
         dptr += pitch;
         memcpy(dptr, (void *)(size_t)(dptr - pitch), (w << format));
     }
+    printf("FillRect done.\n");
 }
 
 void rtg_blitrect(uint16_t x, uint16_t y, uint16_t dx, uint16_t dy, uint16_t w, uint16_t h, uint16_t pitch, uint16_t format, uint8_t mask) {
     if (mask) {}
-    //printf("BlitRect: %d,%d to %d,%d (%dx%d) p:%d dp: %d\n", x, y, dx, dy, w, h, pitch, rtg_pitch);
-    uint8_t *sptr = &rtg_mem[framebuffer_addr + (x << format) + (y * pitch)];
-    uint8_t *dptr = &rtg_mem[framebuffer_addr + (dx << format) + (dy * pitch)];
+    printf("BlitRect: %d,%d to %d,%d (%dx%d) p:%d dp: %d\n", x, y, dx, dy, w, h, pitch, rtg_pitch);
+    uint8_t *sptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)];
+    uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (dx << format) + (dy * pitch)];
 
     uint32_t xdir = 1, pitchstep = pitch;
 
@@ -300,3 +309,298 @@ void rtg_blitrect(uint16_t x, uint16_t y, uint16_t dx, uint16_t dy, uint16_t w,
         dptr += pitchstep;
     }
 }
+
+void rtg_blitrect_nomask_complete(uint16_t sx, uint16_t sy, uint16_t dx, uint16_t dy, uint16_t w, uint16_t h, uint16_t srcpitch, uint16_t dstpitch, uint32_t src_addr, uint32_t dst_addr, uint16_t format, uint8_t minterm) {
+    if (minterm) {}
+    printf("BlitRectNoMaskComplete\n");
+    uint8_t *sptr = &rtg_mem[src_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE) + (sx << format) + (sy * srcpitch)];
+    uint8_t *dptr = &rtg_mem[dst_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE) + (dx << format) + (dy * dstpitch)];
+
+    uint32_t xdir = 1, src_pitchstep = srcpitch, dst_pitchstep = dstpitch;
+
+    if (src_addr == dst_addr) {
+        if (sy < dy) {
+            src_pitchstep = -srcpitch;
+            sptr += ((h - 1) * srcpitch);
+            dst_pitchstep = -dstpitch;
+            dptr += ((h - 1) * dstpitch);
+        }
+        if (sx < dx) {
+            xdir = 0;
+        }
+    }
+
+    for (int ys = 0; ys < h; ys++) {
+        if (xdir)
+            memcpy(dptr, sptr, w << format);
+        else
+            memmove(dptr, sptr, w << format);
+        sptr += src_pitchstep;
+        dptr += dst_pitchstep;
+    }
+}
+
+extern struct emulator_config *cfg;
+
+void rtg_blittemplate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t src_addr, uint32_t fgcol, uint32_t bgcol, uint16_t pitch, uint16_t t_pitch, uint16_t format, uint16_t offset_x, uint8_t mask, uint8_t draw_mode) {
+    if (mask) {}
+    printf("BlitTemplate: %d,%d (%dx%d) @%.8X p:%d dp: %d DM: %d Format: %d\n", x, y, w, h, src_addr, pitch, t_pitch, draw_mode & 0x03, format);
+    printf("FBA: %.8x\n", framebuffer_addr);
+
+    uint8_t *dptr = &rtg_mem[rtg_address_adj[1] + (x << format) + (y * pitch)];
+    uint8_t *sptr = NULL;
+    uint8_t cur_bit = 0, base_bit = 0, cur_byte = 0;
+    uint8_t invert = (draw_mode & DRAWMODE_INVERSVID);
+    uint16_t tmpl_x = 0;
+
+    draw_mode &= 0x03;
+
+       tmpl_x = offset_x / 8;
+    cur_bit = base_bit = (0x80 >> (offset_x % 8));
+
+    uint32_t fg_color[3] = {
+        (fgcol & 0xFF),
+        htobe16((fgcol & 0xFFFF)),
+        htobe32(fgcol),
+    };
+    uint32_t bg_color[3] = {
+        (bgcol & 0xFF),
+        htobe16((bgcol & 0xFFFF)),
+        htobe32(bgcol),
+    };
+
+    if (src_addr >= PIGFX_RTG_BASE)
+        sptr = &rtg_mem[src_addr - PIGFX_RTG_BASE];
+    else {
+        int i = get_mapped_item_by_address(cfg, src_addr);
+        if (i != -1) {
+            //printf("Grabbing data from mapped range %d at offset %ld.\n", i, src_addr - cfg->map_offset[i]);
+            sptr = &cfg->map_data[i][src_addr - cfg->map_offset[i]];
+        }
+        else {
+            printf("BlitTemplate: Failed to find mapped range for address %.8X\n", src_addr);
+            return;
+        }
+    }
+
+    switch (draw_mode) {
+        case DRAWMODE_JAM1:
+            for (uint16_t ys = 0; ys < h; ys++) {
+                //printf("JAM1: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
+                cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
+
+                for (int xs = 0; xs < w; xs++) {
+                    if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
+                        SET_RTG_PIXELS(dptr, xs, format, fg_color);
+                        xs += 7;
+                    }
+                    else {
+                        while (cur_bit > 0 && xs < w) {
+                            if (cur_byte & cur_bit) {
+                                //printf("JAM1: Write byte to dptr[%d] (%p) <- (%p)...\n", xs, dptr, rtg_mem);
+                                SET_RTG_PIXEL(dptr, xs, format, fg_color);
+                            }
+                            xs++;
+                            cur_bit >>= 1;
+                        }
+                        xs--;
+                        cur_bit = 0x80;
+                    }
+                    TEMPLATE_LOOPX;
+                }
+                TEMPLATE_LOOPY;
+            }
+            return;
+        case DRAWMODE_JAM2:
+            for (uint16_t ys = 0; ys < h; ys++) {
+                //printf("JAM2: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
+                cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
+
+                for (int xs = 0; xs < w; xs++) {
+                    if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
+                        SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
+                        xs += 7;
+                    }
+                    else {
+                        while (cur_bit > 0 && xs < w) {
+                            if (cur_byte & cur_bit) {
+                                SET_RTG_PIXEL(dptr, xs, format, fg_color)
+                            }
+                            else {
+                                SET_RTG_PIXEL(dptr, xs, format, bg_color)
+                            }
+                            xs++;
+                            cur_bit >>= 1;
+                        }
+                        xs--;
+                        cur_bit = 0x80;
+                    }
+                    TEMPLATE_LOOPX;
+                }
+                TEMPLATE_LOOPY;
+            }
+            return;
+        case DRAWMODE_COMPLEMENT:
+            for (uint16_t ys = 0; ys < h; ys++) {
+                cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
+
+                for (int xs = 0; xs < w; xs++) {
+                    if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
+                        SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
+                        xs += 7;
+                    }
+                    else {
+                        while (cur_bit > 0 && xs < w) {
+                            if (cur_byte & cur_bit) {
+                                INVERT_RTG_PIXELS(dptr, xs, format)
+                            }
+                            else {
+                                INVERT_RTG_PIXEL(dptr, xs, format)
+                            }
+                            xs++;
+                            cur_bit >>= 1;
+                        }
+                        xs--;
+                        cur_bit = 0x80;
+                    }
+                    TEMPLATE_LOOPX;
+                }
+                TEMPLATE_LOOPY;
+            }
+            return;
+    }
+}
+
+void rtg_blitpattern(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t src_addr, uint32_t fgcol, uint32_t bgcol, uint16_t pitch, uint16_t format, uint16_t offset_x, uint16_t offset_y, uint8_t mask, uint8_t draw_mode, uint8_t loop_rows) {
+    if (mask) {}
+    printf("BlitPattern: %d,%d (%dx%d) @%.8X p:%d dp: %d DM: %d Format: %d\n", x, y, w, h, src_addr, pitch, 2, draw_mode & 0x03, format);
+    printf("FBA: %.8x - lr: %d\n", framebuffer_addr, loop_rows);
+
+    uint8_t *dptr = &rtg_mem[rtg_address_adj[1] + (x << format) + (y * pitch)];
+    uint8_t *sptr = NULL, *sptr_base = NULL;
+    uint8_t cur_bit = 0, base_bit = 0, cur_byte = 0;
+    uint8_t invert = (draw_mode & DRAWMODE_INVERSVID);
+    uint16_t tmpl_x = 0;
+
+    draw_mode &= 0x03;
+
+       tmpl_x = (offset_x / 8) % 2;
+    cur_bit = base_bit = (0x80 >> (offset_x % 8));
+
+    uint32_t fg_color[3] = {
+        (fgcol & 0xFF),
+        htobe16((fgcol & 0xFFFF)),
+        htobe32(fgcol),
+    };
+    uint32_t bg_color[3] = {
+        (bgcol & 0xFF),
+        htobe16((bgcol & 0xFFFF)),
+        htobe32(bgcol),
+    };
+
+
+    if (src_addr >= PIGFX_RTG_BASE)
+        sptr = &rtg_mem[src_addr - PIGFX_RTG_BASE];
+    else {
+        int i = get_mapped_item_by_address(cfg, src_addr);
+        if (i != -1) {
+            //printf("BlitPattern: Grabbing data from mapped range %d at offset %ld.\n", i, src_addr - cfg->map_offset[i]);
+            sptr = &cfg->map_data[i][src_addr - cfg->map_offset[i]];
+        }
+        else {
+            printf("BlitPattern: Failed to find mapped range for address %.8X\n", src_addr);
+            return;
+        }
+    }
+
+    sptr_base = sptr;
+    sptr += (offset_y % loop_rows) * 2;
+
+    switch (draw_mode) {
+        case DRAWMODE_JAM1:
+            for (uint16_t ys = 0; ys < h; ys++) {
+                //printf("JAM1: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
+                cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
+
+                for (int xs = 0; xs < w; xs++) {
+                    if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
+                        SET_RTG_PIXELS(dptr, xs, format, fg_color);
+                        xs += 7;
+                    }
+                    else {
+                        while (cur_bit > 0 && xs < w) {
+                            if (cur_byte & cur_bit) {
+                                //printf("JAM1: Write byte to dptr[%d] (%p) <- (%p)...\n", xs, dptr, rtg_mem);
+                                SET_RTG_PIXEL(dptr, xs, format, fg_color);
+                            }
+                            xs++;
+                            cur_bit >>= 1;
+                        }
+                        xs--;
+                        cur_bit = 0x80;
+                    }
+                    PATTERN_LOOPX;
+                }
+                PATTERN_LOOPY;
+            }
+            return;
+        case DRAWMODE_JAM2:
+            for (uint16_t ys = 0; ys < h; ys++) {
+                //printf("JAM2: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
+                cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
+
+                for (int xs = 0; xs < w; xs++) {
+                    //printf("JAM2: Write byte to dptr[%d] (%p) <- (%p)...\n", xs, dptr, rtg_mem);
+                    if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
+                        SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
+                        xs += 7;
+                    }
+                    else {
+                        while (cur_bit > 0 && xs < w) {
+                            if (cur_byte & cur_bit) {
+                                SET_RTG_PIXEL(dptr, xs, format, fg_color)
+                            }
+                            else {
+                                SET_RTG_PIXEL(dptr, xs, format, bg_color)
+                            }
+                            xs++;
+                            cur_bit >>= 1;
+                        }
+                        xs--;
+                        cur_bit = 0x80;
+                    }
+                    PATTERN_LOOPX;
+                }
+                PATTERN_LOOPY;
+            }
+            return;
+        case DRAWMODE_COMPLEMENT:
+            for (uint16_t ys = 0; ys < h; ys++) {
+                cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
+
+                for (int xs = 0; xs < w; xs++) {
+                    if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
+                        SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
+                        xs += 7;
+                    }
+                    else {
+                        while (cur_bit > 0 && xs < w) {
+                            if (cur_byte & cur_bit) {
+                                INVERT_RTG_PIXELS(dptr, xs, format)
+                            }
+                            else {
+                                INVERT_RTG_PIXEL(dptr, xs, format)
+                            }
+                            xs++;
+                            cur_bit >>= 1;
+                        }
+                        xs--;
+                        cur_bit = 0x80;
+                    }
+                    PATTERN_LOOPX;
+                }
+                PATTERN_LOOPY;
+            }
+            return;
+    }
+}