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;
+}
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);
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;
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;
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;
}
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);
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;
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;
+ }
+}
#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);
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; \
+ }
#include <string.h>
#include <stdio.h>
#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;
#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
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);
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;
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);
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);
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);
+}
--- /dev/null
+// "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,
+};