home *** CD-ROM | disk | FTP | other *** search
- TITLE PREFERS.SYS - Sample Device Driver
- PAGE 60,132
- ;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
- ; P R E F E R S . S Y S
- ; By George W. Seaton -- Assemble with Borland's TASM
- ;
- ; This module is an example of a simple "character" device driver.
- ; It does not "drive" any particular device; instead, it sets up
- ; certain BIOS parameters for the video and keyboard, according
- ; to the user's personal preferences. For the author's AT-clone
- ; with an EGA color video, these preferences include:
- ;
- ; - Turning off the NumLock state.
- ; - Setting the EGA video to 43-line mode.
- ; - Turning OFF the video blink bit.
- ;
- ; After its initial installation, users can use the driver (i.e.,
- ; by writing to the device) to toggle these parameters.
- ;================================================================
- ; Assembler setup commands
- ;================================================================
- CSEG Segment byte public "CODE"
- Assume CS:CSEG,DS:CSEG,ES:CSEG
- Org 00H ;<============ NOTE!
- PREFERS:
- ;================================================================
- ; D R I V E R H E A D E R B L O C K
- ;
- ; Bytes 0000h-0011h of the driver M-U-S-T be set up as follows:
- ;================================================================
- DW 0FFFFh ;+0: Offset of next Device (if any)
- DW 0FFFFh ;+2: Segment of next Device (if any)
- ;----------------------------------------------------------------
- DW 8000h ;+4: Device Attribute Word
- ; (Bit 15 SET for "Character" device)
- ;----------------------------------------------------------------
- DW Offset STRAT ;+6: Offset of "Strategy" routine
- DW Offset INTRPT ;+8: Offset of "Interrupt" routine
- ;----------------------------------------------------------------
- DB 'I_PREFER' ;+0Ah..+11h = Name of Driver
- ; (padded with spaces, as required)
- ;================================================================
- PAGE
- ;================================================================
- ; S T R A T E G Y R O U T I N E
- ;
- ; Called by DOS to save the pointer (in ES:BX) to the Device
- ; Driver Request Header.
- ;----------------------------------------------------------------
- STRAT:
- MOV CS:[HDROFS],BX ;Save offset of Request Header
- MOV CS:[HDRSEG],ES ;Save segment of Request Header
- RETF ;Return to DOS
- ;================================================================
- ; Local Data Storage...
- ;----------------------------------------------------------------
- HEADER LABEL DWORD ;Allow for DD reference
- HDROFS DW 0000 ;Seqment storage
- HDRSEG DW 0000 ;Offset storage
- TOGGLE DB 01 ;Storage for current toggle states
- ; 01 = EGA Blink Bit ON
- ;================================================================
- PAGE
- ;================================================================
- ; I N T E R R U P T P R O C E D U R E
- ;
- ; Called by DOS to process a driver request, as defined in the
- ; Request Header. The Request Header is found at the address
- ; previously passed to the Strategy Routine.
- ;
- ; Request Header format:
- ; +00 = NUMB Number of bytes in Request Header (byte)
- ; +01 = UNIT Unit Number of this request (byte) (BLOCK)
- ; +02 = CMMD Request Command Code (byte)
- ; +03 = STAT Returned Status (word)
- ; +05 = RESRVED Reserved by DOS (8 bytes)
- ; +0D = MEDIA Media Descriptor (byte)
- ; +0E = ADDR Data Transfer Address (word:word)
- ; +12 = COUNT Byte or sector count (word)
- ; +14 = SECT Starting sector value (BLOCK DEVICE)
- ;================================================================
- ; I _ P R E F E R I N T E R R U P T L O G I C
- ;----------------------------------------------------------------
- INTRPT:
- PUSH AX ;Save the entry registers...
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH ES
- PUSH DI
- PUSH SI
- ;----------------------------------------------------------------
- ; Retrieve the address of the Request Header and get the CMMD.
- ;----------------------------------------------------------------
- PUSH CS
- POP DS
- LES BX,CS:[HEADER] ;ES:BX = [HDRSEG:HDROFS]
- MOV AL,ES:[BX+02] ;CMMD = HDRSEG:[HDROFS+2]
- ;----------------------------------------------------------------
- ; If CMMD IS "Write" or "Write with Verify", go to the "WRITE"
- ; logic.
- ;----------------------------------------------------------------
- CMP AL,08h ;If CMMD = "WRITE" then...
- JZ WRITE ;...WRITE
- CMP AL,09h ;If CMMD = "WRITEV" then...
- JZ WRITE ;...WRITE
- ;----------------------------------------------------------------
- ; If CMMD IS "INIT," go to the Initialization logic.
- ;----------------------------------------------------------------
- CMP AL,00 ;If CMMD = "INIT" then...
- JMP INIT ;...INITIALIZE
- ;----------------------------------------------------------------
- PAGE
- ;----------------------------------------------------------------
- ; For any other CMMD, return an error code in the STATUS
- ; parameter and return to DOS.
- ;----------------------------------------------------------------
- BADRTN:
- MOV Word Ptr ES:[BX+03],8103h
- JMP RETURN ;Return
- NOP
- ;----------------------------------------------------------------
- ; Return through here when done
- ;----------------------------------------------------------------
- GUDRTN:
- MOV Word Ptr ES:[BX+03],0100h
- ;----------------------------------------------------------------
- ; Restore registers and return to DOS
- ;----------------------------------------------------------------
- RETURN:
- POP SI ;Restore the entry registers...
- POP DI
- POP ES
- POP DX
- POP CX
- POP BX
- POP AX
- RETF ;Return (Far)
- ;================================================================
- PAGE
- ;================================================================
- ; W R I T E P R O C E D U R E
- ;
- ; Retrieve the "output message" for the driver. This should be
- ; one character, where...
- ;
- ; ... N or n toggles the NumLock state (Initially OFF)
- ; ... L or l toggles the EGA 43-line mode (Initially ON)
- ; ... B or b toggles the EGA video blink state (Initially OFF)
- ;================================================================
- WRITE:
- LDS SI,ES:[BX+0Eh] ;DS:SI = ADDR
- LODSB ;AL = DS:[SI] = [ADDR] = "x"
- PUSH CS ;Move CS...
- POP DS ;...into DS
- ;----------------------------------------------------------------
- ; For [N,L,B]: Go to the appropriate "toggle" logic.
- ; (Otherwise, ignore the character.)
- ;----------------------------------------------------------------
- AND AL,5Fh ;Make letter upper case
- CMP AL,4Eh ;If (AL = 'N') then...
- JNE NotNum
- CALL NUMLCK ;...CALL NUMLCK
- JMP GUDRTN
- NotNum:
- CMP AL,4Ch ;If (AL = 'L') then...
- JNE NotLine
- CALL EGA43 ;...CALL EGA43
- JMP GUDRTN
- NotLine:
- CMP AL,42h ;If (AL = 'B') then...
- JNE BADRTN
- CALL BLINK ;...CALL BLINK
- JMP GUDRTN
- ;================================================================
- PAGE
- ;================================================================
- ; NUMLCK: Toggles the NumLock State for the keyboard.
- ;----------------------------------------------------------------
- NUMLCK PROC NEAR
- PUSH AX ;Save the...
- PUSH ES ;...entry registers
- MOV AX,0040h ;Set DS to...
- MOV ES,AX ;...0040 (BIOS segment)
- MOV AL,Byte Ptr ES:[0017h] ;Get the keyboard state
- TEST AL,20h ;Test the NumLock bit
- JNZ NumOFF ;
- NumON:
- OR AL,20h ;If OFF, turn it ON
- JMP NumSet
- NumOFF:
- AND AL,0DFh ;If ON, turn it OFF
- NumSet:
- MOV Byte Ptr ES:[0017h],AL ;Put it back
- POP ES ;Restore the...
- POP AX ;...entry registers
- RET ;Return to the caller
- NUMLCK ENDP
- ;================================================================
- ; BLINK: Toggles the EGA/VGA Blink Bit
- ;----------------------------------------------------------------
- BLINK PROC NEAR
- PUSH AX ;Save the...
- PUSH BX
- PUSH DS ;...entry registers
- PUSH CS
- POP DS
- MOV AL,[TOGGLE] ;Get the current toggle word
- TEST AL,01 ;Test the Blink state bit
- JNZ BlkOff
- BlkOn:
- MOV BL,01 ;Turn ON if currently OFF
- OR AL,01
- JMP BlkSet
- BlkOff:
- MOV BL,00 ;Turn OFF if currently ON
- AND AL,0FEh
- BlkSet:
- MOV [TOGGLE],AL
- MOV AX,1003h
- INT 10h
- POP DS ;Restore the...
- POP BX
- POP AX ;...entry registers
- RET
- BLINK ENDP
- ;================================================================
- PAGE
- ;================================================================
- ; EGA43: Toggles the 43-line mode for the EGA video.
- ; (Also, sets up a block cursor, "fixes" the EGA cursor
- ; emulation, and selects the EGA BIOS "Print Screen"
- ;----------------------------------------------------------------
- EGA43 PROC NEAR
- PUSH AX ;Save the...
- PUSH BX
- PUSH CX
- PUSH ES ;...entry registers
- ;----------------------------------------------------------------
- ; If the current BIOS screen lines count (less one) at 0040:0084
- ; is NOT 42, then go set up the 43-line mode. Otherwise, restore
- ; the 25-line mode
- ;----------------------------------------------------------------
- MOV AX,0040h ;Set DS to...
- MOV ES,AX ;...0040 (BIOS segment)
- MOV AL,Byte Ptr ES:[0084h] ;IF (0040:0084 <> 42) then...
- CMP AL,42
- JNE GoTo43 ;...GoTo43
- ;----------------------------------------------------------------
- ; Select the 8x14 font and adjust the screen lines (to 25).
- ;----------------------------------------------------------------
- GoTo25:
- MOV AX,1111h
- MOV BL,00
- INT 10h
- ;----------------------------------------------------------------
- ; Turn the EGA cursor emulation logic back on and set up a block
- ; cursor. Then return.
- ;----------------------------------------------------------------
- AND Byte Ptr ES:[0087h],0FEh
- JMP SetCur
- ;----------------------------------------------------------------
- ; Select the 8x8 character font and adjust the screen lines
- ;----------------------------------------------------------------
- GoTo43:
- MOV AX,1112h ;Load the 8x8 font & recalculate
- MOV BL,00 ;RAM block 0
- INT 10h ;BIOS Video Service
- ;----------------------------------------------------------------
- ; Select the alternate (EGA BIOS) Print Screen function
- ;----------------------------------------------------------------
- MOV BL,20h
- MOV AH,12h
- INT 10h
- ;----------------------------------------------------------------
- ; Turn off the buggy EGA cursor emulation and set up a block
- ; cursor. Then return.
- ;----------------------------------------------------------------
- OR Byte Ptr ES:[0087h],01
- SetCur:
- MOV CX,0007h ;CH = Scan top; CL = Scan bottom
- MOV AH,01 ;"Set Cursor Size"
- INT 10h
- POP ES ;Restore the...
- POP CX
- POP BX
- POP AX ;...entry registers
- RET
- EGA43 ENDP
- ;================================================================
- RUNSIZ EQU $-PREFERS
- DB (0100H-RUNSIZ) DUP(00)
- ;================================================================
- PAGE
- ;================================================================
- ; I N I T I A L I Z A T I O N L O G I C
- ;================================================================
- ; This logic is invoked when DOS installs the driver. (CMMD = 0).
- ; The initialization steps include:
- ;
- ; 1. Reseting the keyboard NumLock state.
- ; 2. Setting the EGA video into 43-line mode
- ; 3. Turning off the EGA blink bit
- ; 4. Displaying the "I'm here!" message on the video screen.
- ;
- ; When done, the logic tells DOS where the "expendable" part of
- ; the driver (the initialization logic itsef) begins. DOS will
- ; then release the memory AFTER that address for its own use.
- ;----------------------------------------------------------------
- INIT LABEL NEAR
- PUSH AX ;Save registers
- PUSH BX ;
- PUSH CX ;
- PUSH DX ;
- PUSH ES ;
- ;----------------------------------------------------------------
- ; Call the mainline procedures to set the initial preferences.
- ;----------------------------------------------------------------
- CALL NUMLCK ;Turn OFF the NumLock State
- CALL EGA43 ;Turn ON the EGA 43-line mode
- CALL BLINK ;Turn OFF the EGA Blink bit
- ;----------------------------------------------------------------
- ; Announce the installation of the driver.
- ;----------------------------------------------------------------
- LEA DX,IMHERE ;DX = Offset(IMHERE)
- MOV AH,09h ;"Display string"
- INT 21h ;DOS service
- ;----------------------------------------------------------------
- PAGE
- ;----------------------------------------------------------------
- ; Release the initialization logic and return.
- ;----------------------------------------------------------------
- POP ES ;Restore the key entry registers
- POP DX ;
- POP CX ;
- POP BX ;
- LEA AX,INIT ;AX = Offset(INIT)
- MOV Word Ptr ES:[BX+0Eh],AX ;"ADDR" = AX
- MOV Word Ptr ES:[BX+10h],CS ;"ADDR+2" = CS
- POP AX ;Restore AX
- JMP GUDRTN ;Return
- ;================================================================
- IMHERE LABEL NEAR
- DB 0Dh,0Ah,'PREFERS.SYS Preferences Driver Installed.'
- DB 0Dh,0Ah
- DB 'Write N, L, or B to I_Prefer to change',0Dh,0Ah,'$'
- CSEG ENDS
- END PREFERS
- ;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*