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