From: beeanyew Date: Thu, 7 Jan 2021 05:29:15 +0000 (+0100) Subject: More RTG acceleration, fix everything X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=0a9d2b7650fb9542c647ca914f6cafd7e118443b;p=pistorm More RTG acceleration, fix everything --- diff --git a/config_file/config_file.c b/config_file/config_file.c index 4ac9670..772c6ba 100644 --- a/config_file/config_file.c +++ b/config_file/config_file.c @@ -427,3 +427,14 @@ int get_named_mapped_item(struct emulator_config *cfg, char *name) { return -1; } + +int get_mapped_item_by_address(struct emulator_config *cfg, uint32_t address) { + for (int i = 0; i < MAX_NUM_MAPPED_ITEMS; i++) { + if (cfg->map_type[i] == MAPTYPE_NONE || !cfg->map_data[i]) + continue; + if (address >= cfg->map_offset[i] && address < cfg->map_high[i]) + return i; + } + + return -1; +} diff --git a/config_file/config_file.h b/config_file/config_file.h index 358a570..b19d809 100644 --- a/config_file/config_file.h +++ b/config_file/config_file.h @@ -91,4 +91,5 @@ struct emulator_config *load_config_file(char *filename); int handle_mapped_read(struct emulator_config *cfg, unsigned int addr, unsigned int *val, unsigned char type); int handle_mapped_write(struct emulator_config *cfg, unsigned int addr, unsigned int value, unsigned char type); int get_named_mapped_item(struct emulator_config *cfg, char *name); +int get_mapped_item_by_address(struct emulator_config *cfg, uint32_t address); unsigned int get_int(char *str); diff --git a/platforms/amiga/rtg/rtg.c b/platforms/amiga/rtg/rtg.c index 8bd437d..c31391b 100644 --- a/platforms/amiga/rtg/rtg.c +++ b/platforms/amiga/rtg/rtg.c @@ -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; + } +} diff --git a/platforms/amiga/rtg/rtg.h b/platforms/amiga/rtg/rtg.h index 1e8e7db..ec5f015 100644 --- a/platforms/amiga/rtg/rtg.h +++ b/platforms/amiga/rtg/rtg.h @@ -1,53 +1,11 @@ #define PIGFX_RTG_BASE 0x70000000 -#define PIGFX_RTG_SIZE 0x04000000 +#define PIGFX_RTG_SIZE 0x02000000 #define PIGFX_REG_SIZE 0x00010000 #define CARD_OFFSET 0 -enum pi_regs { - RTG_COMMAND = 0x00, - RTG_X1 = 0x02, - RTG_X2 = 0x04, - RTG_X3 = 0x06, - RTG_Y1 = 0x08, - RTG_Y2 = 0x0A, - RTG_Y3 = 0x0C, - RTG_FORMAT = 0x0E, - RTG_RGB1 = 0x10, - RTG_RGB2 = 0x14, - RTG_ADDR1 = 0x18, - RTG_ADDR2 = 0x1C, - RTG_U81 = 0x20, - RTG_U82 = 0x21, - RTG_U83 = 0x22, - RTG_U84 = 0x23, - RTG_X4 = 0x24, - RTG_X5 = 0x26, - RTG_Y4 = 0x28, - RTG_Y5 = 0x2A, - RTG_U1 = 0x2C, - RTG_U2 = 0x2E, -}; - -enum rtg_cmds { - RTGCMD_SETGC, - RTGCMD_SETPAN, - RTGCMD_SETCLUT, - RTGCMD_ENABLE, - RTGCMD_SETDISPLAY, - RTGCMD_SETSWITCH, - RTGCMD_FILLRECT, - RTGCMD_BLITRECT, -}; - -enum rtg_formats { - RTGFMT_8BIT, - RTGFMT_RBG565, - RTGFMT_RGB32, - RTGFMT_RGB555, - RTGFMT_NUM, -}; +#include "rtg_driver_amiga/rtg_enums.h" void rtg_write(uint32_t address, uint32_t value, uint8_t mode); unsigned int rtg_read(uint32_t address, uint8_t mode); @@ -56,4 +14,157 @@ void rtg_init_display(); void rtg_shutdown_display(); 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); -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); \ No newline at end of file +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); +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); +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); +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); + +#define PATTERN_LOOPX \ + tmpl_x ^= 0x01; \ + cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x]; \ + +#define PATTERN_LOOPY \ + sptr += 2 ; \ + if ((ys + offset_y + 1) % loop_rows == 0) \ + sptr = sptr_base; \ + tmpl_x = (offset_x / 8) % 2; \ + cur_bit = base_bit; \ + dptr += pitch; + +#define TEMPLATE_LOOPX \ + tmpl_x++; \ + cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x]; \ + +#define TEMPLATE_LOOPY \ + sptr += t_pitch; \ + dptr += pitch; \ + tmpl_x = offset_x / 8; \ + cur_bit = base_bit; + +#define SET_RTG_PIXELS(a, b, c, d) \ + switch (c) { \ + case RTGFMT_8BIT: \ + if (cur_byte & 0x80) a[b + 0] = d[c]; \ + if (cur_byte & 0x40) a[b + 1] = d[c]; \ + if (cur_byte & 0x20) a[b + 2] = d[c]; \ + if (cur_byte & 0x10) a[b + 3] = d[c]; \ + if (cur_byte & 0x08) a[b + 4] = d[c]; \ + if (cur_byte & 0x04) a[b + 5] = d[c]; \ + if (cur_byte & 0x02) a[b + 6] = d[c]; \ + if (cur_byte & 0x01) a[b + 7] = d[c]; \ + break; \ + case RTGFMT_RBG565: \ + if (cur_byte & 0x80) ((uint16_t *)a)[b + 0] = d[c]; \ + if (cur_byte & 0x40) ((uint16_t *)a)[b + 1] = d[c]; \ + if (cur_byte & 0x20) ((uint16_t *)a)[b + 2] = d[c]; \ + if (cur_byte & 0x10) ((uint16_t *)a)[b + 3] = d[c]; \ + if (cur_byte & 0x08) ((uint16_t *)a)[b + 4] = d[c]; \ + if (cur_byte & 0x04) ((uint16_t *)a)[b + 5] = d[c]; \ + if (cur_byte & 0x02) ((uint16_t *)a)[b + 6] = d[c]; \ + if (cur_byte & 0x01) ((uint16_t *)a)[b + 7] = d[c]; \ + break; \ + case RTGFMT_RGB32: \ + if (cur_byte & 0x80) ((uint32_t *)a)[b + 0] = d[c]; \ + if (cur_byte & 0x40) ((uint32_t *)a)[b + 1] = d[c]; \ + if (cur_byte & 0x20) ((uint32_t *)a)[b + 2] = d[c]; \ + if (cur_byte & 0x10) ((uint32_t *)a)[b + 3] = d[c]; \ + if (cur_byte & 0x08) ((uint32_t *)a)[b + 4] = d[c]; \ + if (cur_byte & 0x04) ((uint32_t *)a)[b + 5] = d[c]; \ + if (cur_byte & 0x02) ((uint32_t *)a)[b + 6] = d[c]; \ + if (cur_byte & 0x01) ((uint32_t *)a)[b + 7] = d[c]; \ + break; \ + } + +#define SET_RTG_PIXELS_COND(a, b, c, d, e) \ + switch (c) { \ + case RTGFMT_8BIT: \ + a[b + 0] = (cur_byte & 0x80) ? d[c] : e[c]; \ + a[b + 1] = (cur_byte & 0x40) ? d[c] : e[c]; \ + a[b + 2] = (cur_byte & 0x20) ? d[c] : e[c]; \ + a[b + 3] = (cur_byte & 0x10) ? d[c] : e[c]; \ + a[b + 4] = (cur_byte & 0x08) ? d[c] : e[c]; \ + a[b + 5] = (cur_byte & 0x04) ? d[c] : e[c]; \ + a[b + 6] = (cur_byte & 0x02) ? d[c] : e[c]; \ + a[b + 7] = (cur_byte & 0x01) ? d[c] : e[c]; \ + break; \ + case RTGFMT_RBG565: \ + ((uint16_t *)a)[b + 0] = (cur_byte & 0x80) ? d[c] : e[c]; \ + ((uint16_t *)a)[b + 1] = (cur_byte & 0x40) ? d[c] : e[c]; \ + ((uint16_t *)a)[b + 2] = (cur_byte & 0x20) ? d[c] : e[c]; \ + ((uint16_t *)a)[b + 3] = (cur_byte & 0x10) ? d[c] : e[c]; \ + ((uint16_t *)a)[b + 4] = (cur_byte & 0x08) ? d[c] : e[c]; \ + ((uint16_t *)a)[b + 5] = (cur_byte & 0x04) ? d[c] : e[c]; \ + ((uint16_t *)a)[b + 6] = (cur_byte & 0x02) ? d[c] : e[c]; \ + ((uint16_t *)a)[b + 7] = (cur_byte & 0x01) ? d[c] : e[c]; \ + break; \ + case RTGFMT_RGB32: \ + ((uint32_t *)a)[b + 0] = (cur_byte & 0x80) ? d[c] : e[c]; \ + ((uint32_t *)a)[b + 1] = (cur_byte & 0x40) ? d[c] : e[c]; \ + ((uint32_t *)a)[b + 2] = (cur_byte & 0x20) ? d[c] : e[c]; \ + ((uint32_t *)a)[b + 3] = (cur_byte & 0x10) ? d[c] : e[c]; \ + ((uint32_t *)a)[b + 4] = (cur_byte & 0x08) ? d[c] : e[c]; \ + ((uint32_t *)a)[b + 5] = (cur_byte & 0x04) ? d[c] : e[c]; \ + ((uint32_t *)a)[b + 6] = (cur_byte & 0x02) ? d[c] : e[c]; \ + ((uint32_t *)a)[b + 7] = (cur_byte & 0x01) ? d[c] : e[c]; \ + break; \ + } + +#define INVERT_RTG_PIXELS(a, b, c) \ + switch (c) { \ + case RTGFMT_8BIT: \ + if (cur_byte & 0x80) a[b + 0] = ~a[b + 0]; \ + if (cur_byte & 0x40) a[b + 1] = ~a[b + 1]; \ + if (cur_byte & 0x20) a[b + 2] = ~a[b + 2]; \ + if (cur_byte & 0x10) a[b + 3] = ~a[b + 3]; \ + if (cur_byte & 0x08) a[b + 4] = ~a[b + 4]; \ + if (cur_byte & 0x04) a[b + 5] = ~a[b + 5]; \ + if (cur_byte & 0x02) a[b + 6] = ~a[b + 6]; \ + if (cur_byte & 0x01) a[b + 7] = ~a[b + 7]; \ + break; \ + case RTGFMT_RBG565: \ + if (cur_byte & 0x80) ((uint16_t *)a)[b + 0] = ~((uint16_t *)a)[b + 0]; \ + if (cur_byte & 0x40) ((uint16_t *)a)[b + 1] = ~((uint16_t *)a)[b + 1]; \ + if (cur_byte & 0x20) ((uint16_t *)a)[b + 2] = ~((uint16_t *)a)[b + 2]; \ + if (cur_byte & 0x10) ((uint16_t *)a)[b + 3] = ~((uint16_t *)a)[b + 3]; \ + if (cur_byte & 0x08) ((uint16_t *)a)[b + 4] = ~((uint16_t *)a)[b + 4]; \ + if (cur_byte & 0x04) ((uint16_t *)a)[b + 5] = ~((uint16_t *)a)[b + 5]; \ + if (cur_byte & 0x02) ((uint16_t *)a)[b + 6] = ~((uint16_t *)a)[b + 6]; \ + if (cur_byte & 0x01) ((uint16_t *)a)[b + 7] = ~((uint16_t *)a)[b + 7]; \ + break; \ + case RTGFMT_RGB32: \ + if (cur_byte & 0x80) ((uint32_t *)a)[b + 0] = ~((uint32_t *)a)[b + 0]; \ + if (cur_byte & 0x40) ((uint32_t *)a)[b + 1] = ~((uint32_t *)a)[b + 1]; \ + if (cur_byte & 0x20) ((uint32_t *)a)[b + 2] = ~((uint32_t *)a)[b + 2]; \ + if (cur_byte & 0x10) ((uint32_t *)a)[b + 3] = ~((uint32_t *)a)[b + 3]; \ + if (cur_byte & 0x08) ((uint32_t *)a)[b + 4] = ~((uint32_t *)a)[b + 4]; \ + if (cur_byte & 0x04) ((uint32_t *)a)[b + 5] = ~((uint32_t *)a)[b + 5]; \ + if (cur_byte & 0x02) ((uint32_t *)a)[b + 6] = ~((uint32_t *)a)[b + 6]; \ + if (cur_byte & 0x01) ((uint32_t *)a)[b + 7] = ~((uint32_t *)a)[b + 7]; \ + break; \ + } + +#define SET_RTG_PIXEL(a, b, c, d) \ + switch (c) { \ + case RTGFMT_8BIT: \ + a[b] = d[c]; \ + break; \ + case RTGFMT_RBG565: \ + ((uint16_t *)a)[b] = d[c]; \ + break; \ + case RTGFMT_RGB32: \ + ((uint32_t *)a)[b] = d[c]; \ + break; \ + } + +#define INVERT_RTG_PIXEL(a, b, c) \ + switch (c) { \ + case RTGFMT_8BIT: \ + a[b] = ~a[c]; \ + break; \ + case RTGFMT_RBG565: \ + ((uint16_t *)a)[b] = ~((uint16_t *)a)[b]; \ + break; \ + case RTGFMT_RGB32: \ + ((uint32_t *)a)[b] = ~((uint32_t *)a)[b]; \ + break; \ + } diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c index 1835c00..2cb4877 100644 --- a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c +++ b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c @@ -15,6 +15,7 @@ #include #include #include "boardinfo.h" +#include "rtg_enums.h" #define WRITESHORT(cmd, val) *(unsigned short *)((unsigned long)(b->RegisterBase)+cmd) = val; #define WRITELONG(cmd, val) *(unsigned long *)((unsigned long)(b->RegisterBase)+cmd) = val; @@ -24,50 +25,7 @@ #define CARD_REGSIZE 0x00010000 // 32MB "VRAM" #define CARD_MEMSIZE 0x02000000 - -// "Register" offsets for sending data to the RTG. -enum pi_regs { - RTG_COMMAND = 0x00, - RTG_X1 = 0x02, - RTG_X2 = 0x04, - RTG_X3 = 0x06, - RTG_Y1 = 0x08, - RTG_Y2 = 0x0A, - RTG_Y3 = 0x0C, - RTG_FORMAT = 0x0E, - RTG_RGB1 = 0x10, - RTG_RGB2 = 0x14, - RTG_ADDR1 = 0x18, - RTG_ADDR2 = 0x1C, - RTG_U81 = 0x20, - RTG_U82 = 0x21, - RTG_U83 = 0x22, - RTG_U84 = 0x23, - RTG_X4 = 0x24, - RTG_X5 = 0x26, - RTG_Y4 = 0x28, - RTG_Y5 = 0x2A, - RTG_U1 = 0x2C, - RTG_U2 = 0x2E, -}; - -enum rtg_cmds { - RTGCMD_SETGC, - RTGCMD_SETPAN, - RTGCMD_SETCLUT, - RTGCMD_ENABLE, - RTGCMD_SETDISPLAY, - RTGCMD_SETSWITCH, - RTGCMD_FILLRECT, - RTGCMD_BLITRECT, -}; - -enum rtg_formats { - RTGFMT_8BIT, - RTGFMT_RBG565, - RTGFMT_RGB32, - RTGFMT_RGB555, -}; +#define CHIP_RAM_SIZE 0x200000 const unsigned short rgbf_to_rtg[16] = { RTGFMT_8BIT, // 0x00 @@ -122,6 +80,9 @@ void WaitVerticalSync (__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle)); 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)); 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)); +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)); +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)); +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)); static ULONG LibStart(void) { return(-1); @@ -347,10 +308,10 @@ int InitCard(__REGA0(struct BoardInfo* b)) { b->FillRect = (void *)FillRect; //b->InvertRect = (void *)NULL; b->BlitRect = (void *)BlitRect; - //b->BlitTemplate = (void *)NULL; - //b->BlitPattern = (void *)NULL; + b->BlitTemplate = (void *)BlitTemplate; + b->BlitPattern = (void *)BlitPattern; //b->DrawLine = (void *)NULL; - //b->BlitRectNoMaskComplete = (void *)NULL; + b->BlitRectNoMaskComplete = (void *)BlitRectNoMaskComplete; //b->EnableSoftSprite = (void *)NULL; //b->AllocCardMemAbs = (void *)NULL; @@ -516,8 +477,12 @@ void WaitVerticalSync (__REGA0(struct BoardInfo *b), __REGD0(BOOL toggle)) { 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)) { if (!r) return; - if (mask != 0xFF) + if (mask != 0xFF) { b->FillRectDefault(b, r, x, y, w, h, color, mask, format); + return; + } + + WRITELONG(RTG_ADDR1, (unsigned long)r->Memory); WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]); WRITESHORT(RTG_X1, x); @@ -532,8 +497,12 @@ void FillRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __RE 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)) { if (!r) return; - if (mask != 0xFF) + if (mask != 0xFF) { b->BlitRectDefault(b, r, x, y, dx, dy, w, h, mask, format); + return; + } + + WRITELONG(RTG_ADDR1, (unsigned long)r->Memory); WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]); WRITESHORT(RTG_X1, x); @@ -545,3 +514,105 @@ void BlitRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __RE WRITESHORT(RTG_X4, r->BytesPerRow); WRITESHORT(RTG_COMMAND, RTGCMD_BLITRECT); } + +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)) { + if (!rs || !rt) + return; + if (minterm != MINTERM_SRC) { + b->BlitRectNoMaskCompleteDefault(b, rs, rt, x, y, dx, dy, w, h, minterm, format); + return; + } + + WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]); + WRITELONG(RTG_ADDR1, (unsigned long)rs->Memory); + WRITELONG(RTG_ADDR2, (unsigned long)rt->Memory); + WRITESHORT(RTG_X1, x); + WRITESHORT(RTG_X2, dx); + WRITESHORT(RTG_X3, w); + WRITESHORT(RTG_Y1, y); + WRITESHORT(RTG_Y2, dy); + WRITESHORT(RTG_Y3, h); + WRITESHORT(RTG_X4, rs->BytesPerRow); + WRITESHORT(RTG_X5, rt->BytesPerRow); + WRITEBYTE(RTG_U81, minterm); + WRITESHORT(RTG_COMMAND, RTGCMD_BLITRECT_NOMASK_COMPLETE); +} + +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)) { + if (!r || !t) return; + if (w < 1 || h < 1) return; + + if (mask != 0xFF) { + b->BlitTemplateDefault(b, r, t, x, y, w, h, mask, format); + return; + } + + WRITELONG(RTG_ADDR2, (unsigned long)r->Memory); + + WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]); + WRITESHORT(RTG_X1, x); + WRITESHORT(RTG_X2, w); + WRITESHORT(RTG_X3, t->XOffset); + WRITESHORT(RTG_Y1, y); + WRITESHORT(RTG_Y2, h); + WRITESHORT(RTG_Y3, 0); + + if ((unsigned long)t->Memory > CHIP_RAM_SIZE) { + WRITELONG(RTG_ADDR1, (unsigned long)t->Memory); + } + else { + UBYTE *dest = (UBYTE *)((unsigned long)(CARD_OFFSET + CARD_REGSIZE + CARD_MEMSIZE) - 0x1000 - (t->BytesPerRow * h)); + memcpy(dest, t->Memory, (t->BytesPerRow * h)); + WRITELONG(RTG_ADDR1, (unsigned long)dest); + } + + WRITELONG(RTG_RGB1, t->FgPen); + WRITELONG(RTG_RGB2, t->BgPen); + + WRITESHORT(RTG_X4, r->BytesPerRow); + WRITESHORT(RTG_X5, t->BytesPerRow); + + WRITEBYTE(RTG_U81, mask); + WRITEBYTE(RTG_U82, t->DrawMode); + WRITESHORT(RTG_COMMAND, RTGCMD_BLITTEMPLATE); +} + +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)) { + if (!r || !p) return; + if (w < 1 || h < 1) return; + + if (mask != 0xFF) { + b->BlitPatternDefault(b, r, p, x, y, w, h, mask, format); + return; + } + + WRITELONG(RTG_ADDR2, (unsigned long)r->Memory); + + WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]); + WRITESHORT(RTG_X1, x); + WRITESHORT(RTG_X2, w); + WRITESHORT(RTG_X3, p->XOffset); + WRITESHORT(RTG_Y1, y); + WRITESHORT(RTG_Y2, h); + WRITESHORT(RTG_Y3, p->YOffset); + + if ((unsigned long)p->Memory > CHIP_RAM_SIZE) { + WRITELONG(RTG_ADDR1, (unsigned long)p->Memory); + } + else { + UBYTE *dest = (UBYTE *)((unsigned long)(CARD_OFFSET + CARD_REGSIZE + CARD_MEMSIZE) - 0x1000 - (2 * (1 << p->Size))); + memcpy(dest, p->Memory, (2 * (1 << p->Size))); + WRITELONG(RTG_ADDR1, (unsigned long)dest); + } + + WRITELONG(RTG_RGB1, p->FgPen); + WRITELONG(RTG_RGB2, p->BgPen); + + WRITESHORT(RTG_X4, r->BytesPerRow); + WRITESHORT(RTG_X5, (1 << p->Size)); + + WRITEBYTE(RTG_U81, mask); + WRITEBYTE(RTG_U82, p->DrawMode); + WRITEBYTE(RTG_U83, (1 << p->Size)); + WRITESHORT(RTG_COMMAND, RTGCMD_BLITPATTERN); +} diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card index 791667b..bd7d413 100644 Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card differ diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card index 791667b..bd7d413 100644 Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card differ diff --git a/platforms/amiga/rtg/rtg_driver_amiga/rtg_enums.h b/platforms/amiga/rtg/rtg_driver_amiga/rtg_enums.h new file mode 100644 index 0000000..2f1191c --- /dev/null +++ b/platforms/amiga/rtg/rtg_driver_amiga/rtg_enums.h @@ -0,0 +1,73 @@ +// "Register" offsets for sending data to the RTG. +enum pi_regs { + RTG_COMMAND = 0x00, + RTG_X1 = 0x02, + RTG_X2 = 0x04, + RTG_X3 = 0x06, + RTG_Y1 = 0x08, + RTG_Y2 = 0x0A, + RTG_Y3 = 0x0C, + RTG_FORMAT = 0x0E, + RTG_RGB1 = 0x10, + RTG_RGB2 = 0x14, + RTG_ADDR1 = 0x18, + RTG_ADDR2 = 0x1C, + RTG_U81 = 0x20, + RTG_U82 = 0x21, + RTG_U83 = 0x22, + RTG_U84 = 0x23, + RTG_X4 = 0x24, + RTG_X5 = 0x26, + RTG_Y4 = 0x28, + RTG_Y5 = 0x2A, + RTG_U1 = 0x2C, + RTG_U2 = 0x2E, +}; + +enum rtg_cmds { + RTGCMD_SETGC, + RTGCMD_SETPAN, + RTGCMD_SETCLUT, + RTGCMD_ENABLE, + RTGCMD_SETDISPLAY, + RTGCMD_SETSWITCH, + RTGCMD_FILLRECT, + RTGCMD_BLITRECT, + RTGCMD_BLITRECT_NOMASK_COMPLETE, + RTGCMD_BLITPATTERN, + RTGCMD_BLITTEMPLATE, +}; + +enum rtg_formats { + RTGFMT_8BIT, + RTGFMT_RBG565, + RTGFMT_RGB32, + RTGFMT_RGB555, + RTGFMT_NUM, +}; + +enum gfx_minterm_modes { + MINTERM_FALSE, + MINTERM_NOR, + MINTERM_ONLYDST, + MINTERM_NOTSRC, + MINTERM_ONLYSRC, + MINTERM_INVERT, + MINTERM_EOR, + MINTERM_NAND, + MINTERM_AND, + MINTERM_NEOR, + MINTERM_DST, + MINTERM_NOTONLYSRC, + MINTERM_SRC, + MINTERM_NOTONLYDST, + MINTERM_OR, + MINTERM_TRUE, +}; + +enum gfx_draw_modes { + DRAWMODE_JAM1 = 0, + DRAWMODE_JAM2 = 1, + DRAWMODE_COMPLEMENT = 2, + DRAWMODE_INVERSVID = 4, +};