; Public Domain %include "lmacros3.mac" cpu 386 org 256 start: mov eax, dword [0Ah] ; PRA mov dword [origpra], eax mov ax, word [16h] ; parent mov word [origparent], ax mov word [16h], ds push ds push word i22 pop dword [0Ah] 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 xchg bx, ax mov dx, buffer mov cx, 1 mov ah, 3Fh not byte [isabortflag] int 21h jnc .success .fail: not byte [isabortflag] push cs pop es mov di, msg.fail.code call hexword mov ah, 09h mov dx, msg.fail int 21h mov ax, 4C00h int 21h .success: not byte [isabortflag] mov ah, 09h mov dx, msg.success int 21h mov ax, 4C00h int 21h 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 i22: push cs pop ds mov eax, dword [origpra] mov dword [0Ah], eax mov ax, word [origparent] mov word [16h], ax rol byte [isabortflag], 1 jnc .notabort push cs pop es mov di, msg.abort.code mov ah, 4Dh int 21h call hexword mov dx, msg.abort mov ah, 09h int 21h .notabort: les bx, [list] push dword [deviceheader.link] pop dword [es:bx + 22h] mov ax, 4C26h int 21h i24: mov al, 02h ; abort iret i23: stc retf hexword: xchg al, ah call hexbyte xchg al, ah hexbyte: rol al, 4 call hexnybble rol al, 4 hexnybble: push ax and al, 15 add al, '0' cmp al, '9' jbe .got add al, -'9'-1+'A' .got: stosb pop ax retn isabortflag: db 0 msg: .error: ascic "Error!",13,10 .abort: db "Process aborted from i24, term code=" .abort.code: ascic "----h.",13,10 .fail: db "DOS call returned failure, error code=" .fail.code: ascic "----h.",13,10 .success: ascic "DOS call returned success. How?!",13,10 name: asciz "TEST$$" align 2, nop buffer: .size equ 64 times .size db 0 align 4, nop list: dd 0 origpra: dd 0 origparent: dw 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