/* ** A20 gate enable: AX = 2401h ** CF clear if successful ** AH = 00h ** CF set on error ** AH = status ** 01h keyboard controller is in secure mode ** 86h function not supported */ static int emulate_int15_a20_enable() { info->vm.cpu.gpr->rax.bhigh = 0; __rflags.cf = 0; __post_access(__rflags); dev_a20_set(1); return VM_DONE; }
/* ** A20 gate disable: AX = 2400h ** CF clear if successful ** AH = 00h ** CF set on error ** AH = status ** 01h keyboard controller is in secure mode ** 86h function not supported */ static int emulate_int15_a20_disable() { info->vm.cpu.gpr->rax.bhigh = 0; __rflags.cf = 0; __post_access(__rflags); dev_a20_set(0); return EMU_SUCCESS; }
int __dev_kbd_data(kbd_t *kbd, io_insn_t *io) { raw64_t *rax = &info->vm.cpu.gpr->rax; if(io->in) { rax->blow = in(io->port); /* Return the value the VM expects to see for the a20 bit */ if(kbd->last_cmd == KBD_CMD_READ_O_PORT) { rax->blow &= ~KBD_OUTPUT_PORT_A20; rax->blow |= (kbd->output_port.a20 ? KBD_OUTPUT_PORT_A20 : 0); } } else { if(kbd->last_cmd == KBD_CMD_WRITE_O_PORT) { kbd->output_port.raw = rax->blow; /* if(kbd->output_port.sys_rst) */ /* panic("keyboard controller system reset"); */ dev_a20_set(kbd->output_port.a20); /* Don't let the VM _actually_ disable the a20 line */ if(!kbd->output_port.a20) rax->blow |= KBD_OUTPUT_PORT_A20; } out(rax->blow, io->port); } return VM_DONE; }