home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / windows / newcom.zip / NEWCOM.MOD
Text File  |  1990-11-08  |  10KB  |  279 lines

  1. /***************************************************************
  2.  
  3.                 NEWCOM1.MOD
  4.  
  5.        Buffered I/O Communications Routines for WWIV
  6.          Makes WWIV noticeably faster to the users!
  7.             Especially when multitasking!
  8.  
  9.            By One Eyed Willy 1 @18852 WWIVLink
  10.  
  11.  
  12.     WWIV simply excels other BBS softwares in many ways.  One
  13. of which is speed.  However, WWIV is capable of even more speed.
  14. An extra increase can be acheived by using comm routines
  15. that buffer both incoming and outgoing data.
  16.  
  17.     If outgoing data is buffered, then the computer can be sending
  18. data while doing something else such as reading the next message from
  19. the hard disk.  This tactic is often used by external protocols such
  20. as DSZ, but why not a BBS?  WildCat! Software has had such routines
  21. installed.  So its WWIV's turn.
  22.  
  23.     When multitasking, buffered comm routines make multitasking
  24. virutally unnoticeable.  Ever notice how DSZ USUALLY gets 23x CPS, even
  25. though you may set Desqview's clock ticks to 5:1, the BBS having 1?
  26. Well, now your BBS can be the same way.  Another big advantage is
  27. when you have a slow hard disk.  With the standard routines, the user
  28. normally sees the title printed, then has to wait a breif second while
  29. the message is read into memory.  The buffered routines will allow the
  30. BBS to be printing the title WHILE the message is being read.  Much
  31. faster!
  32.  
  33.     One drawback on Wildcat! boards is that these types of routines
  34. make messages un-space-abortable.  This is due to an incredible lack of
  35. common sense by the authors.  A very small addition will handle this
  36. problem for the WWIV software.
  37.  
  38. On with the mod...
  39.  
  40.     I cannot say I owe these comm routines to anybody.  I have looked
  41. high and low on all the programming BBSes in the area, and none could
  42. supply these types of routines.  After doing some DEBUG disassembly of
  43. DSZ.COM, I caught the general gist of how you deal with these types of
  44. routines, and proceeded down the long hard road of trial-and-error
  45. testing.  I was about to give the project up entirely, but I had one
  46. last idea, which turned out to be the key to the operation of these
  47. routines.  So now I'm proud to present: NEWCOM1.MOD.
  48.  
  49.     You may include these routines in any developed software
  50. package without any sort of "tribute".  These did take me many
  51. hours of testing, however, I beleive they're for the good of computing,
  52. and do not require any special registration or recognition.
  53.  
  54.     This mod will load up an output buffer before slowing down
  55. to the normal 2400 baud that a sysop is used to seeing.  The SysOp's
  56. side becomes very fast, but remember, the user's side is always trying
  57. to catch up.  A whole message might appear on your side that hasn't
  58. gotten to the user's side yet.
  59.  
  60. >>> MAKE SURE YOU MAKE A BACKUP OF YOUR SOURCE BEFORE INSTALLING! <<<
  61.  
  62.     These type of routines are very fast indeed, but do not work on
  63. some systems with slow UART chips.  Of course, DSZ uses this same type
  64. of output, so if DSZ works, this should work as well.  It has not yet
  65. been tested with 9600+ baud modems, I have no idea how it will react
  66. with such speed requirements.  It should not pose problems, however,
  67. may not increase the speed.
  68.  
  69. ==== Step 1: VARS.H
  70.  
  71. To start, we must first create ourselves the actual buffer.  Load up
  72. VARS.H, and search for the following, near the top:
  73.  
  74. volatile int head,tail;
  75. volatile char buffer[max_buf];
  76.  
  77. and change them to read:
  78.  
  79. volatile int head,tail,ohead,otail;
  80. volatile char buffer[max_buf],obuffer[max_buf];
  81.  
  82. ==== Step 2: (The Dreaded) VARDEC.H
  83.  
  84. Now we need to lower the output buffer.  Might as well lower the input buffer
  85. as well, I don't think anybody's gonna type 1024 letters while the BBS isn't
  86. paying attention.  This step is optional, however, not doing this will result
  87. in an output buffer that is too large, and will make things a bit unabortable.
  88. Even though the mod will erase the buffer when it detects a "Space abort", if
  89. the SysOp's side has reached a prompt, "Space" no longer is aborting anything.
  90. 256 bytes is definitely reasonable.  If your system multitasks very jerkily
  91. or are using a high speed modem, however, I suggest 512.
  92.  
  93. So, load up VARDEC.H, and search for:
  94.  
  95. #define max_buf 1024
  96.  
  97. and change it to read:
  98.  
  99. #define max_buf 256
  100.  
  101. ==== Step 3: COM.C
  102.  
  103. First thing to do in COM.C is add in the "extrn"s so the compiler is aware
  104. of the new buffer you have put into VARS.H.  Load up COM.C, and search for:
  105.  
  106. extern volatile int head,tail;
  107. extern volatile char buffer[max_buf];
  108.  
  109. and as in Step 1, change them to read:
  110.  
  111. extern volatile int head,tail,ohead,otail;
  112. extern volatile char buffer[max_buf],obuffer[max_buf];
  113.  
  114. Now, we must remove Wayne's outdated and slow routines, and put in the
  115. new set of routines.  Remove the following functions:
  116.  
  117. void far interrupt async_isr ()
  118. void outcomch(char ch)
  119. char get1c()
  120. void initport(int port_num)
  121.  
  122. And replace them with the following code:
  123.  
  124. void far interrupt async_isr()
  125. {
  126.   static int i;
  127.  
  128.   enable();                          /* Re-Enable Interrupts           */
  129.   for(;;) {
  130.     i=inportb(base+2);               /* Why was the handler called?    */
  131.     if (i & 1)  {                    /* Anything more to do?           */
  132.       outportb(0x20,0x20);           /* No? Reset INT Controller.      */
  133.       return;                        /* Resume processing              */
  134.     }
  135.     switch (i) {
  136.     case 0:                          /* Modem Status Changed           */
  137.       inportb(base+6);               /* Just read it in, its not useful*/
  138.       break;
  139.     case 2:                          /* Ready to output character      */
  140.       if (otail!=ohead) {            /* Is there a character to send?  */
  141.     outportb(base,obuffer[otail++]);  /* Send it                   */
  142.     if (otail==max_buf)
  143.       otail=0;
  144.       }
  145.       break;
  146.     case 4:                          /* Character waiting to be read.  */
  147.       buffer[head++] = inportb(base);     /* Read it                   */
  148.       if (head==max_buf)
  149.     head=0;
  150.       break;
  151.     case 6:                          /* Line Status has changed.       */
  152.       inportb(base+5);               /* Again, useless, just read it   */
  153.       break;
  154.     }
  155.   }
  156. }
  157.  
  158. void outcomch(char ch)
  159. {
  160.   enable();                         /* Make sure data can be outputted. */
  161.   /* If buffer is full, wait for an available position */
  162.   while(otail-1==ohead || (ohead==max_buf-1 && otail==0));
  163.   /* Make sure nothing happens while modifying the buffer */
  164.   disable();
  165.   obuffer[ohead++]=ch;
  166.   if (ohead==max_buf)
  167.     ohead=0;
  168.   enable();               /* Resume buffer processing */
  169.   /* Enable output interrupt.  Is shut off when inactive. */
  170.   outportb(base+1,0x0f);
  171. }
  172.  
  173.  
  174. char get1c()
  175. {
  176.   char c;
  177.  
  178.   if (head!=tail) {
  179.     c=buffer[tail++];
  180.     if (tail==max_buf)
  181.       tail=0;
  182.     return(c);
  183.   } else
  184.     return(0);
  185. }
  186.  
  187. void set_up_irq()
  188. {
  189.   int i,m;
  190.  
  191.   setvect(8+async_irq,async_isr);              /* Set communications handler */
  192.   disable();                                   /* Disable during initialization */
  193.   outportb(base+3, inportb(base+3) & 0x7f);    /* Turn on DTR and RTS      */
  194.   i=inportb(base+5);                           /* Read status              */
  195.   i=inportb(base);                             /* Read character           */
  196.   i=inportb(0x21);                             /* Get interrupt settings   */
  197.   m=(1<<async_irq) ^ 0xff;                     /* Turn on the modem's IRQ  */
  198.   outportb(0x21,i & m);                        /* Set new settings.        */
  199.   i=inportb(base+4);                           /* Enable Interrupt Gate    */
  200.   outportb(base+4,i | 0x0b);
  201.   outportb(base+1,0x0f);                       /* Turn on all IRQ Events   */
  202.   outportb(0x20,0x20);                         /* Clear INT chip           */
  203.   enable();                                    /* Reenable all ints        */
  204. }
  205.  
  206. void dumpo()
  207. /* Dump output buffer */
  208. {
  209.   disable();
  210.   ohead=otail=0;
  211.   enable();
  212. }
  213.  
  214. void initport(int port_num)
  215. {
  216.   base = syscfg.com_base[port_num];
  217.   async_irq = syscfg.com_ISR[port_num];
  218.   head = tail = ohead = otail = 0;
  219.   set_up_irq();
  220. }
  221.  
  222. ==== Step 4: EXTERN.C
  223.  
  224. Whenever the BBS runs an external program, there's no guarantee that
  225. when the program returns, the BBS will still have control of the modem.
  226. To handle this, Wayne has two functions for initializing.  However, the
  227. original initport function doesn't need to do the "destructive" things
  228. that the old one did, as they are done at other times.  So, just replace
  229. the initporte() function with this:
  230.  
  231. void initporte(int port_num)
  232. {
  233.   int temp;
  234.  
  235.   if (!ok_modem_stuff)
  236.     return;
  237.   initport(port_num);
  238. }
  239.  
  240. Whoa, hard, eh?
  241.  
  242. ==== Step 5: BBSUTL.C
  243.  
  244. Now you have the comm routines in your bbs software. One more
  245. thing to do to make messages space-abortable.  Load up BBSUTL.C
  246. and in void checka(), replace to make it read:
  247.  
  248. void checka(int *abort, int *next)
  249. {
  250.   char ch;
  251.  
  252.   while ((!empty()) && (!(*abort)) && (!hangup)) {
  253.     checkhangup();
  254.     ch=inkey();
  255.     lines_listed=0;
  256.     switch(ch) {
  257.       case 14:
  258.     dumpo();
  259.     *next=1;
  260.       case 3:
  261.       case 32:
  262.       case 24:
  263.     *abort=1;
  264.     dumpo();
  265.     break;
  266.       case 'P':
  267.       case 'p':
  268.       case 19:
  269.         ch=getkey();
  270.         break;
  271.     }
  272.   }
  273. }
  274.  
  275. And that should do it.  To multitasking maniacs - Enjoy the freedom
  276. to compile WWIV without worrying about your users complaining about
  277. speed problems!
  278.  
  279.