8 #include "../../../config_file/config_file.h"
10 static uint8_t rtg_u8[4];
11 static uint16_t rtg_x[8], rtg_y[8];
12 static uint16_t rtg_user[8];
13 static uint16_t rtg_format;
14 static uint32_t rtg_address[2];
15 static uint32_t rtg_address_adj[2];
16 static uint32_t rtg_rgb[2];
18 static uint8_t display_enabled = 0xFF;
20 uint16_t rtg_display_width, rtg_display_height;
21 uint16_t rtg_display_format;
22 uint16_t rtg_pitch, rtg_total_rows;
23 uint16_t rtg_offset_x, rtg_offset_y;
25 uint8_t *rtg_mem; // FIXME
27 uint32_t framebuffer_addr = 0;
28 uint32_t framebuffer_addr_adj = 0;
30 static void handle_rtg_command(uint32_t cmd);
31 static struct timespec f1, f2;
33 static const char *op_type_names[OP_TYPE_NUM] = {
40 static const char *rtg_format_names[RTGFMT_NUM] = {
48 rtg_mem = calloc(1, 32 * SIZE_MEGA);
50 printf("Failed to allocate RTG video memory.\n");
57 extern uint8_t busy, rtg_on;
58 void rtg_update_screen();
60 unsigned int rtg_read(uint32_t address, uint8_t mode) {
61 //printf("%s read from RTG: %.8X\n", op_type_names[mode], address);
62 if (address >= PIGFX_REG_SIZE) {
66 return (rtg_mem[address - PIGFX_REG_SIZE]);
69 return be16toh(*(( uint16_t *) (&rtg_mem[address - PIGFX_REG_SIZE])));
71 case OP_TYPE_LONGWORD:
72 return be32toh(*(( uint32_t *) (&rtg_mem[address - PIGFX_REG_SIZE])));
83 struct timespec diff(struct timespec start, struct timespec end)
86 if ((end.tv_nsec-start.tv_nsec)<0) {
87 temp.tv_sec = end.tv_sec-start.tv_sec-1;
88 temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
90 temp.tv_sec = end.tv_sec-start.tv_sec;
91 temp.tv_nsec = end.tv_nsec-start.tv_nsec;
96 #define CHKREG(a, b) case a: b = value; break;
98 void rtg_write(uint32_t address, uint32_t value, uint8_t mode) {
99 //printf("%s write to RTG: %.8X (%.8X)\n", op_type_names[mode], address, value);
100 if (address >= PIGFX_REG_SIZE) {
101 /*if ((address - PIGFX_REG_SIZE) < framebuffer_addr) {// || (address - PIGFX_REG_SIZE) > framebuffer_addr + ((rtg_display_width << rtg_display_format) * rtg_display_height)) {
102 printf("Write to RTG memory outside frame buffer %.8X (%.8X).\n", (address - PIGFX_REG_SIZE), framebuffer_addr);
107 rtg_mem[address - PIGFX_REG_SIZE] = value;
110 *(( uint16_t *) (&rtg_mem[address - PIGFX_REG_SIZE])) = htobe16(value);
112 case OP_TYPE_LONGWORD:
113 *(( uint32_t *) (&rtg_mem[address - PIGFX_REG_SIZE])) = htobe32(value);
124 CHKREG(RTG_U81, rtg_u8[0]);
125 CHKREG(RTG_U82, rtg_u8[1]);
126 CHKREG(RTG_U83, rtg_u8[2]);
127 CHKREG(RTG_U84, rtg_u8[3]);
132 CHKREG(RTG_X1, rtg_x[0]);
133 CHKREG(RTG_X2, rtg_x[1]);
134 CHKREG(RTG_X3, rtg_x[2]);
135 CHKREG(RTG_X4, rtg_x[3]);
136 CHKREG(RTG_X5, rtg_x[4]);
137 CHKREG(RTG_Y1, rtg_y[0]);
138 CHKREG(RTG_Y2, rtg_y[1]);
139 CHKREG(RTG_Y3, rtg_y[2]);
140 CHKREG(RTG_Y4, rtg_y[3]);
141 CHKREG(RTG_Y5, rtg_y[4]);
142 CHKREG(RTG_U1, rtg_user[0]);
143 CHKREG(RTG_U2, rtg_user[1]);
144 CHKREG(RTG_FORMAT, rtg_format);
146 handle_rtg_command(value);
150 case OP_TYPE_LONGWORD:
153 rtg_address[0] = value;
154 rtg_address_adj[0] = value - (PIGFX_RTG_BASE + PIGFX_REG_SIZE);
157 rtg_address[1] = value;
158 rtg_address_adj[1] = value - (PIGFX_RTG_BASE + PIGFX_REG_SIZE);
160 CHKREG(RTG_RGB1, rtg_rgb[0]);
161 CHKREG(RTG_RGB2, rtg_rgb[1]);
170 static void handle_rtg_command(uint32_t cmd) {
171 //printf("Handling RTG command %d (%.8X)\n", cmd, cmd);
174 rtg_display_format = rtg_format;
175 rtg_display_width = rtg_x[0];
176 rtg_display_height = rtg_y[0];
178 //rtg_pitch = rtg_display_width << rtg_format;
179 framebuffer_addr_adj = framebuffer_addr + (rtg_offset_x << rtg_display_format) + (rtg_offset_y * rtg_pitch);
180 rtg_total_rows = rtg_y[1];
183 //rtg_pitch = rtg_display_width << rtg_format;
184 framebuffer_addr_adj = framebuffer_addr + (rtg_offset_x << rtg_display_format) + (rtg_offset_y * rtg_pitch);
185 rtg_total_rows = rtg_y[1];
187 printf("Set RTG mode:\n");
188 printf("%dx%d pixels\n", rtg_display_width, rtg_display_height);
189 printf("Pixel format: %s\n", rtg_format_names[rtg_display_format]);
192 //printf("Command: SetPan.\n");
193 rtg_offset_x = rtg_x[1];
194 rtg_offset_y = rtg_y[1];
195 rtg_pitch = (rtg_x[0] << rtg_display_format);
196 framebuffer_addr = rtg_address[0] - (PIGFX_RTG_BASE + PIGFX_REG_SIZE);
197 framebuffer_addr_adj = framebuffer_addr + (rtg_offset_x << rtg_display_format) + (rtg_offset_y * rtg_pitch);
198 printf("Set panning to $%.8X (%.8X)\n", framebuffer_addr, rtg_address[0]);
199 printf("(Panned: $%.8X)\n", framebuffer_addr_adj);
200 printf("Offset X/Y: %d/%d\n", rtg_offset_x, rtg_offset_y);
201 printf("Pitch: %d (%d bytes)\n", rtg_x[0], rtg_pitch);
203 case RTGCMD_SETCLUT: {
204 //printf("Command: SetCLUT.\n");
205 //printf("Set palette entry %d to %d, %d, %d\n", rtg_u8[0], rtg_u8[1], rtg_u8[2], rtg_u8[3]);
206 //printf("Set palette entry %d to 32-bit palette color: %.8X\n", rtg_u8[0], rtg_rgb[0]);
207 rtg_set_clut_entry(rtg_u8[0], rtg_rgb[0]);
210 case RTGCMD_SETDISPLAY:
211 //printf("RTG SetDisplay %s\n", (rtg_u8[1]) ? "enabled" : "disabled");
213 //printf("Command: SetDisplay.\n");
216 case RTGCMD_SETSWITCH:
217 //printf("RTG SetSwitch %s\n", ((rtg_x[0]) & 0x01) ? "enabled" : "disabled");
218 //printf("LAL: %.4X\n", rtg_x[0]);
219 if (display_enabled != ((rtg_x[0]) & 0x01)) {
220 display_enabled = ((rtg_x[0]) & 0x01);
221 if (display_enabled) {
225 rtg_shutdown_display();
228 case RTGCMD_FILLRECT:
229 rtg_fillrect(rtg_x[0], rtg_y[0], rtg_x[1], rtg_y[1], rtg_rgb[0], rtg_x[2], rtg_format, 0xFF);
231 case RTGCMD_BLITRECT:
232 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);
234 case RTGCMD_BLITRECT_NOMASK_COMPLETE:
235 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]);
237 case RTGCMD_BLITPATTERN:
238 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]);
240 case RTGCMD_BLITTEMPLATE:
241 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]);
246 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) {
248 uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)];
249 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);
250 printf("%.8X - %.8X (%p) (%p)\n", framebuffer_addr, rtg_address_adj[0], rtg_mem, dptr);
253 //printf("Incoming 8-bit color: %.8X\n", color);
254 for (int xs = 0; xs < w; xs++) {
255 dptr[xs] = color & 0xFF;
259 case RTGFMT_RBG565: {
260 //printf("Incoming raw 16-bit color: %.8X\n", htobe32(color));
261 color = htobe16((color & 0xFFFF));
262 //printf("Incoming 16-bit color: %.8X\n", color);
263 uint16_t *ptr = (uint16_t *)dptr;
264 for (int xs = 0; xs < w; xs++) {
270 color = htobe32(color);
271 //printf("Incoming 32-bit color: %.8X\n", color);
272 uint32_t *ptr = (uint32_t *)dptr;
273 for (int xs = 0; xs < w; xs++) {
279 for (int ys = 1; ys < h; ys++) {
281 memcpy(dptr, (void *)(size_t)(dptr - pitch), (w << format));
283 printf("FillRect done.\n");
286 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) {
288 printf("BlitRect: %d,%d to %d,%d (%dx%d) p:%d dp: %d\n", x, y, dx, dy, w, h, pitch, rtg_pitch);
289 uint8_t *sptr = &rtg_mem[rtg_address_adj[0] + (x << format) + (y * pitch)];
290 uint8_t *dptr = &rtg_mem[rtg_address_adj[0] + (dx << format) + (dy * pitch)];
292 uint32_t xdir = 1, pitchstep = pitch;
296 sptr += ((h - 1) * pitch);
297 dptr += ((h - 1) * pitch);
303 for (int ys = 0; ys < h; ys++) {
305 memcpy(dptr, sptr, w << format);
307 memmove(dptr, sptr, w << format);
313 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) {
315 printf("BlitRectNoMaskComplete\n");
316 uint8_t *sptr = &rtg_mem[src_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE) + (sx << format) + (sy * srcpitch)];
317 uint8_t *dptr = &rtg_mem[dst_addr - (PIGFX_RTG_BASE + PIGFX_REG_SIZE) + (dx << format) + (dy * dstpitch)];
319 uint32_t xdir = 1, src_pitchstep = srcpitch, dst_pitchstep = dstpitch;
321 if (src_addr == dst_addr) {
323 src_pitchstep = -srcpitch;
324 sptr += ((h - 1) * srcpitch);
325 dst_pitchstep = -dstpitch;
326 dptr += ((h - 1) * dstpitch);
333 for (int ys = 0; ys < h; ys++) {
335 memcpy(dptr, sptr, w << format);
337 memmove(dptr, sptr, w << format);
338 sptr += src_pitchstep;
339 dptr += dst_pitchstep;
343 extern struct emulator_config *cfg;
345 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) {
347 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);
348 printf("FBA: %.8x\n", framebuffer_addr);
350 uint8_t *dptr = &rtg_mem[rtg_address_adj[1] + (x << format) + (y * pitch)];
351 uint8_t *sptr = NULL;
352 uint8_t cur_bit = 0, base_bit = 0, cur_byte = 0;
353 uint8_t invert = (draw_mode & DRAWMODE_INVERSVID);
358 tmpl_x = offset_x / 8;
359 cur_bit = base_bit = (0x80 >> (offset_x % 8));
361 uint32_t fg_color[3] = {
363 htobe16((fgcol & 0xFFFF)),
366 uint32_t bg_color[3] = {
368 htobe16((bgcol & 0xFFFF)),
372 if (src_addr >= PIGFX_RTG_BASE)
373 sptr = &rtg_mem[src_addr - PIGFX_RTG_BASE];
375 int i = get_mapped_item_by_address(cfg, src_addr);
377 //printf("Grabbing data from mapped range %d at offset %ld.\n", i, src_addr - cfg->map_offset[i]);
378 sptr = &cfg->map_data[i][src_addr - cfg->map_offset[i]];
381 printf("BlitTemplate: Failed to find mapped range for address %.8X\n", src_addr);
388 for (uint16_t ys = 0; ys < h; ys++) {
389 //printf("JAM1: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
390 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
392 for (int xs = 0; xs < w; xs++) {
393 if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
394 SET_RTG_PIXELS(dptr, xs, format, fg_color);
398 while (cur_bit > 0 && xs < w) {
399 if (cur_byte & cur_bit) {
400 //printf("JAM1: Write byte to dptr[%d] (%p) <- (%p)...\n", xs, dptr, rtg_mem);
401 SET_RTG_PIXEL(dptr, xs, format, fg_color);
415 for (uint16_t ys = 0; ys < h; ys++) {
416 //printf("JAM2: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
417 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
419 for (int xs = 0; xs < w; xs++) {
420 if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
421 SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
425 while (cur_bit > 0 && xs < w) {
426 if (cur_byte & cur_bit) {
427 SET_RTG_PIXEL(dptr, xs, format, fg_color)
430 SET_RTG_PIXEL(dptr, xs, format, bg_color)
443 case DRAWMODE_COMPLEMENT:
444 for (uint16_t ys = 0; ys < h; ys++) {
445 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
447 for (int xs = 0; xs < w; xs++) {
448 if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
449 SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
453 while (cur_bit > 0 && xs < w) {
454 if (cur_byte & cur_bit) {
455 INVERT_RTG_PIXELS(dptr, xs, format)
458 INVERT_RTG_PIXEL(dptr, xs, format)
474 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) {
476 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);
477 printf("FBA: %.8x - lr: %d\n", framebuffer_addr, loop_rows);
479 uint8_t *dptr = &rtg_mem[rtg_address_adj[1] + (x << format) + (y * pitch)];
480 uint8_t *sptr = NULL, *sptr_base = NULL;
481 uint8_t cur_bit = 0, base_bit = 0, cur_byte = 0;
482 uint8_t invert = (draw_mode & DRAWMODE_INVERSVID);
487 tmpl_x = (offset_x / 8) % 2;
488 cur_bit = base_bit = (0x80 >> (offset_x % 8));
490 uint32_t fg_color[3] = {
492 htobe16((fgcol & 0xFFFF)),
495 uint32_t bg_color[3] = {
497 htobe16((bgcol & 0xFFFF)),
502 if (src_addr >= PIGFX_RTG_BASE)
503 sptr = &rtg_mem[src_addr - PIGFX_RTG_BASE];
505 int i = get_mapped_item_by_address(cfg, src_addr);
507 //printf("BlitPattern: Grabbing data from mapped range %d at offset %ld.\n", i, src_addr - cfg->map_offset[i]);
508 sptr = &cfg->map_data[i][src_addr - cfg->map_offset[i]];
511 printf("BlitPattern: Failed to find mapped range for address %.8X\n", src_addr);
517 sptr += (offset_y % loop_rows) * 2;
521 for (uint16_t ys = 0; ys < h; ys++) {
522 //printf("JAM1: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
523 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
525 for (int xs = 0; xs < w; xs++) {
526 if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
527 SET_RTG_PIXELS(dptr, xs, format, fg_color);
531 while (cur_bit > 0 && xs < w) {
532 if (cur_byte & cur_bit) {
533 //printf("JAM1: Write byte to dptr[%d] (%p) <- (%p)...\n", xs, dptr, rtg_mem);
534 SET_RTG_PIXEL(dptr, xs, format, fg_color);
548 for (uint16_t ys = 0; ys < h; ys++) {
549 //printf("JAM2: Get byte from sptr[%d] (%p) <- (%p)...\n", tmpl_x, sptr, cfg->map_data[1]);
550 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
552 for (int xs = 0; xs < w; xs++) {
553 //printf("JAM2: Write byte to dptr[%d] (%p) <- (%p)...\n", xs, dptr, rtg_mem);
554 if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
555 SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
559 while (cur_bit > 0 && xs < w) {
560 if (cur_byte & cur_bit) {
561 SET_RTG_PIXEL(dptr, xs, format, fg_color)
564 SET_RTG_PIXEL(dptr, xs, format, bg_color)
577 case DRAWMODE_COMPLEMENT:
578 for (uint16_t ys = 0; ys < h; ys++) {
579 cur_byte = (invert) ? sptr[tmpl_x] ^ 0xFF : sptr[tmpl_x];
581 for (int xs = 0; xs < w; xs++) {
582 if (w >= 8 && cur_bit == 0x80 && xs < w - 8) {
583 SET_RTG_PIXELS_COND(dptr, xs, format, fg_color, bg_color);
587 while (cur_bit > 0 && xs < w) {
588 if (cur_byte & cur_bit) {
589 INVERT_RTG_PIXELS(dptr, xs, format)
592 INVERT_RTG_PIXEL(dptr, xs, format)