/* next write to attrc selects the index rather than data */
video_state->attrc_index_flipflop = 0;
+ memset(dest, 0x0, length);
- return notimpl_port_read(priv_data, __FUNCTION__, port, dest, length);
+ handle_port_read(priv_data, __FUNCTION__, port, dest, length, 1);
+ return length;
}
static int feat_ctrl_read(struct guest_info * core, uint16_t port, void * dest, uint_t length, void * priv_data) {
}
}
-static int free_cga(struct video_internal * video_state) {
+static int cga_free(struct video_internal * video_state) {
if (video_state->framebuf_pa) {
PrintError("Freeing framebuffer PA %p\n", (void *)(video_state->framebuf_pa));
}
+#ifdef V3_CONFIG_CHECKPOINT
+static int cga_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+ struct video_internal * cga = (struct video_internal *)private_data;
+
+ if (v3_chkpt_save(ctx, "FRAMEBUFFER", FRAMEBUF_SIZE, cga->framebuf)) {
+ goto savefailout;
+ }
+
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->misc_outp_reg, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->seq_index_reg, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->seq_data_regs, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->crtc_index_reg, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->crtc_data_regs, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->graphc_index_reg, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->graphc_data_regs, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->attrc_index_flipflop, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->attrc_index_reg, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->attrc_data_regs, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->dac_indexr_reg, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->dac_indexr_color, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->dac_indexw_reg, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->dac_indexw_color, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->dac_data_regs, savefailout);
+
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->activefb_addr, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->activefb_len, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->iorange, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->vres, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->hres, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->vchars, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->hchars, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->graphmode, savefailout);
+
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->dirty, savefailout);
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->reschanged, savefailout);
+
+ V3_CHKPT_SAVE_AUTOTAG(ctx, cga->passthrough, savefailout);
+
+ V3_CHKPT_SAVE(ctx, "SCREEN_OFFSET", cga->screen_offset, savefailout);
+ V3_CHKPT_SAVE(ctx, "CURSOR_OFFSET", cga->cursor_offset, savefailout);
+
+ return 0;
+
+ savefailout:
+ PrintError("Failed to save CGA\n");
+ return -1;
+
+}
+
+static int cga_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+ struct video_internal * cga = (struct video_internal *)private_data;
+
+ if (v3_chkpt_load(ctx, "FRAMEBUFFER", FRAMEBUF_SIZE, cga->framebuf)) {
+ goto loadfailout;
+ }
+
+
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->misc_outp_reg, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->seq_index_reg, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->seq_data_regs, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->crtc_index_reg, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->crtc_data_regs, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->graphc_index_reg, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->graphc_data_regs, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->attrc_index_flipflop, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->attrc_index_reg, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->attrc_data_regs, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->dac_indexr_reg, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->dac_indexr_color, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->dac_indexw_reg, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->dac_indexw_color, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->dac_data_regs, loadfailout);
+
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->activefb_addr, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->activefb_len, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->iorange, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->vres, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->hres, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->vchars, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->hchars, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->graphmode, loadfailout);
+
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->dirty, loadfailout);
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->reschanged, loadfailout);
+
+ V3_CHKPT_LOAD_AUTOTAG(ctx, cga->passthrough, loadfailout);
+
+ V3_CHKPT_LOAD(ctx, "SCREEN_OFFSET", cga->screen_offset, loadfailout);
+ V3_CHKPT_LOAD(ctx, "CURSOR_OFFSET", cga->cursor_offset, loadfailout);
+
+
+ return 0;
+
+ loadfailout:
+ PrintError("Failed to load cga\n");
+ return -1;
+
+}
+
+#endif
+
+
static struct v3_device_ops dev_ops = {
- .free = (int (*)(void *))free_cga,
+ .free = (int (*)(void *))cga_free,
+#ifdef V3_CONFIG_CHECKPOINT
+ .save = cga_save,
+ .load = cga_load
+#endif
+
};
static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
PrintDebug("video: init_device\n");
video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
+
+ if (!video_state) {
+ PrintError("Cannot allocate space for CGA state\n");
+ return -1;
+ }
+
memset(video_state, 0, sizeof(struct video_internal));
struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, video_state);
video_state->dev = dev;
video_state->framebuf_pa = (addr_t)V3_AllocPages(FRAMEBUF_SIZE / 4096);
+
+ if (!video_state->framebuf_pa) {
+ PrintError("Cannot allocate frame buffer\n");
+ V3_Free(video_state);
+ return -1;
+ }
+
video_state->framebuf = V3_VAddr((void *)(video_state->framebuf_pa));
+
memset(video_state->framebuf, 0, FRAMEBUF_SIZE);
PrintDebug("PA of array: %p\n", (void *)(video_state->framebuf_pa));