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