home *** CD-ROM | disk | FTP | other *** search
/ Deathday Collection / dday.bin / serial / modemdm / doomodem.c next >
C/C++ Source or Header  |  1994-02-17  |  7KB  |  278 lines

  1. /*
  2.     DOOMODEM
  3.     Configuration utility for DOOM 1.2 modem-vs-modem play
  4.     v1.0ß  2/18/94
  5.  
  6.     Changes the default port and IRQ settings of the SERSETUP.EXE program!
  7.  
  8.     USE AT YOUR OWN RISK and back up your original SERSETUP.EXE first.
  9.     I assume no responsibility for anything this program directly or
  10.     indirectly does.
  11.  
  12.     JoSHua Lehan
  13.     jlehan@galaxy.csc.calpoly.edu
  14. */
  15.  
  16. /*
  17.     Borland C++ 3.1
  18.     Set tab stops to 3 spaces to properly indent code
  19. */
  20.  
  21. /*
  22.     written from 1:30 AM to 6:30 AM so there may be bugs...
  23.  
  24.     I have an 8250 UART, hopefully DOOM does not change the port
  25.     address and IRQ's when referring to different types of UART's
  26.     or any other system changes.  Here's the info, so if this program
  27.     does not work for some reason, you can find what went wrong and
  28.     fix it...  email me (jlehan@galaxy.csc.calpoly.edu) if you can
  29.     improve this program!
  30.  
  31.     At offset 18378 (47CAh) in the SERSETUP.EXE program, the default
  32.     port addresses and IRQ's are stored as 16-bit words (LSB first).
  33.     This is the order they appear in:
  34.  
  35.                  1Port  2Port  3Port  4Port  1IRQ   2IRQ   3IRQ   4IRQ
  36.     Offset    47CAh  47CCh  47CEh  47D0h  47D2h  47D4h  47D6h  47D8h
  37.     Defaults  F8 03  F8 02  E8 03  E8 02  04 00  03 00  04 00  03 00
  38.  
  39.     All this program does is change these values, saving the user the
  40.     trouble of using a disk editor.
  41.  
  42.     Why iD did not include a way to change these from within the
  43.     DOOM setup program, I do not know.  The code to allow temporary
  44.     changes on the command line seems to exist within SERSETUP.EXE
  45.     (undocumented -irq and -port options), but I was completely unable to
  46.     get these to work.  After downloading DOOM 1.2, I was really
  47.     looking forward to modem-vs-modem "DOOMwars".  Imagine my frustration
  48.     when the game started to use the wrong configuration and there was
  49.     seemingly nothing I could do about it.  After staying up all night
  50.     coding and hacking, I was playing ModemDOOM!  And by using this
  51.     program, so can you...  :-)
  52. */
  53.  
  54. #include <stdio.h>
  55.  
  56. #define DRIVERNAME "SERSETUP.EXE"
  57. #define DRIVERSIZE 36567l
  58. #define HACKOFFSET 18378l
  59.  
  60. #undef DEBUG
  61. /* #define DEBUG */
  62.  
  63. #ifdef DEBUG
  64.     #define dprintf(x) printf("==-- %s --==\n",x)
  65. #else
  66.     #define dprintf(x) ;
  67. #endif
  68.  
  69. unsigned Com, Port, Irq;
  70. unsigned Settings[8];
  71. FILE *Driver;
  72.  
  73. void PrintTitle(void)
  74. {
  75.     printf("\nDOOMODEM                     JoSHua Lehan\n");
  76.     printf("v1.0ß   2/18/94              jlehan@galaxy.csc.calpoly.edu\n\n");
  77. }
  78.  
  79. void PrintHelp(void)
  80. {
  81.     printf("Changes the default port and IRQ settings of the SERSETUP.EXE program!\n\n");
  82.     printf("  Usage:  DOOMODEM com port irq      All numbers must be _IN HEX_!!\n");
  83.     printf("Example:  DOOMODEM 3 3e8 5\n          Sets -com3 to port address 3E8h, IRQ 5h\n\n");
  84.     printf("This program is PUBLIC DOMAIN.  Use and distribute freely!\n");
  85. }
  86.  
  87. void HackSettings(void)
  88. {
  89.     Settings[Com - 1] = Port;
  90.     Settings[Com + 3] = Irq;
  91. }
  92.  
  93. int Hexify(unsigned *Value, char Str[])
  94. {
  95.     char *ParsePtr = Str;
  96.     char Nybble;
  97.     unsigned Num = 0;
  98.  
  99.     while (*ParsePtr != 0)
  100.     {
  101.         dprintf(ParsePtr);
  102.         Nybble = *ParsePtr;
  103.         if (Nybble >= 'a' && Nybble <= 'f')
  104.             Nybble -= 32;
  105.         if (Nybble < '0' || Nybble > '9')
  106.             if (Nybble < 'A' || Nybble > 'F')
  107.             {
  108.                 printf("Character '%c' is not a valid hex digit!\n", Nybble);
  109.                 return 1;
  110.             }
  111.             else
  112.                 Nybble -= 55;
  113.         else
  114.             Nybble -= 48;
  115.  
  116.         Num <<= 4;
  117.         Num += Nybble;
  118.         ParsePtr ++;
  119.     }
  120.  
  121.     *Value = Num;
  122.     return 0;
  123. }
  124.  
  125. int CheckBounds(void)
  126. {
  127.     if (Com < 1 || Com > 4)
  128.     {
  129.         printf("COM ports only range from 1 to 4!  \"%X\" won't work.\n\n", Com);
  130.         return 1;
  131.     }
  132.     if (Port != 0x3F8 && Port != 0x2F8 && Port != 0x3E8 && Port != 0x2E8)
  133.     {
  134.         printf("WARNING:  \"%X\" is a nonstandard port address!!\n", Port);
  135.         printf("It might still work, but is not recommended...\n\n");
  136.     }
  137.     if (Irq != 3 && Irq != 4 && Irq != 5 && Irq != 7)
  138.     {
  139.         printf("WARNING:  \"%X\" is a nonstandard IRQ level!!\n", Irq);
  140.         printf("DOOM will probably not like it...\n\n");
  141.     }
  142.     return 0;
  143. }
  144. int OpenDriver(void)
  145. {
  146.     long Size;
  147.  
  148.     Driver = fopen(DRIVERNAME, "r+b");
  149.     if (Driver == NULL)
  150.     {
  151.         printf("Can't open file %s!\n", DRIVERNAME);
  152.         printf("Make sure this program is ran in the \DOOM direcory!!\n\n");
  153.         return 1;
  154.     }
  155.     else
  156.     {
  157.         fseek(Driver, 0, SEEK_END);
  158.         Size = ftell(Driver);
  159.         if (Size != DRIVERSIZE)
  160.         {
  161.             printf("This file %s isn't the DOOM 1.2 serial port driver!!\n", DRIVERNAME);
  162.             printf("Was looking for file size %ld bytes, instead found %ld bytes!\n\n", DRIVERSIZE, Size);
  163.             return 2;
  164.         }
  165.         else
  166.             dprintf("File opened successfully!");
  167.     }
  168.  
  169.     return 0;
  170. }
  171.  
  172. void CloseDriver(void)
  173. {
  174.     fclose(Driver);
  175. }
  176.  
  177. int ReadSettings(void)
  178. {
  179.     int Loop;
  180.  
  181.     fseek(Driver, HACKOFFSET, SEEK_SET);
  182.     for (Loop = 0; Loop < 8; Loop ++)
  183.     {
  184.         if (!fread(&Settings[Loop], 2, 1, Driver))
  185.         {
  186.             printf("ERROR trying to read the file!!!\n");
  187.             return 1;
  188.         }
  189.     }
  190.  
  191.     dprintf("Data read correctly!");
  192.     return 0;
  193. }
  194.  
  195. int WriteSettings(void)
  196. {
  197.     int Loop;
  198.  
  199.     fseek(Driver, HACKOFFSET, SEEK_SET);
  200.     for (Loop = 0; Loop < 8; Loop ++)
  201.     {
  202.         if (!fwrite(&Settings[Loop], 2, 1, Driver))
  203.         {
  204.             printf("ERROR trying to write out the new settings!!!\n");
  205.             return 1;
  206.         }
  207.     }
  208.  
  209.     dprintf("Data written correctly!");
  210.     return 0;
  211. }
  212.  
  213. void PrintSettings(void)
  214. {
  215.     int Loop;
  216.  
  217.     for(Loop = 0; Loop < 4; Loop ++)
  218.         printf("COM%X:  port address %Xh, IRQ %Xh\n", Loop + 1, Settings[Loop], Settings[Loop + 4]);
  219. }
  220.  
  221. int main(int argc, char *argv[])
  222. {
  223.     int Success = 0;
  224.  
  225.     PrintTitle();
  226.     if (argc < 2)
  227.     {
  228.         PrintHelp();
  229.         return 0;
  230.     }
  231.     else
  232.         if (OpenDriver() || ReadSettings())
  233.         {
  234.             printf("PROGRAM ABORTED!  No changes to the file were made.\n");
  235.             return 1;
  236.         }
  237.  
  238.     if (argc == 4)
  239.     {
  240.         dprintf("Parse settings here:");
  241.         if (Hexify(&Com, argv[1]) || Hexify(&Port, argv[2]) || Hexify(&Irq, argv[3]))
  242.         {
  243.             printf("VALUES NOT UNDERSTOOD!  Were they typed IN HEX?\n\n");
  244.             printf("The old settings have not been changed:\n");
  245.         }
  246.         else
  247.         {
  248.             if (CheckBounds())
  249.                 printf("VALUES OUT OF RANGE!  Settings not changed:\n");
  250.             else
  251.             {
  252.                 HackSettings();
  253.                 if (WriteSettings() || ReadSettings())
  254.                     printf("UNABLE TO CHANGE THE FILE!  Here's the old settings:\n");
  255.                 else
  256.                 {
  257.                     printf("Settings of %s have been changed to:\n", DRIVERNAME);
  258.                     Success = 1;
  259.                 }
  260.             }
  261.         }
  262.     }
  263.     else
  264.     {
  265.         printf("Command line doesn't have 3 arguments so settings not changed.\n\n");
  266.         printf("Current settings of %s are:\n", DRIVERNAME);
  267.     }
  268.  
  269.     PrintSettings();
  270.     CloseDriver();
  271.  
  272.     if (Success)
  273.         printf("\nPROGRAM COMPLETE!  You are DOOMed!!!\n");
  274.     else
  275.         return 2;
  276.  
  277.     return 0;
  278. }