Page 60,132 ;**************************************************************** ;* * ;* EMILY is a character-oriented device driver. * ;* * ;* All block-oriented functions in EMILY simply set the * ;* DONE status flag and exit. * ;* * ;* The basic request-header structure used in all * ;* request-headers is called the Request_Header_Preamble. * ;* All request-headers begin with a 13-byte area * ;* corresponding to the Request_Header_Preamble. * ;* * ;* Assembled using Microsoft MASM 1.25. * ;* * ;**************************************************************** ;-------------------------------------------------------------------- ; ; Request-header structure type 1 ; ; Used by services 6, 7, 10, and 11 ; ;-------------------------------------------------------------------- Request_Header_Preamble STRUC Header_Length DB (?) ; Length in bytes Unit_Code DB (?) ; Unit code Command_Code DB (?) ; Command code Status_Code DW (?) ; Status of the request PCDOS_Reserved DB 8 Dup (?) ; Reserved area for PC DOS Request_Header_Preamble Ends ;-------------------------------------------------------------------- ;-------------------------------------------------------------------- ; ; Request-header structure type 2 ; ; Used by service 0 (Init) ; ;-------------------------------------------------------------------- Request_Header_Init STRUC DB 13 dup(?) ; Area for Request_Header_Preamble Init_Unit_Count DB (?) ; Number of units Init_Ending_Program_Addr DD (?) ; Stay resident address Init_Bios_Param_Block_Addr DD (?) ; Doesn't apply to char. devices Init_Byte_Drive_Number DB (?) Request_Header_Init Ends ;-------------------------------------------------------------------- ;-------------------------------------------------------------------- ; ; Request-header structure type 3 ; ; Used by service 1 (Media Check - doesn't apply to char. devices) ; ;-------------------------------------------------------------------- Request_Header_Media STRUC DB 13 dup(?) ; Area for Request_Header_Preamble Media_Media_Descriptor DB (?) ; Define media type Media_Byte_return DB (?) ; Indicate media status Media_Vol_Id_Addr DD (?) ; Previous Vol ID pointer Request_Header_Media Ends ;-------------------------------------------------------------------- ;-------------------------------------------------------------------- ; ; Request-header structure type 4 ; ; Used by service 2 (BUILD BPB - doesn't apply to char. devices) ; ;-------------------------------------------------------------------- Request_Header_BPB STRUC DB 13 dup(?) ; Area for Request_Header_Preamble BPB_Media_Descriptor DB (?) ; Define media type BPB_Data_Transfer_Address DD (?) ; I/O buffer BPB_Bios_Param_Block_Addr DD (?) ; Pointer to BPB Request_Header_BPB Ends ;-------------------------------------------------------------------- ;-------------------------------------------------------------------- ; ; Request-header structure type 5 ; ; Used by service 3, 4, 8, 9, and 12 (Input or Output) ; ;-------------------------------------------------------------------- Request_Header_IO STRUC DB 13 dup(?) ; Area for Request_Header_Preamble IO_Media_Descriptor DB (?) ; Define media type IO_Data_Transfer_Address DD (?) ; I/O buffer IO_Byte_Counter DW (?) ; Number of bytes transferred IO_Starting_Sector DW (?) ; Not used in char. devices IO_Vol_Id_Addr DD (?) ; Pointer to Vol ID Request_Header_IO Ends ;-------------------------------------------------------------------- ;-------------------------------------------------------------------- ; ; Request-header structure type 6 ; ; Used by service 5 (Non Destructive Input No Wait) ; ;-------------------------------------------------------------------- Request_Header_Non_Dest STRUC DB 13 dup(?) ; Area for Request_Header_Preamble Non_Dest_Read_Byte DB (?) ; Byte read from device Request_Header_Non_Dest Ends ;-------------------------------------------------------------------- Page ;**************************************************************** ;* * ;* Beginning of EMILY * ;* * ;**************************************************************** CSEG Segment Para Public 'CODE' Assume CS:CSEG,DS:Nothing,ES:Nothing,SS:Nothing ; ; The source code begins here ; Org 0000H Device_Driver Proc Far ; ; Here is the device header ; Next_Device DD -1 ; Setting this field to -1 ; . indicates that there is ; . only one driver in this ; . device-driver program. Attribute DW 0C000H ; Turn bits 14 and 15 on, all ; . others off. Bit 15 = 1 for ; . a character device. Bit 14 = 1 ; . if device supports the IOCTL ; . function. Strategy DW Offset Strategy_Routine ; Tells PC-DOS the offset address ; . of the Strategy routine. ; . The segment address is assumed ; . to be the value in the CS ; . register. Interrupt DW Offset Interrupt_Routine ; Tells PC-DOS the offset address ; . of the Interrupt routine. ; . Like the Strategy routine, the ; . segment address is assumed to ; . be in the CS register. Device_Name DB "EMILY " ; The name of this particular device ; . driver is EMILY. Name must be ; . 8 characters, so 3 blanks added. Request_Header Label Word Request_Header_Offset DW (?) ; Here is where the pointer Request_Header_Segment DW (?) ; . is defined ; ; Here is the jump table of command modules ; Device_Functions Label Word DW Offset Initialize_Driver_Command ;command-code = 0 DW Offset Media_Check_Command ;command-code = 1 DW Offset Build_BPB_Command ;command-code = 2 DW Offset IOCTL_Input_Command ;command-code = 3 DW Offset Read_Input_Command ;command-code = 4 DW Offset Non_Destruct_Input_Command ;command-code = 5 DW Offset Input_Status_Command ;command-code = 6 DW Offset Input_Flush_Command ;command-code = 7 DW Offset Write_Output_Command ;command-code = 8 DW Offset Write_Verify_Command ;command-code = 9 DW Offset Output_Status_Command ;command-code = 10 DW Offset Output_Flush_Command ;command-code = 11 DW Offset IOCTL_Output_Command ;command-code = 12 DW Offset Device_Open_Command ;command-code = 13 DW Offset Device_Close_Command ;command-code = 14 DW Offset Removable_Media_Command ;command-code = 15 ; ; Here is the strategy routine ; Strategy_Routine Proc Far Mov Word Ptr CS:Request_Header_Offset,BX Mov Word Ptr CS:Request_Header_Segment,ES Ret Strategy_Routine Endp ; ; Here is the interrupt routine ; Interrupt_Routine Proc Far INRT01: Push AX ; Save the registers Push BX ; . and flags Push CX ; . Push DX ; . Push SI ; . Push DI ; . Push DS ; . Push ES ; . Pushf ; ..End INRT02: Push CS ; Set DS equal to CS Pop DS ; ..End Mov BX,Word Ptr CS:Request_Header_Offset Mov ES,Word Ptr CS:Request_Header_Segment ; Get the address of the ; . request header into ; . ES:[BX] Mov Word Ptr ES:[BX].Status_Code,0000H ; Clear the status word Mov DX,0000H ; Calculate the index into Mov DL,Byte Ptr ES:[BX].Command_Code Shl DX,1 ; . the jump table and put Mov DI,DX ; . it into DI Cmp DI,0024D ; Compare for an invalid Jbe INRT03 ; command ; ; Here is the error routine for an illegal command ; Or Byte Ptr ES:[BX].Status_Code+1,80H ; Set the error bit Mov Byte Ptr ES:[BX].Status_Code,03H ; Set the error byte Jmp Short INRT90 INRT03: Mov SI,Word Ptr CS:Device_Functions[DI] ; Get the offset address ; . of the appropriate ; . command Call SI ; This is a near call to ; . the command INRT90: Popf ; Restore the registers Pop ES ; . and flags Pop DS ; . Pop DI ; . Pop SI ; . Pop DX ; . Pop CX ; . Pop BX ; . Pop AX ; ..End Ret Interrupt_Routine Endp ; ; Here is the initialization command ; Initialize_Driver_Command Proc Near Mov AX,Offset End_Of_the_Program Mov Word Ptr ES:[BX].Init_Ending_Program_Addr,AX Mov Word Ptr ES:[BX+2].Init_Ending_Program_Addr,CS Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Initialize_Driver_Command Endp ; ; Here is the media check command ; Media_Check_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Media_Check_Command Endp ; ; Here is the construct Bios Parameter Block command ; Build_BPB_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Build_BPB_Command Endp ; ; Here is the IOCTL input command ; IOCTL_Input_Command Proc Near Lds DI,ES:[BX].IO_Data_Transfer_Address Mov Byte Ptr DS:[DI],'E' Mov Word Ptr ES:[BX].IO_Byte_Counter,0001H Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret IOCTL_Input_Command Endp ; ; Here is the read input command ; Read_Input_Command Proc Near Mov Word Ptr ES:[BX].IO_Byte_Counter,0000H Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Read_Input_Command Endp ; ; Here is the non-destructive input command ; Non_Destruct_Input_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0200H ; Set the busy bit Mov Word Ptr ES:[BX].Non_Dest_Read_Byte,0000H Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Non_Destruct_Input_Command Endp ; ; Here is the input status command ; Input_Status_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Input_Status_Command Endp ; ; Here is the flush input command ; Input_Flush_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Input_Flush_Command Endp ; ; Here is the write output command ; Write_Output_Command Proc Near Mov Word Ptr ES:[BX].IO_Byte_Counter,0000H Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Write_Output_Command Endp ; ; Here is the write verify command ; Write_Verify_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Write_Verify_Command Endp ; ; Here is the output status command ; Output_Status_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Output_Status_Command Endp ; ; Here is the flush the output command ; Output_Flush_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Output_Flush_Command Endp ; ; Here is the IOCTL output command ; IOCTL_Output_Command Proc Near Mov Word Ptr ES:[BX].IO_Byte_Counter,0000H Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret IOCTL_Output_Command Endp ; ; Here is the device open command ; Device_Open_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Device_Open_Command Endp ; ; Here is the device close command ; Device_Close_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Device_Close_Command Endp ; ; Here is the removable media command ; Removable_Media_Command Proc Near Or Word Ptr ES:[BX].Status_Code,0100H ; Set the finished bit Ret Removable_Media_Command Endp Device_Driver Endp End_of_the_Program Equ $ ; The assembler sets the ; . variable to the last ; . valid address in the ; . program CSEG Ends End Device_Driver