--- sbbs/sbbs3/dosxtrn/dosxtrn.c 2018/04/24 16:39:34 1.1 +++ sbbs/sbbs3/dosxtrn/dosxtrn.c 2018/04/24 16:41:15 1.1.1.2 @@ -2,7 +2,7 @@ /* Synchronet External DOS Program Launcher (16-bit MSVC 1.52c project) */ -/* $Id: dosxtrn.c,v 1.1 2018/04/24 16:39:34 root Exp $ */ +/* $Id: dosxtrn.c,v 1.1.1.2 2018/04/24 16:41:15 root Exp $ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * @@ -61,6 +61,8 @@ str[c]=0; short vdd=0; BYTE node_num=0; int mode=0; +DWORD nodata=0; +DWORD polls_before_yield=10; void (interrupt *oldint14)(); void (interrupt *oldint16)(); @@ -97,6 +99,10 @@ static int vdd_op(BYTE op) { int retval; +#if FALSE /* disable yield? */ + if(op==VDD_YIELD) + return(0); +#endif _asm { push bx mov ax, vdd @@ -111,6 +117,8 @@ static int vdd_op(BYTE op) return(retval); } +#if 0 + char win95int14[]={ 0xCF // IRET ,0x90 // NOP @@ -123,6 +131,53 @@ char win95int14[]={ ,0x1B // FOSSIL highest func supported }; +#else + +union REGS inregs; +struct SREGS sregs; +BOOL inside_int14=FALSE; + +/* This function is only necessary for naughty programs that call the vector + directly instead of issuing an interrupt +*/ +void interrupt win95int14( + unsigned _es, unsigned _ds, + unsigned _di, unsigned _si, + unsigned _bp, unsigned _sp, + unsigned _bx, unsigned _dx, + unsigned _cx, unsigned _ax, + unsigned flags ) +{ + union REGS outregs; + + /* prevent recursion, just incase the VXD isn't handling int14h */ + if(inside_int14) + return; + + inside_int14=TRUE; + + inregs.x.ax=_ax; + inregs.x.bx=_bx; + inregs.x.cx=_cx; + inregs.x.dx=_dx; + inregs.x.si=_si; + inregs.x.di=_di; + inregs.x.cflag=flags; + + sregs.es=_es; + sregs.ds=_ds; + + int86x(0x14,&inregs,&outregs,&sregs); + + /* FOSSIL driver only touches these AX and BX */ + _ax= outregs.x.ax; + _bx= outregs.x.bx; + + inside_int14=FALSE; +} + +#endif + void vdd_getstatus(vdd_status_t* status) { WORD buf_seg; @@ -132,8 +187,6 @@ void vdd_getstatus(vdd_status_t* status) memset(status,0,sizeof(vdd_status_t)); } -#if 1 - WORD PortStatus() { WORD status=0x0008; // AL bit 3 (change in DCD) always set @@ -160,47 +213,6 @@ WORD PortStatus() return(status); } -#else - -WORD PortStatus() -{ - WORD status=0x0008; // AL bit 3 (change in DCD) always set - static poll; - static online=1; - static outbuf_full; - static outbuf_size; - - if(!poll) - outbuf_size=vdd_op(VDD_OUTBUF_SIZE); - - if(!(poll%500)) { - online=vdd_op(VDD_ONLINE); - outbuf_full=vdd_op(VDD_OUTBUF_FULL); - } - - if(online) // carrier detect - status|=0x0080; // DCD - - if(vdd_op(VDD_INBUF_FULL)) // receive data ready - status|=0x0100; // RDA - -// if(vm->overrun) // overrun error detected -// status|=0x0200; // OVRN - - if(outbuf_full - =polls_before_yield) + vdd_op(VDD_YIELD); break; case 0x04: /* initialize */ _ax=0x1954; /* magic number = success */ @@ -274,21 +292,32 @@ void interrupt winNTint14( ch=_ax&0xff; _asm mov buf_seg, ss; _ax = vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch); + nodata=0; break; case 0x0C: // non-destructive read-ahead vdd_getstatus(&vdd_status); if(!vdd_status.inbuf_full) { _ax=0xffff; // no char available + vdd_op(VDD_YIELD); break; } _asm mov buf_seg, ss; _ax = vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch); + if(_ax == 0) + vdd_op(VDD_YIELD); + else + nodata=0; break; case 0x18: /* read bock */ _ax = vdd_buf(VDD_READ, _cx, _es, _di); + if(_ax == 0) + vdd_op(VDD_YIELD); + else + nodata=0; break; case 0x19: /* write block */ _ax = vdd_buf(VDD_WRITE, _cx, _es, _di); + nodata=0; break; case 0x1B: /* driver info */ vdd_getstatus(&vdd_status); @@ -297,6 +326,10 @@ void interrupt winNTint14( info.outbuf_size=vdd_status.outbuf_size; info.outbuf_free=info.outbuf_size-vdd_status.outbuf_full; + if(vdd_status.inbuf_full==vdd_status.outbuf_full==0 + && ++nodata>=polls_before_yield) + vdd_op(VDD_YIELD); + p = _MK_FP(_es,_di); wr=sizeof(info); if(wr>_cx) @@ -328,8 +361,11 @@ void interrupt winNTint16( _asm mov buf_seg, ss; vdd_buf(VDD_READ, 1, buf_seg, (WORD)&ch); _ax=ch; + nodata=0; return; - } + } + if(++nodata>=polls_before_yield) + vdd_op(VDD_YIELD); break; case 0x01: // Get keyboard status case 0x11: // Get enhanced keyboard status @@ -338,8 +374,11 @@ void interrupt winNTint16( vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch); flags&=~(1<<6); // clear zero flag _ax=ch; + nodata=0; return; - } + } + if(++nodata>=polls_before_yield) + vdd_op(VDD_YIELD); break; } @@ -360,6 +399,7 @@ void interrupt winNTint29( ch=_ax&0xff; _asm mov buf_seg, ss vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch); + nodata=0; _chain_intr(oldint29); } @@ -386,21 +426,21 @@ int main(int argc, char **argv) ,"This program is for the internal use of Synchronet BBS only\n"); return(1); } -#if 1 + strcpy(dll,argv[0]); p=strrchr(dll,'\\'); if(p!=NULL) *(p+1)=0; strcat(dll,"SBBSEXEC.DLL"); DllName=dll; -#endif - if(argc>2 && !strcmp(argv[2],"NT")) { + if(argc>2 && !strcmp(argv[2],"NT")) NT=TRUE; - if(argc>3) - node_num=atoi(argv[3]); - if(argc>4) - mode=atoi(argv[4]); - } + if(argc>3) + node_num=atoi(argv[3]); + if(argc>4) + mode=atoi(argv[4]); + if(argc>5) + polls_before_yield=atol(argv[5]); if((fp=fopen(argv[1],"r"))==NULL) { fprintf(stderr,"!Error opening %s\n",argv[1]); @@ -478,7 +518,7 @@ int main(int argc, char **argv) if(mode&SBBSEXEC_MODE_DOS_OUT) _dos_setvect(0x29,winNTint29); } - else /* Windows 95/98/Millennium */ + else if(mode==SBBSEXEC_MODE_FOSSIL) /* Windows 95/98/Millennium */ _dos_setvect(0x14,(void(interrupt *)())win95int14); _heapmin();