1 /*
2  * viciitypes.h - A cycle-exact event-driven MOS6569 (VIC-II) emulation.
3  *
4  * Written by
5  *  Ettore Perazzoli <ettore@comm2000.it>
6  *  Andreas Boose <viceteam@t-online.de>
7  *
8  * DTV sections written by
9  *  Hannu Nuotio <hannu.nuotio@tut.fi>
10  *  Daniel Kahlin <daniel@kahlin.net>
11  *
12  * This file is part of VICE, the Versatile Commodore Emulator.
13  * See README for copyright notice.
14  *
15  *  This program is free software; you can redistribute it and/or modify
16  *  it under the terms of the GNU General Public License as published by
17  *  the Free Software Foundation; either version 2 of the License, or
18  *  (at your option) any later version.
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, write to the Free Software
27  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28  *  02111-1307  USA.
29  *
30  */
31 
32 #ifndef VICE_VICIITYPES_H
33 #define VICE_VICIITYPES_H
34 
35 #include "raster.h"
36 #include "types.h"
37 
38 /* Screen constants.  */
39 #define VICII_SCREEN_XPIX                  320
40 #define VICII_SCREEN_YPIX                  200
41 #define VICII_SCREEN_TEXTCOLS              40
42 #define VICII_SCREEN_TEXTLINES             25
43 #define VICII_SCREEN_CHARHEIGHT            8
44 
45 #define VICII_40COL_START_PIXEL vicii.screen_leftborderwidth
46 #define VICII_40COL_STOP_PIXEL  (vicii.screen_leftborderwidth + VICII_SCREEN_XPIX)
47 /* these are one pixel 'off' on the DTV */
48 #define VICII_38COL_START_PIXEL (vicii.screen_leftborderwidth + 7 + vicii.viciidtv)
49 #define VICII_38COL_STOP_PIXEL  (vicii.screen_leftborderwidth + 311 + vicii.viciidtv)
50 
51 #define VICII_NUM_SPRITES      8
52 #define VICII_MAX_SPRITE_WIDTH 56  /* expanded sprite in bug area */
53 #define VICII_NUM_COLORS       16
54 #define VICIIDTV_NUM_COLORS    256
55 
56 /* Available video modes.  The number is given by
57    ((vicii.regs[0x11] & 0x60) | (vicii.regs[0x16] & 0x10)) >> 4.  */
58 /* Also for DTV:
59    | (vicii.regs[0x3c] & 0x04)<<1 | (vicii.regs[0x3c] & 0x01)<<3
60    + FRED/FRED2, CHUNKY/PIXEL/ILLEGAL_LINEAR separation */
61 enum vicii_video_mode_s {
62     VICII_NORMAL_TEXT_MODE,
63     VICII_MULTICOLOR_TEXT_MODE,
64     VICII_HIRES_BITMAP_MODE,
65     VICII_MULTICOLOR_BITMAP_MODE,
66     VICII_EXTENDED_TEXT_MODE,
67     VICII_ILLEGAL_TEXT_MODE,
68     VICII_ILLEGAL_BITMAP_MODE_1,
69     VICII_ILLEGAL_BITMAP_MODE_2,
70 /* DTV modes */
71     VICII_8BPP_NORMAL_TEXT_MODE,
72     VICII_8BPP_MULTICOLOR_TEXT_MODE,
73     VICII_8BPP_HIRES_BITMAP_MODE, /* TODO: doesn't exist */
74     VICII_8BPP_MULTICOLOR_BITMAP_MODE,
75     VICII_8BPP_EXTENDED_TEXT_MODE,
76     VICII_8BPP_CHUNKY_MODE,
77     VICII_8BPP_TWO_PLANE_BITMAP_MODE,
78     VICII_8BPP_FRED_MODE,
79     VICII_8BPP_FRED2_MODE,
80     VICII_8BPP_PIXEL_CELL_MODE,
81     VICII_ILLEGAL_LINEAR_MODE,
82     VICII_IDLE_MODE,           /* Special mode for idle state.  */
83     VICII_NUM_VMODES  /* valid for DTV only */
84 };
85 typedef enum vicii_video_mode_s vicii_video_mode_t;
86 
87 #define VICII_IS_ILLEGAL_MODE(x) ((x) >= VICII_ILLEGAL_TEXT_MODE \
88                                   && (x) <= VICII_ILLEGAL_BITMAP_MODE_2)
89 
90 #define VICII_IS_BITMAP_MODE(x)  ((x) & 0x02)
91 
92 #define VICII_IS_TEXT_MODE(x)    ((x) == VICII_NORMAL_TEXT_MODE \
93                                   || (x) == VICII_MULTICOLOR_TEXT_MODE \
94                                   || (x) == VICII_EXTENDED_TEXT_MODE)
95 
96 /* The actual modes with modulo bug (possibly incomplete) */
97 /*
98 #define VICII_MODULO_BUG(x)      ((x) == VICII_8BPP_FRED_MODE \
99                                  || (x) == VICII_8BPP_FRED2_MODE \
100                                  || (x) == VICII_ILLEGAL_TEXT_MODE \
101                                  || (x) == VICII_8BPP_TWO_PLANE_BITMAP_MODE)
102 */
103 /* Temporary list to keep all demos running correctly */
104 #define VICII_MODULO_BUG(x)      ((x) == VICII_ILLEGAL_TEXT_MODE)
105 
106 /* These timings are taken from the ``VIC Article'' by Christian Bauer
107    <bauec002@goofy.zdv.uni-mainz.de>.  Thanks Christian!
108    Note: we measure cycles from 0 to 62, not from 1 to 63 as he does.  */
109 
110 /* Cycle # at which the VIC takes the bus in a bad line (BA goes low).  */
111 #define VICII_FETCH_CYCLE          11
112 
113 /* Delay for the raster line interrupt.  This is not due to the VIC-II, since
114    it triggers the IRQ line at the beginning of the line, but to the 6510
115    that needs at least 2 cycles to detect it.  */
116 #define VICII_RASTER_IRQ_DELAY     2
117 
118 /* Current char being drawn by the raster.  < 0 or >= VICII_SCREEN_TEXTCOLS
119    if outside the visible range.  */
120 #define VICII_RASTER_CHAR(cycle)   ((int)(cycle) - 15)
121 
122 /* Current horizontal position (in pixels) of the raster.  < 0 or >=
123    SCREEN_WIDTH if outside the visible range.  */
124 #define VICII_RASTER_X(cycle)      (((int)(cycle) - 17) * 8 + vicii.screen_leftborderwidth)
125 
126 /* Adjusted RASTER_X position to account for -2 pixel difference on some
127    C64DTV stores */
128 #define VICIIDTV_RASTER_X_ADJ(cycle)     (VICII_RASTER_X(cycle) - 2)
129 
130 /* Current vertical position of the raster.  Unlike `rasterline', which is
131    only accurate if a pending drawing event has been served, this is
132    guarranteed to be always correct.  It is a bit slow, though.  */
133 #define VICII_RASTER_Y(clk)        ((unsigned int)((clk) \
134                                                    / vicii.cycles_per_line) \
135                                     % vicii.screen_height)
136 
137 /* Cycle # within the current line.  */
138 #define VICII_RASTER_CYCLE(clk)    ((unsigned int)((clk) \
139                                                    % vicii.cycles_per_line))
140 /* DTV Cycle # within the current line.
141    Handles the "hole" on PAL systems at cycles 54-55 and the 1 cycle shift */
142 #define VICIIDTV_RASTER_CYCLE(clk) ((unsigned int)((((clk) - 1) % vicii.cycles_per_line) + ((vicii.cycles_per_line == 63 && (((clk) - 1) % vicii.cycles_per_line) > 53) ? 2 : 0)))
143 
144 /* `clk' value for the beginning of the current line.  */
145 #define VICII_LINE_START_CLK(clk)  (((clk) / vicii.cycles_per_line) \
146                                     * vicii.cycles_per_line)
147 
148 /* # of the previous and next raster line.  Handles wrap over.  */
149 #define VICII_PREVIOUS_LINE(line)  (((line) > 0) \
150                                     ? (line) - 1 : vicii.screen_height - 1)
151 #define VICII_NEXT_LINE(line)      (((line) + 1) % vicii.screen_height)
152 
153 /* VIC-II structures.  This is meant to be used by VIC-II modules
154    *exclusively*!  */
155 
156 struct vicii_light_pen_s {
157     int state;
158     int triggered;
159     int x, y, x_extra_bits;
160 };
161 typedef struct vicii_light_pen_s vicii_light_pen_t;
162 
163 enum vicii_fetch_idx_s {
164     VICII_FETCH_MATRIX,
165     VICII_CHECK_SPRITE_DMA,
166     VICII_FETCH_SPRITE
167 };
168 typedef enum vicii_fetch_idx_s vicii_fetch_idx_t;
169 
170 enum vicii_idle_data_location_s {
171     IDLE_NONE,
172     IDLE_3FFF,
173     IDLE_39FF
174 };
175 typedef enum vicii_idle_data_location_s vicii_idle_data_location_t;
176 
177 struct idle_3fff_s {
178     CLOCK cycle;
179     uint8_t value;
180 };
181 typedef struct idle_3fff_s idle_3fff_t;
182 
183 struct alarm_s;
184 struct video_chip_cap_s;
185 
186 struct vicii_s {
187     /* Flag: Are we initialized?  */
188     int initialized;            /* = 0; */
189 
190     /* VIC-II raster.  */
191     raster_t raster;
192 
193     /* VIC-II registers.  */
194     uint8_t regs[0x50];
195 
196     /* DTV Linear Counters */
197     int counta;
198     int counta_mod;
199     int counta_step;
200     int countb;
201     int countb_mod;
202     int countb_step;
203 
204     /* DTV Palette lookup */
205     uint8_t dtvpalette[256];
206 
207     /* DTV raster IRQ */
208     int raster_irq_offset;
209     int raster_irq_prevent;
210 
211     /* Interrupt register.  */
212     int irq_status;             /* = 0; */
213 
214     /* Line for raster compare IRQ.  */
215     unsigned int raster_irq_line;
216 
217     /* Pointer to the base of RAM seen by the VIC-II.  */
218     /* address is base of 64k bank. vbank adds 0/16k/32k/48k to get actual
219        video address */
220     uint8_t *ram_base_phi1;                /* = VIC-II address during Phi1; */
221     uint8_t *ram_base_phi2;                /* = VIC-II address during Phi2; */
222 
223     /* valid VIC-II address bits for Phi1 and Phi2. After masking
224        the address, it is or'd with the offset value to set always-1 bits */
225     uint16_t vaddr_mask_phi1;            /* mask of valid address bits */
226     uint16_t vaddr_mask_phi2;            /* mask of valid address bits */
227     uint16_t vaddr_offset_phi1;          /* mask of address bits always set */
228     uint16_t vaddr_offset_phi2;          /* mask of address bits always set */
229 
230     /* Those two values determine where in the address space the chargen
231        ROM is mapped. Use mask=0x7000, value=0x1000 for the C64. */
232     uint16_t vaddr_chargen_mask_phi1;    /* address bits to comp. for chargen */
233     uint16_t vaddr_chargen_mask_phi2;    /* address bits to comp. for chargen */
234     uint16_t vaddr_chargen_value_phi1;   /* compare value for chargen */
235     uint16_t vaddr_chargen_value_phi2;   /* compare value for chargen */
236 
237     /* Video memory pointers.  Changed for drawing.  */
238     uint8_t *screen_ptr;
239     uint8_t *chargen_ptr;
240 
241     /* Pointer to the bitmap (lower part)  */
242     uint8_t *bitmap_low_ptr;
243 
244     /* Pointer to the bitmap (higher part)  */
245     uint8_t *bitmap_high_ptr;
246 
247     /* Video memory pointers.  Changed immediately.  */
248     uint8_t *screen_base_phi1;
249     uint8_t *screen_base_phi2;
250 
251     /* Offset to the vbuf/cbuf buffer */
252     int buf_offset;
253 
254     /* Screen memory buffers (chars and color).  */
255     uint8_t vbuf[VICII_SCREEN_TEXTCOLS];
256     uint8_t cbuf[VICII_SCREEN_TEXTCOLS];
257 
258     /* If this flag is set, bad lines (DMA's) can happen.  */
259     int allow_bad_lines;
260 
261     /* Sprite-sprite and sprite-background collision registers.  */
262     uint8_t sprite_sprite_collisions;
263     uint8_t sprite_background_collisions;
264 
265     /* Extended background colors (1, 2 and 3).  */
266     int ext_background_color[3];
267 
268     /* Current video mode.  */
269     int video_mode;
270 
271     /* Flag: are we in idle state? */
272     int idle_state;
273 
274     /* Flag: should we force display (i.e. non-idle) state for the following
275        line? */
276     int force_display_state;
277 
278     /* This flag is set if a memory fetch has already happened on the current
279        line.  FIXME: Value of 2?...  */
280     int memory_fetch_done;
281 
282     /* Internal memory pointer (VCBASE).  */
283     int memptr;
284 
285     /* Internal memory counter (VC).  */
286     int mem_counter;
287 
288     /* Value to add to `mem_counter' after the graphics has been painted.  */
289     int mem_counter_inc;
290 
291     /* Flag: is the current line a `bad' line? */
292     int bad_line;
293 
294     /* Flag: Check for raster.ycounter reset already done on this line?
295        (cycle 13) */
296     int ycounter_reset_checked;
297 
298     /* Flag: Does the currently selected video mode force the overscan
299        background color to be black?  (This happens with the hires bitmap and
300        illegal modes.)  */
301     int force_black_overscan_background_color;
302 
303     /* Background color source */
304     int background_color_source;
305 
306     /* Light pen.  */
307     vicii_light_pen_t light_pen;
308 
309     /* Start of the memory bank seen by the VIC-II.  */
310     int vbank_phi1;                     /* = 0; */
311     int vbank_phi2;                     /* = 0; */
312 
313     /* Pointer to the start of the video bank.  */
314     /* BYTE *vbank_ptr; - never used, only set */
315 
316     /* Data to display in idle state.  */
317     int idle_data;
318 
319     /* left border idle data */
320     int idle_data_l[4];
321     /* middle idle data */
322     int idle_data_m[4];
323     /* right border idle data */
324     int idle_data_r[4];
325 
326     /* Where do we currently fetch idle state from?  If `IDLE_NONE', we are
327        not in idle state and thus do not need to update `idle_data'.  */
328     vicii_idle_data_location_t idle_data_location;
329 
330     /* All the VIC-II logging goes here.  */
331     signed int log;
332 
333     /* VIC-II alarms.  */
334     struct alarm_s *raster_fetch_alarm;
335     struct alarm_s *raster_draw_alarm;
336     struct alarm_s *raster_irq_alarm;
337 
338     /* What do we do when the `A_RASTERFETCH' event happens?  */
339     vicii_fetch_idx_t fetch_idx;
340 
341     /* Number of sprite being DMA fetched.  */
342     unsigned int sprite_fetch_idx;
343 
344     /* Mask for sprites being fetched at DMA.  */
345     unsigned int sprite_fetch_msk;
346 
347     /* Clock cycle for the next "raster fetch" alarm.  */
348     CLOCK fetch_clk;
349 
350     /* Clock cycle for the next "raster draw" alarm.  */
351     CLOCK draw_clk;
352 
353     /* Clock value for raster compare IRQ.  */
354     CLOCK raster_irq_clk;
355 
356     /* FIXME: Bad name.  FIXME: Has to be initialized.  */
357     CLOCK last_emulate_line_clk;
358 
359     /* Clock cycle for the next sprite fetch.  */
360     CLOCK sprite_fetch_clk;
361 
362     /* Geometry and timing parameters of the selected VIC-II emulation.  */
363     unsigned int screen_height;
364     int first_displayed_line;
365     int last_displayed_line;
366 
367     unsigned int row_25_start_line;
368     unsigned int row_25_stop_line;
369     unsigned int row_24_start_line;
370     unsigned int row_24_stop_line;
371 
372     int screen_leftborderwidth;
373     int screen_rightborderwidth;
374     int cycles_per_line;
375     int draw_cycle;
376     int sprite_fetch_cycle;
377     int sprite_wrap_x;
378 
379     unsigned int first_dma_line;
380     unsigned int last_dma_line;
381 
382     /* Flag backgroundcolor in hires mode or extended text mode.  */
383     int get_background_from_vbuf;
384 
385     /* Value to store before DMA.  */
386     CLOCK store_clk;
387     uint16_t store_addr;
388     uint8_t store_value;
389 
390     /* Stores to 0x3fff idle location (used for idle sprite fetch).  */
391     unsigned int num_idle_3fff;
392     idle_3fff_t *idle_3fff;
393     unsigned int num_idle_3fff_old;
394     idle_3fff_t *idle_3fff_old;
395 
396     /* Flag: Enable VIC-IIe features.  */
397     unsigned int viciie;
398 
399     /* Flag: Enable DTV VIC-II features.  */
400     unsigned int viciidtv;
401 
402     /* VIC-IIe clock mode.  */
403     unsigned int fastmode;
404 
405     /* C128 2mhz cycle counter */
406     int half_cycles;
407 
408     /* Last value read from VICII (used for RMW access).  */
409     uint8_t last_read;
410 
411     /* Video chip capabilities.  */
412     struct video_chip_cap_s *video_chip_cap;
413 
414     unsigned int int_num;
415 
416     /* Flag: DTV extended register enable */
417     unsigned int extended_enable;
418 
419     /* Flag: DTV extended register lockout */
420     unsigned int extended_lockout;
421 
422     /* Flag: DTV badline disable */
423     unsigned int badline_disable;
424 
425     /* Flag: DTV colorfetch disable */
426     unsigned int colorfetch_disable;
427 
428     /* Flag: DTV overscan */
429     unsigned int overscan;
430 
431     /* Flag: DTV high color */
432     unsigned int high_color;
433 
434     /* Flag: DTV border off */
435     unsigned int border_off;
436 
437     /* Pointer to color ram */
438     uint8_t *color_ram_ptr;
439 };
440 typedef struct vicii_s vicii_t;
441 
442 extern vicii_t vicii;
443 
444 /* Private function calls, used by the other VIC-II modules.  */
445 extern void vicii_update_memory_ptrs(unsigned int cycle);
446 extern void vicii_update_video_mode(unsigned int cycle);
447 extern void vicii_raster_draw_alarm_handler(CLOCK offset, void *data);
448 extern void vicii_handle_pending_alarms(int num_write_cycles);
449 extern void vicii_delay_clk(void);
450 extern void vicii_delay_oldclk(CLOCK num);
451 
452 /* Debugging options.  */
453 
454 /* #define VICII_VMODE_DEBUG */
455 /* #define VICII_RASTER_DEBUG */
456 /* #define VICII_REGISTERS_DEBUG */
457 
458 #ifdef VICII_VMODE_DEBUG
459 #define VICII_DEBUG_VMODE(x) log_debug x
460 #else
461 #define VICII_DEBUG_VMODE(x)
462 #endif
463 
464 #ifdef VICII_RASTER_DEBUG
465 #define VICII_DEBUG_RASTER(x) log_debug x
466 #else
467 #define VICII_DEBUG_RASTER(x)
468 #endif
469 
470 #ifdef VICII_REGISTERS_DEBUG
471 #define VICII_DEBUG_REGISTER(x) log_debug x
472 #else
473 #define VICII_DEBUG_REGISTER(x)
474 #endif
475 
476 #endif
477