X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f Date: Fri, 20 Mar 2009 15:32:29 -0400 Message-Id: <200903201932.n2KJWTFo023165@envy.delorie.com> From: DJ Delorie To: djgpp AT delorie DOT com In-reply-to: (do_not_have@nohavenot.cmm) Subject: Re: Dos programming References: <06c3c085-f8d3-497f-8f68-3db8518f7938 AT e18g2000yqo DOT googlegroups DOT com> <6ecec264-3874-47ef-b9d7-406f29d72679 AT s20g2000yqh DOT googlegroups DOT com> <4f7b4d8f-fa46-43d0-813f-1f37466aa3ce AT v38g2000yqb DOT googlegroups DOT com> <387c477c-acc2-45ff-bfd2-382f85cccf29 AT e38g2000yqa DOT googlegroups DOT com> Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > AFAICT, there aren't many DOS .sys device drivers with source. Here, have another one. It's only 21 years old but should still useful :-) I probably have a bunch more kicking around, too, although most of my utilities were TSRs, not device drivers. title buf160 ; History:216,15 ; 09-21-87 12:53:59 rearranged force routine ; 09-16-87 16:07:46 added publics ; 09-16-87 16:01:41 comment out buffer transfer code with equate ; DJ Delorie ; ; masm buf160; ; link buf160; ; exe2bin buf160.exe buf160.sys ; ; DEVICE=buf160.sys ( in config.sys) ; transfer equ 1 dqq struc ofs dw ? seg dw ? dqq ends wqq struc w dw ? wqq ends bqq struc b db ? bqq ends rqq struc len db ? unit db ? code db ? status dw ? q1 dd ? q2 dd ? mdesc db ? trans dd ? count dw ? rqq ends cseg segment byte assume cs:cseg,ds:cseg,es:cseg,ss:cseg org 0 success equ 0100h error equ 8100h busy equ 0300h public header header label near dd -1 dw 8000h dw strat dw intr db 'KBUFFER$' public req req dd ? dw 0 buffer_get equ 1ah buffer_put equ 1ch buffer_start equ 80h buffer_end equ 82h public queue_start,queue_end queue_start label word dw 160 dup (0) queue_end label word dw 0 public strat strat proc far mov cs:[req].ofs,bx mov cs:[req].seg,es ret strat endp public intr intr proc far push ds push es push ax push bx push cx push dx push di push si mov ax,cs mov ds,ax les bx,cs:req mov si,offset cmd_table mov cl,es:[bx].code mov ch,0 shl cx,1 add si,cx call [si].w les bx,cs:req mov es:[bx].status,ax pop si pop di pop dx pop cx pop bx pop ax pop es pop ds ret public cmd_table cmd_table: dw cmd_init dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_none dw cmd_output dw cmd_output dw cmd_output_status dw cmd_none dw cmd_none public cmd_none cmd_none proc near mov ax,success ret cmd_none endp public cmd_output cmd_output proc near mov ax,40h mov ds,ax mov cx,es:[bx].count les bx,es:[bx].trans output_loop: mov al,es:[bx] inc bx call force jc output_error loop output_loop mov ax,success ret output_error: mov ax,error ret cmd_output endp public force force proc near cli mov di,ds:[buffer_put] call buf_wrap cmp di,ds:[buffer_get] je buffer_full xchg ds:[buffer_put],di xor ah,ah mov ds:[di],ax clc sti ret buffer_full: stc sti ret force endp public buf_wrap buf_wrap proc near inc di inc di cmp di,ds:[buffer_end] jne no_wrap mov di,ds:[buffer_start] no_wrap: ret buf_wrap endp public cmd_output_status cmd_output_status proc near mov ax,40h mov ds,ax mov di,ds:[buffer_put] mov si,ds:[buffer_get] call buf_wrap cmp si,di je buffer_busy mov ax,success ret buffer_busy: mov ax,busy ret cmd_output_status endp public last_code last_code label near public cmd_init cmd_init proc near mov ax,cs mov ds,ax cmp ax,0ff8h jbe no_init_error jmp init_error no_init_error: mov cx,40h mov ds,cx mov ax,ds:[buffer_start] cmp ax,0 je incompatible if transfer public transfer_buffer transfer_buffer: mov si,ds:[buffer_get] mov di,ds:[buffer_put] mov bx,0 transfer_loop: cmp si,di je transfer_done mov ax,[si] mov cs:queue_start[bx],ax inc si inc si inc bx inc bx cmp si,ds:[buffer_end] jne transfer_loop mov si,ds:[buffer_start] jmp transfer_loop public transfer_done transfer_done: endif mov ax,cs sub ax,cx shl ax,1 shl ax,1 shl ax,1 shl ax,1 mov cx,ax add cx,offset queue_start mov ds:[buffer_start],cx mov ds:[buffer_get],cx add cx,bx mov ds:[buffer_put],cx add ax,offset queue_end mov ds:[buffer_end],ax les bx,cs:[req] mov es:[bx].trans.ofs,offset last_code mov es:[bx].trans.seg,cs push cs pop ds mov ah,9 mov dx,offset banner int 21h mov ax,success ret incompatible: push cs pop ds mov ah,9 mov dx,offset msg_bad int 21h mov es:[bx].trans.ofs,0 mov es:[bx].trans.seg,cs mov ax,success ret public init_error init_error: mov dx,offset msg_err mov ah,9 int 21h mov es:[bx].trans.ofs,0 mov es:[bx].trans.seg,cs mov ax,success ret cmd_init endp public banner, msg_err banner db 'Buf160 has been loaded.',13,10,'$' msg_err db 'Buf160 is not in the first 64K of RAM.',13,10 db 'Please make sure that Buf160 is the first entry in your config.sys file.',13,10,'$' msg_bad db 'Buf160 is not compatible with this computer.',13,10,'$' intr endp cseg ends end