]> wirehaze git hosting - MS-DOS.git/blob - v2.0/source/GETSET.ASM

wirehaze git hosting

Optimized PNG's
[MS-DOS.git] / v2.0 / source / GETSET.ASM
1 TITLE GETSET - GETting and SETting MS-DOS system calls
2 NAME GETSET
3 ;
4 ; System Calls which get and set various things
5 ;
6 ; $GET_VERSION
7 ; $GET_VERIFY_ON_WRITE
8 ; $SET_VERIFY_ON_WRITE
9 ; $SET_CTRL_C_TRAPPING
10 ; $INTERNATIONAL
11 ; $GET_DRIVE_FREESPACE
12 ; $GET_DMA
13 ; $SET_DMA
14 ; $GET_DEFAULT_DRIVE
15 ; $SET_DEFAULT_DRIVE
16 ; $GET_INTERRUPT_VECTOR
17 ; $SET_INTERRUPT_VECTOR
18 ; RECSET
19 ; $CHAR_OPER
20 ;
21 .xlist
22 ;
23 ; get the appropriate segment definitions
24 ;
25 INCLUDE DOSSEG.ASM
26
27 IFNDEF ALTVECT
28 ALTVECT EQU 0 ; FALSE
29 ENDIF
30
31 IFNDEF IBM
32 IBM EQU 0
33 ENDIF
34
35 CODE SEGMENT BYTE PUBLIC 'CODE'
36 ASSUME SS:DOSGROUP,CS:DOSGROUP
37
38 .xcref
39 INCLUDE DOSSYM.ASM
40 INCLUDE DEVSYM.ASM
41 .cref
42 .list
43
44
45 i_need VERFLG,BYTE
46 i_need CNTCFLAG,BYTE
47 i_need DMAADD,DWORD
48 i_need CURDRV,BYTE
49 i_need Current_Country,WORD
50 i_need international_table,BYTE
51 i_need INDOS,BYTE
52 i_need SYSINITVAR,WORD
53 i_need NUMIO,BYTE
54 i_need SWITCH_CHARACTER,BYTE
55 i_need DEVICE_AVAILABILITY,BYTE
56
57 USERNUM DW ? ; 24 bit user number
58 DB ?
59 IF IBM
60 OEMNUM DB 0 ; 8 bit OEM number
61 ELSE
62 OEMNUM DB 0FFH ; 8 bit OEM number
63 ENDIF
64
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
68
69
70 BREAK <$Get_Version -- Return MSDOS version number>
71 procedure $GET_VERSION,NEAR
72 ASSUME DS:NOTHING,ES:NOTHING
73
74 ; Inputs:
75 ; None
76 ; Function:
77 ; Return MS-DOS version number
78 ; Outputs:
79 ; OEM number in BH
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
83
84 PUSH SS
85 POP DS
86 ASSUME DS:DOSGROUP
87 MOV BX,[USERNUM + 2]
88 MOV CX,[USERNUM]
89 MOV AX,[MSVERS]
90 invoke get_user_stack
91 ASSUME DS:NOTHING
92 MOV [SI.user_BX],BX
93 MOV [SI.user_CX],CX
94 MOV [SI.user_AX],AX ; Really only sets AH
95 return
96 $GET_VERSION ENDP
97
98 BREAK <$International - return country-dependent information>
99 ;
100 ; Inputs:
101 ; DS:DX point to a block
102 ; Function:
103 ; give users an idea of what country the application is running
104 ; Outputs:
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 ; +---------------------------------+
115
116 procedure $INTERNATIONAL,NEAR
117 ASSUME DS:NOTHING,ES:NOTHING
118 MOV BL,AL
119 PUSH DS
120 POP ES
121 PUSH DX
122 POP DI
123 PUSH SS
124 POP DS
125 ASSUME DS:DOSGROUP
126 CMP DI,-1
127 JZ international_set
128 OR BL,BL
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
134
135 international_find:
136 CALL international_get
137 JNC international_copy
138 error country_not_found
139
140 international_get:
141 MOV SI,OFFSET DOSGROUP:international_table
142 international_next:
143 LODSW ; Get size in AL, country code in AH
144 CMP AL,-1
145 JNZ check_code
146 STC
147 RET35:
148 RET
149
150 check_code:
151 CMP BL,AH
152 JZ RET35 ; Carry clear
153 XOR AH,AH
154 ADD SI,AX
155 JMP international_next
156
157 international_copy:
158 MOV CL,AL
159 XOR CH,CH
160 PUSH DI
161 REP MOVSB
162 POP DI
163 MOV WORD PTR ES:[DI.MAP_CALL + 2],CS ; Set segment for case map call
164 international_ok:
165 XOR AX,AX
166 MOV AL,BL ; Return country code in AX
167 transfer SYS_RET_OK
168
169 international_set:
170 CALL international_get
171 JNC international_store
172 error country_not_found
173
174 international_store:
175 MOV [Current_Country],SI
176 JMP international_ok
177
178 $INTERNATIONAL ENDP
179
180 BREAK <$Get_Verify_on_Write - return verify-after-write flag>
181 procedure $GET_VERIFY_ON_WRITE,NEAR
182 ASSUME DS:NOTHING,ES:NOTHING
183
184 ; Inputs:
185 ; none.
186 ; Function:
187 ; returns flag
188 ; Returns:
189 ; AL = value of VERIFY flag
190
191 MOV AL,[VERFLG]
192 return
193 $GET_VERIFY_ON_WRITE ENDP
194
195 BREAK <$Set_Verify_on_Write - Toggle verify-after-write flag>
196 procedure $SET_VERIFY_ON_WRITE,NEAR
197 ASSUME DS:NOTHING,ES:NOTHING
198
199 ; Inputs:
200 ; AL = desired value of VERIFY flag
201 ; Function:
202 ; Sets flag
203 ; Returns:
204 ; None
205
206 AND AL,1
207 MOV [VERFLG],AL
208 return
209 $SET_VERIFY_ON_WRITE ENDP
210
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
214
215 ; Inputs:
216 ; AL = 0 read ^C status
217 ; AL = 1 Set ^C status, DL = 0/1 for ^C off/on
218 ; Function:
219 ; Enable disable ^C checking in dispatcher
220 ; Outputs:
221 ; If AL = 0 then DL = 0/1 for ^C off/on
222
223 OR AL,AL
224 JNZ CTRL_C_set
225 invoke get_user_stack
226 MOV AL,[CNTCFLAG]
227 MOV BYTE PTR [SI.user_DX],AL
228 return
229 CTRL_C_set:
230 DEC AL
231 JNZ bad_val
232 AND DL,01h
233 MOV [CNTCFLAG],DL
234 return
235 bad_val:
236 MOV AL,0FFH
237 return
238 $SET_CTRL_C_TRAPPING ENDP
239
240 BREAK <$Get_INDOS_Flag -- Return location of DOS critical-section flag>
241 procedure $GET_INDOS_FLAG,NEAR
242 ASSUME DS:NOTHING,ES:NOTHING
243
244 ; Inputs:
245 ; None
246 ; Function:
247 ; Returns location of DOS status for interrupt routines
248 ; Returns:
249 ; Flag location in ES:BX
250
251 invoke get_user_stack
252 MOV [SI.user_BX],OFFSET DOSGROUP:INDOS
253 MOV [SI.user_ES],SS
254 return
255 $GET_INDOS_FLAG ENDP
256
257 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
258 ; C A V E A T P R O G R A M M E R ;
259 ; ;
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.
263 ; Use at risk.
264 invoke get_user_stack
265 MOV [SI.user_BX],OFFSET DOSGROUP:SYSINITVAR
266 MOV [SI.user_ES],SS
267 return
268 $GET_IN_VARS ENDP
269 ; ;
270 ; C A V E A T P R O G R A M M E R ;
271 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
272
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
276
277 ; Inputs:
278 ; DL = Drive number
279 ; Function:
280 ; Return number of free allocation units on drive
281 ; Outputs:
282 ; BX = Number of free allocation units
283 ; DX = Total Number of allocation units on disk
284 ; CX = Sector size
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
289
290 PUSH SS
291 POP DS
292 ASSUME DS:DOSGROUP
293 MOV AL,DL
294 invoke GETTHISDRV
295 MOV AX,-1
296 JC BADFRDRIVE
297 invoke FATREAD
298 XOR DX,DX
299 MOV BX,2
300 MOV CX,ES:[BP.dpb_max_cluster]
301 DEC CX
302 PUSH CX ; Save Total
303 SCANFREE:
304 invoke UNPACK
305 JNZ NOTFREECLUS
306 INC DX
307 NOTFREECLUS:
308 INC BX
309 LOOP SCANFREE
310 POP BX ; Remember Total
311 MOV AL,ES:[BP.dpb_cluster_mask]
312 INC AL
313 XOR AH,AH
314 MOV CX,ES:[BP.dpb_sector_size]
315 BADFRDRIVE:
316 invoke get_user_stack
317 ASSUME DS:NOTHING
318 MOV [SI. user_CX],CX
319 MOV [SI.user_DX],BX
320 MOV [SI.user_BX],DX
321 MOV [SI.user_AX],AX
322 return
323
324 $GET_DRIVE_FREESPACE ENDP
325
326 BREAK <$Get_DMA, $Set_DMA -- Get/Set current DMA address>
327 procedure $GET_DMA,NEAR
328 ASSUME DS:NOTHING,ES:NOTHING
329
330 ; Inputs:
331 ; None
332 ; Function:
333 ; Get DISK TRANSFER ADDRESS
334 ; Returns:
335 ; ES:BX is current transfer address
336
337 MOV BX,WORD PTR [DMAADD]
338 MOV CX,WORD PTR [DMAADD+2]
339 invoke get_user_stack
340 MOV [SI.user_BX],BX
341 MOV [SI.user_ES],CX
342 return
343 $GET_DMA ENDP
344
345 procedure $SET_DMA,NEAR ; System call 26
346 ASSUME DS:NOTHING,ES:NOTHING
347
348 ; Inputs:
349 ; DS:DX is desired new disk transfer address
350 ; Function:
351 ; Set DISK TRANSFER ADDRESS
352 ; Returns:
353 ; None
354
355 MOV WORD PTR [DMAADD],DX
356 MOV WORD PTR [DMAADD+2],DS
357 return
358 $SET_DMA ENDP
359
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 ;
363 ; ;
364 procedure $GET_DEFAULT_DPB,NEAR
365 ASSUME DS:NOTHING,ES:NOTHING
366
367 ; Inputs:
368 ; DL = Drive number (always default drive for call 31)
369 ; Function:
370 ; Return pointer to drive parameter table for default drive
371 ; Returns:
372 ; DS:BX points to the DPB
373 ; AL = 0 If OK, = -1 if bad drive (call 50 only)
374
375 MOV DL,0
376 entry $GET_DPB
377 PUSH SS
378 POP DS
379 ASSUME DS:DOSGROUP
380 MOV AL,DL
381 invoke GETTHISDRV
382 JC ISNODRV
383 invoke FATREAD
384 invoke get_user_stack
385 ASSUME DS:NOTHING
386 MOV [SI.user_BX],BP
387 MOV [SI.user_DS],ES
388 XOR AL,AL
389 return
390
391 ISNODRV:
392 MOV AL,-1
393 return
394 $GET_Default_dpb ENDP
395 ; ;
396 ; C A V E A T P R O G R A M M E R ;
397 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
398
399
400 BREAK <$Get_Default_Drive, $Set_Default_Drive -- Set/Get default drive>
401 procedure $GET_DEFAULT_DRIVE,NEAR
402 ASSUME DS:NOTHING,ES:NOTHING
403
404 ; Inputs:
405 ; None
406 ; Function:
407 ; Return current drive number
408 ; Returns:
409 ; AL = drive number
410
411 MOV AL,[CURDRV]
412 return
413 $GET_DEFAULT_DRIVE ENDP
414
415 procedure $SET_DEFAULT_DRIVE,NEAR
416 ASSUME DS:NOTHING,ES:NOTHING
417
418 ; Inputs:
419 ; DL = Drive number for new default drive
420 ; Function:
421 ; Set the default drive
422 ; Returns:
423 ; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD
424
425 MOV AL,[NUMIO]
426 CMP DL,AL
427 JNB RET17
428 MOV [CURDRV],DL
429 RET17: return
430 $SET_DEFAULT_DRIVE ENDP
431
432
433 BREAK <$Get_Interrupt_Vector - Get/Set interrupt vectors>
434 procedure $GET_INTERRUPT_VECTOR,NEAR
435 ASSUME DS:NOTHING,ES:NOTHING
436
437 ; Inputs:
438 ; AL = interrupt number
439 ; Function:
440 ; Get the interrupt vector
441 ; Returns:
442 ; ES:BX is current interrupt vector
443
444 CALL RECSET
445 LES BX,DWORD PTR ES:[BX]
446 invoke get_user_stack
447 MOV [SI.user_BX],BX
448 MOV [SI.user_ES],ES
449 return
450 $GET_INTERRUPT_VECTOR ENDP
451
452 procedure $SET_INTERRUPT_VECTOR,NEAR ; System call 37
453 ASSUME DS:NOTHING,ES:NOTHING
454
455 ; Inputs:
456 ; AL = interrupt number
457 ; DS:DX is desired new interrupt vector
458 ; Function:
459 ; Set the interrupt vector
460 ; Returns:
461 ; None
462
463 CALL RECSET
464 MOV ES:[BX],DX
465 MOV ES:[BX+2],DS
466 return
467 $SET_INTERRUPT_VECTOR ENDP
468
469 IF ALTVECT
470 VECIN: ; INPUT VECTORS
471 DB 22H ; Terminate
472 DB 23H ; ^C
473 DB 24H ; Hard error
474 DB 28H ; Spooler
475 LSTVEC DB ? ; ALL OTHER
476
477 VECOUT: ; GET MAPPED VECTOR
478 DB int_terminate
479 DB int_ctrl_c
480 DB int_fatal_abort
481 DB int_spooler
482 LSTVEC2 DB ? ; Map to itself
483
484 NUMVEC = VECOUT-VECIN
485 ENDIF
486
487 procedure RECSET,NEAR
488
489 IF ALTVECT
490 PUSH SS
491 POP ES
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
496 REPNE SCASB
497 MOV AL,ES:[DI+NUMVEC-1] ; Get translation
498 ENDIF
499
500 XOR BX,BX
501 MOV ES,BX
502 MOV BL,AL
503 SHL BX,1
504 SHL BX,1
505 return
506 recset ENDP
507
508 BREAK <$Char_Oper - hack on paths, switches so that xenix can look like PCDOS>
509 ;
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
518 ;
519 procedure $CHAR_OPER,NEAR
520 ASSUME DS:NOTHING,ES:NOTHING
521 PUSH SS
522 POP DS
523 ASSUME DS:DOSGROUP
524 OR AL,AL
525 JNZ char_oper_set_switch
526 MOV DL,[switch_character]
527 JMP SHORT char_oper_ret
528 char_oper_set_switch:
529 DEC AL
530 JNZ char_oper_read_avail
531 MOV [switch_character],DL
532 return
533 char_oper_read_avail:
534 DEC AL
535 JNZ char_oper_set_avail
536 MOV DL,[device_availability]
537 JMP SHORT char_oper_ret
538 char_oper_set_avail:
539 DEC AL
540 JNZ char_oper_bad_ret
541 MOV [device_availability],DL
542 return
543 char_oper_bad_ret:
544 MOV AL,0FFh
545 return
546 char_oper_ret:
547 invoke get_user_stack
548 MOV [SI.user_DX],DX
549 return
550 $CHAR_OPER ENDP
551
552 BREAK <$SetDPB - Create a valid DPB from a user-specified BPB>
553 procedure $SETDPB,NEAR
554 ASSUME DS:NOTHING,ES:NOTHING
555
556 ; Inputs:
557 ; ES:BP Points to DPB
558 ; DS:SI Points to BPB
559 ; Function:
560 ; Build a correct DPB from the BPB
561 ; Outputs:
562 ; ES:BP and DS preserved all others destroyed
563
564 MOV DI,BP
565 ADD DI,2 ; Skip over dpb_drive and dpb_UNIT
566 LODSW
567 STOSW ; dpb_sector_size
568 MOV DX,AX
569 LODSB
570 DEC AL
571 STOSB ; dpb_cluster_mask
572 INC AL
573 XOR AH,AH
574 LOG2LOOP:
575 TEST AL,1
576 JNZ SAVLOG
577 INC AH
578 SHR AL,1
579 JMP SHORT LOG2LOOP
580 SAVLOG:
581 MOV AL,AH
582 STOSB ; dpb_cluster_shift
583 MOV BL,AL
584 MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors)
585 LODSB
586 STOSB ; dpb_FAT_count Number of FATs
587 MOV BH,AL
588 LODSW
589 STOSW ; dpb_root_entries Number of directory entries
590 MOV CL,5
591 SHR DX,CL ; Directory entries per sector
592 DEC AX
593 ADD AX,DX ; Cause Round Up
594 MOV CX,DX
595 XOR DX,DX
596 DIV CX
597 MOV CX,AX ; Number of directory sectors
598 INC DI
599 INC DI ; Skip dpb_first_sector
600 MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster)
601 LODSB
602 MOV ES:[BP.dpb_media],AL ; Media byte
603 LODSW ; Number of sectors in a FAT
604 STOSB ; dpb_FAT_size
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
614 INC AX
615 MOV ES:[BP.dpb_max_cluster],AX
616 MOV ES:[BP.dpb_current_dir],0 ; Current directory is root
617 return
618 $SETDPB ENDP
619 ; ;
620 ; C A V E A T P R O G R A M M E R ;
621 ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----;
622
623 do_ext
624
625 CODE ENDS
626 END
627