diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index eed25509..8b27722b 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -12,19 +12,19 @@ jobs: - name: GCC-5 (Ubuntu 16.04) os: ubuntu-16.04 flags: -c gcc - max_warnings: 304 + max_warnings: 289 - name: GCC-7 (Ubuntu 18.04) os: ubuntu-18.04 flags: -c gcc - max_warnings: 307 + max_warnings: 292 - name: GCC-9 (Ubuntu 18.04) os: ubuntu-18.04 flags: -c gcc -v 9 - max_warnings: 330 + max_warnings: 315 - name: Clang-8 (Ubuntu 18.04) os: ubuntu-18.04 flags: -c clang -v 8 - max_warnings: 170 + max_warnings: 157 steps: - uses: actions/checkout@v1 - run: sudo apt-get update diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0c54cc70..88d38fcc 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -11,10 +11,10 @@ jobs: conf: - name: Clang flags: -c clang - max_warnings: 222 + max_warnings: 209 - name: GCC-9 flags: -c gcc -v 9 - max_warnings: 317 + max_warnings: 302 steps: - uses: actions/checkout@v1 - name: Install C++ compiler and libraries diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 647cb770..e5032fb6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -1,10 +1,10 @@ name: Windows builds on: push env: - MAX_WARNINGS_GCC_32bit_Debug: 234 - MAX_WARNINGS_GCC_64bit_Debug: 350 - MAX_WARNINGS_Clang_32bit_Debug: 100 - MAX_WARNINGS_Clang_64bit_Debug: 155 + MAX_WARNINGS_GCC_32bit_Debug: 230 + MAX_WARNINGS_GCC_64bit_Debug: 305 + MAX_WARNINGS_Clang_32bit_Debug: 99 + MAX_WARNINGS_Clang_64bit_Debug: 143 jobs: @@ -73,6 +73,5 @@ jobs: export MSYSTEM_CARCH="$ARCH_${{ matrix.bits }}" export MSYSTEM_CHOST="$ARCH_${{ matrix.bits }}-pc-msys" ./scripts/build.sh --compiler ${{ matrix.compiler }} --build-type Debug --bin-path /mingw${{ matrix.bits }}/bin - grep '^#define' config.h - name: Debug Warnings run: '.\scripts\count-warnings.py -m $env:MAX_WARNINGS_${{ matrix.compiler }}_${{ matrix.bits }}bit_Debug build.log' diff --git a/include/types.h b/include/types.h index b2f0ac64..a3b5a2d7 100644 --- a/include/types.h +++ b/include/types.h @@ -22,6 +22,19 @@ #include #include +/* Work around this bug in /mingw64/x86_64-w64-mingw64/include/inttypes.h: + * MS runtime does not yet understand C9x standard "ll" + * length specifier. It appears to treat "ll" as "l". + * The non-standard I64 length specifier understood by MS + * runtime functions, so for now we use that. + */ +#if defined(__MINGW64__) && !defined(__clang__) +#ifdef PRIuPTR +#undef PRIuPTR +#endif +#define PRIuPTR "I64u" +#endif + using Bit8u = uint8_t; using Bit16u = uint16_t; using Bit32u = uint32_t; diff --git a/scripts/automator/build/clang-defaults b/scripts/automator/build/clang-defaults index 5792c396..bac59575 100644 --- a/scripts/automator/build/clang-defaults +++ b/scripts/automator/build/clang-defaults @@ -4,11 +4,14 @@ cxx="clang++${postfix}" # Flag additions TYPES+=("debug" "profile") -cflags+=("-fcolor-diagnostics") cflags_release=("${cflags[@]}" "-Os") cflags_debug=("${cflags[@]}" "-g" "-Og" "-fno-omit-frame-pointer") cflags_profile=("${cflags_debug[@]}" "-fprofile-instr-generate" "-fcoverage-mapping") +# Colorize output only for interactive shells +if [[ $- == *i* ]]; then + cflags+=("-fcolor-diagnostics") +fi # Modifier additions MODIFIERS=("fdo") diff --git a/scripts/automator/build/gcc-defaults b/scripts/automator/build/gcc-defaults index aa9e4cff..3674d9f9 100644 --- a/scripts/automator/build/gcc-defaults +++ b/scripts/automator/build/gcc-defaults @@ -7,7 +7,7 @@ ranlib="gcc-ranlib${postfix}" # Flag additions TYPES+=("debug" "profile") -cflags+=("-fstack-protector" "-fdiagnostics-color=always") +cflags+=("-fstack-protector" "-fdiagnostics-color=auto") cflags_release=("${cflags[@]}" "-Ofast" "-ffunction-sections" "-fdata-sections") cflags_debug=("${cflags[@]}" "-g" "-Og" "-fno-omit-frame-pointer") cflags_profile=("${cflags_debug[@]}" "-pg") diff --git a/src/hardware/serialport/softmodem.cpp b/src/hardware/serialport/softmodem.cpp index 10867909..bbacd685 100644 --- a/src/hardware/serialport/softmodem.cpp +++ b/src/hardware/serialport/softmodem.cpp @@ -16,62 +16,69 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #include "dosbox.h" #if C_MODEM - -#include -#include #include +#include +#include +#include #include "support.h" #include "serialport.h" #include "softmodem.h" #include "misc_util.h" -//#include "mixer.h" - - -CSerialModem::CSerialModem(Bitu id, CommandLine* cmd):CSerial(id, cmd) { +CSerialModem::CSerialModem(Bitu id, CommandLine* cmd) + : CSerial(id, cmd), + rqueue(new CFifo(MODEM_BUFFER_QUEUE_SIZE)), + tqueue(new CFifo(MODEM_BUFFER_QUEUE_SIZE)), + cmdbuf {0}, + commandmode(false), + echo(false), + oldDTRstate(false), + ringing(false), + numericresponse(false), + // Default to direct null modem connection; Telnet mode interprets IAC codes + telnetmode(false), + connected(false), + doresponse(0), + waiting_tx_character(0), + cmdpause(0), + ringtimer(0), + ringcount(0), + plusinc(0), + cmdpos(0), + flowcontrol(0), + tmpbuf {0}, + listenport(23), + reg {0}, + serversocket(nullptr), + clientsocket(nullptr), + waitingclientsocket(nullptr), + telClient {}, + dial {} +{ InstallationSuccessful=false; - connected=false; - rqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); - tqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE); - - // Default to direct null modem connection. Telnet mode interprets IAC codes - telnetmode = false; + // Setup the listening port, and ignore the return code as this is optional + (void) getBituSubstring("listenport:", &listenport, cmd); - // Initialize the sockets and setup the listening port - listenport = 23; - waitingclientsocket=0; - clientsocket = 0; - serversocket = 0; - getBituSubstring("listenport:", &listenport, cmd); - // TODO: Fix dialtones if requested //mhd.chan=MIXER_AddChannel((MIXER_MixHandler)this->MODEM_CallBack,8000,"MODEM"); //MIXER_Enable(mhd.chan,false); //MIXER_SetMode(mhd.chan,MIXER_16MONO); - + CSerial::Init_Registers(); Reset(); // reset calls EnterIdleState - + setEvent(SERIAL_POLLING_EVENT,1); InstallationSuccessful=true; } CSerialModem::~CSerialModem() { - if(serversocket) delete serversocket; - if(clientsocket) delete clientsocket; - if(waitingclientsocket) delete waitingclientsocket; - - delete rqueue; - delete tqueue; - // remove events - for(Bitu i = SERIAL_BASE_EVENT_COUNT+1; i <= SERIAL_MODEM_EVENT_COUNT; i++) + for (Bitu i = SERIAL_BASE_EVENT_COUNT+1; i <= SERIAL_MODEM_EVENT_COUNT; i++) removeEvent(i); } @@ -79,8 +86,8 @@ void CSerialModem::handleUpperEvent(Bit16u type) { switch (type) { case SERIAL_RX_EVENT: { // check for bytes to be sent to port - if(CSerial::CanReceiveByte()) - if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))) { + if (CSerial::CanReceiveByte()) + if (rqueue->inuse() && (CSerial::getRTS() || (flowcontrol != 3))) { Bit8u rbyte = rqueue->getb(); //LOG_MSG("Modem: sending byte %2x back to UART3",rbyte); CSerial::receiveByte(rbyte); @@ -96,7 +103,7 @@ void CSerialModem::handleUpperEvent(Bit16u type) { } } else { static Bits lcount=0; - if (lcount<1000) { + if (lcount < 1000) { lcount++; LOG_MSG("MODEM: TX Buffer overflow!"); } @@ -123,7 +130,7 @@ void CSerialModem::handleUpperEvent(Bit16u type) { void CSerialModem::SendLine(const char *line) { rqueue->addb(0xd); rqueue->addb(0xa); - rqueue->adds((Bit8u *)line,strlen(line)); + rqueue->adds((Bit8u *)line, strlen(line)); rqueue->addb(0xd); rqueue->addb(0xa); } @@ -132,18 +139,18 @@ void CSerialModem::SendLine(const char *line) { void CSerialModem::SendNumber(Bitu val) { rqueue->addb(0xd); rqueue->addb(0xa); - - rqueue->addb(val/100+'0'); + + rqueue->addb(val / 100 + '0'); val = val%100; - rqueue->addb(val/10+'0'); + rqueue->addb(val / 10 + '0'); val = val%10; - rqueue->addb(val+'0'); + rqueue->addb(val + '0'); rqueue->addb(0xd); rqueue->addb(0xa); } -void CSerialModem::SendRes(ResTypes response) { +void CSerialModem::SendRes(const ResTypes response) { char const * string = nullptr; Bitu code = -1; switch (response) { @@ -159,10 +166,10 @@ void CSerialModem::SendRes(ResTypes response) { } if(doresponse != 1) { - if(doresponse == 2 && (response == ResRING || + if (doresponse == 2 && (response == ResRING || response == ResCONNECT || response == ResNOCARRIER)) return; - if(numericresponse && code != static_cast(-1)) + if (numericresponse && code != static_cast(-1)) SendNumber(code); else if (string != nullptr) SendLine(string); @@ -184,18 +191,19 @@ bool CSerialModem::Dial(char * host) { // Scan host for port Bit16u port; - char * hasport=strrchr(host,':'); + char * hasport = strrchr(host,':'); if (hasport) { - *hasport++=0; - port=(Bit16u)atoi(hasport); + *hasport++ = 0; + port = (Bit16u)atoi(hasport); } - else port=MODEM_DEFAULT_PORT; + else + port = MODEM_DEFAULT_PORT; + // Resolve host we're gonna dial LOG_MSG("Connecting to host %s port %u", host, port); - clientsocket = new TCPClientSocket(host, port); - if(!clientsocket->isopen) { - delete clientsocket; - clientsocket=0; + clientsocket.reset(new TCPClientSocket(host, port)); + if (!clientsocket->isopen) { + clientsocket.reset(nullptr); LOG_MSG("Failed to connect."); SendRes(ResNOCARRIER); EnterIdleState(); @@ -207,28 +215,28 @@ bool CSerialModem::Dial(char * host) { } void CSerialModem::AcceptIncomingCall(void) { - if(waitingclientsocket) { - clientsocket=waitingclientsocket; - waitingclientsocket=0; + if (waitingclientsocket) { + clientsocket = std::move(waitingclientsocket); EnterConnectedState(); } else { EnterIdleState(); } } -Bitu CSerialModem::ScanNumber(char * & scan) { +Bitu CSerialModem::ScanNumber(char * & scan) const { Bitu ret=0; - while (char c=*scan) { - if (c>='0' && c<='9') { + while (char c = *scan) { + if (c >= '0' && c <= '9') { ret*=10; ret+=c-'0'; scan++; - } else break; + } else + break; } return ret; } -char CSerialModem::GetChar(char * & scan) { +char CSerialModem::GetChar(char * & scan) const { char ch = *scan; scan++; return ch; @@ -237,23 +245,21 @@ char CSerialModem::GetChar(char * & scan) { void CSerialModem::Reset(){ EnterIdleState(); cmdpos = 0; - cmdbuf[0]=0; + cmdbuf[0] = 0; oldDTRstate = getDTR(); flowcontrol = 0; plusinc = 0; - if(clientsocket) { - delete clientsocket; - clientsocket=0; - } - memset(®,0,sizeof(reg)); - reg[MREG_AUTOANSWER_COUNT]=0; // no autoanswer - reg[MREG_RING_COUNT] = 1; - reg[MREG_ESCAPE_CHAR]='+'; - reg[MREG_CR_CHAR]='\r'; - reg[MREG_LF_CHAR]='\n'; - reg[MREG_BACKSPACE_CHAR]='\b'; + clientsocket.reset(nullptr); - cmdpause = 0; + memset(®,0,sizeof(reg)); + reg[MREG_AUTOANSWER_COUNT] = 0; // no autoanswer + reg[MREG_RING_COUNT] = 1; + reg[MREG_ESCAPE_CHAR] = '+'; + reg[MREG_CR_CHAR] = '\r'; + reg[MREG_LF_CHAR] = '\n'; + reg[MREG_BACKSPACE_CHAR] = '\b'; + + cmdpause = 0; echo = true; doresponse = 0; numericresponse = false; @@ -263,37 +269,32 @@ void CSerialModem::Reset(){ } void CSerialModem::EnterIdleState(void){ - connected=false; - ringing=false; + connected = false; + ringing = false; + clientsocket.reset(nullptr); + waitingclientsocket.reset(nullptr); - if(clientsocket) { - delete clientsocket; - clientsocket=0; - } - - if(waitingclientsocket) { // clear current incoming socket - delete waitingclientsocket; - waitingclientsocket=0; - } // get rid of everything - if(serversocket) { - while( (waitingclientsocket=serversocket->Accept()) ) - delete waitingclientsocket; + if (serversocket) { + waitingclientsocket.reset(serversocket->Accept()); + while (waitingclientsocket) { + waitingclientsocket.reset(serversocket->Accept()); + } } else if (listenport) { - serversocket=new TCPServerSocket(listenport); - if(!serversocket->isopen) { - LOG_MSG("Serial%u: Modem could not open TCP port %u.", - static_cast(COMNUMBER), - static_cast(listenport)); - delete serversocket; - serversocket=0; + serversocket.reset(new TCPServerSocket(listenport)); + if (!serversocket->isopen) { + LOG_MSG("Serial%" PRIuPTR ": Modem could not open TCP port %" PRIuPTR ".", + COMNUMBER, + listenport); + + serversocket.reset(nullptr); } else - LOG_MSG("Serial%u: Modem listening on port %u...", - static_cast(COMNUMBER), - static_cast(listenport)); + LOG_MSG("Serial%" PRIuPTR ": Modem listening on port %" PRIuPTR "...", + COMNUMBER, + listenport); } - waitingclientsocket=0; + waitingclientsocket.reset(nullptr); commandmode = true; CSerial::setCD(false); @@ -304,11 +305,8 @@ void CSerialModem::EnterIdleState(void){ } void CSerialModem::EnterConnectedState(void) { - if(serversocket) { - // we don't accept further calls - delete serversocket; - serversocket=0; - } + // we don't accept further calls + serversocket.reset(nullptr); SendRes(ResCONNECT); commandmode = false; memset(&telClient, 0, sizeof(telClient)); @@ -325,7 +323,7 @@ void CSerialModem::DoCommand() { LOG_MSG("Command sent to modem: ->%s<-\n", cmdbuf); /* Check for empty line, stops dialing and autoanswer */ if (!cmdbuf[0]) { - reg[0]=0; // autoanswer off + reg[0] = 0; // autoanswer off return; } //else { @@ -357,21 +355,24 @@ void CSerialModem::DoCommand() { char chr = GetChar(scanbuf); switch (chr) { case 'D': { // Dial - char * foundstr=&scanbuf[0]; - if (*foundstr=='T' || *foundstr=='P') foundstr++; + char * foundstr = &scanbuf[0]; + if (*foundstr == 'T' || *foundstr == 'P') + foundstr++; + // Small protection against empty line and long string - if ((!foundstr[0]) || (strlen(foundstr)>100)) { + if ((!foundstr[0]) || (strlen(foundstr) > 100)) { SendRes(ResERROR); return; } - char* helper; // scan for and remove spaces; weird bug: with leading spaces in the string, // SDLNet_ResolveHost will return no error but not work anyway (win) - while(foundstr[0]==' ') foundstr++; - helper=foundstr; + while(foundstr[0] == ' ') + foundstr++; + + char* helper = foundstr; helper+=strlen(foundstr); - while(helper[0]==' ') { - helper[0]=0; + while(helper[0] == ' ') { + helper[0] = 0; helper--; } @@ -383,7 +384,8 @@ void CSerialModem::DoCommand() { bool isNum = true; size_t fl = strlen(foundstr); for (size_t i = 0; i < fl; i++) - if (foundstr[i] < '0' || foundstr[i] > '9') isNum = false; + if (foundstr[i] < '0' || foundstr[i] > '9') + isNum = false; if (isNum) { // Parameter is a number with at least 12 digits => this cannot // be a valid IP/name @@ -397,7 +399,7 @@ void CSerialModem::DoCommand() { buffer[j++] = '.'; // If the string is longer than 12 digits, // interpret the rest as port - if (i == 11 && strlen(foundstr)>12) + if (i == 11 && strlen(foundstr) > 12) buffer[j++] = ':'; } buffer[j] = 0; @@ -479,7 +481,8 @@ void CSerialModem::DoCommand() { case 'Z': { // Reset and load profiles // scan the number away, if any ScanNumber(scanbuf); - if (clientsocket) SendRes(ResNOCARRIER); + if (clientsocket) + SendRes(ResNOCARRIER); Reset(); break; } @@ -489,32 +492,34 @@ void CSerialModem::DoCommand() { // Response options // 0 = all on, 1 = all off, // 2 = no ring and no connect/carrier in answermode - Bitu val = ScanNumber(scanbuf); - if(!(val>2)) { - doresponse=val; + Bitu val = ScanNumber(scanbuf); + if (!(val > 2)) { + doresponse = val; break; } else { SendRes(ResERROR); return; } } - case 'S': { // Registers - Bitu index=ScanNumber(scanbuf); - if(index>=SREGS) { + case 'S': { // Registers + Bitu index = ScanNumber(scanbuf); + if (index >= SREGS) { SendRes(ResERROR); return; //goto ret_none; } - - while(scanbuf[0]==' ') scanbuf++; // skip spaces - - if(scanbuf[0]=='=') { // set register + + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces + + if (scanbuf[0] == '=') { // set register scanbuf++; - while(scanbuf[0]==' ') scanbuf++; // skip spaces + while (scanbuf[0] == ' ') + scanbuf++; // skip spaces Bitu val = ScanNumber(scanbuf); - reg[index]=val; + reg[index] = val; break; } - else if(scanbuf[0]=='?') { // get register + else if (scanbuf[0] == '?') { // get register SendNumber(reg[index]); scanbuf++; break; @@ -527,7 +532,8 @@ void CSerialModem::DoCommand() { switch(cmdchar) { case 'K': { Bitu val = ScanNumber(scanbuf); - if(val<5) flowcontrol=val; + if(val < 5) + flowcontrol = val; else { SendRes(ResERROR); return; @@ -539,16 +545,16 @@ void CSerialModem::DoCommand() { SendRes(ResERROR); return; default: - LOG_MSG("Modem: Unhandled command: &%c%u", + LOG_MSG("Modem: Unhandled command: &%c%" PRIuPTR, cmdchar, - static_cast(ScanNumber(scanbuf))); + ScanNumber(scanbuf)); break; } break; } case '\\': { // \ escaped commands char cmdchar = GetChar(scanbuf); - switch(cmdchar) { + switch (cmdchar) { case 'N': // error correction stuff - not emulated if (ScanNumber(scanbuf) > 5) { @@ -561,9 +567,9 @@ void CSerialModem::DoCommand() { SendRes(ResERROR); return; default: - LOG_MSG("Modem: Unhandled command: \\%c%u", + LOG_MSG("Modem: Unhandled command: \\%c%" PRIuPTR, cmdchar, - static_cast(ScanNumber(scanbuf))); + ScanNumber(scanbuf)); break; } break; @@ -572,9 +578,9 @@ void CSerialModem::DoCommand() { SendRes(ResOK); return; default: - LOG_MSG("Modem: Unhandled command: %c%u", + LOG_MSG("Modem: Unhandled command: %c%" PRIuPTR, chr, - static_cast(ScanNumber(scanbuf))); + ScanNumber(scanbuf)); break; } } @@ -583,44 +589,44 @@ void CSerialModem::DoCommand() { void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { Bitu i; Bit8u c; - for(i=0;i250) { + if (telClient.command > 250) { /* Reject anything we don't recognize */ tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(c); /* We won't do crap! */ } } - switch(telClient.command) { + switch (telClient.command) { case 251: /* Will */ - if(c == 0) telClient.binary[TEL_SERVER] = true; - if(c == 1) telClient.echo[TEL_SERVER] = true; - if(c == 3) telClient.supressGA[TEL_SERVER] = true; + if (c == 0) telClient.binary[TEL_SERVER] = true; + if (c == 1) telClient.echo[TEL_SERVER] = true; + if (c == 3) telClient.supressGA[TEL_SERVER] = true; break; case 252: /* Won't */ - if(c == 0) telClient.binary[TEL_SERVER] = false; - if(c == 1) telClient.echo[TEL_SERVER] = false; - if(c == 3) telClient.supressGA[TEL_SERVER] = false; + if (c == 0) telClient.binary[TEL_SERVER] = false; + if (c == 1) telClient.echo[TEL_SERVER] = false; + if (c == 3) telClient.supressGA[TEL_SERVER] = false; break; case 253: /* Do */ - if(c == 0) { + if (c == 0) { telClient.binary[TEL_CLIENT] = true; tqueue->addb(0xff); tqueue->addb(251); tqueue->addb(0); /* Will do binary transfer */ } - if(c == 1) { + if (c == 1) { telClient.echo[TEL_CLIENT] = false; tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(1); /* Won't echo (too lazy) */ } - if(c == 3) { + if (c == 3) { telClient.supressGA[TEL_CLIENT] = true; tqueue->addb(0xff); tqueue->addb(251); @@ -628,19 +634,19 @@ void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { } break; case 254: /* Don't */ - if(c == 0) { + if (c == 0) { telClient.binary[TEL_CLIENT] = false; tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(0); /* Won't do binary transfer */ } - if(c == 1) { + if (c == 1) { telClient.echo[TEL_CLIENT] = false; tqueue->addb(0xff); tqueue->addb(252); tqueue->addb(1); /* Won't echo (fine by me) */ } - if(c == 3) { + if (c == 3) { telClient.supressGA[TEL_CLIENT] = true; tqueue->addb(0xff); tqueue->addb(251); @@ -655,15 +661,15 @@ void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { telClient.recCommand = false; continue; } else { - if(c==249) { + if (c == 249) { /* Go Ahead received */ telClient.inIAC = false; continue; } telClient.command = c; telClient.recCommand = true; - - if((telClient.binary[TEL_SERVER]) && (c == 0xff)) { + + if ((telClient.binary[TEL_SERVER]) && (c == 0xff)) { /* Binary data with value of 255 */ telClient.inIAC = false; telClient.recCommand = false; @@ -672,7 +678,7 @@ void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) { } } } else { - if(c == 0xff) { + if (c == 0xff) { telClient.inIAC = true; continue; } @@ -691,7 +697,7 @@ void CSerialModem::Timer2(void) { // Check for eventual break command if (!commandmode) cmdpause++; // Handle incoming data from serial port, read as much as available - CSerial::setCTS(true); // buffer will get 'emptier', new data can be received + CSerial::setCTS(true); // buffer will get 'emptier', new data can be received while (tqueue->inuse()) { txval = tqueue->getb(); if (commandmode) { @@ -699,9 +705,9 @@ void CSerialModem::Timer2(void) { rqueue->addb(txval); //LOG_MSG("Echo back to queue: %x",txval); } - if (txval==0xa) continue; //Real modem doesn't seem to skip this? - else if (txval==0x8 && (cmdpos > 0)) --cmdpos; // backspace - else if (txval==0xd) DoCommand(); // return + if (txval == 0xa) continue; //Real modem doesn't seem to skip this? + else if (txval == 0x8 && (cmdpos > 0)) --cmdpos; // backspace + else if (txval == 0xd) DoCommand(); // return else if (txval != '+') { if(cmdpos<99) { cmdbuf[cmdpos] = txval; @@ -712,10 +718,10 @@ void CSerialModem::Timer2(void) { else {// + character // 1000 ticks have passed, can check for pause command if (cmdpause > 1000) { - if(txval ==reg[MREG_ESCAPE_CHAR]) // + + if (txval == reg[MREG_ESCAPE_CHAR]) // + { plusinc++; - if(plusinc>=3) { + if (plusinc >= 3) { LOG_MSG("Modem: Entering command mode(escape sequence)"); commandmode = true; SendRes(ResOK); @@ -725,55 +731,58 @@ void CSerialModem::Timer2(void) { } else { plusinc=0; } - // If not a special pause command, should go for bigger blocks to send + // If not a special pause command, should go for bigger blocks to send } tmpbuf[txbuffersize] = txval; txbuffersize++; } } // while loop - + if (clientsocket && sendbyte && txbuffersize) { // down here it saves a lot of network traffic - if(!clientsocket->SendArray(tmpbuf,txbuffersize)) { + if (!clientsocket->SendArray(tmpbuf,txbuffersize)) { SendRes(ResNOCARRIER); EnterIdleState(); } } // Handle incoming to the serial port - if(!commandmode && clientsocket && rqueue->left()) { + if (!commandmode && clientsocket && rqueue->left()) { usesize = rqueue->left(); - if (usesize>16) usesize=16; - if(!clientsocket->ReceiveArray(tmpbuf, &usesize)) { + if (usesize > 16) + usesize = 16; + if (!clientsocket->ReceiveArray(tmpbuf, &usesize)) { SendRes(ResNOCARRIER); EnterIdleState(); - } else if(usesize) { - // Filter telnet commands - if(telnetmode) TelnetEmulation(tmpbuf, usesize); - else rqueue->adds(tmpbuf,usesize); + } else if (usesize) { + // Filter telnet commands + if (telnetmode) + TelnetEmulation(tmpbuf, usesize); + else + rqueue->adds(tmpbuf,usesize); cmdpause = 0; - } + } } // Check for incoming calls if (!connected && !waitingclientsocket && serversocket) { - waitingclientsocket=serversocket->Accept(); - if(waitingclientsocket) { - if(!CSerial::getDTR()) { + waitingclientsocket.reset(serversocket->Accept()); + if (waitingclientsocket) { + if (!CSerial::getDTR()) { // accept no calls with DTR off; TODO: AT &Dn EnterIdleState(); } else { - ringing=true; + ringing = true; SendRes(ResRING); CSerial::setRI(!CSerial::getRI()); //MIXER_Enable(mhd.chan,true); ringtimer = 3000; - reg[1] = 0; //Reset ring counter reg + reg[1] = 0; //Reset ring counter reg } } } if (ringing) { if (ringtimer <= 0) { reg[1]++; - if ((reg[0]>0) && (reg[0]>=reg[1])) { + if ((reg[0] > 0) && (reg[0] >= reg[1])) { AcceptIncomingCall(); return; } @@ -791,7 +800,7 @@ void CSerialModem::Timer2(void) { //TODO void CSerialModem::RXBufferEmpty() { // see if rqueue has some more bytes - if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))){ + if (rqueue->inuse() && (CSerial::getRTS() || (flowcontrol != 3))){ Bit8u rbyte = rqueue->getb(); //LOG_MSG("Modem: sending byte %2x back to UART1",rbyte); CSerial::receiveByte(rbyte); @@ -799,14 +808,15 @@ void CSerialModem::RXBufferEmpty() { } void CSerialModem::transmitByte(Bit8u val, bool first) { - waiting_tx_character=val; + waiting_tx_character = val; setEvent(MODEM_TX_EVENT, bytetime); // TX event - if(first) ByteTransmitting(); + if (first) + ByteTransmitting(); //LOG_MSG("MODEM: Byte %x to be transmitted",val); } void CSerialModem::updatePortConfig(Bit16u, Bit8u lcr) { - (void) lcr; // deliberately unused by needed to meet the API + (void) lcr; // deliberately unused but needed for API compliance } void CSerialModem::updateMSR() { @@ -818,26 +828,26 @@ void CSerialModem::setBreak(bool) { } void CSerialModem::setRTSDTR(bool rts_, bool dtr_) { - (void) rts_; // deliberately unused but needed to meet the API + (void) rts_; // deliberately unused but needed for API compliance setDTR(dtr_); } void CSerialModem::setRTS(bool val) { - (void) val; // deliberately unused but needed to meet the API + (void) val; // deliberately unused but but needed for API compliance } void CSerialModem::setDTR(bool val) { - if(!val && connected) { + if (!val && connected) { // If DTR goes low, hang up. SendRes(ResNOCARRIER); EnterIdleState(); LOG_MSG("Modem: Hang up due to dropped DTR."); - } + } } /* void CSerialModem::updateModemControlLines() { //bool txrdy=tqueue->left(); //if(CSerial::getRTS() && txrdy) CSerial::setCTS(true); //else CSerial::setCTS(tqueue->left()); - + // If DTR goes low, hang up. if(connected) if(oldDTRstate) @@ -852,4 +862,3 @@ void CSerialModem::updateModemControlLines() { */ #endif - diff --git a/src/hardware/serialport/softmodem.h b/src/hardware/serialport/softmodem.h index 9f6376aa..c3e01d61 100644 --- a/src/hardware/serialport/softmodem.h +++ b/src/hardware/serialport/softmodem.h @@ -20,6 +20,9 @@ #ifndef DOSBOX_SERIALMODEM_H #define DOSBOX_SERIALMODEM_H +#include +#include + #include "dosbox.h" #if C_MODEM #include "serialport.h" @@ -56,96 +59,105 @@ enum ResTypes { class CFifo { public: - CFifo(Bitu _size) { - size=_size; - pos=used=0; - data=new Bit8u[size]; + CFifo(Bitu _size) + : data(_size), + size(_size), + pos(0), + used(0) + {} + + INLINE Bitu left(void) const { + return size - used; } - ~CFifo() { - delete[] data; - } - INLINE Bitu left(void) { - return size-used; - } - INLINE Bitu inuse(void) { + INLINE Bitu inuse(void) const { return used; } void clear(void) { - used=pos=0; + used = 0; + pos = 0; } void addb(Bit8u _val) { - if(used>=size) { - static Bits lcount=0; - if (lcount<1000) { + if(used >= size) { + static Bits lcount = 0; + if (lcount < 1000) { lcount++; LOG_MSG("MODEM: FIFO Overflow! (addb)"); } return; } //assert(used=size) where-=size; + Bitu where = pos + used; + if (where >= size) + where -= size; data[where]=_val; //LOG_MSG("+%x",_val); used++; } + void adds(Bit8u * _str,Bitu _len) { - if((used+_len)>size) { + if ( (used+_len) > size) { static Bits lcount=0; - if (lcount<1000) { + if (lcount < 1000) { lcount++; - LOG_MSG("MODEM: FIFO Overflow! (adds len %u)", - static_cast(_len)); + LOG_MSG("MODEM: FIFO Overflow! (adds len %" PRIuPTR ")", + _len); } return; } - + //assert((used+_len)<=size); - Bitu where=pos+used; - used+=_len; + Bitu where = pos + used; + used += _len; while (_len--) { - if (where>=size) where-=size; + if (where >= size) + where -= size; //LOG_MSG("+'%x'",*_str); - data[where++]=*_str++; + data[where++] = *_str++; } } + Bit8u getb(void) { if (!used) { - static Bits lcount=0; - if (lcount<1000) { + static Bits lcount = 0; + if (lcount < 1000) { lcount++; LOG_MSG("MODEM: FIFO UNDERFLOW! (getb)"); } return data[pos]; } - Bitu where=pos; - if (++pos>=size) pos-=size; + Bitu where = pos; + if (++pos >= size) + pos -= size; used--; //LOG_MSG("-%x",data[where]); return data[where]; } + void gets(Bit8u * _str,Bitu _len) { if (!used) { - static Bits lcount=0; - if (lcount<1000) { + static Bits lcount = 0; + if (lcount < 1000) { lcount++; - LOG_MSG("MODEM: FIFO UNDERFLOW! (gets len %u)", - static_cast(_len)); + LOG_MSG("MODEM: FIFO UNDERFLOW! (gets len %" PRIuPTR ")", + _len); } return; } //assert(used>=_len); - used-=_len; + used -= _len; while (_len--) { //LOG_MSG("-%x",data[pos]); - *_str++=data[pos]; - if (++pos>=size) pos-=size; + *_str++ = data[pos]; + if (++pos >= size) + pos -= size; } } private: - Bit8u * data; - Bitu size,pos,used; + std::vector data; + Bitu size; + Bitu pos; + Bitu used; }; #define MREG_AUTOANSWER_COUNT 0 #define MREG_RING_COUNT 1 @@ -157,17 +169,12 @@ private: class CSerialModem : public CSerial { public: - - CFifo *rqueue; - CFifo *tqueue; - CSerialModem(Bitu id, CommandLine* cmd); ~CSerialModem(); - void Reset(); void SendLine(const char *line); - void SendRes(ResTypes response); + void SendRes(const ResTypes response); void SendNumber(Bitu val); void EnterIdleState(); @@ -176,12 +183,12 @@ public: void openConnection(void); bool Dial(char * host); void AcceptIncomingCall(void); - Bitu ScanNumber(char * & scan); - char GetChar(char * & scan); + Bitu ScanNumber(char * & scan) const; + char GetChar(char * & scan) const; void DoCommand(); - - void MC_Changed(Bitu new_mc); + + // void MC_Changed(Bitu new_mc); void TelnetEmulation(Bit8u * data, Bitu size); @@ -201,50 +208,44 @@ public: void setRTS(bool val); void setDTR(bool val); + std::unique_ptr rqueue; + std::unique_ptr tqueue; + protected: char cmdbuf[255]; - bool commandmode; // true: interpret input as commands - bool echo; // local echo on or off - + bool commandmode; // true: interpret input as commands + bool echo; // local echo on or off bool oldDTRstate; bool ringing; - //bool response; - bool numericresponse; // true: send control response as number. - // false: send text (i.e. NO DIALTONE) - bool telnetmode; // true: process IAC commands. - + bool numericresponse; // true: send control response as number. + // false: send text (i.e. NO DIALTONE) + bool telnetmode; // true: process IAC commands. bool connected; Bitu doresponse; - Bit8u waiting_tx_character; - Bitu cmdpause; Bits ringtimer; Bits ringcount; Bitu plusinc; Bitu cmdpos; Bitu flowcontrol; - Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE]; - Bitu listenport; Bit8u reg[SREGS]; - - - TCPServerSocket* serversocket; - TCPClientSocket* clientsocket; - TCPClientSocket* waitingclientsocket; + std::unique_ptr serversocket; + std::unique_ptr clientsocket; + std::unique_ptr waitingclientsocket; struct { bool binary[2]; bool echo[2]; bool supressGA[2]; bool timingMark[2]; - bool inIAC; bool recCommand; Bit8u command; } telClient; + struct { bool active; double f1, f2; @@ -253,4 +254,4 @@ protected: } dial; }; #endif -#endif +#endif