X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fvga.c;h=1cf1179ee10fdaade9334c466faab294513fd858;hb=6d3926e16dc1ba6ca0144e65b737e432c48aaa91;hp=db11ea412c8f08cf7a30c45b77d0bb6d9d1f7b53;hpb=acaadd79c597c8d5180fbfbec79c01fef3dff003;p=palacios.git diff --git a/palacios/src/devices/vga.c b/palacios/src/devices/vga.c index db11ea4..1cf1179 100644 --- a/palacios/src/devices/vga.c +++ b/palacios/src/devices/vga.c @@ -710,7 +710,6 @@ static void render_graphics(struct vga_internal *vga, void *fb) db[2] <<= 2; db[0] <<= 2; } - break; // next 4 pixels use planes 1 and 3 for (p=4;p<8;p++) { @@ -1190,8 +1189,8 @@ static int vga_write(struct guest_info * core, struct vm_device *dev = (struct vm_device *)priv_data; struct vga_internal *vga = (struct vga_internal *) dev->private_data; - PrintDebug(core->vm_info, core, "vga: memory write: guest_addr=0x%p len=%u write_mode=%d\n",(void*)guest_addr, length, - vga->vga_graphics_controller.vga_graphics_mode.write_mode); + PrintDebug(core->vm_info, core, "vga: memory write: guest_addr=0x%p len=%u write_mode=%d first_byte=0x%x\n", + (void*)guest_addr, length, vga->vga_graphics_controller.vga_graphics_mode.write_mode, *(uint8_t*)src); if (vga->passthrough) { PrintDebug(core->vm_info, core, "vga: passthrough write to 0x%p\n", V3_VAddr((void*)guest_addr)); @@ -1216,6 +1215,9 @@ static int vga_write(struct guest_info * core, /* Write mode determine by Graphics Mode Register (Index 05h).writemode */ + // probably could just reduce this to the datapath itself instead + // of following the programmer's perspective... + switch (vga->vga_graphics_controller.vga_graphics_mode.write_mode) { case 0: { @@ -1389,7 +1391,7 @@ static int vga_write(struct guest_info * core, uint8_t bm = vga->vga_graphics_controller.vga_bit_mask; uint8_t mm = find_map_write(vga,guest_addr+i); - for (mapnum=0;mapnum<4;mapnum++, bm>>=1, mm>>=1) { + for (mapnum=0;mapnum<4;mapnum++, mm>>=1) { vga_map map = vga->map[mapnum]; uint8_t data = ((uint8_t *)src)[i]; uint8_t latchval = vga->latch[mapnum]; @@ -1458,15 +1460,19 @@ static int vga_write(struct guest_info * core, data = (data>>ror) | (data<<(8-ror)); } + // Note here that the bitmask is the register AND the data + // the data written by the system is used for no other purpose uint8_t bm = vga->vga_graphics_controller.vga_bit_mask & data; + uint8_t sr = vga->vga_graphics_controller.vga_set_reset.val & 0xf; + uint8_t mm = find_map_write(vga,guest_addr+i); - for (mapnum=0;mapnum<4;mapnum++, sr>>=1, bm>>=1, mm>>=1) { + for (mapnum=0;mapnum<4;mapnum++, sr>>=1, mm>>=1) { vga_map map = vga->map[mapnum]; uint8_t latchval = vga->latch[mapnum]; - // expand SR bit + // expand SR bit - that's the data we're going to use data = (sr&0x1) * -1; // mux between latch and alu output @@ -1601,13 +1607,16 @@ static int vga_read(struct guest_info * core, mapnum = find_map_read(vga,guest_addr+i); + // the data returned ((uint8_t*)dst)[i] = *(vga->map[mapnum]+offset); - vga->latch[mapnum] = *(vga->map[mapnum]+offset); - + // need to load all latches even though we are + // returning data from only the selected map + for (mapnum=0;mapnum<4;mapnum++) { + vga->latch[mapnum] = *(vga->map[mapnum]+offset); + } } - } break; @@ -1621,48 +1630,34 @@ static int vga_read(struct guest_info * core, */ int i; - - uint8_t cc=vga->vga_graphics_controller.vga_color_compare.val & 0xf ; - uint8_t dc=vga->vga_graphics_controller.vga_color_dont_care.val & 0xf; - - uint8_t mapnum; uint64_t offset; - uint8_t byte; - uint8_t bits; - + offset = find_offset_read(vga,guest_addr); #if DEBUG_DEEP_MEM - PrintDebug(core->vm_info, core, "vga: mode 1 read, offset=0x%llx, cc=0x%x, dc-0x%x\n",offset,cc,dc); + PrintDebug(core->vm_info, core, "vga: mode 1 read, offset=0x%llx\n",offset); #endif - - for (i=0;imap[mapnum]; - if ( (dc>>mapnum)&0x1 ) { // don't care - bits=0; - } else { - // lower 4 bits - bits = (map[offset]&0xf) == cc; - bits <<= 1; - // upper 4 bits - bits |= (((map[offset]>>4))&0xf) == cc; - } - // not clear whether it is 0..k or k..0 - byte<<=2; - byte|=bits; + for (i=0;ivga_graphics_controller.vga_color_compare.val & 0xf ; + uint8_t dc=vga->vga_graphics_controller.vga_color_dont_care.val & 0xf; + + for (mapnum=0;mapnum<4;mapnum++, cc>>=1, dc>>=1) { + if (dc&0x1) { // dc is active low; 1=we do care + mapcalc &= (cc * -1) & *(vga->map[mapnum]+offset); } - } - - // load the latches with the last item read - for (mapnum=0;mapnum<4;mapnum++) { - vga->latch[mapnum] = vga->map[mapnum][offset+length-1]; + // do latch load + vga->latch[mapnum] = *(vga->map[mapnum]+offset); + } + // write back the comparison result (for 8 pixels) + ((uint8_t *)dst)[i]=mapcalc; } } + break; // there is no default } @@ -1832,6 +1827,28 @@ static int input_stat1_read(struct guest_info *core, *((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val; + // Pretend that horizontal and vertical blanking + // is occurring + if (!vga->vga_misc.vga_input_stat1.disp_en) { + + // if not blanking, start horizontal blanking + vga->vga_misc.vga_input_stat1.disp_en = 1; + vga->vga_misc.vga_input_stat1.vert_retrace = 0; + + } else { + + if (!vga->vga_misc.vga_input_stat1.vert_retrace) { + // if not vertical blanking, then now vertical blanking + vga->vga_misc.vga_input_stat1.disp_en = 1; + vga->vga_misc.vga_input_stat1.vert_retrace = 1; + } else { + // if vertical blanking, now not blanking + vga->vga_misc.vga_input_stat1.disp_en = 0; + vga->vga_misc.vga_input_stat1.vert_retrace = 0; + } + + } + // Stunningly, reading stat1 is also a way to reset // the state of attribute controller address/data flipflop // That is some mighty fine crack the designers were smoking. @@ -2104,9 +2121,14 @@ static int crt_controller_data_write(struct guest_info *core, PASSTHROUGH_IO_OUT(vga,port,src,len); if (index>=VGA_CRT_CONTROLLER_NUM) { - PrintError(core->vm_info, core, "vga; crt controller write is for illegal index %d, ignoring\n",index); + PrintError(core->vm_info, core, "vga; crt controller write is for illegal index %d, ignoring\n",index); } else { - vga->vga_crt_controller.vga_crt_controller_regs[index] = data; + vga->vga_crt_controller.vga_crt_controller_regs[index] = data; + if (index == 17) { + if (vga->vga_crt_controller.vga_vertical_retrace_end.enable_vertical_interrupt) { + PrintError(core->vm_info, core, "vga: vertical_retrace_interrupt_enabled is unsupported -- no interrupts will occur!\n"); + } + } } render(vga);