]>
wirehaze git hosting - MS-DOS.git/blob - v2.0/source/SYSCALL.ASM
2 ; system call entry points MSDOS
7 CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
39 SUBTTL DATE
AND TIME
- SYSTEM CALLS
42,43,44,45; S/G DATE,TIME
41 procedure $GET_DATE
,NEAR ;System call 42
42 ASSUME
DS:NOTHING
,ES:NOTHING
54 invoke READTIME
;Check for rollover to next day
57 invoke get_user_stack
;Get pointer to user registers
59 MOV [SI.user_DX
],BX ;DH=month, DL=day
60 ADD AX,1980 ;Put bias back
61 MOV [SI.user_CX
],AX ;CX=year
62 MOV AL,BYTE PTR [WEEKDAY
]
66 procedure $SET_DATE
,NEAR ;System call 43
67 ASSUME
DS:NOTHING
,ES:NOTHING
74 ; AL = -1 date bad, = 0 OK
76 MOV AL,-1 ;Be ready to flag error
77 SUB CX,1980 ;Fix bias in year
78 JC RET24
;Error if not big enough
79 CMP CX,119 ;Year must be less than 2100
84 JZ RET24
;Error if either month or day is 0
85 CMP DH,12 ;Check against max. month
94 procedure $GET_TIME
,NEAR ;System call 44
95 ASSUME
DS:NOTHING
,ES:NOTHING
108 invoke get_user_stack
;Get pointer to user registers
115 procedure $SET_TIME
,NEAR ;System call 45
116 ;Time is in CX:DX in hours, minutes, seconds, 1/100 sec.
117 ASSUME
DS:NOTHING
,ES:NOTHING
124 ; AL = -1 time bad, = 0 OK
126 MOV AL,-1 ;Flag in case of error
127 CMP CH,24 ;Check hours
129 CMP CL,60 ;Check minutes
131 CMP DH,60 ;Check seconds
133 CMP DL,100 ;Check 1/100's
140 MOV BX,OFFSET DOSGROUP
:TIMEBUF
150 invoke DEVIOCALL2
;Get correct day count
155 POP WORD PTR [TIMEBUF
+4]
156 POP WORD PTR [TIMEBUF
+2]
159 invoke DEVIOCALL2
;Set the time
164 SUBTTL DISK R
/W ROUTINES
166 procedure $FCB_SEQ_READ
,NEAR ; System call 20
167 ASSUME
DS:NOTHING
,ES:NOTHING
170 ; DS:DX Points to openned FCB
172 ; Read next record from file to disk transfer address
174 ; AL = 1 EOF record is empty
175 ; AL = 3 EOF record is partial zero filled
176 ; AL = 2 No room at disk transfer address
183 entry $FCB_SEQ_WRITE
; System call 21
184 ASSUME
DS:NOTHING
,ES:NOTHING
187 ; DS:DX Points to openned FCB
189 ; Write next record to file from disk transfer address
192 ; AL = 2 No room in disk transfer segment
203 entry $FCB_RANDOM_READ
; System call 33
204 ASSUME
DS:NOTHING
,ES:NOTHING
207 ; DS:DX Points to openned FCB
209 ; Read record addressed by random record field from file to
210 ; disk transfer address
212 ; AL = 1 EOF record is empty
213 ; AL = 3 EOF record is partial zero filled
214 ; AL = 2 No room at disk transfer address
221 entry $FCB_RANDOM_WRITE
; System call 34
222 ASSUME
DS:NOTHING
,ES:NOTHING
225 ; DS:DX Points to openned FCB
227 ; Write record addressed by random record field to file from
228 ; disk transfer address
231 ; AL = 2 No room in disk transfer segment
238 entry $FCB_RANDOM_READ_BLOCK
; System call 39
239 ASSUME
DS:NOTHING
,ES:NOTHING
242 ; DS:DX Points to openned FCB
245 ; Read CX records starting at random record field from file
246 ; to disk transfer address
248 ; AL = 1 EOF record is empty
249 ; AL = 3 EOF record is partial zero filled
250 ; AL = 2 No room at disk transfer address
252 ; CX = Actual number of records read
258 entry $FCB_RANDOM_WRITE_BLOCK
; System call 40
259 ASSUME
DS:NOTHING
,ES:NOTHING
262 ; DS:DX Points to openned FCB
265 ; Write CX records starting at random record field to file
266 ; from disk transfer address
267 ; If CX = 0 File is set to length determined from random record field
270 ; AL = 2 No room in disk transfer segment
272 ; CX = Actual number of records written
277 invoke get_user_stack
284 MOV WORD PTR ES:[DI.fcb_RR
],AX
285 MOV ES:[DI.fcb_RR
+2],DL
288 MOV ES:[DI.fcb_RR
+3],DH ; Save 4 byte of RECPOS only if significant
292 MOV ES:[DI.fcb_NR
],AL
298 MOV ES:[DI.fcb_EXTENT
],AX
299 MOV AL,BYTE PTR [DSKERR
]
304 SUBTTL $FCB_DELETE
-- SYSTEM
CALL 19
306 procedure $FCB_DELETE
,NEAR ; System call 19
307 ASSUME
DS:NOTHING
,ES:NOTHING
310 ; DS:DX point to unopened FCB
312 ; Delete all matching entries
314 ; AL = -1 if no entries matched, otherwise 0
319 MOV BYTE PTR [FoundDel
],AL
321 MOV AL,BYTE PTR [ATTRIB
]
322 AND AL,attr_hidden
+attr_system
+attr_directory
+attr_volume_id
+attr_read_only
323 ; Look only at hidden bits
324 CMP AL,attr_hidden
+attr_system
+attr_directory
+attr_volume_id
+attr_read_only
329 MOV DI,OFFSET DOSGROUP
:NAME1
330 REPE SCASB ; See if name is *.*
332 MOV BYTE PTR [DELALL
],0 ; DEL *.* - flag deleting all
338 OR AH,AH ; Check if device name
339 JS RET4
; Can't delete I/O devices
342 MOV AH,BYTE PTR [DELALL
]
346 TEST [Attrib
],attr_read_only
; are we deleting RO files too?
348 TEST DS:[BX.dir_attr
],attr_read_only
349 JZ DoDelete
; not read only
353 MOV BYTE PTR [FoundDel
],0
361 CMP BX,ES:[BP.dpb_max_cluster
]
365 invoke GETENTRY
; Registers need to be reset
369 MOV AL,BYTE PTR [FoundDel
]
374 SUBTTL $FCB_RENAME
-- SYSTEM
CALL 23; RENAME FILES
378 procedure $FCB_RENAME
,NEAR ; System call 23
379 ASSUME
DS:NOTHING
,ES:NOTHING
382 ; DS:DX point to a modified FCB (DS:DX+11H points to destination
385 ; Rename all matching entries to indicated name
387 ; AL = -1 if no entries matched, otherwise 0
393 MOV DI,OFFSET DOSGROUP
:NAME2
395 JC ERRETJ
; Report error if second name invalid
399 OR AH,AH ; Check if I/O device name
400 JS ERRETJ
; If so, can't rename it
401 MOV SI,OFFSET DOSGROUP
:NAME1
402 MOV DI,OFFSET DOSGROUP
:NAME3
404 REP MOVSB ; Copy name to search for --include attribute byte
406 MOV DI,OFFSET DOSGROUP
:NAME1
407 MOV SI,OFFSET DOSGROUP
:NAME2
414 MOV DS,WORD PTR [CURBUF
+2]
422 MOV BYTE PTR [DI],attr_all
;Sets ATTRIB
423 ; Stop duplicates with any attributes
424 invoke DEVNAME
; Check if giving it a device name
428 invoke FINDENTRY
; See if new name already exists
430 JNC RENERR
; Error if found
432 invoke GETENT
; Re-read matching entry
433 MOV DI,BX ; Leave BX,DX until call to NEXTENT
434 MOV ES,WORD PTR [CURBUF
+2]
435 MOV SI,OFFSET DOSGROUP
:NAME1
437 REP MOVSB ; Replace old name with new one
438 MOV DI,WORD PTR [CURBUF
]
439 MOV ES:[DI.BUFDIRTY
],1 ; Directory changed
442 MOV SI,OFFSET DOSGROUP
:NAME3
443 MOV DI,OFFSET DOSGROUP
:NAME1
444 MOV CX,13 ; Include attribute byte
445 REP MOVSB ; Copy name back into search buffer
457 SUBTTL $FCB_OPEN
-- SYSTEM
CALL 15; OPEN A FILE
459 procedure $FCB_OPEN
,NEAR ; System call 15
460 ASSUME
DS:NOTHING
,ES:NOTHING
463 ; DS:DX point to an unopened FCB
465 ; Open indicated file and fill in FCB
467 ; AL = -1 if no entries matched, otherwise 0
469 ; [CURBUF+2]:SI and [CURBUF+2]:BX Preserved
472 ASSUME
DS:DOSGROUP
,ES:NOTHING
476 ; Enter here to perform $FCB_OPEN on file already found
477 ; in directory. AH=device ID number, DS=CS, BX points to directory
478 ; entry in [CURBUF], SI points to First Cluster field, and
479 ; ES:DI point to the FCB to be opened. This entry point
480 ; is used by $FCB_CREATE.
483 PUSH AX ; Save I/O driver number
488 MOV DS,WORD PTR [CURBUF
+2]
496 STOSW ; Zero low byte of extent field if ZERPEXT only
498 ADD DI,12 ; Point to high half of CURRENT BLOCK field
499 STOSB ; Set it to zero (CP/M programs set low byte)
501 MOV AL,128 ; Default record size
502 STOSW ; Set record size
503 LODSW ; Get starting cluster
504 MOV DX,AX ; Save it for the moment
505 MOVSW ; Transfer size to FCB
507 MOV AX,[SI-8] ; Get date
508 STOSW ; Save date in FCB
509 MOV AX,[SI-10] ; Get time
510 STOSW ; Save it in FCB
511 POP AX ; Restore I/O driver number
514 OR AL,40H
; Not dirty
516 JS SAVDEVPT
; If device, go save pointer to it
517 MOV AX,DX ; Restore starting cluster
518 STOSW ; first cluster
519 PUSH AX ; save cluster
522 POP AX ; last cluster
525 MOV AH,BYTE PTR [DIRSTART
]
550 SUBTTL $FCB_CLOSE
-- SYSTEM
CALL 16; CLOSE FILE
552 procedure $FCB_CLOSE
,NEAR ; System call 16
553 ASSUME
DS:NOTHING
,ES:NOTHING
556 ; DS:DX point to an opened FCB
558 ; Close the indicated file
560 ; AL = -1 if disk has been changed, otherwise 0
563 CMP BYTE PTR [DI],-1 ; Check for extended FCB
567 TEST [DI.fcb_DEVID
],devid_file_clean
+devid_device
568 ; Allow only dirty files
569 JNZ OKRET1
; can't close I/O device or not written
571 JC BADCLOSE
; Bad file name
572 entry FCB_CLOSE_INNER
576 MOV BX,[SI.fcb_LSTCLUS
+1]
593 ; note that SI points to dir_first...
595 OR BYTE PTR [SI-dir_first
+dir_attr
],attr_archive
596 MOV CX,ES:[DI.fcb_FIRCLUS
]
597 MOV [SI-dir_first
+dir_first
],CX
598 MOV DX,ES:WORD PTR [DI.fcb_FILSIZ
]
599 MOV [SI-dir_first
+dir_size_l
],DX
600 MOV DX,ES:WORD PTR [DI.fcb_FILSIZ
+2]
601 MOV [SI-dir_first
+dir_size_h
],DX
602 MOV DX,ES:[DI.fcb_FDATE
]
603 MOV [SI-dir_first
+dir_date
],DX
604 MOV DX,ES:[DI.fcb_FTIME
]
605 MOV [SI-dir_first
+dir_time
],DX
612 MOV AL,ES:[BP.dpb_drive
]
623 SUBTTL $FCB_CREATE
-- SYSTEM
CALL 22; MAKE AND OPEN A NEW FILE
625 procedure $FCB_CREATE
,NEAR ; System call 22
626 ASSUME
DS:NOTHING
,ES:NOTHING
629 ; DS:DX point to an unopened FCB
631 ; If file does not exist, create it and open it
632 ; If file exists, free up its contents and open the file
634 ; AL = -1 if file cannot be created, otherwise 0
639 MOV DI,OFFSET DOSGROUP
:NAME1
644 MOV BYTE PTR [CREATING
],-1
655 invoke GETENT
; Point at that free entry
665 POP DX ; Return address
675 JNZ ERRPOP
; Error if attributes don't match
676 OR AH,AH ; Check if file is I/O device
677 JS OPENJMP
; If so, no action
681 MOV CX,[SI] ; Get pointer to clusters
686 CMP CX,ES:[BP.dpb_max_cluster
]
690 PUSH SI ; Save sector number
692 invoke RELEASE
; Free any data already allocated
697 ADD BX,WORD PTR [CURBUF
]
699 TEST BYTE PTR [ATTRIB
],attr_volume_id
701 CMP BYTE PTR [VOLID
],0
702 JNZ ERRPOP
; Can't create a second volume ID
704 MOV ES,WORD PTR [CURBUF
+2]
706 MOV SI,OFFSET DOSGROUP
:NAME1
725 MOV SI,WORD PTR [CURBUF
]
726 MOV ES:[SI.BUFDIRTY
],1
728 MOV AL,ES:[BP.dpb_drive
]
735 MOV AH,AL ; Get I/O driver number back
737 CLC ; Clear carry so OPEN won't fail