summaryrefslogtreecommitdiff
path: root/v2.0/source/SYS.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/SYS.ASM')
-rw-r--r--v2.0/source/SYS.ASM587
1 files changed, 587 insertions, 0 deletions
diff --git a/v2.0/source/SYS.ASM b/v2.0/source/SYS.ASM
new file mode 100644
index 0000000..e15758e
--- /dev/null
+++ b/v2.0/source/SYS.ASM
@@ -0,0 +1,587 @@
1TITLE 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
6; 1.0 1.1 disks.
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
9; calls
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.
15
16FALSE EQU 0
17TRUE EQU NOT FALSE
18
19IBMJAPVER EQU FALSE
20IBMVER EQU FALSE
21MSVER EQU TRUE
22
23.xlist
24.xcref
25 INCLUDE DOSSYM.ASM
26.cref
27.list
28
29
30DOSVER_LOW EQU 0136H ; Lowest acceptable DOS version number
31DOSVER_HIGH EQU 020BH ; Highest acceptable DOS version
32
33CODE SEGMENT WORD PUBLIC
34CODE ENDS
35
36CONST SEGMENT BYTE PUBLIC
37CONST ENDS
38
39DATA SEGMENT BYTE PUBLIC
40DATA ENDS
41
42DG GROUP CODE,DATA,CONST
43
44DATA SEGMENT PUBLIC BYTE
45
46 EXTRN BADDRV:BYTE, BADDRVLen:WORD
47 EXTRN BADPARM:BYTE, BADPARMLen:WORD
48 EXTRN GETSYS:BYTE, GETSYSLen:WORD
49 EXTRN SYSDRV:BYTE
50 EXTRN NODEST:BYTE, NODESTLen:WORD
51 EXTRN BADSIZ:BYTE, BADSIZLen:WORD
52 EXTRN DONE:BYTE, DONELen:WORD
53 EXTRN BADVER:BYTE
54
55 IF IBMJAPVER
56 EXTRN BADDISK:BYTE, BADDISKLen:WORD
57 ENDIF
58
59DEFALT DB 0
60 IF MSVER
61BIOSName DB "A:\IO.SYS",0
62DOSName DB "A:\MSDOS.SYS",0
63 ENDIF
64 IF IBMVER OR IBMJAPVER
65BIOSName DB "A:\IBMBIO.COM",0
66DOSName DB "A:\IBMDOS.COM",0
67 ENDIF
68
69BIOSInFH DW ? ; file handle of source BIOS
70BIOSLenLow DW 2 DUP (?) ; 32-bit length of BIOS
71BIOSLenHigh DW 2 DUP (?) ; 32-bit length of BIOS
72BIOSTime DW 2 DUP (?) ; place to store time of BIOS write
73BIOSOutFH DW ? ; fh of BIOS destination
74
75DOSInFH DW ? ; file handle of source DOS
76DOSLenLow DW 2 DUP (?) ; 32-bit length of DOS
77DOSLenHigh DW 2 DUP (?) ; 32-bit length of DOS
78DOSTime DW 2 DUP (?) ; place to store time of DOS write
79DOSOutFH DW ? ; fh of DOS destination
80
81AllName DB "A:\*.*",0
82
83cbBuf DW ? ; number of bytes in buffer
84pDOS DW ? ; offset of beginning of DOS in buffer
85pDOSEnd DW ? ; offset of end of DOS in buffer
86
87 IF IBMVER OR IBMJAPVER
88BOOT DW 256 DUP (0)
89 IF IBMJAPVER
90LLISTBUF DW 256 DUP (0)
91 ENDIF
92 ENDIF
93
94 IF IBMJAPVER
95RELOC DW 1 DUP(?)
96STARTSECTOR DW 1 DUP(?)
97 ENDIF
98
99BUF LABEL BYTE ; beginning of area for file reads
100
101DATA ENDS
102
103CODE SEGMENT PUBLIC
104
105 ASSUME CS:DG,DS:DG,ES:DG,SS:DG
106
107 ORG 100H
108
109Start:
110 JMP SHORT CheckVersion
111
112 IF IBMVER
113 DW OFFSET DG:BOOT
114 ENDIF
115HEADER DB "Vers 1.81"
116CheckVersion:
117 PUSH AX ; save drive letter validity
118 MOV AH,GET_VERSION
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
125GOTBADDOS:
126 MOV DX,OFFSET DG:BADVER ; message to dump
127 MOV AH,STD_CON_STRING_OUTPUT ; standard output device
128 INT 21H
129 INT 20H ; old style exit for compatability
130
131OKDOS: POP AX ; get drive validity
132 JMP SHORT SYS ; go process
133
134ERR0: MOV DX,OFFSET DG:BADPARM ; no drive letter
135 MOV CX,BadParmLen
136 JMP DisplayError
137
138ERR1: MOV DX,OFFSET DG:BADDRV ; drive letter invalid
139 MOV CX,BadDrvLen
140 JMP DisplayError
141
142ERR2: 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
149 INT 21H
150 CALL GetKeystroke ; wait for him to type simething
151 XOR AL,AL ; valid drive spec now...
152SYS:
153 CMP DS:(BYTE PTR 5DH)," " ; 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 5CH),0 ; No drive specified?
158 JZ ERR1 ; yes, cannot sys to default drive error
159 MOV AH,GET_DEFAULT_DRIVE ; Get default drive
160 INT 21H
161 INC AL ; turn from phys drive to logical drive
162 MOV DEFALT,AL ; save it for possible printing
163 CMP DS:(BYTE PTR 5CH),AL ; did he specify the default drive?
164 JZ ERR1 ; yes, default drive not allowed
165
166 IF IBMVER ; Check for "valid" destination
167 PUSH AX
168 MOV AL,BYTE PTR DS:[5Ch]
169 DEC AL
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
174 POP AX ; Flags
175 POP AX ; Real AX
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
179 ; error
180 CMP BYTE PTR [BUF],0F8H
181 JAE OKFAT
182 JMP ERR3
183OKFAT:
184 ENDIF
185
186 ADD AL,'A'-1 ; turn into letter
187 MOV BIOSName,AL ; twiddle source name
188 MOV DOSName,AL ; twiddle source name
189 CLD
190 MOV DX,OFFSET DG:BIOSName ; source name
191 MOV DI,OFFSET DG:BIOSInFH ; pointer to block of data
192 CALL OpenFile
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
202
203 IF IBMJAPVER
204 CALL READ_BOOT ; need to copy boot sector too
205 ENDIF
206
207 MOV AL,DS:(BYTE PTR 5CH) ; get drive of destination
208
209 IF IBMJAPVER
210 CALL CHECK_TRAN ; check for bootable device
211 JZ DOSWRT ; ok to boot
212 MOV DX,OFFSET DG:BADDISK ; incorrect format to boot
213 MOV CX,BadDiskLen
214 JMP DisplayError ; go error and quit
215DOSWRT:
216 ENDIF
217
218 ADD AL,'A'-1 ; convert to letter
219 MOV BIOSName,AL ; point names at destination drive
220 MOV DOSName,AL
221 MOV AllName,AL ; look for any files
222
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
226 INT 21H
227 JC PutSys ; no files - go and copy
228
229 IF MSVER
230 MOV DL,DS:(BYTE PTR 5CH) ; get drive number
231 MOV AH,GET_DRIVE_FREESPACE ; get free space available
232 INT 21H
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
245 ENDIF
246
247 IF IBMVER OR IBMJAPVER
248 MOV DX,OFFSET DG:BIOSName ; open BIOS
249 MOV CX,7 ; attributes
250 MOV AH,Find_First
251 INT 21H
252 JNC FindDos
253Err3J: JMP Err3 ; not found, go and complain
254FindDos:
255 MOV DX,OFFSET DG:DOSName ; open DOS
256 MOV AH,Find_First
257 INT 21H
258 JC Err3J ; Not found, go complain
259 ENDIF
260
261PUTSYS:
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
265 INT 21h
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
269 INT 21h
270 MOV DX,OFFSET DG:BIOSName ; destination of BIOS
271 MOV CX,7 ; fancy attributes
272 MOV AH,Creat ; make a new one
273 INT 21h
274 MOV BIOSOutFH,AX ; save handle
275 MOV DX,OFFSET DG:DOSName ; destination of DOS
276 MOV AH,Creat ; make a new one
277 INT 21h
278 MOV DOSOutFH,AX ; save handle
279Copy:
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
287 JMP Copy
288ERR4:
289 MOV DX,OFFSET DG:BADSIZ
290 MOV CX,BadSizLen
291 JMP DisplayError
292AllDone:
293 MOV CX,BIOSTime ; get time and date
294 MOV DX,BIOSTime+2
295 MOV BX,BIOSOutFH ; where to stuff the time
296 MOV AX,(File_Times SHL 8) + 1
297 INT 21h
298 MOV AH,Close
299 INT 21h
300
301 MOV CX,DOSTime ; get time and date
302 MOV DX,DOSTime+2
303 MOV BX,DOSOutFH ; where to stuff the time
304 MOV AX,(File_Times SHL 8) + 1
305 INT 21h
306 MOV AH,Close
307 INT 21h
308
309 IF IBMVER OR IBMJAPVER
310 CALL PUTBOOT ; copy the boot sector also
311 ENDIF
312
313 MOV DX,OFFSET DG:DONE ; all finished message
314 MOV CX,DoneLen
315 XOR AL,AL ; ok error code
316SERROR:
317 PUSH AX
318 MOV BX,stderr
319 MOV AH,Write ; convenient place to display message
320 INT 21H
321 POP AX
322ErrorExit:
323 MOV AH,EXIT ; bye and return error code
324 INT 21h
325
326DisplayError:
327 MOV AL,1
328 JMP SERROR
329FillMem:
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?
335 JA UseCX ; use CX
336 CMP BIOSLenLow,CX ; more left to read?
337 JA UseCX ; use CX
338 MOV CX,BIOSLenLow ; move new
339UseCX:
340 MOV AH,Read
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
348
349 MOV BX,DOSInFH ; get bios source handle
350 CMP DOSLenHigh,0 ; > 64K to read?
351 JA UseCXDOS ; use CX
352 CMP DOSLenLow,CX ; more left to read?
353 JA UseCXDOS ; use CX
354 MOV CX,DOSLenLow ; move new
355UseCXDOS:
356 MOV AH,Read
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
362 return
363
364OpenFile:
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
376 MOV AX,DX
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
381 INT 21h
382 MOV AX,(File_Times SHL 8) + 0
383 INT 21h ; get last write times
384 MOV AX,CX
385 STOSW ; save time
386 MOV AX,DX
387 STOSW ; save date
388 return
389
390ERR3:
391 MOV DX,OFFSET DG:NODEST
392 MOV CX,NoDestLen
393 JMP DisplayError
394
395DumpMem:
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
401 MOV AH,Write
402 INT 21h ; wham
403DumpDos:
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
409 MOV AH,Write
410 INT 21h ; wham
411 ret
412
413 IF MSVER
414CHKLEN:
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
420 MOV AH,Find_First
421 MOV CX,7 ; attributes to search for
422 INT 21H
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
433 POP BX ; get old low
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?
443 return
444 ENDIF
445
446 IF IBMJAPVER
447PUTBOOT:
448 CALL READ_LLIST ; Get the list sector and set new boot sector
449 MOV AL,DS:(BYTE PTR 5CH)
450 DEC AL ; A=0
451 MOV CX,1
452 XOR DX,DX
453 MOV BX,OFFSET DG:BOOT
454 INT 26H ; Write out new boot sector
455 POPF
456 CALL WRITE_LLIST ; Make and write out new list sector
457 RET
458 ENDIF
459
460 IF IBMVER
461PUTBOOT:
462 MOV AH,GET_DPB
463 MOV DL,BYTE PTR DS:[5Ch] ; Target drive
464 INT 21H
465ASSUME DS:NOTHING
466 MOV AL,[BX+16H] ; Media byte
467 PUSH CS
468 POP DS
469ASSUME DS:DG
470 CMP AL,0FEH
471 JB RET1
472 TEST AL,1
473 JZ GOTBOOT
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
479
480GOTBOOT:
481 MOV AL,BYTE PTR DS:[5Ch]
482 DEC AL
483 MOV BX,OFFSET DG:BOOT ; Boot sector
484 XOR DX,DX ; Sector 0
485 MOV CX,DX
486 INC CX ; One sector
487 INT 26H ; Write out 8 sector boot sector
488 POP AX ; Flags
489RET1: RET
490 ENDIF
491
492 IF IBMJAPVER
493READ_BOOT:
494 MOV AL,[DEFALT]
495 DEC AL ; A=0
496 MOV CX,1
497 XOR DX,DX
498 MOV BX,OFFSET DG:BOOT
499 INT 25H
500 POPF
501 MOV AX,[BOOT+108H] ; Get old first sector of data
502 MOV [RELOC],AX
503 RET
504
505READ_LLIST:
506 MOV AL,DS:(BYTE PTR 5CH)
507 DEC AL ; A=0
508 MOV CX,1
509 MOV DX,[STARTSECTOR]
510 MOV BX,OFFSET DG:LLISTBUF
511 INT 25H
512 POPF
513 RET
514
515WRITE_LLIST:
516 MOV AX,[STARTSECTOR]
517 MOV DX,AX
518 SUB AX,[RELOC] ; True reloc factor
519 MOV CL,BYTE PTR [LLISTBUF+0CH] ; Number of entries needing reloc
520 XOR CH,CH
521 JCXZ NO_RELOCS
522 MOV BX,OFFSET DG:LLISTBUF + 10H
523RELLOOP:
524 ADD WORD PTR [BX+2],AX
525 ADD BX,10H
526 LOOP RELLOOP
527NO_RELOCS:
528 MOV AL,DS:(BYTE PTR 5CH)
529 DEC AL ; A=0
530 MOV CX,1
531 MOV BX,OFFSET DG:LLISTBUF
532 INT 26H
533 POPF
534 RET
535
536CHECK_TRAN:
537; All registers preserved. Returns zero if SYS OK, NZ if SYS FAIL
538; AL is drive (1=A,...) AL=0 is not valid
539
540 PUSH BX
541 PUSH AX
542 PUSH DS
543 MOV DL,AL
544 MOV AH,GET_DPB
545 INT 21H
546 MOV AX,[BX.dpb_first_sector] ; Get new first sector of data
547 MOV BH,[BX.dpb_media]
548 POP DS
549 MOV [STARTSECTOR],AX
550 MOV [BOOT+108H],AX ; Set new start of data in boot
551 POP AX
552 PUSH AX
553 MOV BL,AL
554 INT 11H ; IBM EQUIP CALL
555 ROL AL,1
556 ROL AL,1
557 AND AL,3
558 JNZ NOT_SINGLE
559 INC AL
560NOT_SINGLE:
561 INC AL ; AL is now MAX floppy #
562 CMP BL,AL
563 POP AX
564 JBE CHECK_FLOP ; Is a floppy
565 XOR BL,BL ; Is Hard file
566 POP BX
567 RET
568
569CHECK_FLOP:
570 CMP BH,0FBH ; Only floppy that boots
571 POP BX
572 RET
573 ENDIF
574
575GetKeystroke:
576 MOV AX,(Std_CON_Input_Flush SHL 8) + Std_CON_Input_No_Echo
577 INT 21H
578 MOV AX,(Std_CON_Input_Flush SHL 8) + 0
579 INT 21H
580
581 return
582
583CODE ENDS
584 END START
585
586
587 \ No newline at end of file