From: beeanyew Date: Sat, 9 Jan 2021 10:08:51 +0000 (+0100) Subject: Fix some bugs, accelerate Planar2Chunky X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=cbf115e82b9ed5f87b6ce7193762db0b23755e34;p=pistorm Fix some bugs, accelerate Planar2Chunky P2C still not working due to some P96 shenanigans --- diff --git a/Makefile b/Makefile index 45ea24d..927a53e 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,7 @@ MAINFILES = emulator.c \ platforms/amiga/gayle-ide/ide.c \ platforms/amiga/rtg/rtg.c \ platforms/amiga/rtg/rtg-output.c \ + platforms/amiga/rtg/rtg-gfx.c \ platforms/shared/rtc.c MUSASHIFILES = m68kcpu.c softfloat/softfloat.c @@ -32,7 +33,7 @@ EXEPATH = ./ CC = gcc WARNINGS = -Wall -Wextra -pedantic -CFLAGS = $(WARNINGS) -march=armv7 -O3 +CFLAGS = $(WARNINGS) -march=armv8-a -mfloat-abi=hard -mfpu=neon-fp-armv8 -O3 LFLAGS = $(WARNINGS) `sdl2-config --libs` TARGET = $(EXENAME)$(EXE) diff --git a/emulator.c b/emulator.c index 7dc1707..d12d623 100644 --- a/emulator.c +++ b/emulator.c @@ -43,6 +43,7 @@ char mouse_buttons = 0; extern volatile unsigned int *gpio; extern volatile uint16_t srdata; +extern uint8_t realtime_graphics_debug; #define KICKBASE 0xF80000 #define KICKSIZE 0x7FFFF @@ -82,7 +83,7 @@ void *iplThread(void *args) { unsigned int cpu_type = M68K_CPU_TYPE_68000; unsigned int loop_cycles = 300; struct emulator_config *cfg = NULL; -char keyboard_file[256] = "/dev/input/event0"; +char keyboard_file[256] = "/dev/input/event1"; //unsigned char g_kick[524288]; //unsigned char g_ram[FASTSIZE + 1]; /* RAM */ @@ -254,7 +255,7 @@ int main(int argc, char *argv[]) { //usleep(0); // FIXME: Rework this to use keyboard events instead. - /*while (get_key_char(&c)) { + while (get_key_char(&c)) { if (c == cfg->keyboard_toggle_key && !kb_hook_enabled) { kb_hook_enabled = 1; printf("Keyboard hook enabled.\n"); @@ -273,6 +274,10 @@ int main(int argc, char *argv[]) { cpu_emulation_running ^= 1; printf("CPU emulation is now %s\n", cpu_emulation_running ? "running" : "stopped"); } + if (c == 'g') { + realtime_graphics_debug ^= 1; + printf("Real time graphics debug is now %s\n", realtime_graphics_debug ? "on" : "off"); + } if (c == 'R') { cpu_pulse_reset(); m68k_pulse_reset(); @@ -283,7 +288,7 @@ int main(int argc, char *argv[]) { goto stop_cpu_emulation; } } - }*/ + } //gpio_handle_irq(); //GPIO_HANDLE_IRQ; @@ -319,7 +324,7 @@ static unsigned int target = 0; unsigned int target = 0; \ switch(cfg->platform->id) { \ case PLATFORM_AMIGA: { \ - if (address >= PIGFX_RTG_BASE && address < PIGFX_RTG_BASE + PIGFX_RTG_SIZE) { \ + if (address >= PIGFX_RTG_BASE && address < PIGFX_UPPER) { \ return rtg_read((address & 0x0FFFFFFF), a); \ } \ if (custom_read_amiga(cfg, address, &target, a) != -1) { \ @@ -391,7 +396,7 @@ unsigned int m68k_read_memory_32(unsigned int address) { if (address >= cfg->custom_low && address < cfg->custom_high) { \ switch(cfg->platform->id) { \ case PLATFORM_AMIGA: { \ - if (address >= PIGFX_RTG_BASE && address < PIGFX_RTG_BASE + PIGFX_RTG_SIZE) { \ + if (address >= PIGFX_RTG_BASE && address < PIGFX_UPPER) { \ rtg_write((address & 0x0FFFFFFF), value, a); \ return; \ } \ diff --git a/input/input.c b/input/input.c index 9958a99..39af402 100644 --- a/input/input.c +++ b/input/input.c @@ -100,9 +100,11 @@ int get_key_char(char *c) if (handle_modifier(&ie)) continue; char ret = char_from_input_event(&ie); - if (ret != 0) { - *c = ret; - return 1; + if (ie.value == 1 || ie.value == 2) { + if (ret != 0) { + *c = ret; + return 1; + } } } } diff --git a/platforms/amiga/amiga-platform.c b/platforms/amiga/amiga-platform.c index 8a36cc6..292989d 100644 --- a/platforms/amiga/amiga-platform.c +++ b/platforms/amiga/amiga-platform.c @@ -146,7 +146,7 @@ void adjust_ranges_amiga(struct emulator_config *cfg) { cfg->custom_low = PIGFX_RTG_BASE; else cfg->custom_low = min(cfg->custom_low, PIGFX_RTG_BASE); - cfg->custom_high = max(cfg->custom_high, PIGFX_RTG_BASE + PIGFX_RTG_SIZE); + cfg->custom_high = max(cfg->custom_high, PIGFX_UPPER); } printf("Platform custom range: %.8X-%.8X\n", cfg->custom_low, cfg->custom_high); diff --git a/platforms/amiga/rtg/rtg-gfx.c b/platforms/amiga/rtg/rtg-gfx.c new file mode 100644 index 0000000..058a8b1 --- /dev/null +++ b/platforms/amiga/rtg/rtg-gfx.c @@ -0,0 +1,799 @@ +#include +#include +#include +#include +#include "../../../config_file/config_file.h" +#ifndef FAKESTORM +#include "../../../gpio/gpio.h" +#endif +#include "rtg.h" + +extern uint32_t rtg_address[8]; +extern uint32_t rtg_address_adj[8]; +extern uint8_t *rtg_mem; // FIXME +extern uint16_t rtg_display_format; +extern uint16_t rtg_user[8]; +extern uint16_t rtg_x[8], rtg_y[8]; + +extern uint8_t realtime_graphics_debug; + +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[rtg_address_adj[0] + (x << format) + (y * pitch)]; + switch(format) { + case RTGFMT_8BIT: { + for (int xs = 0; xs < w; xs++) { + dptr[xs] = color & 0xFF; + } + break; + } + case RTGFMT_RBG565: { + color = htobe16((color & 0xFFFF)); + uint16_t *ptr = (uint16_t *)dptr; + for (int xs = 0; xs < w; xs++) { + ptr[xs] = color; + } + break; + } + case RTGFMT_RGB32: { + color = htobe32(color); + uint32_t *ptr = (uint32_t *)dptr; + for (int xs = 0; xs < w; xs++) { + ptr[xs] = color; + } + break; + } + } + for (int ys = 1; ys < h; ys++) { + dptr += pitch; + memcpy(dptr, (void *)(size_t)(dptr - pitch), (w << format)); + } +} + +void rtg_invertrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t pitch, uint16_t format, uint8_t mask) { + if (mask) {} + uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)]; + for (int ys = 1; ys < h; ys++) { + switch(format) { + case RTGFMT_8BIT: { + for (int xs = 0; xs < w; xs++) { + dptr[xs] = ~dptr[xs]; + } + break; + } + case RTGFMT_RBG565: { + for (int xs = 0; xs < w; xs++) { + ((uint16_t *)dptr)[xs] = ~((uint16_t *)dptr)[xs]; + } + break; + } + case RTGFMT_RGB32: { + for (int xs = 0; xs < w; xs++) { + ((uint32_t *)dptr)[xs] = ~((uint32_t *)dptr)[xs]; + } + break; + } + } + dptr += pitch; + } +} + +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) {} + 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; + + if (y < dy) { + pitchstep = -pitch; + sptr += ((h - 1) * pitch); + dptr += ((h - 1) * pitch); + } + if (x < dx) { + xdir = 0; + } + + for (int ys = 0; ys < h; ys++) { + if (xdir) + memcpy(dptr, sptr, w << format); + else + memmove(dptr, sptr, w << format); + sptr += pitchstep; + 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) {} + 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) {} + + 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)); + + if (realtime_graphics_debug) { + printf("DEBUG: BlitTemplate - %d, %d (%dx%d)\n", x, y, w, h); + printf("Src: %.8X (%.8X)\n", src_addr, rtg_address_adj[0]); + printf("Dest: %.8X (%.8X)\n", rtg_address[1], rtg_address_adj[1]); + printf("pitch: %d t_pitch: %d format: %d\n", pitch, t_pitch, format); + printf("offset_x: %d mask: %.2X draw_mode: %d\n", offset_x, mask, draw_mode); + } + + 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 + PIGFX_REG_SIZE)) { + sptr = &rtg_mem[src_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE)]; + if (realtime_graphics_debug) { + printf("Origin: %.8X\n", rtg_address[2]); + printf("Grabbing data from RTG memory.\nData:\n"); + for (int i = 0; i < h; i++) { + for (int j = 0; j < t_pitch; j++) { + printf("%.2X", sptr[j + (i * t_pitch)]); + } + printf("\n"); + } +#ifndef FAKESTORM + printf("Data available at origin:\n"); + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + printf("%.2X", read8(rtg_address[2] + j + (i * t_pitch))); + } + printf("\n"); + } +#endif + } + } + else { + int i = get_mapped_item_by_address(cfg, src_addr); + if (i != -1) { + sptr = &cfg->map_data[i][src_addr - cfg->map_offset[i]]; + if (realtime_graphics_debug) { + printf("Grabbing data from maping %d - offset %.8X\nData:\n", i, src_addr - cfg->map_offset[i]); + for (int i = 0; i < h; i++) { + for (int j = 0; j < t_pitch; j++) { + printf("%.2X", sptr[j + (i * t_pitch)]); + } + printf("\n"); + } + } + } + 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++) { + 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[format], format); + xs += 7; + } + else { + while (cur_bit > 0 && xs < w) { + if (cur_byte & cur_bit) { + SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format); + } + xs++; + cur_bit >>= 1; + } + xs--; + cur_bit = 0x80; + } + TEMPLATE_LOOPX; + } + TEMPLATE_LOOPY; + } + return; + case DRAWMODE_JAM2: + 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_PIXELS2_COND(&dptr[xs << format], fg_color[format], bg_color[format], format); + xs += 7; + } + else { + while (cur_bit > 0 && xs < w) { + if (cur_byte & cur_bit) { + SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format); + } + else { + SET_RTG_PIXEL(&dptr[xs << format], bg_color[format], format); + } + 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) { + INVERT_RTG_PIXELS(&dptr[xs << format], format) + xs += 7; + } + else { + while (cur_bit > 0 && xs < w) { + if (cur_byte & cur_bit) { + INVERT_RTG_PIXEL(&dptr[xs << format], 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) {} + + 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 + PIGFX_REG_SIZE)) + sptr = &rtg_mem[src_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE)]; + else { + int i = get_mapped_item_by_address(cfg, src_addr); + if (i != -1) { + 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++) { + 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[format], format); + xs += 7; + } + else { + while (cur_bit > 0 && xs < w) { + if (cur_byte & cur_bit) { + SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format); + } + xs++; + cur_bit >>= 1; + } + xs--; + cur_bit = 0x80; + } + PATTERN_LOOPX; + } + PATTERN_LOOPY; + } + return; + case DRAWMODE_JAM2: + 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_PIXELS2_COND(&dptr[xs << format], fg_color[format], bg_color[format], format); + xs += 7; + } + else { + while (cur_bit > 0 && xs < w) { + if (cur_byte & cur_bit) { + SET_RTG_PIXEL(&dptr[xs << format], fg_color[format], format); + } + else { + SET_RTG_PIXEL(&dptr[xs << format], bg_color[format], format); + } + 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) { + INVERT_RTG_PIXELS(&dptr[xs << format], format) + xs += 7; + } + else { + while (cur_bit > 0 && xs < w) { + if (cur_byte & cur_bit) { + INVERT_RTG_PIXEL(&dptr[xs << format], format) + } + xs++; + cur_bit >>= 1; + } + xs--; + cur_bit = 0x80; + } + PATTERN_LOOPX; + } + PATTERN_LOOPY; + } + return; + } +} + +void rtg_drawline_solid(int16_t x1_, int16_t y1_, int16_t x2_, int16_t y2_, uint16_t len, uint32_t fgcol, uint16_t pitch, uint16_t format) { + int16_t x1 = x1_, y1 = y1_; + int16_t x2 = x1_ + x2_, y2 = y1 + y2_; + + uint32_t fg_color[3] = { + (fgcol & 0xFF), + htobe16((fgcol & 0xFFFF)), + htobe32(fgcol), + }; + + uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (y1 * pitch)]; + + int32_t line_step = pitch; + int8_t x_step = 1; + + int16_t dx, dy, dx_abs, dy_abs, ix, iy, x = x1; + + if (x2 < x1) + x_step = -1; + if (y2 < y1) + line_step = -pitch; + + dx = x2 - x1; + dy = y2 - y1; + dx_abs = abs(dx); + dy_abs = abs(dy); + ix = dy_abs >> 1; + iy = dx_abs >> 1; + + SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format); + + if (dx_abs >= dy_abs) { + if (!len) len = dx_abs; + for (uint16_t i = 0; i < len; i++) { + iy += dy_abs; + if (iy >= dx_abs) { + iy -= dx_abs; + dptr += line_step; + } + x += x_step; + + SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format); + } + } + else { + if (!len) len = dy_abs; + for (uint16_t i = 0; i < len; i++) { + ix += dx_abs; + if (ix >= dy_abs) { + ix -= dy_abs; + x += x_step; + } + dptr += line_step; + + SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format); + } + } +} + +#define DRAW_LINE_PIXEL \ + if (pattern & cur_bit) { \ + if (invert) { INVERT_RTG_PIXEL(&dptr[x << format], format) } \ + else { \ + if (mask == 0xFF || format != RTGFMT_8BIT) { SET_RTG_PIXEL(&dptr[x << format], fg_color[format], format); } \ + else { SET_RTG_PIXEL_MASK(&dptr[x << format], fg_color[format], format); } \ + } \ + } \ + else if (draw_mode == DRAWMODE_JAM2) { \ + if (invert) { INVERT_RTG_PIXEL(&dptr[x << format], format) } \ + else { \ + if (mask == 0xFF || format != RTGFMT_8BIT) { SET_RTG_PIXEL(&dptr[x << format], bg_color[format], format); } \ + else { SET_RTG_PIXEL_MASK(&dptr[x << format], bg_color[format], format); } \ + } \ + } \ + if ((cur_bit >>= 1) == 0) \ + cur_bit = 0x8000; + +void rtg_drawline (int16_t x1_, int16_t y1_, int16_t x2_, int16_t y2_, uint16_t len, uint16_t pattern, uint16_t pattern_offset, uint32_t fgcol, uint32_t bgcol, uint16_t pitch, uint16_t format, uint8_t mask, uint8_t draw_mode) { + if (pattern_offset) {} + + int16_t x1 = x1_, y1 = y1_; + int16_t x2 = x1_ + x2_, y2 = y1 + y2_; + uint16_t cur_bit = 0x8000; + uint32_t color_mask = 0xFFFF0000; + uint8_t invert = 0; + + uint32_t fg_color[3] = { + (fgcol & 0xFF), + htobe16((fgcol & 0xFFFF)), + htobe32(fgcol), + }; + uint32_t bg_color[3] = { + (bgcol & 0xFF), + htobe16((bgcol & 0xFFFF)), + htobe32(bgcol), + }; + + uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (y1 * pitch)]; + + int32_t line_step = pitch; + int8_t x_step = 1; + + int16_t dx, dy, dx_abs, dy_abs, ix, iy, x = x1; + + if (x2 < x1) + x_step = -1; + if (y2 < y1) + line_step = -pitch; + + dx = x2 - x1; + dy = y2 - y1; + dx_abs = abs(dx); + dy_abs = abs(dy); + ix = dy_abs >> 1; + iy = dx_abs >> 1; + + if (draw_mode & DRAWMODE_INVERSVID) + pattern = ~pattern; + if (draw_mode & DRAWMODE_COMPLEMENT) { + invert = 1; + } + draw_mode &= 0x01; + + DRAW_LINE_PIXEL; + + if (dx_abs >= dy_abs) { + if (!len) len = dx_abs; + for (uint16_t i = 0; i < len; i++) { + iy += dy_abs; + if (iy >= dx_abs) { + iy -= dx_abs; + dptr += line_step; + } + x += x_step; + + DRAW_LINE_PIXEL; + } + } + else { + if (!len) len = dy_abs; + for (uint16_t i = 0; i < len; i++) { + ix += dx_abs; + if (ix >= dy_abs) { + ix -= dy_abs; + x += x_step; + } + dptr += line_step; + + DRAW_LINE_PIXEL; + } + } +} + +#define HANDLE_MINTERM_PIXEL_8(s, d, f) \ + switch(draw_mode) {\ + case MINTERM_NOR: \ + s &= ~(d); \ + SET_RTG_PIXEL_MASK(&d, s, f); break; \ + case MINTERM_ONLYDST: \ + d = d & ~(s); break; \ + case MINTERM_NOTSRC: \ + SET_RTG_PIXEL_MASK(&d, s, f); break; \ + case MINTERM_ONLYSRC: \ + s &= (d ^ 0xFF); \ + SET_RTG_PIXEL_MASK(&d, s, f); break; \ + case MINTERM_INVERT: \ + d ^= 0xFF; break; \ + case MINTERM_EOR: \ + d ^= s; break; \ + case MINTERM_NAND: \ + s = ~(d & ~(s)) & mask; \ + SET_RTG_PIXEL_MASK(&d, s, f); break; \ + case MINTERM_AND: \ + s &= d; \ + SET_RTG_PIXEL_MASK(&d, s, f); break; \ + case MINTERM_NEOR: \ + d ^= (s & mask); break; \ + case MINTERM_DST: /* This one does nothing. */ \ + return; break; \ + case MINTERM_NOTONLYSRC: \ + d |= (s & mask); break; \ + case MINTERM_SRC: \ + SET_RTG_PIXEL_MASK(&d, s, f); break; \ + case MINTERM_NOTONLYDST: \ + s = ~(d & s) & mask; \ + SET_RTG_PIXEL_MASK(&d, s, f); break; \ + case MINTERM_OR: \ + d |= (s & mask); break; \ + } + + +#define DECODE_PLANAR_PIXEL(a) \ + switch (planes) { \ + case 8: if (layer_mask & 0x80 && bmp_data[(plane_size * 7) + cur_byte] & cur_bit) a |= 0x80; \ + case 7: if (layer_mask & 0x40 && bmp_data[(plane_size * 6) + cur_byte] & cur_bit) a |= 0x40; \ + case 6: if (layer_mask & 0x20 && bmp_data[(plane_size * 5) + cur_byte] & cur_bit) a |= 0x20; \ + case 5: if (layer_mask & 0x10 && bmp_data[(plane_size * 4) + cur_byte] & cur_bit) a |= 0x10; \ + case 4: if (layer_mask & 0x08 && bmp_data[(plane_size * 3) + cur_byte] & cur_bit) a |= 0x08; \ + case 3: if (layer_mask & 0x04 && bmp_data[(plane_size * 2) + cur_byte] & cur_bit) a |= 0x04; \ + case 2: if (layer_mask & 0x02 && bmp_data[plane_size + cur_byte] & cur_bit) a |= 0x02; \ + case 1: if (layer_mask & 0x01 && bmp_data[cur_byte] & cur_bit) a |= 0x01; \ + break; \ + } + +#define DECODE_INVERTED_PLANAR_PIXEL(a) \ + switch (planes) { \ + case 8: if (layer_mask & 0x80 && (bmp_data[(plane_size * 7) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x80; \ + case 7: if (layer_mask & 0x40 && (bmp_data[(plane_size * 6) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x40; \ + case 6: if (layer_mask & 0x20 && (bmp_data[(plane_size * 5) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x20; \ + case 5: if (layer_mask & 0x10 && (bmp_data[(plane_size * 4) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x10; \ + case 4: if (layer_mask & 0x08 && (bmp_data[(plane_size * 3) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x08; \ + case 3: if (layer_mask & 0x04 && (bmp_data[(plane_size * 2) + cur_byte] ^ 0xFF) & cur_bit) a |= 0x04; \ + case 2: if (layer_mask & 0x02 && (bmp_data[plane_size + cur_byte] ^ 0xFF) & cur_bit) a |= 0x02; \ + case 1: if (layer_mask & 0x01 && (bmp_data[cur_byte] ^ 0xFF) & cur_bit) a |= 0x01; \ + break; \ + } + +void rtg_p2c (int16_t sx, int16_t sy, int16_t dx, int16_t dy, int16_t w, int16_t h, uint8_t draw_mode, uint8_t planes, uint8_t mask, uint8_t layer_mask, uint16_t src_line_pitch, uint8_t *bmp_data_src) { + uint16_t pitch = rtg_x[3]; + uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (dy * pitch)]; + + uint8_t cur_bit, base_bit, base_byte; + uint16_t cur_byte = 0, u8_fg = 0; + uint32_t color_mask = 0xFFFFFFFF; + + uint32_t plane_size = src_line_pitch * h; + uint8_t *bmp_data = bmp_data_src; + + cur_bit = base_bit = (0x80 >> (sx % 8)); + cur_byte = base_byte = ((sx / 8) % src_line_pitch); + + if (realtime_graphics_debug) { + printf("P2C: %d,%d - %d,%d (%dx%d) %d, %.2X\n", sx, sy, dx, dy, w, h, planes, layer_mask); + printf("Mask: %.2X Minterm: %.2X\n", mask, draw_mode); + printf("Pitch: %d Src Pitch: %d (!!!: %.4X)\n", pitch, src_line_pitch, rtg_user[0]); + printf("Curbyte: %d Curbit: %d\n", cur_byte, cur_bit); + printf("Plane size: %d Total size: %d (%X)\n", plane_size, plane_size * planes, plane_size * planes); + printf("Source: %.8X - %.8X\n", rtg_address[1], rtg_address_adj[1]); + printf("Target: %.8X - %.8X\n", rtg_address[0], rtg_address_adj[0]); + fflush(stdout); + + printf("Grabbing data from RTG memory.\nData:\n"); + for (int i = 0; i < h; i++) { + for (int k = 0; k < planes; k++) { + for (int j = 0; j < src_line_pitch; j++) { + printf("%.2X", bmp_data_src[j + (i * src_line_pitch) + (plane_size * k)]); + } + printf(" "); + } + printf("\n"); + } + } + + for (int16_t line_y = 0; line_y < h; line_y++) { + for (int16_t x = dx; x < dx + w; x++) { + u8_fg = 0; + if (draw_mode & 0x01) { + DECODE_INVERTED_PLANAR_PIXEL(u8_fg) + } + else { + DECODE_PLANAR_PIXEL(u8_fg) + } + + if (mask == 0xFF && (draw_mode == MINTERM_SRC || draw_mode == MINTERM_NOTSRC)) { + dptr[x] = u8_fg; + goto skip; + } + + //HANDLE_MINTERM_PIXEL_8(u8_fg, ((uint8_t *)dptr)[x]); + HANDLE_MINTERM_PIXEL_8(u8_fg, dptr[x], rtg_display_format); + + skip:; + if ((cur_bit >>= 1) == 0) { + cur_bit = 0x80; + cur_byte++; + cur_byte %= src_line_pitch; + } + + } + dptr += pitch; + if ((line_y + sy + 1) % h) + bmp_data += src_line_pitch; + else + bmp_data = bmp_data_src; + cur_bit = base_bit; + cur_byte = base_byte; + } +} + +//void rtg_p2c_broken(int16_t sx, int16_t sy, int16_t dx, int16_t dy, int16_t w, int16_t h, uint16_t pitch, uint8_t mask, uint8_t minterm, uint8_t depth, uint16_t planemask_) { + /*uint8_t *planeptr_src = &rtg_mem[rtg_address_adj[1]]; + uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (dy * pitch)]; + + uint8_t cur_bit, base_bit, base_byte; + uint16_t cur_byte = 0;//, color = 0; + uint16_t srcpitch = rtg_user[1]; + uint32_t plane_size = srcpitch * rtg_y[3]; + uint32_t color_mask = 0x00FFFFFF; + uint8_t color = 0; + + uint8_t planemask = planemask_ & 0xFF; + uint8_t planemask_0 = (planemask_ >> 8); + + cur_bit = base_bit = (0x80 >> (sx % 8)); + cur_byte = base_byte = ((sx / 8) % srcpitch); + + planeptr_src += (srcpitch * sy); + + if (realtime_graphics_debug) { + uint8_t *sptr = NULL; + + printf("P2C: %d,%d - %d,%d (%dx%d) %d, %.4X\n", sx, sy, dx, dy, w, h, depth, planemask_); + printf("Mask: %.2X Minterm: %.2X\n", mask, minterm); + printf("Pitch: %d Src Pitch: %d (!!!: %d)\n", pitch, srcpitch, rtg_user[1]); + printf("Curbyte: %d Curbit: %d\n", cur_byte, cur_bit); + printf("Plane size: %d Total size: %d (%X)\n", plane_size, plane_size * depth, plane_size * depth); + printf("Source: %.8X - %.8X\n", rtg_address[1], rtg_address_adj[1]); + printf("Target: %.8X - %.8X\n", rtg_address[0], rtg_address_adj[0]); + fflush(stdout); + + printf("Origin: %.8X\n", rtg_address[2]); + printf("Grabbing data from RTG memory.\nData:\n"); + for (int i = 0; i < h; i++) { + for (int k = 0; k < depth; k++) { + for (int j = 0; j < srcpitch; j++) { + printf("%.2X", planeptr_src[j + (i * srcpitch) + (plane_size * k)]); + } + printf(" "); + } + printf("\n"); + } +#ifndef FAKESTORM + printf("Data available at origin:\n"); + for (int i = 0; i < h; i++) { + for (int k = 0; k < depth; k++) { + for (int j = 0; j < srcpitch; j++) { + printf("%.2X", read8(rtg_address[2] + j + (i * srcpitch) + (plane_size * k))); + } + printf(" "); + } + printf("\n"); + } +#endif + } + + for (int16_t line_y = 0; line_y < h; line_y++) { + for (int16_t xs = dx; xs < dx + w; xs++) { + color = 0; + if (minterm & 0x01) { + //printf("Decode inverted planar pixel.\n"); + DECODE_INVERTED_PLANAR_PIXEL(color, planeptr_src); + } + else { + //printf("Decode planar pixel.\n"); + DECODE_PLANAR_PIXEL(color, planeptr_src); + } + + if (mask == 0xFF && (minterm == MINTERM_SRC || minterm == MINTERM_NOTSRC)) { + dptr[xs << rtg_display_format] = color; + goto skip; + } + + //printf("Place pixel.\n"); + HANDLE_MINTERM_PIXEL_8(color, dptr[xs << rtg_display_format], rtg_display_format); + + skip:; + if ((cur_bit >>= 1) == 0) { + cur_bit = 0x80; + cur_byte++; + cur_byte %= srcpitch; + } + } + dptr += pitch; + //if (line_y + sy + 1 == rtg_y[3]) + //planeptr_src = &rtg_mem[rtg_address_adj[1]];// + (srcpitch * sy); + //else + planeptr_src += srcpitch; + cur_bit = base_bit; + cur_byte = base_byte; + }*/ +//} diff --git a/platforms/amiga/rtg/rtg-output.c b/platforms/amiga/rtg/rtg-output.c index 895a7ee..813c1f7 100644 --- a/platforms/amiga/rtg/rtg-output.c +++ b/platforms/amiga/rtg/rtg-output.c @@ -134,8 +134,12 @@ reinit_sdl:; break; } + uint64_t frame_start = 0, frame_end = 0; + float elapsed = 0.0f; + while (1) { if (renderer && win && img) { + frame_start = SDL_GetPerformanceCounter(); SDL_RenderClear(renderer); if (*data->running) { switch (format) { @@ -152,7 +156,7 @@ reinit_sdl:; SDL_RenderCopy(renderer, img, NULL, NULL); } SDL_RenderPresent(renderer); - usleep(16667); //ghetto 60hz + //usleep(16667); //ghetto 60hz if (height != *data->height || width != *data->width || format != *data->format) { printf("Reinitializing due to something change.\n"); reinit = 1; @@ -174,6 +178,9 @@ reinit_sdl:; } break; } + frame_end = SDL_GetPerformanceCounter(); + elapsed = (frame_end - frame_start) / (float)SDL_GetPerformanceFrequency() * 1000.0f; + SDL_Delay(floor(16.66666f - elapsed)); } else break; diff --git a/platforms/amiga/rtg/rtg.c b/platforms/amiga/rtg/rtg.c index 86aa550..910ee9b 100644 --- a/platforms/amiga/rtg/rtg.c +++ b/platforms/amiga/rtg/rtg.c @@ -7,13 +7,13 @@ #include "rtg.h" #include "../../../config_file/config_file.h" -static uint8_t rtg_u8[4]; -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]; +uint8_t rtg_u8[4]; +uint16_t rtg_x[8], rtg_y[8]; +uint16_t rtg_user[8]; +uint16_t rtg_format; +uint32_t rtg_address[8]; +uint32_t rtg_address_adj[8]; +uint32_t rtg_rgb[8]; static uint8_t display_enabled = 0xFF; @@ -30,6 +30,9 @@ uint32_t framebuffer_addr_adj = 0; static void handle_rtg_command(uint32_t cmd); static struct timespec f1, f2; +uint8_t realtime_graphics_debug = 0; +extern int cpu_emulation_running; + static const char *op_type_names[OP_TYPE_NUM] = { "BYTE", "WORD", @@ -45,7 +48,7 @@ static const char *rtg_format_names[RTGFMT_NUM] = { }; int init_rtg_data() { - rtg_mem = calloc(1, 32 * SIZE_MEGA); + rtg_mem = calloc(1, 40 * SIZE_MEGA); if (!rtg_mem) { printf("Failed to allocate RTG video memory.\n"); return 0; @@ -60,7 +63,7 @@ void rtg_update_screen(); unsigned int rtg_read(uint32_t address, uint8_t mode) { //printf("%s read from RTG: %.8X\n", op_type_names[mode], address); if (address >= PIGFX_REG_SIZE) { - if (rtg_mem) { + if (rtg_mem && (address - PIGFX_REG_SIZE) < PIGFX_UPPER) { switch (mode) { case OP_TYPE_BYTE: return (rtg_mem[address - PIGFX_REG_SIZE]); @@ -101,7 +104,7 @@ void rtg_write(uint32_t address, uint32_t value, uint8_t mode) { /*if ((address - PIGFX_REG_SIZE) < framebuffer_addr) {// || (address - PIGFX_REG_SIZE) > framebuffer_addr + ((rtg_display_width << rtg_display_format) * rtg_display_height)) { printf("Write to RTG memory outside frame buffer %.8X (%.8X).\n", (address - PIGFX_REG_SIZE), framebuffer_addr); }*/ - if (rtg_mem) { + if (rtg_mem && (address - PIGFX_REG_SIZE) < PIGFX_UPPER) { switch (mode) { case OP_TYPE_BYTE: rtg_mem[address - PIGFX_REG_SIZE] = value; @@ -157,6 +160,8 @@ void rtg_write(uint32_t address, uint32_t value, uint8_t mode) { rtg_address[1] = value; rtg_address_adj[1] = value - (PIGFX_RTG_BASE + PIGFX_REG_SIZE); break; + CHKREG(RTG_ADDR3, rtg_address[2]); + CHKREG(RTG_ADDR4, rtg_address[3]); CHKREG(RTG_RGB1, rtg_rgb[0]); CHKREG(RTG_RGB2, rtg_rgb[1]); } @@ -167,6 +172,8 @@ void rtg_write(uint32_t address, uint32_t value, uint8_t mode) { return; } +#define gdebug(a) if (realtime_graphics_debug) { printf(a); m68k_end_timeslice(); cpu_emulation_running = 0; } + static void handle_rtg_command(uint32_t cmd) { //printf("Handling RTG command %d (%.8X)\n", cmd, cmd); switch (cmd) { @@ -227,380 +234,41 @@ static void handle_rtg_command(uint32_t cmd) { break; case RTGCMD_FILLRECT: rtg_fillrect(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_rgb[0], rtg_x[2], rtg_format, 0xFF); + gdebug("FillRect\n"); + break; + case RTGCMD_INVERTRECT: + rtg_invertrect(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_x[2], rtg_format, 0xFF); + gdebug("InvertRect\n"); 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); + gdebug("BlitRect\n"); 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]); + 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_format, rtg_u8[0]); + gdebug("BlitRectNoMaskComplete\n"); 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]); + 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_format, rtg_x[2], rtg_y[2], rtg_u8[0], rtg_u8[1], rtg_u8[2]); + gdebug("BlitPattern\n"); 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]); + 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_format, rtg_x[2], rtg_u8[0], rtg_u8[1]); + gdebug("BlitTemplate\n"); 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[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); - for (int xs = 0; xs < w; xs++) { - dptr[xs] = color & 0xFF; - } + case RTGCMD_DRAWLINE: + if (rtg_u8[0] == 0xFF && rtg_y[2] == 0xFFFF) + rtg_drawline_solid(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_x[2], rtg_rgb[0], rtg_x[3], rtg_format); + else + rtg_drawline(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_x[2], rtg_y[2], rtg_x[4], rtg_rgb[0], rtg_rgb[1], rtg_x[3], rtg_format, rtg_u8[0], rtg_u8[1]); + gdebug("DrawLine\n"); break; - } - case RTGFMT_RBG565: { - //printf("Incoming raw 16-bit color: %.8X\n", htobe32(color)); - color = htobe16((color & 0xFFFF)); - //printf("Incoming 16-bit color: %.8X\n", color); - uint16_t *ptr = (uint16_t *)dptr; - for (int xs = 0; xs < w; xs++) { - ptr[xs] = color; - } + case RTGCMD_P2C: + rtg_p2c(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_x[2], rtg_y[2], rtg_u8[1], rtg_u8[2], rtg_u8[0], (rtg_user[0] >> 0x8), rtg_x[4], (uint8_t *)&rtg_mem[rtg_address_adj[1]]); + //rtg_p2c_broken(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_x[2], rtg_y[2], rtg_x[3], rtg_u8[0], rtg_u8[1], rtg_u8[2], rtg_user[0]); + gdebug("Planar2Chunky\n"); break; - } - case RTGFMT_RGB32: { - color = htobe32(color); - //printf("Incoming 32-bit color: %.8X\n", color); - uint32_t *ptr = (uint32_t *)dptr; - for (int xs = 0; xs < w; xs++) { - ptr[xs] = color; - } + case RTGCMD_P2D: break; - } - } - for (int ys = 1; ys < h; ys++) { - 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[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; - - if (y < dy) { - pitchstep = -pitch; - sptr += ((h - 1) * pitch); - dptr += ((h - 1) * pitch); - } - if (x < dx) { - xdir = 0; - } - - for (int ys = 0; ys < h; ys++) { - if (xdir) - memcpy(dptr, sptr, w << format); - else - memmove(dptr, sptr, w << format); - sptr += pitchstep; - 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 ec5f015..ca63898 100644 --- a/platforms/amiga/rtg/rtg.h +++ b/platforms/amiga/rtg/rtg.h @@ -1,7 +1,9 @@ -#define PIGFX_RTG_BASE 0x70000000 -#define PIGFX_RTG_SIZE 0x02000000 - -#define PIGFX_REG_SIZE 0x00010000 +#define PIGFX_RTG_BASE 0x70000000 +#define PIGFX_REG_SIZE 0x00010000 +#define PIGFX_RTG_SIZE 0x02000000 +#define PIGFX_SCRATCH_SIZE 0x00800000 +#define PIGFX_SCRATCH_AREA 0x72010000 +#define PIGFX_UPPER 0x72810000 #define CARD_OFFSET 0 @@ -14,10 +16,15 @@ 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_invertrect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, 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); 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); +void rtg_drawline_solid(int16_t x1_, int16_t y1_, int16_t x2_, int16_t y2_, uint16_t len, uint32_t fgcol, uint16_t pitch, uint16_t format); +void rtg_drawline (int16_t x1_, int16_t y1_, int16_t x2_, int16_t y2_, uint16_t len, uint16_t pattern, uint16_t pattern_offset, uint32_t fgcol, uint32_t bgcol, uint16_t pitch, uint16_t format, uint8_t mask, uint8_t draw_mode); + +void rtg_p2c (int16_t sx, int16_t sy, int16_t dx, int16_t dy, int16_t w, int16_t h, uint8_t draw_mode, uint8_t planes, uint8_t mask, uint8_t layer_mask, uint16_t src_line_pitch, uint8_t *bmp_data_src); #define PATTERN_LOOPX \ tmpl_x ^= 0x01; \ @@ -41,130 +48,145 @@ void rtg_blitpattern(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t sr tmpl_x = offset_x / 8; \ cur_bit = base_bit; -#define SET_RTG_PIXELS(a, b, c, d) \ - switch (c) { \ +#define INVERT_RTG_PIXELS(dest, format) \ + switch (format) { \ + case RTGFMT_8BIT: \ + if (cur_byte & 0x80) (dest)[0] = ~(dest)[0]; \ + if (cur_byte & 0x40) (dest)[1] = ~(dest)[1]; \ + if (cur_byte & 0x20) (dest)[2] = ~(dest)[2]; \ + if (cur_byte & 0x10) (dest)[3] = ~(dest)[3]; \ + if (cur_byte & 0x08) (dest)[4] = ~(dest)[4]; \ + if (cur_byte & 0x04) (dest)[5] = ~(dest)[5]; \ + if (cur_byte & 0x02) (dest)[6] = ~(dest)[6]; \ + if (cur_byte & 0x01) (dest)[7] = ~(dest)[7]; \ + break; \ + case RTGFMT_RBG565: \ + if (cur_byte & 0x80) ((uint16_t *)dest)[0] = ~((uint16_t *)dest)[0]; \ + if (cur_byte & 0x40) ((uint16_t *)dest)[1] = ~((uint16_t *)dest)[1]; \ + if (cur_byte & 0x20) ((uint16_t *)dest)[2] = ~((uint16_t *)dest)[2]; \ + if (cur_byte & 0x10) ((uint16_t *)dest)[3] = ~((uint16_t *)dest)[3]; \ + if (cur_byte & 0x08) ((uint16_t *)dest)[4] = ~((uint16_t *)dest)[4]; \ + if (cur_byte & 0x04) ((uint16_t *)dest)[5] = ~((uint16_t *)dest)[5]; \ + if (cur_byte & 0x02) ((uint16_t *)dest)[6] = ~((uint16_t *)dest)[6]; \ + if (cur_byte & 0x01) ((uint16_t *)dest)[7] = ~((uint16_t *)dest)[7]; \ + break; \ + case RTGFMT_RGB32: \ + if (cur_byte & 0x80) ((uint32_t *)dest)[0] = ~((uint32_t *)dest)[0]; \ + if (cur_byte & 0x40) ((uint32_t *)dest)[1] = ~((uint32_t *)dest)[1]; \ + if (cur_byte & 0x20) ((uint32_t *)dest)[2] = ~((uint32_t *)dest)[2]; \ + if (cur_byte & 0x10) ((uint32_t *)dest)[3] = ~((uint32_t *)dest)[3]; \ + if (cur_byte & 0x08) ((uint32_t *)dest)[4] = ~((uint32_t *)dest)[4]; \ + if (cur_byte & 0x04) ((uint32_t *)dest)[5] = ~((uint32_t *)dest)[5]; \ + if (cur_byte & 0x02) ((uint32_t *)dest)[6] = ~((uint32_t *)dest)[6]; \ + if (cur_byte & 0x01) ((uint32_t *)dest)[7] = ~((uint32_t *)dest)[7]; \ + break; \ + } + +#define SET_RTG_PIXELS(dest, src, format) \ + switch (format) { \ 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]; \ + if (cur_byte & 0x80) (dest)[0] = src; \ + if (cur_byte & 0x40) (dest)[1] = src; \ + if (cur_byte & 0x20) (dest)[2] = src; \ + if (cur_byte & 0x10) (dest)[3] = src; \ + if (cur_byte & 0x08) (dest)[4] = src; \ + if (cur_byte & 0x04) (dest)[5] = src; \ + if (cur_byte & 0x02) (dest)[6] = src; \ + if (cur_byte & 0x01) (dest)[7] = src; \ 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]; \ + if (cur_byte & 0x80) ((uint16_t *)dest)[0] = src; \ + if (cur_byte & 0x40) ((uint16_t *)dest)[1] = src; \ + if (cur_byte & 0x20) ((uint16_t *)dest)[2] = src; \ + if (cur_byte & 0x10) ((uint16_t *)dest)[3] = src; \ + if (cur_byte & 0x08) ((uint16_t *)dest)[4] = src; \ + if (cur_byte & 0x04) ((uint16_t *)dest)[5] = src; \ + if (cur_byte & 0x02) ((uint16_t *)dest)[6] = src; \ + if (cur_byte & 0x01) ((uint16_t *)dest)[7] = src; \ 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]; \ + if (cur_byte & 0x80) ((uint32_t *)dest)[0] = src; \ + if (cur_byte & 0x40) ((uint32_t *)dest)[1] = src; \ + if (cur_byte & 0x20) ((uint32_t *)dest)[2] = src; \ + if (cur_byte & 0x10) ((uint32_t *)dest)[3] = src; \ + if (cur_byte & 0x08) ((uint32_t *)dest)[4] = src; \ + if (cur_byte & 0x04) ((uint32_t *)dest)[5] = src; \ + if (cur_byte & 0x02) ((uint32_t *)dest)[6] = src; \ + if (cur_byte & 0x01) ((uint32_t *)dest)[7] = src; \ break; \ } -#define SET_RTG_PIXELS_COND(a, b, c, d, e) \ - switch (c) { \ +#define SET_RTG_PIXELS2_COND(dest, src, src2, format) \ + switch (format) { \ 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]; \ + (dest)[0] = (cur_byte & 0x80) ? src : src2; \ + (dest)[1] = (cur_byte & 0x40) ? src : src2; \ + (dest)[2] = (cur_byte & 0x20) ? src : src2; \ + (dest)[3] = (cur_byte & 0x10) ? src : src2; \ + (dest)[4] = (cur_byte & 0x08) ? src : src2; \ + (dest)[5] = (cur_byte & 0x04) ? src : src2; \ + (dest)[6] = (cur_byte & 0x02) ? src : src2; \ + (dest)[7] = (cur_byte & 0x01) ? src : src2; \ 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]; \ + ((uint16_t *)dest)[0] = (cur_byte & 0x80) ? src : src2; \ + ((uint16_t *)dest)[1] = (cur_byte & 0x40) ? src : src2; \ + ((uint16_t *)dest)[2] = (cur_byte & 0x20) ? src : src2; \ + ((uint16_t *)dest)[3] = (cur_byte & 0x10) ? src : src2; \ + ((uint16_t *)dest)[4] = (cur_byte & 0x08) ? src : src2; \ + ((uint16_t *)dest)[5] = (cur_byte & 0x04) ? src : src2; \ + ((uint16_t *)dest)[6] = (cur_byte & 0x02) ? src : src2; \ + ((uint16_t *)dest)[7] = (cur_byte & 0x01) ? src : src2; \ 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]; \ + ((uint32_t *)dest)[0] = (cur_byte & 0x80) ? src : src2; \ + ((uint32_t *)dest)[1] = (cur_byte & 0x40) ? src : src2; \ + ((uint32_t *)dest)[2] = (cur_byte & 0x20) ? src : src2; \ + ((uint32_t *)dest)[3] = (cur_byte & 0x10) ? src : src2; \ + ((uint32_t *)dest)[4] = (cur_byte & 0x08) ? src : src2; \ + ((uint32_t *)dest)[5] = (cur_byte & 0x04) ? src : src2; \ + ((uint32_t *)dest)[6] = (cur_byte & 0x02) ? src : src2; \ + ((uint32_t *)dest)[7] = (cur_byte & 0x01) ? src : src2; \ break; \ } -#define INVERT_RTG_PIXELS(a, b, c) \ - switch (c) { \ + + +#define SET_RTG_PIXEL(dest, src, format) \ + switch (format) { \ 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]; \ + *(dest) = src; \ 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]; \ + *((uint16_t *)dest) = src; \ 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]; \ + *((uint32_t *)dest) = src; \ break; \ } -#define SET_RTG_PIXEL(a, b, c, d) \ - switch (c) { \ +#define SET_RTG_PIXEL_MASK(dest, src, format) \ + switch (format) { \ case RTGFMT_8BIT: \ - a[b] = d[c]; \ + *(dest) = src ^ (*(dest) & ~mask); \ break; \ case RTGFMT_RBG565: \ - ((uint16_t *)a)[b] = d[c]; \ + *((uint16_t *)dest) = src ^ (*((uint16_t *)dest) & ~color_mask); \ break; \ case RTGFMT_RGB32: \ - ((uint32_t *)a)[b] = d[c]; \ + *((uint32_t *)dest) = src ^ (*((uint32_t *)dest) & ~color_mask); \ break; \ } -#define INVERT_RTG_PIXEL(a, b, c) \ - switch (c) { \ +#define INVERT_RTG_PIXEL(dest, format) \ + switch (format) { \ case RTGFMT_8BIT: \ - a[b] = ~a[c]; \ + *(dest) ^= mask; \ break; \ case RTGFMT_RBG565: \ - ((uint16_t *)a)[b] = ~((uint16_t *)a)[b]; \ + *((uint16_t *)dest) = ~*((uint16_t *)dest); \ break; \ case RTGFMT_RGB32: \ - ((uint32_t *)a)[b] = ~((uint32_t *)a)[b]; \ + *((uint32_t *)dest) = ~*((uint32_t *)dest); \ break; \ } diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c index 2cb4877..6b4cff9 100644 --- a/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c +++ b/platforms/amiga/rtg/rtg_driver_amiga/pigfx.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include "boardinfo.h" #include "rtg_enums.h" @@ -21,11 +21,12 @@ #define WRITELONG(cmd, val) *(unsigned long *)((unsigned long)(b->RegisterBase)+cmd) = val; #define WRITEBYTE(cmd, val) *(unsigned char *)((unsigned long)(b->RegisterBase)+cmd) = val; -#define CARD_OFFSET 0x70000000 -#define CARD_REGSIZE 0x00010000 -// 32MB "VRAM" -#define CARD_MEMSIZE 0x02000000 -#define CHIP_RAM_SIZE 0x200000 +#define CARD_OFFSET 0x70000000 +#define CARD_REGSIZE 0x00010000 +#define CARD_MEMSIZE 0x02000000 // 32MB "VRAM" +#define CARD_SCRATCH 0x72010000 + +#define CHIP_RAM_SIZE 0x00200000 // Chip RAM offset, 2MB const unsigned short rgbf_to_rtg[16] = { RTGFMT_8BIT, // 0x00 @@ -79,10 +80,15 @@ void SetReadPlane (__REGA0(struct BoardInfo *b), __REGD0(UBYTE plane)); 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 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)); 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)); +void DrawLine (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Line *l), __REGD0(UBYTE mask), __REGD7(RGBFTYPE format)); + +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)); +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)); static ULONG LibStart(void) { return(-1); @@ -302,15 +308,15 @@ int InitCard(__REGA0(struct BoardInfo* b)) { //b->ScrollPlanar = (void *)NULL; //b->UpdatePlanar = (void *)NULL; - //b->BlitPlanar2Chunky = (void *)NULL; + b->BlitPlanar2Chunky = (void *)BlitPlanar2Chunky; //b->BlitPlanar2Direct = (void *)NULL; b->FillRect = (void *)FillRect; - //b->InvertRect = (void *)NULL; + b->InvertRect = (void *)InvertRect; b->BlitRect = (void *)BlitRect; b->BlitTemplate = (void *)BlitTemplate; b->BlitPattern = (void *)BlitPattern; - //b->DrawLine = (void *)NULL; + b->DrawLine = (void *)DrawLine; b->BlitRectNoMaskComplete = (void *)BlitRectNoMaskComplete; //b->EnableSoftSprite = (void *)NULL; @@ -491,9 +497,30 @@ void FillRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __RE WRITESHORT(RTG_Y2, h); WRITELONG(RTG_RGB1, color); WRITESHORT(RTG_X3, r->BytesPerRow); + WRITEBYTE(RTG_U81, mask); WRITESHORT(RTG_COMMAND, RTGCMD_FILLRECT); } +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)) { + if (!r) + return; + if (mask != 0xFF) { + b->InvertRectDefault(b, r, x, y, 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_X2, w); + WRITESHORT(RTG_Y1, y); + WRITESHORT(RTG_Y2, h); + WRITESHORT(RTG_X3, r->BytesPerRow); + WRITEBYTE(RTG_U81, mask); + WRITESHORT(RTG_COMMAND, RTGCMD_INVERTRECT); +} + 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; @@ -512,6 +539,7 @@ void BlitRect (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __RE WRITESHORT(RTG_Y2, dy); WRITESHORT(RTG_Y3, h); WRITESHORT(RTG_X4, r->BytesPerRow); + WRITEBYTE(RTG_U81, mask); WRITESHORT(RTG_COMMAND, RTGCMD_BLITRECT); } @@ -561,9 +589,10 @@ void BlitTemplate (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), 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)); + unsigned long dest = CARD_SCRATCH; + memcpy((unsigned char *)dest, t->Memory, (t->BytesPerRow * h)); WRITELONG(RTG_ADDR1, (unsigned long)dest); + WRITELONG(RTG_ADDR3, (unsigned long)t->Memory); } WRITELONG(RTG_RGB1, t->FgPen); @@ -600,8 +629,8 @@ void BlitPattern (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), _ 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))); + unsigned long dest = CARD_SCRATCH; + memcpy((unsigned char *)dest, p->Memory, (2 * (1 << p->Size))); WRITELONG(RTG_ADDR1, (unsigned long)dest); } @@ -616,3 +645,149 @@ void BlitPattern (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), _ WRITEBYTE(RTG_U83, (1 << p->Size)); WRITESHORT(RTG_COMMAND, RTGCMD_BLITPATTERN); } + +void DrawLine (__REGA0(struct BoardInfo *b), __REGA1(struct RenderInfo *r), __REGA2(struct Line *l), __REGD0(UBYTE mask), __REGD7(RGBFTYPE format)) { + if (!r || !b) return; + + WRITELONG(RTG_ADDR1, (unsigned long)r->Memory); + + WRITELONG(RTG_RGB1, l->FgPen); + WRITELONG(RTG_RGB2, l->BgPen); + + WRITESHORT(RTG_FORMAT, rgbf_to_rtg[format]); + + WRITESHORT(RTG_X1, l->X); + WRITESHORT(RTG_X2, l->dX); + WRITESHORT(RTG_Y1, l->Y); + WRITESHORT(RTG_Y2, l->dY); + + WRITESHORT(RTG_X3, l->Length); + WRITESHORT(RTG_Y3, l->LinePtrn); + + WRITESHORT(RTG_X4, r->BytesPerRow); + WRITESHORT(RTG_X5, l->PatternShift); + + WRITEBYTE(RTG_U81, mask); + WRITEBYTE(RTG_U82, l->DrawMode); + WRITEBYTE(RTG_U83, l->pad); + + WRITESHORT(RTG_COMMAND, RTGCMD_DRAWLINE); +} + +void BlitPlanar2Chunky_Broken (__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)) { + if (!r || !b || !bm) return; + + //unsigned long bmp_size = bm->BytesPerRow * bm->Rows; + unsigned char planemask_0 = 0, planemask = 0; + //unsigned short line_size = (w >> 3) + 2; + //unsigned long output_plane_size = line_size * h; + unsigned long plane_size = bm->BytesPerRow * bm->Rows; + short x_offset = (x >> 3); + + unsigned long dest = CARD_SCRATCH; + + WRITELONG(RTG_ADDR1, (unsigned long)r->Memory); + WRITELONG(RTG_ADDR2, (unsigned long)dest); + WRITELONG(RTG_ADDR3, (unsigned long)bm->Planes[0]); + + for (unsigned short i = 0; i < bm->Depth; i++) { + if ((unsigned long)bm->Planes[i] == 0xFFFFFFFF) { + planemask |= (1 << i); + } + else if (bm->Planes[i] == NULL) { + planemask_0 |= (1 << i); + } + else { + unsigned long bmp_mem = (unsigned long)(bm->Planes[i]) + x_offset + (y * bm->BytesPerRow); + unsigned long plane_dest = dest; + for (unsigned short y_line = 0; y_line < h; y_line++) { + memcpy((unsigned char *)plane_dest, (unsigned char *)bmp_mem, bm->BytesPerRow); + plane_dest += bm->BytesPerRow; + bmp_mem += bm->BytesPerRow; + } + } + dest += plane_size; + } + + WRITESHORT(RTG_X1, x % 0x07); + WRITESHORT(RTG_X2, dx); + WRITESHORT(RTG_X3, w); + WRITESHORT(RTG_Y1, 0); + WRITESHORT(RTG_Y2, dy); + WRITESHORT(RTG_Y3, h); + + WRITESHORT(RTG_Y4, bm->Rows); + WRITESHORT(RTG_X4, r->BytesPerRow); + WRITESHORT(RTG_U1, planemask_0 << 8 | planemask); + WRITESHORT(RTG_U2, bm->BytesPerRow); + + WRITEBYTE(RTG_U81, mask); + WRITEBYTE(RTG_U82, minterm); + WRITEBYTE(RTG_U83, bm->Depth); + + WRITESHORT(RTG_COMMAND, RTGCMD_P2C); +} + +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)) { + if (!b || !r) + return; + + uint32_t plane_size = bm->BytesPerRow * bm->Rows; + + uint32_t template_addr = CARD_SCRATCH; + + uint16_t plane_mask = mask; + uint8_t ff_mask = 0x00; + uint8_t cur_plane = 0x01; + + uint16_t line_size = (w >> 3) + 2; + uint32_t output_plane_size = line_size * h; + uint16_t x_offset = (x >> 3); + + WRITELONG(RTG_ADDR1, (unsigned long)r->Memory); + WRITELONG(RTG_ADDR2, template_addr); + WRITESHORT(RTG_X4, r->BytesPerRow); + WRITESHORT(RTG_X5, line_size); + WRITESHORT(RTG_FORMAT, rgbf_to_rtg[r->RGBFormat]); + + WRITEBYTE(RTG_U81, mask); + WRITEBYTE(RTG_U82, minterm); + + for (int16_t i = 0; i < bm->Depth; i++) { + uint16_t x_offset = (x >> 3); + if ((uint32_t)bm->Planes[i] == 0xFFFFFFFF) { + //memset((uint8_t*)(((uint32_t)b->memory)+template_addr), 0xFF, output_plane_size); + ff_mask |= cur_plane; + } + else if (bm->Planes[i] != NULL) { + uint8_t* bmp_mem = (uint8_t*)bm->Planes[i] + (y * bm->BytesPerRow) + x_offset; + uint8_t* dest = (uint8_t*)((uint32_t)template_addr); + for (int16_t y_line = 0; y_line < h; y_line++) { + memcpy(dest, bmp_mem, line_size); + dest += line_size; + bmp_mem += bm->BytesPerRow; + } + } + else { + plane_mask &= (cur_plane ^ 0xFF); + } + cur_plane <<= 1; + template_addr += output_plane_size; + } + + WRITESHORT(RTG_X1, (x & 0x07)); + WRITESHORT(RTG_X2, dx); + WRITESHORT(RTG_X3, w); + WRITESHORT(RTG_Y1, 0); + WRITESHORT(RTG_Y2, dy); + WRITESHORT(RTG_Y3, h); + + WRITESHORT(RTG_U1, (plane_mask << 8 | ff_mask)); + WRITEBYTE(RTG_U83, bm->Depth); + + WRITESHORT(RTG_COMMAND, RTGCMD_P2C); +} + +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)) { + +} diff --git a/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card b/platforms/amiga/rtg/rtg_driver_amiga/pigfx020.card index bd7d413..c58bd89 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 bd7d413..c58bd89 100644 Binary files a/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card and b/platforms/amiga/rtg/rtg_driver_amiga/pigfx030.card differ