1 /*
2  * tedtypes.h - A cycle-exact event-driven TED emulation.
3  *
4  * Written by
5  *  Andreas Boose <viceteam@t-online.de>
6  *  Ettore Perazzoli <ettore@comm2000.it>
7  *  Tibor Biczo <crown@axelero.hu>
8  *
9  * This file is part of VICE, the Versatile Commodore Emulator.
10  * See README for copyright notice.
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25  *  02111-1307  USA.
26  *
27  */
28 
29 #ifndef VICE_TEDTYPES_H
30 #define VICE_TEDTYPES_H
31 
32 #include "raster.h"
33 #include "types.h"
34 
35 /* Screen constants.  */
36 #define TED_SCREEN_XPIX                 320
37 #define TED_SCREEN_YPIX                 200
38 #define TED_SCREEN_TEXTCOLS             40
39 #define TED_SCREEN_TEXTLINES            25
40 
41 /*
42 #define TED_40COL_START_PIXEL           0x20
43 #define TED_40COL_STOP_PIXEL            0x160
44 #define TED_38COL_START_PIXEL           0x28
45 #define TED_38COL_STOP_PIXEL            0x158
46 */
47 
48 #define TED_40COL_START_PIXEL ted.screen_leftborderwidth
49 #define TED_40COL_STOP_PIXEL  (ted.screen_leftborderwidth + TED_SCREEN_XPIX)
50 #define TED_38COL_START_PIXEL (ted.screen_leftborderwidth + 7)
51 #define TED_38COL_STOP_PIXEL  (ted.screen_leftborderwidth + 311)
52 
53 /* FIXME don't need */
54 #define TED_PAL_OFFSET                  48
55 #define TED_NTSC_OFFSET                 0 /* FIXME */
56 
57 /* values in TED raster counter */
58 /* 0x004 in TED raster counter */
59 #define TED_PAL_25ROW_START_LINE        4
60 /* 0x0CB in TED raster counter */
61 #define TED_PAL_25ROW_STOP_LINE         0xcb
62 /* 0x008 in TED raster counter */
63 #define TED_PAL_24ROW_START_LINE        8
64 /* 0x0C7 in TED raster counter */
65 #define TED_PAL_24ROW_STOP_LINE         0xc7
66 
67 /* FIXME calculate NTSC values */
68 /*
69 #define TED_NTSC_25ROW_START_LINE       (0x33 - TED_NTSC_OFFSET)
70 #define TED_NTSC_25ROW_STOP_LINE        (0xfb - TED_NTSC_OFFSET)
71 #define TED_NTSC_24ROW_START_LINE       (0x37 - TED_NTSC_OFFSET)
72 #define TED_NTSC_24ROW_STOP_LINE        (0xf7 - TED_NTSC_OFFSET)
73 */
74 #define TED_NTSC_25ROW_START_LINE       4
75 #define TED_NTSC_25ROW_STOP_LINE        0xcb
76 #define TED_NTSC_24ROW_START_LINE       8
77 #define TED_NTSC_24ROW_STOP_LINE        0xc7
78 
79 /* TED raster counter values */
80 #define TED_PAL_VSYNC_LINE              257
81 #define TED_NTSC_VSYNC_LINE             229
82 
83 /* FIXME add negated colors as well */
84 #define TED_NUM_COLORS                  128
85 
86 
87 /* Available video modes.  The number is given by TED registers.  */
88 enum ted_video_mode_s {
89     TED_NORMAL_TEXT_MODE,
90     TED_MULTICOLOR_TEXT_MODE,
91     TED_HIRES_BITMAP_MODE,
92     TED_MULTICOLOR_BITMAP_MODE,
93     TED_EXTENDED_TEXT_MODE,
94     TED_ILLEGAL_TEXT_MODE,
95     TED_ILLEGAL_BITMAP_MODE_1,
96     TED_ILLEGAL_BITMAP_MODE_2,
97     TED_IDLE_MODE,           /* Special mode for idle state.  */
98     TED_NUM_VMODES
99 };
100 typedef enum ted_video_mode_s ted_video_mode_t;
101 
102 #define TED_IS_ILLEGAL_MODE(x)       ((x) >= TED_ILLEGAL_TEXT_MODE && (x) != TED_IDLE_MODE)
103 #define TED_IS_BITMAP_MODE(x)        ((x) & 0x02)
104 
105 /* Note: we measure cycles from 0 to 113, not from 1 to 114.  */
106 
107 /* Cycle # at which the TED takes the bus in a bad line (BA goes low).  */
108 #define TED_FETCH_CYCLE             4
109 
110 /* Delay for the raster line interrupt.  This is not due to the TED, since
111    it triggers the IRQ line at the beginning of the line, but to the 7501
112    that needs at least 2 cycles to detect it.  */
113 #define TED_RASTER_IRQ_DELAY        2 /* FIXME!!! */
114 
115 /* Current char being drawn by the raster.  < 0 or >= TED_SCREEN_TEXTCOLS
116    if outside the visible range.  */
117 #define TED_RASTER_CHAR(cycle)      (((int)(cycle) - 15) / 2 )
118 
119 /* Current horizontal position (in pixels) of the raster.  < 0 or >=
120    SCREEN_WIDTH if outside the visible range.  */
121 /* #define TED_RASTER_X(cycle)         (((int)(cycle) - 7) * 4) */
122 #define TED_RASTER_X(cycle)         ((((int)(cycle) - 15) * 4) + ted.screen_leftborderwidth)
123 
124 /* Current vertical position of the raster.  Unlike `rasterline', which is
125    only accurate if a pending drawing event has been served, this is
126    guaranteed to be always correct. */
127 #define TED_RASTER_Y(clk)           ((unsigned int)((ted.ted_raster_counter \
128                                                      + (((clk) - ted.last_emulate_line_clk) \
129                                                         >= 114 ? (ted.ted_raster_counter == ted.screen_height - 1 \
130                                                                   ? 1 - ted.screen_height : 1) : 0)) & 0x1ff))
131 
132 /* Cycle # within the current line.  */
133 #define TED_RASTER_CYCLE(clk)       ((unsigned int)((clk) - ted.last_emulate_line_clk - (((clk) - ted.last_emulate_line_clk) >= 114 ? 114 : 0)))
134 
135 /* `clk' value for the beginning of the current line.  */
136 #define TED_LINE_START_CLK(clk)     ((unsigned int)(ted.last_emulate_line_clk + (((clk) - ted.last_emulate_line_clk) >= 114 ? 114 : 0)))
137 
138 /* # of the previous and next raster line.  Handles wrap over.  */
139 /* FIXME not always true, previous line can be 511 */
140 #define TED_PREVIOUS_LINE(line)  (((line) > 0) ? (line) - 1 : ted.screen_height - 1)
141 /* FIXME not always true, line counter can be in range [screen_height, 511] */
142 #define TED_NEXT_LINE(line)      (((line) + 1) % ted.screen_height)
143 
144 /* FIXME not used can be dropped */
145 #define TED_LINE_RTOU(line) ((line + ted.screen_height - ted.offset) % ted.screen_height)
146 #define TED_LINE_UTOR(line) ((line + ted.screen_height + ted.offset) % ted.screen_height)
147 
148 /* Bad line range.  */
149 /* TED raster_counter values */
150 #define TED_PAL_FIRST_DMA_LINE      0x0
151 #define TED_PAL_LAST_DMA_LINE       0xcb
152 
153 /* FIXME: verify ntsc values */
154 /*
155 #define TED_NTSC_FIRST_DMA_LINE     (0x30 - TED_NTSC_OFFSET)
156 #define TED_NTSC_LAST_DMA_LINE      0xf7
157 */
158 #define TED_NTSC_FIRST_DMA_LINE     0x0   /* FIXME */
159 #define TED_NTSC_LAST_DMA_LINE      0xcb  /* FIXME */
160 
161 /* TED structures.  This is meant to be used by TED modules
162    *exclusively*!  */
163 
164 /*
165 enum ted_fetch_idx_s {
166     TED_FETCH_MATRIX,
167     TED_FETCH_COLOR,
168 };
169 typedef enum ted_fetch_idx_s ted_fetch_idx_t;
170 */
171 
172 /* FIXME Idle location is always $ffff in TED or the data is coming from CPU cycles in certain cases */
173 enum ted_idle_data_location_s {
174     IDLE_NONE,
175     IDLE_3FFF,
176     IDLE_39FF
177 };
178 typedef enum ted_idle_data_location_s ted_idle_data_location_t;
179 
180 struct alarm_s;
181 
182 struct ted_s {
183     /* Flag: Are we initialized?  */
184     int initialized;            /* = 0; */
185 
186     /* TED raster.  */
187     raster_t raster;
188 
189     /* TED registers.  */
190     uint8_t regs[64];
191 
192     /* Interrupt register.  */
193     int irq_status;             /* = 0; */
194 
195     /* Line for raster compare IRQ.  */
196     unsigned int raster_irq_line;
197 
198     /* Video memory pointers.  */
199     uint8_t *screen_ptr;
200     uint8_t *chargen_ptr;
201     uint8_t *bitmap_ptr;
202     uint8_t *color_ptr;
203 
204     /* Screen memory buffers (chars and color).  */
205     uint8_t vbuf[TED_SCREEN_TEXTCOLS];
206     uint8_t cbuf[TED_SCREEN_TEXTCOLS];
207     uint8_t cbuf_tmp[TED_SCREEN_TEXTCOLS];
208 
209     /* If this flag is set, bad lines (DMA's) can happen.  */
210     int allow_bad_lines;
211 
212     /* Extended background colors (1, 2 and 3).  */
213     int ext_background_color[3];
214 
215     /* Flag: is reverse mode enabled or not (bit 7 of $ff07) */
216     int reverse_mode;
217 
218     /* Flag: are we in idle state? */
219     int idle_state;
220 
221     /* Flag: should we force display (i.e. non-idle) state for the following
222        line? */
223     int force_display_state;
224 
225     /* Which display line is drawn? */
226     unsigned int tv_current_line;
227     unsigned int ted_raster_counter;
228 
229     /* This flag is set if a memory fetch has already happened on the current
230        line.  FIXME: Value of 2?...  */
231     int memory_fetch_done;
232 
233     /* Internal memory pointer (VCBASE).  */
234     int memptr;
235     int memptr_col;
236 
237     /* Internal memory counter (VC).  */
238     int mem_counter;
239     /* For bitmap fetch */
240     int chr_pos_reload;
241     int chr_pos_count;
242     int chr_pos_inc_enable;
243 
244     /* Value to add to `mem_counter' after the graphics has been painted.  */
245     int mem_counter_inc;
246 
247     /* Flag: is the current line a `bad' line? */
248     int bad_line;
249 
250     /* Is the cursor visible?  */
251     int cursor_visible;
252 
253     /* Cursor interval counter.  */
254     int cursor_phase;
255 
256     /* Cursor position.  */
257     int crsrpos;
258 
259     /* Flag: Check for raster.ycounter reset already done on this line?
260        (cycle 13) */
261     int ycounter_reset_checked;
262 
263     /* Flag: Does the currently selected video mode force the overscan
264        background color to be black?  (This happens with the hires bitmap and
265        illegal modes.)  */
266     int force_black_overscan_background_color;
267 
268     /* Data to display in idle state.  */
269     int idle_data;
270 
271     /* Where do we currently fetch idle stata from?  If `IDLE_NONE', we are
272        not in idle state and thus do not need to update `idle_data'.  */
273     ted_idle_data_location_t idle_data_location;
274 
275     /* TED keybaord read value.  */
276     uint8_t kbdval;
277 
278     /* All the TED logging goes here.  */
279     signed int log;
280 
281     /* TED alarms.  */
282     struct alarm_s *raster_fetch_alarm;
283     struct alarm_s *raster_draw_alarm;
284     struct alarm_s *raster_irq_alarm;
285 #if 0
286     /* What do we do when the `A_RASTERFETCH' event happens?  */
287     ted_fetch_idx_t fetch_idx;
288 #endif
289     /* Clock cycle for the next "raster fetch" alarm.  */
290     CLOCK fetch_clk;
291 
292     /* Clock cycle for the next "raster draw" alarm.  */
293     CLOCK draw_clk;
294 
295     /* Clock value for raster compare IRQ.  */
296     CLOCK raster_irq_clk;
297 
298     /* FIXME: Bad name.  FIXME: Has to be initialized.  */
299     CLOCK last_emulate_line_clk;
300 
301     /* Geometry and timing parameters of the selected TED emulation.  */
302     unsigned int screen_height;
303     int first_displayed_line;
304     int last_displayed_line;
305 
306     unsigned int row_25_start_line;
307     unsigned int row_25_stop_line;
308     unsigned int row_24_start_line;
309     unsigned int row_24_stop_line;
310 
311     int screen_leftborderwidth;
312     int screen_rightborderwidth;
313 
314     int cycles_per_line;
315     int draw_cycle;
316 
317     unsigned int first_dma_line;
318     unsigned int last_dma_line;
319 
320     unsigned int vsync_line;
321 
322     /* Number of lines the whole screen is shifted up.  */
323     int offset;
324 
325     /* TED clock mode.  */
326     unsigned int fastmode;
327 
328     int character_fetch_on;
329 
330     /* Last value read from TED (used for RMW access).  */
331     uint8_t last_read;
332 
333     /* Video chip capabilities.  */
334     struct video_chip_cap_s *video_chip_cap;
335 
336     unsigned int int_num;
337 };
338 typedef struct ted_s ted_t;
339 
340 extern ted_t ted;
341 
342 /* Private function calls, used by the other TED modules.  */
343 extern void ted_update_memory_ptrs(unsigned int cycle);
344 extern void ted_update_video_mode(unsigned int cycle);
345 extern void ted_raster_draw_alarm_handler(CLOCK offset, void *data);
346 /* extern void ted_resize(void); */
347 extern void ted_delay_clk(void);
348 extern void ted_delay_oldclk(CLOCK num);
349 
350 /* Debugging options.  */
351 
352 /* #define TED_VMODE_DEBUG */
353 /* #define TED_RASTER_DEBUG */
354 /* #define TED_REGISTERS_DEBUG */
355 
356 #ifdef TED_VMODE_DEBUG
357 #define TED_DEBUG_VMODE(x) log_debug x
358 #else
359 #define TED_DEBUG_VMODE(x)
360 #endif
361 
362 #ifdef TED_RASTER_DEBUG
363 #define TED_DEBUG_RASTER(x) log_debug x
364 #else
365 #define TED_DEBUG_RASTER(x)
366 #endif
367 
368 #ifdef TED_REGISTERS_DEBUG
369 #define TED_DEBUG_REGISTER(x) log_debug x
370 #else
371 #define TED_DEBUG_REGISTER(x)
372 #endif
373 
374 #endif
375