36 static Uint16 lpt_a, lpt_set, ld1, ld2;
37 static int slot, visible, scanlines, max_scanlines;
39 static Uint32 *
pixels, *pixels_init, *pixels_limit_up, *pixels_limit_bottom, *pixels_limit_vsync_shortest, *pixels_limit_vsync_long_force;
40 static int pixels_gap;
45 static Uint8 nick_last_byte;
46 static int reload, vres;
47 static int all_rasters;
54 static int chs, msbalt, lsbalt;
55 static Uint8 balt_mask, chm, chb, altind;
59 #define RASTER_FIRST_VISIBLE 25
60 #define RASTER_LAST_VISIBLE 312
61 #define RASTER_NO_VSYNC_BEFORE 300
62 #define RASTER_FORCE_VSYNC 326
65 static void nick_open_frame_access (
void )
71 FATAL(
"tail_sdl is not zero!");
72 pixels_limit_up = pixels_buffer;
81 static int nick_addressing_init (
void )
84 ERROR_WINDOW(
"NICK: SDL: FATAL ERROR: target SDL surface has width (or pitch?) smaller than 736 pixels [%d]!",
SCREEN_WIDTH);
88 ERROR_WINDOW(
"NICK: SDL: FATAL ERROR: line size bytes not 4 bytes aligned!");
92 nick_open_frame_access();
99 if (!xemu_screenshot_png(
108 const char *p = strrchr(xemu_screenshot_full_path,
DIRSEP_CHR);
110 OSD(-1, -1,
"%s", p + 1);
118 if (nick_addressing_init())
120 for (
int a = 0; a < 256; a++) {
123 r = (((a << 2) & 4) | ((a >> 2) & 2) | ((a >> 6) & 1)) * 255 / 7;
124 g = (((a << 1) & 4) | ((a >> 3) & 2) | ((a >> 7) & 1)) * 255 / 7;
125 b = ( ((a >> 1) & 2) | ((a >> 5) & 1)) * 255 / 3;
126 full_palette[a] = SDL_MapRGBA(
sdl_pix_fmt,
r, g, b, 0xFF);
130 col4trans[a * 4 + 0] = ((a >> 2) & 2) | ((a >> 7) & 1);
131 col4trans[a * 4 + 1] = ((a >> 1) & 2) | ((a >> 6) & 1);
132 col4trans[a * 4 + 2] = ((a ) & 2) | ((a >> 5) & 1);
133 col4trans[a * 4 + 3] = ((a << 1) & 2) | ((a >> 4) & 1);
135 col16trans[a * 2 + 0] = ((a << 2) & 8) | ((a >> 3) & 4) | ((a >> 2) & 2) | ((a >> 7) & 1);
136 col16trans[a * 2 + 1] = ((a << 3) & 8) | ((a >> 2) & 4) | ((a >> 1) & 2) | ((a >> 6) & 1);
143 nick_last_byte = 0xFF;
151 DEBUG(
"NICK: initialized." NL);
159 return nick_last_byte;
166 border = full_palette[bcol];
177 for (a = 0; a < 8; a++)
178 palette_bias[a] = full_palette[
value++];
185 lpt_set = (lpt_set & 0xF000) | (
value << 4);
193 lpt_set = (lpt_set & 0x0FF0) | ((
value & 0xF) << 12);
194 DEBUG(
"NICK: LPT is set to %04Xh" NL, lpt_set);
195 if (!(
value & 128)) {
201 lpt_clk =
value & 64;
205 #define NICK_READ(a) (nick_last_byte = vram[a])
212 for(a = 0; a < 16; a++)
220 static inline void TODO(
void) {
221 FILL(full_palette[1]);
222 DEBUG(
"NO VM = %d CM = %d" NL, vm, cm);
227 static void _render_border (
void )
234 static void _render_pixel_2 (
void )
241 for (j = 0; j < 2; j ++) {
244 if (msbalt && (
data & 128)) {
249 if (lsbalt && (
data & 1)) {
253 for (a = 128; a; a >>= 1) {
254 *(
pixels++) = palette[(
data & a ? 1 : 0) | ps];
262 static void _render_lpixel_2 (
void )
270 if (msbalt && (
data & 128)) {
275 if (lsbalt && (
data & 1)) {
279 for (a = 128; a; a >>= 1) {
287 static void _render_pixel_256 (
void )
295 for (a = 0; a < 8; a++)
298 for (a = 0; a < 8; a++)
302 static void _render_lpixel_256 (
void )
310 for (a = 0; a < 16; a++)
317 static void _render_vsync(
void)
319 FILL(full_palette[4]);
324 static Uint8 _altind_modes[] = {
332 static void _render_char_2 (
void )
338 Uint32 c1 = _altind_modes[(altind &
data) >> 6];
355 static void _render_char_4 (
void )
362 col[0] = _altind_modes[(altind &
data) >> 6];
377 static void _render_invalid (
void )
379 FILL(full_palette[3]);
383 static void _render_attrib_2 (
void )
406 static void _render_pixel_4 (
void )
416 trans = col4trans + (
NICK_READ(ld1++) << 2);
425 static void _render_lpixel_4 (
void )
440 static void _render_pixel_16 (
void )
448 trans = col16trans + (
NICK_READ(ld1++) << 1);
455 static void _render_lpixel_16 (
void )
469 static void _render_char_16 (
void ) { TODO(); }
470 static void _render_char_256 (
void ) { TODO(); }
473 static int _render_selection;
475 static const int chb_for_modes[] = { 0, 0, 0, 8, 7, 6, 0, 0 };
487 static int frames = 0;
490 static inline void _update (
void )
498 nick_open_frame_access();
502 static const char *_vm_names[] = {
"vsync",
"pixel",
"attrib",
"ch256",
"ch128",
"ch64",
"invalid",
"lpixel"};
503 static const char *_cm_names[] = {
"2c",
"4c",
"16c",
"256c"};
514 snprintf(buffer,
sizeof buffer,
"%04X SC=%3d VINT=%d CM=%d VRES=%d VM=%d RELOAD=%d LM=%2d RM=%2d LD1=%04X LD2=%04X %s/%s%s",
518 (vram[a + 1] >> 5) & 3,
519 (vram[a + 1] >> 4) & 1,
520 (vram[a + 1] >> 1) & 7,
524 vram[a + 4] | (vram[a + 5] << 8),
525 vram[a + 6] | (vram[a + 7] << 8),
526 _vm_names[(vram[a + 1] >> 1) & 7],
527 _cm_names[(vram[a + 1] >> 5) & 3],
530 p =
xemu_realloc(p, p ? strlen(p) + strlen(buffer) + 256 : strlen(buffer) + 256);
534 scs += 256 - vram[a];
535 if (vram[a + 1] & 1) {
536 sprintf(buffer,
"Total scanlines = %d%s", scs, newline_seq);
540 a = (a + 16) & 0xFFFF;
541 }
while (a != lpt_set);
542 sprintf(buffer,
"ERROR: LPT is endless!%s", newline_seq);
558 if (scanlines >= max_scanlines) {
570 max_scanlines = 256 -
NICK_READ(lpt_a++);
580 if (
pixels >= pixels_limit_vsync_shortest)
585 if (
pixels >= pixels_limit_vsync_long_force)
588 _render_selection = vm | ((a >> 2) & 0x18);
590 FATAL(
"NICK: render funcarray bound check failure!");
597 balt_mask = lsbalt ? 0xFE : 0xFF;
598 if (msbalt) balt_mask &= 0x7F;
603 altind = ((a & 128) >> 1) | ((a & 64) << 1);
608 if ((!scanlines) || (!vres))
615 chb = chb_for_modes[vm];
650 case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
651 case 29:
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
case 48:
case 49:
652 case 50:
case 51:
case 52:
case 53:
654 if (slot < lm || slot >= rm) {
660 switch (_render_selection) {
661 case 0: _render_vsync();
break;
662 case 1: _render_pixel_2();
break;
663 case 2: _render_attrib_2();
break;
664 case 3: _render_char_2();
break;
665 case 4: _render_char_2();
break;
666 case 5: _render_char_2();
break;
667 case 6: _render_invalid();
break;
668 case 7: _render_lpixel_2();
break;
669 case 8: _render_vsync();
break;
670 case 9: _render_pixel_4();
break;
671 case 10: _render_attrib_2();
break;
672 case 11: _render_char_4();
break;
673 case 12: _render_char_4();
break;
674 case 13: _render_char_4();
break;
675 case 14: _render_invalid();
break;
676 case 15: _render_lpixel_4();
break;
677 case 16: _render_vsync();
break;
678 case 17: _render_pixel_16();
break;
679 case 18: _render_attrib_2();
break;
680 case 19: _render_char_16();
break;
681 case 20: _render_char_16();
break;
682 case 21: _render_char_16();
break;
683 case 22: _render_invalid();
break;
684 case 23: _render_lpixel_16();
break;
685 case 24: _render_vsync();
break;
686 case 25: _render_pixel_256();
break;
687 case 26: _render_attrib_2();
break;
688 case 27: _render_char_256();
break;
689 case 28: _render_char_256();
break;
690 case 29: _render_char_256();
break;
691 case 30: _render_invalid();
break;
692 case 31: _render_lpixel_256();
break;
698 FATAL(
"NICK: FATAL ERROR: invalid slot number for rendering: %d", slot);