1 /*
2  * vdctypes.h - MOS8563 (VDC) emulation.
3  *
4  * Written by
5  *  Markus Brenner <markus@brenner.de>
6  *  Ettore Perazzoli <ettore@comm2000.it>
7  *  Andreas Boose <viceteam@t-online.de>
8  *  Errol Smith <strobey@users.sourceforge.net>
9  *
10  * This file is part of VICE, the Versatile Commodore Emulator.
11  * See README for copyright notice.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26  *  02111-1307  USA.
27  *
28  */
29 
30 #ifndef VICE_VDCTYPES_H
31 #define VICE_VDCTYPES_H
32 
33 #include "raster.h"
34 #include "types.h"
35 
36 /* Screen constants.  */
37 /* Double pixelsize in y-resolution, to allow for scanlines */
38 /*  and interlace effects                                   */
39 
40 /* Not exact, but for now allow 16 pixels of border each    */
41 
42 #define VDC_DOT_CLOCK 16000000.0
43 
44 #define VDC_SCREEN_WIDTH              856 /* Approx resolution based on experiment - real vdc shows ~107 columns * 8 = 856 */
45 #define VDC_SCREEN_HEIGHT             312 /* Vertical resolution (PAL) based on default kernal settings */
46 
47 #define VDC_SCREEN_XPIX               800
48 #define VDC_SCREEN_YPIX               200
49 #define VDC_SCREEN_MAX_TEXTCOLS       100
50 #define VDC_SCREEN_BORDERWIDTH        8
51 #define VDC_SCREEN_BORDERHEIGHT       0
52 
53 #define VDC_FIRST_DISPLAYED_LINE      21
54 #define VDC_LAST_DISPLAYED_LINE       308
55 #define VDC_80COL_START_PIXEL         16
56 
57 #define VDC_NUM_SPRITES               0
58 #define VDC_NUM_COLORS                16
59 
60 
61 /* VDC Attribute masks */
62 #define VDC_FLASH_ATTR              0x10
63 #define VDC_UNDERLINE_ATTR          0x20
64 #define VDC_REVERSE_ATTR            0x40
65 #define VDC_ALTCHARSET_ATTR         0x80
66 
67 /* Available video modes. */
68 enum vdc_video_mode_s {
69     VDC_TEXT_MODE,
70     VDC_BITMAP_MODE,
71     VDC_IDLE_MODE,
72     VDC_NUM_VMODES
73 };
74 typedef enum vdc_video_mode_s vdc_video_mode_t;
75 
76 #define VDC_IS_ILLEGAL_MODE(x)  ((x) >= VDC_ILLEGAL_TEXT_MODE && (x) != VDC_IDLE_MODE)
77 #define VDC_IS_BITMAP_MODE(x)   ((x) & 0x02)
78 
79 /* VDC structures.  This is meant to be used by VDC modules
80    *exclusively*!  */
81 
82 struct vdc_light_pen_s {
83     int triggered;
84     int x, y;
85 };
86 typedef struct vdc_light_pen_s vdc_light_pen_t;
87 
88 struct alarm_s;
89 struct video_chip_cap_s;
90 
91 #define VDC_REVISION_0  0 /* 8563 R7A */
92 #define VDC_REVISION_1  1 /* 8563 R8/R9 */
93 #define VDC_REVISION_2  2 /* 8568 */
94 
95 #define VDC_NUM_REVISIONS 3
96 
97 struct vdc_s {
98     /* Flag: Are we initialized?  */
99     int initialized;            /* = 0; */
100 
101     /* VDC registers.  */
102     uint8_t regs[64];
103 
104     /* VDC geometry constants that differ in double size mode.  */
105     unsigned int screen_height;
106     unsigned int screen_xpix;
107     unsigned int screen_ypix;
108     unsigned int first_displayed_line;
109     unsigned int last_displayed_line;
110     unsigned int border_height;
111     unsigned int border_width;
112     unsigned int raster_ycounter_max;
113     unsigned int screen_textlines;
114 
115     /* Additional left shift.  */
116     unsigned int hsync_shift;
117 
118     /* Number of chars per line (including blank and sync).  */
119     unsigned int xchars_total;
120 
121     /* VDC to host processor synchronization.  */
122     unsigned int xsync_increment;
123 
124     /* Internal VDC register pointer */
125     int update_reg;
126 
127     /* Number of text characters displayed.  */
128     unsigned int screen_text_cols;
129 
130     /* Video memory offsets.  */
131     unsigned int screen_adr;
132     unsigned int cursor_adr;
133     unsigned int update_adr;
134     unsigned int attribute_adr;
135     unsigned int chargen_adr;
136 
137     /* Internal memory counter. */
138     unsigned int mem_counter;
139     unsigned int bitmap_counter;
140 
141     /* Bytes per character.  */
142     unsigned int bytes_per_char;
143 
144     /* Character width - width of each character on screen in physical pixels */
145     unsigned int charwidth;
146 
147     /* Value to add to `mem_counter' after the graphics has been painted.  */
148     unsigned int mem_counter_inc;
149 
150     /* All the VDC logging goes here.  */
151     signed int log;
152 
153     /* VDC alarms.  */
154     /* Alarm to update a raster line. */
155     struct alarm_s *raster_draw_alarm;
156 
157     /* Memory address mask.  */
158     int vdc_address_mask;
159 
160     /* Frame counter (required for character blink, cursor blink and interlace) */
161     int frame_counter;
162 
163     /* Character attribute blink */
164     int attribute_blink;
165 
166     /* Cursor position.  */
167     int crsrpos;
168 
169     /* Repaint the whole screen next frame.  */
170     int force_repaint;
171 
172     /* Resize geometry next frame.  */
173     int force_resize;
174 
175     /* Flush the cache next frame.  */
176     int force_cache_flush;
177 
178     /* The screen geometry has changed.  */
179     int update_geometry;
180 
181     /* 0..7 pixel x shift.  */
182     unsigned int xsmooth;
183 
184     /* VDC Revision.  */
185     unsigned int revision;
186 
187     /* VDC raster.  */
188     raster_t raster;
189 
190     /* Video chip capabilities.  */
191     struct video_chip_cap_s *video_chip_cap;
192 
193     /* Internal VDC video memory */
194     uint8_t ram[0x10000];
195 
196     /* used to record the value of the cpu clock at the start of a raster line */
197     CLOCK vdc_line_start;
198     /* based on blacky_stardust calculations, calculating current_x_pixel should be like:
199     current_x_pixel = pixels_per_line / (vdc.xsync_increment >> 16) * (current_cycle - vdc_line_start) */
200 
201     /* record register 27 in case of a change between raster updates */
202     int old_reg27;
203 
204     /* Row counter (required for comparison with reg[6] - number of visible screen rows - to know if we are at the end of the visible data) */
205     unsigned int row_counter;
206 
207     /* Row counter_y counts individual raster lines of the current row to know if we are at the end of the current row. */
208     unsigned int row_counter_y;
209 
210     /* offset into the attribute memory - used for emulating the 8x1 attribute VDC quirk */
211     unsigned int attribute_offset;
212 
213     /* flag as to whether the VDC is actually rendering active raster lines, or is idle (i.e in the top or bottom border) */
214     unsigned int display_enable;
215 
216     /* flag as to whether the VDC is preparing to draw but hasn't actually started yet, usually when it's reset to internal row # 0 */
217     unsigned int prime_draw;
218 
219     /* flag as to whether the VDC is drawing (e.g. reading from screen memory) or if it is stopped. This is different to above, because the VDC can be drawing inside the top or bottom border */
220     unsigned int draw_active;
221 
222     /* flag as to whether the VDC is finished drawing or not, to make sure end of frame stuff like video pointers is handled properly */
223     unsigned int draw_finished;
224 
225     /* flag as to whether the VDC is in VSYNC or not */
226     unsigned int vsync;
227 
228     /* internal VDC counter so the vsync is the correct height (in rows) */
229     unsigned int vsync_counter;
230 
231     /* height of the vsync pulse in raster lines, this varies by video standard/video mode */
232     unsigned int vsync_height;
233 
234     /* Row counter used by drawing code. Separate from row_counter above because the drawing can be asynch with the main video signal */
235     unsigned int draw_counter;
236 
237     /* Raster line counter used by drawing code as above. */
238     unsigned int draw_counter_y;
239 
240     /* used to monitor for changes in screen and/or attribute addresses, as the cache can't cope with that */
241     unsigned int old_screen_adr, old_attribute_adr;
242 
243     /* Interlace flag - 0 if normal/non-interlaced, 1 if interlaced */
244     unsigned int interlaced;
245 
246     /* Light pen. */
247     vdc_light_pen_t light_pen;
248 
249     /* Size of vdc canvas, i.e. total visible screen area in pixels */
250     unsigned int canvas_width;
251     unsigned int canvas_height;
252 
253     /* To compare if it changes since last frame */
254     unsigned int canvas_width_old;
255     unsigned int canvas_height_old;
256 
257     /* Internal character and attribute buffers */
258     uint8_t scrnbuf[0x200];
259     unsigned int scrnbufdraw;
260     uint8_t attrbuf[0x200];
261     unsigned int attrbufdraw;
262 };
263 typedef struct vdc_s vdc_t;
264 
265 extern vdc_t vdc;
266 
267 /* Private function calls, used by the other VDC modules.  */
268 extern int vdc_load_palette(const char *name);
269 extern void vdc_fetch_matrix(int offs, int num);
270 extern void vdc_update_memory_ptrs(unsigned int cycle);
271 extern void vdc_update_video_mode(unsigned int cycle);
272 extern void vdc_set_set_canvas_refresh(int enable);
273 extern void vdc_calculate_xsync(void);
274 
275 #endif
276