Update os2 serial support(Josch). Add some fixes for Mac OS X. Fix uninitialized variable.
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2816
This commit is contained in:
parent
6027e7710f
commit
cfa3a9d466
7 changed files with 327 additions and 224 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: directserial_os2.cpp,v 1.3 2007-01-08 19:45:40 qbix79 Exp $ */
|
||||
/* $Id: directserial_os2.cpp,v 1.4 2007-02-22 08:41:16 qbix79 Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
|
||||
|
@ -26,6 +26,8 @@
|
|||
#if defined(OS2)
|
||||
#include "serialport.h"
|
||||
#include "directserial_os2.h"
|
||||
#include "misc_util.h"
|
||||
#include "pic.h"
|
||||
|
||||
// OS/2 related headers
|
||||
#define INCL_DOSFILEMGR
|
||||
|
@ -38,24 +40,46 @@
|
|||
/* This is a serial passthrough class. Its amazingly simple to */
|
||||
/* write now that the serial ports themselves were abstracted out */
|
||||
|
||||
CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh,
|
||||
TIMER_TickHandler th, Bit16u baseAddr, Bit8u initIrq,
|
||||
Bit32u initBps, Bit8u bytesize, const char *parity,
|
||||
Bit8u stopbits,const char *realPort)
|
||||
:CSerial (rh, wh, th,baseAddr,initIrq, initBps,
|
||||
bytesize, parity,stopbits) {
|
||||
CDirectSerial::CDirectSerial (Bitu id, CommandLine *cmd)
|
||||
: CSerial(id, cmd) {
|
||||
InstallationSuccessful = false;
|
||||
InstallTimerHandler(th);
|
||||
lastChance = 0;
|
||||
LOG_MSG ("OS/2 Serial port at %x: Opening %s", base, realPort);
|
||||
LOG_MSG("Opening OS2 serial port");
|
||||
|
||||
|
||||
rx_retry = 0;
|
||||
rx_retry_max = 0;
|
||||
|
||||
std::string tmpstring;
|
||||
|
||||
if (!cmd->FindStringBegin("realport:", tmpstring, false))
|
||||
{
|
||||
return;
|
||||
}
|
||||
#if SERIAL_DEBUG
|
||||
if (dbg_modemcontrol)
|
||||
{
|
||||
fprintf(debugfp, "%12.3f Port type directserial realport %s\r\n", PIC_FullIndex(), tmpstring.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// rxdelay: How many milliseconds to wait before causing an
|
||||
// overflow when the application is unresponsive.
|
||||
if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) {
|
||||
if(!(rx_retry_max<=10000)) {
|
||||
rx_retry_max=0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* tmpchar=tmpstring.c_str();
|
||||
|
||||
LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str());
|
||||
|
||||
ULONG ulAction = 0;
|
||||
APIRET rc = DosOpen((unsigned char*)realPort, &hCom, &ulAction, 0L, FILE_NORMAL, FILE_OPEN,
|
||||
APIRET rc = DosOpen((unsigned char*)tmpstring.c_str(), &hCom, &ulAction, 0L, FILE_NORMAL, FILE_OPEN,
|
||||
OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L);
|
||||
if (rc != NO_ERROR)
|
||||
{
|
||||
LOG_MSG ("Serial port \"%s\" could not be opened.", realPort);
|
||||
LOG_MSG ("Serial%d: Serial port \"%s\" could not be opened.", COMNUMBER, tmpstring.c_str());
|
||||
if (rc == 2) {
|
||||
LOG_MSG ("The specified port does not exist.");
|
||||
} else if (rc == 99) {
|
||||
|
@ -73,135 +97,125 @@ CDirectSerial::CDirectSerial (IO_ReadHandler * rh, IO_WriteHandler * wh,
|
|||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
|
||||
if ( rc != NO_ERROR)
|
||||
{
|
||||
DosClose(hCom);
|
||||
hCom = 0;
|
||||
return;
|
||||
}
|
||||
dcb.usWriteTimeout = 0;
|
||||
dcb.usReadTimeout = 0; //65535;
|
||||
dcb.fbTimeout |= 6;
|
||||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
if ( rc != NO_ERROR)
|
||||
{
|
||||
LOG_MSG("GetCommState failed with error %d.\n", rc);
|
||||
DosClose(hCom);
|
||||
hCom = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
CSerial::Init_Registers (initBps, bytesize, parity, stopbits);
|
||||
InstallationSuccessful = true;
|
||||
//LOG_MSG("InstSuccess");
|
||||
dcb.usWriteTimeout = 0;
|
||||
dcb.usReadTimeout = 0; //65535;
|
||||
dcb.fbCtlHndShake = dcb.fbFlowReplace = 0;
|
||||
dcb.fbTimeout = 6;
|
||||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
if ( rc != NO_ERROR)
|
||||
{
|
||||
LOG_MSG("SetDCBInfo failed with error %d.\n", rc);
|
||||
DosClose(hCom);
|
||||
hCom = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
struct {
|
||||
ULONG baud;
|
||||
BYTE fraction;
|
||||
} setbaud;
|
||||
setbaud.baud = 9600;
|
||||
setbaud.fraction = 0;
|
||||
ulParmLen = sizeof(setbaud);
|
||||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
if (rc != NO_ERROR)
|
||||
{
|
||||
LOG_MSG("ExtSetBaudrate failed with error %d.\n", rc);
|
||||
DosClose (hCom);
|
||||
hCom = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
struct {
|
||||
UCHAR data;
|
||||
UCHAR parity;
|
||||
UCHAR stop;
|
||||
} paramline;
|
||||
|
||||
// byte length
|
||||
paramline.data = 8;
|
||||
paramline.parity = 0;
|
||||
paramline.stop = 0;
|
||||
ulParmLen = sizeof(paramline);
|
||||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
if ( rc != NO_ERROR)
|
||||
{
|
||||
LOG_MSG ("SetLineCtrl failed with error %d.\n", rc);
|
||||
}
|
||||
|
||||
CSerial::Init_Registers();
|
||||
InstallationSuccessful = true;
|
||||
receiveblock = false;
|
||||
|
||||
// Clears comm errors
|
||||
USHORT errors = 0;
|
||||
ulParmLen = sizeof(errors);
|
||||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
|
||||
setEvent(SERIAL_POLLING_EVENT, 1);
|
||||
}
|
||||
|
||||
CDirectSerial::~CDirectSerial () {
|
||||
if (hCom != 0)
|
||||
DosClose (hCom);
|
||||
}
|
||||
|
||||
Bitu lastChance;
|
||||
|
||||
void CDirectSerial::RXBufferEmpty () {
|
||||
ULONG dwRead;
|
||||
Bit8u chRead;
|
||||
USHORT errors = 0;
|
||||
ULONG ulParmLen = sizeof(errors);
|
||||
|
||||
if (lastChance > 0) {
|
||||
receiveByte (ChanceChar);
|
||||
lastChance = 0;
|
||||
} else {
|
||||
// update RX
|
||||
if (DosRead (hCom, &chRead, 1, &dwRead) != NO_ERROR) {
|
||||
if (dwRead != 0) {
|
||||
//LOG_MSG("UART 0x%x: RX 0x%x", base,chRead);
|
||||
receiveByte (chRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check for errors
|
||||
Bit8u errreg = 0;
|
||||
APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
|
||||
if (rc != NO_ERROR && errors)
|
||||
{
|
||||
if (errors & 8) {
|
||||
LOG_MSG ("Serial port at 0x%x: line error: framing error.", base);
|
||||
errreg |= LSR_FRAMING_ERROR_MASK;
|
||||
}
|
||||
if (errors & 4) {
|
||||
LOG_MSG ("Serial port at 0x%x: line error: parity error.", base);
|
||||
errreg |= LSR_PARITY_ERROR_MASK;
|
||||
}
|
||||
}
|
||||
errors = 0;
|
||||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
|
||||
if (rc != NO_ERROR && errors)
|
||||
{
|
||||
if (errors & 6) {
|
||||
LOG_MSG ("Serial port at 0x%x: line error: break received.", base);
|
||||
errreg |= LSR_RX_BREAK_MASK;
|
||||
}
|
||||
}
|
||||
if (errreg != 0)
|
||||
{
|
||||
receiveError (errreg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* updatePortConfig is called when emulated app changes the serial port **/
|
||||
/* parameters baudrate, stopbits, number of databits, parity. **/
|
||||
/*****************************************************************************/
|
||||
void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) {
|
||||
void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) {
|
||||
Bit8u parity = 0;
|
||||
Bit8u bytelength = 0;
|
||||
Bit16u baudrate = 0, baud = 0;
|
||||
|
||||
// baud
|
||||
baudrate = dlm;
|
||||
baudrate = baudrate << 8;
|
||||
baudrate |= dll;
|
||||
if (baudrate <= 0x1)
|
||||
baud = 115200;
|
||||
else if (baudrate <= 0x2)
|
||||
baud = 57600;
|
||||
else if (baudrate <= 0x3)
|
||||
baud = 38400;
|
||||
else if (baudrate <= 0x6)
|
||||
baud = 19200;
|
||||
else if (baudrate <= 0xc)
|
||||
baud = 9600;
|
||||
else if (baudrate <= 0x18)
|
||||
baud = 4800;
|
||||
else if (baudrate <= 0x30)
|
||||
baud = 2400;
|
||||
else if (baudrate <= 0x60)
|
||||
baud = 1200;
|
||||
else if (baudrate <= 0xc0)
|
||||
baud = 600;
|
||||
else if (baudrate <= 0x180)
|
||||
baud = 300;
|
||||
else if (baudrate <= 0x417)
|
||||
baud = 110;
|
||||
|
||||
// I read that windows can handle nonstandard baudrates:
|
||||
else
|
||||
baud = 115200 / baudrate;
|
||||
|
||||
#ifdef SERIALPORT_DEBUGMSG
|
||||
LOG_MSG ("Serial port at %x: new baud rate: %d", base, dcb.BaudRate);
|
||||
#endif
|
||||
|
||||
struct {
|
||||
ULONG baud;
|
||||
BYTE fraction;
|
||||
} setbaud;
|
||||
setbaud.baud = baud;
|
||||
|
||||
// baud
|
||||
if (divider <= 0x1)
|
||||
setbaud.baud = 115200;
|
||||
else if (divider <= 0x2)
|
||||
setbaud.baud = 57600;
|
||||
else if (divider <= 0x3)
|
||||
setbaud.baud = 38400;
|
||||
else if (divider <= 0x6)
|
||||
setbaud.baud = 19200;
|
||||
else if (divider <= 0xc)
|
||||
setbaud.baud = 9600;
|
||||
else if (divider <= 0x18)
|
||||
setbaud.baud = 4800;
|
||||
else if (divider <= 0x30)
|
||||
setbaud.baud = 2400;
|
||||
else if (divider <= 0x60)
|
||||
setbaud.baud = 1200;
|
||||
else if (divider <= 0xc0)
|
||||
setbaud.baud = 600;
|
||||
else if (divider <= 0x180)
|
||||
setbaud.baud = 300;
|
||||
else if (divider <= 0x417)
|
||||
setbaud.baud = 110;
|
||||
|
||||
// I read that windows can handle nonstandard baudrates:
|
||||
else
|
||||
setbaud.baud = 115200 / divider;
|
||||
|
||||
|
||||
setbaud.fraction = 0;
|
||||
ULONG ulParmLen = sizeof(setbaud);
|
||||
APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
if (rc != NO_ERROR)
|
||||
{
|
||||
LOG_MSG("Serial%d: Desired serial mode not supported (Baud: %d, %d, Error: %d)",
|
||||
COMNUMBER, setbaud.baud, divider, rc);
|
||||
}
|
||||
|
||||
|
||||
|
@ -248,12 +262,28 @@ void CDirectSerial::updatePortConfig (Bit8u dll, Bit8u dlm, Bit8u lcr) {
|
|||
}
|
||||
|
||||
|
||||
#ifdef SERIAL_DEBUG
|
||||
LOG_MSG("_____________________________________________________");
|
||||
LOG_MSG("Serial%d, new baud rate: %d", COMNUMBER, setbaud.baud);
|
||||
LOG_MSG("Serial%d: new bytelen: %d", COMNUMBER, paramline.data);
|
||||
LOG_MSG("Serial%d: new parity: %d", COMNUMBER, paramline.parity);
|
||||
LOG_MSG("Serial%d: new stopbits: %d", COMNUMBER, paramline.stop);
|
||||
#endif
|
||||
|
||||
ulParmLen = sizeof(paramline);
|
||||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, ¶mline, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
if ( rc != NO_ERROR)
|
||||
{
|
||||
LOG_MSG ("Serial port at 0x%x: API did not like the new values.", base);
|
||||
#ifdef SERIAL_DEBUG
|
||||
if (dbg_modemcontrol)
|
||||
{
|
||||
fprintf(debugfp, "%12.3f serial mode not supported: rate=%d, LCR=%x.\r\n", PIC_FullIndex(), setbaud.baud, lcr);
|
||||
}
|
||||
#endif
|
||||
LOG_MSG("Serial%d: Desired serial mode not supported (%d,%d,%d,%d)",
|
||||
COMNUMBER, setbaud.baud, paramline.data, paramline.parity, lcr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -262,33 +292,29 @@ void CDirectSerial::updateMSR () {
|
|||
UCHAR dptr = 0;
|
||||
ULONG ulParmLen = sizeof(dptr);
|
||||
|
||||
APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, &dptr, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, 0, 0, 0, &dptr, ulParmLen, &ulParmLen);
|
||||
if (rc != NO_ERROR) {
|
||||
#ifdef SERIALPORT_DEBUGMSG
|
||||
// LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base);
|
||||
#endif
|
||||
//return;
|
||||
LOG_MSG ("Serial port at %x: GetModemInput failed with %d !", idnumber, dptr);
|
||||
}
|
||||
if (dptr & 16)
|
||||
newmsr |= MSR_CTS_MASK;
|
||||
if (dptr & 32)
|
||||
newmsr |= MSR_DSR_MASK;
|
||||
if (dptr & 64)
|
||||
newmsr |= MSR_RI_MASK;
|
||||
if (dptr & 128)
|
||||
newmsr |= MSR_CD_MASK;
|
||||
changeMSR (newmsr);
|
||||
setCTS( (dptr & 16) != 0);
|
||||
setDSR( (dptr & 32) != 0);
|
||||
setRI( (dptr & 64) != 0);
|
||||
setCD( (dptr & 128) != 0);
|
||||
}
|
||||
|
||||
void CDirectSerial::transmitByte (Bit8u val) {
|
||||
// mean bug: with break = 1, WriteFile will never return.
|
||||
void CDirectSerial::transmitByte (Bit8u val, bool first) {
|
||||
ULONG bytesWritten = 0;
|
||||
APIRET rc = DosWrite (hCom, &val, 1, &bytesWritten);
|
||||
if (rc == NO_ERROR && bytesWritten > 0) {
|
||||
ByteTransmitted ();
|
||||
//LOG_MSG("UART 0x%x: TX 0x%x", base,val);
|
||||
} else {
|
||||
LOG_MSG ("UART 0x%x: NO BYTE WRITTEN!", base);
|
||||
LOG_MSG ("Serial%d: NO BYTE WRITTEN!", idnumber);
|
||||
}
|
||||
if (first)
|
||||
{
|
||||
setEvent(SERIAL_THR_EVENT, bytetime / 8);
|
||||
} else {
|
||||
setEvent(SERIAL_TX_EVENT, bytetime);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,9 +323,6 @@ void CDirectSerial::transmitByte (Bit8u val) {
|
|||
/*****************************************************************************/
|
||||
|
||||
void CDirectSerial::setBreak (bool value) {
|
||||
//#ifdef SERIALPORT_DEBUGMSG
|
||||
//LOG_MSG("UART 0x%x: Break toggeled: %d", base, value);
|
||||
//#endif
|
||||
USHORT error;
|
||||
ULONG ulParmLen = sizeof(error);
|
||||
if (value)
|
||||
|
@ -311,7 +334,8 @@ void CDirectSerial::setBreak (bool value) {
|
|||
/*****************************************************************************/
|
||||
/* updateModemControlLines(mcr) sets DTR and RTS. **/
|
||||
/*****************************************************************************/
|
||||
void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) {
|
||||
void CDirectSerial::setRTSDTR(bool rts, bool dtr)
|
||||
{
|
||||
bool change = false;
|
||||
DCBINFO dcb;
|
||||
ULONG ulParmLen = sizeof(dcb);
|
||||
|
@ -319,7 +343,7 @@ void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) {
|
|||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
|
||||
|
||||
/*** DTR ***/
|
||||
if (CSerial::getDTR ()) { // DTR on
|
||||
if (dtr) { // DTR on
|
||||
if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled
|
||||
dcb.fbCtlHndShake |= 1;
|
||||
change = true;
|
||||
|
@ -331,7 +355,7 @@ void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) {
|
|||
}
|
||||
}
|
||||
/*** RTS ***/
|
||||
if (CSerial::getRTS ()) { // RTS on
|
||||
if (rts) { // RTS on
|
||||
if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled
|
||||
dcb.fbFlowReplace |= 64;
|
||||
change = true;
|
||||
|
@ -346,72 +370,145 @@ void CDirectSerial::updateModemControlLines ( /*Bit8u mcr */ ) {
|
|||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
}
|
||||
|
||||
void CDirectSerial::Timer2(void) {
|
||||
ULONG dwRead = 0;
|
||||
USHORT errors = 0;
|
||||
Bit8u chRead = 0;
|
||||
ULONG ulParmLen = sizeof(errors);
|
||||
void CDirectSerial::setRTS(bool val)
|
||||
{
|
||||
bool change = false;
|
||||
DCBINFO dcb;
|
||||
ULONG ulParmLen = sizeof(dcb);
|
||||
|
||||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
|
||||
|
||||
if (lastChance == 0) { // lastChance = 0
|
||||
if (CanReceiveByte ()) {
|
||||
if (DosRead (hCom, &chRead, 1, &dwRead)) {
|
||||
if (dwRead)
|
||||
receiveByte (chRead);
|
||||
/*** RTS ***/
|
||||
if (val) { // RTS on
|
||||
if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled
|
||||
dcb.fbFlowReplace |= 64;
|
||||
change = true;
|
||||
}
|
||||
} else {
|
||||
if (DosRead (hCom, &chRead, 1, &dwRead)) {
|
||||
if (dwRead) {
|
||||
ChanceChar = chRead;
|
||||
lastChance++;
|
||||
if (dcb.fbFlowReplace && 192 == 1) { // RTS enabled
|
||||
dcb.fbFlowReplace &= ~192;
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
if (change)
|
||||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
}
|
||||
} else if (lastChance > 10) {
|
||||
receiveByte (0); // this causes RX Overrun now
|
||||
lastChance = 0;
|
||||
// empty serial buffer
|
||||
dwRead = 1;
|
||||
while (dwRead > 0) { // throw away bytes in buffer
|
||||
DosRead (hCom, &chRead, 1, &dwRead);
|
||||
|
||||
void CDirectSerial::setDTR(bool val)
|
||||
{
|
||||
bool change = false;
|
||||
DCBINFO dcb;
|
||||
ULONG ulParmLen = sizeof(dcb);
|
||||
|
||||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
|
||||
|
||||
/*** DTR ***/
|
||||
if (val) { // DTR on
|
||||
if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled
|
||||
dcb.fbCtlHndShake |= 1;
|
||||
change = true;
|
||||
}
|
||||
} else { // lastChance>0 // already one waiting
|
||||
if (CanReceiveByte ()) { // chance used
|
||||
receiveByte (ChanceChar);
|
||||
lastChance = 0;
|
||||
} else
|
||||
lastChance++;
|
||||
} else {
|
||||
if (dcb.fbCtlHndShake && 3 == 1) { // DTR enabled
|
||||
dcb.fbCtlHndShake &= ~3;
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
if (change)
|
||||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
}
|
||||
|
||||
// check for errors
|
||||
Bit8u errreg = 0;
|
||||
APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
|
||||
if (rc != NO_ERROR && errors)
|
||||
|
||||
void CDirectSerial::handleUpperEvent(Bit16u type)
|
||||
{
|
||||
if (errors & 8) {
|
||||
LOG_MSG ("Serial port at 0x%x: line error: framing error.", base);
|
||||
errreg |= LSR_FRAMING_ERROR_MASK;
|
||||
switch(type) {
|
||||
case SERIAL_POLLING_EVENT: {
|
||||
ULONG dwRead = 0;
|
||||
ULONG errors = 0;
|
||||
Bit8u chRead = 0;
|
||||
|
||||
setEvent(SERIAL_POLLING_EVENT, 1);
|
||||
if(!receiveblock) {
|
||||
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
|
||||
{
|
||||
rx_retry=0;
|
||||
if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) {
|
||||
if (dwRead) {
|
||||
receiveByte (chRead);
|
||||
setEvent(40, bytetime-0.03f); // receive timing
|
||||
receiveblock=true;
|
||||
}
|
||||
if (errors & 4) {
|
||||
LOG_MSG ("Serial port at 0x%x: line error: parity error.", base);
|
||||
errreg |= LSR_PARITY_ERROR_MASK;
|
||||
}
|
||||
} else rx_retry++;
|
||||
}
|
||||
// check for errors
|
||||
CheckErrors();
|
||||
// update Modem input line states
|
||||
updateMSR ();
|
||||
break;
|
||||
}
|
||||
case 40: {
|
||||
// receive time is up
|
||||
ULONG dwRead = 0;
|
||||
Bit8u chRead = 0;
|
||||
receiveblock=false;
|
||||
// check if there is something to receive
|
||||
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
|
||||
{
|
||||
rx_retry=0;
|
||||
if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) {
|
||||
if (dwRead) {
|
||||
receiveByte (chRead);
|
||||
setEvent(40, bytetime-0.03f); // receive timing
|
||||
receiveblock=true;
|
||||
}
|
||||
}
|
||||
} else rx_retry++;
|
||||
break;
|
||||
}
|
||||
case SERIAL_TX_EVENT: {
|
||||
ULONG dwRead = 0;
|
||||
Bit8u chRead = 0;
|
||||
if(!receiveblock) {
|
||||
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
|
||||
{
|
||||
rx_retry=0;
|
||||
if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) {
|
||||
if (dwRead) {
|
||||
receiveByte (chRead);
|
||||
setEvent(40, bytetime-0.03f); // receive timing
|
||||
receiveblock=true;
|
||||
}
|
||||
}
|
||||
} else rx_retry++;
|
||||
}
|
||||
ByteTransmitted();
|
||||
break;
|
||||
}
|
||||
case SERIAL_THR_EVENT: {
|
||||
ByteTransmitting();
|
||||
setEvent(SERIAL_TX_EVENT,bytetime+0.03f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
errors = 0;
|
||||
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
|
||||
if (rc != NO_ERROR && errors)
|
||||
{
|
||||
if (errors & 6) {
|
||||
LOG_MSG ("Serial port at 0x%x: line error: break received.", base);
|
||||
errreg |= LSR_RX_BREAK_MASK;
|
||||
|
||||
}
|
||||
|
||||
void CDirectSerial::CheckErrors() {
|
||||
|
||||
USHORT errors = 0, event = 0;
|
||||
ULONG ulParmLen = sizeof(errors);
|
||||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &event, ulParmLen, &ulParmLen);
|
||||
if (event & (64 + 128) ) { // Break (Bit 6) or Frame or Parity (Bit 7) error
|
||||
Bit8u errreg = 0;
|
||||
if (event & 64) errreg |= LSR_RX_BREAK_MASK;
|
||||
if (event & 128) {
|
||||
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
|
||||
if (errors & 8) errreg |= LSR_FRAMING_ERROR_MASK;
|
||||
if (errors & 4) errreg |= LSR_PARITY_ERROR_MASK;
|
||||
}
|
||||
}
|
||||
if (errreg != 0)
|
||||
{
|
||||
receiveError (errreg);
|
||||
}
|
||||
// update Modem input line states
|
||||
updateMSR ();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: directserial_os2.h,v 1.3 2007-01-08 19:45:40 qbix79 Exp $ */
|
||||
/* $Id: directserial_os2.h,v 1.4 2007-02-22 08:41:16 qbix79 Exp $ */
|
||||
|
||||
// include guard
|
||||
#ifndef DOSBOX_DIRECTSERIAL_OS2_H
|
||||
|
@ -40,42 +40,38 @@ public:
|
|||
HFILE hCom;
|
||||
BOOL fSuccess;
|
||||
|
||||
CDirectSerial(
|
||||
IO_ReadHandler* rh,
|
||||
IO_WriteHandler* wh,
|
||||
TIMER_TickHandler th,
|
||||
Bit16u baseAddr,
|
||||
Bit8u initIrq,
|
||||
Bit32u initBps,
|
||||
Bit8u bytesize,
|
||||
const char *parity,
|
||||
Bit8u stopbits,
|
||||
const char * realPort
|
||||
);
|
||||
|
||||
|
||||
CDirectSerial(Bitu id, CommandLine* cmd);
|
||||
~CDirectSerial();
|
||||
|
||||
|
||||
Bitu lastChance; // If there is no space for new
|
||||
//Bitu lastChance; // If there is no space for new
|
||||
// received data, it gets a little chance
|
||||
Bit8u ChanceChar;
|
||||
//Bit8u ChanceChar;
|
||||
|
||||
bool CanRecv(void);
|
||||
bool CanSend(void);
|
||||
//bool CanRecv(void);
|
||||
//bool CanSend(void);
|
||||
|
||||
bool InstallationSuccessful; // check after constructing. If
|
||||
// something was wrong, delete it right away.
|
||||
|
||||
void RXBufferEmpty();
|
||||
//void RXBufferEmpty();
|
||||
bool receiveblock;
|
||||
Bitu rx_retry;
|
||||
Bitu rx_retry_max;
|
||||
|
||||
void CheckErrors();
|
||||
|
||||
void updatePortConfig(Bit8u dll, Bit8u dlm, Bit8u lcr);
|
||||
void updatePortConfig(Bit16u divider, Bit8u lcr);
|
||||
void updateMSR();
|
||||
void transmitByte(Bit8u val);
|
||||
void transmitByte(Bit8u val, bool first);
|
||||
void setBreak(bool value);
|
||||
void updateModemControlLines(/*Bit8u mcr*/);
|
||||
void Timer2(void);
|
||||
|
||||
void setRTSDTR(bool rts, bool dtr);
|
||||
void setRTS(bool val);
|
||||
void setDTR(bool val);
|
||||
void handleUpperEvent(Bit16u type);
|
||||
|
||||
|
||||
//void updateModemControlLines(/*Bit8u mcr*/);
|
||||
//void Timer2(void);
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
// C++ SDLnet wrapper
|
||||
|
||||
// Socket inheritance
|
||||
#ifdef LINUX
|
||||
#if defined LINUX || defined OS2
|
||||
#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET)
|
||||
#ifdef OS2
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -18,6 +21,13 @@
|
|||
#include <winsock.h>
|
||||
typedef int socklen_t;
|
||||
|
||||
#elif defined __APPLE__
|
||||
#define CAPWORD (NETWRAPPER_TCP|NETWRAPPER_TCP_NATIVESOCKET)
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#define SOCKET socklen_t
|
||||
|
||||
#else
|
||||
#define CAPWORD NETWRAPPER_TCP
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "SDL_net.h"
|
||||
#include "support.h"
|
||||
|
||||
#ifdef LINUX
|
||||
#if defined LINUX || defined OS2
|
||||
#define NATIVESOCKETS
|
||||
|
||||
#elif defined WIN32
|
||||
|
|
|
@ -34,7 +34,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
|
|||
clientport = 0;
|
||||
|
||||
rx_retry = 0;
|
||||
rx_retry_max = 100;
|
||||
rx_retry_max = 100;
|
||||
|
||||
tx_gather = 12;
|
||||
|
||||
|
@ -99,7 +99,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
|
|||
// custom connect
|
||||
Bit8u peernamebuf[16];
|
||||
LOG_MSG("inheritance port: %d",sock);
|
||||
clientsocket = new TCPClientSocket(sock);
|
||||
clientsocket = new TCPClientSocket(sock);
|
||||
if(!clientsocket->isopen) {
|
||||
LOG_MSG("Serial%d: Connection failed.",COMNUMBER);
|
||||
delete clientsocket;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: nullmodem.h,v 1.1 2007-01-13 08:35:49 qbix79 Exp $ */
|
||||
/* $Id: nullmodem.h,v 1.2 2007-02-22 08:41:16 qbix79 Exp $ */
|
||||
|
||||
// include guard
|
||||
#ifndef DOSBOX_NULLMODEM_WIN32_H
|
||||
|
@ -29,10 +29,10 @@
|
|||
#include "misc_util.h"
|
||||
#include "serialport.h"
|
||||
|
||||
#define SERIAL_SERVER_POLLING_EVENT SERIAL_BASE_EVENT_COUNT+1
|
||||
#define SERIAL_TX_REDUCTION SERIAL_BASE_EVENT_COUNT+2
|
||||
#define SERIAL_NULLMODEM_DTR_EVENT SERIAL_BASE_EVENT_COUNT+3
|
||||
#define SERIAL_NULLMODEM_EVENT_COUNT SERIAL_BASE_EVENT_COUNT+ 3
|
||||
#define SERIAL_SERVER_POLLING_EVENT SERIAL_BASE_EVENT_COUNT+1
|
||||
#define SERIAL_TX_REDUCTION SERIAL_BASE_EVENT_COUNT+2
|
||||
#define SERIAL_NULLMODEM_DTR_EVENT SERIAL_BASE_EVENT_COUNT+3
|
||||
#define SERIAL_NULLMODEM_EVENT_COUNT SERIAL_BASE_EVENT_COUNT+3
|
||||
|
||||
class CNullModem : public CSerial {
|
||||
public:
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: serialport.cpp,v 1.6 2007-01-13 08:35:49 qbix79 Exp $ */
|
||||
/* $Id: serialport.cpp,v 1.7 2007-02-22 08:41:16 qbix79 Exp $ */
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
@ -950,7 +950,7 @@ void CSerial::Init_Registers () {
|
|||
ISR = 0x1;
|
||||
LCR = 0;
|
||||
//MCR = 0xff;
|
||||
loopback;
|
||||
loopback = true;
|
||||
dtr=true;
|
||||
rts=true;
|
||||
op1=true;
|
||||
|
|
Loading…
Add table
Reference in a new issue