Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
nick.c
Go to the documentation of this file.
1 /* Minimalistic Enterprise-128 emulator with focus on "exotic" hardware
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2015-2017,2020 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 
20 #include "xemu/emutools.h"
21 #include "xemu/emutools_files.h"
22 #include "enterprise128.h"
23 #include "nick.h"
24 #include "cpu.h"
25 #include "dave.h"
26 
27 
28 /*
29  * The basic idea to speed emulation up: use the actual RGB
30  * Uint32 value of EP colours at the sources (eg: setting
31  * border colour, reading LPB, setting BIAS register) and use
32  * those values instead of conversion all the time.
33  */
34 
35 
36 static Uint16 lpt_a, lpt_set, ld1, ld2;
37 static int slot, visible, scanlines, max_scanlines;
38 static Uint8 *vram;
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;
41 static Uint32 palette[16] VARALIGN;
42 static Uint32 full_palette[256] VARALIGN;
43 static Uint32 *palette_bias = palette + 8;
44 static Uint32 border;
45 static Uint8 nick_last_byte;
46 static int reload, vres;
47 static int all_rasters;
48 static int lpt_clk;
49 int vsync;
50 static int frameskip;
51 static int lm, rm;
52 static int vm, cm;
53 static Uint8 col4trans[256 * 4] VARALIGN, col16trans[256 * 2] VARALIGN;
54 static int chs, msbalt, lsbalt;
55 static Uint8 balt_mask, chm, chb, altind;
57 
58 
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
63 
64 
65 static void nick_open_frame_access ( void )
66 {
67  int tail_sdl;
68  Uint32 *pixels_buffer = xemu_start_pixel_buffer_access(&tail_sdl);
69  pixels = pixels_init = pixels_buffer - RASTER_FIRST_VISIBLE * SCREEN_WIDTH;
70  if (tail_sdl)
71  FATAL("tail_sdl is not zero!");
72  pixels_limit_up = pixels_buffer;
73  pixels_limit_bottom = pixels_init + RASTER_LAST_VISIBLE * SCREEN_WIDTH;
74  pixels_limit_vsync_shortest = pixels_init + RASTER_NO_VSYNC_BEFORE * SCREEN_WIDTH;
75  pixels_limit_vsync_long_force = pixels_init + RASTER_FORCE_VSYNC * SCREEN_WIDTH;
76  //pixels_gap = line_size - SCREEN_WIDTH;
77  pixels_gap = 0;
78 }
79 
80 
81 static int nick_addressing_init ( void )
82 {
83  if (SCREEN_WIDTH < 736) {
84  ERROR_WINDOW("NICK: SDL: FATAL ERROR: target SDL surface has width (or pitch?) smaller than 736 pixels [%d]!", SCREEN_WIDTH);
85  return 1;
86  }
87  if (SCREEN_WIDTH & 3) {
88  ERROR_WINDOW("NICK: SDL: FATAL ERROR: line size bytes not 4 bytes aligned!");
89  return 1;
90  }
91  DEBUG("NICK: first visible scanline = %d, last visible scanline = %d, line pitch pixels = %d" NL, RASTER_FIRST_VISIBLE, RASTER_LAST_VISIBLE, 0);
92  nick_open_frame_access();
93  return 0;
94 }
95 
96 
97 void screenshot ( void )
98 {
99  if (!xemu_screenshot_png(
100  NULL, NULL,
101  1,
102  2,
103  NULL, // Allow function to figure it out ;)
104  SCREEN_WIDTH,
107  )) {
108  const char *p = strrchr(xemu_screenshot_full_path, DIRSEP_CHR);
109  if (p)
110  OSD(-1, -1, "%s", p + 1);
111  }
112 }
113 
114 
115 int nick_init ( void )
116 {
117  pixels = NULL; // no previous state of buffer before the next function
118  if (nick_addressing_init())
119  return 1;
120  for (int a = 0; a < 256; a++) {
121  // RGB colours for the target screen
122  int r, g, b;
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);
127  //full_palette[a] = (0xFF << 24) | (r << 16) | (g << 8) | b;
128  //DEBUG("PAL#%d = (%d,%d,%d) = %d" NL, a, r, g, b, full_palette[a]);
129  // this is translation table for 4 colour modes
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);
134  // this is translation table for 16 colour modes
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);
137 
138  }
139  nick_set_bias(ports[0x80] = rand());
140  nick_set_border(ports[0x81] = rand());
141  nick_set_lptl(ports[0x82] = rand());
142  nick_set_lpth(ports[0x83] = rand() | 128 | 64);
143  nick_last_byte = 0xFF;
144  lpt_a = lpt_set;
145  slot = 0;
146  frameskip = 0;
147  all_rasters = 0;
148  scanlines = 0;
149  vsync = 0;
150  vram = memory + 0x3F0000;
151  DEBUG("NICK: initialized." NL);
152  return 0;
153 }
154 
155 
156 
158 {
159  return nick_last_byte;
160 }
161 
162 
163 
164 void nick_set_border ( Uint8 bcol )
165 {
166  border = full_palette[bcol];
167 }
168 
169 
170 
172 {
173  int a;
174  value = (value & 31) << 3;
175  // update the second half of the internal palette ("bias palette") based on the given BIAS value
176  // the first half of the palette is updated by the Nick LPB read process
177  for (a = 0; a < 8; a++)
178  palette_bias[a] = full_palette[value++];
179 }
180 
181 
182 
184 {
185  lpt_set = (lpt_set & 0xF000) | (value << 4);
186 }
187 
188 
189 
191 {
192  DEBUG("NICK SET LPT-H!" NL);
193  lpt_set = (lpt_set & 0x0FF0) | ((value & 0xF) << 12);
194  DEBUG("NICK: LPT is set to %04Xh" NL, lpt_set);
195  if (!(value & 128)) {
196  lpt_a = lpt_set;
197  slot = 0;
198  pixels = pixels_init;
199  scanlines = 0;
200  }
201  lpt_clk = value & 64;
202 }
203 
204 
205 #define NICK_READ(a) (nick_last_byte = vram[a])
206 
207 
208 static inline void FILL( Uint32 colour )
209 {
210  if (visible) {
211  int a;
212  for(a = 0; a < 16; a++)
213  *(pixels++) = colour;
214  } else
215  pixels += 16;
216 }
217 
218 
219 
220 static inline void TODO(void) {
221  FILL(full_palette[1]);
222  DEBUG("NO VM = %d CM = %d" NL, vm, cm);
223 }
224 
225 
226 
227 static void _render_border ( void )
228 {
229  FILL(border);
230 }
231 
232 
233 
234 static void _render_pixel_2 ( void )
235 {
236  if (!visible) {
237  ld1 += 2;
238  pixels += 16;
239  } else {
240  int j;
241  for (j = 0; j < 2; j ++) {
242  int a, ps;
243  Uint8 data = NICK_READ(ld1++);
244  if (msbalt && (data & 128)) {
245  data &= 127;
246  ps = 2;
247  } else
248  ps = 0;
249  if (lsbalt && (data & 1)) {
250  data &= 254;
251  ps |= 4;
252  }
253  for (a = 128; a; a >>= 1) {
254  *(pixels++) = palette[(data & a ? 1 : 0) | ps];
255  }
256  }
257  }
258 }
259 
260 
261 
262 static void _render_lpixel_2 ( void )
263 {
264  if (!visible) {
265  ld1 += 1;
266  pixels += 16;
267  } else {
268  int a, ps;
269  Uint8 data = NICK_READ(ld1++);
270  if (msbalt && (data & 128)) {
271  data &= 127;
272  ps = 2;
273  } else
274  ps = 0;
275  if (lsbalt && (data & 1)) {
276  data &= 254;
277  ps |= 4;
278  }
279  for (a = 128; a; a >>= 1) {
280  pixels[0] = pixels[1] = palette[(data & a ? 1 : 0) | ps];
281  pixels += 2;
282  }
283  }
284 }
285 
286 
287 static void _render_pixel_256 ( void )
288 {
289  if (!visible) {
290  ld1 += 2;
291  pixels += 16;
292  } else {
293  int a;
294  Uint32 colour = full_palette[NICK_READ(ld1++)];
295  for (a = 0; a < 8; a++)
296  *(pixels++) = colour;
297  colour = full_palette[NICK_READ(ld1++)];
298  for (a = 0; a < 8; a++)
299  *(pixels++) = colour;
300  }
301 }
302 static void _render_lpixel_256 ( void )
303 {
304  if (!visible) {
305  ld1++;
306  pixels += 16;
307  } else {
308  int a;
309  Uint8 colour = full_palette[NICK_READ(ld1++)];
310  for (a = 0; a < 16; a++)
311  *(pixels++) = colour;
312  }
313 }
314 
315 
316 
317 static void _render_vsync(void)
318 {
319  FILL(full_palette[4]);
320 }
321 
322 
323 
324 static Uint8 _altind_modes[] = {
325  0, // no altind1, no altind0 (00) 0+0
326  4, // no altind1, do altind0 (01) 0+4
327  2, // do altind1, no altind0 (10) 2+0
328  6, // do altind1, do altind0 (11)
329 };
330 
331 
332 static void _render_char_2 ( void )
333 {
334  if (!visible) {
335  ld1++;
336  } else {
337  Uint8 data = NICK_READ(ld1++);
338  Uint32 c1 = _altind_modes[(altind & data) >> 6];
339  Uint32 c2 = palette[c1 + 1];
340  c1 = palette[c1];
341  data = NICK_READ(ld2 | (data & chm));
342  pixels[ 0] = pixels[ 1] = (data & 0x80) ? c2 : c1;
343  pixels[ 2] = pixels[ 3] = (data & 0x40) ? c2 : c1;
344  pixels[ 4] = pixels[ 5] = (data & 0x20) ? c2 : c1;
345  pixels[ 6] = pixels[ 7] = (data & 0x10) ? c2 : c1;
346  pixels[ 8] = pixels[ 9] = (data & 0x08) ? c2 : c1;
347  pixels[10] = pixels[11] = (data & 0x04) ? c2 : c1;
348  pixels[12] = pixels[13] = (data & 0x02) ? c2 : c1;
349  pixels[14] = pixels[15] = (data & 0x01) ? c2 : c1;
350  }
351  pixels += 16;
352 }
353 
354 
355 static void _render_char_4 ( void )
356 {
357  if (!visible) {
358  ld1++;
359  } else {
360  Uint8 data = NICK_READ(ld1++);
361  Uint32 col[2];
362  col[0] = _altind_modes[(altind & data) >> 6];
363  col[1] = palette[col[0] + 1];
364  col[0] = palette[col[0]];
365  data = NICK_READ(ld2 | (data & chm));
366  Uint8 *trans = col4trans + (data << 2);
367  pixels[ 0] = pixels[ 1] = pixels[ 2] = pixels[ 3] = trans[0] < 2 ? col[trans[0]] : palette[trans[0]];
368  pixels[ 4] = pixels[ 5] = pixels[ 6] = pixels[ 7] = trans[1] < 2 ? col[trans[1]] : palette[trans[1]];
369  pixels[ 8] = pixels[ 9] = pixels[10] = pixels[11] = trans[2] < 2 ? col[trans[2]] : palette[trans[2]];
370  pixels[12] = pixels[13] = pixels[14] = pixels[15] = trans[3] < 2 ? col[trans[3]] : palette[trans[3]];
371  }
372  pixels += 16;
373 }
374 
375 
376 
377 static void _render_invalid ( void )
378 {
379  FILL(full_palette[3]);
380 }
381 
382 
383 static void _render_attrib_2 ( void )
384 {
385  if (!visible) {
386  ld1++;
387  ld2++;
388  } else {
389  int data = NICK_READ(ld1++); // read attribute byte
390  Uint32 c1 = palette[data & 0xF];
391  Uint32 c2 = palette[data >> 4];
392  data = NICK_READ(ld2++); // read graphic byte
393  pixels[ 0] = pixels[ 1] = (data & 0x80) ? c1 : c2;
394  pixels[ 2] = pixels[ 3] = (data & 0x40) ? c1 : c2;
395  pixels[ 4] = pixels[ 5] = (data & 0x20) ? c1 : c2;
396  pixels[ 6] = pixels[ 7] = (data & 0x10) ? c1 : c2;
397  pixels[ 8] = pixels[ 9] = (data & 0x08) ? c1 : c2;
398  pixels[10] = pixels[11] = (data & 0x04) ? c1 : c2;
399  pixels[12] = pixels[13] = (data & 0x02) ? c1 : c2;
400  pixels[14] = pixels[15] = (data & 0x01) ? c1 : c2;
401  }
402  pixels += 16;
403 }
404 
405 
406 static void _render_pixel_4 ( void )
407 {
408  if (!visible) {
409  ld1 += 2;
410  } else {
411  Uint8 *trans = col4trans + (NICK_READ(ld1++) << 2);
412  pixels[ 0] = pixels[ 1] = palette[trans[0]];
413  pixels[ 2] = pixels[ 3] = palette[trans[1]];
414  pixels[ 4] = pixels[ 5] = palette[trans[2]];
415  pixels[ 6] = pixels[ 7] = palette[trans[3]];
416  trans = col4trans + (NICK_READ(ld1++) << 2);
417  pixels[ 8] = pixels[ 9] = palette[trans[0]];
418  pixels[10] = pixels[11] = palette[trans[1]];
419  pixels[12] = pixels[13] = palette[trans[2]];
420  pixels[14] = pixels[15] = palette[trans[3]];
421  }
422  pixels += 16;
423 }
424 
425 static void _render_lpixel_4 ( void )
426 {
427  if (!visible) {
428  ld1 += 1;
429  } else {
430  Uint8 *trans = col4trans + (NICK_READ(ld1++) << 2);
431  pixels[ 0] = pixels[ 1] = pixels[ 2] = pixels[ 3] = palette[trans[0]];
432  pixels[ 4] = pixels[ 5] = pixels[ 6] = pixels[ 7] = palette[trans[1]];
433  pixels[ 8] = pixels[ 9] = pixels[10] = pixels[11] = palette[trans[2]];
434  pixels[12] = pixels[13] = pixels[14] = pixels[15] = palette[trans[3]];
435  }
436  pixels += 16;
437 }
438 
439 
440 static void _render_pixel_16 ( void ) // TODO
441 {
442  if (!visible) {
443  ld1 += 2;
444  } else {
445  Uint8 *trans = col16trans + (NICK_READ(ld1++) << 1);
446  pixels[ 0] = pixels[ 1] = pixels[ 2] = pixels[ 3] = palette[trans[0]];
447  pixels[ 4] = pixels[ 5] = pixels[ 6] = pixels[ 7] = palette[trans[1]];
448  trans = col16trans + (NICK_READ(ld1++) << 1);
449  pixels[ 8] = pixels[ 9] = pixels[10] = pixels[11] = palette[trans[0]];
450  pixels[12] = pixels[13] = pixels[14] = pixels[15] = palette[trans[1]];
451  }
452  pixels += 16;
453 }
454 
455 static void _render_lpixel_16 ( void ) // TODO
456 {
457  if (!visible) {
458  ld1 += 1;
459  } else {
460  Uint8 *trans = col16trans + (NICK_READ(ld1++) << 1);
461  pixels[ 0] = pixels[ 1] = pixels[ 2] = pixels[ 3] =
462  pixels[ 4] = pixels[ 5] = pixels[ 6] = pixels[ 7] = palette[trans[0]];
463  pixels[ 8] = pixels[ 9] = pixels[10] = pixels[11] =
464  pixels[12] = pixels[13] = pixels[14] = pixels[15] = palette[trans[1]];
465  }
466  pixels += 16;
467 }
468 
469 static void _render_char_16 ( void ) { TODO(); }
470 static void _render_char_256 ( void ) { TODO(); }
471 
472 
473 static int _render_selection;
474 //static const int chs_for_modes[] = { 0, 0, 0, 256, 128, 64, 0, 0 };
475 static const int chb_for_modes[] = { 0, 0, 0, 8, 7, 6, 0, 0 };
476 
477 
478 
479 
480 
481 void nick_set_frameskip ( int val )
482 {
483  frameskip = val;
484 }
485 
486 
487 static int frames = 0;
488 //static Uint32 omg = 0x8040C0;
489 
490 static inline void _update ( void )
491 {
492  /*int a;
493  for(a=0;a<100;a++)
494  pixels_limit_up[100*736+400+a]=omg++;*/
495  emu_one_frame(all_rasters, frameskip);
496  all_rasters = 0;
497  frames++;
498  nick_open_frame_access();
499 }
500 
501 
502 static const char *_vm_names[] = {"vsync", "pixel", "attrib", "ch256", "ch128", "ch64", "invalid", "lpixel"};
503 static const char *_cm_names[] = {"2c", "4c", "16c", "256c"};
504 
505 
506 /* Result should be free()'d by the caller then! */
507 char *nick_dump_lpt ( const char *newline_seq )
508 {
509  int a = lpt_set;
510  int scs = 0;
511  char *p = NULL;
512  char buffer[256];
513  do {
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",
515  a,
516  256 - vram[a], // sc
517  vram[a + 1] >> 7, // vint
518  (vram[a + 1] >> 5) & 3, // cm
519  (vram[a + 1] >> 4) & 1, // vres
520  (vram[a + 1] >> 1) & 7, // vm
521  vram[a + 1] & 1, // reload
522  vram[a + 2] & 63, // LM
523  vram[a + 3] & 63, // RM
524  vram[a + 4] | (vram[a + 5] << 8), // LD1
525  vram[a + 6] | (vram[a + 7] << 8), // LD2
526  _vm_names[(vram[a + 1] >> 1) & 7],
527  _cm_names[(vram[a + 1] >> 5) & 3],
528  newline_seq
529  );
530  p = xemu_realloc(p, p ? strlen(p) + strlen(buffer) + 256 : strlen(buffer) + 256);
531  if (a == lpt_set)
532  *p = '\0';
533  strcat(p, buffer);
534  scs += 256 - vram[a];
535  if (vram[a + 1] & 1) {
536  sprintf(buffer, "Total scanlines = %d%s", scs, newline_seq);
537  strcat(p, buffer);
538  return p;
539  }
540  a = (a + 16) & 0xFFFF;
541  } while (a != lpt_set);
542  sprintf(buffer, "ERROR: LPT is endless!%s", newline_seq);
543  strcat(p, buffer);
544  return p;
545 }
546 
547 
548 
549 
550 void nick_render_slot ( void )
551 {
552  register int a;
553  switch (slot) {
554  case 57:
555  raster_time++;
556  all_rasters++;
557  scanlines++;
558  if (scanlines >= max_scanlines) {
559  scanlines = 0;
560  if (!lpt_clk) // LPT clocking is inhibited?
561  lpt_a -= 16; // stay at the current LPB if so
562  else if (reload) // if LPT clocking is OK (it is here) but reload LPT bit is set, then start from the beginning
563  lpt_a = lpt_set;
564  // if non of the above, the default is to continue read the LPT, which is the next LPB, as it should be
565  } else
566  lpt_a -= 16; // stay at the current LPB, it still applies for one or more scanlines
567  pixels += pixels_gap;
568  slot = 0; // NO break after this, control flows over "case 0". This is not a bug, but a feature! :)
569  case 0:
570  max_scanlines = 256 - NICK_READ(lpt_a++);
571  a = NICK_READ(lpt_a++);
572  dave_int1(a & 128);
573  reload = a & 1;
574  vres = a & 16;
575  vm = (a >> 1) & 7;
576  cm = (a >> 5) & 3;
577  if (!vm) { // vsync mode is the actual video mode (vm=0)
578  if (!vsync) { // if previous mode line was not vsync, this is start of the vsync!
579  vsync = 1;
580  if (pixels >= pixels_limit_vsync_shortest)
581  _update();
582  }
583  } else
584  vsync = 0;
585  if (pixels >= pixels_limit_vsync_long_force)
586  _update();
587  visible = (pixels >= pixels_limit_up && pixels < pixels_limit_bottom && (!frameskip));
588  _render_selection = vm | ((a >> 2) & 0x18);
589  if (XEMU_UNLIKELY(_render_selection >= 8 * 4))
590  FATAL("NICK: render funcarray bound check failure!");
591  break;
592  case 1:
593  a = NICK_READ(lpt_a++);
594  lm = a & 63;
595  lsbalt = a & 64;
596  msbalt = a & 128;
597  balt_mask = lsbalt ? 0xFE : 0xFF;
598  if (msbalt) balt_mask &= 0x7F;
599  a = NICK_READ(lpt_a++);
600  rm = a & 63;
601  //altind1 = a & 64;
602  //altind0 = a & 128;
603  altind = ((a & 128) >> 1) | ((a & 64) << 1);
604  break;
605  case 2:
606  a = NICK_READ(lpt_a++);
607  a |= NICK_READ(lpt_a++) << 8;
608  if ((!scanlines) || (!vres))
609  ld1 = a;
610  break;
611  case 3:
612  a = NICK_READ(lpt_a++);
613  a |= NICK_READ(lpt_a++) << 8;
614  if (!scanlines) {
615  chb = chb_for_modes[vm];
616  if (chb) {
617  ld2 = a << chb;
618  chs = 1 << chb;
619  chm = chs - 1;
620  } else {
621  ld2 = a;
622  chs = 0;
623  }
624  } else
625  ld2 += chs; // if chs==0 (non-ch mode) it won't make any difference anyway ...
626  break;
627  // these slots are used to read the palette related info from LPB
628  // note: the high 8 colours of the palette is set by BIAS register, not by the LPB!
629  case 4:
630  palette[0] = full_palette[NICK_READ(lpt_a++)];
631  palette[1] = full_palette[NICK_READ(lpt_a++)];
632  break;
633  case 5:
634  palette[2] = full_palette[NICK_READ(lpt_a++)];
635  palette[3] = full_palette[NICK_READ(lpt_a++)];
636  break;
637  case 6:
638  palette[4] = full_palette[NICK_READ(lpt_a++)];
639  palette[5] = full_palette[NICK_READ(lpt_a++)];
640  break;
641  case 7:
642  palette[6] = full_palette[NICK_READ(lpt_a++)];
643  palette[7] = full_palette[NICK_READ(lpt_a++)];
644  break;
645  case 54:
646  case 55:
647  case 56:
648  // Nick does VRAM refresh here, and generates HSYNC, not so much needed in an emulator, though :)
649  break;
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:
653  // TODO: real nick does not use complicated comparsion just disables border and enables again while hitting lm and rm ...
654  if (slot < lm || slot >= rm) {
655  if (vsync)
656  _render_vsync();
657  else
658  _render_border();
659  } else {
660  switch (_render_selection) {
661  case 0: _render_vsync(); break; // col-2 vsync
662  case 1: _render_pixel_2(); break; // col-2 pixel
663  case 2: _render_attrib_2(); break; // col-2 attrib
664  case 3: _render_char_2(); break; // col-2 ch256
665  case 4: _render_char_2(); break; // col-2 ch128
666  case 5: _render_char_2(); break; // col-2 ch64
667  case 6: _render_invalid(); break; // col-2 invalid
668  case 7: _render_lpixel_2(); break; // col-2 lpixel
669  case 8: _render_vsync(); break; // col-4 vsync
670  case 9: _render_pixel_4(); break; // col-4 pixel
671  case 10: _render_attrib_2(); break; // col-4 attrib TODO
672  case 11: _render_char_4(); break; // col-4 ch256
673  case 12: _render_char_4(); break; // col-4 ch128
674  case 13: _render_char_4(); break; // col-4 ch64
675  case 14: _render_invalid(); break; // col-4 invalid
676  case 15: _render_lpixel_4(); break; // col-4 lpixel
677  case 16: _render_vsync(); break; // col-16 vsync
678  case 17: _render_pixel_16(); break; // col-16 pixel
679  case 18: _render_attrib_2(); break; // col-16 attrib TODO
680  case 19: _render_char_16(); break; // col-16 ch256
681  case 20: _render_char_16(); break; // col-16 ch128
682  case 21: _render_char_16(); break; // col-16 ch64
683  case 22: _render_invalid(); break; // col-16 invalid
684  case 23: _render_lpixel_16(); break; // col-16 lpixel
685  case 24: _render_vsync(); break; // col-256 vsync
686  case 25: _render_pixel_256(); break; // col-256 pixel
687  case 26: _render_attrib_2(); break; // col-256 attrib TODO
688  case 27: _render_char_256(); break; // col-256 ch256
689  case 28: _render_char_256(); break; // col-256 ch128
690  case 29: _render_char_256(); break; // col-256 ch64
691  case 30: _render_invalid(); break; // col-256 invalid
692  case 31: _render_lpixel_256(); break; // col-256 lpixel
693  default: XEMU_UNREACHABLE();
694  }
695  }
696  break;
697  default:
698  FATAL("NICK: FATAL ERROR: invalid slot number for rendering: %d", slot);
699  break;
700  }
701  slot++;
702 }
nick_set_bias
void nick_set_bias(Uint8 value)
Definition: nick.c:171
nick_init
int nick_init(void)
Definition: nick.c:115
emutools.h
nick_set_lpth
void nick_set_lpth(Uint8 value)
Definition: nick.c:190
nick_set_border
void nick_set_border(Uint8 bcol)
Definition: nick.c:164
SCREEN_WIDTH
#define SCREEN_WIDTH
Definition: vic3.h:29
colour
Uint32 colour
Definition: vera.c:67
VARALIGN
#define VARALIGN
Definition: xemu-target.h:25
RASTER_FORCE_VSYNC
#define RASTER_FORCE_VSYNC
Definition: nick.c:62
sdl_pix_fmt
SDL_PixelFormat * sdl_pix_fmt
Definition: emutools.c:80
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
Uint32
uint32_t Uint32
Definition: fat32.c:49
Uint8
uint8_t Uint8
Definition: fat32.c:51
nick_render_slot
void nick_render_slot(void)
Definition: nick.c:550
nick_set_lptl
void nick_set_lptl(Uint8 value)
Definition: nick.c:183
screenshot
void screenshot(void)
Definition: nick.c:97
palette
Uint32 * palette
Definition: vic4_palette.c:33
emutools_files.h
RASTER_NO_VSYNC_BEFORE
#define RASTER_NO_VSYNC_BEFORE
Definition: nick.c:61
raster_time
Uint32 raster_time
Definition: nick.c:56
xemu_start_pixel_buffer_access
Uint32 * xemu_start_pixel_buffer_access(int *texture_tail)
Definition: emutools.c:1153
ERROR_WINDOW
#define ERROR_WINDOW(...)
Definition: xep128.h:116
nick_dump_lpt
char * nick_dump_lpt(const char *newline_seq)
Definition: nick.c:507
cpu.h
NL
#define NL
Definition: fat32.c:37
compress_sd_image.r
def r
Definition: compress_sd_image.py:76
memory
Uint8 memory[0x100000]
Definition: commodore_65.c:43
dave.h
dave_int1
void dave_int1(int level)
Definition: dave.c:227
SCREEN_HEIGHT
#define SCREEN_HEIGHT
Definition: vic3.h:30
OSD
#define OSD(...)
Definition: xep128.h:100
nick_set_frameskip
void nick_set_frameskip(int val)
Definition: nick.c:481
value
int value
Definition: dma65.c:90
Uint16
uint16_t Uint16
Definition: fat32.c:50
emu_one_frame
void emu_one_frame(int rasters, int frameskip)
Definition: enterprise128.c:114
RASTER_LAST_VISIBLE
#define RASTER_LAST_VISIBLE
Definition: nick.c:60
enterprise128.h
XEMU_UNREACHABLE
#define XEMU_UNREACHABLE()
Definition: emutools_basicdefs.h:127
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
xemu_realloc
void * xemu_realloc(void *p, size_t size)
Definition: emutools.c:235
FATAL
#define FATAL(...)
Definition: xep128.h:117
RASTER_FIRST_VISIBLE
#define RASTER_FIRST_VISIBLE
Definition: nick.c:59
vsync
int vsync
Definition: nick.c:49
XEMU_UNLIKELY
#define XEMU_UNLIKELY(__x__)
Definition: emutools_basicdefs.h:125
nick_get_last_byte
Uint8 nick_get_last_byte(void)
Definition: nick.c:157
frameskip
int frameskip
Definition: vic3.c:75
pixels
Uint32 * pixels
Definition: osd.c:33
nick.h
NICK_READ
#define NICK_READ(a)
Definition: nick.c:205
DIRSEP_CHR
#define DIRSEP_CHR
Definition: emutools_basicdefs.h:142