// so we need a temp variable to hold the partial update
uint16_t tmp_screen_offset;
+ struct vm_device * dev;
+
uint8_t passthrough;
port, port);
return -1;
}
-
-
+
video_state->crtc_index_reg = *(uint8_t *)src;
// Only do the passthrough IO for the first byte
V3_ASSERT(offset < SCREEN_SIZE);
V3_ASSERT(length <= SCREEN_SIZE);
V3_ASSERT(offset + length <= SCREEN_SIZE);
+
memcpy(dst, state->framebuf + screen_byte_offset + offset, length);
return 0;
-static int free_device(struct vm_device * dev) {
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+static int free_cga(struct video_internal * video_state) {
if (video_state->framebuf_pa) {
+ PrintError("Freeing framebuffer PA %p\n", (void *)(video_state->framebuf_pa));
V3_FreePages((void *)(video_state->framebuf_pa), (FRAMEBUF_SIZE / 4096));
}
- v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR);
-
+ v3_unhook_mem(video_state->dev->vm, V3_MEM_CORE_ANY, START_ADDR);
V3_Free(video_state);
static struct v3_device_ops dev_ops = {
- .free = free_device,
+ .free = (int (*)(void *))free_cga,
};
static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
V3_Free(video_state);
return -1;
}
+
+ video_state->dev = dev;
video_state->framebuf_pa = (addr_t)V3_AllocPages(FRAMEBUF_SIZE / 4096);
video_state->framebuf = V3_VAddr((void *)(video_state->framebuf_pa));