/* * 86Box A hypervisor and IBM PC system emulator that specializes in * running old operating systems and software designed for IBM * PC systems and compatibles from 1981 through fairly recent * system designs based on the PCI bus. * * This file is part of the 86Box distribution. * * Implementation of a port 80h POST diagnostic card. * * * * Author: RichardG, * Copyright 2020 RichardG. */ #include #include #include #include #include #define HAVE_STDARG_H #include "86box.h" #include "86box_io.h" #include "device.h" #include "machine.h" #include "plat.h" #include "ui.h" #include "postcard.h" static uint16_t postcard_port; static uint8_t postcard_written; static uint8_t postcard_code, postcard_prev_code; #define UISTR_LEN 13 static char postcard_str[UISTR_LEN]; /* UI output string */ extern void ui_sb_bugui(char *__str); #ifdef ENABLE_POSTCARD_LOG int postcard_do_log = ENABLE_POSTCARD_LOG; static void postcard_log(const char *fmt, ...) { va_list ap; if (postcard_do_log) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); } } #else int postcard_do_log = 0; #define postcard_log(fmt, ...) #endif static void postcard_setui(void) { if (!postcard_written) sprintf(postcard_str, "POST: -- --"); else if (postcard_written == 1) sprintf(postcard_str, "POST: %02X --", postcard_code); else sprintf(postcard_str, "POST: %02X %02X", postcard_code, postcard_prev_code); ui_sb_bugui(postcard_str); if (postcard_do_log) { /* log same string sent to the UI */ int len = strlen(postcard_str); postcard_str[len + 1] = '\0'; postcard_str[len] = '\n'; postcard_log(postcard_str); } } static void postcard_reset(void) { postcard_written = 0; postcard_code = postcard_prev_code = 0x00; postcard_setui(); } static void postcard_write(uint16_t port, uint8_t val, void *priv) { if (postcard_written && val == postcard_code) return; postcard_prev_code = postcard_code; postcard_code = val; if (postcard_written < 2) postcard_written++; postcard_setui(); } static void * postcard_init(const device_t *info) { postcard_reset(); if (machines[machine].flags & MACHINE_MCA) postcard_port = 0x680; /* MCA machines */ else if (strstr(machines[machine].name, " PS/2 ")) postcard_port = 0x90; /* ISA PS/2 machines */ else postcard_port = 0x80; /* AT and clone machines */ postcard_log("POST card initializing on port %04Xh\n", postcard_port); if (postcard_port) io_sethandler(postcard_port, 1, NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); return postcard_write; } static void postcard_close(UNUSED(void *priv)) { if (postcard_port) io_removehandler(postcard_port, 1, NULL, NULL, NULL, postcard_write, NULL, NULL, NULL); } const device_t postcard_device = { "POST Card", DEVICE_ISA, 0, postcard_init, postcard_close, NULL, NULL, NULL, NULL, NULL };