]>
wirehaze git hosting - MS-DOS.git/blob - v2.0/source/SYS.ASM
1 TITLE
MS-DOS SYS Program
2 ; SYS - Copies system programs IBMBIO.COM/IO.SYS and IBMDOS.COM/MSDOS.SYS
3 ; 1.6 05/21/82 Added rev number message
4 ; 1.61 06/04/82 Allow SYS to blank disk TimP at SCP
5 ; 1.70 06/30/82 NON contiguous DOS allowed on 2.00 IBM. Allows SYS to
7 ; 1.71 07/02/82 Put in CHDIRs to make sure everything done in root dir.
8 ; 1.80 04/26/83 MZ make sys work in small machines; use full 2.0 system
10 ; 1.81 07/22/83 ARR Added check in IBM version for valid FAT ID on
11 ; destination because of IBM problem with SYSing to
12 ; unformatted disks which are really formatted.
13 ; Prints NoDest message for ridic IBM reasons, should
14 ; have a better message.
30 DOSVER_LOW EQU
0136H ; Lowest acceptable DOS version number
31 DOSVER_HIGH EQU
020BH ; Highest acceptable DOS version
33 CODE SEGMENT WORD PUBLIC
36 CONST
SEGMENT BYTE PUBLIC
39 DATA SEGMENT BYTE PUBLIC
42 DG GROUP
CODE,DATA,CONST
44 DATA SEGMENT PUBLIC BYTE
46 EXTRN BADDRV
:BYTE, BADDRVLen
:WORD
47 EXTRN BADPARM
:BYTE, BADPARMLen
:WORD
48 EXTRN GETSYS
:BYTE, GETSYSLen
:WORD
50 EXTRN NODEST
:BYTE, NODESTLen
:WORD
51 EXTRN BADSIZ
:BYTE, BADSIZLen
:WORD
52 EXTRN DONE
:BYTE, DONELen
:WORD
56 EXTRN BADDISK
:BYTE, BADDISKLen
:WORD
61 BIOSName
DB "A:\IO.SYS",0
62 DOSName
DB "A:\MSDOS.SYS",0
64 IF IBMVER
OR IBMJAPVER
65 BIOSName
DB "A:\IBMBIO.COM",0
66 DOSName
DB "A:\IBMDOS.COM",0
69 BIOSInFH
DW ?
; file handle of source BIOS
70 BIOSLenLow
DW 2 DUP (?
) ; 32-bit length of BIOS
71 BIOSLenHigh
DW 2 DUP (?
) ; 32-bit length of BIOS
72 BIOSTime
DW 2 DUP (?
) ; place to store time of BIOS write
73 BIOSOutFH
DW ?
; fh of BIOS destination
75 DOSInFH
DW ?
; file handle of source DOS
76 DOSLenLow
DW 2 DUP (?
) ; 32-bit length of DOS
77 DOSLenHigh
DW 2 DUP (?
) ; 32-bit length of DOS
78 DOSTime
DW 2 DUP (?
) ; place to store time of DOS write
79 DOSOutFH
DW ?
; fh of DOS destination
83 cbBuf
DW ?
; number of bytes in buffer
84 pDOS
DW ?
; offset of beginning of DOS in buffer
85 pDOSEnd
DW ?
; offset of end of DOS in buffer
87 IF IBMVER
OR IBMJAPVER
90 LLISTBUF
DW 256 DUP (0)
96 STARTSECTOR
DW 1 DUP(?
)
99 BUF
LABEL BYTE ; beginning of area for file reads
105 ASSUME
CS:DG
,DS:DG
,ES:DG
,SS:DG
110 JMP SHORT CheckVersion
115 HEADER
DB "Vers 1.81"
117 PUSH AX ; save drive letter validity
119 INT 21H
; get dos version
120 XCHG AH,AL ; Turn it around to AH.AL
121 CMP AX,DOSVER_LOW
; is it too low?
122 JB GOTBADDOS
; yes, error
123 CMP AX,DOSVER_HIGH
; too high?
124 JBE OKDOS
; yes, go check drive letter
126 MOV DX,OFFSET DG
:BADVER
; message to dump
127 MOV AH,STD_CON_STRING_OUTPUT
; standard output device
129 INT 20H
; old style exit for compatability
131 OKDOS: POP AX ; get drive validity
132 JMP SHORT SYS
; go process
134 ERR0: MOV DX,OFFSET DG
:BADPARM
; no drive letter
138 ERR1: MOV DX,OFFSET DG
:BADDRV
; drive letter invalid
142 ERR2: MOV AL,DEFALT
; get default drive number
143 ADD AL,'A'-1 ; turn into letter
144 MOV SYSDRV
,AL ; place into middle of message
145 MOV DX,OFFSET DG
:GETSYS
146 MOV CX,GETSYSLen
; length for output
147 MOV BX,stderr
; use stderr
148 MOV AH,Write
; Ask for system disk
150 CALL GetKeystroke
; wait for him to type simething
151 XOR AL,AL ; valid drive spec now...
153 CMP DS:(BYTE PTR 5
DH)," " ; Was file specified?
154 JNZ ERR0
; yes, no files are allowed -> error
155 CMP AL,-1 ; Invalid drive spec?
156 JZ ERR1
; yes, must have valid drive -> error
157 CMP DS:(BYTE PTR 5
CH),0 ; No drive specified?
158 JZ ERR1
; yes, cannot sys to default drive error
159 MOV AH,GET_DEFAULT_DRIVE
; Get default drive
161 INC AL ; turn from phys drive to logical drive
162 MOV DEFALT
,AL ; save it for possible printing
163 CMP DS:(BYTE PTR 5
CH),AL ; did he specify the default drive?
164 JZ ERR1
; yes, default drive not allowed
166 IF IBMVER
; Check for "valid" destination
168 MOV AL,BYTE PTR DS:[5
Ch]
170 MOV BX,OFFSET DG
:BUF
; Temp space
171 MOV DX,1 ; Sector 1 (first sec of FAT)
172 MOV CX,DX ; One sector
173 INT 25H
; Read Fat sector
176 JC OKFAT
; Don't error here, let a CREATE or
177 ; some other call to the dest
178 ; generate a more useful INT 24H
180 CMP BYTE PTR [BUF
],0F8H
186 ADD AL,'A'-1 ; turn into letter
187 MOV BIOSName
,AL ; twiddle source name
188 MOV DOSName
,AL ; twiddle source name
190 MOV DX,OFFSET DG
:BIOSName
; source name
191 MOV DI,OFFSET DG
:BIOSInFH
; pointer to block of data
193 JC Err2
; not found, go and try again
194 MOV DX,OFFSET DG
:DOSName
; source of DOS
195 MOV DI,OFFSET DG
:DOSInFH
; pointer to block of data
196 CALL OpenFile
; Look for DOS
197 JC ERR2
; not there, go ask for a system disk
198 MOV CX,SP ; get lowest available spot
199 SUB CX,0200h+(OFFSET DG
:BUF
); leave room for all sorts of things
200 MOV cbBuf
,CX ; store length away
201 CALL FillMem
; load up memory with files
204 CALL READ_BOOT
; need to copy boot sector too
207 MOV AL,DS:(BYTE PTR 5
CH) ; get drive of destination
210 CALL CHECK_TRAN
; check for bootable device
211 JZ DOSWRT
; ok to boot
212 MOV DX,OFFSET DG
:BADDISK
; incorrect format to boot
214 JMP DisplayError
; go error and quit
218 ADD AL,'A'-1 ; convert to letter
219 MOV BIOSName
,AL ; point names at destination drive
221 MOV AllName
,AL ; look for any files
223 MOV AH,Find_First
; look for files
224 MOV DX,OFFSET DG
:AllName
; path of where to look
225 MOV CX,Attr_Hidden
+Attr_System
; attributes to find
227 JC PutSys
; no files - go and copy
230 MOV DL,DS:(BYTE PTR 5
CH) ; get drive number
231 MOV AH,GET_DRIVE_FREESPACE
; get free space available
233 MUL CX ; Compute size of cluster (secsiz*secperclus)
234 XCHG CX,AX ; move it to correct spot
235 MOV DX,OFFSET DG
:BIOSName
; who to open
236 MOV AX,BIOSLenLow
+2 ; get low part of size
237 MOV BX,BIOSLenHigh
+2 ; get high size
238 CALL CHKLEN
; open and snoop size
239 JNZ ERR4
; Must fit exact so MSDOS is in right place
240 MOV DX,OFFSET DG
:DOSName
; other guy to open
241 MOV AX,DOSLenLow
+2 ; get low part of size
242 MOV BX,DOSLenHigh
+2 ; get high size
243 CALL CHKLEN
; open and snoop second size
244 JA ERR4
; Must be enough (or too much) space
247 IF IBMVER
OR IBMJAPVER
248 MOV DX,OFFSET DG
:BIOSName
; open BIOS
249 MOV CX,7 ; attributes
253 Err3J: JMP Err3
; not found, go and complain
255 MOV DX,OFFSET DG
:DOSName
; open DOS
258 JC Err3J
; Not found, go complain
262 MOV DX,OFFSET DG
:BIOSName
; who to change mode
263 MOV CX,0 ; undo attributes
264 MOV AX,(ChMod
SHL 8) + 1 ; set the attributes
266 MOV DX,OFFSET DG
:DOSName
; who to change mode
267 MOV CX,0 ; undo attributes
268 MOV AX,(ChMod
SHL 8) + 1 ; set the attributes
270 MOV DX,OFFSET DG
:BIOSName
; destination of BIOS
271 MOV CX,7 ; fancy attributes
272 MOV AH,Creat
; make a new one
274 MOV BIOSOutFH
,AX ; save handle
275 MOV DX,OFFSET DG
:DOSName
; destination of DOS
276 MOV AH,Creat
; make a new one
278 MOV DOSOutFH
,AX ; save handle
280 CALL DumpMem
; flush out memory
281 MOV AX,DOSLenHigh
; more DOS?
282 OR AX,DOSLenLow
; more low dos
283 OR AX,BIOSLenHigh
; more high BIOS
284 OR AX,BIOSLenLow
; more low BIOS
285 JZ AllDone
; nope, all done
286 CALL FillMem
; reload world
289 MOV DX,OFFSET DG
:BADSIZ
293 MOV CX,BIOSTime
; get time and date
295 MOV BX,BIOSOutFH
; where to stuff the time
296 MOV AX,(File_Times
SHL 8) + 1
301 MOV CX,DOSTime
; get time and date
303 MOV BX,DOSOutFH
; where to stuff the time
304 MOV AX,(File_Times
SHL 8) + 1
309 IF IBMVER
OR IBMJAPVER
310 CALL PUTBOOT
; copy the boot sector also
313 MOV DX,OFFSET DG
:DONE
; all finished message
315 XOR AL,AL ; ok error code
319 MOV AH,Write
; convenient place to display message
323 MOV AH,EXIT
; bye and return error code
330 MOV CX,cbBuf
; get length of buffer
331 MOV BX,BIOSInFH
; get bios source handle
332 MOV DX,OFFSET DG
:BUF
; point to beginning of buffer
333 PUSH CX ; save away total length
334 CMP BIOSLenHigh
,0 ; > 64K to read?
336 CMP BIOSLenLow
,CX ; more left to read?
338 MOV CX,BIOSLenLow
; move new
341 INT 21h
; read in what we can
342 ADD DX,AX ; update pointer for DOS Read
343 MOV pDOS
,DX ; point to beginning of DOS
344 SUB BIOSLenLow
,AX ; decrement remaining
345 SBB BIOSLenHigh
,0 ; do 32 bit
346 POP CX ; get original length
347 SUB CX,AX ; this much is left
349 MOV BX,DOSInFH
; get bios source handle
350 CMP DOSLenHigh
,0 ; > 64K to read?
352 CMP DOSLenLow
,CX ; more left to read?
354 MOV CX,DOSLenLow
; move new
357 INT 21h
; read in what we can
358 ADD DX,AX ; update pointer for DOS Read
359 MOV pDOSEnd
,DX ; point to End of dos DOS
360 SUB DOSLenLow
,AX ; decrement remaining
361 SBB DOSLenHigh
,0 ; do 32 bit arithmetic
365 MOV AX,(OPEN
SHL 8) + 0 ; open for reading only
366 INT 21H
; Look for BIOS
367 retc
; not found, go and try again
368 STOSW ; stash away handle
369 MOV BX,AX ; get ready for seeks
370 MOV AX,(LSeek
SHL 8) + 2 ; seek relative to eof
371 XOR CX,CX ; zero offset
372 XOR DX,DX ; zero offset
373 INT 21h
; get offsets
374 STOSW ; save low part of size
375 STOSW ; save low part of size
377 STOSW ; save high part of size
378 STOSW ; save high part of size
379 XOR DX,DX ; zero offset
380 MOV AX,(LSeek
SHL 8) + 0 ; seek relative to beginning
382 MOV AX,(File_Times
SHL 8) + 0
383 INT 21h
; get last write times
391 MOV DX,OFFSET DG
:NODEST
396 MOV DX,OFFSET DG
:BUF
; get offset of bios start
397 MOV CX,pDOS
; beginning of next guy
398 SUB CX,DX ; difference is length
399 JZ DumpDos
; no bios to move
400 MOV BX,BIOSOutFH
; where to output
404 MOV DX,pDOS
; beginning of dos
405 MOV CX,pDOSEnd
; end of dos
406 SUB CX,DX ; difference is length
407 retz
; if zero no write
408 MOV BX,DOSOutFH
; where to output
415 ; CX has size of cluster, DX has pointer to file name
416 ; Returns with flags set on (size of file) - (size of hole)
417 PUSH AX ; old size low
418 PUSH BX ; old size high
419 PUSH CX ; old cluster size
421 MOV CX,7 ; attributes to search for
423 JC ERR3
; cannot find file, error
424 POP CX ; get cluster size back
425 MOV DX,DS:[80h
+find_buf_size_h
] ; get destination size high
426 MOV AX,DS:[80h
+find_buf_size_l
] ; get size low
427 ADD AX,CX ; add cluster size
428 ADC DX,0 ; 32 bit add
429 SUB AX,1 ; adding CLUSSIZE-1
430 SBB DX,0 ; 32 bit dec
431 DIV CX ; compute new cluster size
432 POP DX ; get old high
434 PUSH AX ; save away dividend
435 MOV AX,BX ; put into correct register
436 ADD AX,CX ; do the same as above (+CLUSSIZE-1)/CLUSSIZE
437 ADC DX,0 ; 32 bit add
438 SUB AX,1 ; adding CLUSSIZE-1
439 SBB DX,0 ; 32 bit dec
440 DIV CX ; compute old cluster size
441 POP DX ; get new size
442 CMP AX,DX ; is old >= new?
448 CALL READ_LLIST
; Get the list sector and set new boot sector
449 MOV AL,DS:(BYTE PTR 5
CH)
453 MOV BX,OFFSET DG
:BOOT
454 INT 26H
; Write out new boot sector
456 CALL WRITE_LLIST
; Make and write out new list sector
463 MOV DL,BYTE PTR DS:[5
Ch] ; Target drive
466 MOV AL,[BX+16H
] ; Media byte
474 MOV BX,OFFSET DG
:BOOT
475 MOV WORD PTR [BX+17],112 ; Set number of dir entries
476 MOV WORD PTR [BX+19],2*8*40 ; Set number of sectors
477 INC BYTE PTR [BX+21] ; Media = ff
478 INC WORD PTR [BX+26] ; Number of heads = 2
481 MOV AL,BYTE PTR DS:[5
Ch]
483 MOV BX,OFFSET DG
:BOOT
; Boot sector
487 INT 26H
; Write out 8 sector boot sector
498 MOV BX,OFFSET DG
:BOOT
501 MOV AX,[BOOT
+108H
] ; Get old first sector of data
506 MOV AL,DS:(BYTE PTR 5
CH)
510 MOV BX,OFFSET DG
:LLISTBUF
518 SUB AX,[RELOC
] ; True reloc factor
519 MOV CL,BYTE PTR [LLISTBUF
+0CH] ; Number of entries needing reloc
522 MOV BX,OFFSET DG
:LLISTBUF
+ 10H
524 ADD WORD PTR [BX+2],AX
528 MOV AL,DS:(BYTE PTR 5
CH)
531 MOV BX,OFFSET DG
:LLISTBUF
537 ; All registers preserved. Returns zero if SYS OK, NZ if SYS FAIL
538 ; AL is drive (1=A,...) AL=0 is not valid
546 MOV AX,[BX.dpb_first_sector
] ; Get new first sector of data
547 MOV BH,[BX.dpb_media
]
550 MOV [BOOT
+108H
],AX ; Set new start of data in boot
554 INT 11H
; IBM EQUIP CALL
561 INC AL ; AL is now MAX floppy #
564 JBE CHECK_FLOP
; Is a floppy
565 XOR BL,BL ; Is Hard file
570 CMP BH,0FBH ; Only floppy that boots
576 MOV AX,(Std_CON_Input_Flush
SHL 8) + Std_CON_Input_No_Echo
578 MOV AX,(Std_CON_Input_Flush
SHL 8) + 0