mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-20 21:43:39 -07:00
MS-DOS v2.0 Release
This commit is contained in:
parent
fce0f75959
commit
80ab2fddfd
156 changed files with 56403 additions and 0 deletions
749
v2.0/source/SYSCALL.ASM
Normal file
749
v2.0/source/SYSCALL.ASM
Normal file
|
@ -0,0 +1,749 @@
|
|||
;
|
||||
; system call entry points MSDOS
|
||||
;
|
||||
|
||||
INCLUDE DOSSEG.ASM
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME SS:DOSGROUP,CS:DOSGROUP
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.ASM
|
||||
INCLUDE DEVSYM.ASM
|
||||
.cref
|
||||
.list
|
||||
|
||||
|
||||
i_need YEAR,WORD
|
||||
i_need DAY,BYTE
|
||||
i_need WeekDay,BYTE
|
||||
i_need TimeBuf,6
|
||||
i_need BCLOCK,DWORD
|
||||
i_need DskErr,BYTE
|
||||
i_need Attrib,BYTE
|
||||
i_need Name1,BYTE
|
||||
i_need Name2,BYTE
|
||||
i_need Name3,BYTE
|
||||
i_need DelAll,BYTE
|
||||
i_need ThisDPB,DWORD
|
||||
i_need CurBuf,DWORD
|
||||
i_need LastEnt,WORD
|
||||
i_need ThisDrv,BYTE
|
||||
i_need DirStart,WORD
|
||||
i_need DevPt,DWORD
|
||||
i_need Creating,BYTE
|
||||
i_need VolID,BYTE
|
||||
i_need FoundDel,BYTE
|
||||
|
||||
SUBTTL DATE AND TIME - SYSTEM CALLS 42,43,44,45; S/G DATE,TIME
|
||||
PAGE
|
||||
procedure $GET_DATE,NEAR ;System call 42
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; None
|
||||
; Function:
|
||||
; Return current date
|
||||
; Returns:
|
||||
; Date in CX:DX
|
||||
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
invoke READTIME ;Check for rollover to next day
|
||||
MOV AX,[YEAR]
|
||||
MOV BX,WORD PTR [DAY]
|
||||
invoke get_user_stack ;Get pointer to user registers
|
||||
ASSUME DS:NOTHING
|
||||
MOV [SI.user_DX],BX ;DH=month, DL=day
|
||||
ADD AX,1980 ;Put bias back
|
||||
MOV [SI.user_CX],AX ;CX=year
|
||||
MOV AL,BYTE PTR [WEEKDAY]
|
||||
RET
|
||||
$GET_DATE ENDP
|
||||
|
||||
procedure $SET_DATE,NEAR ;System call 43
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; CX:DX valid date
|
||||
; Function:
|
||||
; Set current date
|
||||
; Returns:
|
||||
; AL = -1 date bad, = 0 OK
|
||||
|
||||
MOV AL,-1 ;Be ready to flag error
|
||||
SUB CX,1980 ;Fix bias in year
|
||||
JC RET24 ;Error if not big enough
|
||||
CMP CX,119 ;Year must be less than 2100
|
||||
JA RET24
|
||||
OR DH,DH
|
||||
JZ RET24
|
||||
OR DL,DL
|
||||
JZ RET24 ;Error if either month or day is 0
|
||||
CMP DH,12 ;Check against max. month
|
||||
JA RET24
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
invoke DODATE
|
||||
RET24: RET
|
||||
$SET_DATE ENDP
|
||||
|
||||
procedure $GET_TIME,NEAR ;System call 44
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; None
|
||||
; Function:
|
||||
; Get current time
|
||||
; Returns:
|
||||
; Time in CX:DX
|
||||
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
invoke READTIME
|
||||
invoke get_user_stack ;Get pointer to user registers
|
||||
MOV [SI.user_DX],DX
|
||||
MOV [SI.user_CX],CX
|
||||
XOR AL,AL
|
||||
RET26: RET
|
||||
$GET_TIME ENDP
|
||||
|
||||
procedure $SET_TIME,NEAR ;System call 45
|
||||
;Time is in CX:DX in hours, minutes, seconds, 1/100 sec.
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; CX:DX = Time
|
||||
; Function:
|
||||
; Set time
|
||||
; Returns:
|
||||
; AL = -1 time bad, = 0 OK
|
||||
|
||||
MOV AL,-1 ;Flag in case of error
|
||||
CMP CH,24 ;Check hours
|
||||
JAE RET26
|
||||
CMP CL,60 ;Check minutes
|
||||
JAE RET26
|
||||
CMP DH,60 ;Check seconds
|
||||
JAE RET26
|
||||
CMP DL,100 ;Check 1/100's
|
||||
JAE RET26
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
MOV BX,OFFSET DOSGROUP:TIMEBUF
|
||||
MOV CX,6
|
||||
XOR DX,DX
|
||||
MOV AX,DX
|
||||
PUSH BX
|
||||
invoke SETREAD
|
||||
ASSUME ES:DOSGROUP
|
||||
PUSH DS
|
||||
LDS SI,[BCLOCK]
|
||||
ASSUME DS:NOTHING
|
||||
invoke DEVIOCALL2 ;Get correct day count
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
POP BX
|
||||
invoke SETWRITE
|
||||
POP WORD PTR [TIMEBUF+4]
|
||||
POP WORD PTR [TIMEBUF+2]
|
||||
LDS SI,[BCLOCK]
|
||||
ASSUME DS:NOTHING
|
||||
invoke DEVIOCALL2 ;Set the time
|
||||
XOR AL,AL
|
||||
RET
|
||||
$SET_TIME ENDP
|
||||
|
||||
SUBTTL DISK R/W ROUTINES
|
||||
PAGE
|
||||
procedure $FCB_SEQ_READ,NEAR ; System call 20
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX Points to openned FCB
|
||||
; Function:
|
||||
; Read next record from file to disk transfer address
|
||||
; Returns:
|
||||
; AL = 1 EOF record is empty
|
||||
; AL = 3 EOF record is partial zero filled
|
||||
; AL = 2 No room at disk transfer address
|
||||
; AL = 0 All OK
|
||||
|
||||
invoke GETREC
|
||||
invoke LOAD
|
||||
JMP SHORT FINSEQ
|
||||
|
||||
entry $FCB_SEQ_WRITE ; System call 21
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX Points to openned FCB
|
||||
; Function:
|
||||
; Write next record to file from disk transfer address
|
||||
; Returns:
|
||||
; AL = 1 Disk full
|
||||
; AL = 2 No room in disk transfer segment
|
||||
; AL = 0 All OK
|
||||
|
||||
invoke GETREC
|
||||
invoke STORE
|
||||
FINSEQ:
|
||||
JCXZ SETNREX
|
||||
ADD AX,1
|
||||
ADC DX,0
|
||||
JMP SHORT SETNREX
|
||||
|
||||
entry $FCB_RANDOM_READ ; System call 33
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX Points to openned FCB
|
||||
; Function:
|
||||
; Read record addressed by random record field from file to
|
||||
; disk transfer address
|
||||
; Returns:
|
||||
; AL = 1 EOF record is empty
|
||||
; AL = 3 EOF record is partial zero filled
|
||||
; AL = 2 No room at disk transfer address
|
||||
; AL = 0 All OK
|
||||
|
||||
invoke GETRRPOS1
|
||||
invoke LOAD
|
||||
JMP SHORT FINRND
|
||||
|
||||
entry $FCB_RANDOM_WRITE ; System call 34
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX Points to openned FCB
|
||||
; Function:
|
||||
; Write record addressed by random record field to file from
|
||||
; disk transfer address
|
||||
; Returns:
|
||||
; AL = 1 Disk full
|
||||
; AL = 2 No room in disk transfer segment
|
||||
; AL = 0 All OK
|
||||
|
||||
invoke GETRRPOS1
|
||||
invoke STORE
|
||||
JMP SHORT FINRND
|
||||
|
||||
entry $FCB_RANDOM_READ_BLOCK ; System call 39
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX Points to openned FCB
|
||||
; CX = Record count
|
||||
; Function:
|
||||
; Read CX records starting at random record field from file
|
||||
; to disk transfer address
|
||||
; Returns:
|
||||
; AL = 1 EOF record is empty
|
||||
; AL = 3 EOF record is partial zero filled
|
||||
; AL = 2 No room at disk transfer address
|
||||
; AL = 0 All OK
|
||||
; CX = Actual number of records read
|
||||
|
||||
invoke GETRRPOS
|
||||
invoke LOAD
|
||||
JMP SHORT FINBLK
|
||||
|
||||
entry $FCB_RANDOM_WRITE_BLOCK ; System call 40
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX Points to openned FCB
|
||||
; CX = Record count
|
||||
; Function:
|
||||
; Write CX records starting at random record field to file
|
||||
; from disk transfer address
|
||||
; If CX = 0 File is set to length determined from random record field
|
||||
; Returns:
|
||||
; AL = 1 Disk full
|
||||
; AL = 2 No room in disk transfer segment
|
||||
; AL = 0 All OK
|
||||
; CX = Actual number of records written
|
||||
|
||||
invoke GETRRPOS
|
||||
invoke STORE
|
||||
FINBLK:
|
||||
invoke get_user_stack
|
||||
MOV [SI.user_CX],CX
|
||||
entry FINNOSAV
|
||||
JCXZ FINRND
|
||||
ADD AX,1
|
||||
ADC DX,0
|
||||
FINRND:
|
||||
MOV WORD PTR ES:[DI.fcb_RR],AX
|
||||
MOV ES:[DI.fcb_RR+2],DL
|
||||
OR DH,DH
|
||||
JZ SETNREX
|
||||
MOV ES:[DI.fcb_RR+3],DH ; Save 4 byte of RECPOS only if significant
|
||||
SETNREX:
|
||||
MOV CX,AX
|
||||
AND AL,7FH
|
||||
MOV ES:[DI.fcb_NR],AL
|
||||
AND CL,80H
|
||||
SHL CX,1
|
||||
RCL DX,1
|
||||
MOV AL,CH
|
||||
MOV AH,DL
|
||||
MOV ES:[DI.fcb_EXTENT],AX
|
||||
MOV AL,BYTE PTR [DSKERR]
|
||||
RET4:
|
||||
RET
|
||||
$FCB_SEQ_READ ENDP
|
||||
|
||||
SUBTTL $FCB_DELETE -- SYSTEM CALL 19
|
||||
PAGE
|
||||
procedure $FCB_DELETE,NEAR ; System call 19
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX point to unopened FCB
|
||||
; Function:
|
||||
; Delete all matching entries
|
||||
; Returns:
|
||||
; AL = -1 if no entries matched, otherwise 0
|
||||
|
||||
invoke MOVNAME
|
||||
ASSUME ES:DOSGROUP
|
||||
MOV AL,-1
|
||||
MOV BYTE PTR [FoundDel],AL
|
||||
JC RET4
|
||||
MOV AL,BYTE PTR [ATTRIB]
|
||||
AND AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only
|
||||
; Look only at hidden bits
|
||||
CMP AL,attr_hidden+attr_system+attr_directory+attr_volume_id+attr_read_only
|
||||
; All must be set
|
||||
JNZ NOTALL
|
||||
MOV CX,11
|
||||
MOV AL,"?"
|
||||
MOV DI,OFFSET DOSGROUP:NAME1
|
||||
REPE SCASB ; See if name is *.*
|
||||
JNZ NOTALL
|
||||
MOV BYTE PTR [DELALL],0 ; DEL *.* - flag deleting all
|
||||
NOTALL:
|
||||
invoke FINDNAME
|
||||
ASSUME DS:DOSGROUP
|
||||
MOV AL,-1
|
||||
JC RET4
|
||||
OR AH,AH ; Check if device name
|
||||
JS RET4 ; Can't delete I/O devices
|
||||
DELFILE:
|
||||
LES BP,[THISDPB]
|
||||
MOV AH,BYTE PTR [DELALL]
|
||||
PUSH DS
|
||||
LDS DI,[CURBUF]
|
||||
ASSUME DS:NOTHING
|
||||
TEST [Attrib],attr_read_only ; are we deleting RO files too?
|
||||
JNZ DoDelete ; yes
|
||||
TEST DS:[BX.dir_attr],attr_read_only
|
||||
JZ DoDelete ; not read only
|
||||
POP DS
|
||||
JMP SHORT DelNxt
|
||||
DoDelete:
|
||||
MOV BYTE PTR [FoundDel],0
|
||||
MOV [DI.BUFDIRTY],1
|
||||
MOV BYTE PTR [BX],AH
|
||||
MOV BX,[SI]
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
OR BX,BX
|
||||
JZ DELNXT
|
||||
CMP BX,ES:[BP.dpb_max_cluster]
|
||||
JA DELNXT
|
||||
invoke RELEASE
|
||||
DELNXT:
|
||||
invoke GETENTRY ; Registers need to be reset
|
||||
invoke NEXTENT
|
||||
JNC DELFILE
|
||||
CALL FLUSHRET1
|
||||
MOV AL,BYTE PTR [FoundDel]
|
||||
RET
|
||||
|
||||
$FCB_DELETE ENDP
|
||||
|
||||
SUBTTL $FCB_RENAME -- SYSTEM CALL 23; RENAME FILES
|
||||
PAGE
|
||||
ERRETJ: JMP ERRET
|
||||
|
||||
procedure $FCB_RENAME,NEAR ; System call 23
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX point to a modified FCB (DS:DX+11H points to destination
|
||||
; name)
|
||||
; Function:
|
||||
; Rename all matching entries to indicated name
|
||||
; Returns:
|
||||
; AL = -1 if no entries matched, otherwise 0
|
||||
|
||||
invoke MOVNAME
|
||||
ASSUME ES:DOSGROUP
|
||||
JC ERRETJ
|
||||
ADD SI,5
|
||||
MOV DI,OFFSET DOSGROUP:NAME2
|
||||
invoke LODNAME
|
||||
JC ERRETJ ; Report error if second name invalid
|
||||
invoke FINDNAME
|
||||
ASSUME DS:DOSGROUP
|
||||
JC ERRETJ
|
||||
OR AH,AH ; Check if I/O device name
|
||||
JS ERRETJ ; If so, can't rename it
|
||||
MOV SI,OFFSET DOSGROUP:NAME1
|
||||
MOV DI,OFFSET DOSGROUP:NAME3
|
||||
MOV CX,13
|
||||
REP MOVSB ; Copy name to search for --include attribute byte
|
||||
RENFIL:
|
||||
MOV DI,OFFSET DOSGROUP:NAME1
|
||||
MOV SI,OFFSET DOSGROUP:NAME2
|
||||
MOV CX,11
|
||||
NEWNAM:
|
||||
LODSB
|
||||
CMP AL,"?"
|
||||
JNZ NOCHG
|
||||
PUSH DS
|
||||
MOV DS,WORD PTR [CURBUF+2]
|
||||
MOV AL,[BX]
|
||||
POP DS
|
||||
NOCHG:
|
||||
STOSB
|
||||
INC BX
|
||||
LOOP NEWNAM
|
||||
INC DI
|
||||
MOV BYTE PTR [DI],attr_all ;Sets ATTRIB
|
||||
; Stop duplicates with any attributes
|
||||
invoke DEVNAME ; Check if giving it a device name
|
||||
JNC RENERR
|
||||
XOR AX,AX
|
||||
PUSH [LASTENT]
|
||||
invoke FINDENTRY ; See if new name already exists
|
||||
POP AX
|
||||
JNC RENERR ; Error if found
|
||||
LES BP,[THISDPB]
|
||||
invoke GETENT ; Re-read matching entry
|
||||
MOV DI,BX ; Leave BX,DX until call to NEXTENT
|
||||
MOV ES,WORD PTR [CURBUF+2]
|
||||
MOV SI,OFFSET DOSGROUP:NAME1
|
||||
MOV CX,11
|
||||
REP MOVSB ; Replace old name with new one
|
||||
MOV DI,WORD PTR [CURBUF]
|
||||
MOV ES:[DI.BUFDIRTY],1 ; Directory changed
|
||||
PUSH SS
|
||||
POP ES
|
||||
MOV SI,OFFSET DOSGROUP:NAME3
|
||||
MOV DI,OFFSET DOSGROUP:NAME1
|
||||
MOV CX,13 ; Include attribute byte
|
||||
REP MOVSB ; Copy name back into search buffer
|
||||
invoke NEXTENT
|
||||
JNC RENFIL
|
||||
JMP FLUSHRET1
|
||||
|
||||
RENERR:
|
||||
CALL FLUSHRET1
|
||||
ERRET:
|
||||
MOV AL,-1
|
||||
RET
|
||||
$FCB_RENAME ENDP
|
||||
|
||||
SUBTTL $FCB_OPEN -- SYSTEM CALL 15; OPEN A FILE
|
||||
PAGE
|
||||
procedure $FCB_OPEN,NEAR ; System call 15
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX point to an unopened FCB
|
||||
; Function:
|
||||
; Open indicated file and fill in FCB
|
||||
; Returns:
|
||||
; AL = -1 if no entries matched, otherwise 0
|
||||
; FOR INTERNAL USE
|
||||
; [CURBUF+2]:SI and [CURBUF+2]:BX Preserved
|
||||
|
||||
invoke GETFILE
|
||||
ASSUME DS:DOSGROUP,ES:NOTHING
|
||||
|
||||
entry DOOPEN
|
||||
|
||||
; Enter here to perform $FCB_OPEN on file already found
|
||||
; in directory. AH=device ID number, DS=CS, BX points to directory
|
||||
; entry in [CURBUF], SI points to First Cluster field, and
|
||||
; ES:DI point to the FCB to be opened. This entry point
|
||||
; is used by $FCB_CREATE.
|
||||
JC ERRET
|
||||
PUSH SI
|
||||
PUSH AX ; Save I/O driver number
|
||||
XOR AL,AL
|
||||
OR AH,AH
|
||||
JS OPENDEV
|
||||
MOV AL,[THISDRV]
|
||||
MOV DS,WORD PTR [CURBUF+2]
|
||||
ASSUME DS:NOTHING
|
||||
INC AX
|
||||
OPENDEV:
|
||||
STOSB
|
||||
XOR AX,AX
|
||||
IF ZEROEXT
|
||||
ADD DI,11
|
||||
STOSW ; Zero low byte of extent field if ZERPEXT only
|
||||
ELSE
|
||||
ADD DI,12 ; Point to high half of CURRENT BLOCK field
|
||||
STOSB ; Set it to zero (CP/M programs set low byte)
|
||||
ENDIF
|
||||
MOV AL,128 ; Default record size
|
||||
STOSW ; Set record size
|
||||
LODSW ; Get starting cluster
|
||||
MOV DX,AX ; Save it for the moment
|
||||
MOVSW ; Transfer size to FCB
|
||||
MOVSW
|
||||
MOV AX,[SI-8] ; Get date
|
||||
STOSW ; Save date in FCB
|
||||
MOV AX,[SI-10] ; Get time
|
||||
STOSW ; Save it in FCB
|
||||
POP AX ; Restore I/O driver number
|
||||
POP SI
|
||||
MOV AL,AH
|
||||
OR AL,40H ; Not dirty
|
||||
STOSB
|
||||
JS SAVDEVPT ; If device, go save pointer to it
|
||||
MOV AX,DX ; Restore starting cluster
|
||||
STOSW ; first cluster
|
||||
PUSH AX ; save cluster
|
||||
XOR AX,AX
|
||||
STOSW ; clus pos
|
||||
POP AX ; last cluster
|
||||
STOSB
|
||||
MOV AL,AH
|
||||
MOV AH,BYTE PTR [DIRSTART]
|
||||
PUSH CX
|
||||
MOV CL,4
|
||||
SHL AH,CL
|
||||
OR AL,AH
|
||||
STOSB
|
||||
MOV AX,[DIRSTART]
|
||||
MOV CL,4
|
||||
SHL AX,CL
|
||||
POP CX
|
||||
MOV AL,AH
|
||||
STOSB
|
||||
OPEN_RET:
|
||||
XOR AX,AX
|
||||
RET
|
||||
|
||||
SAVDEVPT:
|
||||
ASSUME DS:DOSGROUP
|
||||
LDS AX,[DEVPT]
|
||||
ASSUME DS:NOTHING
|
||||
STOSW
|
||||
MOV ES:[DI],DS
|
||||
JMP SHORT OPEN_RET
|
||||
$FCB_OPEN ENDP
|
||||
|
||||
SUBTTL $FCB_CLOSE -- SYSTEM CALL 16; CLOSE FILE
|
||||
PAGE
|
||||
procedure $FCB_CLOSE,NEAR ; System call 16
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX point to an opened FCB
|
||||
; Function:
|
||||
; Close the indicated file
|
||||
; Returns:
|
||||
; AL = -1 if disk has been changed, otherwise 0
|
||||
|
||||
MOV DI,DX
|
||||
CMP BYTE PTR [DI],-1 ; Check for extended FCB
|
||||
JNZ NORMFCB3
|
||||
ADD DI,7
|
||||
NORMFCB3:
|
||||
TEST [DI.fcb_DEVID],devid_file_clean+devid_device
|
||||
; Allow only dirty files
|
||||
JNZ OKRET1 ; can't close I/O device or not written
|
||||
invoke MOVNAMENOSET
|
||||
JC BADCLOSE ; Bad file name
|
||||
entry FCB_CLOSE_INNER
|
||||
PUSH DX
|
||||
PUSH DS
|
||||
MOV SI,DX
|
||||
MOV BX,[SI.fcb_LSTCLUS+1]
|
||||
MOV CL,4
|
||||
SHR BX,CL
|
||||
PUSH BX
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
invoke FATREAD
|
||||
POP BX
|
||||
invoke SETDIRSRCH
|
||||
invoke FINDENTRY
|
||||
POP ES
|
||||
POP DI
|
||||
JC BADCLOSE
|
||||
LDS BX,[CURBUF]
|
||||
ASSUME DS:NOTHING
|
||||
|
||||
; note that SI points to dir_first...
|
||||
|
||||
OR BYTE PTR [SI-dir_first+dir_attr],attr_archive
|
||||
MOV CX,ES:[DI.fcb_FIRCLUS]
|
||||
MOV [SI-dir_first+dir_first],CX
|
||||
MOV DX,ES:WORD PTR [DI.fcb_FILSIZ]
|
||||
MOV [SI-dir_first+dir_size_l],DX
|
||||
MOV DX,ES:WORD PTR [DI.fcb_FILSIZ+2]
|
||||
MOV [SI-dir_first+dir_size_h],DX
|
||||
MOV DX,ES:[DI.fcb_FDATE]
|
||||
MOV [SI-dir_first+dir_date],DX
|
||||
MOV DX,ES:[DI.fcb_FTIME]
|
||||
MOV [SI-dir_first+dir_time],DX
|
||||
MOV [BX.BUFDIRTY],1
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
FLUSHRET1:
|
||||
LES BP,[THISDPB]
|
||||
MOV AL,ES:[BP.dpb_drive]
|
||||
invoke FLUSHBUF
|
||||
OKRET1:
|
||||
XOR AL,AL
|
||||
RET
|
||||
|
||||
BADCLOSE:
|
||||
MOV AL,-1
|
||||
RET
|
||||
$FCB_CLOSE ENDP
|
||||
|
||||
SUBTTL $FCB_CREATE -- SYSTEM CALL 22; MAKE AND OPEN A NEW FILE
|
||||
PAGE
|
||||
procedure $FCB_CREATE,NEAR ; System call 22
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:DX point to an unopened FCB
|
||||
; Function:
|
||||
; If file does not exist, create it and open it
|
||||
; If file exists, free up its contents and open the file
|
||||
; Returns:
|
||||
; AL = -1 if file cannot be created, otherwise 0
|
||||
|
||||
invoke MOVNAME
|
||||
ASSUME ES:DOSGROUP
|
||||
JC ERRET3
|
||||
MOV DI,OFFSET DOSGROUP:NAME1
|
||||
MOV CX,11
|
||||
MOV AL,"?"
|
||||
REPNE SCASB
|
||||
JZ ERRET3
|
||||
MOV BYTE PTR [CREATING],-1
|
||||
PUSH DX
|
||||
PUSH DS
|
||||
invoke FINDNAME
|
||||
ASSUME DS:DOSGROUP
|
||||
NWENTY:
|
||||
LES BP,[THISDPB]
|
||||
ASSUME ES:NOTHING
|
||||
JNC EXISTENT
|
||||
invoke BUILDDIR
|
||||
JC ERRPOP
|
||||
invoke GETENT ; Point at that free entry
|
||||
JMP SHORT FREESPOT
|
||||
ERRPOP:
|
||||
POP DS
|
||||
POP DX
|
||||
ASSUME DS:NOTHING
|
||||
ERRET3:
|
||||
JMP SHORT BADCLOSE
|
||||
|
||||
entry NEWENTRY
|
||||
POP DX ; Return address
|
||||
POP ES ; ES
|
||||
POP CX ; DI
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
PUSH ES
|
||||
JMP NWENTY
|
||||
|
||||
EXISTENT:
|
||||
ASSUME DS:DOSGROUP
|
||||
JNZ ERRPOP ; Error if attributes don't match
|
||||
OR AH,AH ; Check if file is I/O device
|
||||
JS OPENJMP ; If so, no action
|
||||
PUSH DS
|
||||
LDS DI,[CURBUF]
|
||||
ASSUME DS:NOTHING
|
||||
MOV CX,[SI] ; Get pointer to clusters
|
||||
MOV SI,[DI.BUFSECNO]
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
JCXZ FREESPOT
|
||||
CMP CX,ES:[BP.dpb_max_cluster]
|
||||
JA FREESPOT
|
||||
SUB BX,DI
|
||||
PUSH BX
|
||||
PUSH SI ; Save sector number
|
||||
MOV BX,CX
|
||||
invoke RELEASE ; Free any data already allocated
|
||||
POP DX
|
||||
XOR AL,AL
|
||||
invoke GETBUFFR
|
||||
POP BX
|
||||
ADD BX,WORD PTR [CURBUF]
|
||||
FREESPOT:
|
||||
TEST BYTE PTR [ATTRIB],attr_volume_id
|
||||
JZ NOTVOLID
|
||||
CMP BYTE PTR [VOLID],0
|
||||
JNZ ERRPOP ; Can't create a second volume ID
|
||||
NOTVOLID:
|
||||
MOV ES,WORD PTR [CURBUF+2]
|
||||
MOV DI,BX
|
||||
MOV SI,OFFSET DOSGROUP:NAME1
|
||||
MOV CX,5
|
||||
MOVSB
|
||||
REP MOVSW
|
||||
MOV AL,[ATTRIB]
|
||||
STOSB
|
||||
MOV CL,5
|
||||
XOR AX,AX
|
||||
REP STOSW
|
||||
invoke DATE16
|
||||
XCHG AX,DX
|
||||
STOSW
|
||||
XCHG AX,DX
|
||||
STOSW
|
||||
XOR AX,AX
|
||||
PUSH DI
|
||||
STOSW
|
||||
STOSW
|
||||
STOSW
|
||||
MOV SI,WORD PTR [CURBUF]
|
||||
MOV ES:[SI.BUFDIRTY],1
|
||||
LES BP,[THISDPB]
|
||||
MOV AL,ES:[BP.dpb_drive]
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
invoke FLUSHBUF
|
||||
POP BX
|
||||
POP AX
|
||||
POP SI
|
||||
MOV AH,AL ; Get I/O driver number back
|
||||
OPENJMP:
|
||||
CLC ; Clear carry so OPEN won't fail
|
||||
POP ES
|
||||
POP DI
|
||||
ASSUME ES:NOTHING
|
||||
JMP DOOPEN
|
||||
$FCB_CREATE ENDP
|
||||
|
||||
do_ext
|
||||
|
||||
CODE ENDS
|
||||
END
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue