; ============================================================================
;
; LT-DOS - Int 21h services
;
; ============================================================================
; ------------- DOS error codes
DOSERR_OK EQU 00h ; (0) no error
DOSERR_INVFUNC EQU 01h ; (1) invalid function number
DOSERR_FILEFND EQU 02h ; (2) file not found
DOSERR_PATHFND EQU 03h ; (3) path not found
DOSERR_TOOFILES EQU 04h ; (4) too many open files (no handles avail.)
DOSERR_ACCESS EQU 05h ; (5) access denied
DOSERR_INVHAND EQU 06h ; (6) invalid handle
DOSERR_MCBERR EQU 07h ; (7) memory control block destroyed
DOSERR_MEMORY EQU 08h ; (8) insufficient memory
DOSERR_ADDRESS EQU 09h ; (9) invalid memory control block address
DOSERR_ENV EQU 0Ah ; (10) invalid environment
DOSERR_FORMAT EQU 0Bh ; (11) format invalid
DOSERR_INVCODE EQU 0Ch ; (12) invalid access code
DOSERR_INVDATA EQU 0Dh ; (13) invalid data
DOSERR_INVDISK EQU 0Fh ; (15) invalid drive
DOSERR_REMDIR EQU 10h ; (16) attempt to remove current directory
DOSERR_SAMEDEV EQU 11h ; (17) not same device
DOSERR_NOFILE EQU 12h ; (18) no more files
; --- Int 24h errors
;DOSERR_PROT EQU 13h ; (19) disk write-protected
;DOSERR_UNIT EQU 14h ; (20) unknown unit
;DOSERR_READY EQU 15h ; (21) device not ready
;DOSERR_COMMAND EQU 16h ; (22) unknown command
;DOSERR_CRC EQU 17h ; (23) CRC failure
;DOSERR_LENGTH EQU 18h ; (24) bad drive request structure length
;DOSERR_SEEK EQU 19h ; (25) seek failure
;DOSERR_MEDIA EQU 1Ah ; (26) unknown media type
;DOSERR_SECTOR EQU 1Bh ; (27) sector not found
;DOSERR_PAPER EQU 1Ch ; (28) printer out of paper
;DOSERR_WRITE EQU 1Dh ; (29) write fault
;DOSERR_READ EQU 1Eh ; (30) read fault
;DOSERR_GENERAL EQU 1Fh ; (31) general failure
; ------------- Standard device identifiers
STDIN EQU 0 ; Standard console input
STDOUT EQU 1 ; Standard console output
STDERR EQU 2 ; Standard error output
; ------------- Table of Int 21h functions
Int21Fnc: dw Int2100 ; 00h terminate program
dw Int2101 ; 01h get char. from STDIN with echo
dw Int2102 ; 02h put character to STDOUT
dw Int2103 ; 03h get character from STDAUX
dw Int2104 ; 04h output character to STDAUX
dw Int2105 ; 05h output character to STDPRN
dw Int2106 ; 06h direct STDIO - kbd to screen
dw Int2107 ; 07h char from STDIO, no echo
dw Int2108 ; 08h char from STDIO, no echo, ^C
dw Int2109 ; 09h display a string to STDOUT
dw Int210A ; 0Ah buffered keyboard input
dw Int210B ; 0Bh check STDIN status
dw Int210C ; 0Ch clear+invoke keyboard function
dw Int210D ; 0Dh flush all disk buffers
dw Int210E ; 0Eh select disk
dw Int210F ; 0Fh open file with FCB
dw Int2110 ; 10h close file opened with FCB
dw Int2111 ; 11h search for first file entry
dw Int2112 ; 12h search for next file entry
dw Int2113 ; 13h delete file specified by FCB
dw Int2114 ; 14h sequential read from file FCB
dw Int2115 ; 15h sequential write to file FCB
dw Int2116 ; 16h find or create firectory entry
dw Int2117 ; 17h rename file FCB
dw Int2118 ; 18h unknown
dw Int2119 ; 19h return current disk drive
dw Int211A ; 1Ah set disk transfer area (DTA)
dw Int211B ; 1Bh get current disk drive FAT
dw Int211C ; 1Ch get disk FAT for any drive
dw Int211D ; 1Dh unknown
dw Int211E ; 1Eh unknown
dw Int211F ; 1Fh read DOS disk block
dw Int2120 ; 20h unknown
dw Int2121 ; 21h random read from file FCB
dw Int2122 ; 22h random write to file FCB
dw Int2123 ; 23h return number of records in FCB
dw Int2124 ; 24h set file record size FCB
dw Int2125 ; 25h set interrupt vector
dw Int2126 ; 26h create new PSP
dw Int2127 ; 27h random file block read from FCB
dw Int2128 ; 28h random file block write to FCB
dw Int2129 ; 29h parse the command line
dw Int212A ; 2Ah get the system date
dw Int212B ; 2Bh set the system date
dw Int212C ; 2Ch get the system time
dw Int212D ; 2Dh set the system time
dw Int212E ; 2Eh set/clear disk write VERIFY
dw Int212F ; 2Fh get disk transfer area (DTA)
dw Int2130 ; 30h get DOS version number
dw Int2131 ; 31h terminate and stay resident
dw Int2132 ; 32h read DOS Disk Block
dw Int2133 ; 33h get or set Ctrl-Break
dw Int2134 ; 34h INDOS Critical Section Flag
dw Int2135 ; 35h get interrupt vector
dw Int2136 ; 36h get free disk space
dw Int2137 ; 37h get/set SWITCHAR
dw Int2138 ; 38h return country-dep. information
dw Int2139 ; 39h create subdirectory
dw Int213A ; 3Ah remove subdirectory
dw Int213B ; 3Bh change current directory
dw Int213C ; 3Ch create file with file handle
dw Int213D ; 3Dh open file with file handle
dw Int213E ; 3Eh close file with file handle
dw Int213F ; 3Fh read from file with file handle
dw Int2140 ; 40h write to file with file handle
dw Int2141 ; 41h delete file
dw Int2142 ; 42h move file pointer
dw Int2143 ; 43h set/get file attributes
dw Int2144 ; 44h device IOCTL (I/O control) info
dw Int2145 ; 45h duplicate file handle
dw Int2146 ; 46h force a duplicate file handle
dw Int2147 ; 47h get current directory
dw Int2148 ; 48h allocate memory
dw Int2149 ; 49h release allocated memory
dw Int214A ; 4Ah resize allocated memory
dw Int214B ; 4Bh load or execute a program
dw Int214C ; 4Ch terminate prog and return to DOS
dw Int214D ; 4Dh get return code of subprocess
dw Int214E ; 4Eh find first matching file
dw Int214F ; 4Fh find next matching file
dw Int2150 ; 50h set new current PSP
dw Int2151 ; 51h puts current PSP into BX
dw Int2152 ; 52h pointer to the DOS list of lists
dw Int2153 ; 53h translates Bios Parameter Block
dw Int2154 ; 54h get disk verification status
dw Int2155 ; 55h create PSP
dw Int2156 ; 56h rename a file
dw Int2157 ; 57h get/set file date and time
dw Int2158 ; 58h get/set allocation strategy
dw Int2159 ; 59h get extended error information
dw Int215A ; 5Ah create a unique filename
dw Int215B ; 5Bh create a DOS file
dw Int215C ; 5Ch lock/unlock file contents
dw Int215D ; 5Dh DOS internal functions
dw Int215E ; 5Eh network printer
dw Int215F ; 5Fh network redirection
dw Int2160 ; 60h parse pathname
dw Int2161 ; 61h unknown
dw Int2162 ; 62h get program segment prefix (PSP)
dw Int2163 ; 63h get lead byte table
dw Int2164 ; 64h unknown
dw Int2165 ; 65h get extended country information
dw Int2166 ; 66h get/set global code page table
dw Int2167 ; 67h set handle count
dw Int2168 ; 68h commit file
dw Int2169 ; 69h disk serial number
dw Int216A ; 6Ah unknown
dw Int216B ; 6Bh unknown
dw Int216C ; 6Ch extended open/create
Int21Num EQU ($-Int21Fnc)/2 ; number of Int 21h functions
; ----------------------------------------------------------------------------
; Unsupported Int 21h functions
; ----------------------------------------------------------------------------
Int2100:
Int210D:
Int210E:
Int210F:
Int2110:
Int2111:
Int2112:
Int2113:
Int2114:
Int2115:
Int2116:
Int2117:
Int2118:
Int2119:
Int211A:
Int211D:
Int211E:
Int211F:
Int2120:
Int2121:
Int2122:
Int2123:
Int2124:
Int2125:
Int2126:
Int2127:
Int2128:
Int2129:
Int212E:
Int212F:
Int2131:
Int2132:
Int2133:
Int2134:
Int2135:
Int2136:
Int2137:
Int2138:
Int2139:
Int213A:
Int213B:
Int213C:
Int213D:
Int213E:
Int213F:
Int2140:
Int2141:
Int2142:
Int2143:
Int2144:
Int2145:
Int2146:
Int2147:
Int214B:
Int214C:
Int214D:
Int214E:
Int214F:
Int2152:
Int2153:
Int2154:
Int2155:
Int2156:
Int2157:
Int2159:
Int215A:
Int215B:
Int215C:
Int215D:
Int215E:
Int215F:
Int2160:
Int2161:
Int2162:
Int2163:
Int2164:
Int2165:
Int2166:
Int2167:
Int2168:
Int2169:
Int216A:
Int216B:
Int216C:
mov al,0 ; AL <- 0 (unsupported function)
ret
; ----------------------------------------------------------------------------
; Int 20h service (terminate program)
; ----------------------------------------------------------------------------
MyInt20: mov ah,0 ; AH <- 0 function code
jmp short MyInt211
; ----------------------------------------------------------------------------
; Int 21h service
; ----------------------------------------------------------------------------
; ------------- Register offsets of Int 21h service (in stack)
REG21F EQU 22 ; Int 21h flags register in stack
REG21CS EQU 20 ; Int 21h CS register in stack
REG21IP EQU 18 ; Int 21h IP register in stack
REG21ES EQU 16 ; Int 21h ES register in stack
REG21DS EQU 14 ; Int 21h DS register in stack
REG21BP EQU 12 ; Int 21h BP register in stack
REG21DI EQU 10 ; Int 21h DI register in stack
REG21SI EQU 8 ; Int 21h SI register in stack
REG21DX EQU 6 ; Int 21h DX register in stack
REG21CX EQU 4 ; Int 21h CX register in stack
REG21BX EQU 2 ; Int 21h BX register in stack
REG21AX EQU 0 ; Int 21h AX register in stack
; ------------- Check function number
MyInt21: cmp ah,Int21Num ; check function number
jb MyInt211 ; function number is OK
MyInt210: mov al,0 ; error code - unsupported function
iret
; ----------------------------------------------------------------------------
; Old style (CALL 5) DOS service
; ----------------------------------------------------------------------------
; - user call this with "call near 5" instruction (only in COM program)
; - PSP:5 addres contains "call far 0000:00c0h" instruction
; - address 0000:00c0h (=address of int 30h) contains "jump far"instruction
; ----------------------------------------------------------------------------
; ------------- Store return address
OldDOS: pop ax ; destroy offset of return address
pop ax ; AX <- segment of PSP
pop word [cs:OldStack]; store offset of return address
; ------------- Simulate Int 21h call
pushf ; push flags to simulate Int 21h
push ax ; push segment of PSP
push word [cs:OldStack]; restore offset of return address
cli ; disable interrupts
; ------------- Check function number
cmp cl,24h ; check maximal number of function
ja MyInt210 ; invalid function number
mov ah,cl ; AH <- function code
; ------------- Push registers (at this point interrupt is disabled)
MyInt211: call PushAll ; push all registers
; ------------- Push DS:BX registers
mov [cs:PushDSBX+2],ds ; push DS
push cs ; push CS
pop ds ; DS <- CS
mov [PushDSBX],bx ; push BX
; ------------- Set DOS active flag
inc byte [DOSActive] ; set DOS active flag
; ------------- Push previous stack pointer
mov bx,[OldStack] ; BX <- previous SP
mov [OldStack2],bx ; push previous SP
mov bx,[OldStack+2] ; BX <- previous SS
mov [OldStack2+2],bx ; push previous SS
; ------------- Push stack pointer
mov [OldStack],sp ; push SP
mov [OldStack+2],ss ; push SS
; ------------- Store stack pointer into PSP
push ds ; push DS
mov ds,[CurrentPSP] ; DS <- segment of current PSP
mov [2Eh],sp ; store SP
mov [30h],ss ; store SS
pop ds ; pop DS
; ------------- Enable Int 28h idle service
mov byte [Int28Enabled],1 ; enable Int 28h service
; ------------- Functions without internal stack
cmp ah,50h ; set new PSP address
je MyInt216 ; no internal stack
cmp ah,51h ; get current PSP address
je MyInt216 ; no internal stack
; ------------- Init Int 21h stack (within Int 24h)
mov sp,cs ; SP <- CS
mov ss,sp ; SS <- CS
mov sp,Int21Stack3 ; stack for Int 24h
; ------------- Console functions use own internal stack
or ah,ah ; function 00h (program end)
jz MyInt212 ; internal stack 1
cmp ah,0Ch ; character functions ?
jbe MyInt213 ; internal stack 2
; ------------- Init internal stack - other functions
MyInt212: mov sp,Int21Stack1 ; SS:SP <- INT 21h internal stack 1
mov byte [Int24Active],0 ; Int 24h is not active
mov byte [LastDiskError],0ffh ; no last disk with error
; ------------- Test BREAK
cmp byte [Break],0 ; test BREAK?
je MyInt216 ; don't test BREAK
push ax ; push AX
call BreakTest ; test BREAK
pop ax ; pop AX
jmp short MyInt216
; ------------- Init internal stack - console functions
MyInt213: cmp byte [Int24Active],0 ; is Int 24h active?
jne MyInt216 ; Int 24h is active
mov sp,Int21Stack2 ; SS:SP <- INT 21h internal stack 2
MyInt216: sti ; enable interrupts
; ------------- Prepare return address from service (simulates CALL NEAR)
mov bx,MyInt21Ret ; BX <- return address
push bx ; prepare return address
; ------------- Prepare jump address of service
mov bh,0 ; BH <- 0
mov bl,ah ; BL <- function code
shl bx,1 ; BX = function code * 2
push word [Int21Fnc+bx] ; push address of service
; ------------- Pop DS:BX registers and jump to the service
lds bx,[PushDSBX] ; pop DS:BX registers
cld ; direction up
ret ; junp to the service
; ------------- Return from service (here is AL = return code)
MyInt21Ret: cli ; disable interrupts
push cs ; push CS
pop ds ; DS <- CS
; ------------- Reset DOS active flag
dec byte [DOSActive] ; reset DOS active flag
; ------------- Return old stack pointer
mov sp,[OldStack] ; SP <- old SP
mov ss,[OldStack+2] ; SS <- old SS
; ------------- Set AL register (return code)
mov bp,sp ; BP <- stack pointer
mov [bp+REG21AX],al ; store AL return code
; ------------- Return previous stack pointer
mov ax,[OldStack2] ; AX <- previous SP
mov [OldStack],ax ; return previous SP
mov ax,[OldStack2+2] ; AX <- previous SS
mov [OldStack+2],ax ; return previous SS
; ------------- Pop registers
call PopAll ; pop all registers
iret
; ----------------------------------------------------------------------------
; Get register pointer
; ----------------------------------------------------------------------------
; OUTPUT: DS:SI = registers in call stack (offset RE21AX...REG21F)
; ----------------------------------------------------------------------------
GetReg: lds si,[cs:OldStack] ; DS:DI <- old stack
ret
; ----------------------------------------------------------------------------
; Set output register AX
; ----------------------------------------------------------------------------
; INPUT: AX = output register AX
; ----------------------------------------------------------------------------
SetRegAX: push ds ; push DS
push si ; push SI
call GetReg ; get register pointer
mov [si+REG21AX],ax ; store output register AX
pop si ; pop SI
pop ds ; pop DS
ret
; ----------------------------------------------------------------------------
; Set output register BX
; ----------------------------------------------------------------------------
; INPUT: BX = output register BX
; ----------------------------------------------------------------------------
SetRegBX: push ds ; push DS
push si ; push SI
call GetReg ; get register pointer
mov [si+REG21BX],bx ; store output register BX
pop si ; pop SI
pop ds ; pop DS
ret
; ----------------------------------------------------------------------------
; Set output register CX
; ----------------------------------------------------------------------------
; INPUT: CX = output register CX
; ----------------------------------------------------------------------------
SetRegCX: push ds ; push DS
push si ; push SI
call GetReg ; get register pointer
mov [si+REG21CX],cx ; store output register CX
pop si ; pop SI
pop ds ; pop DS
ret
; ----------------------------------------------------------------------------
; Set output register DX
; ----------------------------------------------------------------------------
; INPUT: DX = output register DX
; ----------------------------------------------------------------------------
SetRegDX: push ds ; push DS
push si ; push SI
call GetReg ; get register pointer
mov [si+REG21DX],dx ; store output register DX
pop si ; pop SI
pop ds ; pop DS
ret
; ----------------------------------------------------------------------------
; Set DOS result error flag (and AH <- 0)
; ----------------------------------------------------------------------------
DOSError: mov ah,0 ; AH <- 0
push ds ; push DS
push si ; push SI
call GetReg ; get register pointer
or byte [si+REG21F],1 ; set error flag
pop si ; pop SI
pop ds ; pop DS
ret
; ----------------------------------------------------------------------------
; Reset DOS result error flag
; ----------------------------------------------------------------------------
DOSOK: push ds ; push DS
push si ; push SI
call GetReg ; get register pointer
and byte [si+REG21F],~1 ; reset error flag
pop si ; pop SI
pop ds ; pop DS
ret
; ----------------------------------------------------------------------------
; Int 21h, function 30h - get version number
; ----------------------------------------------------------------------------
; INT21 INPUT: AH = 30h (function code)
; INT21 OUTPUT: AL = major version number
; AH = minor version number
; BH = OEM number (LT-DOS: 0F3h)
; BL:CX = 24-bit user serial number
; ----------------------------------------------------------------------------
Int2130: push cs ; push CS
pop ds ; DS <- CS
mov ax,[DOSVer] ; AL <- major, AH <- minor version
mov bx,[DOSSerialH] ; BL <- serial HIGH, BH <- OEM number
mov cx,[DOSSerial] ; CX <- serial LOW
call SetRegAX ; set output register AX
call SetRegBX ; set output register BX
call SetRegCX ; set output register CX
ret
; ----------------------------------------------------------------------------
; Int 21h, function 54h - get verify flag
; ----------------------------------------------------------------------------
; INT21 INPUT: AH = 54h (function code)
; INT21 OUTPUT: AL = verify flag
; 0 = verify flag is off
; 1 = verify flag is on, all disk writes verified
; ----------------------------------------------------------------------------
; ----------------------------------------------------------------------------
; Execute Int 24h disk error routine
; ----------------------------------------------------------------------------
; !!!!!!!!!!!!!!!!!!!
DoDiskInt24:
; ----------------------------------------------------------------------------
; Execute Int 24h error routine
; ----------------------------------------------------------------------------
; INPUT: AL = drive number
; AH = type and processing flags (see below)
; DI = error code
; ES:BP = address of DDPB
; OUTPUT: AL = action code (0=ignore, 1=retry, 2=terminate, 3=fail)
; DESTROYS: AH, SI, DI
; ----------------------------------------------------------------------------
; Int 24h handler:
; INPUT:
; AL = drive number if bit 7 of AH is clear
; AH = type and processing flags
; bit 7: 0=disk I-O error
; 1=bad FAT image in memory (block device)
; or error code in DI (char device)
; bit 5: 1=ignore allowed
; bit 4: 1=retry allowed
; bit 3: 1=fail allowed
; bit 1,2: disk area of error
; 0=DOS area, 1=FAT, 2=root, 3=data
; bit 0: 1=write, 0=read
; BP:SI = Device Driver Header
; DI = error code if AH bit 7 is set, see Device driver error codes
; STACK: [SP+0]: (2) offset of return address for Int 24h
; [SP+2]: (2) segment of return address for Int 24h
; [SP+4]: (2) flags pushed with Int 24h
; [SP+6]: (2) AX
; [SP+8]: (2) BX
; [SP+10]: (2) CX
; [SP+12]: (2) DX
; [SP+14]: (2) SI
; [SP+16]: (2) DI
; [SP+18]: (2) BP
; [SP+20]: (2) DS
; [SP+22]: (2) ES
; [SP+24]: (2) offset of return address for Int 21h
; [SP+26]: (2) segment return address for Int 21h
; [SP+28]: (2) flags pushed with Int 21h
; OUTPUT:
; AL = action code (0=ignore, 1=retry, 2=terminate, 3=fail)
; ----------------------------------------------------------------------------
; ------------- Push registers ES, BP
DoInt24: mov [cs:Int24ESBP],bp ; push register BP
mov [cs:Int24ESBP+2],es; push register ES
; ------------- Pointer to DDH (-> BP:SI)
mov si,[es:bp+DDPB_DDH] ; SI <- offset of DDH
mov bp,[es:bp+DDPB_DDH+2] ; BP <- segment of DDH
; ------------- Test, if Int 24h is already active
cmp byte [cs:Int24Active],0 ; is Int 24h already active?
jne DoInt244 ; Int 24h is already active
; ------------- Call Int 24h routine
cli ; disable interrupts
push cs ; push CS
pop es ; ES <- CS
dec byte [cs:DOSActive] ; decrease DOS active flag
inc byte [cs:Int24Active] ; increase Int 24h active flag
mov [cs:Int24SP],sp ; push SP register
mov ss,[cs:OldStack+2]; return SS
mov sp,[cs:OldStack] ; return SP
int 24h ; call Int 24h routine
mov [cs:OldStack],sp ; store new SP
mov [cs:OldStack+2],ss ; store new SS
mov sp,cs ; SP <- CS
mov ss,sp ; SS <- CS
mov sp,[cs:Int24SP] ; pop SP register
mov byte [cs:Int24Active],0 ; Int 24h is not active
inc byte [cs:DOSActive] ; increase DOS active flag
sti ; enable interrupts
; ------------- Pop registers ES, BP
DoInt242: les bp,[cs:Int24ESBP] ; ES:BP <- pop ES:BP
; ------------- Terminate program
cmp al,2 ; terminate program?
je DoInt246 ; terminate program
mov byte [cs:LastDiskError],0ffh ; no last disk with error
ret
; ------------- Default Int 24h handler, if Int 24h is already active
DoInt244: mov al,0 ; AL <- 0 code to ignore
jmp short DoInt242
; ------------- Terminate program
DoInt246: push cs ; push CS
pop ds ; DS <- CS
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Int 24h = 2DC8
iret
; ----------------------------------------------------------------------------
; Push all registers
; ----------------------------------------------------------------------------
PushAll: pop word [cs:PushAllRet] ; store return address
push es ; 16: push ES
push ds ; 14: push DS
push bp ; 12: push BP
push di ; 10: push DI
push si ; 8: push SI
push dx ; 6: push DX
push cx ; 4: push CX
push bx ; 2: push BX
push ax ; 0: push AX
PushAll2: jmp [cs:PushAllRet] ; return
; ----------------------------------------------------------------------------
; Pop all registers
; ----------------------------------------------------------------------------
PopAll: pop word [cs:PushAllRet] ; store return address
pop ax ; pop AX
pop bx ; pop BX
pop cx ; pop CX
pop dx ; pop DX
pop si ; pop SI
pop di ; pop DI
pop bp ; pop BP
pop ds ; pop DS
pop es ; pop ES
jmp short PushAll2 ; return
; ----------------------------------------------------------------------------
; Data
; ----------------------------------------------------------------------------
; ------------- Internal stacks
times 80h db 0 ; internal stack for INT 21h/25h/26h
Int21Stack1:
times 80h db 0 ; internal stack for console functions
Int21Stack2:
times 80h db 0 ; internal stack for INT 21h/INT 24h
Int21Stack3:
; ------------- DOS version number
DOSVer: db 2,20 ; major and minor DOS version number
DOSSerial: dw 0 ; user serial number LOW
DOSSerialH: db 0 ; user serial number HIGH
DOSOEM: db 0F3h ; DOS OEM number
; ------------- INT 21h variables
PushAllRet: dw 0 ; push return address
PushDSBX: dd 0 ; push DS:BX in 21h call
OldStack: dd 0 ; push old stack pointer
OldStack2: dd 0 ; previous old stack pointer
DOSActive: db 0 ; DOS active flag
; ------------- SYSVAR array - List of lists
FirstAlloc: dw 0 ; -2: segment of first MCB
SYSVAR:
FirstDDPB: dd 0 ; 0: address of first DDPB
FirstSFT: dd 0 ; 4: pointer to first System File Table
ClockDev: dd 0 ; 8: pointer to active CLOCK$ device
ConDev: dd 0 ; 0Ch: pointer to active CON device
DiskCount: db 0 ; 10h: number of block devices
MaxSectorSize: dw 512 ; 11h: maximum bytes/sector
FirstDiskBuff: dd 0 ; 13h: pointer to first disk bubffer
; 17h: actual NUL device header
DPBNUL: dw DPBCON,BOOTSEG ; pointer to next device
dw B15+B2 ; attributes (NUL, char)
dw SetStrat ; device strategy
dw NULInt ; device interrupt
db 'NUL ' ; device name
; ------------- DOS Device Driver Request
DOSDDR:
DOSDDR_len: db 0 ; 0: length of this header (in bytes)
DOSDDR_unit: db 0 ; 1: subunit number (block device only)
DOSDDR_cmd: db 0 ; 2: command code
DOSDDR_errorstatus: ; (3: error code + status)
DOSDDR_error: db 0 ; 3: error code (if S_ERROR is set)
DOSDDR_status: db 0 ; 4: device request status
DOSDDR_res: dd 0 ; 5: ... reserved
DOSDDR_next: dd 0 ; 9: pointer to next DDR
DOSDDR_media: db 0 ; 13: media descriptor
DOSDDR_trans: dd 0 ; 14: transfer address
DOSDDR_count: dw 0 ; 18: byte count or sector count
DOSDDR_start: dw 0 ; 20: starting sector number (-1=32bit)
DOSDDR_volID: dd 0 ; 22: pointer to volume ID
DOSDDR_start2: dd 0 ; 26: 32-bit starting sector number
; ------------- data for Int 24h routine
Int24Active: db 0 ; <> 0 Int 24h routine is active
Int24ESBP: dd 0 ; push ES:BP registers for Int 24h
Int24SP: dw 0 ; push SP register for Int 24h
|