#define MAP_SIZE 65536
#define MAP_NUM 4
+#define UPDATES_PER_RENDER 100
+
typedef uint8_t *vga_map; // points to MAP_SIZE data
+/* HACK HACK HACK */
+
+struct fb_info {
+ uint32_t rows;
+ uint32_t cols;
+ uint32_t bitsperpixel;
+};
+
+struct fb {
+ struct fb_info *info;
+ uint8_t * data;
+};
+
+//extern
+struct fb *palacios_linux_fb_hack_pointer;
+
+/* HACK HACK HACK */
+
#define VGA_MISC_OUT_READ 0x3cc
#define VGA_MISC_OUT_WRITE 0x3c2
#define VGA_DAC_WRITE_ADDR 0x3c8
#define VGA_DAC_READ_ADDR 0x3c7
-#define VGA_DAC_DATA 0x3c8
+#define VGA_DAC_DATA 0x3c9
#define VGA_DAC_PIXEL_MASK 0x3c6
#define VGA_DAC_NUM_ENTRIES 256
bool passthrough;
+ uint32_t updates_since_render;
+
struct frame_buf *framebuf; // we render to this
// void *mem_store; // This is the region where the memory hooks will go
+static int render(struct vga_internal *vga)
+{
+ vga->updates_since_render++;
+
+ if (vga->updates_since_render<UPDATES_PER_RENDER) {
+ return 0;
+ }
+
+ // PrintError("vga: render UNIMPLEMENTED\n");
+
+ vga->updates_since_render=0;
+
+ if (!palacios_linux_fb_hack_pointer) {
+ return 0;
+ }
+
+
+
+
+ return 0;
+}
+
+
+static void get_mem_region(struct vga_internal *vga, uint64_t *mem_start, uint64_t *mem_end)
+{
+ switch (vga->vga_graphics_controller.vga_misc.memory_map) {
+ case 0:
+ *mem_start=0xa0000;
+ *mem_end=0xc0000;
+ break;
+ case 1:
+ *mem_start=0xa0000;
+ *mem_end=0xb0000;
+ break;
+ case 2:
+ *mem_start=0xb0000;
+ *mem_end=0xb8000;
+ break;
+ case 3:
+ *mem_start=0xb8000;
+ *mem_end=0xc0000;
+ break;
+ }
+}
+
+static uint64_t find_offset(struct vga_internal *vga, addr_t guest_addr)
+{
+ uint64_t mem_start, mem_end;
+
+ mem_start=mem_end=0;
+
+ get_mem_region(vga, &mem_start, &mem_end);
+
+ return (guest_addr-mem_start) % (mem_end-mem_start > 65536 ? 65536 : (mem_end-mem_start));
+
+}
+
+
+
+
static int vga_write(struct guest_info * core,
addr_t guest_addr,
void * src,
uint_t length,
void * priv_data)
{
- struct vga_internal *vga = (struct vga_internal *) priv_data;
+ int i;
+ struct vm_device *dev = (struct vm_device *)priv_data;
+ struct vga_internal *vga = (struct vga_internal *) dev->private_data;
PrintDebug("vga: memory write: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
if (vga->passthrough) {
+ PrintDebug("vga: passthrough write to 0x%p\n", V3_VAddr((void*)guest_addr));
memcpy(V3_VAddr((void*)guest_addr),src,length);
}
+ PrintDebug("vga: data written was \"");
+ for (i=0;i<length;i++) {
+ char c= ((char*)src)[i];
+ PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
+ }
+ PrintDebug("\"\n");
+
/* Write mode determine by Graphics Mode Register (Index 05h).writemode */
switch (vga->vga_graphics_controller.vga_graphics_mode.write_mode) {
uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
- offset =(uint64_t) guest_addr - (uint64_t) MEM_REGION_START;
+ offset = find_offset(vga, guest_addr);
+
+ PrintDebug("vga: mode 0 write, offset=0x%llx, ror=%u, func=%u\n", offset,ror,func);
for (i=0;i<length;i++,offset++) {
// now for each map
// selective write
if (mm & 0x1) {
// write to this map
+ //PrintDebug("vga: write map %u offset 0x%p map=0x%p pointer=0x%p\n",mapnum,(void*)offset,map,&(map[offset]));
map[offset] = data;
} else {
// skip this map
int i;
- uint64_t offset =(uint64_t) guest_addr - (uint64_t) MEM_REGION_START;
+ uint64_t offset = find_offset(vga,guest_addr);
+
+ PrintDebug("vga: mode 1 write, offset=0x%llx\n", offset);
for (i=0;i<length;i++,offset++) {
uint8_t func = vga->vga_graphics_controller.vga_data_rotate.function;
- offset =(uint64_t) guest_addr - (uint64_t) MEM_REGION_START;
+ offset = find_offset(vga, guest_addr);
+
+ PrintDebug("vga: mode 2 write, offset=0x%llx, func=%u\n", offset,func);
for (i=0;i<length;i++,offset++) {
// now for each map
uint8_t ror = vga->vga_graphics_controller.vga_data_rotate.rotate_count;
- offset =(uint64_t) guest_addr - (uint64_t) MEM_REGION_START;
+ offset = find_offset(vga, guest_addr);
+
+ PrintDebug("vga: mode 3 write, offset=0x%llx, ror=%u\n", offset,ror);
for (i=0;i<length;i++,offset++) {
// now for each map
// There is no default
}
+
+ render(vga);
return length;
}
- // PrintError("vga: vga_write UNIMPLEMENTED\n");
/*
-up to 256K mapped through a window of 128K
+up to 256K mapped through a window of 32 to 128K
most cards support linear mode as well
uint_t length,
void * priv_data)
{
-
- struct vga_internal *vga = (struct vga_internal *) priv_data;
+ int i;
+ struct vm_device *dev = (struct vm_device *)priv_data;
+ struct vga_internal *vga = (struct vga_internal *) dev->private_data;
+
PrintDebug("vga: memory read: guest_addr=0x%p len=%u\n",(void*)guest_addr, length);
- if (vga->passthrough) {
- memcpy(dst,V3_VAddr((void*)guest_addr),length);
- }
-
+
+
+
/*
Reading, 2 modes, set via Graphics Mode Register (index 05h).Read Mode:
*/
uint64_t offset;
mapnum = vga->vga_graphics_controller.vga_read_map_select.map_select;
- offset =(uint64_t) guest_addr - (uint64_t) MEM_REGION_START;
+ offset = find_offset(vga,guest_addr);
if (offset>=65536) {
PrintError("vga: read to offset=%llu map=%u (%u bytes)\n",offset,mapnum,length);
uint8_t byte;
uint8_t bits;
- offset =(uint64_t) guest_addr - (uint64_t) MEM_REGION_START;
+ offset = find_offset(vga,guest_addr);
for (i=0;i<length;i++,offset++) {
vga_map map;
// there is no default
}
+ if (vga->passthrough) {
+ PrintDebug("vga: passthrough read from 0x%p\n",V3_VAddr((void*)guest_addr));
+ memcpy(dst,V3_VAddr((void*)guest_addr),length);
+ }
+
+
+ PrintDebug("vga: data read is \"");
+ for (i=0;i<length;i++) {
+ char c= ((char*)dst)[i];
+ PrintDebug("%c", (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') ? c : '.');
+ }
+ PrintDebug("\"\n");
+
return length;
}
-static int render(struct vga_internal *vga)
-{
- PrintError("vga: render UNIMPLEMENTED\n");
- return 0;
-}
#define ERR_WRONG_SIZE(op,reg,len,min,max) \
do { if ((vga)->passthrough) { passthrough_io_in(port,dest,len); } } while (0)
#define PASSTHROUGH_IO_OUT(vga,port,src,len) \
- do { if ((vga)->passthrough) { passthrough_io_in(port,src,len); } } while (0)
+ do { if ((vga)->passthrough) { passthrough_io_out(port,src,len); } } while (0)
-
+#define PASSTHROUGH_READ_CHECK(vga,inter,pass) \
+ do { if ((vga)->passthrough) { if ((inter)!=(pass)) { PrintError("vga: passthrough error: passthrough value read is 0x%x, but internal value read is 0x%x\n",(pass),(inter)); } } } while (0)
static int misc_out_read(struct guest_info *core,
uint16_t port,
PrintDebug("vga: misc out read data=0x%x\n", vga->vga_misc.vga_misc_out.val);
ERR_WRONG_SIZE("read","misc out",len,1,1);
-
+
+ *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_misc.vga_misc_out.val;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_misc_out.val,*((uint8_t*)dest));
return len;
}
ERR_WRONG_SIZE("read","input stat0",len,1,1);
+ *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_misc.vga_input_stat0.val;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat0.val,*(uint8_t*)dest);
return len;
}
ERR_WRONG_SIZE("read","input stat1",len,1,1);
- PASSTHROUGH_IO_IN(vga,port,dest,len);
*((uint8_t*)dest) = vga->vga_misc.vga_input_stat1.val;
vga->vga_attribute_controller.state=ATTR_ADDR;
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
+
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_input_stat1.val,*(uint8_t*)dest);
+
return len;
}
ERR_WRONG_SIZE("read","feature control",len,1,1);
- PASSTHROUGH_IO_IN(vga,port,dest,len);
*((uint8_t*)dest) = vga->vga_misc.vga_feature_control.val;
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
+
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_feature_control.val,*(uint8_t*)dest);
+
return len;
}
ERR_WRONG_SIZE("read","video subsys enable",len,1,1);
+ *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_misc.vga_video_subsys_enable.val;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_misc.vga_video_subsys_enable.val,*(uint8_t*)dest);
return len;
}
ERR_WRONG_SIZE("read","vga sequencer addr",len,1,1);
+ *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_sequencer.vga_sequencer_addr.val;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_sequencer.vga_sequencer_addr.val,*(uint8_t*)dest);
+
+ return len;
+}
+static int sequencer_data_write(struct guest_info *core,
+ uint16_t port,
+ void *src,
+ uint_t len,
+ void *priv_data)
+{
+ struct vga_internal *vga = (struct vga_internal *) priv_data;
+ uint8_t index;
+ uint8_t data;
+
+ data=*((uint8_t*)src);
+ index=vga->vga_sequencer.vga_sequencer_addr.val; // should mask probably
+
+ PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n",
+ index, data);
+
+ ERR_WRONG_SIZE("write","vga sequencer data",len,1,1);
+
+ PASSTHROUGH_IO_OUT(vga,port,src,len);
+
+
+ if (index>=VGA_SEQUENCER_NUM) {
+ PrintError("vga: sequencer data write is for invalid index %d, ignoring\n",index);
+ } else {
+ vga->vga_sequencer.vga_sequencer_regs[index] = data;
+ }
+
+ render(vga);
+
return len;
}
new_addr=*((uint8_t*)src);
- PrintDebug("vga: sequencer address write data=0x%x\n", new_addr);
+ PrintDebug("vga: sequencer address write data=0x%x len=%u\n", len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
- ERR_WRONG_SIZE("write","vga sequenver addr",len,1,1);
+ ERR_WRONG_SIZE("write","vga sequencer addr",len,1,2);
- PASSTHROUGH_IO_OUT(vga,port,src,len);
+ PASSTHROUGH_IO_OUT(vga,port,src,1);
- if (new_addr>VGA_SEQUENCER_NUM) {
- PrintError("vga: ignoring change of sequencer address to %u (>%u)\n",
- new_addr, VGA_SEQUENCER_NUM);
- //return -1;
- } else {
- vga->vga_sequencer.vga_sequencer_addr.val = *((uint8_t*)src) ;
+ vga->vga_sequencer.vga_sequencer_addr.val = *((uint8_t*)src) ;
+
+ if (len==2) {
+ // second byte is the data
+ if (sequencer_data_write(core,port,src+1,1,vga)!=1) {
+ PrintError("vga: write of data failed\n");
+ return -1;
+ }
}
return len;
uint8_t data;
index=vga->vga_sequencer.vga_sequencer_addr.val; // should mask probably
- data=vga->vga_sequencer.vga_sequencer_regs[index];
-
- PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n",
- index, data);
- ERR_WRONG_SIZE("read","vga sequenver data",len,1,1);
+ if (index>=VGA_SEQUENCER_NUM) {
+ data=0;
+ PrintError("vga: sequencer data read at invalid index %d, returning zero\n",index);
+ } else {
+ data=vga->vga_sequencer.vga_sequencer_regs[index];
+ }
- PASSTHROUGH_IO_IN(vga,port,dest,len);
+ PrintDebug("vga: sequencer data read data (index=%d) = 0x%x\n",
+ index, data);
+
+ ERR_WRONG_SIZE("read","vga sequencer data",len,1,1);
*((uint8_t*)dest) = data;
- return len;
-}
-
-static int sequencer_data_write(struct guest_info *core,
- uint16_t port,
- void *src,
- uint_t len,
- void *priv_data)
-{
- struct vga_internal *vga = (struct vga_internal *) priv_data;
- uint8_t index;
- uint8_t data;
-
- data=*((uint8_t*)src);
- index=vga->vga_sequencer.vga_sequencer_addr.val; // should mask probably
-
- PrintDebug("vga: sequencer write data (index=%d) with 0x%x\n",
- index, data);
-
- ERR_WRONG_SIZE("write","vga sequencer data",len,1,1);
-
- PASSTHROUGH_IO_OUT(vga,port,src,len);
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
- vga->vga_sequencer.vga_sequencer_regs[index] = data;
+ PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
- render(vga);
-
return len;
}
+
ERR_WRONG_SIZE("read","vga crt controller addr",len,1,1);
+ *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_crt_controller.vga_crt_addr.val;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_crt_controller.vga_crt_addr.val,*(uint8_t*)dest);
+
+ return len;
+}
+
+static int crt_controller_data_write(struct guest_info *core,
+ uint16_t port,
+ void *src,
+ uint_t len,
+ void *priv_data)
+{
+ struct vga_internal *vga = (struct vga_internal *) priv_data;
+ uint8_t index;
+ uint8_t data;
+
+ data=*((uint8_t*)src);
+
+ index=vga->vga_crt_controller.vga_crt_addr.val; // should mask probably
+
+ PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n",
+ port==0x3b5 ? "mono" : "color",
+ index, data);
+
+ ERR_WRONG_SIZE("write","vga crt controller data",len,1,1);
+
+ PASSTHROUGH_IO_OUT(vga,port,src,len);
+
+ if (index>=VGA_CRT_CONTROLLER_NUM) {
+ PrintError("vga; crt controller write is for illegal index %d, ignoring\n",index);
+ } else {
+ vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
+ }
+
+ render(vga);
return len;
}
new_addr=*((uint8_t*)src);
- PrintDebug("vga: crt controller (%s) address write data=0x%x\n",
+ PrintDebug("vga: crt controller (%s) address write data=0x%x len=%u\n",
port==0x3b4 ? "mono" : "color",
- new_addr);
+ len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
- ERR_WRONG_SIZE("write","vga crt controller addr",len,1,1);
+ ERR_WRONG_SIZE("write","vga crt controller addr",len,1,2);
- PASSTHROUGH_IO_OUT(vga,port,src,len);
+ PASSTHROUGH_IO_OUT(vga,port,src,1);
- if (new_addr>VGA_CRT_CONTROLLER_NUM) {
- PrintError("vga: ignoring change of crt controller address to %u (>%u)\n",
- new_addr, VGA_CRT_CONTROLLER_NUM);
- //return -1;
- } else {
- vga->vga_crt_controller.vga_crt_addr.val = *((uint8_t*)src) ;
+ vga->vga_crt_controller.vga_crt_addr.val = *((uint8_t*)src) ;
+
+ if (len==2) {
+ // second byte is the data
+ if (crt_controller_data_write(core,port,src+1,1,vga)!=1) {
+ PrintError("vga: write of data failed\n");
+ return -1;
+ }
}
-
+
return len;
}
uint8_t data;
index=vga->vga_crt_controller.vga_crt_addr.val; // should mask probably
- data=vga->vga_crt_controller.vga_crt_controller_regs[index];
- PrintDebug("vga: crt controller data (%s) read data (index=%d) = 0x%x\n",
- port==0x3b5 ? "mono" : "color",
- index, data);
+ if (index>=VGA_CRT_CONTROLLER_NUM) {
+ data=0;
+ PrintError("vga: crt controller data read for illegal index %d, returning zero\n",index);
+ } else {
+ data=vga->vga_crt_controller.vga_crt_controller_regs[index];
+ }
+ PrintDebug("vga: crt controller data (index=%d) = 0x%x\n",index,data);
+
ERR_WRONG_SIZE("read","vga crt controller data",len,1,1);
- PASSTHROUGH_IO_IN(vga,port,dest,len);
-
*((uint8_t*)dest) = data;
- return len;
-}
-
-static int crt_controller_data_write(struct guest_info *core,
- uint16_t port,
- void *src,
- uint_t len,
- void *priv_data)
-{
- struct vga_internal *vga = (struct vga_internal *) priv_data;
- uint8_t index;
- uint8_t data;
-
- data=*((uint8_t*)src);
-
- index=vga->vga_crt_controller.vga_crt_addr.val; // should mask probably
-
- PrintDebug("vga: crt controller (%s) write data (index=%d) with 0x%x\n",
- port==0x3b5 ? "mono" : "color",
- index, data);
-
- ERR_WRONG_SIZE("write","vga crt controller data",len,1,1);
-
- PASSTHROUGH_IO_OUT(vga,port,src,len);
-
- vga->vga_crt_controller.vga_crt_controller_regs[index] = data;
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
- render(vga);
+ PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t *)dest);
return len;
}
+
static int graphics_controller_address_read(struct guest_info *core,
uint16_t port,
void *dest,
ERR_WRONG_SIZE("read","vga graphics controller addr",len,1,1);
+ *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_graphics_controller.vga_graphics_ctrl_addr.val;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_graphics_controller.vga_graphics_ctrl_addr.val,*(uint8_t*)dest);
return len;
}
+static int graphics_controller_data_write(struct guest_info *core,
+ uint16_t port,
+ void *src,
+ uint_t len,
+ void *priv_data)
+{
+ struct vga_internal *vga = (struct vga_internal *) priv_data;
+ uint8_t index;
+ uint8_t data;
+
+ data=*((uint8_t*)src);
+ index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val; // should mask probably
+
+
+ PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n",
+ index, data);
+
+ ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
+
+ PASSTHROUGH_IO_OUT(vga,port,src,len);
+
+ if (index>=VGA_GRAPHICS_CONTROLLER_NUM) {
+ PrintError("vga: graphics controller write for illegal index %d ignored\n",index);
+ } else {
+ vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
+ }
+
+ render(vga);
+
+ return len;
+}
+
static int graphics_controller_address_write(struct guest_info *core,
uint16_t port,
void *src,
new_addr=*((uint8_t*)src);
- PrintDebug("vga: graphics controller address write data=0x%x\n", new_addr);
+ PrintDebug("vga: graphics controller address write data=0x%x len=%u\n",
+ len==1 ? *((uint8_t*)src) : len==2 ? *((uint16_t*)src) : *((uint32_t*)src), len);
- ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,1);
+ ERR_WRONG_SIZE("write","vga graphics controller addr",len,1,2);
- PASSTHROUGH_IO_OUT(vga,port,src,len);
+ PASSTHROUGH_IO_OUT(vga,port,src,1);
- if (new_addr>VGA_GRAPHICS_CONTROLLER_NUM) {
- PrintError("vga: ignoring change of graphics controller address to %u (>%u)\n",
- new_addr, VGA_GRAPHICS_CONTROLLER_NUM);
- //return -1;
- } else {
- vga->vga_graphics_controller.vga_graphics_ctrl_addr.val = *((uint8_t*)src) ;
+ vga->vga_graphics_controller.vga_graphics_ctrl_addr.val = *((uint8_t*)src) ;
+
+ if (len==2) {
+ // second byte is the data
+ if (graphics_controller_data_write(core,port,src+1,1,vga)!=1) {
+ PrintError("vga: write of data failed\n");
+ return -1;
+ }
}
return len;
uint8_t data;
index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val; // should mask probably
- data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
+
+
+ if (index>=VGA_GRAPHICS_CONTROLLER_NUM) {
+ data=0;
+ PrintError("vga: graphics controller data read from illegal index %d, returning zero\n",index);
+ } else {
+ data=vga->vga_graphics_controller.vga_graphics_controller_regs[index];
+ }
PrintDebug("vga: graphics controller data read data (index=%d) = 0x%x\n",
index, data);
ERR_WRONG_SIZE("read","vga graphics controller data",len,1,1);
- PASSTHROUGH_IO_IN(vga,port,dest,len);
-
*((uint8_t*)dest) = data;
- return len;
-}
-
-static int graphics_controller_data_write(struct guest_info *core,
- uint16_t port,
- void *src,
- uint_t len,
- void *priv_data)
-{
- struct vga_internal *vga = (struct vga_internal *) priv_data;
- uint8_t index;
- uint8_t data;
-
- data=*((uint8_t*)src);
- index=vga->vga_graphics_controller.vga_graphics_ctrl_addr.val; // should mask probably
-
- PrintDebug("vga: graphics_controller write data (index=%d) with 0x%x\n",
- index, data);
-
- ERR_WRONG_SIZE("write","vga graphics controller data",len,1,1);
-
- PASSTHROUGH_IO_OUT(vga,port,src,len);
-
- vga->vga_graphics_controller.vga_graphics_controller_regs[index] = data;
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
- render(vga);
+ PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
return len;
}
+
/* Note that these guys have a bizarre protocol*/
static int attribute_controller_address_read(struct guest_info *core,
ERR_WRONG_SIZE("read","vga attribute controller addr",len,1,1);
+ *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_attribute_controller.vga_attribute_controller_addr.val;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_attribute_controller.vga_attribute_controller_addr.val,*(uint8_t*)dest);
// Reading the attribute controller does not change the state
PASSTHROUGH_IO_OUT(vga,port,src,len);
- if (new_addr>VGA_ATTRIBUTE_CONTROLLER_NUM) {
- PrintError("vga: ignoring change of attribute controller address to %u (>%u)\n",
- new_addr, VGA_ATTRIBUTE_CONTROLLER_NUM);
- //return -1;
- } else {
- vga->vga_attribute_controller.vga_attribute_controller_addr.val = *((uint8_t*)src) ;
- }
+ vga->vga_attribute_controller.vga_attribute_controller_addr.val = new_addr;
+
vga->vga_attribute_controller.state=ATTR_DATA;
return len;
PASSTHROUGH_IO_OUT(vga,port,src,len);
- vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
+ if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) {
+ PrintError("vga: attribute controller write to illegal index %d ignored\n",index);
+ } else {
+ vga->vga_attribute_controller.vga_attribute_controller_regs[index] = data;
+ }
vga->vga_attribute_controller.state=ATTR_ADDR;
uint8_t data;
index=vga->vga_attribute_controller.vga_attribute_controller_addr.val; // should mask probably
- data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
+
+ if (index>=VGA_ATTRIBUTE_CONTROLLER_NUM) {
+ data=0;
+ PrintError("vga: attribute controller read of illegal index %d, returning zero\n",index);
+ } else {
+ data=vga->vga_attribute_controller.vga_attribute_controller_regs[index];
+ }
PrintDebug("vga: attribute controller data read data (index=%d) = 0x%x\n",
index, data);
ERR_WRONG_SIZE("read","vga attribute controller data",len,1,1);
+ *((uint8_t*)dest) = data;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = data;
+ PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
return len;
}
ERR_WRONG_SIZE("read","vga dac write addr",len,1,1);
- PASSTHROUGH_IO_IN(vga,port,dest,len);
*((uint8_t*)dest) = vga->vga_dac.vga_dac_write_addr;
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
+
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_write_addr,*(uint8_t*)dest);
+
// This read does not reset the state machine
return len;
ERR_WRONG_SIZE("read","vga dac read addr",len,1,1);
- PASSTHROUGH_IO_IN(vga,port,dest,len);
-
*((uint8_t*)dest) = vga->vga_dac.vga_dac_read_addr;
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
+
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_dac_read_addr,*(uint8_t*)dest);
+
// This read does not reset the state machine
return len;
ERR_WRONG_SIZE("read","vga dac read data",len,1,1);
- PASSTHROUGH_IO_IN(vga,port,dest,len);
-
curreg = vga->vga_dac.vga_dac_read_addr;
curchannel = vga->vga_dac.channel;
data = (vga->vga_dac.vga_dac_palette[curreg] >> curchannel*8) & 0x3f;
data);
*((uint8_t*)dest) = data;
+
+ PASSTHROUGH_IO_IN(vga,port,dest,len);
+
+ PASSTHROUGH_READ_CHECK(vga,data,*(uint8_t*)dest);
curchannel = (curchannel+1)%3;
vga->vga_dac.channel=curchannel;
ERR_WRONG_SIZE("read","vga pixel mask",len,1,1);
+ *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
+
PASSTHROUGH_IO_IN(vga,port,dest,len);
- *((uint8_t*)dest) = vga->vga_dac.vga_pixel_mask;
+ PASSTHROUGH_READ_CHECK(vga,vga->vga_dac.vga_pixel_mask,*(uint8_t*)dest);
return len;
}
// No memory store is allocated since we will use a full memory hook
// The VGA maps can be read as well as written
+ // Reads also affect writes, since they are how you fill the latches
// Now allocate the maps
for (i=0;i<MAP_NUM;i++) {
vga->map[i] = (vga_map) V3_VAddr((void*)V3_AllocPages(MAP_SIZE/4096));
if (!(vga->map[i])) {
+ PrintError("vga: cannot allocate maps\n");
free_vga(vga);
+ return -1;
}
memset(vga->map[i],0,MAP_SIZE);
}