home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / f / fdomaini.zoo / fdomainb.c < prev    next >
Text File  |  1992-08-30  |  9KB  |  268 lines

  1. /******************************************************************************
  2. *******************************************************************************
  3. ***
  4. *** Module: fdomainbios.c
  5. ***
  6. *** Description:
  7. ***        Routines to get information on SCSI devices connected to a Future
  8. ***        Domain SCSI controller.
  9. ***        All information comes from the controller's configuration RAM and is
  10. ***        retrieved by Future Domain's undocumented interrupt calls.
  11. ***        Tested on a TMC-870 controller with ver. 6.0A ROM; it may or may not
  12. ***        work on other controllers.
  13. ***
  14. *** History:
  15. ***        92-08-15  ver. 1.0  Daniel Fandrich <shad04@ccu.umanitoba.ca>
  16. ***            Initial release.
  17. ***            Formatted for 80 columns with a tab size of 4.
  18. ***            ANSI C program tested under MS-DOS V5 with Turbo C V2.0.
  19. ***        92-08-29  ver. 1.1  DTF
  20. ***            Added BIOS ver. 7.0 support in GetTMCInfo().
  21. ***            Added FDCopyright() function.
  22. ***
  23. *******************************************************************************
  24. ******************************************************************************/
  25.  
  26. /******************************************************************************
  27. *******************************************************************************
  28. ***
  29. *** Includes
  30. ***
  31. *******************************************************************************
  32. ******************************************************************************/
  33. #include <dos.h>
  34. #include <stddef.h>
  35. #include "fdomainbios.h"
  36.  
  37. /******************************************************************************
  38. *******************************************************************************
  39. ***
  40. *** Constants
  41. ***
  42. *******************************************************************************
  43. ******************************************************************************/
  44. enum {DiskInt = 0x13};            /* Disk interrupt number */
  45.  
  46. enum {
  47.     GetSCSIInfo = 0x18,            /* Undocumented call to get SCSI info */
  48.     GetSCSIDiskPtr = 0x1B,        /* Undocumented call to get SCSI disk info */
  49.     GetSCSIRAMPtr = 0x1C        /* Undocumented call to get SCSI free RAM ptr */
  50. };
  51.  
  52. enum {CopyrightOfs = 5};        /* Offset into controller segment for copyright
  53.                                    message */
  54.  
  55. enum {TMCMagic = 0x4321};        /* Magic number to indicate Future Domain
  56.                                    controller is present */
  57.  
  58. enum {FlagsCarry = 1};            /* Mask to get carry flag in processor status
  59.                                    register */
  60.  
  61. /******************************************************************************
  62. *******************************************************************************
  63. ***
  64. *** Public Functions
  65. ***
  66. *******************************************************************************
  67. ******************************************************************************/
  68.  
  69. /******************************************************************************
  70. *
  71. * Synopsis:                                                                     */
  72.     char *FDCopyright(void)
  73. /*
  74. * Description:
  75. *    Return the copyright message contained in the controller ROM.
  76. *
  77. * Parameters:
  78. *    none
  79. *
  80. * Return value:
  81. *    pointer to ASCIIZ copyright string
  82. *
  83. * Notes:
  84. *    This function gets the copyright message without using interrupt calls,
  85. *    and so is more subject to fail on newer BIOS versions.
  86. *
  87. ******************************************************************************/
  88. {
  89.     static char ROMMessage[65];
  90.     char *ROMMessagePtr = ROMMessage;
  91.     char far *ROMPtr;
  92.  
  93.     for (
  94.         ROMPtr = MK_FP(FP_SEG(GetTMCFreeRAMPtr(IsTMC())), CopyrightOfs);
  95.         (*ROMPtr >= ' ') &&
  96.             (*ROMPtr < '~') &&
  97.             (ROMMessagePtr < ROMMessage + sizeof(ROMMessage));
  98.         ++ROMPtr, ++ROMMessagePtr
  99.     )
  100.         *ROMMessagePtr = *ROMPtr;
  101.     *ROMMessagePtr = 0;
  102.  
  103.     return ROMMessage;
  104. }
  105.  
  106. /******************************************************************************
  107. *
  108. * Synopsis:                                                                     */
  109.     struct TMCDiskInfoBlock far *GetTMCDiskInfo(int DriveNum)
  110. /*
  111. * Description:
  112. *    Get information on drives connected to TMC-xxx controller.
  113. *
  114. * Parameters:
  115. *    DriveNum
  116. *        Number of a drive connected to the TMC-xxx controller.
  117. *        Must be in the range 0x80 to 0xFF.
  118. *
  119. * Return value:
  120. *    NULL    TMC-xxx controller is not connected.
  121. *    <>NULL    Far pointer to the SCSI disk info block.
  122. *
  123. * Notes:
  124. *    DO NOT call this function on an ESDI disk (non-SCSI) -- ES:BX isn't set and
  125. *    memory will be overwritten.
  126. *    Use GetTMCInfo() to check first.
  127. *
  128. ******************************************************************************/
  129. {
  130.     struct REGPACK Regs;
  131.  
  132.     Regs.r_ax = GetSCSIDiskPtr << 8;
  133.     Regs.r_dx = DriveNum;
  134.     Regs.r_cx = 0;
  135.     intr(DiskInt, &Regs);
  136.     if (Regs.r_flags & FlagsCarry)
  137.         return (struct TMCDiskInfoBlock far *) NULL;
  138.     return (struct TMCDiskInfoBlock far *) MK_FP(Regs.r_es, Regs.r_bx);
  139. }
  140.  
  141. /******************************************************************************
  142. *
  143. * Synopsis:                                                                     */
  144.     void far *GetTMCFreeRAMPtr(int DriveNum)
  145. /*
  146. * Description:
  147. *    Get a pointer to the first byte of free RAM on board the TMC-xxx controller.
  148. *
  149. * Parameters:
  150. *    DriveNum
  151. *        Number of a drive connected to the TMC-xxx controller.
  152. *        Must be in the range 0x80 to 0xFF.
  153. *
  154. * Return value:
  155. *    NULL    TMC-xxx controller is not connected.
  156. *    <>NULL    Far pointer to the first byte of free controller RAM.
  157. *            (Controller RAM ends at offset 0x1BFF in the segment.)
  158. *
  159. ******************************************************************************/
  160. {
  161.     struct REGPACK Regs;
  162.  
  163.     Regs.r_ax = (GetSCSIRAMPtr << 8) | 0;        /* low byte 0 so accidental
  164.                                                    ESDI call will fail */
  165.     Regs.r_dx = DriveNum;
  166.     intr(DiskInt, &Regs);
  167.     if (Regs.r_flags & FlagsCarry)            /* DriveNum isn't a SCSI drive */
  168.         return (void far *) NULL;
  169.     return (void far *) MK_FP(Regs.r_es, Regs.r_bx);
  170. }
  171.  
  172. /******************************************************************************
  173. *
  174. * Synopsis:                                                                     */
  175.     int GetTMCInfo(
  176.         int DriveNum,
  177.         int *CanonicalNum,
  178.         int *NumDrives,
  179.         unsigned *Version
  180.     )
  181. /*
  182. * Description:
  183. *    Get information on drives connected to TMC-xxx controller.
  184. *
  185. * Parameters:
  186. *    DriveNum
  187. *        Number of a drive connected to the TMC-xxx controller.
  188. *        Must be in the range 0x80 to 0xFF.
  189. *    CanonicalNum
  190. *        Pointer to an integer which will contain the canonical number of the
  191. *        drive DriveNum relative to SCSI drives in the system.
  192. *        (i.e. 0 for first SCSI drive, 1 for second, etc.)
  193. *        Will be <0 if the drive is not a SCSI drive.
  194. *    NumDrives
  195. *        Pointer to an integer which will contain the number of SCSI drives
  196. *        connected to the TMC-xxx controller.
  197. *    Version
  198. *        Pointer to an integer which will contain the version number of the
  199. *        TMC-xxx controller.
  200. *        NOTE: I haven't confirmed that this number is actually the version --
  201. *        maybe it's the controller type.
  202. *
  203. * Return value:
  204. *    0    Valid data is returned
  205. *    <>0    Valid data is not returned (drive wasn't SCSI)
  206. *
  207. ******************************************************************************/
  208. {
  209.     struct REGPACK Regs;
  210.  
  211.     Regs.r_ax = GetSCSIInfo << 8;
  212.     Regs.r_dx = DriveNum;
  213.     Regs.r_cx = 0;                    /* Just in case the Set Media Type
  214.                                        function is called instead */
  215.     intr(DiskInt, &Regs);
  216.     if ((Regs.r_flags & FlagsCarry) || (Regs.r_ax != TMCMagic)) {
  217.                                             /* DriveNum isn't a SCSI drive */
  218.         *CanonicalNum = -1;
  219.         *NumDrives = 0;
  220.         *Version = 0;
  221.         return -1;
  222.     }
  223.     *Version = Regs.r_cx;
  224.     if (*Version >= 0x700) {        /* Newer BIOS version */
  225.         *CanonicalNum = (int) (unsigned char) Regs.r_dx;
  226.         *NumDrives = Regs.r_dx >> 8;
  227.     } else {
  228.         *CanonicalNum = (int) (unsigned char) Regs.r_bx;
  229.         *NumDrives = Regs.r_bx >> 8;
  230.     }
  231.     return 0;
  232. }
  233.  
  234. /******************************************************************************
  235. *
  236. * Synopsis:                                                                     */
  237.     int IsTMC(void)
  238. /*
  239. * Description:
  240. *    Check for existance of Future Domain TMC-xxx controller
  241. *
  242. * Parameters:
  243. *    none
  244. *
  245. * Return value:
  246. *    0    no TMC-xxx controller found
  247. *    <>0    drive number of first SCSI drive connected to the TMC-xxx controller
  248. *
  249. ******************************************************************************/
  250. {
  251.     struct REGPACK Regs;
  252.     unsigned DiskNum;
  253.  
  254. /******************************************************************************
  255. * Check all the possible drive numbers for a valid SCSI drive
  256. ******************************************************************************/
  257.     for (DiskNum = 0x80; DiskNum <=0x8f; ++DiskNum) {
  258.         Regs.r_ax = GetSCSIInfo << 8;
  259.         Regs.r_dx = DiskNum;
  260.         Regs.r_cx = 0;
  261.         intr(DiskInt, &Regs);
  262.         if (!(Regs.r_flags & FlagsCarry) && (Regs.r_ax == TMCMagic))
  263.                                                     /* Found a SCSI drive */
  264.             return DiskNum;
  265.     }
  266.     return 0;
  267. }
  268.