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 memory pointers according to the values stored in the VIC registers. */ void vic_update_memory_ptrs(void) { static BYTE *old_chargen_ptr = NULL; static BYTE *old_color_ptr = NULL; static BYTE *old_screen_ptr = NULL; WORD char_addr; int tmp; BYTE *new_chargen_ptr; BYTE *new_color_ptr; BYTE *new_screen_ptr; tmp = vic.regs[0x5] & 0xf; char_addr = (tmp & 0x8) ? 0x0000 : 0x8000; char_addr += (tmp & 0x7) * 0x400; if (char_addr >= 0x8000 && char_addr < 0x9000) { new_chargen_ptr = vic20memrom_chargen_rom + 0x400 + (char_addr & 0xfff); VIC_DEBUG_REGISTER(("Character memory at $%04X " "(character ROM + $%04X).", char_addr, char_addr & 0xfff)); } else { if (char_addr == 0x1c00) new_chargen_ptr = vic20memrom_chargen_rom; /* handle wraparound */ else new_chargen_ptr = mem_ram + char_addr; VIC_DEBUG_REGISTER (("Character memory at $%04X.", char_addr)); } new_color_ptr = mem_ram + 0x9400 + (vic.regs[0x2] & 0x80 ? 0x200 : 0x0); new_screen_ptr = mem_ram + (((vic.regs[0x2] & 0x80) << 2) | ((vic.regs[0x5] & 0x70) << 6)); VIC_DEBUG_REGISTER(("Color memory at $%04X.", vic.color_ptr - ram)); VIC_DEBUG_REGISTER(("Screen memory at $%04X.", vic.screen_ptr - ram)); if (new_chargen_ptr != old_chargen_ptr) { raster_changes_foreground_add_ptr(&vic.raster, VIC_RASTER_CHAR(VIC_RASTER_CYCLE(maincpu_clk) + 2), (void*)&vic.chargen_ptr, new_chargen_ptr); old_chargen_ptr = new_chargen_ptr; } if (new_color_ptr != old_color_ptr) { raster_changes_foreground_add_ptr(&vic.raster, VIC_RASTER_CHAR(VIC_RASTER_CYCLE(maincpu_clk) + 3), (void*)&vic.color_ptr, new_color_ptr); old_color_ptr = new_color_ptr; } if (new_screen_ptr != old_screen_ptr) { raster_changes_foreground_add_ptr(&vic.raster, VIC_RASTER_CHAR(VIC_RASTER_CYCLE(maincpu_clk) + 3), (void*)&vic.screen_ptr, new_screen_ptr); old_screen_ptr = new_screen_ptr; } }