]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Flush serial transmit buffer, intreq clear clears overrun bit.
authorToni Wilen <twilen@winuae.net>
Sun, 20 Dec 2015 11:03:38 +0000 (13:03 +0200)
committerToni Wilen <twilen@winuae.net>
Sun, 20 Dec 2015 11:03:38 +0000 (13:03 +0200)
custom.cpp
include/serial.h
od-win32/parser.cpp
od-win32/parser.h
od-win32/serial_win32.cpp

index 00266f80b813d63de651e210cda3d6888ec58741..878d86420399fc26bcc41749af35e383dc0ca870 100644 (file)
@@ -5057,8 +5057,11 @@ void INTREQ_f (uae_u16 v)
                setclr (&intreq, v);
                send_intreq_do (v);
        } else {
+               uae_u16 old = intreq;
                setclr (&intreq, v);
                setclr (&intreq_internal, v);
+               if ((old & 0x0800) && !(intreq & 0x0800))
+                       serial_rbf_clear();
        }
 }
 
@@ -5071,6 +5074,9 @@ bool INTREQ_0 (uae_u16 v)
        uae_u16 old = intreq;
        setclr (&intreq, v);
 
+       if ((old & 0x0800) && !(intreq & 0x0800))
+               serial_rbf_clear();
+
        if (int_recursive) {
                // don't add new event if this call came from send_intreq_do/rethink
                // and intreq didn't change.
index 89e1412fc684681e53269b4d6a208cb5b4eb3f17..d603969d11ca52220a7071d468baedf764117019 100644 (file)
@@ -25,6 +25,7 @@ extern void  SERDAT (uae_u16 w);
 extern uae_u8 serial_writestatus (uae_u8, uae_u8);
 extern uae_u8 serial_readstatus (uae_u8);
 extern void serial_uartbreak (int);
+extern void serial_rbf_clear (void);
 extern uae_u16 serdat;
 
 extern int doreadser, serstat;
index f2824b86b912e12db783329dfc471b4c90fafa57..1aeccaad1c998b1360bb43a6af67ffed11244001 100644 (file)
@@ -1091,17 +1091,27 @@ void closeser (void)
 
 static void outser (void)
 {
-       DWORD actual;
-       if (datainoutput > 0 && WaitForSingleObject (writeevent, 0) == WAIT_OBJECT_0 ) {
+       if (datainoutput <= 0)
+               return;
+       DWORD v = WaitForSingleObject (writeevent, 0);
+       if (v == WAIT_OBJECT_0) {
+               DWORD actual;
                memcpy (outputbufferout, outputbuffer, datainoutput);
                WriteFile (hCom, outputbufferout, datainoutput, &actual, &writeol);
                datainoutput = 0;
        }
 }
 
+void writeser_flush(void)
+{
+       outser();
+}
+
 void writeser (int c)
 {
-       //write_log(_T("writeser %d (buf=%d)\n"), c, datainoutput);
+#if 0
+       write_log(_T("writeser %04X (buf=%d)\n"), c, datainoutput);
+#endif
        if (tcpserial) {
                if (tcp_is_connected ()) {
                        char buf[1];
index 838a38ad0ed43d452c86215ab12168c33761ea6b..c9256d7cd0d634af66980fe1b13199b75aaa145c 100644 (file)
@@ -14,7 +14,8 @@ void getserstat(int *status);
 void setserstat (int mask, int onoff);
 int readser (int *buffer);
 int readseravail (void);
-void writeser (int c);
+void writeser(int c);
+void writeser_flush(void);
 int openser (const TCHAR *sername);
 void closeser (void);
 void doserout (void);
index f0b20df4e8d147269d5dfef59f248a95b182bc61..d4165e69e60c0b1cd706df10b4978b566469238c 100644 (file)
@@ -27,7 +27,7 @@
 #include "parser.h"
 
 #define SERIALLOGGING 0
-#define SERIALDEBUG 1 /* 0, 1, 2 3 */
+#define SERIALDEBUG 0 /* 0, 1, 2 3 */
 #define SERIALHSDEBUG 0
 #define SERIAL_HSYNC_BEFORE_OVERFLOW 200
 
@@ -246,7 +246,7 @@ void SERPER (uae_u16 w)
 #endif
 }
 
-static TCHAR dochar (int v)
+static TCHAR docharlog(int v)
 {
        v &= 0xff;
        if (v >= 32 && v < 127)
@@ -256,6 +256,14 @@ static TCHAR dochar (int v)
        return '.';
 }
 
+static TCHAR dochar(int v)
+{
+       v &= 0xff;
+       if (v >= 32 && v < 127)
+               return v;
+       return '.';
+}
+
 static void flushser(void)
 {
        while (readseravail() > 0) {
@@ -374,7 +382,7 @@ static void serdatcopy(void);
 
 static void checksend(void)
 {
-       if (data_in_sershift != 1)
+       if (data_in_sershift != 1 && data_in_sershift != 2)
                return;
 
 #ifdef SERIAL_MAP
@@ -388,29 +396,35 @@ static void checksend(void)
 #endif
 #ifdef SERIAL_PORT
        if (ninebit) {
-               if (!checkserwrite(2))
+               if (!checkserwrite(2)) {
+                       data_in_sershift = 2;
                        return;
+               }
                writeser(((serdatshift >> 8) & 1) | 0xa8);
                writeser(serdatshift_masked);
        } else {
                if (currprefs.serial_crlf) {
                        if (serdatshift_masked == 10 && serial_send_previous != 13) {
-                               if (!checkserwrite(2))
+                               if (!checkserwrite(2)) {
+                                       data_in_sershift = 2;
                                        return;
+                               }
                                writeser(13);
                        }
                }
-               if (!checkserwrite(1))
+               if (!checkserwrite(1)) {
+                       data_in_sershift = 2;
                        return;
+               }
                writeser(serdatshift_masked);
                serial_send_previous = serdatshift_masked;
        }
 #endif
-       if (serial_period_hsyncs <= 1) {
+       if (serial_period_hsyncs <= 1 || data_in_sershift == 2) {
                data_in_sershift = 0;
                serdatcopy();
        } else {
-               data_in_sershift = 2;
+               data_in_sershift = 3;
        }
 #if SERIALDEBUG > 2
        write_log(_T("SERIAL: send %04X (%c)\n"), serdatshift, dochar(serdatshift));
@@ -419,8 +433,9 @@ static void checksend(void)
 
 static bool checkshiftempty(void)
 {
+       writeser_flush();
        checksend();
-       if (data_in_sershift == 2) {
+       if (data_in_sershift == 3) {
                data_in_sershift = 0;
                serdatcopy();
                return true;
@@ -433,7 +448,7 @@ static void sersend_ce(uae_u32 v)
        if (checkshiftempty()) {
                lastbitcycle = get_cycles() + ((serper & 0x7fff) + 1) * CYCLE_UNIT;
                lastbitcycle_active_hsyncs = ((serper & 0x7fff) + 1) / maxhpos + 2;
-       } else if (data_in_sershift == 1) {
+       } else if (data_in_sershift == 1 || data_in_sershift == 2) {
                event2_newevent_x(-1, maxhpos, 0, sersend_ce);
        }
 }
@@ -455,14 +470,12 @@ static void serdatcopy(void)
 
        if (seriallog) {
                gotlogwrite = true;
-               write_log(_T("%c"), dochar(serdatshift_masked));
+               write_log(_T("%c"), docharlog(serdatshift_masked));
        }
 
        if (serper == 372) {
                if (enforcermode & 2) {
-                       console_out_f(_T("%c"), dochar(serdatshift_masked));
-                       if (serdatshift_masked == 10)
-                               console_out(_T("\n"));
+                       console_out_f(_T("%c"), docharlog(serdatshift_masked));
                }
        }
 
@@ -538,6 +551,10 @@ void serial_hsynchandler (void)
 
 void SERDAT (uae_u16 w)
 {
+#if SERIALDEBUG > 2
+       write_log(_T("SERIAL: SERDAT write 0x%04x (%c) PC=%x\n"), w, dochar(w), M68K_GETPC);
+#endif
+
        serdatcopy();
 
        serdat = w;
@@ -557,10 +574,6 @@ void SERDAT (uae_u16 w)
 
        data_in_serdat = 1;
        serdatcopy();
-
-#if SERIALDEBUG > 2
-       write_log (_T("SERIAL: wrote 0x%04x (%c) PC=%x\n"), w, dochar (w), M68K_GETPC);
-#endif
 }
 
 uae_u16 SERDATR (void)
@@ -577,16 +590,20 @@ uae_u16 SERDATR (void)
 #if SERIALDEBUG > 2
        write_log (_T("SERIAL: read 0x%04x (%c) %x\n"), serdatr, dochar (serdatr), M68K_GETPC);
 #endif
-       ovrun = 0;
        data_in_serdatr = 0;
        return serdatr;
 }
 
+void serial_rbf_clear(void)
+{
+       ovrun = 0;
+}
+
 void serial_check_irq (void)
 {
        // Data in receive buffer
        if (data_in_serdatr)
-               INTREQ(0x8000 | 0x0800);
+               INTREQ_0(0x8000 | 0x0800);
 }
 
 void serial_dtr_on (void)