false equ 0 true equ not false title GUMDisk Block device driver for MS-DOS 3.0 cseg segment assume cs:cseg subttl device header device_header label word dw -1,-1 attributes dw 0110000000000000b dw strategy_entry dw interrupt_entry db 1,'2345678' subttl daten format_data db 0,0,0 db 04DH,053H,044H,04FH db 053H,033H,02EH,032H gumdiskbpb dw 512 db 2 dw 1 db 2 dw 112 nu_of_sectors dw 719 db 0FDH dw 2 dw 9 dw 2 belegung db 00FDH,0FFH,0FFH volume_label db 4FH,44H,2DH,52H,61H,6DH,44H,69H db 73H,6BH,20H,28H,00H,00H,00H db 00H,00H,00H,00H,00H,00H,00H db 0ADH,09H,25H,10H drive_func_table label word dw init_gumdisk dw media_check dw build_bpb dw io_control_input dw file_input dw bad_command dw bad_command dw bad_command dw file_output dw file_output dw bad_command dw bad_command dw io_control_output sector_count dw ? media_check_b db 1 request_ptr dd 0 gumdiskbpb_ptr dw gumdiskbpb gumd_segments db 48 dup (0) vergroessert db false zaehler dw 0 test_flag db 'M&T GUMDISK.DEV ' subttl strategy entry point strategy_prg proc far strategy_entry: mov word ptr [request_ptr],bx mov word ptr [request_ptr+2],es ret strategy_prg endp subttl interrupt entry point interrupt_entry: push ax push bx push cx push dx push bp push di push si push ds push es push cs pop ds cmp media_check_b,-1 jne nicht_initialisieren cmp word ptr [nu_of_sectors],0 je nicht_initialisieren cmp vergroessert,true je nicht_initialisieren call format nicht_initialisieren: lds bx,[request_ptr] mov al,byte ptr [bx+2] cmp al,3 je bereit cmp al,12 je bereit cmp word ptr [nu_of_sectors],0 je nicht_bereit cmp al,12 ja bad_command bereit: cbw shl ax,1 mov si,offset drive_func_table add si,ax push cs pop ds jmp word ptr[si] nicht_bereit: mov al,2 jmp short error_exit bad_command: mov al,3 jmp short error_exit schreib_fehler: mov al,10 jmp short error_exit lese_fehler: mov al,11 error_exit: mov ah,10000001b jmp short err exit_prg proc far ende:xor al,al mov ah,1 err: lds bx,[request_ptr] mov word ptr [bx+3],ax pop es pop ds pop si pop di pop bp pop dx pop cx pop bx pop ax ret exit_prg endp subttl media check routine media_check: lds bx,[request_ptr] mov al,cs:media_check_b mov byte ptr[bx+14],al mov media_check_b,1 jmp ende subttl build bpb build_bpb: lds bx,[request_ptr] mov word ptr [bx+18],offset gumdiskbpb mov [bx+20],cs jmp ende subttl i/o-control input io_control_input: les bx,[request_ptr] lds si,dword ptr es:[bx+14] mov cx,es:[bx+18] cmp cx,48 jne falsche_laenge push cs pop es mov di,offset gumd_segments rep movsb mov si,offset gumd_segments+2 mov cx,12 xor dx,dx zaehlen: add dx,word ptr cs:[si] add si,4 loop zaehlen push cs pop ds mov vergroessert,false cmp word ptr [gumd_segments],0 je aus cmp word ptr [nu_of_sectors],0 je neu mov vergroessert,true neu: mov word ptr [nu_of_sectors],dx mov es,word ptr [gumd_segments] mov word ptr es:[20],dx mov media_check_b,-1 ic_ende: lds bx,[request_ptr] mov word ptr [bx+18],48 jmp ende falsche_laenge: mov word ptr[bx+18],0 jmp bad_command aus: mov word ptr[nu_of_sectors],0 jmp short ic_ende subttl i/o-control output io_control_output: lds bx,[request_ptr] les di,dword ptr [bx+14] mov cx,[bx+18] push cs pop ds cmp cx,17 jne nicht_testflag mov si,offset test_flag rep movsb lds bx,[request_ptr] mov word ptr[bx+18],17 jmp ende nicht_testflag: cmp cx,48 jne nicht_konfiguration mov si,offset gumd_segments rep movsb lds bx,[request_ptr] mov word ptr[bx+18],48 jmp ende nicht_konfiguration: lds bx,[request_ptr] mov word ptr[bx+18],0 jmp bad_command file_io_init proc near push ds mov ds,ax mov cx,[bx+18] mov cs:[sector_count],cx mov dx,[bx+20] mov ax,dx add ax,cx cmp ax,word ptr cs:[nu_of_sectors] jbe gueltiger_sector mov word ptr [bx+18],0 mov al,8 jmp error_exit gueltiger_sector: mov bp,0 mov zaehler,0 mov ax,word ptr cs:[gumd_segments] pop ds ret file_io_init endp bestimmte_adresse proc near cmp dx,word ptr cs:[gumd_segments+bp+2] jb richtiger_bereich mov cx,zaehler cmp cx,0 je keine_korrektur korrektur: add dx,128 loop korrektur mov zaehler,0 keine_korrektur: sub dx,word ptr cs:[gumd_segments+bp+2] add bp,4 mov ax,word ptr cs:[gumd_segments+bp] jmp short bestimmte_adresse richtiger_bereich: cmp dx,128 jnb nicht_fertig ret nicht_fertig: add ax,1000H sub dx,128 inc zaehler jmp short richtiger_bereich bestimmte_adresse endp subttl read file file_input: lds bx,[request_ptr] les di,dword ptr[bx+14] mov ax,ds call file_io_init lesen: call bestimmte_adresse mov ds,ax mov si,dx mov cl,9 shl si,cl mov cx,256 rep movsw dec cs:[sector_count] jz input_ende inc dx jmp short lesen input_ende: jmp ende subttl write file file_output: les bx,[request_ptr] lds si,dword ptr es:[bx+14] mov ax,es call file_io_init schreiben: call bestimmte_adresse mov es,ax mov di,dx mov cl,9 shl di,cl mov cx,256 rep movsw dec cs:[sector_count] jz output_ende inc dx jmp short schreiben output_ende: jmp ende subttl format gumdisk format proc near mov es,word ptr[gumd_segments] mov di,0 mov cx,12*256 mov ax,0 rep stosw mov si,offset format_data mov di,0 mov cx,14 rep movsw mov dx,word ptr [belegung] mov word ptr es:[512],dx mov dl,byte ptr [belegung+2] mov byte ptr es:[514],dl mov dx,word ptr [belegung] mov word ptr es:[3*512],dx mov dl,byte ptr [belegung+2] mov byte ptr es:[3*512+2],dl mov di,5*512 mov si,offset volume_label mov cx,13 rep movsw ret format endp subttl initialize gumdisk inst_message db 13,10 db 'GUMDisk Device Driver V2.1 by Markt & Technik' db 13,10,' Logisches Laufwerk : ' drivestring db '#' db 13,10,' Ph. Sektorgr”áe : 512 Byte' db 13,10,' Zuordnungseinheit : 2 Sektoren' db 13,10,' Directory-Eintr„ge : max. 112' db 13,10,'Einrichtung mit GDISK.COM ' db 13,10,'$' init_gumdisk: lds bx,[request_ptr] mov byte ptr[bx+13],1 mov word ptr [bx+14],offset inst_message mov word ptr [bx+16],cs mov word ptr [bx+18],offset gumdiskbpb_ptr mov word ptr [bx+20],cs mov ah,byte ptr [bx+22] add ah,65 push cs pop ds mov byte ptr [drivestring],ah mov word ptr [nu_of_sectors],0 mov media_check_b,-1 mov dx,offset inst_message mov ah,9 int 21h jmp ende cseg ends end