Commits (4)
  • Rob Swindell's avatar
    Print the upload TCP protocol (when available) w/user name, not host/IP · 066c4bd3
    Rob Swindell authored
    Long hostnames would prevent the protocol from being shown. Also, non-operators should be able to see the protocol used to upload files.
    066c4bd3
  • Rob Swindell's avatar
    Support an optional ini filename argument, write to DOSXTRN.ERR · 5e9cc98f
    Rob Swindell authored
    If a 4th optional argument is provided, use that as the ini filename for virtual UART/FOSSIL driver settings instead of "sbbsexec.ini". Using this feature requires an updated sbbsexec.dll that supports an ini-filename argument (instead of a directory) to the VDD_LOAD_INI_FILE command.
    
    If DOSXTRN fails to execute the passed command-line, _spawnvp() returns -1, log the errno value and description to DOSXTRN.ERR (in the same directory as DOSXTRN.ENV). This will help diagnose issues executing DOS command-lines (e.g. file not found).
    
    Upon failure to open/create DOSXTRN.RET, don't prematurely terminate as that would skip a lot of important cleanup.
    5e9cc98f
  • Rob Swindell's avatar
    Improvements to virtual UART driver for Windows · 7791b698
    Rob Swindell authored
    In the process of creating/testing the new Synchronet Virtual DOS Modem (SVDM) project, I made the following significant improvements:
    
    - Don't default the log level to DEBUG for debug builds
    - Add a "carrier change" event so carrier low to high transitions can be tracked too
    - Replace several lprintf() calls with lputs() for performance reasons
    - Specify 'volatile' storage for pending_interrupts
    - Interrupts are re-asserted if there are any pending interrupts after reading IIR register
    - Emulate FIFO enablement
    - Support RTS flow control signal
    - Remove conditional/configurable yields when polling LSR and MSR register, would just unnecessarily slow down terminal programs
    - Report "DCD change" in MSR correctly
    - Clean-up (e.g. close handles) in VDD_CLOSE handler
    - VDD_LOAD_INI_FILE allows an optional ini filename (instead of directory) as its argument - for loading an ini filename other than sbbsexec.ini (e.g. svdm.ini).
    
    Initialize log level in VDDInitialize(). For versions of Windows/NTVDM that use/call the "init proc" (this function), we just re-initialize global variables here.
    7791b698
  • Rob Swindell's avatar
    Synchronet Virtual DOS Modem for Windows · b70d5898
    Rob Swindell authored
    First commit.
    
    Right now it just connects/accepts-connections using raw TCP. As demonstrated in YouTube video:
    https://www.youtube.com/watch?v=fxp38Nde3fg
    b70d5898
......@@ -13,21 +13,9 @@
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
......@@ -461,8 +449,10 @@ int main(int argc, char **argv)
char exec_dir[128];
char* envvar[MAX_ENVVARS];
char* arg[MAX_ARGS];
char* ini_fname = exec_dir;
int i,c,d,envnum=0;
int mode = SBBSEXEC_MODE_UNSPECIFIED;
int argn;
FILE* fp;
BOOL x64=FALSE;
BOOL success=FALSE;
......@@ -475,7 +465,7 @@ int main(int argc, char **argv)
,"%s - Copyright %s Rob Swindell\n"
,id_string, __DATE__+7);
fprintf(stderr
,"usage: dosxtrn <path/dosxtrn.env> [NT|x64] [node_num] [mode]\n");
,"usage: dosxtrn <path/dosxtrn.env> [NT|x64] [node_num] [mode] [ini_file]\n");
return(1);
}
......@@ -485,14 +475,24 @@ int main(int argc, char **argv)
sprintf(dll,"%s%s",exec_dir,VDD_FILENAME);
DllName=dll;
if(argc>2) {
if(strcmp(argv[2],"x64") == 0)
argn = 2;
if(argn < argc) {
if(strcmp(argv[argn],"x64") == 0)
x64=TRUE;
argn++;
}
if(argn < argc && IS_DIGIT(argv[argn][0])) {
node_num=atoi(argv[argn]);
argn++;
}
if(argn < argc && IS_DIGIT(argv[argn][0])) {
mode = atoi(argv[argn]);
argn++;
}
if(argn < argc) {
ini_fname = argv[argn];
argn++;
}
if(argc>3)
node_num=atoi(argv[3]);
if(argc>4)
mode=atoi(argv[4]);
if(mode == SBBSEXEC_MODE_UNSPECIFIED)
mode = SBBSEXEC_MODE_DEFAULT;
......@@ -575,7 +575,7 @@ int main(int argc, char **argv)
fprintf(stderr,"vdd handle=%d\n",vdd);
fprintf(stderr,"mode=%d\n",mode);
#endif
vdd_str(VDD_LOAD_INI_FILE, exec_dir);
vdd_str(VDD_LOAD_INI_FILE, ini_fname);
vdd_str(VDD_LOAD_INI_SECTION, getfname(arg[0]));
......@@ -610,9 +610,20 @@ int main(int argc, char **argv)
strcpy(p,"RET");
if((fp=fopen(argv[1],"w+"))==NULL) {
fprintf(stderr,"!Error opening %s\n",argv[1]);
return(3);
} else {
fprintf(fp,"%d",i);
fclose(fp);
}
fprintf(fp,"%d",i);
strcpy(p,"ERR");
if(i == -1) {
if((fp=fopen(argv[1],"w+"))==NULL) {
fprintf(stderr,"!Error opening %s\n",argv[1]);
} else {
fprintf(fp,"%d\n%s\n", errno, strerror(errno));
fclose(fp);
}
} else
remove(argv[1]);
/* Restore original ISRs */
_dos_setvect(0x14,oldint14);
......
......@@ -69,8 +69,11 @@ void sbbs_t::showfileinfo(file_t* f, bool show_extdesc)
if(f->author_org)
bprintf(P_TRUNCATE, text[FiGroup], f->author_org);
char* p = f->hdr.attr&MSG_ANONYMOUS ? text[UNKNOWN_USER] : f->from;
if(p != NULL && *p != '\0')
if(p != NULL && *p != '\0') {
bprintf(P_TRUNCATE, text[FiUploadedBy], p);
if(f->from_prot != NULL)
bprintf(P_TRUNCATE, " via %s ", f->from_prot);
}
if(is_op) {
*tmp = '\0';
if(f->from_ip != NULL)
......@@ -79,10 +82,6 @@ void sbbs_t::showfileinfo(file_t* f, bool show_extdesc)
SAFEPRINTF(tmp2, "%s ", f->from_host);
SAFECAT(tmp, tmp2);
}
if(f->from_prot != NULL) {
SAFEPRINTF(tmp2, "via %s ", f->from_prot);
SAFECAT(tmp, tmp2);
}
if(*tmp != '\0')
bprintf(P_TRUNCATE, text[FiUploadedBy], tmp);
}
......
......@@ -13,21 +13,9 @@
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
......@@ -55,24 +43,24 @@ WORD uart_io_base = UART_COM1_IO_BASE; /* COM1 */
BYTE uart_irq = UART_COM1_IRQ;
BYTE uart_ier_reg = 0;
BYTE uart_lcr_reg = UART_LCR_8_DATA_BITS;
BYTE uart_mcr_reg = UART_MCR_RTS | UART_MCR_DTR;
BYTE uart_mcr_reg = UART_MCR_DTR;
BYTE uart_lsr_reg = UART_LSR_EMPTY_DATA | UART_LSR_EMPTY_XMIT;
BYTE uart_msr_reg = UART_MSR_CTS | UART_MSR_DSR;
BYTE uart_scratch_reg = 0;
BYTE uart_divisor_latch_lsb = 0x03; /* 38400 */
BYTE uart_divisor_latch_msb = 0x00;
BYTE uart_fifo_enabled = 0;
#if defined (_DEBUG)
int log_level = LOG_DEBUG;
#else
int log_level = LOG_WARNING;
#endif
// Notice: re-initialize global variables in VDDInitialize for NTVDMx64 and pre-Vista versions of Windows
int log_level = LOG_INFO;
BOOL virtualize_uart=FALSE;
double yield_interval=1.0;
BOOL dcd_changed = FALSE;
BOOL hangup_supported=TRUE;
HANDLE hangup_event=NULL;
HANDLE hungup_event=NULL;
HANDLE carrier_event=NULL;
HANDLE interrupt_event=NULL;
HANDLE rdslot=INVALID_HANDLE_VALUE;
HANDLE wrslot=INVALID_HANDLE_VALUE;
......@@ -108,7 +96,7 @@ static void lprintf(int level, const char *fmt, ...)
void hangup()
{
if(hangup_supported && hangup_event!=NULL) {
lprintf(LOG_DEBUG,"Hanging-up at application request");
lputs(LOG_DEBUG,"Hanging-up at application request");
SetEvent(hangup_event);
}
}
......@@ -166,7 +154,7 @@ void parse_ini(char* program)
/* Mutex-protected pending interrupt "queue" */
int pending_interrupts = 0;
volatile int pending_interrupts = 0;
CRITICAL_SECTION interrupt_mutex;
void set_interrupt_pending(BYTE intr, BOOL assert)
......@@ -192,18 +180,20 @@ void set_interrupt_pending(BYTE intr, BOOL assert)
void _cdecl interrupt_thread(void *arg)
{
HANDLE handles[] = {interrupt_event, hungup_event};
HANDLE handles[] = {interrupt_event, carrier_event};
while(1) {
DWORD handle_count = (uart_msr_reg & UART_MSR_DCD) ? 2 : 1;
DWORD handle_count = (carrier_event == NULL) ? 1 : 2;
DWORD result = WaitForMultipleObjects(handle_count, handles, /* waitAll */FALSE, INFINITE);
if(result == WAIT_OBJECT_0 + 1) {
lprintf(LOG_DEBUG, "Hangup detected in " __FUNCTION__);
uart_msr_reg &=~ UART_MSR_DCD;
lputs(LOG_DEBUG, "Carrier change detected in " __FUNCTION__);
dcd_changed = TRUE;
assert_interrupt(UART_IER_MODEM_STATUS);
continue;
}
if(result != WAIT_OBJECT_0)
if(result != WAIT_OBJECT_0) {
lprintf(LOG_NOTICE, "Waiting for interrupt returned %ld", result);
break;
}
if((uart_ier_reg&pending_interrupts) != 0) {
lprintf(LOG_DEBUG,"VDDSimulateInterrupt (pending: %02X) - IER: %02X"
,pending_interrupts, uart_ier_reg);
......@@ -215,7 +205,7 @@ void _cdecl interrupt_thread(void *arg)
* the interrupt is enabled."
*/
if(pending_interrupts==0 && uart_ier_reg&UART_IER_TX_EMPTY)
pending_interrupts|=UART_IER_TX_EMPTY;
assert_interrupt(UART_IER_TX_EMPTY);
#endif
}
}
......@@ -225,11 +215,11 @@ void _cdecl input_thread(void* arg)
char buf[LINEAR_RX_BUFLEN];
int count;
lprintf(LOG_DEBUG,"input_thread: started");
lputs(LOG_DEBUG,"input_thread: started");
while(1) {
count=RingBufFree(&rdbuf);
if(count<1) {
lprintf(LOG_WARNING,"input_thread: input buffer full!");
lputs(LOG_WARNING,"input_thread: input buffer full!");
YIELD();
continue;
}
......@@ -237,7 +227,7 @@ void _cdecl input_thread(void* arg)
count=sizeof(buf);
if(!ReadFile(rdslot,buf,count,&count,NULL)) {
if(GetLastError()==ERROR_HANDLE_EOF) { /* closed by VDD_CLOSE */
lprintf(LOG_INFO,"input_thread: ReadFile returned EOF");
lputs(LOG_INFO,"input_thread: ReadFile returned EOF");
break;
}
lprintf(LOG_ERR,"!input_thread: ReadFile Error %d (size=%d)"
......@@ -245,7 +235,7 @@ void _cdecl input_thread(void* arg)
continue;
}
if(count==0) {
lprintf(LOG_ERR,"!input_thread: ReadFile read 0");
lputs(LOG_ERR,"!input_thread: ReadFile read 0");
continue;
}
RingBufWrite(&rdbuf,buf,count);
......@@ -257,18 +247,18 @@ void _cdecl input_thread(void* arg)
assert_interrupt(UART_IER_RX_DATA); /* assert rx data interrupt */
}
}
lprintf(LOG_DEBUG,"input_thread: terminated");
lputs(LOG_DEBUG,"input_thread: terminated");
}
unsigned vdd_read(BYTE* p, unsigned count)
{
count=RingBufRead(&rdbuf,p,count);
if(count==0) {
lprintf(LOG_ERR,"!VDD_READ: RingBufRead read 0, waiting");
lputs(LOG_ERR,"!VDD_READ: RingBufRead read 0, waiting");
if(sem_trywait_block(&rdbuf.sem, READ_TIMEOUT) != 0)
lprintf(LOG_ERR,"!VDD_READ: rdbuf sem timeout");
lputs(LOG_ERR,"!VDD_READ: rdbuf sem timeout");
count = RingBufRead(&rdbuf,p,count);
lprintf(LOG_ERR,"!VDD_READ: RingBufRead read 0 (after wait)");
lputs(LOG_ERR,"!VDD_READ: RingBufRead read 0 (after wait)");
}
return(count);
......@@ -346,22 +336,35 @@ VOID uart_wrport(WORD port, BYTE data)
if(uart_lcr_reg&UART_LCR_DLAB) {
uart_divisor_latch_msb = data;
lprintf(LOG_DEBUG,"set divisor latch high byte: %02X", data);
} else
} else {
uart_ier_reg = data;
lprintf(LOG_INFO, "Set IER to %02X", data);
}
assert_interrupt(UART_IER_TX_EMPTY); /* should this be re-asserted for all writes? */
break;
case UART_IIR: /* FCR not supported */
case UART_FCR:
uart_fifo_enabled = data & UART_FCR_ENABLE_FIFO;
lprintf(LOG_INFO, "Set FCR to %02X", data);
break;
case UART_LCR:
uart_lcr_reg = data;
lprintf(LOG_INFO, "Set LCR to %02X", data);
break;
case UART_MCR:
uart_mcr_reg = data;
if((uart_mcr_reg&UART_MCR_DTR) == 0) /* Dropping DTR (i.e. "hangup") */
hangup();
if((uart_mcr_reg & UART_MCR_RTS) && RingBufFull(&rdbuf) > 0) {
assert_interrupt(UART_IER_RX_DATA);
} else {
deassert_interrupt(UART_IER_RX_DATA);
uart_lsr_reg &= ~UART_LSR_DATA_READY;
}
lprintf(LOG_INFO, "Set MCR to %02X", data);
break;
case UART_SCRATCH:
uart_scratch_reg = data;
lprintf(LOG_INFO, "Set scratch register to %02X", data);
break;
default:
lprintf(LOG_ERR,"UNSUPPORTED register: %u", reg);
......@@ -380,7 +383,7 @@ VOID uart_rdport(WORD port, PBYTE data)
switch(reg) {
case UART_BASE:
if(uart_lcr_reg&UART_LCR_DLAB) {
lprintf(LOG_DEBUG,"reading divisor latch LSB");
lputs(LOG_DEBUG,"reading divisor latch LSB");
*data = uart_divisor_latch_lsb;
break;
}
......@@ -392,7 +395,7 @@ VOID uart_rdport(WORD port, PBYTE data)
} else
*data=0;
if(avail==0) {
lprintf(LOG_DEBUG,"No more data");
lputs(LOG_DEBUG,"No more data");
/* Clear the data ready bit in the LSR */
uart_lsr_reg &= ~UART_LSR_DATA_READY;
......@@ -403,12 +406,13 @@ VOID uart_rdport(WORD port, PBYTE data)
break;
case UART_IER:
if(uart_lcr_reg&UART_LCR_DLAB) {
lprintf(LOG_DEBUG,"reading divisor latch MSB");
lputs(LOG_DEBUG,"reading divisor latch MSB");
*data = uart_divisor_latch_msb;
} else
*data = uart_ier_reg;
break;
case UART_IIR:
{
/* Report IIR based on *priority* of pending interrupts */
if(pending_interrupts & UART_IER_LINE_STATUS)
*data = UART_IIR_LINE_STATUS;
......@@ -424,28 +428,41 @@ VOID uart_rdport(WORD port, PBYTE data)
*data = UART_IIR_MODEM_STATUS;
else
*data = UART_IIR_NONE;
if(pending_interrupts)
SetEvent(interrupt_event);
if(uart_fifo_enabled)
*data |= UART_IIR_FIFO_ENABLED;
lprintf(LOG_INFO, "IIR: %02X (pending: %02X)", *data, pending_interrupts);
break;
}
case UART_LCR:
*data = uart_lcr_reg;
lprintf(LOG_INFO, "LCR: %02X", uart_lcr_reg);
break;
case UART_MCR:
*data = uart_mcr_reg;
lprintf(LOG_INFO, "MCR: %02X", uart_mcr_reg);
break;
case UART_LSR:
*data = uart_lsr_reg;
maybe_yield();
/* Clear line status interrupt pending */
deassert_interrupt(UART_IER_LINE_STATUS);
lprintf(LOG_INFO, "LSR: %02X", *data);
break;
case UART_MSR:
if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
uart_msr_reg &=~ UART_MSR_DCD;
uart_msr_reg &= ~UART_MSR_DCD;
else
uart_msr_reg |= UART_MSR_DCD;
if(dcd_changed)
uart_msr_reg |= UART_MSR_DCD_CHANGE;
else
uart_msr_reg &= ~UART_MSR_DCD_CHANGE;
dcd_changed = FALSE;
*data = uart_msr_reg;
maybe_yield();
/* Clear modem status interrupt pending */
deassert_interrupt(UART_IER_MODEM_STATUS);
lprintf(LOG_DEBUG, "MSR: %02X", *data);
break;
case UART_SCRATCH:
*data = uart_scratch_reg;
......@@ -553,6 +570,16 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
,GetLastError(),str);
}
sprintf(str,"sbbsexec_carrier%d",node_num);
carrier_event=OpenEvent(
EVENT_ALL_ACCESS, /* access flag */
FALSE, /* inherit flag */
str); /* pointer to event-object name */
if(carrier_event==NULL) {
lprintf(LOG_WARNING,"!VDD_OPEN: Error %d opening %s"
,GetLastError(),str);
}
status_poll=0;
inbuf_poll=0;
online_poll=0;
......@@ -571,7 +598,12 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
VDDInstallIOHook((HANDLE)getAX(), 1, &PortRange, &IOHandlers);
interrupt_event=CreateEvent(NULL,FALSE,FALSE,NULL);
interrupt_event = CreateEvent(
NULL // pointer to security attributes
,FALSE // flag for manual-reset event (TRUE = level-trigger, FALSE = edge-trigger)
,FALSE // flag for initial state
,NULL // pointer to event-object name
);
InitializeCriticalSection(&interrupt_mutex);
_beginthread(interrupt_thread, 0, NULL);
......@@ -593,16 +625,35 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
lprintf(LOG_INFO," wrote=%u bytes (in %u calls)",bytes_written,writes);
if(virtualize_uart) {
lprintf(LOG_INFO,"Uninstalling Virtualizaed UART IO Hook");
lputs(LOG_INFO,"Uninstalling Virtualizaed UART IO Hook");
VDDDeInstallIOHook((HANDLE)getAX(), 1, &PortRange);
DeleteCriticalSection(&interrupt_mutex);
}
CloseHandle(rdslot);
CloseHandle(wrslot);
if(hungup_event!=NULL)
CloseHandle(hungup_event);
if(hangup_event!=NULL)
if(rdslot != INVALID_HANDLE_VALUE) {
CloseHandle(rdslot);
rdslot = INVALID_HANDLE_VALUE;
}
if(wrslot != INVALID_HANDLE_VALUE) {
CloseHandle(wrslot);
wrslot = INVALID_HANDLE_VALUE;
}
if(hangup_event != NULL) {
CloseHandle(hangup_event);
hangup_event = NULL;
}
if(hungup_event != NULL) {
CloseHandle(hungup_event);
hungup_event = NULL;
}
if(carrier_event != NULL) {
CloseHandle(carrier_event);
carrier_event = NULL;
}
if(interrupt_event != NULL) {
CloseHandle(interrupt_event);
interrupt_event = NULL;
}
#if 0 /* This isn't strictly necessary...
and possibly the cause of a NULL dereference in the input_thread */
......@@ -708,7 +759,7 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
break;
case VDD_OUTBUF_PURGE:
lprintf(LOG_WARNING,"!VDD_OUTBUF_PURGE: NOT IMPLEMENTED");
lputs(LOG_WARNING,"!VDD_OUTBUF_PURGE: NOT IMPLEMENTED");
retval=0;
break;
......@@ -771,21 +822,32 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
/* Load exec/sbbsexec.ini first (setting default values) */
count = getCX();
p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI())
,count,FALSE);
iniFileName(ini_fname, sizeof(ini_fname), p, INI_FILENAME);
,count,FALSE);
lprintf(LOG_INFO, "LOAD_INI_FILE: %s", p);
if(isdir(p))
iniFileName(ini_fname, sizeof(ini_fname), p, INI_FILENAME);
else
SAFECOPY(ini_fname, p);
if((fp=fopen(ini_fname,"r"))!=NULL) {
iniFreeStringList(ini);
ini=iniReadFile(fp);
fclose(fp);
parse_ini(ROOT_SECTION);
lprintf(LOG_INFO, "Parsed root section of: %s", ini_fname);
}
/* Load cwd/sbbsexec.ini second (over-riding default values) */
GetCurrentDirectory(sizeof(cwd),cwd);
iniFileName(ini_fname, sizeof(ini_fname), cwd, INI_FILENAME);
if(getfname(p) == p)
iniFileName(ini_fname, sizeof(ini_fname), cwd, p);
else
iniFileName(ini_fname, sizeof(ini_fname), cwd, INI_FILENAME);
if((fp=fopen(ini_fname,"r"))!=NULL) {
iniFreeStringList(ini);
ini=iniReadFile(fp);
fclose(fp);
parse_ini(ROOT_SECTION);
lprintf(LOG_INFO, "Parsed root section of: %s", ini_fname);
}
}
break;
......@@ -821,6 +883,8 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
__declspec(dllexport) BOOL __cdecl VDDInitialize(IN PVOID hVDD, IN ULONG Reason,
IN PCONTEXT Context OPTIONAL)
{
{
log_level = LOG_INFO;
lputs(LOG_INFO, __FUNCTION__);
return TRUE;
}
......@@ -61,7 +61,10 @@ const char* uart_reg_desc[] = { "base", "IER", "IIR", "LCR", "MCR", "LSR", "MSR"
#define UART_IIR_NONE 0x01 /* Bit 0=0, Interrupt Pending */
#define UART_IIR_TX_EMPTY 0x02 /* THRE (Transmit Holding Register Empty) */
#define UART_IIR_RX_DATA 0x04
#define UART_IIR_LINE_STATUS 0x06
#define UART_IIR_LINE_STATUS 0x06 /* "This is usually an error condition" */
#define UART_IIR_FIFO_ENABLED 0xc0 /* Bits 7 and 6 */
#define UART_FCR_ENABLE_FIFO (1<<0)
#define UART_LSR_FIFO_ERROR (1<<7)
#define UART_LSR_EMPTY_DATA (1<<6)
......
This diff is collapsed.

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32106.194
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vdmodem", "vdmodem.vcxproj", "{20051597-6298-4098-8F26-E408C2880FE4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{20051597-6298-4098-8F26-E408C2880FE4}.Debug|x86.ActiveCfg = Debug|Win32
{20051597-6298-4098-8F26-E408C2880FE4}.Debug|x86.Build.0 = Debug|Win32
{20051597-6298-4098-8F26-E408C2880FE4}.Release|x86.ActiveCfg = Release|Win32
{20051597-6298-4098-8F26-E408C2880FE4}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9F30FE81-9971-48D0-AC51-EE3F15248CB0}
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{20051597-6298-4098-8f26-e408c2880fe4}</ProjectGuid>
<RootNamespace>svdmodem</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\build\undeprecate.props" />
<Import Project="..\xpdev\xpdev_mt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\build\undeprecate.props" />
<Import Project="..\xpdev\xpdev_mt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\build\undeprecate.props" />
<Import Project="..\xpdev\xpdev_mt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\build\undeprecate.props" />
<Import Project="..\xpdev\xpdev_mt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<TargetName>svdm</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>svdm</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<TargetName>svdm</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>svdm</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\xpdev\genwrap.c" />
<ClCompile Include="..\xpdev\sockwrap.c" />
<ClCompile Include="vdmodem.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file