/* reset the screen pointer at the beginning of the screen */ static inline void crtc_reset_screen_ptr(void) { if (!crtc.initialized) return; crtc.screen_rel = ((CRTC_SCREEN_ADDR() & crtc.vaddr_mask) * crtc.hw_cols); crtc.chargen_rel = (((CRTC_SCREEN_ADDR() & crtc.vaddr_charswitch) ? crtc.vaddr_charoffset : 0) | crtc.chargen_offset) & crtc.chargen_mask; if ((crtc.vaddr_revswitch & crtc.vaddr_mask) || ((crtc.vaddr_revswitch < 0) && !(CRTC_SCREEN_ADDR() & (-crtc.vaddr_revswitch))) || ((crtc.vaddr_revswitch > 0) && (CRTC_SCREEN_ADDR() & crtc.vaddr_revswitch))) { /* standard mode */ if (crtc.raster.video_mode != CRTC_STANDARD_MODE) { raster_changes_foreground_add_int(&crtc.raster, 0, &crtc.raster.video_mode, CRTC_STANDARD_MODE); } } else { /* reverse mode */ if (crtc.raster.video_mode != CRTC_REVERSE_MODE) { raster_changes_foreground_add_int(&crtc.raster, 0, &crtc.raster.video_mode, CRTC_REVERSE_MODE); } } }
inline static void switch_to_display_state(const int cycle) { raster_changes_foreground_add_int(&vicii.raster, VICII_RASTER_CHAR(cycle), &vicii.raster.draw_idle_state, 0); raster_changes_background_add_int(&vicii.raster, VICII_RASTER_X(cycle), &vicii.raster.draw_idle_state, 0); vicii.idle_state = 0; vicii.idle_data_location = IDLE_NONE; }
void vic_store(WORD addr, BYTE value) { addr &= 0xf; vic.regs[addr] = value; VIC_DEBUG_REGISTER (("VIC: write $90%02X, value = $%02X.", addr, value)); switch (addr) { #if 0 /* handled in vic_cycle.c */ case 0: /* $9000 Screen X Location. */ /* VIC checks in cycle n for peek($9000)=n and in this case opens the horizontal flipflop */ case 1: /* $9001 Screen Y Location. */ /* VIC checks from cycle 1 of line r*2 to cycle 0 of line r*2+2 if peek($9001)=r is true and in this case it opens the vertical flipflop */ case 2: /* $9002 Columns Displayed. */ case 5: /* $9005 Video and char matrix base address. */ /* read-only registers */ case 4: /* $9004 Raster line count -- read only. */ case 6: /* $9006. */ case 7: /* $9007 Light Pen X,Y. */ case 8: /* $9008. */ case 9: /* $9009 Paddle X,Y. */ #endif default: return; case 3: /* $9003 Rows Displayed, Character size . */ { int new_char_height = (value & 0x1) ? 16 : 8; vic.row_increase_line = new_char_height; vic.char_height = new_char_height; } return; case 10: /* $900A Bass Enable and Frequency. */ case 11: /* $900B Alto Enable and Frequency. */ case 12: /* $900C Soprano Enable and Frequency. */ case 13: /* $900D Noise Enable and Frequency. */ vic_sound_store(addr, value); return; case 14: /* $900E Auxiliary Colour, Master Volume. */ /* changes of auxiliary color in cycle n is visible at pixel 4*(n-7)+1 */ { static int old_aux_color = -1; int new_aux_color = value>>4; if (new_aux_color != old_aux_color) { /* integer part */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR_INT(vic.raster_cycle+1), &vic.auxiliary_color, new_aux_color); /* fractional part (half chars) */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR_INT(vic.raster_cycle+1), &vic.half_char_flag, VIC_RASTER_CHAR_FRAC(vic.raster_cycle+1)); /* old_mc_auxilary_color is used by vic-draw.c to handle the one hires vic pixel lateness of change */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR(vic.raster_cycle+2), &vic.old_auxiliary_color, new_aux_color); old_aux_color = new_aux_color; } } vic_sound_store(addr, value); return; case 15: /* $900F Screen and Border Colors, Reverse Video. */ /* changes of border/background in cycle n are visible at pixel 4*(n-7)+1, changes of reverse mode at pixel 4*(n-7)+3. */ { static int old_background_color = -1; static int old_border_color = -1; static int old_reverse = -1; int new_background_color, new_border_color, new_reverse; new_background_color = value>>4; new_border_color = value & 0x7; new_reverse = ((value & 0x8) ? 0 : 1); if (new_background_color != old_background_color) { raster_changes_background_add_int(&vic.raster, VIC_RASTER_X(vic.raster_cycle+1) + VIC_PIXEL_WIDTH, (int*)&vic.raster.background_color, new_background_color); old_background_color = new_background_color; } if (new_border_color != old_border_color) { raster_changes_border_add_int(&vic.raster, VIC_RASTER_X(vic.raster_cycle+1) + VIC_PIXEL_WIDTH, (int*)&vic.raster.border_color, new_border_color); /* we also need the border color in multicolor mode, so we duplicate it */ /* integer part */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR_INT(vic.raster_cycle+1), &vic.mc_border_color, new_border_color); /* fractional part (half chars) */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR_INT(vic.raster_cycle+1), &vic.half_char_flag, VIC_RASTER_CHAR_FRAC(vic.raster_cycle+1)); } if (new_reverse != old_reverse) { /* integer part */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR_INT(vic.raster_cycle+1), &vic.reverse, new_reverse); /* fractional part (half chars) */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR_INT(vic.raster_cycle+1), &vic.half_char_flag, VIC_RASTER_CHAR_FRAC(vic.raster_cycle+1)); } if (new_border_color != old_border_color) { /* old_mc_border_color is used by vic-draw.c to handle the one hires vic pixel lateness of change */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR(vic.raster_cycle+2), &vic.old_mc_border_color, new_border_color); old_border_color = new_border_color; } if (new_reverse != old_reverse) { /* old_reverse is used by vic-draw.c to handle the 3 hires vic pixels lateness of change */ raster_changes_foreground_add_int(&vic.raster, VIC_RASTER_CHAR(vic.raster_cycle+2), &vic.old_reverse, new_reverse); old_reverse = new_reverse; } return; } } }
/* Set the video mode according to the values in registers 6 and 7 of TED */ void ted_update_video_mode(unsigned int cycle) { static int old_video_mode = -1; int new_video_mode; new_video_mode = ((ted.regs[0x06] & 0x60) | (ted.regs[0x07] & 0x10)) >> 4; if (new_video_mode != old_video_mode) { if (TED_IS_ILLEGAL_MODE(new_video_mode)) { /* Force the overscan color to black. */ raster_changes_background_add_int (&ted.raster, TED_RASTER_X(cycle), &ted.raster.idle_background_color, 0); raster_changes_background_add_int (&ted.raster, TED_RASTER_X(cycle), &ted.raster.xsmooth_color, 0); ted.force_black_overscan_background_color = 1; } else { /* The overscan background color is given by the background color register. */ if (ted.raster.idle_background_color != ted.regs[0x15]) { raster_changes_background_add_int (&ted.raster, TED_RASTER_X(cycle), &ted.raster.idle_background_color, ted.regs[0x15]); raster_changes_background_add_int (&ted.raster, TED_RASTER_X(cycle), &ted.raster.xsmooth_color, ted.regs[0x15]); } ted.force_black_overscan_background_color = 0; } { int pos; pos = TED_RASTER_CHAR(cycle); raster_changes_foreground_add_int(&ted.raster, pos, &ted.raster.video_mode, new_video_mode); if (ted.idle_data_location != IDLE_NONE) { if (ted.regs[0x06] & 0x40) { raster_changes_foreground_add_int (&ted.raster, pos, (void *)&ted.idle_data, mem_ram[0xffff]); } else { raster_changes_foreground_add_int (&ted.raster, pos, (void *)&ted.idle_data, mem_ram[0xffff]); } } } old_video_mode = new_video_mode; } #ifdef TED_VMODE_DEBUG switch (new_video_mode) { case TED_NORMAL_TEXT_MODE: TED_DEBUG_VMODE(("Standard Text")); break; case TED_MULTICOLOR_TEXT_MODE: TED_DEBUG_VMODE(("Multicolor Text")); break; case TED_HIRES_BITMAP_MODE: TED_DEBUG_VMODE(("Hires Bitmap")); break; case TED_MULTICOLOR_BITMAP_MODE: TED_DEBUG_VMODE(("Multicolor Bitmap")); break; case TED_EXTENDED_TEXT_MODE: TED_DEBUG_VMODE(("Extended Text")); break; case TED_ILLEGAL_TEXT_MODE: TED_DEBUG_VMODE(("Illegal Text")); break; case TED_ILLEGAL_BITMAP_MODE_1: TED_DEBUG_VMODE(("Invalid Bitmap")); break; case TED_ILLEGAL_BITMAP_MODE_2: TED_DEBUG_VMODE(("Invalid Bitmap")); break; default: /* cannot happen */ TED_DEBUG_VMODE(("???")); } TED_DEBUG_VMODE((" Mode enabled at line $%04X, cycle %d.", TED_RASTER_Y(clk), cycle)); #endif }
/* Set the memory pointers according to the values in the registers. */ void ted_update_memory_ptrs(unsigned int cycle) { /* FIXME: This is *horrible*! */ static BYTE *old_screen_ptr, *old_bitmap_ptr, *old_chargen_ptr; static BYTE *old_color_ptr; WORD screen_addr, char_addr, bitmap_addr, color_addr; BYTE *screen_base; /* Pointer to screen memory. */ BYTE *char_base; /* Pointer to character memory. */ BYTE *bitmap_base; /* Pointer to bitmap memory. */ BYTE *color_base; /* Pointer to color memory. */ int tmp; unsigned int video_romsel; unsigned int cpu_romsel; video_romsel = ted.regs[0x12] & 4; cpu_romsel = (ted.regs[0x13] & 1) << 2; screen_addr = ((ted.regs[0x14] & 0xf8) << 8) | 0x400; screen_base = mem_get_tedmem_base((screen_addr >> 14) | cpu_romsel) + (screen_addr & 0x3fff); TED_DEBUG_REGISTER(("\tVideo memory at $%04X", screen_addr)); bitmap_addr = (ted.regs[0x12] & 0x38) << 10; bitmap_base = mem_get_tedmem_base((bitmap_addr >> 14) | video_romsel) + (bitmap_addr & 0x3fff); TED_DEBUG_REGISTER(("\tBitmap memory at $%04X", bitmap_addr)); char_addr = (ted.regs[0x13] & (((ted.regs[0x06] & 0x40) | (ted.regs[0x07] & 0x80)) ? 0xf8 : 0xfc)) << 8; char_base = mem_get_tedmem_base((char_addr >> 14) | video_romsel) + (char_addr & 0x3fff); TED_DEBUG_REGISTER(("\tUser-defined character set at $%04X", char_addr)); color_addr = ((ted.regs[0x14] & 0xf8) << 8); color_base = mem_get_tedmem_base((color_addr >> 14) | cpu_romsel) + (color_addr & 0x3fff); TED_DEBUG_REGISTER(("\tColor memory at $%04X", color_addr)); tmp = TED_RASTER_CHAR(cycle); /* FIXME */ if (ted.idle_data_location != IDLE_NONE) { if (ted.idle_data_location == IDLE_39FF) { raster_changes_foreground_add_int(&ted.raster, TED_RASTER_CHAR(cycle), &ted.idle_data, mem_ram[0x39ff]); } else { raster_changes_foreground_add_int(&ted.raster, TED_RASTER_CHAR(cycle), &ted.idle_data, mem_ram[0x3fff]); } } if (ted.raster.skip_frame || (tmp <= 0 && maincpu_clk < ted.draw_clk)) { old_screen_ptr = ted.screen_ptr = screen_base; old_bitmap_ptr = ted.bitmap_ptr = bitmap_base; old_chargen_ptr = ted.chargen_ptr = char_base; old_color_ptr = ted.color_ptr = color_base; } else if (tmp < TED_SCREEN_TEXTCOLS) { if (screen_base != old_screen_ptr) { raster_changes_foreground_add_ptr(&ted.raster, tmp, (void *)&ted.screen_ptr, (void *)screen_base); old_screen_ptr = screen_base; } if (bitmap_base != old_bitmap_ptr) { raster_changes_foreground_add_ptr(&ted.raster, tmp, (void *)&ted.bitmap_ptr, (void *)(bitmap_base)); old_bitmap_ptr = bitmap_base; } if (char_base != old_chargen_ptr) { raster_changes_foreground_add_ptr(&ted.raster, tmp, (void *)&ted.chargen_ptr, (void *)char_base); old_chargen_ptr = char_base; } if (color_base != old_color_ptr) { raster_changes_foreground_add_ptr(&ted.raster, tmp, (void *)&ted.color_ptr, (void *)color_base); old_color_ptr = color_base; } } else { if (screen_base != old_screen_ptr) { raster_changes_next_line_add_ptr(&ted.raster, (void *)&ted.screen_ptr, (void *)screen_base); old_screen_ptr = screen_base; } if (bitmap_base != old_bitmap_ptr) { raster_changes_next_line_add_ptr(&ted.raster, (void *)&ted.bitmap_ptr, (void *)(bitmap_base)); old_bitmap_ptr = bitmap_base; } if (char_base != old_chargen_ptr) { raster_changes_next_line_add_ptr(&ted.raster, (void *)&ted.chargen_ptr, (void *)char_base); old_chargen_ptr = char_base; } if (color_base != old_color_ptr) { raster_changes_next_line_add_ptr(&ted.raster, (void *)&ted.color_ptr, (void *)color_base); old_color_ptr = color_base; } } }