static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
    CirrusVGAState *s = opaque;
    int index;

    /* check port range access depending on color/monochrome mode */
    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
	|| (addr >= 0x3d0 && addr <= 0x3df
	    && !(s->msr & MSR_COLOR_EMULATION)))
	return;

#ifdef DEBUG_VGA
    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
#endif

    switch (addr) {
    case 0x3c0:
	if (s->ar_flip_flop == 0) {
	    val &= 0x3f;
	    s->ar_index = val;
	} else {
	    index = s->ar_index & 0x1f;
	    switch (index) {
	    case 0x00 ... 0x0f:
		s->ar[index] = val & 0x3f;
		break;
	    case 0x10:
		s->ar[index] = val & ~0x10;
		break;
	    case 0x11:
		s->ar[index] = val;
		break;
	    case 0x12:
		s->ar[index] = val & ~0xc0;
		break;
	    case 0x13:
		s->ar[index] = val & ~0xf0;
		break;
	    case 0x14:
		s->ar[index] = val & ~0xf0;
		break;
	    default:
		break;
	    }
	}
	s->ar_flip_flop ^= 1;
	break;
    case 0x3c2:
	s->msr = val & ~0x10;
	break;
    case 0x3c4:
	s->sr_index = val;
	break;
    case 0x3c5:
	if (cirrus_hook_write_sr(s, s->sr_index, val))
	    break;
#ifdef DEBUG_VGA_REG
	printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
#endif
	s->sr[s->sr_index] = val & sr_mask[s->sr_index];
	break;
    case 0x3c6:
	cirrus_write_hidden_dac(s, val);
	break;
    case 0x3c7:
	s->dac_read_index = val;
	s->dac_sub_index = 0;
	s->dac_state = 3;
	break;
    case 0x3c8:
	s->dac_write_index = val;
	s->dac_sub_index = 0;
	s->dac_state = 0;
	break;
    case 0x3c9:
	if (cirrus_hook_write_palette(s, val))
	    break;
	s->dac_cache[s->dac_sub_index] = val;
	if (++s->dac_sub_index == 3) {
	    memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
	    s->dac_sub_index = 0;
	    s->dac_write_index++;
	}
	break;
    case 0x3ce:
	s->gr_index = val;
	break;
    case 0x3cf:
	if (cirrus_hook_write_gr(s, s->gr_index, val))
	    break;
#ifdef DEBUG_VGA_REG
	printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
#endif
	s->gr[s->gr_index] = val & gr_mask[s->gr_index];
	break;
    case 0x3b4:
    case 0x3d4:
	s->cr_index = val;
	break;
    case 0x3b5:
    case 0x3d5:
	if (cirrus_hook_write_cr(s, s->cr_index, val))
	    break;
#ifdef DEBUG_VGA_REG
	printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
#endif
	/* handle CR0-7 protection */
	if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
	    /* can always write bit 4 of CR7 */
	    if (s->cr_index == 7)
		s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
	    return;
	}
	switch (s->cr_index) {
	case 0x01:		/* horizontal display end */
	case 0x07:
	case 0x09:
	case 0x0c:
	case 0x0d:
	case 0x12:		/* vertical display end */
	    s->cr[s->cr_index] = val;
	    break;

	default:
	    s->cr[s->cr_index] = val;
	    break;
	}
	break;
    case 0x3ba:
    case 0x3da:
	s->fcr = val & 0x10;
	break;
    }
}
Unknown