1 TITLE GETSET
- GETting
and SETting
MS-DOS system calls
4 ; System Calls which get and set various things
11 ; $GET_DRIVE_FREESPACE
16 ; $GET_INTERRUPT_VECTOR
17 ; $SET_INTERRUPT_VECTOR
23 ; get the appropriate segment definitions
35 CODE SEGMENT BYTE PUBLIC 'CODE'
36 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
49 i_need Current_Country
,WORD
50 i_need international_table
,BYTE
52 i_need SYSINITVAR
,WORD
54 i_need SWITCH_CHARACTER
,BYTE
55 i_need DEVICE_AVAILABILITY
,BYTE
57 USERNUM
DW ?
; 24 bit user number
60 OEMNUM
DB 0 ; 8 bit OEM number
62 OEMNUM
DB 0FFH ; 8 bit OEM number
65 MSVERS EQU THIS
WORD ; MS-DOS version in hex for $GET_VERSION
66 MSMAJOR
DB DOS_MAJOR_VERSION
67 MSMINOR
DB DOS_MINOR_VERSION
70 BREAK <$Get_Version
-- Return MSDOS version number
>
71 procedure $GET_VERSION
,NEAR
72 ASSUME
DS:NOTHING
,ES:NOTHING
77 ; Return MS-DOS version number
80 ; User number in BL:CX (24 bits)
81 ; Version number as AL.AH in binary
82 ; NOTE: On pre 1.28 DOSs AL will be zero
94 MOV [SI.user_AX
],AX ; Really only sets AH
98 BREAK <$International
- return country
-dependent information
>
101 ; DS:DX point to a block
103 ; give users an idea of what country the application is running
105 ; AX = number of bytes transferred
106 ; DS:DX ->+---------------------------------+
107 ; | WORD Date/time format |
108 ; +---------------------------------+
109 ; | BYTE ASCIZ currency symbol |
110 ; +---------------------------------+
111 ; | BYTE ASCIZ thousands separator |
112 ; +---------------------------------+
113 ; | BYTE ASCIZ decimal separator |
114 ; +---------------------------------+
116 procedure $INTERNATIONAL
,NEAR
117 ASSUME
DS:NOTHING
,ES:NOTHING
129 JNZ international_find
130 MOV SI,[Current_Country
]
131 MOV AX,WORD PTR [SI-2] ; Get size in AL, country code in AH
132 MOV BL,AH ; Set country code
133 JMP SHORT international_copy
136 CALL international_get
137 JNC international_copy
138 error country_not_found
141 MOV SI,OFFSET DOSGROUP
:international_table
143 LODSW ; Get size in AL, country code in AH
152 JZ RET35
; Carry clear
155 JMP international_next
163 MOV WORD PTR ES:[DI.MAP_CALL
+ 2],CS ; Set segment for case map call
166 MOV AL,BL ; Return country code in AX
170 CALL international_get
171 JNC international_store
172 error country_not_found
175 MOV [Current_Country
],SI
180 BREAK <$Get_Verify_on_Write
- return verify
-after
-write flag
>
181 procedure $GET_VERIFY_ON_WRITE
,NEAR
182 ASSUME
DS:NOTHING
,ES:NOTHING
189 ; AL = value of VERIFY flag
193 $GET_VERIFY_ON_WRITE ENDP
195 BREAK <$Set_Verify_on_Write
- Toggle verify
-after
-write flag
>
196 procedure $SET_VERIFY_ON_WRITE
,NEAR
197 ASSUME
DS:NOTHING
,ES:NOTHING
200 ; AL = desired value of VERIFY flag
209 $SET_VERIFY_ON_WRITE ENDP
211 BREAK <$Set_CTRL_C_Trapping
-- En
/Disable ^C check
in dispatcher
>
212 procedure $SET_CTRL_C_TRAPPING
,NEAR
213 ASSUME
DS:NOTHING
,ES:NOTHING
216 ; AL = 0 read ^C status
217 ; AL = 1 Set ^C status, DL = 0/1 for ^C off/on
219 ; Enable disable ^C checking in dispatcher
221 ; If AL = 0 then DL = 0/1 for ^C off/on
225 invoke get_user_stack
227 MOV BYTE PTR [SI.user_DX
],AL
238 $SET_CTRL_C_TRAPPING ENDP
240 BREAK <$Get_INDOS_Flag
-- Return location of DOS critical
-section flag
>
241 procedure $GET_INDOS_FLAG
,NEAR
242 ASSUME
DS:NOTHING
,ES:NOTHING
247 ; Returns location of DOS status for interrupt routines
249 ; Flag location in ES:BX
251 invoke get_user_stack
252 MOV [SI.user_BX
],OFFSET DOSGROUP
:INDOS
257 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
258 ; C A V E A T P R O G R A M M E R ;
260 procedure $GET_IN_VARS
,NEAR
261 ; Return a pointer to interesting DOS variables This call is version
262 ; dependent and is subject to change without notice in future versions.
264 invoke get_user_stack
265 MOV [SI.user_BX
],OFFSET DOSGROUP
:SYSINITVAR
270 ; C A V E A T P R O G R A M M E R ;
271 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
273 BREAK <$Get_Drive_Freespace
-- Return bytes of free disk space
on a drive
>
274 procedure $GET_DRIVE_FREESPACE
,NEAR
275 ASSUME
DS:NOTHING
,ES:NOTHING
280 ; Return number of free allocation units on drive
282 ; BX = Number of free allocation units
283 ; DX = Total Number of allocation units on disk
285 ; AX = Sectors per allocation unit
286 ; = -1 if bad drive specified
287 ; This call returns the same info in the same registers (except for FAT pointer)
288 ; as the old FAT pointer calls
300 MOV CX,ES:[BP.dpb_max_cluster
]
310 POP BX ; Remember Total
311 MOV AL,ES:[BP.dpb_cluster_mask
]
314 MOV CX,ES:[BP.dpb_sector_size
]
316 invoke get_user_stack
324 $GET_DRIVE_FREESPACE ENDP
326 BREAK <$Get_DMA
, $Set_DMA
-- Get
/Set current DMA address
>
327 procedure $GET_DMA
,NEAR
328 ASSUME
DS:NOTHING
,ES:NOTHING
333 ; Get DISK TRANSFER ADDRESS
335 ; ES:BX is current transfer address
337 MOV BX,WORD PTR [DMAADD
]
338 MOV CX,WORD PTR [DMAADD
+2]
339 invoke get_user_stack
345 procedure $SET_DMA
,NEAR ; System call 26
346 ASSUME
DS:NOTHING
,ES:NOTHING
349 ; DS:DX is desired new disk transfer address
351 ; Set DISK TRANSFER ADDRESS
355 MOV WORD PTR [DMAADD
],DX
356 MOV WORD PTR [DMAADD
+2],DS
360 BREAK <$Get_Default_DPB
,$Get_DPB
-- Return pointer to DPB
>
361 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
362 ; C A V E A T P R O G R A M M E R ;
364 procedure $GET_DEFAULT_DPB
,NEAR
365 ASSUME
DS:NOTHING
,ES:NOTHING
368 ; DL = Drive number (always default drive for call 31)
370 ; Return pointer to drive parameter table for default drive
372 ; DS:BX points to the DPB
373 ; AL = 0 If OK, = -1 if bad drive (call 50 only)
384 invoke get_user_stack
394 $GET_Default_dpb ENDP
396 ; C A V E A T P R O G R A M M E R ;
397 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
400 BREAK <$Get_Default_Drive
, $Set_Default_Drive
-- Set
/Get default drive
>
401 procedure $GET_DEFAULT_DRIVE
,NEAR
402 ASSUME
DS:NOTHING
,ES:NOTHING
407 ; Return current drive number
413 $GET_DEFAULT_DRIVE ENDP
415 procedure $SET_DEFAULT_DRIVE
,NEAR
416 ASSUME
DS:NOTHING
,ES:NOTHING
419 ; DL = Drive number for new default drive
421 ; Set the default drive
423 ; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD
430 $SET_DEFAULT_DRIVE ENDP
433 BREAK <$Get_Interrupt_Vector
- Get
/Set interrupt vectors
>
434 procedure $GET_INTERRUPT_VECTOR
,NEAR
435 ASSUME
DS:NOTHING
,ES:NOTHING
438 ; AL = interrupt number
440 ; Get the interrupt vector
442 ; ES:BX is current interrupt vector
445 LES BX,DWORD PTR ES:[BX]
446 invoke get_user_stack
450 $GET_INTERRUPT_VECTOR ENDP
452 procedure $SET_INTERRUPT_VECTOR
,NEAR ; System call 37
453 ASSUME
DS:NOTHING
,ES:NOTHING
456 ; AL = interrupt number
457 ; DS:DX is desired new interrupt vector
459 ; Set the interrupt vector
467 $SET_INTERRUPT_VECTOR ENDP
470 VECIN: ; INPUT VECTORS
475 LSTVEC
DB ?
; ALL OTHER
477 VECOUT: ; GET MAPPED VECTOR
482 LSTVEC2
DB ?
; Map to itself
484 NUMVEC
= VECOUT
-VECIN
487 procedure RECSET
,NEAR
492 MOV [LSTVEC
],AL ; Terminate list with real vector
493 MOV [LSTVEC2
],AL ; Terminate list with real vector
494 MOV CX,NUMVEC
; Number of possible translations
495 MOV DI,OFFSET DOSGROUP
:VECIN
; Point to vectors
497 MOV AL,ES:[DI+NUMVEC
-1] ; Get translation
508 BREAK <$Char_Oper
- hack
on paths
, switches so that xenix can look like PCDOS
>
510 ; input: AL = function:
511 ; 0 - read switch char
512 ; 1 - set switch char (char in DL)
513 ; 2 - read device availability
514 ; 3 - set device availability (0/FF in DL)
515 ; DL = 0 means /DEV/ must preceed device names
516 ; DL = Non0 means /DEV/ need not preeceed
517 ; output: (get) DL - character/flag
519 procedure $CHAR_OPER
,NEAR
520 ASSUME
DS:NOTHING
,ES:NOTHING
525 JNZ char_oper_set_switch
526 MOV DL,[switch_character
]
527 JMP SHORT char_oper_ret
528 char_oper_set_switch:
530 JNZ char_oper_read_avail
531 MOV [switch_character
],DL
533 char_oper_read_avail:
535 JNZ char_oper_set_avail
536 MOV DL,[device_availability
]
537 JMP SHORT char_oper_ret
540 JNZ char_oper_bad_ret
541 MOV [device_availability
],DL
547 invoke get_user_stack
552 BREAK <$SetDPB
- Create a valid DPB
from a user
-specified BPB
>
553 procedure $SETDPB
,NEAR
554 ASSUME
DS:NOTHING
,ES:NOTHING
557 ; ES:BP Points to DPB
558 ; DS:SI Points to BPB
560 ; Build a correct DPB from the BPB
562 ; ES:BP and DS preserved all others destroyed
565 ADD DI,2 ; Skip over dpb_drive and dpb_UNIT
567 STOSW ; dpb_sector_size
571 STOSB ; dpb_cluster_mask
582 STOSB ; dpb_cluster_shift
584 MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors)
586 STOSB ; dpb_FAT_count Number of FATs
589 STOSW ; dpb_root_entries Number of directory entries
591 SHR DX,CL ; Directory entries per sector
593 ADD AX,DX ; Cause Round Up
597 MOV CX,AX ; Number of directory sectors
599 INC DI ; Skip dpb_first_sector
600 MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster)
602 MOV ES:[BP.dpb_media
],AL ; Media byte
603 LODSW ; Number of sectors in a FAT
605 MUL BH ; Space occupied by all FATs
606 ADD AX,ES:[BP.dpb_first_FAT
]
607 STOSW ; dpb_dir_sector
608 ADD AX,CX ; Add number of directory sectors
609 MOV ES:[BP.dpb_first_sector
],AX
610 SUB AX,ES:[BP.DSKSIZ
]
611 NEG AX ; Sectors in data area
612 MOV CL,BL ; dpb_cluster_shift
613 SHR AX,CL ; Div by sectors/cluster
615 MOV ES:[BP.dpb_max_cluster
],AX
616 MOV ES:[BP.dpb_current_dir
],0 ; Current directory is root
620 ; C A V E A T P R O G R A M M E R ;
621 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;