From dcf354688d9419092a6f1bdd0280232a74691a8d Mon Sep 17 00:00:00 2001 From: SarahW Date: Thu, 12 Mar 2020 18:12:47 +0000 Subject: [PATCH] Support serial UART without FIFO. Patch from EluanCM. --- src/model.c | 8 ++++---- src/ps1.c | 4 ++-- src/ps2.c | 2 +- src/ps2_mca.c | 16 ++++++++-------- src/serial.c | 9 ++++++--- src/serial.h | 5 +++-- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/model.c b/src/model.c index 2778be7..419c6e7 100644 --- a/src/model.c +++ b/src/model.c @@ -312,8 +312,8 @@ void common_init() lpt_init(); pic_init(); pit_init(); - serial1_init(0x3f8, 4); - serial2_init(0x2f8, 3); + serial1_init(0x3f8, 4, 1); + serial2_init(0x2f8, 3, 1); } void xt_init() @@ -343,7 +343,7 @@ void pcjr_init() pic_init(); pit_init(); pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); keyboard_pcjr_init(); device_add(&sn76489_device); nmi_mask = 0x80; @@ -427,7 +427,7 @@ void xt_zenith_init() /* [8088] Zenith Data Systems SupersPort */ lpt2_remove(); /* only one parallel port */ pic_init(); pit_init(); - serial1_init(0x3f8, 4); /* only one serial port */ + serial1_init(0x3f8, 4, 1); /* only one serial port */ mem_add_bios(); device_add(&zenith_scratchpad_device); pit_set_out_func(&pit, 1, pit_refresh_timer_xt); diff --git a/src/ps1.c b/src/ps1.c index f248647..e1f6fce 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -73,7 +73,7 @@ void ps1_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else serial1_remove(); if (val & 0x10) @@ -238,7 +238,7 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else serial1_remove(); if (val & 0x10) diff --git a/src/ps2.c b/src/ps2.c index 6334666..fe0d6a9 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -68,7 +68,7 @@ void ps2_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else serial1_remove(); if (val & 0x10) diff --git a/src/ps2_mca.c b/src/ps2_mca.c index f510e46..dd4e024 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -315,9 +315,9 @@ static void model_50_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); @@ -371,9 +371,9 @@ static void model_55sx_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); @@ -445,9 +445,9 @@ static void model_70_type3_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); @@ -494,9 +494,9 @@ static void model_80_write(uint16_t port, uint8_t val) if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial1_init(0x3f8, 4, 1); else - serial1_init(0x2f8, 3); + serial1_init(0x2f8, 3, 1); } else serial1_remove(); diff --git a/src/serial.c b/src/serial.c index 2866f7c..b563b0d 100644 --- a/src/serial.c +++ b/src/serial.c @@ -111,7 +111,8 @@ void serial_write(uint16_t addr, uint8_t val, void *p) serial_update_ints(serial); break; case 2: - serial->fcr = val; + if (serial->has_fifo) + serial->fcr = val; break; case 3: serial->lcr = val; @@ -247,7 +248,7 @@ void serial_receive_callback(void *p) } /*Tandy might need COM1 at 2f8*/ -void serial1_init(uint16_t addr, int irq) +void serial1_init(uint16_t addr, int irq, int has_fifo) { memset(&serial1, 0, sizeof(serial1)); io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); @@ -255,6 +256,7 @@ void serial1_init(uint16_t addr, int irq) serial1.addr = addr; serial1.rcr_callback = NULL; timer_add(&serial1.receive_timer, serial_receive_callback, &serial1, 0); + serial1.has_fifo = has_fifo; } void serial1_set(uint16_t addr, int irq) { @@ -268,7 +270,7 @@ void serial1_remove() io_removehandler(serial1.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } -void serial2_init(uint16_t addr, int irq) +void serial2_init(uint16_t addr, int irq, int has_fifo) { memset(&serial2, 0, sizeof(serial2)); io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); @@ -276,6 +278,7 @@ void serial2_init(uint16_t addr, int irq) serial2.addr = addr; serial2.rcr_callback = NULL; timer_add(&serial2.receive_timer, serial_receive_callback, &serial2, 0); + serial2.has_fifo = has_fifo; } void serial2_set(uint16_t addr, int irq) { diff --git a/src/serial.h b/src/serial.h index 453acbf..841aaaa 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,7 +1,7 @@ #include "timer.h" -void serial1_init(uint16_t addr, int irq); -void serial2_init(uint16_t addr, int irq); +void serial1_init(uint16_t addr, int irq, int has_fifo); +void serial2_init(uint16_t addr, int irq, int has_fifo); void serial1_set(uint16_t addr, int irq); void serial2_set(uint16_t addr, int irq); void serial1_remove(); @@ -26,6 +26,7 @@ typedef struct void *rcr_callback_p; uint8_t fifo[256]; int fifo_read, fifo_write; + int has_fifo; pc_timer_t receive_timer; } SERIAL;