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.
 
 
 
 
 
 

618 lines
23 KiB

/*
* SoftPC Version 2.0
*
* Title : Generic Floppy Interface level definitions
*
* Description : Data structures for GFI
*
* Author : Henry Nash + various others
*
*/
/*
static char SccsID[]="@(#)gfi.h 1.12 04/08/93 Copyright Insignia Solutions Ltd.";
*/
/*
* ============================================================================
* Structure/Data definitions
* ============================================================================
*/
#define MAX_COMMAND_LEN 9 /* max number of command bytes */
#define MAX_RESULT_LEN 7 /* max number of result bytes */
typedef unsigned char FDC_CMD_BLOCK;
typedef unsigned char FDC_RESULT_BLOCK;
/* START: FDC COMMAND BLOCK DEFINITIONS >>>>>>>>>>>>>>>>>>>>>>>>>>> */
/*
* A simple access to the command type and drive
*/
/* the command itself */
#define get_type_cmd(ptr) (ptr[0] & 0x1f)
#define put_type_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* ...and the drive no */
#define get_type_drive(ptr) (ptr[1] & 0x3)
#define put_type_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/*
* Class 0 - read data, read deleted data, all scans
*/
/* multi-track */
#define get_c0_MT(ptr) ((ptr[0] & 0x80) >> 7)
#define put_c0_MT(ptr,val) ptr[0] = (ptr[0] & ~0x80) | ((val << 7) & 0x80)
/* always 1 - FM not used */
#define get_c0_MFM(ptr) ((ptr[0] & 0x40) >> 6)
#define put_c0_MFM(ptr,val) ptr[0] = (ptr[0] & ~0x40) | ((val << 6) & 0x40)
/* skip data */
#define get_c0_skip(ptr) ((ptr[0] & 0x20) >> 5)
#define put_c0_skip(ptr,val) ptr[0] = (ptr[0] & ~0x20) | ((val << 5) & 0x20)
/* the command itself */
#define get_c0_cmd(ptr) (ptr[0] & 0x1f)
#define put_c0_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* padding */
#define get_c0_pad(ptr) ((ptr[1] & 0xf8) >> 3)
#define put_c0_pad(ptr,val) ptr[1] = (ptr[1] & ~0xf8) | ((val << 3) & 0xf8)
/* which head */
#define get_c0_head(ptr) ((ptr[1] & 0x4) >> 2)
#define put_c0_head(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* drive unit */
#define get_c0_drive(ptr) (ptr[1] & 0x3)
#define put_c0_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/* cylinder number */
#define get_c0_cyl(ptr) ptr[2]
#define put_c0_cyl(ptr,val) ptr[2] = val
/* head number - again ! */
#define get_c0_hd(ptr) ptr[3]
#define put_c0_hd(ptr,val) ptr[3] = val
/* sector number */
#define get_c0_sector(ptr) ptr[4]
#define put_c0_sector(ptr,val) ptr[4] = val
/* encoded bytes per sector */
#define get_c0_N(ptr) ptr[5]
#define put_c0_N(ptr,val) ptr[5] = val
/* last sector on track */
#define get_c0_EOT(ptr) ptr[6]
#define put_c0_EOT(ptr,val) ptr[6] = val
/* gap length */
#define get_c0_GPL(ptr) ptr[7]
#define put_c0_GPL(ptr,val) ptr[7] = val
/* data length */
#define get_c0_DTL(ptr) ptr[8]
#define put_c0_DTL(ptr,val) ptr[8] = val
/*
* Class 1 - write data, write deleted data
*/
/* multi-track */
#define get_c1_MT(ptr) ((ptr[0] & 0x80) >> 7)
#define put_c1_MT(ptr,val) ptr[0] = (ptr[0] & ~0x80) | ((val << 7) & 0x80)
/* always 1 - FM not used */
#define get_c1_MFM(ptr) ((ptr[0] & 0x40) >> 6)
#define put_c1_MFM(ptr,val) ptr[0] = (ptr[0] & ~0x40) | ((val << 6) & 0x40)
/* padding */
#define get_c1_pad(ptr) ((ptr[0] & 0x20) >> 5)
#define put_c1_pad(ptr,val) ptr[0] = (ptr[0] & ~0x20) | ((val << 5) & 0x20)
/* the command itself */
#define get_c1_cmd(ptr) (ptr[0] & 0x1f)
#define put_c1_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* padding */
#define get_c1_pad1(ptr) ((ptr[1] & 0xf8) >> 3)
#define put_c1_pad1(ptr,val) ptr[1] = (ptr[1] & ~0xf8) | ((val << 3) & 0xf8)
/* which head */
#define get_c1_head(ptr) ((ptr[1] & 0x4) >> 2)
#define put_c1_head(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* drive unit */
#define get_c1_drive(ptr) (ptr[1] & 0x3)
#define put_c1_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/* cylinder number */
#define get_c1_cyl(ptr) ptr[2]
#define put_c1_cyl(ptr,val) ptr[2] = val
/* head number - again ! */
#define get_c1_hd(ptr) ptr[3]
#define put_c1_hd(ptr,val) ptr[3] = val
/* sector number */
#define get_c1_sector(ptr) ptr[4]
#define put_c1_sector(ptr,val) ptr[4] = val
/* encoded bytes per sector */
#define get_c1_N(ptr) ptr[5]
#define put_c1_N(ptr,val) ptr[5] = val
/* last sector on track */
#define get_c1_EOT(ptr) ptr[6]
#define put_c1_EOT(ptr,val) ptr[6] = val
/* gap length */
#define get_c1_GPL(ptr) ptr[7]
#define put_c1_GPL(ptr,val) ptr[7] = val
/* data length */
#define get_c1_DTL(ptr) ptr[8]
#define put_c1_DTL(ptr,val) ptr[8] = val
/*
* Class 2 - read a track
*/
/* always 1 - FM not used */
#define get_c2_MFM(ptr) ((ptr[0] & 0x40) >> 6)
#define put_c2_MFM(ptr,val) ptr[0] = (ptr[0] & ~0x40) | ((val << 6) & 0x40)
/* skip data */
#define get_c2_skip(ptr) ((ptr[0] & 0x20) >> 5)
#define put_c2_skip(ptr,val) ptr[0] = (ptr[0] & ~0x20) | ((val << 5) & 0x20)
/* the command itself */
#define get_c2_cmd(ptr) (ptr[0] & 0x1f)
#define put_c2_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* padding */
/* padding */
#define get_c2_pad1(ptr) ((ptr[1] & 0xf8) >> 3)
#define put_c2_pad1(ptr,val) ptr[1] = (ptr[1] & ~0xf8) | ((val << 3) & 0xf8)
/* which head */
#define get_c2_head(ptr) ((ptr[1] & 0x4) >> 2)
#define put_c2_head(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* drive unit */
#define get_c2_drive(ptr) (ptr[1] & 0x3)
#define put_c2_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/* cylinder number */
#define get_c2_cyl(ptr) ptr[2]
#define put_c2_cyl(ptr,val) ptr[2] = val
/* head number - again ! */
#define get_c2_hd(ptr) ptr[3]
#define put_c2_hd(ptr,val) ptr[3] = val
/* sector number */
#define get_c2_sector(ptr) ptr[4]
#define put_c2_sector(ptr,val) ptr[4] = val
/* encoded bytes per sector */
#define get_c2_N(ptr) ptr[5]
#define put_c2_N(ptr,val) ptr[5] = val
/* last sector on track */
#define get_c2_EOT(ptr) ptr[6]
#define put_c2_EOT(ptr,val) ptr[6] = val
/* gap length */
#define get_c2_GPL(ptr) ptr[7]
#define put_c2_GPL(ptr,val) ptr[7] = val
/* data length */
#define get_c2_DTL(ptr) ptr[8]
#define put_c2_DTL(ptr,val) ptr[8] = val
/*
* Class 3 - format a track
*/
/* padding */
#define get_c3_pad(ptr) ((ptr[0] & 0x80) >> 7)
#define put_c3_pad(ptr,val) ptr[0] = (ptr[0] & ~0x80) | ((val << 7) & 0x80)
/* always 1 - FM not used */
#define get_c3_MFM(ptr) ((ptr[0] & 0x40) >> 6)
#define put_c3_MFM(ptr,val) ptr[0] = (ptr[0] & ~0x40) | ((val << 6) & 0x40)
/* padding */
#define get_c3_pad1(ptr) ((ptr[0] & 0x20) >> 5)
#define put_c3_pad1(ptr,val) ptr[0] = (ptr[0] & ~0x20) | ((val << 5) & 0x20)
/* the command itself */
#define get_c3_cmd(ptr) (ptr[0] & 0x1f)
#define put_c3_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* padding */
#define get_c3_pad2(ptr) ((ptr[1] & 0xf8) >> 3)
#define put_c3_pad2(ptr,val) ptr[1] = (ptr[1] & ~0xf8) | ((val << 3) & 0xf8)
/* which head */
#define get_c3_head(ptr) ((ptr[1] & 0x4) >> 2)
#define put_c3_head(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* drive unit */
#define get_c3_drive(ptr) (ptr[1] & 0x3)
#define put_c3_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/* encoded bytes per sector */
#define get_c3_N(ptr) ptr[2]
#define put_c3_N(ptr,val) ptr[2] = val
/* sectors per cylinder */
#define get_c3_SC(ptr) ptr[3]
#define put_c3_SC(ptr,val) ptr[3] = val
/* gap length */
#define get_c3_GPL(ptr) ptr[4]
#define put_c3_GPL(ptr,val) ptr[4] = val
/* filler byte */
#define get_c3_filler(ptr) ptr[5]
#define put_c3_filler(ptr,val) ptr[5] = val
/*
* Class 4 - read ID
*/
/* padding */
#define get_c4_pad(ptr) ((ptr[0] & 0x80) >> 7)
#define put_c4_pad(ptr,val) ptr[0] = (ptr[0] & ~0x80) | ((val << 7) & 0x80)
/* always 1 - FM not used */
#define get_c4_MFM(ptr) ((ptr[0] & 0x40) >> 6)
#define put_c4_MFM(ptr,val) ptr[0] = (ptr[0] & ~0x40) | ((val << 6) & 0x40)
/* padding */
#define get_c4_pad1(ptr) ((ptr[0] & 0x20) >> 5)
#define put_c4_pad1(ptr,val) ptr[0] = (ptr[0] & ~0x20) | ((val << 5) & 0x20)
/* the command itself */
#define get_c4_cmd(ptr) (ptr[0] & 0x1f)
#define put_c4_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* padding */
#define get_c4_pad2(ptr) ((ptr[1] & 0xf8) >> 3)
#define put_c4_pad2(ptr,val) ptr[1] = (ptr[1] & ~0xf8) | ((val << 3) & 0xf8)
/* which head */
#define get_c4_head(ptr) ((ptr[1] & 0x4) >> 2)
#define put_c4_head(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* drive unit */
#define get_c4_drive(ptr) (ptr[1] & 0x3)
#define put_c4_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/*
* Class 5 - recalibrate
*/
/* padding */
#define get_c5_pad(ptr) ((ptr[0] & 0xe0) >> 5)
#define put_c5_pad(ptr,val) ptr[0] = (ptr[0] & ~0xe0) | ((val << 5) & 0xe0)
/* the command itself */
#define get_c5_cmd(ptr) (ptr[0] & 0x1f)
#define put_c5_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* padding */
#define get_c5_pad1(ptr) ((ptr[1] & 0xfc) >> 2)
#define put_c5_pad1(ptr,val) ptr[1] = (ptr[1] & ~0xfc) | ((val << 2) & 0xfc)
/* drive unit */
#define get_c5_drive(ptr) (ptr[1] & 0x3)
#define put_c5_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/*
* Class 6 - specify
*/
/* the command itself */
#define get_c6_cmd(ptr) (ptr[0] & 0x1f)
#define put_c6_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* step rate time */
#define get_c6_SRT(ptr) ((ptr[1] & 0xf0) >> 4)
#define put_c6_SRT(ptr,val) ptr[1] = (ptr[1] & ~0xf0) | ((val << 4) & 0xf0)
/* head unload time */
#define get_c6_HUT(ptr) (ptr[1] & 0xf)
#define put_c6_HUT(ptr,val) ptr[1] = (ptr[1] & ~0xf) | ((val << 0) & 0xf)
/* head load time */
#define get_c6_HLT(ptr) ((ptr[2] & 0xfe) >> 1)
#define put_c6_HLT(ptr,val) ptr[2] = (ptr[2] & ~0xfe) | ((val << 1) & 0xfe)
/* non-dma mode - not supp. */
#define get_c6_ND(ptr) (ptr[2] & 0x1)
#define put_c6_ND(ptr,val) ptr[2] = (ptr[2] & ~0x1) | ((val << 0) & 0x1)
/*
* Class 7 - sense drive status
*/
/* the command itself */
#define get_c7_cmd(ptr) (ptr[0] & 0x1f)
#define put_c7_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* which head */
#define get_c7_head(ptr) ((ptr[1] & 0x4) >> 2)
#define put_c7_head(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* drive unit */
#define get_c7_drive(ptr) (ptr[1] & 0x3)
#define put_c7_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/*
* Class 8 - seek
*/
/* padding */
#define get_c8_pad(ptr) ((ptr[0] & 0xe0) >> 5)
#define put_c8_pad(ptr,val) ptr[0] = (ptr[0] & ~0xe0) | ((val << 5) & 0xe0)
/* the command itself */
#define get_c8_cmd(ptr) (ptr[0] & 0x1f)
#define put_c8_cmd(ptr,val) ptr[0] = (ptr[0] & ~0x1f) | ((val << 0) & 0x1f)
/* padding */
#define get_c8_pad1(ptr) ((ptr[1] & 0xf8) >> 3)
#define put_c8_pad1(ptr,val) ptr[1] = (ptr[1] & ~0xf8) | ((val << 3) & 0xf8)
/* which head */
#define get_c8_head(ptr) ((ptr[1] & 0x4) >> 2)
#define put_c8_head(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* drive unit */
#define get_c8_drive(ptr) (ptr[1] & 0x3)
#define put_c8_drive(ptr,val) ptr[1] = (ptr[1] & ~0x3) | ((val << 0) & 0x3)
/* new cylinder no for seek */
#define get_c8_new_cyl(ptr) ptr[2]
#define put_c8_new_cyl(ptr,val) ptr[2] = val
/* END: FDC COMMAND BLOCK DEFINITIONS <<<<<<<<<<<<<<<<<<<<<<<<<<< */
/* START: FDC RESULT BLOCK DEFINITIONS >>>>>>>>>>>>>>>>>>>>>>>>>>>> */
/*
* Class 0 - read/write data, read/write deleted data,
* all scans, read/format a track
*/
/* status register 0 */
#define get_r0_ST0(ptr) ptr[0]
#define put_r0_ST0(ptr,val) ptr[0] = val
/* status register 1 */
#define get_r0_ST1(ptr) ptr[1]
#define put_r0_ST1(ptr,val) ptr[1] = val
/* status register 2 */
#define get_r0_ST2(ptr) ptr[2]
#define put_r0_ST2(ptr,val) ptr[2] = val
/* cylinder number */
#define get_r0_cyl(ptr) ptr[3]
#define put_r0_cyl(ptr,val) ptr[3] = val
/* head number */
#define get_r0_head(ptr) ptr[4]
#define put_r0_head(ptr,val) ptr[4] = val
/* sector number */
#define get_r0_sector(ptr) ptr[5]
#define put_r0_sector(ptr,val) ptr[5] = val
/* encoded bytes per sector if N == 0 */
#define get_r0_N(ptr) ptr[6]
#define put_r0_N(ptr,val) ptr[6] = val
/*
* Class 1 - a split up way of looking at Status registers
* ST0 to ST2.
*/
/* Termination code */
#define get_r1_ST0_int_code(ptr) ((ptr[0] & 0xc0) >> 6)
#define put_r1_ST0_int_code(ptr,val) ptr[0] = (ptr[0] & ~0xc0) | ((val << 6) & 0xc0)
/* End of seek cmd */
#define get_r1_ST0_seek_end(ptr) ((ptr[0] & 0x20) >> 5)
#define put_r1_ST0_seek_end(ptr,val) ptr[0] = (ptr[0] & ~0x20) | ((val << 5) & 0x20)
/* Equipment fault */
#define get_r1_ST0_equipment(ptr) ((ptr[0] & 0x10) >> 4)
#define put_r1_ST0_equipment(ptr,val) ptr[0] = (ptr[0] & ~0x10) | ((val << 4) & 0x10)
/* Device not ready */
#define get_r1_ST0_not_ready(ptr) ((ptr[0] & 0x8) >> 3)
#define put_r1_ST0_not_ready(ptr,val) ptr[0] = (ptr[0] & ~0x8) | ((val << 3) & 0x8)
/* State of head */
#define get_r1_ST0_head_address(ptr) ((ptr[0] & 0x4) >> 2)
#define put_r1_ST0_head_address(ptr,val) ptr[0] = (ptr[0] & ~0x4) | ((val << 2) & 0x4)
/* Which drive */
#define get_r1_ST0_unit(ptr) (ptr[0] & 0x3)
#define put_r1_ST0_unit(ptr,val) ptr[0] = (ptr[0] & ~0x3) | ((val << 0) & 0x3)
/* Access off end of cylinder */
#define get_r1_ST1_end_of_cylinder(ptr) ((ptr[1] & 0x80) >> 7)
#define put_r1_ST1_end_of_cylinder(ptr,val) ptr[1] = (ptr[1] & ~0x80) | ((val << 7) & 0x80)
/* CRC error in data field/ID */
#define get_r1_ST1_data_error(ptr) ((ptr[1] & 0x20) >> 5)
#define put_r1_ST1_data_error(ptr,val) ptr[1] = (ptr[1] & ~0x20) | ((val << 5) & 0x20)
/* timeout of device */
#define get_r1_ST1_over_run(ptr) ((ptr[1] & 0x10) >> 4)
#define put_r1_ST1_over_run(ptr,val) ptr[1] = (ptr[1] & ~0x10) | ((val << 4) & 0x10)
/* sector not found */
#define get_r1_ST1_no_data(ptr) ((ptr[1] & 0x4) >> 2)
#define put_r1_ST1_no_data(ptr,val) ptr[1] = (ptr[1] & ~0x4) | ((val << 2) & 0x4)
/* write protected */
#define get_r1_ST1_write_protected(ptr) ((ptr[1] & 0x2) >> 1)
#define put_r1_ST1_write_protected(ptr,val) ptr[1] = (ptr[1] & ~0x2) | ((val << 1) & 0x2)
/* Cannot find adress mask/ID */
#define get_r1_ST1_no_address_mark(ptr) (ptr[1] & 0x1)
#define put_r1_ST1_no_address_mark(ptr,val) ptr[1] = (ptr[1] & ~0x1) | ((val << 0) & 0x1)
/* Deleted data found in Read/Scan */
#define get_r1_ST2_control_mark(ptr) ((ptr[2] & 0x40) >> 6)
#define put_r1_ST2_control_mark(ptr,val) ptr[2] = (ptr[2] & ~0x40) | ((val << 6) & 0x40)
/* CRC error in data field */
#define get_r1_ST2_data_field_error(ptr) ((ptr[2] & 0x20) >> 5)
#define put_r1_ST2_data_field_error(ptr,val) ptr[2] = (ptr[2] & ~0x20) | ((val << 5) & 0x20)
/* cylinder miss-match */
#define get_r1_ST2_wrong_cyclinder(ptr) ((ptr[2] & 0x10) >> 4)
#define put_r1_ST2_wrong_cyclinder(ptr,val) ptr[2] = (ptr[2] & ~0x10) | ((val << 4) & 0x10)
/* Match found in scan */
#define get_r1_ST2_scan_equal_hit(ptr) ((ptr[2] & 0x8) >> 3)
#define put_r1_ST2_scan_equal_hit(ptr,val) ptr[2] = (ptr[2] & ~0x8) | ((val << 3) & 0x8)
/* Sector not found during scan command */
#define get_r1_ST2_scan_not_satisfied(ptr) ((ptr[2] & 0x4) >> 2)
#define put_r1_ST2_scan_not_satisfied(ptr,val) ptr[2] = (ptr[2] & ~0x4) | ((val << 2) & 0x4)
/* Invalid cylinder found */
#define get_r1_ST2_bad_cylinder(ptr) ((ptr[2] & 0x2) >> 1)
#define put_r1_ST2_bad_cylinder(ptr,val) ptr[2] = (ptr[2] & ~0x2) | ((val << 1) & 0x2)
/* Missing Address mark */
#define get_r1_ST2_no_address_mark(ptr) (ptr[2] & 0x1)
#define put_r1_ST2_no_address_mark(ptr,val) ptr[2] = (ptr[2] & ~0x1) | ((val << 0) & 0x1)
/*
* Class 2 - sense drive status
*/
/* Device fault */
#define get_r2_ST3_fault(ptr) ((ptr[0] & 0x80) >> 7)
#define put_r2_ST3_fault(ptr,val) ptr[0] = (ptr[0] & ~0x80) | ((val << 7) & 0x80)
/* Write protected diskette */
#define get_r2_ST3_write_protected(ptr) ((ptr[0] & 0x40) >> 6)
#define put_r2_ST3_write_protected(ptr,val) ptr[0] = (ptr[0] & ~0x40) | ((val << 6) & 0x40)
/* Device is ready */
#define get_r2_ST3_ready(ptr) ((ptr[0] & 0x20) >> 5)
#define put_r2_ST3_ready(ptr,val) ptr[0] = (ptr[0] & ~0x20) | ((val << 5) & 0x20)
/* Track zero found */
#define get_r2_ST3_track_0(ptr) ((ptr[0] & 0x10) >> 4)
#define put_r2_ST3_track_0(ptr,val) ptr[0] = (ptr[0] & ~0x10) | ((val << 4) & 0x10)
/* Double sided diskette */
#define get_r2_ST3_two_sided(ptr) ((ptr[0] & 0x8) >> 3)
#define put_r2_ST3_two_sided(ptr,val) ptr[0] = (ptr[0] & ~0x8) | ((val << 3) & 0x8)
/* Side address signal */
#define get_r2_ST3_head_address(ptr) ((ptr[0] & 0x4) >> 2)
#define put_r2_ST3_head_address(ptr,val) ptr[0] = (ptr[0] & ~0x4) | ((val << 2) & 0x4)
/* Which unit is selected */
#define get_r2_ST3_unit(ptr) (ptr[0] & 0x3)
#define put_r2_ST3_unit(ptr,val) ptr[0] = (ptr[0] & ~0x3) | ((val << 0) & 0x3)
/*
* Class 3 - sense interrupt status
*/
/* status register 0 */
#define get_r3_ST0(ptr) ptr[0]
#define put_r3_ST0(ptr,val) ptr[0] = val
/* present cylinder number */
#define get_r3_PCN(ptr) ptr[1]
#define put_r3_PCN(ptr,val) ptr[1] = val
/*
* Class 4 - invalid codes
*/
/* status register 0 */
#define get_r4_ST0(ptr) ptr[0]
#define put_r4_ST0(ptr,val) ptr[0] = val
/* END: FDC RESULT BLOCK DEFINITIONS <<<<<<<<<<<<<<<<<<<<<<<<<<<< */
/*
* An entry data structure that holds information describing the number of bytes
* in the fdc command/result phases. The index is the fdc command code, see
* the INTEL Application note on the 8272A for a full description.
*
* The "result_byte" is the number of bytes in the standard FDC result phase
* while "gfi_result_byte" is the number of bytes in the pseudo result phase
* used by GFI and its server modules (ie some commands that do not normally
* have a result phase, use an implicit Sense Interrupt Status result phase).
*/
typedef struct {
half_word cmd_bytes; /* number of command bytes */
half_word result_bytes; /* number of result bytes */
half_word gfi_result_bytes; /* number of GFI result bytes */
half_word cmd_class; /* class of the command */
half_word result_class; /* class of the result */
boolean dma_required; /* dma required ? */
boolean int_required; /* interrupts required ? */
} FDC_DATA_ENTRY;
/*
* The following list the error codes that the GFI commands (see gfi.f) can
* return. 0 is considered to be success.
*/
#define GFI_PROTOCOL_ERROR 1
#define GFI_FDC_TIMEOUT 2
#define GFI_FDC_LOGICAL_ERROR 3
/*
* GFI Drive types
*/
#define GFI_DRIVE_TYPE_NULL 0 /* unidentified */
#define GFI_DRIVE_TYPE_360 1 /* 360K 5.25" */
#define GFI_DRIVE_TYPE_12 2 /* 1.2M 5.25" */
#define GFI_DRIVE_TYPE_720 3 /* 720K 3.5" */
#define GFI_DRIVE_TYPE_144 4 /* 1.44M 3.5" */
#define GFI_DRIVE_TYPE_288 5 /* 2.88M 3.5" */
#ifdef NTVDM
#define GFI_DRIVE_TYPE_MAX 6
#endif
/***************************************************************************
**
** Definitions and prototypes for the gfi_function_table,
** the functions therein, and the orthogonal floppy interface functions.
** Using the typedef'd prototypes should make it much easier to avoid
** definition clashes.
** This is now the only base floppy header file, and if you use the
** generic unix_flop.c module, the only floppy header anywhere. The generic
** code is meant to help a new unix port get quick floppy support; it is
** not meant to replace fancy host floppy code.
** The improvements that I have made to the floppy system in general are
** also supposed to make life easier.
**
** GM.
****************************************************************************
**
**
**
** The GFI has a structure containing pointers to functions that provide
** the diskette support for all possible drives (0-1) and drive types.
** Each floppy emmulator module has a function for loading this table
** with the module's own local functions which can then be used by the
** gfi system to emmulate the sort of device the module was designed for.
**
** This table (of two structures - one for each possible drive)
** is of course GLOBAL.
**
** The structure has the following fields:
**
** The GFI command function: GFI_FUNC_ENTRY.command_fn,
** The GFI drive on function: GFI_FUNC_ENTRY.drive_on_fn,
** The GFI drive off function: GFI_FUNC_ENTRY.drive_off_fn,
** The GFI reset function: GFI_FUNC_ENTRY.reset_fn,
** The GFI set high density function: GFI_FUNC_ENTRY.high_fn,
** The GFI drive type function: GFI_FUNC_ENTRY.drive_type_fn,
** The GFI disk changed function: GFI_FUNC_ENTRY.change_fn
**
** Structure definition:
** -----------------------
*/
typedef struct
{
SHORT (*command_fn) IPT2( FDC_CMD_BLOCK *, ip, FDC_RESULT_BLOCK *, res );
SHORT (*drive_on_fn) IPT1( UTINY, drive );
SHORT (*drive_off_fn) IPT1( UTINY, drive );
SHORT (*reset_fn) IPT2( FDC_RESULT_BLOCK *, res, UTINY, drive );
SHORT (*high_fn) IPT2( UTINY, drive, half_word, n);
SHORT (*drive_type_fn) IPT1( UTINY, drive );
SHORT (*change_fn) IPT1( UTINY, drive );
} GFI_FUNCTION_ENTRY;
/*
** ============================================================================
** External declarations and macros
** ============================================================================
**
**
**
** The data structure describing the fdc command/result phases, and the
** function pointer table set up by calls to the individual init functions
** in each of the GFI server modules.
**
**
**
** These tables are in gfi.c
*/
IMPORT GFI_FUNCTION_ENTRY gfi_function_table[];
IMPORT FDC_DATA_ENTRY gfi_fdc_description[];
/*
** The following functions form the interface between the GFI system
** and the floppy module (whichever). They are global, but the only access
** to the other functions gfi needs is via the gfi_function_table.
*/
IMPORT SHORT host_gfi_rdiskette_valid
IPT3(UTINY,hostID,ConfigValues *,vals,CHAR *,err);
IMPORT SHORT host_gfi_rdiskette_active
IPT3(UTINY, hostID, BOOL, active, CHAR, *err);
IMPORT SHORT gfi_empty_active
IPT3(UTINY, hostID, BOOL, active, CHAR, *err);
IMPORT VOID host_gfi_rdiskette_change
IPT2(UTINY, hostID, BOOL, apply);
#ifndef host_rflop_drive_type
/* new function to say what kind of drive we have
*/
IMPORT SHORT host_rflop_drive_type IPT2 (INT, fd, CHAR *, name);
#endif /* host_rflop_drive_type */
/* The gfi global functions. These need to be global because they are the
** interface to the private host dependant floppy functions. Each one does
** little more than call the real function via the table.
*/
/* The gfi_reset is special; not the same as the other floppy inits because
** it is called from main() to startup the gfi system by making both drives
** 'empty'. This means that it has no drive parameter.
*/
IMPORT SHORT gfi_drive_on IPT1( UTINY, drive );
IMPORT SHORT gfi_drive_off IPT1( UTINY, drive );
IMPORT SHORT gfi_low IPT1( UTINY, drive );
IMPORT SHORT gfi_drive_type IPT1( UTINY, drive );
IMPORT SHORT gfi_change IPT1( UTINY, drive );
IMPORT VOID gfi_init IPT0();
IMPORT SHORT gfi_reset IPT2( FDC_RESULT_BLOCK *, res, UTINY, drive );
IMPORT SHORT gfi_high IPT2( UTINY, drive, half_word, n);
IMPORT SHORT gfi_fdc_command IPT2( FDC_CMD_BLOCK *, ip, FDC_RESULT_BLOCK *, res );