; Public Domain %include "lmacros3.mac" cpu 386 org 256 start: mov dx, i24 mov ax, 2524h int 21h mov ah, 52h int 21h cmp dword [es:bx + 22h + 10], "NUL " jne error push dword [es:bx + 22h] pop dword [deviceheader.link] mov word [list], bx mov word [list + 2], es push cs push word deviceheader pop dword [es:bx + 22h] mov dx, i23 mov ax, 2523h int 21h mov ax, 3D00h mov dx, name int 21h jc error_undo push word 0AAAAh push ax pop eax push word 0BBBBh push bx pop ebx push word 0CCCCh push cx pop ecx push word 0DDDDh push dx pop edx mov dx, 0FFFFh mov fs, dx mov dx, 5555h mov gs, dx xchg bx, ax mov dx, buffer mov cx, data.size - 3 mov ah, 3Fh int 21h jnc @F mov ah, 09h mov dx, msg.failedretrying int 21h mov dx, buffer mov cx, data.size - 3 mov ah, 3Fh int 21h jc error_undo_close @@: xchg cx, ax mov ah, 09h mov dx, msg.read int 21h mov ah, 3Eh int 21h mov dx, buffer mov bx, 1 mov ah, 40h int 21h call undo push eax pop ax pop ax mov dx, msg.eaxh cmp ax, 0AAAAh call mismatch push ebx pop bx pop ax mov dx, msg.ebxh cmp ax, 0BBBBh call mismatch push ecx pop cx pop ax mov dx, msg.ecxh cmp ax, 0CCCCh call mismatch push edx pop dx pop ax mov dx, msg.edxh cmp ax, 0DDDDh call mismatch mov ax, fs mov dx, msg.fs cmp ax, 0FFFFh call mismatch mov ax, gs mov dx, msg.gs cmp ax, 5555h call mismatch mov ax, 4C00h int 21h error_undo_close: mov ah, 3Eh int 21h error_undo: call undo error: mov ah, 09h mov dx, msg.error int 21h mov ax, 4CFFh int 21h mismatch: je .ret mov ah, 09h int 21h .ret: retn undo: les bx, [list] push dword [deviceheader.link] pop dword [es:bx + 22h] retn i24: mov al, 01h iret i23: push es push ds push bx push cs pop ds call undo pop bx pop ds pop es stc retf msg: .error: ascic "Error!",13,10 .read: ascic "Read content: " .eaxh: ascic "EAXH mismatch!",13,10 .ebxh: ascic "EBXH mismatch!",13,10 .ecxh: ascic "ECXH mismatch!",13,10 .edxh: ascic "EDXH mismatch!",13,10 .fs: ascic "FS mismatch!",13,10 .gs: ascic "GS mismatch!",13,10 .failedretrying:ascic "DOS call returned failure, retrying.",13,10 name: asciz "TEST$$" align 2, nop buffer: .size equ 64 times .size db 0 align 4, nop list: dd 0 deviceheader: .link: dd -1 .attr: dw 8000h .strat: dw deviceentry .int: dw retf_instruction .name: fill 8, 32, db "TEST$$" deviceentry: push ax push bx push cx push dx push ds push si push es push di xor ax, ax mov al, [es:bx + 2] add ax, ax mov si, ax mov dx, deviceerror cmp si, devicetable.end - devicetable jae .dispatch mov dx, [cs:devicetable + si] .dispatch: call dx pop di pop es pop si pop ds pop dx pop cx pop bx pop ax retf_instruction: retf align 2 devicetable: dw deviceinit dw devicemediacheck dw devicegetbpb dw devicereadioctl dw deviceread dw devicereadnd dw deviceinputstatus dw deviceinputflush dw devicewrite dw devicewritev dw deviceoutputstatus dw deviceoutputflush dw devicewriteioctl dw deviceopen dw deviceclose dw deviceremovable .end: data: .: db "Hello world!",13,10 db "123" .end: .size equ .end - . deviceinit: devicemediacheck: devicegetbpb: devicereadioctl: deviceinputstatus: deviceinputflush: devicewrite: devicewritev: deviceoutputstatus: deviceoutputflush: devicewriteioctl: deviceopen: deviceclose: deviceremovable: deviceerror: mov word [es:bx + 3], 8103h retn deviceread: push cs pop ds rol byte [flag], 1 jc .read not byte [flag] jmp deviceerror .read: push es mov cx, [es:bx + 12h] les di, [es:bx + 0Eh] mov si, word [pointer] mov ax, data.end sub ax, si cmp cx, ax jb @F mov cx, ax @@: mov ax, cx rep movsb mov word [pointer], si pop es mov word [es:bx + 12h], ax deviceok: mov word [es:bx + 3], 0100h retn align 2, nop pointer: dw data flag: db 0 devicereadnd: mov si, word [cs:pointer] cmp si, data.end jae .busy cs lodsb mov byte [es:bx + 0Dh], al jmp deviceok .busy: mov word [es:bx + 3], 0300h retn