aboutsummaryrefslogtreecommitdiff
path: root/w9x/inc
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2026-10-26 00:50:06 +0100
committerJavier <dev.git@javispedro.com>2026-10-26 00:50:06 +0100
commit6b8a368c51082fdd010ef5e1b0be4eb9b5059d1a (patch)
treee274d41a8dd5e912e20617a937a1fda5af91f8de /w9x/inc
parent9b1cf601360fb194047e6dcc2af75c2f38c611ec (diff)
downloadchu-6b8a368c51082fdd010ef5e1b0be4eb9b5059d1a.tar.gz
chu-6b8a368c51082fdd010ef5e1b0be4eb9b5059d1a.zip
refactor common parts into inc/ch375.h and add win9x, linux drivers
Diffstat (limited to 'w9x/inc')
-rw-r--r--w9x/inc/configmg.h213
-rw-r--r--w9x/inc/ios.h1520
-rw-r--r--w9x/inc/vmm.h161
-rw-r--r--w9x/inc/vxd.h132
4 files changed, 2026 insertions, 0 deletions
diff --git a/w9x/inc/configmg.h b/w9x/inc/configmg.h
new file mode 100644
index 0000000..d3cec38
--- /dev/null
+++ b/w9x/inc/configmg.h
@@ -0,0 +1,213 @@
+#ifndef CONFIGMG_H
+#define CONFIGMG_H
+
+/** CONFIGMG VxD services and types.
+ * Manually generated for now. */
+
+enum CONFIGMG_RESULT {
+ CR_SUCCESS = 0x0,
+ CR_DEFAULT = 0x1,
+ CR_OUT_OF_MEMORY = 0x2,
+ CR_INVALID_POINTER = 0x3,
+ CR_INVALID_FLAG = 0x4,
+ CR_INVALID_DEVNODE = 0x5,
+ CR_INVALID_RES_DES = 0x6,
+ CR_INVALID_LOG_CONF = 0x7,
+ CR_INVALID_ARBITRATOR = 0x8,
+ CR_INVALID_NODELIST = 0x9,
+ CR_DEVNODE_HAS_REQS = 0xA,
+ CR_INVALID_RESOURCEID = 0xB,
+ CR_DLVXD_NOT_FOUND = 0xC,
+ CR_NO_SUCH_DEVNODE = 0xD,
+ CR_NO_MORE_LOG_CONF = 0xE,
+ CR_ALREADY_SUCH_DEVNODE = 0x10,
+ CR_INVALID_RANGE_LIST = 0x11,
+ CR_INVALID_RANGE = 0x12,
+ CR_FAILURE = 0x13,
+ CR_NO_SUCH_LOGICAL_KEY = 0x14,
+ CR_CREATE_BLOCKED = 0x15,
+ CR_NOT_SYSTEM_VM = 0x16,
+ CR_REMOVE_VETOED = 0x17,
+ CR_APM_VETOED = 0x18,
+ CR_INVALID_LOAD_TYPE = 0x19,
+ CR_BUFFER_SMALL = 0x1A,
+ // ...
+};
+typedef uint32_t CONFIGRET;
+
+
+enum DLVXD_LOAD_TYPE {
+ DLVXD_LOAD_ENUMERATE = 0,
+ DLVXD_LOAD_DEVLOADER = 1,
+ DLVXD_LOAD_DRIVER = 2
+};
+
+// Handles
+/** Device node */
+typedef uint32_t DEVNODE;
+/** Logical configuration */
+typedef uint32_t LOG_CONF, *PLOG_CONF;
+
+#define MAX_MEM_REGISTERS 9
+#define MAX_IO_PORTS 20
+#define MAX_IRQS 7
+#define MAX_DMA_CHANNELS 7
+
+typedef _Packed struct cm_config {
+ uint16_t num_mem_windows;
+ uint32_t mem_base[MAX_MEM_REGISTERS];
+ uint32_t mem_length[MAX_MEM_REGISTERS];
+ uint16_t mem_attrib[MAX_MEM_REGISTERS];
+ uint16_t num_io_ports;
+ uint16_t io_port_base[MAX_IO_PORTS];
+ uint16_t io_port_length[MAX_IO_PORTS];
+ uint16_t num_irqs;
+ uint8_t irq_registers[MAX_IRQS];
+ uint8_t irq_attrib[MAX_IRQS];
+ uint16_t num_dmas;
+ uint8_t dma_lst[MAX_DMA_CHANNELS];
+ uint16_t dma_attrib[MAX_DMA_CHANNELS];
+ uint8_t reserved[3];
+} CMCONFIG;
+
+static inline CONFIGRET CONFIGMG_Get_Parent(DEVNODE *out, DEVNODE node, unsigned long flags);
+#pragma aux CONFIGMG_Get_Parent = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 3" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+static inline CONFIGRET CONFIGMG_Get_Child(DEVNODE *out, DEVNODE node, unsigned long flags);
+#pragma aux CONFIGMG_Get_Child = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 4" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+static inline CONFIGRET CONFIGMG_Get_Private_DWord(unsigned long *value, DEVNODE inDevNode, DEVNODE forDevNode, unsigned long flags);
+#pragma aux CONFIGMG_Get_Private_DWord = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 9" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+static inline CONFIGRET CONFIGMG_Set_Private_DWord(DEVNODE inDevNode, DEVNODE forDevNode, unsigned long value, unsigned long flags);
+#pragma aux CONFIGMG_Set_Private_DWord = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 10" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+static inline CONFIGRET CONFIGMG_Create_DevNode(DEVNODE *out, const char * deviceId, DEVNODE parent, unsigned long flags);
+#pragma aux CONFIGMG_Create_DevNode = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 11" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+static inline CONFIGRET CONFIGMG_Set_Bus_Info(DEVNODE devnode, uint32_t busType, unsigned long infoSize, void *info, unsigned long flags);
+#pragma aux CONFIGMG_Set_Bus_Info = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 67" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+static inline CONFIGRET CONFIGMG_Get_Bus_Info(DEVNODE devnode, uint32_t busType, unsigned long *infoSize, void *info, unsigned long flags);
+#pragma aux CONFIGMG_Set_Bus_Info = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 67" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+enum CONFIGFUNCS {
+ /** Check if the given resources are acceptable. */
+ CONFIG_FILTER = 0x0,
+ /** Start using hardware with the given resources. */
+ CONFIG_START = 0x1,
+ /** Stop using the allocated resources. */
+ CONFIG_STOP = 0x2,
+ CONFIG_TEST = 0x3,
+ /** Send to devnode and parents when removed from the tree.
+ * Stop using the hardware and deallocate all instance data. */
+ CONFIG_REMOVE = 0x4,
+ CONFIG_ENUMERATE = 0x5,
+ CONFIG_SETUP = 0x6,
+ CONFIG_CALLBACK = 0x7,
+ CONFIG_APM = 0x8,
+ CONFIG_TEST_FAILED = 0x9,
+ CONFIG_TEST_SUCCEEDED = 0xA,
+ CONFIG_VERIFY_DEVICE = 0xB,
+ CONFIG_PREREMOVE = 0xC,
+ CONFIG_SHUTDOWN = 0xD,
+ CONFIG_PREREMOVE2 = 0xE,
+ CONFIG_READY = 0xF,
+ CONFIG_PROP_CHANGE = 0x10,
+ CONFIG_PRIVATE = 0x11,
+ CONFIG_PRESHUTDOWN = 0x12
+};
+
+enum SUBCONFIGFUNCS {
+ CONFIG_START_DYNAMIC_START = 0x0,
+ CONFIG_START_FIRST_START = 0x1,
+
+ CONFIG_STOP_DYNAMIC_STOP = 0x0,
+ CONFIG_STOP_HAS_PROBLEM = 0x1,
+
+ CONFIG_REMOVE_DYNAMIC = 0x0,
+ CONFIG_REMOVE_SHUTDOWN = 0x1,
+ CONFIG_REMOVE_REBOOT = 0x2
+};
+
+typedef uint32_t CONFIGFUNC;
+typedef uint32_t SUBCONFIGFUNC;
+typedef CONFIGRET (__cdecl *CMCONFIGHANDLER)(CONFIGFUNC func, SUBCONFIGFUNC subFunc, DEVNODE devNode, unsigned long refData, unsigned long flags);
+enum register_device_driver_flags {
+ CM_REGISTER_DEVICE_DRIVER_STATIC = 0,
+ CM_REGISTER_DEVICE_DRIVER_DISABLEABLE = 1,
+ CM_REGISTER_DEVICE_DRIVER_REMOVABLE = 2
+};
+
+static inline CONFIGRET CONFIGMG_Register_Device_Driver(DEVNODE devNode, CMCONFIGHANDLER handler, unsigned long refData, unsigned long flags);
+#pragma aux CONFIGMG_Register_Device_Driver = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 14" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+typedef CONFIGRET (__cdecl *CMENUMFUNCTION)(CONFIGFUNC func, SUBCONFIGFUNC subFunc, DEVNODE bus, DEVNODE about, unsigned long flags);
+enum register_enumerator_flags {
+ CM_REGISTER_ENUMERATOR_SOFTWARE = 0,
+ CM_REGISTER_ENUMERATOR_HARDWARE = 1
+};
+
+static inline CONFIGRET CONFIGMG_Register_Enumerator(DEVNODE devNode, CMENUMFUNCTION handler, unsigned long flags);
+#pragma aux CONFIGMG_Register_Enumerator = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 15" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+
+enum LOG_CONF_FLAS {
+ BASIC_LOG_CONG = 0,
+ FILTERED_LOG_CONF = 1,
+ ALLOC_LOG_CONF = 2,
+ BOOT_LOG_CONF = 3,
+ FORCED_LOG_CONF = 4
+};
+
+static inline CONFIGRET CONFIGMG_Get_First_Log_Conf(LOG_CONF *logconf, DEVNODE devNode, unsigned long flags);
+#pragma aux CONFIGMG_Get_First_Log_Conf = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 26" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+static inline CONFIGRET CONFIGMG_Get_Next_Log_Conf(LOG_CONF *logconf, DEVNODE prevLogConf, unsigned long flags);
+#pragma aux CONFIGMG_Get_Next_Log_Conf = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 27" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+enum CM_GET_ALLOC_LOG_CONF_FLAGS {
+ CM_GET_ALLOC_LOG_CONF_ALLOC = 0,
+ CM_GET_ALLOC_LOG_CONF_BOOT_ALLOC = 1
+};
+
+static inline CONFIGRET CONFIGMG_Get_Alloc_Log_Conf(CMCONFIG *config, DEVNODE devNode, unsigned long flags);
+#pragma aux CONFIGMG_Get_Alloc_Log_Conf = \
+ "int 0x20" \
+ "dd ( 0x33 shl 16 ) + 59" \
+ __parm __caller [] __value [eax] __modify [eax ecx edx]
+
+#endif // CONFIGMG_H
diff --git a/w9x/inc/ios.h b/w9x/inc/ios.h
new file mode 100644
index 0000000..59214d8
--- /dev/null
+++ b/w9x/inc/ios.h
@@ -0,0 +1,1520 @@
+#ifndef IOS_H
+#define IOS_H
+
+/** This is a big mess of IOS structs and functions.
+ * They come from the storage.doc / FAQ.
+ * There are also some VxDCall wrappers, manually generated.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "sassert.h"
+
+typedef void __cdecl (*IO_callback)(struct IOP *iop);
+
+// IOS ================
+
+#define IOS_DEVICE_ID 0x10
+
+static inline uint32_t IOS_Get_Version(void);
+#pragma aux IOS_Get_Version = \
+ "int 0x20" \
+ "dd ( 0x10 shl 16 ) + 0" \
+ "jnc ok" \
+ "xor eax, eax" \
+ "ok:" \
+ __parm __caller [] __value [eax] __modify [ecx edx]
+
+static inline void IOS_Register(const struct DRP *drp);
+#pragma aux IOS_Register = \
+ "int 0x20" \
+ "dd ( 0x10 shl 16 ) + 7" \
+ __parm __caller [] __modify [eax ecx edx]
+
+// AEP ================
+
+typedef _Packed struct AEPHDR {
+ uint16_t AEP_func; // function; see below
+ uint16_t AEP_result; // result; set to zero if successful; see below
+ uint32_t AEP_ddb; // address of DDB
+ uint8_t AEP_lgn; // current load group number (from DVT)
+ uint8_t AEP_align[3]; // reserved; don't use
+} AEPHDR, *PAEPHDR;
+
+typedef _Packed struct AEP_bi_init {
+ AEPHDR AEP_bi_i_hdr;
+ uint32_t AEP_bi_reference_data; // optional value passed in from DRP
+ uint8_t AEP_bi_flags; // flags; see below
+ uint8_t AEP_bi_i_max_target; // max scsi target id
+ uint8_t AEP_bi_i_max_lun; // max scsi lun
+ uint32_t AEP_bi_i_dcb; // init DCB for port drivers
+ void* AEP_bi_i_hdevnode; // handle to devnode for this adapter
+ void* AEP_bi_i_regkey; // registry key for this adapter
+ uint8_t AEP_bi_i_align[1]; // reserved; don't use
+} AEP_bi_init, *PAEP_bi_init;
+
+typedef _Packed struct AEP_boot_done {
+ AEPHDR AEP_bi_i_hdr;
+} AEP_boot_done, *PAEP_boot_done;
+
+typedef _Packed struct AEP_dcb_config {
+ struct AEPHDR AEP_d_c_hdr;
+ struct DCB *AEP_d_c_dcb; // 32-bit ptr to DCB
+} AEP_dcb_config, *PAEP_dcb_config;
+
+typedef _Packed struct AEP_dcb_unconfig {
+ struct AEPHDR AEP_d_u_hdr;
+ struct DCB *AEP_d_u_dcb; // 32-bit ptr to DCB
+} AEP_dcb_unconfig, *PAEP_dcb_unconfig;
+
+typedef _Packed struct AEP_iop_timeout_occurred {
+ struct AEPHDR AEP_i_t_o_hdr;
+ struct IOP *AEP_i_t_o_iop; // address of IOP that timed out
+} AEP_iop_timeout_occurred, *PAEP_iop_timeout_occurred;
+
+typedef _Packed struct AEP_inquiry_device {
+ struct AEPHDR AEP_i_d_hdr;
+ uint32_t AEP_i_d_dcb; // address of DCB
+} AEP_inquiry_device, *PAEP_inquiry_device;
+
+typedef _Packed struct AEP_bi_uninit {
+ struct AEPHDR AEP_bi_u_hdr;
+} AEP_bi_uninit, *PAEP_bi_uninit;
+
+typedef struct AEP_dcb_unconfig_pend {
+ struct AEPHDR AEP_d_u_p_hdr;
+ struct DCB *AEP_d_u_p_dcb; // 32-bit ptr to DCB
+} AEP_dcb_unconfig_pend, *PAEP_dcb_unconfig_pend;
+
+typedef _Packed union AEP {
+ struct AEPHDR;
+ struct AEP_bi_init bi_i;
+ struct AEP_boot_done b_d;
+ struct AEP_dcb_config d_c;
+ struct AEP_dcb_unconfig d_u;
+ struct AEP_iop_timeout_occurred i_t_o;
+ struct AEP_inquiry_device i_d;
+ struct AEP_bi_uninit bi_u;
+ struct AEP_dcb_unconfig_pend d_u_p;
+} AEP, *PAEP;
+
+typedef enum AEP_result {
+ AEP_SUCCESS = 0,
+ AEP_FAILURE = -1,
+
+ AEP_NO_INQ_DATA = 1,
+ AEP_NO_MORE_DEVICES = 2
+} AEP_result;
+
+enum AEP_funcs {
+ /** initializes driver/interface */
+ AEP_INITIALIZE = 0,
+ /** indicates system critical shutdown */
+ AEP_SYSTEM_CRIT_SHUTDOWN = 1,
+ /** booting done - switch to run time */
+ AEP_BOOT_COMPLETE = 2,
+ /* configure device */
+ AEP_CONFIG_DCB = 3,
+ /* unconfigure device */
+ AEP_UNCONFIG_DCB = 4,
+ /* iop timeout occured */
+ AEP_IOP_TIMEOUT = 5,
+ /* get device indentification data */
+ AEP_DEVICE_INQUIRY = 6,
+ /* 1/2 second interval notification */
+ AEP_HALF_SEC = 7,
+ /* one second interval notification */
+ AEP_1_SEC = 8,
+ /* two second interval notification */
+ AEP_2_SECS = 9,
+ /* four second interval notification*/
+ AEP_4_SECS = 10,
+ /* parameters for '.I' debug command*/
+ AEP_DBG_DOT_CMD = 11,
+ /* associate logical DCBs w/ physical */
+ AEP_ASSOCIATE_DCB = 12,
+ /* IFSMGR about to hook in */
+ AEP_REAL_MODE_HANDOFF = 13,
+ /* indicates system shutdown */
+ AEP_SYSTEM_SHUTDOWN = 14,
+ /* uninitialize driver/interface */
+ AEP_UNINITIALIZE = 15,
+ /* logical dcb is going to be locked */
+ AEP_DCB_LOCK = 16,
+ /* notify drivers of volume mount */
+ AEP_MOUNT_NOTIFY = 17,
+ /* notify drivers of VRP creation */
+ AEP_CREATE_VRP = 18,
+ /* notify drivers of VRP destruction */
+ AEP_DESTROY_VRP = 19,
+ /* tell drivers to refresh drive data */
+ AEP_REFRESH_DRIVE = 20,
+ /** tell drivers that DCB removal is pending */
+ AEP_PEND_UNCONFIG_DCB = 21,
+ /** notify int13 of a possible change in the int 1eh vector for copy protection */
+ AEP_1E_VEC_UPDATE = 22,
+ /** inform driver vsd to change the floppy spindle speed */
+ AEP_CHANGE_RPM = 23,
+};
+
+// BlockDev ===========
+
+typedef struct BlockDev_Scatter_Gather{
+ uint32_t BD_SG_Count; // Block count; else byte count if IORF_CHAR_COMMAND set
+ void* BD_SG_Buffer_Ptr;
+} _BlockDev_Scatter_Gather;
+
+enum BDD_FLAGS {
+ BDF_Int13_Drive = 0x01,
+ BDF_Int13_Drive_Bit = 0,
+
+ BDF_Writeable = 0x02,
+ BDF_Writeable_Bit = 1,
+
+ BDF_Removable = 0x04,
+ BDF_Removable_Bit = 2,
+
+ BDF_Remote = 0x08,
+ BDF_Remote_Bit = 3,
+
+ BDF_Serial_Cmd = 0x10,
+ BDF_Serial_Cmd_Bit = 4,
+
+ BDF_Cache = 0x20,
+ BDF_Cache_Bit = 5,
+};
+
+// DCB ================
+
+typedef _Packed struct _DCB_COMMON {
+ uint32_t DCB_physical_dcb; // DCB for physical device
+ uint32_t DCB_expansion_length; // expansion length; see below
+ struct DCB_cd_entry *DCB_ptr_cd; // address of calldown list
+ uint32_t DCB_next_dcb; // link to next DCB
+ uint32_t DCB_next_logical_dcb; // address of next logical dcb
+ uint8_t DCB_drive_lttr_equiv; // drive number; see below
+ uint8_t DCB_unit_number; // drive or unit #; see below
+ uint16_t DCB_TSD_Flags; // TSD flags; see below
+
+ // Volume Tracking
+ uint32_t DCB_vrp_ptr; // address of VRP for this DCB
+ uint32_t DCB_dmd_flags; // demand bits; see below
+ uint32_t DCB_device_flags; // general purpose flags; see DCB_DEV_FLAGS
+ uint32_t DCB_device_flags2; // general purpose flags; see DCB_DEV_FLAGS2
+ uint32_t DCB_Partition_Start; // partition start sector
+ uint32_t DCB_track_table_ptr; // address of track table buffer
+ // for ioctls
+ uint32_t DCB_bds_ptr; // DOS BDS corresp. to this DCB
+ // (logical DCB's only)
+ uint32_t DCB_Reserved1; // reserved; must be zero
+ uint32_t DCB_Reserved2; // reserved; must be zero
+ uint8_t DCB_apparent_blk_shift; // log of apparent_blk_size
+ uint8_t DCB_partition_type; // partition type
+ uint16_t DCB_sig; // padding and signature
+ uint8_t DCB_device_type; // device type; see below
+ uint32_t DCB_Exclusive_VM; // exclusive access handle
+ uint8_t DCB_disk_bpb_flags; // BPB flags; see below
+ uint8_t DCB_cAssoc; // # of assoc. logical drives
+ uint8_t DCB_Sstor_Host; // indicates a sstor host volume
+ uint16_t DCB_user_drvlet; // userdriveletter settings or 0xff
+ uint16_t DCB_Reserved3; // reserved; must be zero
+ uint32_t DCB_Reserved4; // reserved; must be zero
+} DCB_COMMON, *PDCB_COMMON;
+
+typedef _Packed struct _DCB_BLOCKDEV {
+ uint32_t DCB_BDD_Next;
+ uint8_t DCB_BDD_BD_Major_Version; // INIT <BDD_BD_Major_Ver>
+ uint8_t DCB_BDD_BD_Minor_Version; // INIT <BDD_BD_Minor_Ver>
+ uint8_t DCB_BDD_Device_SubType;
+ uint8_t DCB_BDD_Int_13h_Number;
+ uint32_t DCB_BDD_flags; // was BDD_Flags
+ char * DCB_BDD_Name_Ptr;
+
+ // Apparent geometry as seen by TSD and above
+ uint64_t DCB_apparent_sector_cnt; // # of sectors
+ uint32_t DCB_apparent_blk_size; // blk size of device
+ uint32_t DCB_apparent_head_cnt; // # of heads
+ uint32_t DCB_apparent_cyl_cnt; // # of cylinders
+ uint32_t DCB_apparent_spt; // # of secs/trk
+
+ uint32_t DCB_BDD_Sync_Cmd_Proc;
+ uint32_t DCB_BDD_Command_Proc;
+ uint32_t DCB_BDD_Hw_Int_Proc; // INIT <0>
+ uint32_t DCB_BDP_Cmd_Queue_Ascending;
+ uint32_t DCB_BDP_Cmd_Queue_Descending;
+ uint32_t DCB_BDP_Current_Flags;
+ uint32_t DCB_BDP_Int13_Param_Ptr;
+ uint32_t DCB_BDP_Current_Command;
+ uint32_t DCB_BDP_Current_Position[2];
+ uint32_t DCB_BDP_Reserved[5];
+ uint32_t DCB_fastdisk_bdd; // set for DCBs created when a
+ // fastdisk regs with the
+ // blockdev BDD for it. Else 0.
+} DCB_BLOCKDEV, *PDCB_BLOCKDEV;
+
+
+typedef _Packed struct DCB {
+ DCB_COMMON DCB_cmn; // common information
+ uint32_t DCB_max_xfer_len; // maximum transfer length
+
+ // Actual geometry data (as seen below the TSD)
+ uint64_t DCB_actual_sector_cnt; // number of sectors
+ uint32_t DCB_actual_blk_size; // actual block size of the device
+ uint32_t DCB_actual_head_cnt; // number of heads
+ uint32_t DCB_actual_cyl_cnt; // number of cylinders
+ uint32_t DCB_actual_spt; // number of sectors per track
+
+ void* DCB_next_ddb_dcb; // link to next DCB on DDB chain
+ void* DCB_dev_node; // address of dev node for device
+ uint8_t DCB_bus_type; // Bus type; see below
+ uint8_t DCB_bus_number; // channel (cable) within adapter
+ uint8_t DCB_queue_freeze; // queue freeze depth counter
+ uint8_t DCB_max_sg_elements; // max # s/g elements; see below
+
+ // Volume tracking layer use only
+ uint8_t DCB_io_pend_count; // # of pending requests for DCB
+ uint8_t DCB_lock_count; // # of LOCK MEDIA commands
+
+ // SCSI
+ uint16_t DCB_SCSI_VSD_FLAGS; // Flags for SRB builder
+ uint8_t DCB_scsi_target_id; // SCSI target ID
+ uint8_t DCB_scsi_lun; // SCSI logical unit number
+ uint8_t DCB_scsi_hba; // prot-driver-relative adapter #
+ uint8_t DCB_max_sense_data_len; // Maximum sense length
+ uint16_t DCB_srb_ext_size; // miniport srb extension length
+
+ uint8_t DCB_inquiry_flags[8]; // Device inquiry flags
+ char DCB_vendor_id[8]; // Vendor ID string
+ char DCB_product_id[16]; // Product ID string
+ char DCB_rev_level[4]; // Product revision level
+ char DCB_port_name[8]; //
+ uint8_t DCB_current_unit; // current unit #; see below
+
+ // Volume tracking layer use only
+ uint32_t DCB_blocked_iop; // address of requests for an
+ // inactive volume
+
+ uint32_t DCB_vol_unlock_timer; // unlock timer handle
+ uint8_t DCB_access_timer; // time measure between accesses
+
+ // Volume tracking layer use only
+ uint8_t DCB_Vol_Flags; // Volume tracking; see below
+
+ uint8_t DCB_q_algo; // algorithm index; see below
+ uint8_t DCB_unit_on_ctl; // 0-based device number on ctlr
+ uint32_t DCB_Port_Specific; // bytes for port driver use
+ uint32_t DCB_spindown_timer; // timer for drive spin down
+
+ DCB_BLOCKDEV DCB_bdd;
+} DCB, *PDCB;
+
+/** Contains information about a calldown entry. */
+typedef _Packed struct DCB_cd_entry {
+ IO_callback DCB_cd_io_address; // address of request routine
+ uint32_t DCB_cd_flags; // demand bits; see below
+ struct DDB *DCB_cd_ddb; // driver's DDB pointer
+ struct DCB_cd_entry *DCB_cd_next; // address of next cd entry
+ uint16_t DCB_cd_expan_off; // offset of expansion area
+ uint8_t DCB_cd_layer_flags; // flags for layer's use
+ uint8_t DCB_cd_lgn; // load group number
+} DCB_cd_entry, *PDCB_cd_entry;
+
+enum DCB_BUS {
+ DCB_BUS_ESDI = 0,
+ DCB_BUS_SCSI = 1,
+ DCB_BUS_NEC = 2,
+ DCB_BUS_SMART = 3,
+ DCB_BUS_ABIOS = 4
+};
+
+enum DCB_TSD_FLAGS {
+ /** Don't trust the BPB */
+ DCB_TSD_INVALID_PARTITION = 1,
+ /** Bad MBR (physical device only) */
+ DCB_TSD_BAD_MBR = 1,
+ /** User drive letters checked */
+ DCB_TSD_USER_LETTERS_CHECKED = (1 << 1),
+ /** User drive letters checked first time */
+ DCB_TSD_FIRST_USER_CHECK = (1 << 2),
+ /** User set the a drive letter range */
+ DCB_TSD_USER_SET = (1 << 4),
+ /** User int 13 disabled */
+ DCB_TSD_NO_USER_INT13 = 0x020,
+ /** Protmode only int 13 */
+ DCB_TSD_PROTMODE_INT_13 = (1 << 6),
+ /** Reserved drive letter */
+ DCB_TSD_NONEXIST_PARTITION = (1 << 7),
+ /** Recommend BPB set from PBR by TSD (from int 41 or int 46) */
+ DCB_TSD_MBPB_PBR = 0x0100,
+ /** Bit shift for recommended BPB initialized */
+ DCB_TSD_RBPB_INIT = (1 << 9),
+ /** Media BPB initialized */
+ DCB_TSD_MBPB_INIT = 0x0400,
+ /** Apparent set from primary PBR */
+ DCB_TSD_APPARENT_PBR = 0x0800,
+ /** Apparent set from ROM data */
+ DCB_TSD_APPARENT_ROM = 0x1000,
+ /** Actual set from apparent by TSD */
+ DCB_TSD_ACTUAL_SET = 0x2000,
+ /** Actual geometry set prior to TSD */
+ DCB_TSD_ACTUAL_PRE_SET = 0x4000,
+ /** Apparent geometry set prior to TSD */
+ DCB_TSD_APPARENT_PRE_SET = 0x8000
+};
+
+enum DCB_DEV_FLAGS
+{
+ /** indicates drive supports spindown command */
+ DCB_DEV_SPINDOWN_SUPPORTED_BIT = 31,
+ DCB_DEV_SPINDOWN_SUPPORTED = (1 << DCB_DEV_SPINDOWN_SUPPORTED_BIT),
+
+ /* indicates drive is currently spun down */
+ DCB_DEV_SPUN_DOWN_BIT = 30,
+ DCB_DEV_SPUN_DOWN = (1 << DCB_DEV_SPUN_DOWN_BIT),
+
+ /* port driver use only - indicates I/O has been received for this DCB */
+
+ DCB_DEV_IO_ACTIVE_BIT = 29,
+ DCB_DEV_IO_ACTIVE = (1 << DCB_DEV_IO_ACTIVE_BIT),
+
+ /* this device has been configured as an int 13 drive */
+
+ DCB_DEV_INT13_CONFIGURED_BIT = 28,
+ DCB_DEV_INT13_CONFIGURED = (1 << DCB_DEV_INT13_CONFIGURED_BIT),
+
+ /* This DCB cannot handle ASPI or CAM requests */
+
+ DCB_DEV_NO_ASPICAM_BIT = 27,
+ DCB_DEV_NO_ASPICAM = (1 << DCB_DEV_NO_ASPICAM_BIT),
+
+ /* this device is going away soon */
+ DCB_DEV_REMOVAL_PENDING_BIT = 26,
+ DCB_DEV_REMOVAL_PENDING = (1 << DCB_DEV_REMOVAL_PENDING_BIT),
+
+ /* logical drives for this int 13 device are controlled by the mapper */
+ DCB_DEV_RMM_INT13_BIT = 25,
+ DCB_DEV_RMM_INT13 = (1 << DCB_DEV_RMM_INT13_BIT),
+
+ /* this device has been processed by a TSD */
+ DCB_DEV_TSD_PROCESSED_BIT = 24,
+ DCB_DEV_TSD_PROCESSED = (1 << DCB_DEV_TSD_PROCESSED_BIT),
+
+ /* this is an equivlaent of IRS_DRV_SINGLE_FLOPPY. This indicates that */
+ /* the dmd_a_b_toggling is not set in the floppy dcb. */
+ DCB_DEV_SINGLE_FLOPPY = 0x00800000,
+
+ /* this device must be controlled by a real mode driver, and should not */
+ /* be taken over in protected mode */
+ DCB_DEV_REAL_MODE = 0x00400000,
+
+ /* current queing direction is descending - used by port drivers or IOS if */
+ /* DCB_SERIAL_CMD flag is set */
+ DCB_DEV_QUE_DESCEND = 0x00200000,
+
+ /* hardware indicated media change */
+ DCB_DEV_MEDIA_CHANGED = 0x00100000,
+
+ /* bit indicates the disk geometry has become invalid. */
+ DCB_DEV_INVALID_GEOM = 0x00080000,
+
+ /* If this bit is set, it specifies not have the volume tracking layer do
+ * the 2 second timing stuff for media change. This bit is typically set
+ * if DCB_DEV_SYNC_MED_CHG_SUPPORT is set.
+ */
+ DCB_DEV_INHIBIT_SW_TIMED_SUPPORT = 0x00040000, /* drive is in read only mode */
+
+ /* drive has h/w support to indicate by interrupt that disk door has been
+ * popped open, etc.
+ */
+ DCB_DEV_ASYNC_MED_CHG_SUPPORT = 0x00020000,
+
+ /* drive has h/w sync med. chg supp. -- when u first access a drive with
+ * media changed, drive returns an error.
+ */
+ DCB_DEV_SYNC_MED_CHG_SUPPORT = 0x00010000,
+
+ DCB_DEV_PHYSICAL = 0x00008000, /* on = physical */
+ DCB_DEV_LOGICAL = 0x00004000, /* on = logical */
+ DCB_DEV_LOGICAL_BIT = 14,
+
+ DCB_DEV_RMM = 0x00002000, /* on = real mode mapper DCB*/
+ DCB_DEV_RMM_BIT = 13,
+
+ DCB_DEV_UNCERTAIN_MEDIA = 0x00001000, /* media may have been changed */
+ DCB_DEV_ROM_CFG_REQ = 0x00000800, /* tsd must use rom chain data */
+
+ DCB_DEV_MUST_CONFIGURE = 0x00000400,/* set at create dcb time */
+ /* cleared after all layers */
+ /* get the config aep for */
+ /* this DCB. */
+
+ DCB_DEV_SSTOR_VOL = 0x00000200, /* set if this is SSTOR volume */
+
+ DCB_DEV_PAGING_DEVICE = 0x00000100, /* indicates that the paging drive */
+ /* is on this DCB */
+
+ DCB_CHAR_DEVICE = 0x00000080, /* indicates that this is a char dev*/
+ /*
+ * The foll. DCB_DEV_I13_IN_PROGRESS flag is used in conjunction with RMM
+ * and the global DCB. This flag is set when an int 13 in progress, in
+ * iosint13.asm, and cleared when the int 13 is done.
+ */
+
+ DCB_DEV_I13_IN_PROGRESS = 0x00000040,
+
+ /** Cached device */
+ DCB_DEV_CACHE = 0x00000020 ,
+ /** Serial commands */
+ DCB_DEV_SERIAL_CMD = 0x00000010,
+ /** Remote device */
+ DCB_DEV_REMOTE = 0x00000008,
+ /* Removable media */
+ DCB_DEV_REMOVABLE = 0x00000004 ,
+ DCB_DEV_REMOVABLE_BIT = 2,
+ /** Writeable media */
+ DCB_DEV_WRITEABLE = 0x00000002,
+ /** Int 13h drive */
+ DCB_DEV_INT13_DRIVE = 0x00000001,
+};
+
+enum DCB_DEV2_FLAGS {
+ DCB_DEV2_THREAD_LOCK = 0x00000001,
+ DCB_DEV2_THREAD_LOCK_BIT = 0,
+
+ DCB_DEV2_ATAPI_DEVICE = 0x00000002,
+ DCB_DEV2_ATAPI_DEVICE_BIT = 1,
+
+ DCB_DEV2_DMF_DISK = 0x00000004, /* indicates current media is DMF */
+ DCB_DEV2_DMF_DISK_BIT = 2,
+
+ DCB_DEV2_I13_COPY_PROT = 0x00000008,/* indicates int 13 copy protection */
+ DCB_DEV2_I13_COPY_PROT_BIT = 3, /* access to one of the floppies */
+
+ DCB_DEV2_FAIL_FORMAT = 0x00000010, /* indicates that we cannot allow format*/
+ DCB_DEV2_FAIL_FORMAT_BIT = 4,
+
+ DCB_DEV2_FLOPTICAL = 0x00000020, /* indicates device is floptical */
+ DCB_DEV2_FLOPTICAL_BIT = 5,
+};
+
+enum DCB_TYPE {
+ DCB_type_disk = 0x00, /* All Direct Access Devices -- non-removable */
+ DCB_type_tape = 0x01, /* Sequencial Access Devices */
+ DCB_type_printer = 0x02, /* Printer Device */
+ DCB_type_processor = 0x03, /* Processor type device */
+ DCB_type_worm = 0x04, /* Write Once Read Many Device */
+ DCB_type_cdrom = 0x05, /* CD ROM Device */
+ DCB_type_scanner = 0x06, /* Scanner Device */
+ DCB_type_optical_memory = 0x07, /* some Optical disk */
+ DCB_type_changer = 0x08, /* Changer device e.g. juke box */
+ DCB_type_comm = 0x09, /* Communication devices */
+ DCB_type_floppy = 0x0A, /* devices like floppy */
+ DCB_type_optical_nec = 0x84 /* NEC 5.25" optical disk */
+};
+
+enum DCB_dmd_flags {
+ DCB_dmd_srb_cdb = 0x00000001, /* there must be an srb and cdb for */
+ /* each ior. */
+ DCB_dmd_rsrv_1 = 0x00000002, /* reserved - must be zero. */
+
+ DCB_dmd_logical = 0x00000004, /* media address must be logical and*/
+ /* dcb must be for a logical device.*/
+
+ DCB_dmd_physical = 0x00000008, /* media adresses must be physical */
+ /* and dcb must be for a physical */
+ /* device. */
+
+ DCB_dmd_small_memory = 0x00000010, /* data buffers must reside in */
+ /* in low 16M. */
+
+ DCB_dmd_rsrv_2 = 0x00000020, /* reserved - must be zero. */
+
+ DCB_dmd_rsrv_3 = 0x00000040, /* reserved - must be zero. */
+ DCB_dmd_rsrv_4 = 0x00000080, /* reserved - must be zero. */
+
+ DCB_dmd_not_512 = 0x00000100, /* sector size on the media is not */
+ /* 512 bytes */
+
+ DCB_dmd_word_align = 0x00000200, /* data buffers must be word */
+ /* aligned. */
+
+ DCB_dmd_dword_align = 0x00000400, /* data buffers must be double word */
+ /* aligned. */
+
+ DCB_dmd_phys_sgd = 0x00000800, /* scatter/gather descriptors must */
+ /* contain physical addresses (they */
+ /* will contain linear addresses if */
+ /* this demand bit is not set). */
+
+ DCB_dmd_phys_sgd_ptr = 0x00001000, /* the pointer to the first */
+ /* scatter/gather descriptor */
+ /* (IOR_sgd_lin_phys) must be a */
+ /* physical address (it will be a */
+ /* linear addresses if this demand */
+ /* bit is not set). */
+
+ /* If foll. bit set, single floppy drive system -- voltrack needs to do
+ * the toggling between A: and B: when accesses to made to these drive
+ * letters. */
+ DCB_dmd_do_a_b_toggling = 0x00002000,
+
+ DCB_dmd_query_remov = 0x00004000, /* lower level must be called to */
+ /* check if media is removeable/has */
+ /* changed. */
+
+ DCB_dmd_request_sns = 0x00008000, /* port driver cannot perform autosense */
+ DCB_dmd_lock_unlock_media = 0x00010000, /* media supports software locking */
+ DCB_dmd_load_eject_media = 0x00020000, /* media supports electronic eject */
+ DCB_dmd_clear_media_chg = 0x00040000, /* command to clear media change */
+ DCB_dmd_serialize_bit = 19, /* layer requires request serialization */
+ DCB_dmd_serialize = 1 << DCB_dmd_serialize_bit,
+ DCB_dmd_prot_mode = 0x00100000, /* override real mode checks for */
+ /* this device i.e. ATAPI cdrom */
+ DCB_dmd_no_xclusive = 0x00200000, /* indicates exclusive access is */
+ /* not required for abs write */
+ DCB_dmd_pageability = 0x00400000, /* indicates that access to this volume */
+ /* can cause paging */
+
+ DCB_dmd_rsrv = DCB_dmd_rsrv_1+DCB_dmd_rsrv_2+DCB_dmd_rsrv_3+DCB_dmd_rsrv_4
+};
+
+
+
+// DDB ================
+
+typedef _Packed struct DDB { //
+ uint32_t DDB_phys_addr; // Physical address of ddb
+ uint32_t DDB_Next_DDB; // next DDB on DVT_DDB chain
+ uint32_t DDB_Next_DDB_init; // next DDB on DVT_DDB_init chain
+ uint32_t DDB_dcb_ptr; // address of first DCB owned by this DDB
+ uint8_t DDB_number_buses; // # of buses supported by the adapter
+ uint8_t DDB_ios_flags; // IOS flags; see below
+ uint16_t DDB_sig; // DDB signature; also padding
+ void* DDB_dvt; // address of this DDB's DVT
+ void* DDB_devnode_ptr; // address of devnode for device
+ void* DDB_reserved; // reserved; must be zero
+} DDB , *PDDB;
+
+
+// DRP ================
+
+typedef _Packed struct DRP {
+ char DRP_eyecatch_str[8]; // eye catcher string
+ uint32_t DRP_LGN; // load group number; see below
+ void* DRP_aer; // addr of asynchronous event routine
+ struct ILB *DRP_ilb; // address of ILB; see below
+ char DRP_ascii_name[16]; // driver name; see below
+ uint8_t DRP_revision; // driver revision
+ uint32_t DRP_feature_code; // feature code; see below
+ uint16_t DRP_if_requirements; // I/F requirements; see below
+ uint8_t DRP_bus_type; // type of I/O bus; see below
+ uint16_t DRP_reg_result; // registration result; see below
+ uint32_t DRP_reference_data; // data to pass with AEP_INITIALIZE
+ uint8_t DRP_reserved1[2]; // reserved
+ uint32_t DRP_reserved2[1]; // reserved; must be zero
+} DRP, *PDRP;
+
+enum DRP_IF {
+ DRP_IF_ISA = 0x01,
+ DRP_IF_EISA = 0x02,
+ DRP_IF_MCA = 0x04,
+ DRP_IF_STD = 0xFF
+};
+
+enum DRP_LGN {
+ /* Installable File System layer. */
+ DRP_FSD = 1 << 0x02,
+ /** Other port drivers. */
+ DRP_MISC_PD = 1 << 0x13
+};
+
+enum DRP_reg_result {
+ /* Driver should remain resident */
+ DRP_REMAIN_RESIDENT = 1,
+ /* Driver should minimize */
+ DRP_MINIMIZE = 2,
+ /* Driver should not load */
+ DRP_ABORT = 3,
+ /* bad layer number - abort driver */
+ DRP_INVALID_LAYER = 4
+};
+
+
+// ILB ==================
+
+typedef _Packed struct ILB {
+ /* service routine */
+ void __cdecl (*ILB_service)(struct ISP *pisp);
+ void __cdecl (*ILB_dprintf)(const char *format, ...);
+ /** waits for 1/10 seconds. */
+ void __cdecl (*ILB_Wait_10th_Sec)(void);
+ void* ILB_internal_request; // addr of request routine
+ void* ILB_io_criteria_rtn; // addr of IOR criteria routine
+ void* ILB_int_io_criteria_rtn; // addr of IOP criteria routine
+ uint32_t ILB_dvt; // offset to addr of driver's DVT
+ uint32_t ILB_ios_mem_virt; // addr of IOS memory pool
+ void __cdecl (*ILB_enqueue_iop)(struct IOP *iop, struct DCB *dcb);
+ struct IOP * __cdecl (*ILB_dequeue_iop)(struct DCB *dcb);
+ uint32_t ILB_reserved_1; // reserved; must be zero
+ uint32_t ILB_reserved_2; // reserved; must be zero
+ uint16_t ILB_flags; // flags
+ uint8_t ILB_driver_numb; // number of calls to AEP_INITIALIZE
+ uint8_t ILB_reserved_3; // reserved; must be zero
+} ILB, *PILB;
+
+// IOR =================
+
+typedef _Packed struct type_sdeffsd_req_usage { /* */
+ uint16_t _IOR_ioctl_drive;
+ uint16_t _IOR_ioctl_function ;
+ uint32_t _IOR_ioctl_control_param ;
+ uint32_t _IOR_ioctl_buffer_ptr;
+ uint32_t _IOR_ioctl_client_params;
+ uint32_t _IOR_ioctl_return;
+} _type_sdeffsd_req_usage;
+
+typedef _Packed union urequestor_usage { /* */
+ uint32_t _IOR_requestor_usage[5];
+ struct type_sdeffsd_req_usage sdeffsd_req_usage;
+} _urequestor_usage;
+
+typedef void (* CMDCPLT)(void);
+
+typedef _Packed struct _IOR {
+ uint32_t IOR_next; // client link; see below
+ uint16_t IOR_func; // function; see below
+ uint16_t IOR_status; // request status; see below
+ uint32_t IOR_flags; // request flags; see below
+ CMDCPLT IOR_callback; // address of callback; see below
+ uint64_t IOR_start_addr; // starting address; see below
+ uint32_t IOR_xfer_count; // # of sectors/bytes; see below
+ void* IOR_buffer_ptr; // client buffer; see below
+ uint32_t IOR_private_client; // BlockDev/IOS client reserved
+ uint32_t IOR_private_IOS; // reserved space for IOS
+ uint32_t IOR_private_port; // private area for port driver
+ union urequestor_usage _ureq; // requestor usage; see below
+ uint32_t IOR_req_req_handle; // request handle; see below
+ uint32_t IOR_req_vol_handle; // media handle; see below
+ uint32_t IOR_sgd_lin_phys; // first physical SGD; see below
+ uint8_t IOR_num_sgds; // number of physical SGDs
+ uint8_t IOR_vol_designtr; // drive letter; see below
+ uint16_t IOR_ios_private_1; // reserved by IOS to force alignment
+ uint32_t IOR_reserved_2[2]; // reserved for internal use
+} IOR, *PIOR;
+
+/** command codes for IOR_func as defined above */
+enum IOR_funcs {
+ /*
+ ** IOR_READ
+ **
+ ** Function:
+ **
+ ** Reads the # of sectors/bytes as specified in IOR_xfer_count.
+ ** See PDK documentation for specifics of parameter setting.
+ **
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_READ = 0x00,
+
+ /*
+ ** IOR_WRITE
+ **
+ ** Function:
+ **
+ ** Writes the # of sectors/bytes as specified in IOR_xfer_count.
+ ** See PDK documentation for specifics of parameter setting.
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_WRITE = 0x01,
+
+ /*
+ ** IOR_VERIFY
+ **
+ ** Function:
+ **
+ ** Verifies the # of sectors/bytes as specified in IOR_xfer_count.
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_VERIFY = 0x02, /* verify data on device */
+
+ /*
+ ** IOR_CANCEL
+ **
+ ** Function:
+ **
+ ** Cancels the IOR referenced in ...
+ **
+ ** Notes:
+ **
+ ** Currently not supported in Chicago
+ **
+ */
+
+ IOR_CANCEL = 0x03,
+
+ /*
+ ** IOR_WRITEV
+ **
+ ** Function:
+ **
+ ** Writes and verifies the # of sectors/bytes as specified in IOR_xfer_count.
+ **
+ ** Notes:
+ **
+ ** Some hardware (IDE, for example) does not support this function.
+ **
+ */
+
+ IOR_WRITEV = 0x04,
+
+ /*
+ ** IOR_MEDIA_CHECK
+ **
+ ** Function:
+ **
+ ** Checks to see if media has changed, and returns status in IOR_status.
+ **
+ ** Notes:
+ **
+ ** Obsolete. Use MEDIA_CHECK_RESET below
+ **
+ */
+
+ IOR_MEDIA_CHECK = 0x05,
+
+ /*
+ ** IOR_MEDIA_CHECK_RESET
+ **
+ ** Function:
+ **
+ ** Checks to see if media has changed, and returns status in IOR_status.
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_MEDIA_CHECK_RESET = 0x06,
+
+ /*
+ ** IOR_LOAD_MEDIA
+ **
+ ** Function:
+ **
+ ** Performs a LOAD MEDIA operation on removable drives.
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_LOAD_MEDIA = 0x07,
+
+ /*
+ ** IOR_EJECT_MEDIA
+ **
+ ** Function:
+ **
+ ** Performs an EJECT MEDIA operation on removable drives.
+ **
+ ** Notes:
+ **
+ ** For disk and CD-ROM devices, applications are queried before eject,
+ ** and the lock count is checked for zero. If one of these checks fails,
+ ** the user is queried to see if he wants to proceed.
+ */
+
+ IOR_EJECT_MEDIA = 0x08,
+
+ /*
+ ** IOR_LOCK_MEDIA
+ **
+ ** Function:
+ **
+ ** Performs a LOCK MEDIA operation on removable drives.
+ **
+ ** Notes:
+ **
+ ** LOCK and UNLOCK MEDIA calls must be synchronized, as a depth counter is
+ ** maintained by IOS.
+ */
+
+ IOR_LOCK_MEDIA = 0x09,
+
+ /*
+ ** IOR_UNLOCK_MEDIA
+ **
+ ** Function:
+ **
+ ** Performs an UNLOCK MEDIA operation on removable drives.
+ **
+ ** Notes:
+ **
+ ** LOCK and UNLOCK MEDIA calls must be synchronized, as a depth counter is
+ ** maintained by IOS. UNLOCK MEDIA is delayed by about 5 seconds.
+ */
+
+ IOR_UNLOCK_MEDIA = 0x0A,
+
+ /*
+ ** IOR_REQUEST_SENSE
+ **
+ ** Function:
+ **
+ ** Performs an REQUEST SENSE operation on removable drives.
+ **
+ ** Notes:
+ **
+ ** Currently supported for SCSI devices only.
+ **
+ */
+
+ IOR_REQUEST_SENSE = 0x0B,
+
+ /*
+ ** IOR_COMPUTE_GEOM
+ **
+ ** Function:
+ **
+ ** Results in a reexamination of volume and device characteristics.
+ **
+ ** Notes:
+ **
+ ** When this command is received, each IOS layer assumes the device has
+ ** changed, and performs whatever initialization required. For example,
+ ** the disk TSD will reexamine the partitions of a device.
+ **
+ */
+
+ IOR_COMPUTE_GEOM = 0x0C,
+
+ /*
+ ** IOR_GEN_IOCTL
+ **
+ ** Function:
+ **
+ ** Function permits device-specific IOCtl's to be issued to IOS drivers.
+ ** Also supports standard Int 21 function 44xx DOS IOCtl's. See CDIOCTL.H
+ ** for examples of CD IOCtl's.
+ **
+ ** aliasing for fields used by IOCTL's -
+ ** this section gives both the normal and IOCTL names for the fields
+ **
+ ** IOR_ioctl_drive - BX from 16 bit IOCTL - usually a 1 based drive number
+ ** IOR_ioctl_function - AX from 16 bit IOCTL
+ ** IOR_ioctl_handle - useful handle? or original?
+ ** IOR_ioctl_control_param - CX zero extended to ULONG
+ ** IOR_ioctl_buffer_ptr - DS:DX mapped flat general buffer from the IOCTL
+ ** IOR_ioctl_client_params - a pointer to the parameters passed in from
+ ** the calling application the IORF_16BIT_IOCTL flag must be used to
+ ** determine the structure type. If it is a 16 bit IOCTL, the pointer
+ ** will be to the CLIENT_REGS structure. 32 bit is as of yet undef'ed
+ ** IOR_ioctl_return - return value to be mapped to the IOCTL caller on exit
+ ** IOR_ioctl_buffer_length - size of buffer pointed to by
+ ** IOR_ioctl_buffer_ptr (not used by int 21 440d IOCTL calls)
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_GEN_IOCTL = 0x0D,
+
+ /*
+ ** IOR_FORMAT
+ **
+ ** Function:
+ **
+ ** Allows issuance of a low level format packet as defined in the int 13
+ ** specification.
+ **
+ ** Notes:
+ **
+ ** IOR_format_address_field => low level sector map
+ ** See IOP.H IOP_FORMAT_XXX fields for additional information.
+ */
+
+ IOR_FORMAT = 0x0E,
+
+ /*
+ ** IOR_SCSI_PASS_THROUGH
+ **
+ ** Function:
+ **
+ ** Each layer passes this request down with modification to the SCSI port
+ ** driver.
+ **
+ ** Notes:
+ **
+ ** The IOR must contain a pointer to a valid SRB. Also, "ebx" must point
+ ** to the BDD portion of the DCB when IOS_SendCommand is called with a
+ ** passthrough request.
+ */
+
+ IOR_SCSI_PASS_THROUGH = 0x0F,
+
+ /*
+ ** IOR_CLEAR_QUEUE
+ **
+ ** Function:
+ **
+ ** Callback of request indicates all requests issued prior to this request
+ ** have been completed.
+ **
+ ** Notes:
+ */
+
+ IOR_CLEAR_QUEUE = 0x10,
+
+ /*
+ ** IOR_DOS_RESET
+ **
+ ** Function:
+ **
+ ** Issued in response to an int 13 reset by the int 13 vxd
+ **
+ ** Notes:
+ **
+ ** Currently used only by and for the IOS floppy driver.
+ */
+
+ IOR_DOS_RESET = 0x11,
+
+ /*
+ ** IOR_SCSI_REQUEST
+ **
+ ** Function:
+ **
+ ** generic function that indicates the request is for SCSI.
+ **
+ ** Notes:
+ **
+ ** SRB field in IOR must be valid. Normally used by IOS layers to send
+ ** internal requests to SCSI devices.
+ */
+
+ IOR_SCSI_REQUEST = 0x12,
+
+ /*
+ ** IOR_SET_WRITE_STATUS
+ **
+ ** Function:
+ **
+ ** results in the correct setting of DCB_DEV_WRITABLE flag in the DCB if
+ ** SUCCESS status is returned.
+ **
+ ** Notes:
+ **
+ ** Currently only supported by the IOS floppy driver.
+ */
+
+ IOR_SET_WRITE_STATUS = 0x22,
+
+ /*
+ ** IOR_RESTART_QUEUE
+ **
+ ** Function:
+ **
+ ** "Placeholder" function that results in restarting of the queue provided
+ ** by the IOS queuing services. Has no other effect.
+ **
+ ** Notes:
+ **
+ ** Should be sent after the DCB_QUEUE_FREEZE field has been decremented to
+ ** zero.
+ */
+
+ IOR_RESTART_QUEUE = 0x23,
+
+ /*
+ ** IOR_ABORT_QUEUE
+ **
+ ** Function:
+ **
+ ** Causes each layer to call back each queued request with status of
+ ** IORS_CANCELED
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_ABORT_QUEUE = 0x24,
+
+ /*
+ ** IOR_SPIN_DOWN
+ **
+ ** Function:
+ **
+ ** Causes the specified drive to be spun down.
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_SPIN_DOWN = 0x25,
+
+ /*
+ ** IOR_SPIN_UP
+ **
+ ** Function:
+ **
+ ** Causes the specified drive to be spun up.
+ **
+ ** Notes:
+ **
+ */
+
+ IOR_SPIN_UP = 0x26,
+
+ /*
+ ** IOR_FLUSH_DRIVE
+ **
+ ** Function:
+ **
+ ** Causes layer drivers to flush out dirty data.
+ **
+ ** Notes:
+ **
+ ** This is a synchronous function and should not be called at
+ ** event/interrupt time.
+ **
+ */
+
+ IOR_FLUSH_DRIVE = 0x27,
+
+
+ /*
+ ** IOR_FLUSH_DRIVE_AND_DISCARD
+ **
+ ** Function:
+ **
+ ** Causes layer drivers to flush out dirty data and then dicard cached
+ ** data.
+ **
+ ** Notes:
+ **
+ ** This is a synchronous function and should not be called at
+ ** event/interrupt time.
+ **
+ */
+
+ IOR_FLUSH_DRIVE_AND_DISCARD = 0x28,
+
+
+ /*
+ ** IOR_FSD_EXT
+ **
+ ** Function:
+ **
+ ** Sends private command from an IOS client to the FSD extension
+ ** layer (DRP_FSD_EXT_1 or DRP_FSD_EXT_2) such as a Compressed
+ ** Volume Manager (CVM).
+ **
+ ** Notes:
+ **
+ ** This call is similar in intent and usage to IOR_GEN_IOCTL;
+ ** however, it can be used in the swapper path, so, in general,
+ ** the handling driver should not touch pageable code or data.
+ **
+ */
+
+ IOR_FSD_EXT = 0x29,
+
+ /*
+ ** IOR_FLOPTICAL_MODE_SENSE
+ **
+ ** Function:
+ **
+ ** Issues MODE SENSE command to page 0x2e, as is required to indicate to the
+ ** floptical that it is supported.
+ **
+ ** Notes:
+ **
+ ** Don't use this command, as it is used by the system.
+ **
+ */
+
+ IOR_FLOPTICAL_MODE_SENSE = 0x2A,
+
+};
+
+/** IOR status codes for IOR_status */
+
+enum IOR_STATUS {
+ IORS_SUCCESS = 0x00, /* command completed successfully */
+
+ IORS_SUCCESS_WITH_RETRY = 0x01, /* successful, but retries required */
+
+ IORS_SUCCESS_WITH_ECC = 0x02, /* ditto, but with ECC */
+
+ IORS_INVALID_SECTOR = 0x10, /* old blockdev error code for */
+ /* requests on an invalid sector */
+ /* number */
+ IORS_CANCELED = 0x11, /* command was canceled */
+
+ IORS_CMD_IN_PROGRESS = 0x12, /* command is in progress, and can't be canceled */
+
+ IORS_INVALID_CMD_PTR = 0x13, /* cancel of an invalid command */
+
+ IORS_MEDIA_ERROR = 0x14, /* media failure */
+
+ IORS_DEVICE_ERROR = 0x15, /* error on recalib. drive, etc. */
+
+ IORS_INVALID_COMMAND = 0x16, /* Command not supported or invalid */
+
+ IORS_NO_DEVICE = 0x17, /* physical or logical device nonexistant */
+
+ IORS_NO_MEDIA = 0x18, /* media removed from device */
+
+ IORS_UNCERTAIN_MEDIA = 0x19, /* media may have changed */
+
+ IORS_UNREC_ERROR = 0x1A, /* un-recoverable error */
+
+ IORS_HW_FAILURE = 0x1B, /* general hardware failure */
+
+ IORS_UNFORMATTED_MEDIA = 0x1C, /* unformatted media */
+
+ IORS_MEMORY_ERROR = 0x1D, /* error allocating DMA buffer space for I/O */
+
+ IORS_TIME_OUT = 0x1E, /* device timed out */
+
+ IORS_WRITE_PROTECT = 0x1F, /* write protect error */
+
+ IORS_NOT_READY = 0x20, /* device not ready */
+
+ IORS_BUSY = 0x21, /* device is busy */
+
+ IORS_VOL_NOT_LOCKED = 0x22, /* volume received unlock without lk*/
+
+ IORS_VOL_LOCKED = 0x23, /* eject received with drive locked */
+
+ IORS_VOL_NOT_REMOVABLE = 0x24, /* removable request to non-remov drive */
+
+ IORS_VOL_IN_USE = 0x25, /* volume is in use - used for eject*/
+
+ IORS_LOCK_COUNT_EXCEEDED = 0x26, /* volume lock count exceeded */
+
+ IORS_VALID_EJECT_FAILED = 0x27, /* eject command was not accepted */
+
+ IORS_ILLEGAL_ACCESS_MODE = 0x28, /* cdrom read on audio or attempt */
+ /* play on data */
+
+ IORS_LOCK_VIOLATION = 0x29, /* illegal access to locked device */
+
+ IORS_WRONG_MEDIA = 0x2a, /* wrong media in drive */
+
+ IORS_OUT_OF_SPACE = 0x2b, /* no space on media */
+
+ IORS_BIG_IO_BREAKUP_FAILED = 0x2c,/* attempt to split big I/O barfed */
+
+ IORS_ERROR_DESIGNTR = 0x10, /* bit indicating error occurred */
+
+ IORS_INVALID_PARM = IORS_ERROR_DESIGNTR, /* bit indicating error occurred */
+};
+
+enum IOR_FLAGS {
+
+ IORF_HIGH_PRIORITY_BIT=0, /* binary priority indication */
+ IORF_HIGH_PRIORITY = (1 << IORF_HIGH_PRIORITY_BIT), /* 0x0001 */
+
+ IORF_SCATTER_GATHER_BIT=1, /* bit indicating BDCB physical SGD */
+ /* list present */
+ IORF_SCATTER_GATHER = (1 << IORF_SCATTER_GATHER_BIT), /* 0x0002 */
+
+ IORF_DONT_CACHE_BIT=2, /* bit indicating that the BDCB data*/
+ /* should not be cached */
+ IORF_DONT_CACHE = (1 << IORF_DONT_CACHE_BIT), /* 0x0004 */
+
+ IORF_BYPASS_VOLTRK=0x0008, /* request will not be volume trked */
+ IORF_BYPASS_VOLTRK_BIT=3,
+
+ IORF_16BIT_IOCTL=0x0010, /* if true, 16 bit IOCTL calling */
+ /* app, else 32 bit ioctl */
+ IORF_16BIT_IOCTL_BIT=4,
+
+ IORF_SWAPPER_IO=0x0020, /* request is from the swapper */
+ IORF_SWAPPER_IO_BIT=5,
+
+ IORF_DOUBLE_BUFFER=0x0040, /* indicates that the request is to */
+ /* be completed via double */
+ /* buffering. client must */
+ /* ensure that both the sgd buffer */
+ /* pointers and IOR_sgd_lin_phys */
+ /* are virtual pointers. */
+ IORF_DOUBLE_BUFFER_BIT=6,
+
+ IORF_SYNC_CMD_DONE=0x0080, /* used by IOS only to indicate */
+ /* completion */
+ /* of synchronous command */
+ IORF_SYNC_CMD_DONE_BIT=7,
+
+ IORF_SYNC_COMMAND=0x0100, /* indicates synchronous command */
+ /* (complete before return from IOS */
+ IORF_SYNC_COMMAND_BIT=8,
+
+ IORF_CHAR_COMMAND=0x0200, /* indicates transfer counts and */
+ /* scatter/gather buffer sizes are */
+ /* byte values */
+ IORF_CHAR_COMMAND_BIT=9,
+
+ IORF_VERSION_002=0x0400, /* indicates use of extended BCB */
+ /* (IOR) format for request */
+ IORF_VERSION_002_BIT=10,
+
+ IORF_BYPASS_QUEUE=0x0800, /* request should bypass IOS queuing*/
+ /* internal IOS driver use only */
+ IORF_BYPASS_QUEUE_BIT=11,
+
+ IORF_BLOCKDEV_EMULATE=0x1000, /* this request started as a BCB */
+ IORF_BLOCKDEV_EMULATE_BIT=12,
+
+ IORF_POSTPONED_VOL_OPS=0x2000,
+ IORF_POSTPONED_VOL_OPS_BIT=13,
+
+ IORF_INHIBIT_GEOM_RECOMPUTE=0x4000,
+ IORF_INHIBIT_GEOM_RECOMPUTE_BIT=14,
+ /* force inhibit of device geometry */
+ /* recomputation. */
+
+ IORF_SRB_VALID=0x8000, /* indicates that IOP_srb points to */
+ IORF_SRB_VALID_BIT=15, /* a valid SRB */
+
+ IORF_BYPASS_A_B=0x10000, /* indicates that VOLTRK should */
+ IOFR_BYPASS_A_B_BIT=16, /* bypass AB check */
+
+ IORF_QUIET_VOLTRK=0x20000, /* indicates that volume tracking */
+ IORF_QUIET_VOLTRL_BIT=17, /* just return error when wrong */
+ /* media in drive (no dialog box) */
+
+ IORF_AUDIO_DATA_READ=0x40000, /* indicates an audio data read */
+ IORF_AUDIO_DATA_READ_BIT=18,
+
+ IORF_LOGICAL_START_SECTOR=0x80000,
+ IORF_LOGICAL_START_SECTOR_BIT=19,
+ /* IOR_start_addr is logical */
+
+ IORF_PARTITION_BIAS_ADDED=0x100000,
+ IORF_PARTITION_BIAS_ADDED_BIT=20, /* set by TSD only to indicate that */
+ /* it has added in the bias, as req'd */
+ /* by IORF_LOGICAL_START_SECTOR */
+
+ IORF_DATA_IN_BIT=21, /* indicates a data read operation */
+ IORF_DATA_IN = (1 << IORF_DATA_IN_BIT),
+
+ IORF_DATA_OUT_BIT=22, /* indicates a data write operation */
+ IORF_DATA_OUT = (1 << IORF_DATA_OUT_BIT),
+
+ IORF_VOL_RETRY_BIT=23, /* indicates volume tracking retried*/
+ IORF_VOL_RETRY = (1 << IORF_VOL_RETRY_BIT),
+ /* request (internal use only) */
+
+ IORF_NO_COMPRESS_BIT=24, /* do not compress data */
+ IORF_NO_COMPRESS = (1 << IORF_NO_COMPRESS_BIT),
+
+ IORF_DIRECT_IO_BIT=25, /* E.g., INT 25h or INT 26h */
+ IORF_DIRECT_IO = (1 << IORF_DIRECT_IO_BIT),
+
+ IORF_PHYS_SGDS_BIT=26,
+ IORF_PHYS_SGDS = (1 << IORF_PHYS_SGDS_BIT),
+ /* indicates IOR_sgd_lin_phys valid */
+
+ IORF_IO_TOO_BIG_BIT=27,
+ IORF_IO_TOO_BIG = (1 << IORF_IO_TOO_BIG_BIT),
+ /* indicates I/O is too big for */
+ /* single pass (set by IOS criteria*/
+ /* code). */
+ IORF_WIN32_BIT=28,
+ IORF_WIN32 = (1 << IORF_WIN32_BIT),
+ /* indicates I/O is from 32 bit API */
+ IORF_CHAR_DEVICE_BIT=29,
+ IORF_CHAR_DEVICE = (1 << IORF_CHAR_DEVICE_BIT),
+
+ IORF_PHYS_CMD_BIT=30, /* indicates I/O is for a physical */
+ /* device */
+ IORF_PHYS_CMD = (1 << IORF_PHYS_CMD_BIT),
+
+ IORF_IDE_RESERVED_BIT=31, /* indicates I/O is for a physical */
+ /* device */
+ IORF_IDE_RESERVED = (1 << IORF_IDE_RESERVED_BIT)
+
+};
+
+// IOP =================
+
+#define IOP_CALLBACK_TABLE_DEPTH 6
+
+typedef _Packed struct IOP_callback_entry {
+ IO_callback IOP_CB_address; /* call back address */
+ uint32_t IOP_CB_ref_data; /* pointer to callback ref data */
+} IOP_callback_entry;
+
+typedef _Packed struct IOP {
+ uint32_t IOP_physical; // physical address of IOP
+ struct DCB *IOP_physical_dcb; // address of physical DCB
+ struct DCB *IOP_original_dcb; // address of DCB designated by IOR
+ uint16_t IOP_timer; // Request Control Block (RCB) current
+ // timeout value
+ uint16_t IOP_timer_orig; // original timeout value
+ DCB_cd_entry* IOP_calldown_ptr; // address of next calldown routine
+ IOP_callback_entry* IOP_callback_ptr; // address of current callback address
+ uint32_t IOP_voltrk_private; // for use by volume tracking
+ uint32_t IOP_Thread_Handle; // handle of thread originating
+ // the I/O request
+ uint32_t IOP_srb; // used by SCSI'izers to pass SRB
+ // address to next layer
+ uint32_t IOP_reserved[2]; // reserved; must be zero
+ IOP_callback_entry IOP_callback_table[IOP_CALLBACK_TABLE_DEPTH];
+ // RCB_CallBackTable
+ uint8_t IOP_format_head; // low level format data
+ uint8_t IOP_format_xfer_rate;
+ uint16_t IOP_format_track;
+ uint32_t IOP_format_num_sectors;
+ IOR IOP_ior; // I/O request descriptor
+} IOP, *PIOP;
+
+/** Let lower levels continue processing this IOP. */
+static void IopCalldown(IOP* iop) {
+ // Get who is supposed to be next driver in the chain
+ iop->IOP_calldown_ptr = iop->IOP_calldown_ptr->DCB_cd_next;
+ // Call it
+ iop->IOP_calldown_ptr->DCB_cd_io_address(iop);
+}
+
+/** Finish processing this IOP, and call back previous levels. */
+static void IopCallback(IOP* iop) {
+ iop->IOP_callback_ptr -= 1;
+ iop->IOP_callback_ptr->IOP_CB_address(iop);
+}
+
+// ISP =================
+
+typedef uint16_t IspResult; // unspecified error codes, but zero = no error
+
+typedef _Packed struct ISP {
+ uint16_t ISP_func; // function to be performed; see below
+ IspResult ISP_result; // result: zero = no error
+} ISP, *PISP;
+
+enum ISP_funcs {
+ /* create ddb */
+ ISP_CREATE_DDB = 0,
+ /* create dcb (Physical) */
+ ISP_CREATE_DCB = 1,
+ /* create iop */
+ ISP_CREATE_IOP = 2,
+ /* allocate memory */
+ ISP_ALLOC_MEM = 3,
+ /* deallocate memory */
+ ISP_DEALLOC_MEM = 4,
+ /** insert entry in calldown table */
+ ISP_INSERT_CALLDOWN = 5,
+ /* associate dcb & relative drive # */
+ ISP_ASSOCIATE_DCB = 6,
+ /* return DCB for logical volume */
+ ISP_GET_DCB = 7,
+ /** get first/next DCB */
+ ISP_GET_FIRST_NEXT_DCB = 8,
+ /* deallocate DDB */
+ ISP_DEALLOC_DDB = 9,
+ /* destroy DCB */
+ ISP_DESTROY_DCB = 10,
+ /* ask for logical-to-physical info */
+ ISP_QUERY_MATCHING_DCBS = 11,
+ /* ask if we can remove a device */
+ ISP_QUERY_REMOVE_DCB = 12,
+ /* indicate that a device has been removed */
+ ISP_DEVICE_REMOVED = 13,
+ /* indicate that a device has arrived */
+ ISP_DEVICE_ARRIVED = 14,
+ /* disassociate dcb & drive # */
+ ISP_DISASSOCIATE_DCB = 15,
+ /* pick a drive letter */
+ ISP_DRIVE_LETTER_PICK = 16,
+ /* read registry */
+ ISP_REGISTRY_READ = 17,
+ /* find LDM entry */
+ ISP_FIND_LDM_ENTRY = 18,
+ /* delete LDM entry */
+ ISP_DELETE_LDM_ENTRY = 19,
+ /* broadcast an AEP from a driver */
+ ISP_BROADCAST_AEP = 20
+};
+
+typedef _Packed struct ISP_dcb_create { //
+ ISP ISP_dcb_hdr; // Standard header
+ uint16_t ISP_dcb_size; // size of DCB to create, in bytes
+ uint32_t ISP_dcb_ptr; // address of DCB
+ uint8_t ISP_pad1[2]; // Pad to DWORD boundary
+} ISP_dcb_create, *PISP_dcb_create;
+
+static PDCB IspCreateDcb(ILB* ilb, uint16_t size) {
+ ISP_dcb_create isp = {{ISP_CREATE_DCB}};
+ isp.ISP_dcb_size = size;
+ ilb->ILB_service((PISP)&isp);
+ return isp.ISP_dcb_hdr.ISP_result != 0 ? NULL : (PDCB) isp.ISP_dcb_ptr;
+}
+
+typedef _Packed struct ISP_ddb_create { //
+ ISP ISP_ddb_hdr; // Standard header
+ uint16_t ISP_ddb_size; // size of DDB to create, in bytes
+ uint32_t ISP_ddb_ptr; // address of DDB
+ uint8_t ISP_ddb_flags; // flags; see below
+ uint8_t ISP_pad0[1]; // Pad to DWORD boundary
+} ISP_ddb_create, *PISP_ddb_create;
+
+static PDDB IspCreateDdb(ILB* ilb, uint16_t size) {
+ ISP_ddb_create isp = {{ISP_CREATE_DDB}};
+ isp.ISP_ddb_size = size;
+ ilb->ILB_service((PISP)&isp);
+ return isp.ISP_ddb_hdr.ISP_result != 0 ? NULL : (PDDB) isp.ISP_ddb_ptr;
+}
+
+typedef _Packed struct ISP_calldown_insert {
+ ISP ISP_i_cd_hdr; // Standard header
+ uint32_t ISP_i_cd_dcb; // address of DCB
+ void* ISP_i_cd_req; // address of request routine
+ uint32_t ISP_i_cd_ddb; // address of DDB
+ uint16_t ISP_i_cd_expan_len; // size of IOP expansion required by this driver
+ uint32_t ISP_i_cd_flags; // demand flags
+ uint8_t ISP_i_cd_lgn; // load group number; typically same as AEP_lgn
+ uint8_t ISP_pad4[1]; // Pad to DWORD boundary
+} ISP_calldown_insert, *PISP_calldown_insert;
+
+static IspResult IspInsertCalldown(ILB* ilb, PDCB dcb, void (*calldown)(PIOP), PDDB ddb, uint16_t expand_len, uint32_t flags, uint8_t lgn) {
+ ISP_calldown_insert isp = {{ISP_INSERT_CALLDOWN}};
+ isp.ISP_i_cd_dcb = (uint32_t) dcb;
+ isp.ISP_i_cd_req = calldown;
+ isp.ISP_i_cd_ddb = (uint32_t) ddb;
+ isp.ISP_i_cd_expan_len = expand_len;
+ isp.ISP_i_cd_flags = flags;
+ isp.ISP_i_cd_lgn = lgn;
+ ilb->ILB_service((PISP)&isp);
+ return isp.ISP_i_cd_hdr.ISP_result;
+}
+
+typedef _Packed struct ISP_AEP_BROADCAST {
+ ISP ISP_baep_hdr; // Standard header
+ void* ISP_baep_paep; // address of AEP to broadcast
+} ISP_AEP_BROADCAST,*PISP_AEP_BROADCAST;
+
+static IspResult IspBroadcastAep(ILB* ilb, PAEP paep) {
+ ISP_AEP_BROADCAST isp = {{ISP_BROADCAST_AEP}};
+ isp.ISP_baep_paep = paep;
+ ilb->ILB_service((PISP)&isp);
+ return isp.ISP_baep_hdr.ISP_result;
+}
+
+// SGD =========
+
+typedef struct _SGD {
+ uint32_t SG_buff_ptr; // address of data buffer; see below
+ uint32_t SG_buff_size; // number of bytes to transfer
+} SGD, *PSGD;
+
+#endif // IOS_H
diff --git a/w9x/inc/vmm.h b/w9x/inc/vmm.h
new file mode 100644
index 0000000..eb8f834
--- /dev/null
+++ b/w9x/inc/vmm.h
@@ -0,0 +1,161 @@
+#ifndef VMM_H
+#define VMM_H
+
+/** VMM VxD services and types.
+ * Manually generated for now. */
+
+#include <stdint.h>
+
+#define PAGESHIFT 12
+#define PAGESIZE (1 << PAGESHIFT)
+
+/** Timeout handle, see Set_*_Time_Out, Cancel_Time_Out services. */
+typedef void* HTIMEOUT;
+
+static inline unsigned short Get_VMM_Version(void);
+#pragma aux Get_VMM_Version = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 0" \
+ __parm caller [] __value [ax]
+
+static inline void Release_Time_Slice(void);
+#pragma aux Release_Time_Slice = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 56" \
+ __parm caller __modify []
+
+static inline void Time_Slice_Sleep(uint32_t ms);
+#pragma aux Time_Slice_Sleep = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 353" \
+ __parm caller [eax] __modify []
+
+typedef void (Global_Time_Out_Proc)(void *VMHandle, uint32_t tardiness, uint32_t ref_data);
+#pragma aux Global_Time_Out_Proc __parm [ebx] [ecx] [edx]
+
+static inline HTIMEOUT Set_Global_Time_Out(Global_Time_Out_Proc *proc, uint32_t ms, uint32_t refData);
+#pragma aux Set_Global_Time_Out = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 60" \
+ __parm caller [esi] __value [esi] __modify [ecx edx]
+
+static inline void Cancel_Time_Out(HTIMEOUT timeout);
+#pragma aux Cancel_Time_Out = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 62" \
+ __parm caller [esi] __modify [eax ecx edx]
+
+typedef void (Async_Time_Out_Proc)(uint32_t tardiness, uint32_t ref_data);
+#pragma aux Async_Time_Out_Proc __parm [ecx] [edx]
+
+static inline HTIMEOUT Set_Async_Time_Out(Async_Time_Out_Proc *proc, uint32_t ms, uint32_t refData);
+#pragma aux Set_Async_Time_Out = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 254" \
+ __parm caller [esi] [eax] [edx] __value [esi] __modify [ecx edx]
+
+static inline uint32_t Get_System_Time(void);
+#pragma aux Get_System_Time = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 63" \
+ __parm caller __value [eax] __modify []
+
+static inline uint32_t Get_Last_Updated_System_Time(void);
+#pragma aux Get_Last_Updated_System_Time = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 207" \
+ __parm caller __value [eax] __modify []
+
+static inline uint32_t * Get_System_Time_Address(void);
+#pragma aux Get_System_Time_Address = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 324" \
+ __parm caller __value [eax] __modify []
+
+enum {
+ HEAPZEROINIT = 0x0001,
+ HEAPZEROREINIT = 0x0002,
+ HEAPNOCOPY = 0x0004,
+ HEAPLOCKEDIFDP = 0x0100,
+ HEAPSWAP = 0x0200,
+ HEAPINIT = 0x0400,
+ HEAPCLEAN = 0x0800
+};
+
+static inline void * HeapAllocate(unsigned long bytes, unsigned long flags);
+#pragma aux HeapAllocate = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 79" \
+ __parm caller [] __value [eax] __modify [ecx edx]
+
+static inline unsigned long HeapFree(void *addr, unsigned long flags);
+#pragma aux HeapFree = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 81" \
+ __parm caller [] __value [eax] __modify [ecx edx]
+
+enum page_allocate_types {
+ PG_VM = 0,
+ PG_SYS = 1,
+ PG_RESERVED1 = 2,
+ PG_PRIVATE = 3,
+ PG_RESERVED2 = 4,
+ PG_RELOCK = 5,
+ PG_INSTANCE = 6,
+ PG_HOOKED = 7
+};
+
+enum page_allocate_flags {
+ PAGEZEROINIT = 0x00000001,
+ PAGEUSEALIGN = 0x00000002,
+ PAGECONTIG = 0x00000004,
+ PAGEFIXED = 0x00000008,
+ PAGEDEBUGNULFAULT = 0x00000010,
+ PAGEZEROREINIT = 0x00000020,
+ PAGENOCOPY = 0x00000040,
+ PAGELOCKED = 0x00000080,
+ PAGELOCKEDIFDP = 0x00000100,
+ PAGESETV86PAGEABLE = 0x00000200,
+ PAGECLEARV86PAGEABLE = 0x00000400,
+ PAGESETV86INTSLOCKED = 0x00000800,
+ PAGECLEARV86INTSLOCKED = 0x00001000,
+ PAGEMARKPAGEOUT = 0x00002000,
+ PAGEPDPSETBASE = 0x00004000,
+ PAGEPDPCLEARBASE = 0x00008000,
+ PAGEDISCARD = 0x00010000,
+ PAGEPDPQUERYDIRTY = 0x00020000,
+ PAGEMAPFREEPHYSREG = 0x00040000,
+ PAGENOMOVE = 0x10000000,
+ PAGEMAPGLOBAL = 0x40000000,
+ PAGEMARKDIRTY = 0x80000000
+};
+
+static inline void * PageAllocate(unsigned long npages, unsigned long type, unsigned long vm,
+ unsigned long alignMask, unsigned long minPhys, unsigned long maxPhys,
+ uint32_t *physAddr, unsigned long flags);
+#pragma aux PageAllocate = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 83" \
+ __parm caller [] __value [eax] __modify [ecx edx]
+
+static inline unsigned long PageFree(void *addr, unsigned long flags);
+#pragma aux PageFree = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 85" \
+ __parm caller [] __value [eax] __modify [ecx edx]
+
+static inline char Hook_Device_Service(uint32_t service, void *hook);
+#pragma aux Hook_Device_Service = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 144" \
+ "setc al" \
+ __parm caller [eax] [esi] __value [al] __modify [ecx edx]
+
+static inline char Unhook_Device_Service(uint32_t service, void *hook);
+#pragma aux Unhook_Device_Service = \
+ "int 0x20" \
+ "dd ( 1 shl 16 ) + 284" \
+ "setc al" \
+ __parm caller [eax] [esi] __value [al] __modify [ecx edx]
+
+#endif // VMM_H
diff --git a/w9x/inc/vxd.h b/w9x/inc/vxd.h
new file mode 100644
index 0000000..b73ab68
--- /dev/null
+++ b/w9x/inc/vxd.h
@@ -0,0 +1,132 @@
+#ifndef WINVXD_H
+#define WINVXD_H
+
+/** Some definitions from VMM or general VXD structs. */
+
+#include <stdint.h>
+
+#include <sassert.h>
+
+enum {
+ SDK_VERSION_3 = 0x30A,
+ SDK_VERSION_4 = 0x400
+};
+
+enum {
+ UNDEFINED_INIT_ORDER = 0x80000000UL
+};
+
+enum VXD_DEVICE_IDS {
+ UNDEFINED_DEVICE_ID = 0,
+ VMM_DEVICE_ID = 1,
+ VMD_DEVICE_ID = 0xC,
+ VKD_DEVICE_ID = 0xD,
+ CONFIGMG_DEVICE_ID = 0x33,
+};
+
+enum {
+ /* Required for w9x to load 4.0 VxD */
+ DDB_PREV_INIT = 'Prev'
+};
+
+typedef struct {
+ uint32_t next;
+ uint16_t sdk_version;
+ uint16_t req_device_number;
+ uint8_t dev_major_version;
+ uint8_t dev_minor_version;
+ uint16_t flags;
+ char name[8];
+ uint32_t init_order;
+
+ void * control_proc;
+ void * v86_api_proc;
+ void * pm_api_proc;
+ void * v86_api_csip;
+ void * pm_api_csip;
+ void * reference_data;
+ void * service_table_ptr;
+ uint32_t service_table_size;
+
+ /** Windows 9x */
+ void * win32_service_table;
+ uint32_t prev;
+ uint32_t size;
+
+ uint32_t reserved[3];
+} VxD_Desc_Block;
+STATIC_ASSERT(sizeof(VxD_Desc_Block) == 80);
+
+enum SYSTEM_CONTROL_MSGS {
+ SYS_CRITICAL_INIT = 0x0,
+ DEVICE_INIT = 0x1,
+ INIT_COMPLETE = 0x2,
+ SYS_VM_INIT = 0x3,
+ SYS_VM_TERMINATE = 0x4,
+ SYSTEM_EXIT = 0x5,
+ SYS_CRITICAL_EXIT=0x6,
+ CREATE_VM=0x7,
+ VM_CRITICAL_INIT=0x8,
+ VM_INIT=0x9,
+ VM_TERMINATE=0xA,
+ VM_NOT_EXECUTEABLE=0xB,
+ DESTROY_VM=0xC,
+ VM_SUSPEND=0xD,
+ VM_RESUME=0xE,
+ SET_DEVICE_FOCUS=0xF,
+
+ BEGIN_MESSAGE_MODE=0x10,
+ END_MESSAGE_MODE=0x11,
+
+ REBOOT_PROCESSOR=0x12,
+
+ QUERY_DESTROY=0x13,
+
+ DEBUG_QUERY=0x14,
+
+ BEGIN_PM_APP=0x15,
+ END_PM_APP=0x16,
+
+ DEVICE_REBOOT_NOTIFY=0x17,
+ CRIT_REBOOT_NOTIFY=0x18,
+
+ CLOSE_VM_NOTIFY=0x19,
+
+ POWER_EVENT=0x1A,
+
+ SYS_DYNAMIC_DEVICE_INIT=0x1B,
+ SYS_DYNAMIC_DEVICE_EXIT=0x1C,
+
+ CREATE_THREAD=0x1D,
+ THREAD_INIT=0x1E,
+ TERMINATE_THREAD=0x1F,
+ THREAD_NOT_EXECUTEABLE=0x20,
+ DESTROY_THREAD=0x21,
+
+ PNP_NEW_DEVNODE = 0x22,
+
+ W32_DEVICEIOCONTROL = 0x23,
+
+ SYS_VM_TERMINATE2 = 0x24,
+ //...
+ CLOSE_VM_NOTIFY2 = 0x2F,
+
+ KERNEL32_INITIALIZED=0x31,
+ KERNEL32_SHUTDOWN=0x32
+
+};
+
+static inline void clear_carry(void);
+#pragma aux clear_carry = "clc" modify exact [];
+
+static inline void set_carry(void);
+#pragma aux set_carry = "stc" modify exact [];
+
+static inline int set_carry_if_notzero(int arg);
+#pragma aux set_carry_if_notzero = \
+ "cmp eax, 1" \
+ parm [eax] \
+ value [eax] \
+ modify exact [];
+
+#endif // WINVXD_H