diff --git a/src/CPU/808x.c b/src/CPU/808x.c index 297782386..1f6f67cca 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -1998,7 +1998,7 @@ void execx86(int cycs) case 0xA1: /*MOV AX,(w)*/ addr=getword(); AX=readmemw(ds,addr); - cycles-=!4; + cycles-=14; break; case 0xA2: /*MOV (w),AL*/ addr=getword(); diff --git a/src/disc_86f.c b/src/disc_86f.c index 10f4ff486..5a7614e32 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -3328,5 +3328,4 @@ void d86f_close(int drive) fclose(d86f[drive].f); if (d86f[drive].is_compressed) _wremove(temp_file_name); - d86f[drive].f = NULL; } diff --git a/src/disc_fdi.c b/src/disc_fdi.c index b7aae9819..bf8410e91 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -286,7 +286,6 @@ void fdi_close(int drive) fdi2raw_header_free(fdi[drive].h); if (fdi[drive].f) fclose(fdi[drive].f); - fdi[drive].f = NULL; } void fdi_seek(int drive, int track) diff --git a/src/disc_imd.c b/src/disc_imd.c index e583335e0..fcbed568d 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -289,7 +289,6 @@ void imd_close(int drive) } fclose(imd[drive].f); } - imd[drive].f = NULL; } int imd_track_is_xdf(int drive, int side, int track) diff --git a/src/disc_img.c b/src/disc_img.c index e5020353d..0391820d0 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -850,8 +850,6 @@ void img_close(int drive) fclose(img[drive].f); if (img[drive].disk_data) free(img[drive].disk_data); - img[drive].f = NULL; - img[drive].disk_data = NULL; } #define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] diff --git a/src/disc_td0.c b/src/disc_td0.c index ab3511a32..c63a62dc5 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -584,7 +584,6 @@ void td0_close(int drive) if (td0[drive].f) fclose(td0[drive].f); - td0[drive].f = NULL; } uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm) diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 46ebbbb1e..84e85a673 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -85,13 +85,9 @@ sermouse_init(void) memset(ms, 0x00, sizeof(mouse_serial_t)); /* Attach a serial port to the mouse. */ -#if 1 - ms->serial = serial_attach(0, sermouse_rcr, ms); -#else - ms->serial = &serial1; - serial1.rcr_callback = sermouse_rcr; - serial1.rcr_callback_p = ms; -#endif + ms->serial = &serial1; + serial1.rcr_callback = sermouse_rcr; + serial1.rcr_callback_p = ms; timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); @@ -105,11 +101,7 @@ sermouse_close(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; /* Detach serial port from the mouse. */ -#if 1 - serial_attach(0, NULL, NULL); -#else serial1.rcr_callback = NULL; -#endif free(ms); } diff --git a/src/pc.c b/src/pc.c index b4bf2b942..bf8036f52 100644 --- a/src/pc.c +++ b/src/pc.c @@ -953,15 +953,21 @@ void loadconfig(wchar_t *fn) bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); } +wchar_t temp_nvr_path[1024]; + wchar_t *nvr_concat(wchar_t *to_concat) { - char *p = (char *) nvr_path; + char *p; + + memset(temp_nvr_path, 0, 2048); + wcscpy(temp_nvr_path, nvr_path); + + p = (char *) temp_nvr_path; p += (path_len * 2); wchar_t *wp = (wchar_t *) p; - memset(wp, 0, (1024 - path_len) * 2); wcscpy(wp, to_concat); - return nvr_path; + return temp_nvr_path; } void saveconfig() diff --git a/src/serial.c b/src/serial.c index a80912ddf..4eb78e821 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,639 +1,295 @@ -/* - * 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 NS8250-series UART devices. - * - * The original IBM-PC design did not have any serial ports of - * any kind. Rather, these were offered as add-on devices, most - * likely because a) most people did not need one at the time, - * and, b) this way, IBM could make more money off them. - * - * So, for the PC, the offerings were for an IBM Asynchronous - * Communications Adapter, and, later, a model for synchronous - * communications. - * - * The "Async Adapter" was based on the NS8250 UART chip, and - * is what we now call the "serial" or "com" port of the PC. - * - * Of course, many system builders came up with similar boards, - * and even more boards were designed where several I/O functions - * were combined into a single board: the Multi-I/O adapters. - * Initially, these had all the chips as-is, but later many of - * these functions were integrated into a single MIO chip. - * - * This file implements the standard NS8250 series of chips, with - * support for the later (16450 and 16550) FIFO additions. On the - * lower half of the driver, we interface to the host system's - * serial ports for real-world access. - * - * Based on the 86Box serial port driver as a framework. - * - * Version: @(#)serial.c 1.0.2 2017/05/05 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ #include "ibm.h" #include "io.h" #include "mouse.h" #include "pic.h" #include "serial.h" #include "timer.h" -#include "win-serial.h" - -enum { - SERINT_LSR = 1, - SERINT_RECEIVE = 2, - SERINT_TRANSMIT = 4, - SERINT_MSR = 8 +enum +{ + SERIAL_INT_LSR = 1, + SERIAL_INT_RECEIVE = 2, + SERIAL_INT_TRANSMIT = 4, + SERIAL_INT_MSR = 8 }; +SERIAL serial1, serial2; -/* IER register bits. */ -#define IER_RDAIE (0x01) -#define IER_THREIE (0x02) -#define IER_RXLSIE (0x04) -#define IER_MSIE (0x08) -#define IER_SLEEP (0x10) /* NS16750 */ -#define IER_LOWPOWER (0x20) /* NS16750 */ -#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ - -/* IIR register bits. */ -#define IIR_IP (0x01) -#define IIR_IID (0x0e) -# define IID_IDMDM (0x00) -# define IID_IDTX (0x02) -# define IID_IDRX (0x04) -# define IID_IDERR (0x06) -# define IID_IDTMO (0x0c) -#define IIR_IIRFE (0xc0) -# define IIR_FIFO64 (0x20) -# define IIR_FIFOBAD (0x80) /* 16550 */ -# define IIR_FIFOENB (0xc0) - -/* FCR register bits. */ -#define FCR_FCRFE (0x01) -#define FCR_RFR (0x02) -#define FCR_TFR (0x04) -#define FCR_SELDMA1 (0x08) -#define FCR_FENB64 (0x20) /* 16750 */ -#define FCR_RTLS (0xc0) -# define FCR_RTLS1 (0x00) -# define FCR_RTLS4 (0x40) -# define FCR_RTLS8 (0x80) -# define FCR_RTLS14 (0xc0) - -/* LCR register bits. */ -#define LCR_WLS (0x03) -# define WLS_BITS5 (0x00) -# define WLS_BITS6 (0x01) -# define WLS_BITS7 (0x02) -# define WLS_BITS8 (0x03) -#define LCR_SBS (0x04) -#define LCR_PE (0x08) -#define LCR_EP (0x10) -#define LCR_PS (0x20) -# define PAR_NONE (0x00) -# define PAR_EVEN (LCR_PE | LCR_EP) -# define PAR_ODD (LCR_PE) -# define PAR_MARK (LCR_PE | LCR_PS) -# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) -#define LCR_BC (0x40) -#define LCR_DLAB (0x80) - -/* MCR register bits. */ -#define MCR_DTR (0x01) -#define MCR_RTS (0x02) -#define MCR_OUT1 (0x04) /* 8250 */ -#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ -#define MCR_LMS (0x10) -#define MCR_AUTOFLOW (0x20) /* 16750 - -/* LSR register bits. */ -#define LSR_DR (0x01) -#define LSR_OE (0x02) -#define LSR_PE (0x04) -#define LSR_FE (0x08) -#define LSR_BI (0x10) -#define LSR_THRE (0x20) -#define LSR_TEMT (0x40) -#define LSR_RXFE (0x80) - -/* MSR register bits. */ -#define MSR_DCTS (0x01) -#define MSR_DDSR (0x02) -#define MSR_TERI (0x04) -#define MSR_DDCD (0x08) -#define MSR_CTS (0x10) -#define MSR_DSR (0x20) -#define MSR_RI (0x40) -#define MSR_DCD (0x80) -#define MSR_MASK (0x0f) - - -static uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; -static int serial_irq[2] = { 4, 3 }; -static SERIAL serial1, serial2; - - -static void -update_ints(SERIAL *sp) +void serial_reset() { - int stat = 0; + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; + serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; + serial1.fifo_read = serial1.fifo_write = 0; + serial2.fifo_read = serial2.fifo_write = 0; +} + +void serial_update_ints(SERIAL *serial) +{ + int stat = 0; - sp->iir = IIR_IP; - if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { - /* Line Status interrupt. */ - stat = 1; - sp->iir = IID_IDERR; - } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { - /* Received Data available. */ - stat = 1; - sp->iir = IID_IDRX; - } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { - /* Transmit Data empty. */ - stat = 1; - sp->iir = IID_IDTX; - } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { - /* Modem Status interrupt. */ - stat = 1; - sp->iir = IID_IDMDM; - } + serial->iir = 1; - /* Raise or clear the level-based IRQ. */ - if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) - picintlevel(1 << sp->irq); - else - picintc(1 << sp->irq); + if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/ + { + stat = 1; + serial->iir = 6; + } + else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ + { + stat = 1; + serial->iir = 4; + } + else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/ + { + stat = 1; + serial->iir = 2; + } + else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/ + { + stat = 1; + serial->iir = 0; + } + + if (stat && ((serial->mctrl & 8) || PCJR)) + picintlevel(1 << serial->irq); + else + picintc(1 << serial->irq); } - -/* Write data to the (input) FIFO. Used by MOUSE driver. */ -void -serial_write_fifo(SERIAL *sp, uint8_t dat) +void serial_write_fifo(SERIAL *serial, uint8_t dat) { - /* Stuff data into FIFO. */ - sp->fifo[sp->fifo_write] = dat; - sp->fifo_write = (sp->fifo_write + 1) & 0xFF; - - if (! (sp->lsr & LSR_DR)) { - sp->lsr |= LSR_DR; - sp->int_status |= SERINT_RECEIVE; - update_ints(sp); - } + serial->fifo[serial->fifo_write] = dat; + serial->fifo_write = (serial->fifo_write + 1) & 0xFF; + if (!(serial->lsr & 1)) + { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } } - -static uint8_t -read_fifo(SERIAL *sp) +uint8_t serial_read_fifo(SERIAL *serial) { - if (sp->fifo_read != sp->fifo_write) { - sp->dat = sp->fifo[sp->fifo_read]; - sp->fifo_read = (sp->fifo_read + 1) & 0xFF; - } - - return(sp->dat); + if (serial->fifo_read != serial->fifo_write) + { + serial->dat = serial->fifo[serial->fifo_read]; + serial->fifo_read = (serial->fifo_read + 1) & 0xFF; + } + return serial->dat; } - -/* BHTTY WRITE COMPLETE handler. */ -static void -serial_wr_done(void *arg) +void serial_write(uint16_t addr, uint8_t val, void *p) { - SERIAL *sp = (SERIAL *)arg; - - /* The WRITE completed, we are ready for more. */ - sp->lsr |= LSR_THRE; - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); + SERIAL *serial = (SERIAL *)p; + switch (addr&7) + { + case 0: + if (serial->lcr & 0x80) + { + serial->dlab1 = val; + return; + } + serial->thr = val; + serial->lsr |= 0x20; + serial->int_status |= SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + if (serial->mctrl & 0x10) + { + serial_write_fifo(serial, val); + } + break; + case 1: + if (serial->lcr & 0x80) + { + serial->dlab2 = val; + return; + } + serial->ier = val & 0xf; + serial_update_ints(serial); + break; + case 2: + serial->fcr = val; + break; + case 3: + serial->lcr = val; + break; + case 4: + if ((val & 2) && !(serial->mctrl & 2)) + { + if (serial->rcr_callback) + serial->rcr_callback(serial, serial->rcr_callback_p); + } + serial->mctrl = val; + if (val & 0x10) + { + uint8_t new_msr; + + new_msr = (val & 0x0c) << 4; + new_msr |= (val & 0x02) ? 0x10: 0; + new_msr |= (val & 0x01) ? 0x20: 0; + + if ((serial->msr ^ new_msr) & 0x10) + new_msr |= 0x01; + if ((serial->msr ^ new_msr) & 0x20) + new_msr |= 0x02; + if ((serial->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((serial->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + serial->msr = new_msr; + } + break; + case 5: + serial->lsr = val; + if (serial->lsr & 0x01) + serial->int_status |= SERIAL_INT_RECEIVE; + if (serial->lsr & 0x1e) + serial->int_status |= SERIAL_INT_LSR; + if (serial->lsr & 0x20) + serial->int_status |= SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + break; + case 6: + serial->msr = val; + if (serial->msr & 0x0f) + serial->int_status |= SERIAL_INT_MSR; + serial_update_ints(serial); + break; + case 7: + serial->scratch = val; + break; + } } - -/* Handle a WRITE operation to one of our registers. */ -static void -serial_write(uint16_t addr, uint8_t val, void *priv) +uint8_t serial_read(uint16_t addr, void *p) { - SERIAL *sp = (SERIAL *)priv; - uint8_t wl, sb, pa; - uint16_t baud; - long speed; + SERIAL *serial = (SERIAL *)p; + uint8_t temp = 0; + switch (addr&7) + { + case 0: + if (serial->lcr & 0x80) + { + temp = serial->dlab1; + break; + } - switch (addr & 0x07) { - case 0: /* DATA / DLAB1 */ - if (sp->lcr & LCR_DLAB) { - sp->dlab1 = val; - return; - } - sp->thr = val; -#if 0 - bhtty_write((BHTTY *)sp->bh, sp->thr, serial_wrdone, sp); -#else - bhtty_write((BHTTY *)sp->bh, sp->thr); - serial_wr_done(sp); -#endif - if (sp->mctrl & MCR_LMS) { - /* Echo data back to RX. */ - serial_write_fifo(sp, val); - } - break; - - case 1: /* IER / DLAB2 */ - if (sp->lcr & LCR_DLAB) { - sp->dlab2 = val; - return; - } - sp->ier = (val & IER_MASK); - update_ints(sp); - break; - - case 2: /* FCR */ - sp->fcr = val; - break; - - case 3: /* LCR */ - if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { - /* We dropped DLAB, so handle baudrate. */ - baud = ((sp->dlab2 << 8) | sp->dlab1); - speed = 115200UL/baud; -#if 1 - pclog("Serial: new divisor %u, baudrate %ld\n", - baud, speed); -#endif - bhtty_speed((BHTTY *)sp->bh, speed); - } - wl = (val & LCR_WLS) + 5; /* databits */ - sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ - pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; -#if 1 - pclog("Serial: WL=%d SB=%d PA=%d\n", wl, sb, pa); -#endif - bhtty_params((BHTTY *)sp->bh, wl, pa, sb); - sp->lcr = val; - break; - - case 4: - if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { - /* - * This is old code for use by the Serial Mouse - * driver. If the user toggles RTS, any serial - * mouse is expected to send an 'M' character, - * to inform any enumerator there 'is' something. - */ - if (sp->rcr_callback) { - sp->rcr_callback(sp, sp->rcr_callback_p); -#if 0 - pclog("RTS raised; sending M\n"); -#endif - } - } - - if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { - /* Start up reading from the real port. */ - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); - } - sp->mctrl = val; - if (val & MCR_LMS) { /* loopback mode */ - uint8_t new_msr; - - /*FIXME: WTF does this do?? --FvK */ - new_msr = (val & 0x0c) << 4; - new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; - new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; - - if ((sp->msr ^ new_msr) & 0x10) - new_msr |= MCR_DTR; - if ((sp->msr ^ new_msr) & 0x20) - new_msr |= MCR_RTS; - if ((sp->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((sp->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; - - sp->msr = new_msr; - } - break; - - case 5: - sp->lsr = val; - if (sp->lsr & LSR_DR) - sp->int_status |= SERINT_RECEIVE; - if (sp->lsr & 0x1e) - sp->int_status |= SERINT_LSR; - if (sp->lsr & LSR_THRE) - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); - break; - - case 6: - sp->msr = val; - if (sp->msr & MSR_MASK) - sp->int_status |= SERINT_MSR; - update_ints(sp); - break; - - case 7: - sp->scratch = val; - break; - } + serial->lsr &= ~1; + serial->int_status &= ~SERIAL_INT_RECEIVE; + serial_update_ints(serial); + temp = serial_read_fifo(serial); + if (serial->fifo_read != serial->fifo_write) + serial->recieve_delay = 1000 * TIMER_USEC; + break; + case 1: + if (serial->lcr & 0x80) + temp = serial->dlab2; + else + temp = serial->ier; + break; + case 2: + temp = serial->iir; + if ((temp & 0xe) == 2) + { + serial->int_status &= ~SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + } + if (serial->fcr & 1) + temp |= 0xc0; + break; + case 3: + temp = serial->lcr; + break; + case 4: + temp = serial->mctrl; + break; + case 5: + if (serial->lsr & 0x20) + serial->lsr |= 0x40; + serial->lsr |= 0x20; + temp = serial->lsr; + if (serial->lsr & 0x1f) + serial->lsr &= ~0x1e; + serial->int_status &= ~SERIAL_INT_LSR; + serial_update_ints(serial); + break; + case 6: + temp = serial->msr; + serial->msr &= ~0x0f; + serial->int_status &= ~SERIAL_INT_MSR; + serial_update_ints(serial); + break; + case 7: + temp = serial->scratch; + break; + } + return temp; } - -/* BHTTY READ COMPLETE handler. */ -static void -serial_rd_done(void *arg, int num) +void serial_recieve_callback(void *p) { - SERIAL *sp = (SERIAL *)arg; -//pclog("%04x: %d bytes available: %02x (%c)\n",sp->port,num,sp->hold,sp->hold); - - /* Stuff the byte in the FIFO and set intr. */ - serial_write_fifo(sp, sp->hold); - - /* Start up the next read from the real port. */ - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -serial_read(uint16_t addr, void *priv) -{ - SERIAL *sp = (SERIAL *)priv; - uint8_t ret = 0x00; - - switch (addr&0x07) { - case 0: /* DATA / DLAB1 */ - if (sp->lcr & LCR_DLAB) { - ret = sp->dlab1; - break; - } - sp->lsr &= ~LSR_DR; - sp->int_status &= ~SERINT_RECEIVE; - update_ints(sp); - ret = read_fifo(sp); -#if 0 - if (sp->fifo_read != sp->fifo_write) - sp->receive_delay = 1000 * TIMER_USEC; -#endif - break; - - case 1: /* LCR / DLAB2 */ - if (sp->lcr & LCR_DLAB) - ret = sp->dlab2; - else - ret = sp->ier; - break; - - case 2: /* IIR */ - ret = sp->iir; - if ((ret & IIR_IID) == IID_IDTX) { - sp->int_status &= ~SERINT_TRANSMIT; - update_ints(sp); - } - if (sp->fcr & 1) - { - ret |= 0xc0; - } - break; - - case 3: /* LCR */ - ret = sp->lcr; - break; - - case 4: /* MCR */ - ret = sp->mctrl; - break; - - case 5: /* LSR */ - if (sp->lsr & LSR_THRE) - sp->lsr |= LSR_TEMT; - sp->lsr |= LSR_THRE; - ret = sp->lsr; - if (sp->lsr & 0x1f) - sp->lsr &= ~0x1e; -#if 0 - sp->lsr |= (LSR_THRE | LSR_TEMT); -#endif - sp->int_status &= ~SERINT_LSR; - update_ints(sp); - break; - - case 6: - ret = sp->msr; - sp->msr &= ~0x0f; - sp->int_status &= ~SERINT_MSR; - update_ints(sp); - break; - - case 7: - ret = sp->scratch; - break; - } - - return(ret); + SERIAL *serial = (SERIAL *)p; + + serial->recieve_delay = 0; + + if (serial->fifo_read != serial->fifo_write) + { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } } +uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; +int serial_irq[2] = { 4, 3 }; /*Tandy might need COM1 at 2f8*/ -void -serial1_init(uint16_t addr, int irq) +void serial1_init(uint16_t addr, int irq) { - BHTTY *bh; - - memset(&serial1, 0x00, sizeof(serial1)); - - pclog("Serial1, I/O=%04x, IRQ=%d, host ", addr, irq); - - /* Request a port from the host system. */ - bh = bhtty_open(BHTTY_PORT1, 0); /*FIXME: from config! --FvK */ - if (bh == NULL) { - return; - } - serial1.bh = bh; - serial1.port = addr; - serial1.irq = irq; - serial1.rcr_callback = NULL; - pclog("'%s'\n", bh->name); - - /* Set up bottom-half I/O callback info. */ - bh->rd_done = serial_rd_done; - bh->rd_arg = &serial1; - - /* Request an I/O range. */ - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - -#if 0 - timer_add(serial_receive_callback, - &serial1.receive_delay, &serial1.receive_delay, &serial1); -#endif - - serial_addr[0] = addr; - serial_irq[0] = irq; + memset(&serial1, 0, sizeof(serial1)); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1.irq = irq; + serial1.rcr_callback = NULL; + timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); + serial_addr[0] = addr; + serial_irq[0] = irq; +} +void serial1_set(uint16_t addr, int irq) +{ + serial1_remove(); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1.irq = irq; + serial_addr[0] = addr; + serial_irq[0] = irq; +} +void serial1_remove() +{ + io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } - -/* Release all resources held by the device. */ -void -serial1_remove(void) +void serial2_init(uint16_t addr, int irq) { - /* Close the host device. */ - if (serial1.bh != NULL) - bhtty_close((BHTTY *)serial1.bh); - - /* Release our I/O range. */ - io_removehandler(serial_addr[0], 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + memset(&serial2, 0, sizeof(serial2)); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2.irq = irq; + serial2.rcr_callback = NULL; + timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); + serial_addr[1] = addr; + serial_irq[1] = irq; } - - -void -serial1_set(uint16_t addr, int irq) +void serial2_set(uint16_t addr, int irq) { - void *temp; - -#if 0 - pclog("serial1_set(%04X, %02X)\n", addr, irq); -#endif - temp = serial1.bh; - serial1.bh = NULL; - serial1_remove(); - serial1.bh = temp; - serial1.port = addr; - serial1.irq = irq; - - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial_addr[0] = addr; - serial_irq[0] = irq; + serial2_remove(); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2.irq = irq; + serial_addr[1] = addr; + serial_irq[1] = irq; } - - -void -serial2_init(uint16_t addr, int irq) +void serial2_remove() { - BHTTY *bh; - - memset(&serial2, 0x00, sizeof(serial2)); - - pclog("Serial2, I/O=%04x, IRQ=%d, host ", addr, irq); - - /* Request a port from the host system. */ - bh = bhtty_open(BHTTY_PORT2, 0); /*FIXME: from config! --FvK */ - if (bh == NULL) { - return; - } - serial2.bh = bh; - serial2.port = addr; - serial2.irq = irq; - serial2.rcr_callback = NULL; - pclog("'%s'\n", bh->name); - - /* Set up bottom-half I/O callback info. */ - bh->rd_done = serial_rd_done; - bh->rd_arg = &serial2; - - /* Request an I/O range. */ - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - - serial_addr[1] = addr; - serial_irq[1] = irq; -} - - -/* Release all resources held by the device. */ -void -serial2_remove(void) -{ - /* Close the host device. */ - if (serial2.bh != NULL) - bhtty_close((BHTTY *)serial2.bh); - - /* Release our I/O range. */ - io_removehandler(serial_addr[1], 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); -} - - -void -serial2_set(uint16_t addr, int irq) -{ - void *temp; - -#if 0 - pclog("serial2_set(%04X, %02X)\n", addr, irq); -#endif - temp = serial2.bh; - serial2.bh = NULL; - serial2_remove(); - serial2.bh = temp; - serial2.port = addr; - serial2.irq = irq; - - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - - serial_addr[1] = addr; - serial_irq[1] = irq; -} - - -/* - * Reset the serial ports. - * - * This should be a per-port function. - */ -void -serial_reset(void) -{ - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; - - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial2.fifo_read = serial2.fifo_write = 0; -} - - -/* Fake interrupt generator, needed for Serial Mouse. */ -static void -serial_timer(void *priv) -{ - SERIAL *sp = (SERIAL *)priv; - - sp->receive_delay = 0; - - if (sp->fifo_read != sp->fifo_write) { - sp->lsr |= LSR_DR; - sp->int_status |= SERINT_RECEIVE; - update_ints(sp); - } -} - - -/* Attach another device (MOUSE) to a serial port. */ -SERIAL * -serial_attach(int port, void *func, void *arg) -{ - SERIAL *sp; - - if (port == 0) - sp = &serial1; - else - sp = &serial2; - - /* Set up callback info. */ - sp->rcr_callback = func; - sp->rcr_callback_p = arg; - - /* Create a timer to fake RX interrupts for mouse data. */ - timer_add(serial_timer, - &sp->receive_delay, &sp->receive_delay, sp); - - return(sp); + io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); } diff --git a/src/serial.h b/src/serial.h index 05a5c7ff5..96104068e 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,56 +1,35 @@ -/* - * 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. - * - * Definitions for the SERIAL card. - * - * Version: @(#)serial.h 1.0.1 2017/04/14 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef SERIAL_H -# define SERIAL_H +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +void serial1_init(uint16_t addr, int irq); +void serial2_init(uint16_t addr, int irq); +void serial1_set(uint16_t addr, int irq); +void serial2_set(uint16_t addr, int irq); +void serial1_remove(); +void serial2_remove(); +void serial_reset(); +struct SERIAL; -typedef struct _serial_ { - uint16_t port; - int16_t irq; +typedef struct +{ + uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; + uint8_t dlab1,dlab2; + uint8_t dat; + uint8_t int_status; + uint8_t scratch; + uint8_t fcr; + + int irq; - uint8_t lsr, thr, mctrl, rcr, iir, ier, lcr, msr; - uint8_t dlab1, dlab2; - uint8_t dat; - uint8_t int_status; - uint8_t scratch; - uint8_t fcr; - - void (*rcr_callback)(struct _serial_ *, void *); - void *rcr_callback_p; - - uint8_t hold; - uint8_t fifo[256]; - int fifo_read, fifo_write; - - int receive_delay; - - void *bh; + void (*rcr_callback)(struct SERIAL *serial, void *p); + void *rcr_callback_p; + uint8_t fifo[256]; + int fifo_read, fifo_write; + + int recieve_delay; } SERIAL; +extern SERIAL serial1, serial2; -extern void serial1_init(uint16_t addr, int irq); -extern void serial2_init(uint16_t addr, int irq); -extern void serial1_set(uint16_t addr, int irq); -extern void serial2_set(uint16_t addr, int irq); -extern void serial1_remove(); -extern void serial2_remove(); - -extern void serial_reset(); -extern SERIAL *serial_attach(int, void *, void *); -extern void serial_write_fifo(SERIAL *, uint8_t); - - -#endif /*SERIAL_H*/ +void serial_write_fifo(SERIAL *serial, uint8_t dat); diff --git a/src/win.c b/src/win.c index ee792c5d8..9b85ac8ca 100644 --- a/src/win.c +++ b/src/win.c @@ -2156,7 +2156,6 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { disc_close(0); ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - msgbox_info_wstr(ghwnd, wopenfilestring); disc_load(0, wopenfilestring); update_status_bar_icon_state(0x00, 0); update_tip(0x00);