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