mirror of https://github.com/lianthony/NT4.0
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.
299 lines
7.2 KiB
299 lines
7.2 KiB
#include "insignia.h"
|
|
#include "host_def.h"
|
|
|
|
/*
|
|
* SoftPC Version 2.0
|
|
*
|
|
* Title : Generic Floppy Interface Empty Module
|
|
*
|
|
* Description : This module acts as a pseudo GFI diskette server, in the
|
|
* case when the diskette in question does not physically exist
|
|
* (eg accessing drive B: on a one drive system).
|
|
*
|
|
* 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_empty.c 1.13 08/03/93 Copyright Insignia Solutions Ltd.";
|
|
#endif
|
|
|
|
#ifdef SEGMENTATION
|
|
/*
|
|
* The following #define 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 "bios.h"
|
|
#include "ios.h"
|
|
#include "trace.h"
|
|
#include "config.h"
|
|
#include "fla.h"
|
|
#include "gfi.h"
|
|
#include "trace.h"
|
|
#include "debug.h"
|
|
|
|
|
|
/* Routines called via vector table. These are all local now;
|
|
** The prototype typedefs are defined in gfi.h which is now th. only
|
|
** base floppy header file needed. GM.
|
|
*/
|
|
|
|
LOCAL SHORT gfi_empty_drive_on
|
|
IPT1( UTINY, drive );
|
|
LOCAL SHORT gfi_empty_drive_off
|
|
IPT1( UTINY, drive );
|
|
LOCAL SHORT gfi_empty_change
|
|
IPT1( UTINY, drive );
|
|
LOCAL SHORT gfi_empty_drive_type
|
|
IPT1( UTINY, drive );
|
|
LOCAL SHORT gfi_empty_high
|
|
IPT2( UTINY, drive, half_word, n);
|
|
LOCAL SHORT gfi_empty_reset
|
|
IPT2( FDC_RESULT_BLOCK *, res, UTINY, drive );
|
|
LOCAL SHORT gfi_empty_command
|
|
IPT2( FDC_CMD_BLOCK *, ip, FDC_RESULT_BLOCK *, res );
|
|
LOCAL VOID gfi_empty_init
|
|
IPT1( UTINY, drive );
|
|
|
|
|
|
/*
|
|
* ============================================================================
|
|
* External functions
|
|
* ============================================================================
|
|
*/
|
|
|
|
|
|
/********************************************************/
|
|
|
|
/* Turn the empty floppy on and off. This forms an orthogonal interface
|
|
** with the host/generic floppy module which also has a XXX_active() func.
|
|
** 'Activating' the empty floppy means de-activating the real/slave one,
|
|
** and vice versa.
|
|
**
|
|
** NB: This is for SoftPC (gfi); the actual closing/opening must still be
|
|
** done in your floppy code! Also note that deactivating the empty floppy
|
|
** means activating the host one, but this is never done like that.
|
|
** GM.
|
|
*/
|
|
|
|
GLOBAL SHORT
|
|
gfi_empty_active IFN3(UTINY, hostID, BOOL, active, CHAR *, err)
|
|
{
|
|
UTINY drive = hostID - C_FLOPPY_A_DEVICE;
|
|
|
|
UNUSED( active );
|
|
UNUSED( err );
|
|
|
|
gfi_empty_init(drive);
|
|
return(C_CONFIG_OP_OK);
|
|
}
|
|
|
|
/********************************************************/
|
|
|
|
|
|
LOCAL VOID gfi_empty_init IFN1(UTINY,drive)
|
|
{
|
|
/*
|
|
* Initialise the floppy on the required drive:
|
|
*
|
|
* 0 - Drive A
|
|
* 1 - Drive B
|
|
*/
|
|
|
|
gfi_function_table[drive].command_fn = gfi_empty_command;
|
|
gfi_function_table[drive].drive_on_fn = gfi_empty_drive_on;
|
|
gfi_function_table[drive].drive_off_fn = gfi_empty_drive_off;
|
|
gfi_function_table[drive].reset_fn = gfi_empty_reset;
|
|
gfi_function_table[drive].high_fn = gfi_empty_high;
|
|
gfi_function_table[drive].drive_type_fn = gfi_empty_drive_type;
|
|
gfi_function_table[drive].change_fn = gfi_empty_change;
|
|
}
|
|
|
|
/********************************************************/
|
|
|
|
LOCAL SHORT
|
|
gfi_empty_command
|
|
IFN2(FDC_CMD_BLOCK *, command_block, FDC_RESULT_BLOCK *,result_block)
|
|
{
|
|
int ret_stat = FAILURE;
|
|
half_word D;
|
|
|
|
/* Clear result status registers */
|
|
put_r0_ST0 (result_block, 0);
|
|
put_r0_ST1 (result_block, 0);
|
|
put_r0_ST2 (result_block, 0);
|
|
|
|
switch (get_type_cmd (command_block))
|
|
{
|
|
case FDC_READ_DATA:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf (trace_file, "\tGFI-empty: Read Data Command \n");
|
|
#endif
|
|
break;
|
|
|
|
case FDC_WRITE_DATA:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf (trace_file,"\tGFI-empty: Write Data Command\n");
|
|
#endif
|
|
break;
|
|
|
|
case FDC_READ_TRACK:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf(trace_file,"\tGFI-empty: Read Track Command \n");
|
|
#endif
|
|
break;
|
|
|
|
case FDC_SPECIFY:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf(trace_file, "\tGFI-empty: Specify command\n");
|
|
#endif
|
|
break;
|
|
|
|
case FDC_READ_ID:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf(trace_file, "\tGFI-empty: read id command\n");
|
|
#endif
|
|
break;
|
|
|
|
case FDC_RECALIBRATE:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf (trace_file, "\tGFI-empty: Recalibrate command\n");
|
|
#endif
|
|
/* Controller tries 77 pulses to get drive to head 0,
|
|
but fails, so we set Equipment Check */
|
|
D = get_c5_drive(command_block);
|
|
put_r1_ST0_unit(result_block, D);
|
|
put_r1_ST0_equipment(result_block, 1);
|
|
put_r1_ST0_seek_end(result_block, 1);
|
|
put_r1_ST0_int_code(result_block, 1);
|
|
ret_stat = SUCCESS;
|
|
break;
|
|
|
|
case FDC_SENSE_DRIVE_STATUS:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf (trace_file, "\tGFI-empty: Sense Drive Status command\n");
|
|
#endif
|
|
break;
|
|
|
|
case FDC_SEEK:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf(trace_file, "\tGFI-empty: Seek command\n");
|
|
#endif
|
|
break;
|
|
|
|
case FDC_FORMAT_TRACK:
|
|
#ifndef PROD
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf(trace_file, "\tGFI-empty: Format Track command\n");
|
|
#endif
|
|
break;
|
|
|
|
#ifndef PROD
|
|
default:
|
|
if (io_verbose & GFI_VERBOSE)
|
|
fprintf(trace_file, "GFI-empty: Unimplemented command, type %x\n",
|
|
get_type_cmd (command_block));
|
|
#endif
|
|
}
|
|
|
|
return (ret_stat);
|
|
}
|
|
|
|
|
|
LOCAL SHORT gfi_empty_drive_on IFN1(UTINY,drive)
|
|
{
|
|
#ifdef PROD
|
|
UNUSED(drive);
|
|
#endif
|
|
note_trace1(GFI_VERBOSE, "GFI-Empty: Drive on command - drive %x", drive);
|
|
return(SUCCESS);
|
|
}
|
|
|
|
LOCAL SHORT gfi_empty_drive_off IFN1(UTINY,drive)
|
|
{
|
|
#ifdef PROD
|
|
UNUSED(drive);
|
|
#endif
|
|
note_trace1(GFI_VERBOSE, "GFI-Empty: Drive off command - drive %x", drive);
|
|
return(SUCCESS);
|
|
}
|
|
|
|
LOCAL SHORT gfi_empty_high IFN2(UTINY,drive, half_word, rate)
|
|
{
|
|
UNUSED(rate);
|
|
#ifdef PROD
|
|
UNUSED(drive);
|
|
#endif
|
|
|
|
note_trace1(GFI_VERBOSE, "GFI-Empty: Set high density command - drive %x",
|
|
drive);
|
|
return(FAILURE);
|
|
}
|
|
|
|
|
|
LOCAL SHORT gfi_empty_drive_type IFN1(UTINY,drive)
|
|
{
|
|
#ifdef PROD
|
|
UNUSED(drive);
|
|
#endif
|
|
note_trace1(GFI_VERBOSE, "GFI-Empty: Drive type command - drive %x", drive);
|
|
return( GFI_DRIVE_TYPE_NULL );
|
|
}
|
|
|
|
LOCAL SHORT gfi_empty_change IFN1(UTINY,drive)
|
|
{
|
|
#ifdef PROD
|
|
UNUSED(drive);
|
|
#endif
|
|
note_trace1(GFI_VERBOSE, "GFI-Empty: Disk changed command - drive %x", drive);
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
LOCAL SHORT gfi_empty_reset IFN2(FDC_RESULT_BLOCK *,result_block,UTINY, drive)
|
|
{
|
|
UNUSED(drive);
|
|
|
|
note_trace0(GFI_VERBOSE, "GFI-Empty: Reset command");
|
|
|
|
/*
|
|
* Fake up the Sense Interrupt Status result phase. We don't know the
|
|
* Present Cylinder No, so leave as zero.
|
|
*/
|
|
|
|
put_r3_ST0(result_block, 0);
|
|
put_r3_PCN(result_block, 0);
|
|
|
|
return(SUCCESS);
|
|
}
|