;************************************************
;* Prog5_4.asm *
;* Practical Character Driver CON3 *
;* Author: YU.I.Petrenko *
;************************************************
.286
code segment byte
assume CS:code,DS:code,ES:code,SS:nothing
;====================================================
; CON3 - true character device driver
;====================================================
Con2header: ; CON3 device header
;====================================================
Link DW -1,-1
Attributes DW 8013h ;Bits 15,4,1 and 0 are set
Strategy DW Stratgy
Interrupt DW Intrpt
DrvName DB 'CON',5 dup (' ')
;====================================================
Stratgy: ;Strategy Routine
;====================================================
MOV WORD PTR CS:[ReqHdr],BX
MOV WORD PTR CS:[ReqHdr+2],ES
RETF
;----------------------------------------------------
ReqHdr DD 0
;====================================================
Intrpt: ;Interrupt Routine
;====================================================
PUSHF ;Register savings
PUSHA
PUSH DS
PUSH ES
;----------------------------------------------------
CLD
LES DI,CS:[ReqHdr] ;RequESt header in ES:DI
MOV BL,BYTE PTR ES:[DI+2] ;Command code
XOR BH,BH ;now is
SHL BL,1 ;in AX
CMP BL,22 ;Is command valid?
JNA Valid ;Yes, valid
JMP ErrCom ;No, erroneous
Valid:
JMP WORD PTR CS:[BX+Comtable]
;Yes, valid -> execute it
;----------------------------------------------------
ComTable:
;----------------------------------------------------
DW Init ;00h - Init
DW OutFrom ;01h - Illegal Request = Media Check
DW OutFrom ;02h - Illegal Request = Build BPB
DW ErrCom ;03h - Erroneous Command
IOCTL DW Read ;04h - Read
DW NndRead ;05h - Nondestructive Read
DW InpStatus ;06h - Input Status
DW InpFlush ;07h - Input Flush
DW Write ;08h - Write
DW WriteVer ;09h - Write with Verify
DW OutptStatus ;0AH - Output Status
DW OutptFlush ;0BH - Output Flush
;----------------------------------------------------
MakeIt:
;----------------------------------------------------
CALL Beg
PUSH CS
POP DS
LES BX,ReqHdr
CALL DWORD PTR[ConStrategy]
PUSH CS
POP DS
LES BX,ReqHdr
CALL DWORD PTR[ConInterrupt]
JMP done
;----------------------------------------------------
Message1 DB 0Dh,0Ah
DB ' Message 1',0dh,0AH,'$'
OldSymbol DB 0
;----------------------------------------------------
Read: ;Command 04h - Read
;----------------------------------------------------
;JMP MakeIt
CALL Beg ;
LES BX,CS:ReqHdr ; ???what is this!!!!
MOV CX,ES:[BX+12h] ;
TEST CX,CX
JZ JmpOut
LES DI,DWORD PTR ES:[BX+0Eh]
;----------------------------------------------------
Reading:
PUSH CX
CALL InputChar
POP CX
STOSB
LOOP Reading
JmpOut:
JMP OutFrom
InputChar:
MOV AX,0
XCHG AL,OldSymbol
TEST AL,AL
JNZ Rt ;Return
InChr:
MOV AH,0
INT 16h
TEST AX,AX
JZ InChr ;
TEST AL,AL
JNZ Rt
MOV OldSymbol,AH
Rt: RET
;----------------------------------------------------
NndRead: ;Command 05h -
;NondEStructive Read
;----------------------------------------------------
;JMP MakeIt
CALL Beg ;
RdOld:
MOV AL,CS:[OlDSymbol] ;Read old symbol
TEST AL,AL
JNZ SblOut ;Old symbol in AL
MOV AH,1
INT 16h
JNZ Got
MOV AH,3
JMP Out1
Got:
TEST AX,AX ;Symbol has been got
JNZ SblOut
MOV AH,0
INT 16h
JMP RdOld
SblOut: ;Symbol's out
LDS BX,CS:[ReqHdr]
MOV [BX+13],AL
MOV AH,01h
JMP Out1
;----------------------------------------------------
InpStatus:
;----------------------------------------------------
JMP MakeIt
;----------------------------------------------------
InpFlush:
;----------------------------------------------------
;JMP MakeIt
CALL beg ;Before the command
MOV CS:[OlDSymbol],0
XOR AX,AX
MOV ES,AX
MOV BYTE PTR ES:[41AH],20h
MOV BYTE PTR ES:[41Ch],20h
JMP Done
;----------------------------------------------------
Write:
;----------------------------------------------------
JMP MakeIt
;----------------------------------------------------
WriteVer:
;----------------------------------------------------
JMP MakeIt
;----------------------------------------------------
OutptStatus:
;----------------------------------------------------
JMP MakeIt
;----------------------------------------------------
OutptFlush:
;----------------------------------------------------
JMP MakeIt
;====================================================
; Various Exits
;====================================================
ErrCom: ;Erroneous command
MOV AX,8103h ;AL=03h - Unknown
;command Error value
;AH=81h - errOR+done bits
JMP outfrom
;----------------------------------------------------
ErrUnnwn: ;Unknown error
MOV AX,8100h ;AH=81h - error+done bits
JMP Outfrom
DrvBusy:
MOV AX,0300h ;Driver busy
JMP OutFrom
Done:
MOV AX,0
OutFrom:
MOV AH,1 ;Bit done
Out1:
LES BX,DWORD PTR CS:[ReqHdr];Request header in DS:BX
MOV WORD PTR ES:[BX+3],AX ;Status word now = AX
POP ES
POP DS
POPA
POPF
RETF ;Exit from driver
;====================================================
Message DB 0dh,0AH
DB ' Now CON3 is resident'
DB 0dh,0AH,'$'
;----------------------------------------------------
DoMessage:
PUSH CS
POP DS
MOV DX,offset Message
MOV AH,9
INT 21h
RET
Init:
CALL DoMessage
LES DI,DWORD PTR CS:[ReqHdr]
;Request header in DS:BX
MOV WORD PTR ES:[DI+0Eh],offset Endd
;End of driver's memory
MOV ES:[DI+10h],CS
JMP Done
;----------------------------------------------------
ConAdr DD 0
ConStrategy DD 0
ConInterrupt DD 0
;----------------------------------------------------
Beg:
;----------------------------------------------------
;At first this subroutine checks if it is the first
;search. If not, it returns. Else this subroutine
;gets the current driver Header address and extracts
; the driver Name. Later this name is compared
;with its own name (CON), byte after byte. If name differs,
;it reads addresses of next driver, if it exists, and
;saves them. Then the driver search is repeated.
;When the driver with identical name is found,
;the search is finished.
;----------------------------------------------------
PUSH CS
POP DS
TEST WORD PTR [ConAdr+2],0ffffh
;First search? If first, the word contents 0. If not,
;it contents nonzero address segment.
JZ D ;Yes
RET;No,return
D: ;Driver search
LES BX,DWORD PTR [Link]
CMP BX,0FFFFh ;Is the driver the last
;in the System?
JNZ DrvrSearch
RET ;Yes, return
DrvrSearch: ;No, try to meet the twin
MOV CX,8
MOV DI,offset DrvName
MOV SI,0Ah
L: ;Comparing of driver
;name with the own
MOV AL,ES:[BX+SI]
CMP BYTE PTR [DI],AL ;Identical?
JZ Go ;One character more
;coincides yet
JMP Next ;No, that one differs
Go: ;Hope exists yet,
;let's continue
INC DI
INC SI
LOOP L ;This driver is identical
MOV WORD PTR [ConAdr],BX
MOV WORD PTR [ConAdr+2],ES ;[ConAdr+2] is a flag!
MOV AX,WORD PTR ES:[BX+6] ;Storing the twin driver's
;personal data
;for the future using
MOV WORD PTR[ConStrategy],AX
MOV WORD PTR[ConStrategy+2],ES
MOV AX,WORD PTR ES:[BX+8]
MOV WORD PTR[ConInterrupt+2],ES
MOV WORD PTR[ConInterrupt],AX
RET
Next: ;Try if is the driver last
CMP ES:[BX],0ffffh
JZ Last ;Yes, last driver, return
LES BX,DWORD PTR ES:[BX] ;Not last, try to find the twin
;Now the ES:BX points to the
;next Driver Header
JMP DrvrSearch
Last:
RET
;----------------------------------------------------
Endd:
;----------------------------------------------------
NOP ;These NOP's marks
NOP ;the end of the
CODE ENDS ;program (in debugger)
END
;====================================================
;****************************************************