Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

379 lines
9.2 KiB

#include "insignia.h"
#include "host_def.h"
/*
* SoftPC Version 2.0
*
* Title : Generic Floppy Interface (GFI)
*
* Description : GFI is a layer that insulates the Floppy Adaptor (FLA)
* from the type of device that is attached to VPC. It
* supports the slave PC, Virtual Diskette and a real
* device attached to the host.
*
* GFI provides a suite of functions which can
* be called to action Floppy commands. GFI will
* route these to the current resident device.
*
*
* Author : Henry Nash
*
* Notes : None
*
* Mods: (r3.2) : The system directory /usr/include/sys is not available
* on a Mac running Finder and MPW. Bracket references to
* such include files by "#ifdef macintosh <Mac file> #else
* <Unix file> #endif".
*/
#ifdef SCCSID
static char SccsID[]="@(#)gfi.c 1.16 08/03/93 Copyright Insignia Solutions Ltd.";
#endif
#ifdef SEGMENTATION
/*
* The following #include specifies the code segment into which this
* module will by placed by the MPW C compiler on the Mac II running
* MultiFinder.
*/
#include "SOFTPC_FLOPPY.seg"
#endif
/*
* O/S include files.
*/
#include <stdio.h>
#include TypesH
/*
* SoftPC include files
*/
#include "xt.h"
#include CpuH
#include "sas.h"
#include "ios.h"
#include "bios.h"
#include "error.h"
#include "config.h"
#include "trace.h"
#include "fla.h"
#include "gfi.h"
#include "gfitest.h"
#include "error.h"
#include "debug.h"
/*
* ============================================================================
* External definitions
* ============================================================================
*/
/*
* The command/result phases of the FDC are described in the following database.
*
* The structure contains
*
* - number of command bytes
* - number of result bytes
* - number of GFI result bytes
* - command class
* - result class
* - if dma is required
* - if an interrupt is generated
*
* A command byte count of 0 indicates a command that is handled by the FLA
* itself and not passed to GFI.
*
* Note that Sense Interrupt Status is not considered a generic GFI command
* but as a terminating command for the seek and recalibrate commands.
* These two commands now have "result" phases as far as gfi is concerned
* since the gfi level will ensure that a Sense Interrupt Status is performed
* to provide the result phase.
*/
FDC_DATA_ENTRY gfi_fdc_description[] =
{
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 9, 7, 7, 2, 0, TRUE, TRUE }, /* read track */
{ 3, 0, 0, 6, 0, FALSE, FALSE }, /* specify */
{ 2, 1, 1, 7, 2, FALSE, FALSE }, /* sense drive status */
{ 9, 7, 7, 1, 0, TRUE, TRUE }, /* write data */
{ 9, 7, 7, 0, 0, TRUE, TRUE }, /* read data */
{ 2, 0, 2, 5, 0, FALSE, TRUE }, /* recalibrate */
{ 0, 2, 2, 0, 3, FALSE, FALSE }, /* sense int status */
{ 9, 7, 7, 1, 0, TRUE, TRUE }, /* write deleted data */
{ 2, 7, 7, 4, 0, FALSE, TRUE }, /* read ID */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 9, 7, 7, 0, 0, TRUE, TRUE }, /* read deleted data */
{ 6, 7, 7, 3, 0, TRUE, TRUE }, /* format track */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 3, 0, 2, 8, 3, FALSE, TRUE }, /* seek */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 9, 7, 7, 0, 0, TRUE, TRUE }, /* scan equal */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 9, 7, 7, 0, 0, TRUE, TRUE }, /* scan equal */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 9, 7, 7, 0, 0, TRUE, TRUE }, /* scan equal */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
{ 0, 1, 1, 0, 4, FALSE, FALSE }, /* invalid */
};
/*
* The function table that is built by the init function of the
* individual GFI servers.
*/
GFI_FUNCTION_ENTRY gfi_function_table[MAX_DISKETTES];
/*
* ============================================================================
* External functions
* ============================================================================
*/
GLOBAL SHORT gfi_fdc_command
IFN2(FDC_CMD_BLOCK *,command_block,FDC_RESULT_BLOCK *,result_block)
{
/*
* The main FDC command. Route to the correct module.
*/
int i;
int ret_stat = SUCCESS;
#ifndef PROD
if (io_verbose & GFI_VERBOSE)
gfi_test_command(command_block, result_block);
#endif
if (get_type_cmd(command_block) == FDC_SPECIFY)
{
/*
* A specify command relates to all drives so call each in turn.
* Not that even the empty drive allows specifies.
*/
for (i = 0; i < MAX_DISKETTES; i++)
{
put_type_drive(command_block, i);
/* some host floppies like to know the correct drive number */
(*gfi_function_table[i].command_fn)(command_block, result_block);
}
}
else
/*
* All other commands specify the drive in the command.
*/
ret_stat = (*gfi_function_table[get_type_drive(command_block)].command_fn)(command_block, result_block);
return(ret_stat);
}
GLOBAL SHORT gfi_drive_on IFN1(UTINY,drive)
{
#ifndef PROD
if (io_verbose & GFI_VERBOSE)
gfi_test_drive_on(drive);
#endif
/*
* Route to the correct module.
*/
return((*gfi_function_table[drive].drive_on_fn)(drive));
}
GLOBAL SHORT gfi_drive_off IFN1(UTINY,drive)
{
#ifndef PROD
if (io_verbose & GFI_VERBOSE)
gfi_test_drive_off(drive);
#endif
/*
* Route to the correct module.
*/
return((*gfi_function_table[drive].drive_off_fn)(drive));
}
GLOBAL SHORT gfi_reset IFN2(FDC_RESULT_BLOCK *,result_block, UTINY, drive)
{
/*
* Reset the specified drive.
*/
#ifndef PROD
if (io_verbose & GFI_VERBOSE)
gfi_test_reset(result_block);
#endif
/*
* Reset the appropriate drive.
*/
(*gfi_function_table[drive].reset_fn)(result_block, drive);
/*
* The result phase returns the data for a subsequent Sense Interrupt
* Status, and should contain a "termination due to state change".
*/
put_r3_ST0(result_block, 0);
put_r1_ST0_int_code(result_block, 3);
put_r3_PCN(result_block, 0);
return(SUCCESS);
}
/*
** Set the specified datarate.
*/
GLOBAL SHORT gfi_high IFN2(UTINY,drive,half_word,datarate)
{
#ifndef PROD
if (io_verbose & GFI_VERBOSE)
gfi_test_high(drive);
#endif
/*
* Route to the correct module.
*/
return((*gfi_function_table[drive].high_fn)(drive,datarate));
}
GLOBAL SHORT gfi_drive_type IFN1(UTINY,drive)
{
#ifndef PROD
if (io_verbose & GFI_VERBOSE)
gfi_test_drive_type(drive);
#endif
/*
* Route to the correct module.
*/
return((*gfi_function_table[drive].drive_type_fn)(drive));
}
GLOBAL SHORT gfi_change IFN1(UTINY,drive)
{
#ifndef PROD
if (io_verbose & GFI_VERBOSE)
gfi_test_change(drive);
#endif
/*
* Route to the correct module.
*/
return((*gfi_function_table[drive].change_fn)(drive));
}
GLOBAL SHORT
gfi_floppy_valid
IFN4(UTINY, hostID, ConfigValues *,vals, NameTable *,table, CHAR *,err)
{
UNUSED(table);
#ifdef SLAVEPC
if (hostID == C_SLAVEPC_DEVICE)
return host_slave_port_validate(host_expand_environment_vars(
vals->string), err);
#endif /* SLAVEPC */
return host_gfi_rdiskette_valid(hostID, vals, err);
}
GLOBAL VOID
gfi_floppy_change IFN2(UTINY, hostID, BOOL, apply)
{
#ifdef SLAVEPC
if (hostID == C_SLAVEPC_DEVICE)
{
gfi_slave_change(hostID, apply);
return;
}
#endif /* SLAVEPC */
host_gfi_rdiskette_change(hostID, apply);
}
GLOBAL SHORT
gfi_floppy_active IFN3(UTINY, hostID, BOOL, active, CHAR *,err)
{
#ifdef SLAVEPC
if (hostID == C_SLAVEPC_DEVICE)
return gfi_slave_active(hostID, active, err);
#endif /* SLAVEPC */
return host_gfi_rdiskette_active(hostID, active, err);
}
GLOBAL VOID
gfi_attach_adapter IFN2(UTINY, adapter, BOOL, attach)
{
#ifdef SLAVEPC
if (host_runtime_inquire(C_FLOPPY_SERVER) == GFI_SLAVE_SERVER)
{
if (adapter == 1)
return; /* No B adapter for slave PC */
/* First cleaup the other possible adapters */
if (config_get_active(C_FLOPPY_A_DEVICE))
config_activate(C_FLOPPY_A_DEVICE, FALSE);
#ifdef FLOPPY_B
if (config_get_active(C_FLOPPY_B_DEVICE))
config_activate(C_FLOPPY_B_DEVICE, FALSE);
#endif /* FLOPPY_B */
/* Activate the SLAVEPC device handler */
config_activate(C_SLAVEPC_DEVICE, attach);
return;
}
/* Must be a GFI_REAL_DISKETTE_SERVER */
if (config_get_active(C_SLAVEPC_DEVICE))
config_activate(C_SLAVEPC_DEVICE, FALSE);
#endif /* SLAVEPC */
config_activate(C_FLOPPY_A_DEVICE + adapter, attach);
}
#ifdef SEGMENTATION
/*
* The following #include specifies the code segment into which this
* function will by placed by the MPW C compiler on the Mac II running
* MultiFinder.
*/
#include "SOFTPC_INIT.seg"
#endif
/*
* Initialize the GFI module. Fill the function table with the GFI
* "empty" server module (which will cause a timeout when accessed).
*/
GLOBAL VOID gfi_init IFN0()
{
int i;
host_runtime_set(C_FLOPPY_SERVER, GFI_REAL_DISKETTE_SERVER);
for (i = 0; i < MAX_DISKETTES; i++)
gfi_empty_active(C_FLOPPY_A_DEVICE+i,TRUE,NULL);
}