home *** CD-ROM | disk | FTP | other *** search
-
- ;DRIVER2.SYS B.Kauler,89
- ;simple device driver
- ;.....
- code_seg segment para public 'code'
- main_proc proc far
- assume cs:code_seg,es:code_seg,ds:code_seg
- org 0 ;required for device drivers.
- begin:
- ;...........................................
- ;this area is the DEVICE HEADER....
- next_dev dd -1 ;no other device drivers
- attribute dw 8000h ;character device.
- strategy dw dev_str ;addr of 1st DOS call.
- interrupt dw dev_int ;addr of 2nd DOS call.
- dev_name db "PRN " ;name of the driver.
- ;...........................................
- ;this is the LOCAL WORKSPACE AREA....
- rh_off dw ? ;Request Header offset.
- rh_seg dw ? ;Request Header segment.
- messages db 07h
- db "Simple character device driver"
- db 0Dh,0Ah,07h,"$"
- ;...........................................
- ;this is the STRATEGY procedure area...
- dev_str:
- push ds ;save DS.
- push cs ;to avoid segment
- pop ds ; override.
- mov rh_seg,es ;save Req.Header seg.
- mov rh_off,bx ;save Req.Head offset.
- pop ds ;restore DS.
- ret
- ;..........................................
- ;this is the INTERRUPT procedure.....
- dev_int:
- push ds ;save registers.
- push es ; /
- push ax ; /
- push bx ; /
- push cx ; /
- push dx ; /
- push di ; /
- push si ; /
- push cs ;to avoid segment
- pop ds ; override.
- ;.......................
- ;I would like to dump the Req.Hdr
- ;to the printer....
- call dump
- ;.......................
- ;I will not assume that the second call to the
- ;driver will still have the addr. of the Req.
- ;Hdr. in ES:BX. Load it from workspace...
- mov es,rh_seg
- mov bx,rh_off
- ;.......................
- ;perform branch based on the command passed in
- ;the Request Header...
- mov al,es:[bx+2] ;get command code.
- cmp al,0 ;check for zero.
- je initialise
- cmp al,8 ;check for o/p
- jne nogo
- jmp data_out
- nogo: cmp al,10 ;check o/p status.
- je out_status
- ;just return the DONE-bit set in status
- ;byte of Req.Hdr, for these commands....
- cmp al,1
- je done
- cmp al,2
- je done
- cmp al,4
- je done
- cmp al,5
- je done
- cmp al,6
- je done
- cmp al,7
- je done
- cmp al,11
- je done
- cmp al,13
- je done
- cmp al,14
- je done
- ;for any other command,return error...
- jmp errors
- done:
- mov es:word ptr [bx+3],0100h ;return status.
- jmp finish
- ;......................................
- out_status:
- ;DOS functions that access the printer
- ;most likely check the output status, so I
- ;had better respond to this command....
- ;Bit-9 in the status-word of the Req.Hdr
- ;=0 if not busy. Bit-8 =1 job done....
- mov es:word ptr [bx+3],0100h
- jmp finish
- ;...............
- initialise:
- ;perform required initialisation action...
- mov dx,offset messages ;message
- mov ah,9 ;to screen.
- int 21h ;/
- ;............
- mov es:word ptr [bx+3],0100h ;return status.
- ;............
- ;it seems that DOS will also require to know
- ;where the driver ends....
- mov ax,offset the_end ;end prog.
- mov es:[bx+14],ax ;break-addr for DOS.
- mov es:[bx+16],cs ; /
- ;.......................
- ;I would like to display some info about
- ;where this driver starts and ends in
- ;memory...
- push cs
- pop dx
- mov di,offset msga
- call hex2asc
- mov ah,9
- mov dx,offset msgb
- int 21h
- jmp goon1
- msgb db "driver loaded at segment "
- msga db "0000h",0Dh,0Ah,"$"
- goon1: mov dx,offset begin
- mov di,offset msgc
- call hex2asc
- mov ah,9
- mov dx,offset msgd
- int 21h
- jmp goon2
- msgd db "and starting offset :"
- msgc db "0000h",0Dh,0Ah,"$"
- goon2: mov dx,offset the_end
- mov di,offset msge
- call hex2asc
- mov ah,9
- mov dx,offset msgf
- int 21h
- jmp goon3
- msgf db "and ending offset :"
- msge db "0000h",0Dh,0Ah,"$"
- goon3:
- ;.......................
- ;also I would like to dump the Req.Hdr
- ;to the printer....
- call dump
- ;...................
- jmp finish
- ;.................................
- data_out:
- ;Processing the OUTPUT command...
- ;note that an offset of 13dec from the
- ;beginning of the Req Hdr is the start of
- ;the dynamic portion.
- ;first get the byte count....
- mov cx,es:[bx+18]
- ;now get the data address....
- mov di,es:[bx+14]
- mov ax,es:[bx+16]
- mov es,ax
- ;now transfer the data....
- push bx ;save BX.
- push es ;save ES.
- mov bx,0
- next_char:
- mov al,es:[di]
- inc di
- mov ah,0Eh ;display char.
- int 10h ; /
- loop next_char
- pop es ;restore ES.
- pop bx ;restore BX.
-
- mov es:word ptr [bx+3],0100h ;return status.
-
- jmp finish
- ;..................................
- errors:
- ;put an "E" onto screen....
- push bx
- mov bx,0
- mov ax,0E45h
- int 10h
- pop bx
- mov es:word ptr [bx+3],8103h ;return status
- ;......................................
- finish:
- pop si ;restore all reg's.
- pop di
- pop dx
- pop cx
- pop bx
- pop ax
- pop es
- pop ds
- ret
- ;......................................
- hex2asc proc near
- ;hex to ascii conversion, for display...
- ;requires DX=binary number,DI=addr.ASCII
- ;string. Returns nothing.
- push cx
- push ax
- mov cx,4
- h1: push cx
- mov cl,4
- rol dx,cl
- mov al,dl
- and al,0Fh
- cmp al,0Ah
- jge h2
- add al,30h
- jmp h3
- h2: add al,37h
- h3: mov cs:[di],al
- inc di
- pop cx
- loop h1
- pop ax
- pop cx
- ret
- hex2asc endp
- ;......................................
- dump proc near
- ;a problem I have had with debugging
- ;these drivers is knowing what DOS has
- ;sent to the driver via the Req. Hdr.
- ;This routine will (hopefully) print out
- ;the contents of the Req.Hdr.
- ;Make sure the printer is turned on and
- ;paper inserted.
- mov ax,cs:rh_seg
- mov es,ax
- mov bx,cs:rh_off
- mov al,es:[bx+2] ;get command
- mov ah,0
- rol al,1
- mov di,offset cmtab
- add di,ax
- mov ax,[di]
- call prtmsg
- ;display the req.Hdr....
- mov dl,es:[bx]
- mov dh,0
- mov di,offset crh1
- call hex2asc
- mov dl,es:[bx+1]
- mov dh,0
- mov di,offset crh2
- call hex2asc
- mov dl,es:[bx+2]
- mov dh,0
- mov di,offset crh3
- call hex2asc
- mov dx,es:word ptr [bx+3]
- mov di,offset crh4
- call hex2asc
- mov ax,offset crh
- call prtmsg
- ;display req hdr unique to each
- ;command...
- mov al,es:[bx+2]
- cmp al,0
- jne d1
- d1: cmp al,1
- jne d2
- mov dl,es:[bx+14]
- mov dh,0
- mov di,offset cp1a
- call hex2asc
- mov ax,offset cp1
- call prtmsg
- jmp dexit
- d2: cmp al,2
- jne d3
- d3: cmp al,3
- jne d4
- d4: cmp al,4
- jne d5
- mov dx,es:word ptr [bx+18]
- mov di,offset cp4a
- call hex2asc
- mov dx,es:word ptr [bx+20]
- mov di,offset cp4b
- call hex2asc
- mov ax,offset cp4
- call prtmsg
- jmp dexit
- d5: cmp al,5
- jne d6
- d6: cmp al,6
- jne d7
- d7: cmp al,7
- jne d8
- d8: cmp al,8
- jne d9
- mov dx,es:word ptr [bx+18]
- mov di,offset cp4a
- call hex2asc
- mov dx,es:word ptr [bx+20]
- mov di,offset cp4b
- call hex2asc
- mov ax,offset cp4
- call prtmsg
- jmp dexit
- d9: cmp al,9
- jne da
- mov dx,es:word ptr [bx+18]
- mov di,offset cp4a
- call hex2asc
- mov dx,es:word ptr [bx+20]
- mov di,offset cp4b
- call hex2asc
- mov ax,offset cp4
- call prtmsg
- jmp dexit
- da: cmp al,0Ah
- jne dbb
- dbb: cmp al,0Bh
- jne dc
- dc: cmp al,0Ch
- jne ddd
- ddd: cmp al,0Dh
- jne de
- de: cmp al,0Eh
- jne dff
- dff: cmp al,0Fh
- jne d10
- d10: cmp al,10h
- jne dexit
- dexit: ret
- dump endp
- ;.....
- crh db " len "
- crh1 db "0000",0Dh,0Ah
- db " unit "
- crh2 db "0000",0dh,0ah
- db " cmd "
- crh3 db "0000",0dh,0ah
- db " status "
- crh4 db "0000",0dh,0ah,"$"
- cp1 db " media status "
- cp1a db "0000",0dh,0ah,"$"
- cp4 db " count "
- cp4a db "0000",0dh,0ah
- db " start "
- cp4b db "0000",0dh,0ah,"$"
- cm0 db "initialisation",0dh,0ah,"$"
- cm1 db "media_check ",0dh,0ah,"$"
- cm2 db "get_bpb ",0dh,0ah,"$"
- cm3 db "ioctl_in ",0dh,0ah,"$"
- cm4 db "input ",0dh,0ah,"$"
- cm5 db "nd_input ",0dh,0ah,"$"
- cm6 db "input_status ",0dh,0ah,"$"
- cm7 db "input_flush ",0dh,0ah,"$"
- cm8 db "output ",0dh,0ah,"$"
- cm9 db "output_verify ",0dh,0ah,"$"
- cma db "output_status ",0dh,0ah,"$"
- cmb db "output_flush ",0dh,0ah,"$"
- cmcc db "ioctl_out ",0dh,0ah,"$"
- cmd db "open ",0dh,0ah,"$"
- cme db "close ",0dh,0ah,"$"
- cmf db "removable ",0dh,0ah,"$"
- cm10 db "output_busy ",0dh,0ah,"$"
- cmtab label word
- dw cm0
- dw cm1
- dw cm2
- dw cm3
- dw cm4
- dw cm5
- dw cm6
- dw cm7
- dw cm8
- dw cm9
- dw cma
- dw cmb
- dw cmcc
- dw cmd
- dw cme
- dw cmf
- dw cm10
- ;...............
- prtmsg proc near
- ;requires AX=address of string to be
- ;printed. Returns nothing.
- push dx
- push si
- mov dx,0
- mov si,ax
- prt1: mov ah,0
- mov al,[si]
- cmp al,"$"
- je prt2
- int 17h
- inc si
- jmp prt1
- prt2: pop si
- pop dx
- ret
- prtmsg endp
- ;....................................
- the_end:
- ;..........................................
- main_proc endp
- code_seg ends
- end begin
- ;*****end of device driver******
- ;..........................................
-