1
0
Fork 0

Use PRIuPTR and define it for Windows GCC 64-bit

This commit is contained in:
krcroft 2019-11-29 17:28:51 -08:00 committed by Patryk Obara
parent 7d21bb1408
commit b55b43f543
8 changed files with 295 additions and 270 deletions

View file

@ -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

View file

@ -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

View file

@ -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'

View file

@ -22,6 +22,19 @@
#include <cinttypes>
#include <cstdint>
/* 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;

View file

@ -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")

View file

@ -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")

View file

@ -16,62 +16,69 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "dosbox.h"
#if C_MODEM
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <utility>
#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<Bitu>(-1))
if (numericresponse && code != static_cast<Bitu>(-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(&reg,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(&reg,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<uint32_t>(COMNUMBER),
static_cast<uint32_t>(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<uint32_t>(COMNUMBER),
static_cast<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint32_t>(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;i<size;i++) {
for (i=0; i < size; i++) {
c = data[i];
if(telClient.inIAC) {
if(telClient.recCommand) {
if((c != 0) && (c != 1) && (c != 3)) {
if (telClient.inIAC) {
if (telClient.recCommand) {
if ((c != 0) && (c != 1) && (c != 3)) {
LOG_MSG("MODEM: Unrecognized option %u", c);
if(telClient.command>250) {
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

View file

@ -20,6 +20,9 @@
#ifndef DOSBOX_SERIALMODEM_H
#define DOSBOX_SERIALMODEM_H
#include <vector>
#include <memory>
#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);
Bitu where=pos+used;
if (where>=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<uint32_t>(_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<uint32_t>(_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<Bit8u> 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<CFifo> rqueue;
std::unique_ptr<CFifo> 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<TCPServerSocket> serversocket;
std::unique_ptr<TCPClientSocket> clientsocket;
std::unique_ptr<TCPClientSocket> 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