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 >
Wrap
Text File
|
1992-08-30
|
9KB
|
268 lines
/******************************************************************************
*******************************************************************************
***
*** Module: fdomainbios.c
***
*** Description:
*** Routines to get information on SCSI devices connected to a Future
*** Domain SCSI controller.
*** All information comes from the controller's configuration RAM and is
*** retrieved by Future Domain's undocumented interrupt calls.
*** Tested on a TMC-870 controller with ver. 6.0A ROM; it may or may not
*** work on other controllers.
***
*** History:
*** 92-08-15 ver. 1.0 Daniel Fandrich <shad04@ccu.umanitoba.ca>
*** Initial release.
*** Formatted for 80 columns with a tab size of 4.
*** ANSI C program tested under MS-DOS V5 with Turbo C V2.0.
*** 92-08-29 ver. 1.1 DTF
*** Added BIOS ver. 7.0 support in GetTMCInfo().
*** Added FDCopyright() function.
***
*******************************************************************************
******************************************************************************/
/******************************************************************************
*******************************************************************************
***
*** Includes
***
*******************************************************************************
******************************************************************************/
#include <dos.h>
#include <stddef.h>
#include "fdomainbios.h"
/******************************************************************************
*******************************************************************************
***
*** Constants
***
*******************************************************************************
******************************************************************************/
enum {DiskInt = 0x13}; /* Disk interrupt number */
enum {
GetSCSIInfo = 0x18, /* Undocumented call to get SCSI info */
GetSCSIDiskPtr = 0x1B, /* Undocumented call to get SCSI disk info */
GetSCSIRAMPtr = 0x1C /* Undocumented call to get SCSI free RAM ptr */
};
enum {CopyrightOfs = 5}; /* Offset into controller segment for copyright
message */
enum {TMCMagic = 0x4321}; /* Magic number to indicate Future Domain
controller is present */
enum {FlagsCarry = 1}; /* Mask to get carry flag in processor status
register */
/******************************************************************************
*******************************************************************************
***
*** Public Functions
***
*******************************************************************************
******************************************************************************/
/******************************************************************************
*
* Synopsis: */
char *FDCopyright(void)
/*
* Description:
* Return the copyright message contained in the controller ROM.
*
* Parameters:
* none
*
* Return value:
* pointer to ASCIIZ copyright string
*
* Notes:
* This function gets the copyright message without using interrupt calls,
* and so is more subject to fail on newer BIOS versions.
*
******************************************************************************/
{
static char ROMMessage[65];
char *ROMMessagePtr = ROMMessage;
char far *ROMPtr;
for (
ROMPtr = MK_FP(FP_SEG(GetTMCFreeRAMPtr(IsTMC())), CopyrightOfs);
(*ROMPtr >= ' ') &&
(*ROMPtr < '~') &&
(ROMMessagePtr < ROMMessage + sizeof(ROMMessage));
++ROMPtr, ++ROMMessagePtr
)
*ROMMessagePtr = *ROMPtr;
*ROMMessagePtr = 0;
return ROMMessage;
}
/******************************************************************************
*
* Synopsis: */
struct TMCDiskInfoBlock far *GetTMCDiskInfo(int DriveNum)
/*
* Description:
* Get information on drives connected to TMC-xxx controller.
*
* Parameters:
* DriveNum
* Number of a drive connected to the TMC-xxx controller.
* Must be in the range 0x80 to 0xFF.
*
* Return value:
* NULL TMC-xxx controller is not connected.
* <>NULL Far pointer to the SCSI disk info block.
*
* Notes:
* DO NOT call this function on an ESDI disk (non-SCSI) -- ES:BX isn't set and
* memory will be overwritten.
* Use GetTMCInfo() to check first.
*
******************************************************************************/
{
struct REGPACK Regs;
Regs.r_ax = GetSCSIDiskPtr << 8;
Regs.r_dx = DriveNum;
Regs.r_cx = 0;
intr(DiskInt, &Regs);
if (Regs.r_flags & FlagsCarry)
return (struct TMCDiskInfoBlock far *) NULL;
return (struct TMCDiskInfoBlock far *) MK_FP(Regs.r_es, Regs.r_bx);
}
/******************************************************************************
*
* Synopsis: */
void far *GetTMCFreeRAMPtr(int DriveNum)
/*
* Description:
* Get a pointer to the first byte of free RAM on board the TMC-xxx controller.
*
* Parameters:
* DriveNum
* Number of a drive connected to the TMC-xxx controller.
* Must be in the range 0x80 to 0xFF.
*
* Return value:
* NULL TMC-xxx controller is not connected.
* <>NULL Far pointer to the first byte of free controller RAM.
* (Controller RAM ends at offset 0x1BFF in the segment.)
*
******************************************************************************/
{
struct REGPACK Regs;
Regs.r_ax = (GetSCSIRAMPtr << 8) | 0; /* low byte 0 so accidental
ESDI call will fail */
Regs.r_dx = DriveNum;
intr(DiskInt, &Regs);
if (Regs.r_flags & FlagsCarry) /* DriveNum isn't a SCSI drive */
return (void far *) NULL;
return (void far *) MK_FP(Regs.r_es, Regs.r_bx);
}
/******************************************************************************
*
* Synopsis: */
int GetTMCInfo(
int DriveNum,
int *CanonicalNum,
int *NumDrives,
unsigned *Version
)
/*
* Description:
* Get information on drives connected to TMC-xxx controller.
*
* Parameters:
* DriveNum
* Number of a drive connected to the TMC-xxx controller.
* Must be in the range 0x80 to 0xFF.
* CanonicalNum
* Pointer to an integer which will contain the canonical number of the
* drive DriveNum relative to SCSI drives in the system.
* (i.e. 0 for first SCSI drive, 1 for second, etc.)
* Will be <0 if the drive is not a SCSI drive.
* NumDrives
* Pointer to an integer which will contain the number of SCSI drives
* connected to the TMC-xxx controller.
* Version
* Pointer to an integer which will contain the version number of the
* TMC-xxx controller.
* NOTE: I haven't confirmed that this number is actually the version --
* maybe it's the controller type.
*
* Return value:
* 0 Valid data is returned
* <>0 Valid data is not returned (drive wasn't SCSI)
*
******************************************************************************/
{
struct REGPACK Regs;
Regs.r_ax = GetSCSIInfo << 8;
Regs.r_dx = DriveNum;
Regs.r_cx = 0; /* Just in case the Set Media Type
function is called instead */
intr(DiskInt, &Regs);
if ((Regs.r_flags & FlagsCarry) || (Regs.r_ax != TMCMagic)) {
/* DriveNum isn't a SCSI drive */
*CanonicalNum = -1;
*NumDrives = 0;
*Version = 0;
return -1;
}
*Version = Regs.r_cx;
if (*Version >= 0x700) { /* Newer BIOS version */
*CanonicalNum = (int) (unsigned char) Regs.r_dx;
*NumDrives = Regs.r_dx >> 8;
} else {
*CanonicalNum = (int) (unsigned char) Regs.r_bx;
*NumDrives = Regs.r_bx >> 8;
}
return 0;
}
/******************************************************************************
*
* Synopsis: */
int IsTMC(void)
/*
* Description:
* Check for existance of Future Domain TMC-xxx controller
*
* Parameters:
* none
*
* Return value:
* 0 no TMC-xxx controller found
* <>0 drive number of first SCSI drive connected to the TMC-xxx controller
*
******************************************************************************/
{
struct REGPACK Regs;
unsigned DiskNum;
/******************************************************************************
* Check all the possible drive numbers for a valid SCSI drive
******************************************************************************/
for (DiskNum = 0x80; DiskNum <=0x8f; ++DiskNum) {
Regs.r_ax = GetSCSIInfo << 8;
Regs.r_dx = DiskNum;
Regs.r_cx = 0;
intr(DiskInt, &Regs);
if (!(Regs.r_flags & FlagsCarry) && (Regs.r_ax == TMCMagic))
/* Found a SCSI drive */
return DiskNum;
}
return 0;
}