]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/SYS/SYS1.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / SYS / SYS1.ASM
1 TITLE SYS-1- Program
2 INCLUDE SYSHDR.INC
3 include version.inc
4 page 80,132
5
6 false = 0
7
8 DATA SEGMENT PARA PUBLIC
9
10 public TargDrvNum, TargSpec, bio_owns_it, DOS_VER
11 public packet, packet_sectors, packet_buffer
12 extrn THIS_DPB:dword, BUF:word, DIR_SECTOR:word, first_dir_sector:word
13
14 ; $SALUT (4,25,30,41)
15
16 DOS_VER DB 0 ; DOS Version - 0 = current
17 ; 1 = 3.2 or 3
18 DEFALT DB 0 ; Default Drive (source - NUMBER
19 TargDrvNum DB 0 ; Target Drive (destination) - NUMBER
20 TargDrv DB 0 ; Target Drive (destination) - LETTER
21 TargSpec DB "A:\",0 ; z string for target name
22 IF IBMCOPYRIGHT
23 BIOSName DB "A:\IBMBIO.COM",0 ; z string for target name
24 DOSName DB "A:\IBMDOS.COM",0 ; z string for target name
25 ELSE
26 BIOSName DB "A:\IO.SYS",0
27 DOSName DB "A:\MSDOS.SYS",0
28 ENDIF
29
30 SourceBIOSName LABEL WORD
31 SourceSpec DB "A:"
32 DB 53 dup (0)
33 IF IBMCOPYRIGHT
34 SourceBIOS DB "\IBMBIO.COM",0
35 ELSE
36 SourceBIOS DB "\IO.SYS",0
37 ENDIF
38
39 IF IBMCOPYRIGHT
40 NameLen equ $ - SourceBios
41 ELSE
42 BiosNameLen equ $ - SourceBios
43 ENDIF
44
45 SourceDOSName DB "A:"
46 DB 53 dup (0)
47 IF IBMCOPYRIGHT
48 SourceDOS DB "\IBMDOS.COM",0
49 ELSE
50 SourceDOS DB "\MSDOS.SYS",0
51 ENDIF
52
53 IF IBMCOPYRIGHT
54 ELSE
55 DosNameLen equ $ - SourceDOS
56 ENDIF
57
58 SourceSize dw 2
59 Spec_flag db 0
60
61 IBMBIO_LOW DW 0 ;length of IBMBIO on disk
62 IBMBIO_HIGH DW 0
63 IBMDOS_LOW DW 0 ;length of old IBMDOS on disk
64 IBMDOS_HIGH DW 0
65
66 SIZE_OLD_HIGH DW 0
67 SIZE_OLD_LOW DW 0
68
69 NEWBIO_SIZE_LOW DW 0
70 NEWBIO_SIZE_HIGH DW 0
71 NEWDOS_SIZE_LOW DW 0
72 NEWDOS_SIZE_HIGH DW 0
73
74
75 Need_Clusters dw 0
76 Bytes_Per_Cluster dw 0
77 Number_Free_Clusters dw 0
78
79 ; $SALUT (4,9,17,41)
80 ;---------------------------------------
81 ; SRORAGE FOR COMMAND LINE PARAMETERS
82 ;---------------------------------------
83
84 PARMS LABEL WORD
85 DW OFFSET PARMSX ; POINTER TO PARMS STRUCTURE
86 DB 0 ; NO DELIMITER LIST FOLLOWS
87 DB 0 ; NUMBER OF ADDITIONAL DELIMITERS
88
89 ;---------------------------------------
90 ; STRUCTURE TO DEFINE SYS SYNTAX REQUIREMENT
91 ;---------------------------------------
92
93 PARMSX LABEL BYTE
94 PAR_MIN DB 1 ; MINIMUM POSITIONAL PARAMETERS = 1 ;AC021;
95 DB 2 ; MAXIMUM PARAMETERS = 2 ;AC021;
96 DW OFFSET POS1 ; POINTER TO POSITIONAL DEFINITION
97 DW OFFSET POS1 ; POINTER TO SAME POSITIONAL DEFINITION;AC021;
98 DB 0 ; THERE ARE NO SWITCHES
99 DB 0 ; THERE ARE NO KEYWORDS IN PRINT SYNTAX
100
101 ;---------------------------------------
102 ; STRUCTURE TO DEFINE THE POSITIONAL PARAMETER (Drive ID)
103 ;---------------------------------------
104
105 POS1 LABEL WORD
106 POSREP DB reqd ; MATCH FLAG LOW ;AC021;
107 POSTYP DB f_spec + drv_id ; MATCH FLAG HIGH ;AC021;
108 DW 0001H ; CAPS BY FILE TABLE
109 DW OFFSET POS_BUFF ; PLACE RESULT IN POSITIONAL BUFFER
110 DW OFFSET NOVALS ; NO VALUES LIST REQUIRED
111 DB 0 ; NO KEYWORDS
112
113 reqd equ 0
114 f_spec equ 2
115 drv_id equ 1
116 ;---------------------------------------
117 ; VALUE LIST FOR POSITIONAL
118 ;---------------------------------------
119
120 NOVALS LABEL WORD
121 DB 0 ; NO VALUES
122
123 ; $SALUT (4,25,30,41)
124
125 ;---------------------------------------
126 ; RETURN BUFFER FOR POSITIONAL INFORMATION
127 ;---------------------------------------
128 POS_BUFF LABEL BYTE
129 POS_TYPE DB ? ; TYPE RETURNED
130 POS_ITEM_TAG DB ? ; SPACE FOR ITEM TAG
131 POS_SYN DW ? ; POINTER TO LIST ENTRY
132 POS_OFF LABEL WORD
133 POS_DRV_ID DB ? ; SPACE FOR DRIVE NUMBER (1=A, 2=B, ect)
134 DB ? ; ;AC021;
135 POS_SEG DW ? ; ;AC021;
136
137
138 failopen equ 0 ; extended open 'does not exist action
139 openit equ 1 ; extended open 'exists' action
140 replaceit equ 2 ; extended open 'exists' action - replace
141
142 OPEN_PARMS label dword
143
144 open_off dw ? ; name pointer offset
145 open_seg dw ? ; name pointer segment
146
147 PACKET dw 0,0 ; CONTROL PACKET ;AN001;
148 packet_sectors dw 0 ; COUNT ;AN001;
149 PACKET_BUFFER dw 0,0 ; BUFFER ADDRESS ;AN001;
150
151 ;---------------------------------------
152 ; Buffer for IOCtl Get/Set Media
153 ;---------------------------------------
154
155 IOCTL_BUF LABEL BYTE
156
157 IOCtl_Level DW 0 ; INFO LEVEL (SET ON INPUT)
158 IOCtl_Ser_No_Low DW ? ; SERIAL #
159 IOCtl_Ser_No_Hi DW ? ; SERIAL #
160 IOCtl_Vol_ID DB "NO NAME " ; VOLUME LABEL - 11 bytes
161 IOCTL_File_Sys DB 8 DUP(' ') ; FILE SYSTEM TYPE
162
163 IOCTL_Ser_Vol_Sys equ $ - IOCtl_Ser_No_Low
164 file_sys_size equ $ - IOCtl_File_Sys
165
166 File_Sys_End LABEL WORD
167
168 db 0 ; safety
169
170 fat_12 DB "FAT12 " ; 12 bit FAT
171 FAT_len equ $ - fat_12
172 fat_16 DB "FAT16 " ; 16 or 32 bit FAT
173
174 ;---------------------------------------
175 ; SUBLIST for Message call
176 ;---------------------------------------
177
178 .xlist
179 include sysmsg.inc
180
181 MSG_UTILNAME <SYS> ; ;AN000;
182
183 MSG_SERVICES <MSGDATA> ; ;AN000;
184 .list
185
186 SUBLIST LABEL DWORD
187
188 DB sub_size ; size of sublist
189 DB 0 ; reserved
190 insert_ptr_off DW ? ; pointer to insert - offset
191 insert_ptr_seg DW ? ; pointer to insert - segment
192 insert_number DB 1 ; number of insert
193 DB Char_Field_ASCIIZ ;type flag
194 insert_max DB 3 ; maximum field size (limited to 3)
195 ; - this handles - SYS
196 ; - and - D:\
197 DB 1 ; minimum field size
198 DB " " ; pad character
199
200 sub_size equ $ - SUBLIST ; size of sublist
201
202 sys_ptr db "SYS",0
203
204 bio_owns_it db 0
205 EntryFree db 0 ; for create file
206
207 ;*** WARNING ***
208 ; KEEP THE FOLLOWING ITEMS IN THE EXACT ORDER BELOW!!!
209 DOSEntFree DB 1
210 BIOSEntFree DB 1
211
212 Xfer_data STRUC
213
214 InFH DW ? ; file handle of source
215 LenLow DW ? ; 32-bit length of source
216 LenHigh DW ?
217 FTime DW ? ; place to store time of write
218 FDate DW ? ; place to store date of write
219 OutFH DW ? ; fh of destination
220
221 Xfer_data ENDS
222
223 BIOSInFH DW ? ; file handle of source BIOS
224 BIOSLenLow DW ? ; 32-bit length of BIOS
225 BIOSLenHigh DW ?
226 BIOSTime DW 2 DUP (?) ; place to store time of BIOS write
227 BIOSOutFH DW ? ; fh of BIOS destination
228 BIOSPos dw 0,0 ;AN001;lseek position into file
229
230 DOSInFH DW ? ; file handle of source DOS
231 DOSLenLow DW ? ; 32-bit length of DOS
232 DOSLenHigh DW ?
233 DOSTime DW 2 DUP (?) ; place to store time of DOS write
234 DOSOutFH DW ? ; fh of DOS destination
235 DOSPos dw 0,0 ;AN001;lseek position into file
236
237 IF IBMCOPYRIGHT
238 FCBDOS DB "IBMDOS COM"
239 FCBBIO DB "IBMBIO COM"
240 ELSE
241 FCBDOS DB "MSDOS SYS"
242 FCBBIO DB "IO SYS"
243 ENDIF
244
245 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; The following is a Extended FCB
246 ExtFCB db 0FFh
247 db 5 dup (0)
248 db DOS_volume_atrib
249 ExtFCB_Drive db 0
250 ExtFCB_Name db "???????????"
251 db 24 dup (0)
252 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
253
254 DOS_BUFFER DB 80h DUP (?)
255 cbBuf DW ? ; number of bytes in buffer
256 pDOS DW ? ; offset of beginning of DOS in buffer
257 pDOSEnd DW ? ; offset of end of DOS in buffer
258
259
260 public boot
261 BOOT LABEL BYTE
262 .xlist
263 INCLUDE BOOT.INC
264 .list
265 ;
266 ; Following structure used by Generic IOCTL call Get Device Parameters to get
267 ; the BPB of a hard disk. It 'overflows' into area of BUF.
268 ;
269 DeviceParameters a_DeviceParameters <1,DEV_HARDDISK>
270
271 DATA ENDS
272
273 CODE SEGMENT PARA PUBLIC
274
275 EXTRN SYSLOADMSG:near, SYSDISPMSG:near, SYSPARSE:near
276 EXTRN Data_Space:WORD, Find_DPB:near,
277 EXTRN Move_DIR_Entry:near, Free_Cluster:near, Direct_Access:near
278
279 BREAK <SYS - Main>
280 ;******************* START OF SPECIFICATIONS ***********************************
281 ;Routine name: Main
282 ;*******************************************************************************
283 ;
284 ;Description: Main control routine. Subroutines are structured so that they
285 ; will pass back an error return code (message number) and set
286 ; the fail flag (CF) if there was a fatal error.
287 ;
288 ; NOTES:
289 ;
290 ; 1 - This program uses its own internal stack. The stack space provided
291 ; by DOS is used as an input buffer for transfering IBMBIO and IBMDOS.
292 ;
293 ; SYS is linked with the CODE segment followed by the DATA segment. The
294 ; last symbol in DATA is BUF. It marks the end end of data and the
295 ; start of the BUFfer. The BUFfer extends from here to SP. The first
296 ; 6.5Kb (13 sectors) in BUFfer are used for up to 12 sectors of the FAT
297 ; or the directory. In Main, the remaining space is set
298 ; as follows:
299 ; cdBuf = SP - ( FAT_BUF + BUF )
300 ;
301 ; 2 - The main line program calls 1 routine that loops until specific
302 ; requirements are met. It is:
303 ; Get_System_Files - if default drive has replaceable
304 ; media this routine loops until
305 ; a diskette with the correct system
306 ; files is inserted.
307 ;
308 ; 3 - Great effort is expended to keep the number of open files to a minimum.
309 ; This is required in case output is directed to NULL. (See DOS 4.00
310 ; PTR P71)
311 ;
312 ;Called Procedures: Init_Input_Output
313 ; Validate_Target_Drive
314 ; Get_System_Files
315 ; Check_SYS_Conditions
316 ; Do_SYS
317 ; Message
318 ;
319 ;Input: Command line input in PSP
320 ;
321 ;Ouput: no error - System transfered to target media
322 ; error - Appropriate error message displayed
323 ;
324 ;Change History: Created 5/01/87 FG
325 ;
326 ;******************* END OF SPECIFICATIONS *************************************
327 ;******************+ START OF PSEUDOCODE +**************************************
328 ;
329 ; START Main
330 ;
331 ; setup messages and parsing (CALL Init_Input_Output)
332 ; if there is no error and
333 ; verify target drive is valid (CALL Validate_Target_Drive)
334 ; if there is no error and
335 ; get system files loaded (CALL Get_System_Files)
336 ; if there is no error and
337 ; verify target drive is SYSable (Check_SYS_Conditions)
338 ; if there is no error and
339 ; perform SYS operation (CALL Do_SYS)
340 ; if no error and
341 ; clean up loose ends (CALL Do_End)
342 ; if no error
343 ; load return code (System transfered)
344 ; endif
345 ; display message (CALL Message)
346 ; ret
347 ;
348 ; END Main
349 ;
350 ;******************- END OF PSEUDOCODE -**************************************
351
352 ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
353
354 ORG 80H
355
356 PSP_PRAM DB 128 DUP(?)
357
358 START: JMP BEGIN
359
360 DB " - SYS - Utility "
361 DB 01Ah
362
363 even
364
365 db 510 dup(0) ; stack
366
367 EOS EQU BYTE PTR $
368
369 DW 0 ; RETURN OFFSET
370
371
372 public Begin
373
374 BEGIN PROC NEAR
375
376 ; $SALUT (4,4,9,41)
377
378 mov ax,OFFSET Data_Space
379 add ax,15 ; round up to next segment
380 mov cl,4 ; convert to segment value
381 shr ax,cl
382 mov cx,ds
383 add ax,cx ; generate DATA segment value
384 mov ds,ax
385
386 ASSUME DS:DATA,ES:NOTHING
387
388 mov cx,sp ; get lowest available spot
389 mov sp,OFFSET EOS ; set up internal stack
390 sub cx,FAT_BUF + (OFFSET BUF) ; leave room for:
391 ; CODE +
392 ; DATA +
393 ; FAT_BUF (12 sectors of FAT)
394
395 mov cbBuf,cx ; store length of Xfer buffer
396
397 mov dx,OFFSET DOS_BUFFER ; set up DTA
398 mov ah,SET_DMA
399 INT 21h
400
401 call Init_Input_Output ; setup messages and parsing ;AN000;
402
403 ; $if nc,and ; there is no error and ;AN000;
404 JC $$IF1
405
406 call Validate_Target_Drive ; verify target drive is valid ;AN000;
407
408 ; $if nc,and ; there is no error ;AN000;
409 JC $$IF1
410
411 call Get_System_Files ; get system files loaded ;AN000;
412
413 ; $if nc,and ; there is no error ;AN000;
414 JC $$IF1
415
416 call Check_SYS_Conditions ; verify target drive is SYSable ;AN000;
417
418 ; $if nc,and ; there is no error ;AN000;
419 JC $$IF1
420
421 call Do_SYS ; perform SYS operation ;AN000;
422
423 ; $if nc,and ; no error and ;AN000;
424 JC $$IF1
425
426 call Do_End ; clean up loose ends ;AN000;
427
428 ; $if nc ; no error ;AN000;
429 JC $$IF1
430
431 mov ax,(util_B shl 8) + done ; load return code (System transfered) ;AN000;
432
433 ; $endif ; ;AN000;
434 $$IF1:
435
436 call Message ; display message ;AN000;
437
438 mov ah,exit ; just set function - RC set by MAIN
439 int 21h ; if version is < DOS 2.0 the int 21
440
441 ret ; ret if version < 2.00
442
443 BEGIN ENDP
444
445 BREAK <SYS - Init_Input_Output >
446 ;******************* START OF SPECIFICATIONS ***********************************
447 ;Routine name: Init_Input_Output
448 ;*******************************************************************************
449 ;
450 ;Description: Initialize messages and Parse command line.
451 ;
452 ;Called Procedures: Preload_Messages
453 ; Parse_Command_Line
454 ;
455 ;Input: PSP command line at 81h and length at 80h
456 ;
457 ;Output: no error - CF = 0 AX = 0
458 ; error - CF = 1 AX = return code (message #)
459 ;
460 ;Change History: Created 5/01/87 FG
461 ;
462 ;******************* END OF SPECIFICATIONS *************************************
463 ;******************+ START OF PSEUDOCODE +**************************************
464 ;
465 ; START Init_Input_Output
466 ;
467 ; load messages (CALL Preload_Messages)
468 ; if no error
469 ; get DOS version
470 ; if not = current and
471 ; set not current flag
472 ; if not = current - 1
473 ; load incorrect DOS version message
474 ; set fail flag
475 ; else
476 ; if no error and
477 ; parse the saved command line (CALL Parse_Command_Line)
478 ; if no error
479 ; load return code (success)
480 ; endif
481 ; endif
482 ; endif
483 ; ret
484 ;
485 ; END Init_Input_Output
486 ;
487 ;******************- END OF PSEUDOCODE -**************************************
488
489 public Init_Input_Output
490
491 Init_Input_Output PROC NEAR
492
493 call SysLoadMsg ; preload all error messages ;AN000;
494
495 ; $if c ; if error - set to Utility ;AN000;
496 JNC $$IF3
497 mov ah,0bh ; ;AN000;
498 ; $else ; ;AN019;
499 JMP SHORT $$EN3
500 $$IF3:
501 mov ax,(GET_VERSION shl 8) ; ;AN019;
502 int 21h ; ;AN019;
503 xchg al,ah ; ;AN019;
504 cmp ax,(major_version shl 8) + minor_version ; ;AN019;
505 ; $if ne ; ;AN019;
506 JE $$IF5
507 mov DOS_VER,0ffh ; keep track that DOS is down a level ;AN019;
508 ; 0 = current (default)
509 ; $endif ; ff = down one level ;AN021;
510 $$IF5:
511 ; $if be,and ; ;AN019;
512 JNBE $$IF7
513 cmp ax,DOS_low ; ;AC023;
514 ; $if ae ; ;AN019;
515 JNAE $$IF7
516
517
518
519 cmp ax,(3 shl 8) + 40 ;;;; to
520 ; $if e ;;;; cover
521 JNE $$IF8
522 mov DOS_VER,0 ;;;; 4.00
523 ; $endif ;;;; this must be remover
524 $$IF8:
525
526
527
528
529 clc ; ;AN019;
530 ; $else ; ;AN019;
531 JMP SHORT $$EN7
532 $$IF7:
533 mov ax,(util shl 8) + DOS_error ; ;AN019;
534 stc ; ;AN019;
535 ; $endif ; ;AN019;
536 $$EN7:
537
538 ; $if nc,and ; no error and ;AN000;
539 JC $$IF12
540
541 xor cx,cx ; zero out # of parms processed so far ;AN000;
542 mov si,command_line ; move here to loop thru twice ;AN000;
543 call Parse_Command_Line ; parse the saved command line ;AN000;
544
545 ; $if nc ; no error ;AN000;
546 JC $$IF12
547
548 mov al,noerror ; load return code (success) ;AN000;
549
550 ; $endif ; ;AN000;
551 $$IF12:
552 ; $endif ; ;AC019;
553 $$EN3:
554
555 ret ; ;AN000;
556
557 ENDPROC Init_Input_Output
558
559 BREAK <SYS - Parse_Command_Line >
560 ;******************* START OF SPECIFICATIONS ***********************************
561 ;Routine name: Parse_Command_Line
562 ;*******************************************************************************
563 ;
564 ;Description: Parse the command line. Check for errors, loading return code and
565 ; setting fail flag if found. Use parse error messages except in
566 ; case of no parameters, which has its own message.
567 ;
568 ;Called Procedures: SysParse
569 ;
570 ;Input: None
571 ;
572 ;Output: no error - CF = 0
573 ; error - CF = 1 AX = return code (Parse error + error #)
574 ;
575 ;Change History: Created 5/01/87 FG
576 ;
577 ;******************* END OF SPECIFICATIONS *************************************
578 ;******************+ START OF PSEUDOCODE +**************************************
579 ;
580 ; START Parse_Command_Line
581 ;
582 ; parse command line (Call Do_Parse)
583 ; if parse error
584 ; call GetError to find out what happened
585 ; (fail flag set)
586 ; else
587 ; if filespec found
588 ; set up to move filespec into SourceBIOSName
589 ; call Move_It to do the move
590 ; save size of filespec
591 ; set source spec flag
592 ; else
593 ; call Set_Target to process drive id (only other non error
594 ; endif
595 ; turn off filespec as valid input
596 ; if first parm was NOT a filespec (ie a drive id)
597 ; turn on optional bit
598 ; else
599 ; force required parms to 2
600 ; endif
601 ; call Do_Parse
602 ; if no errors
603 ; call Set_Target to initialize drive id
604 ; call Do_Parse to look for EOF or error
605 ; if eol
606 ; clear error flag
607 ; else
608 ; call Get_Error to see what went wrong
609 ; endif
610 ; else
611 ; if not EOL
612 ; call Get_Error to see what went wrong
613 ; else
614 ; clear error flag
615 ; endif
616 ; endif
617 ; endif
618 ;
619 ; ret
620 ;
621 ; END Parse_Command_Line
622 ;
623 ;******************- END OF PSEUDOCODE -**************************************
624
625 public Parse_Command_Line
626
627 Parse_Command_Line PROC NEAR
628 ;---------------------------------------
629 ; Parse Equates
630 ;---------------------------------------
631 ; $SALUT (4,27,34,41)
632
633 eol equ -1 ; Indicator for End-Of-Line ;AN000;
634 noerror equ 0 ; Return Indicator for No Errors ;AN000;
635 command_line equ 081H ; offset of command line in PSP ;AN000;
636 Syntax_Error equ 9 ; PARSE syntax error ;AN000;
637
638 ; $SALUT (4,4,9,41)
639
640 ;---------------------------------------
641 ; Get address of command line
642 ;---------------------------------------
643
644 push ds ; ;AN000;
645 pop es ; ;AN000;
646 lea di,PARMS ; ;AC021:
647
648 call Do_Parse ; ;AC021:
649
650 cmp ax,0 ; did we find our required parm? ;AN000;
651
652 ; $if ne ; no -check what happened ;AN000;
653 JE $$IF15
654
655 call Get_Error ; ;AC021;
656
657 ; $else ; ;AC021;
658 JMP SHORT $$EN15
659 $$IF15:
660
661 cmp POS_TYPE,5 ; is it a file spec? ;AN021;
662 ; $if e ; if it is a file spec ;AN021;
663 JNE $$IF17
664 push ds ; copy spec into source ;AN021;
665 push di ; ;AN021;
666 push si ; ;AN021;
667 lea di,SourceSpec ; ;AN021;
668 mov si,word ptr POS_OFF ; ;AN021;
669 mov ax,POS_SEG ; ;AN021;
670 mov ds,ax ; ;AN021;
671
672 ASSUME ds:nothing,es:DATA
673
674 xor bx,bx ; ;AN021;
675
676 call Move_Source ; ;AN021;
677
678 pop si ; ;AN021;
679 pop di ; ;AN021;
680 pop ds ; ;AN021;
681
682 ASSUME ds:DATA,es:nothing
683
684 mov SourceSize,bx ; ;AN021;
685 mov Spec_Flag,1 ; set spec flag ;AN021;
686 ; $else ; must be a drive id ;AN021;
687 JMP SHORT $$EN17
688 $$IF17:
689 call Set_Target ; initialize target just in case ;AN021;
690 mov SourceSpec,al ; save Source Spec ;AN000;
691 ; remember that the colon and size
692 ; $endif ; ;AN021;
693 $$EN17:
694 and POSTYP,drv_id ; off filespec bit - on drive bit ;AN021;
695 cmp Spec_Flag,0 ; do we have a source spec ? ;AN021;
696 ; $if e ; if spec flag not set ;AN021;
697 JNE $$IF20
698 inc POSREP ; turn on optional ;AN021;
699 ; $else ; ;AN021;
700 JMP SHORT $$EN20
701 $$IF20:
702 inc PAR_MIN ; must have the second parm. ;AN021;
703 ; $endif ; ;AN021;
704 $$EN20:
705
706 call Do_Parse ; ;AN021;
707
708 cmp ax,0 ; no parse errors? ;AN000;
709
710 ; $if e ; if no error - must be a drive id ;AN021;
711 JNE $$IF23
712 call Set_Target ; initialize target ;AN021;
713 cmp Spec_Flag,0 ; do we have a source spec ? ;AN021;
714 ; $if e ; if spec flag not set ;AN021;
715 JNE $$IF24
716 inc Spec_Flag ; turn it on ;AN021;
717 ; $endif ; ;AN021;
718 $$IF24:
719
720 call Do_Parse ; make sure there are no extra parms. ;AN021;
721 cmp ax,eol ; ;AN021;
722 ; $if e ; ;AN021;
723 JNE $$IF26
724 clc ; ;AN021;
725 ; $else ; ;AN021;
726 JMP SHORT $$EN26
727 $$IF26:
728 call Get_Error ; ;AN021;
729 ; $endif ; ;AN021;
730 $$EN26:
731 ; $else ; could be EOL or error ;AN021;
732 JMP SHORT $$EN23
733 $$IF23:
734 cmp ax,eol ; is it EOL ? ;AN021;
735 ; $if ne ; if it is not eol ;AN021;
736 JE $$IF30
737 call Get_Error ; error - make sure it makes sense ;AN021;
738 ; $else ; ;AN021;
739 JMP SHORT $$EN30
740 $$IF30:
741 clc ; ;AN021;
742 ; $endif ; ;AN021;
743 $$EN30:
744 ; $endif ; ;AN021;
745 $$EN23:
746 ; $endif ; ;AN000;
747 $$EN15:
748
749 ret ; ;AN000;
750
751
752 Move_Source PROC NEAR
753
754 ; $search ; ;AN021;
755 $$DO35:
756 lodsb ; ;AN021;
757 stosb ; ;AN021;
758 inc bl ; ;AN021;
759 cmp bl,54 ; are we past the maximum? ;AN021;
760 ; $exitif a ; ;AN021;
761 JNA $$IF35
762 mov ax,(util_B SHL 8) + bad_path ; Invalid path ;AN021;
763 stc ; ;AN021;
764 ; $orelse ; ;AN021;
765 JMP SHORT $$SR35
766 $$IF35:
767 or al,al ; ;AN021;
768 ; $endloop z ; ;AN021;
769 JNZ $$DO35
770 dec bl ; ;AN021;
771 clc ; ;AN021;
772 ; $endsrch ; ;AN021;
773 $$SR35:
774
775 ret ; ;AN021;
776
777 ENDPROC Move_Source
778
779 Do_Parse PROC NEAR
780
781 mov insert_ptr_off,si ; save it in case of error ;AN024;
782 push cs ; ;AN000;
783 pop ds ; ;AN000;
784 xor dx,dx ; ;AN021;
785
786 ASSUME ds:nothing,es:DATA
787
788 call SysParse ; parse command line ;AN000;
789
790 push es ; ;AN000;
791 pop ds ; ;AN000;
792
793 ASSUME ds:DATA,es:nothing
794
795
796 ret ; ;AN021;
797
798 ENDPROC Do_Parse
799
800 Set_Target PROC NEAR
801
802 mov al,byte ptr pos_drv_id ; initalize drive id ;AN000;
803 mov TargDrvNum,al ; save it for later ;AN000;
804 mov ExtFCB_Drive,al ; save it for finding VOL id ;AN000;
805 or al,num_2_letter ; convert to a drive letter ;AC000;
806 mov TargSpec,al ; save it for later ;AN000;
807 mov TargDrv,al ; ;AC000;
808 ret ; ;AN021;
809
810 ENDPROC Set_Target
811
812 Get_Error PROC NEAR
813
814 lea bx,Parse_Ret_Code ; error - make sure it makes sense ;AN000;
815 xlat cs:[bx] ; ;AN000;
816 mov ah,parse_error ; indicate parse error CLASS ;AN000;
817 stc ; set fail flag ;AN000;
818 ret ; ;AN021;
819
820 ENDPROC Get_Error
821
822 Parse_Ret_Code label byte
823
824 db 0 ; Ret Code 0 - ;AN000;
825 db 1 ; Ret Code 1 - Too many operands ;AN000;
826 db 2 ; Ret Code 2 - Required operand missing;AC002;
827 db 9 ; Ret Code 3 - Not in switch list provided ;AC002;
828 db 9 ; Ret Code 4 - Not in keyword list provided;AC002;
829 db 9 ; Ret Code 5 - (not used) ;AN000;
830 db 9 ; Ret Code 6 - Out of range specified ;AN000;
831 db 9 ; Ret Code 7 - Not in value list provided
832 db 9 ; Ret Code 8 - Not in string list provided
833 db 9 ; Ret Code 9 - Syntax error
834
835 ENDPROC Parse_Command_Line
836
837 BREAK <SYS - Validate_Target_Drive >
838 ;******************* START OF SPECIFICATIONS ***********************************
839 ;Routine name: Validate_Target_Drive
840 ;*******************************************************************************
841 ;
842 ;Description: Verify that target drive was specified, is not default drive,
843 ; is a valid drive letter, and is not a network drive
844 ;
845 ;Called Procedures: Check_Default_Drive
846 ; Check_Target_Drive
847 ; Check_For_Network
848 ;
849 ;Input: None
850 ;
851 ;Output: no error - CF = 0 AX = 0
852 ; error - CF = 1 AX = return code (message #)
853 ;
854 ;Change History: Created 5/01/87 FG
855 ;
856 ;******************* END OF SPECIFICATIONS *************************************
857 ;******************+ START OF PSEUDOCODE +**************************************
858 ;
859 ; START Validate_Target_Drive
860 ;
861 ; can't have target as default (CALL Check_Default_Drive)
862 ; if no error and
863 ; can't have target as network (CALL Check_For_Network)
864 ; if no error
865 ; see if valid drive letter (CALL Check_Target_Drive)
866 ; ret
867 ;
868 ; END Validate_Target_Drive
869 ;
870 ;******************- END OF PSEUDOCODE -**************************************
871
872 public Validate_Target_Drive
873
874 Validate_Target_Drive PROC NEAR
875
876 call Check_Default_Drive ; can't have target as default ;AN000;
877
878 ; $if nc,and ; no error and ;AN000;
879 JC $$IF40
880
881 call Check_For_Network ; can't have target as network ;AC022;
882
883 ; $if nc ; no error ;AN000;
884 JC $$IF40
885
886 call Check_Target_Drive ; see if valid drive letter ;AC022;
887
888 ; $endif ; ;AN000;
889 $$IF40:
890
891 ret ; ;AN000;
892
893 ENDPROC Validate_Target_Drive
894
895 BREAK <SYS - Check_Default_Drive >
896 ;******************* START OF SPECIFICATIONS ***********************************
897 ;Routine name: Check_Default_Drive
898 ;*******************************************************************************
899 ;
900 ;Description: Check to see if drive specified is default drive. If it is,
901 ; load return code and set fail flag.
902 ;
903 ;Called Procedures: None
904 ;
905 ;Input: None
906 ;
907 ;Output: no error - CF = 0
908 ; error - CF = 1 AX = 16d - Can not specify default drive
909 ;
910 ;Change History: Created 5/01/87 FG
911 ;Change History: Ax021 2/22/88 FG
912 ;
913 ;******************* END OF SPECIFICATIONS *************************************
914 ;******************+ START OF PSEUDOCODE +**************************************
915 ;
916 ; START Check_Default_Drive
917 ;
918 ; initialize BIO and DOS found flags
919 ; if source specified
920 ; copy source into SourceDOSName from SourceBIOName
921 ; else
922 ; get_default_drive (INT21 Get_Default_Drive + 00 <1900>)
923 ; if target drive = default drive
924 ; load return code (Can not specify default drive)
925 ; set fail flag
926 ; else
927 ; initialize SourceBIOName and SourceDOSName
928 ; reset fail flag
929 ; endif
930 ; endif
931 ; remove blanks in \IBMBIO.COM
932 ; remove blanks in \IBMDOS.COM
933 ; ret
934 ;
935 ; END Check_Default_Drive
936 ;
937 ;******************- END OF PSEUDOCODE -**************************************
938
939 public Check_Default_Drive
940
941 Check_Default_Drive PROC NEAR
942
943 push ds
944 pop es
945
946 ASSUME DS:DATA,ES:DATA
947
948 mov DOSEntFree,1 ; set to not found ;AC021;
949 mov BIOSEntFree,1 ; set to not found ;AC021;
950 cmp Spec_Flag,1 ; was a source specified ? ;AN021;
951 ; $if e ; if a source was specified ;AN021;
952 JNE $$IF42
953 lea si,SourceSpec ; copy source for IBMDOS.COM ;AN021;
954 mov al,[si] ; get the drive ID ;AN025;
955 sub al,num_2_letter ; convert it to a 1 base number ;AN025;
956 mov DEFALT,al ; save it in case its removable ;AN025;
957 lea di,SourceDOSName ; ;AN021;
958 mov cx,SourceSize ; set up size to move ;AN021;
959 rep movsb ; move it! ;AN021;
960
961 ; $else ; figure out what the default is ;AN021;
962 JMP SHORT $$EN42
963 $$IF42:
964
965 mov ax,(Get_Default_Drive shl 8) + not_used ; get_default_drive
966 INT 21h ; Get_Default_Drive <1900>
967 inc al ; turn from phys drive to logical drive
968 mov DEFALT,al ; save default for later
969 mov SourceSpec,al
970 or SourceSpec,num_2_letter ; covert number to letter
971 cmp al,TargDrvNum ; is target drive = default drive
972 ; $if e ; if it is the same - we have a problem;AC000;
973 JNE $$IF44
974
975 mov ax,(util_B shl 8) + not_on_default ; load return code
976 ; - Can not specify default drive
977 stc ; set fail flag
978
979 ; $else ; it wasn't = so its ok ;AC000;
980 JMP SHORT $$EN44
981 $$IF44:
982
983 ; initalize SourceBIOSNane, SourceDOSName
984 mov al,DEFALT
985 or al,num_2_letter ; turn into letter
986 mov byte ptr SourceBIOSName,AL ; twiddle source name
987 mov SourceDOSName,AL ; twiddle source name
988 clc ; reset fail flag ;AN000;
989
990 ; $endif ; ;AC000;
991 $$EN44:
992 ; $endif ; ;AN021;
993 $$EN42:
994 ; $if nc ; if no error to this point ;AN021;
995 JC $$IF48
996 cld ; ;AN021;
997
998 IF IBMCOPYRIGHT
999 mov bx,NameLen ; ;AN021;
1000 mov cx,bx ; ;AN021;
1001 ELSE
1002 mov cx,BIOSNameLen
1003 ENDIF
1004
1005 lea di,SourceBiosName ; move IBMBIO.COM into place ;AN021;
1006 add di,SourceSize ; move to end of specified part ;AN021;
1007 lea si,SourceBIOS ; point to system file name ;AN021;
1008 rep movsb ; ;AN021;
1009
1010 IF IBMCOPYRIGHT
1011 mov cx,bx ; ;AN021;
1012 ELSE
1013 mov cx,DosNameLen
1014 ENDIF
1015
1016 lea di,SourceDOSName ; move IBMDOS.COM into place ;AN021;
1017 add di,SourceSize ; move to end of specified part ;AN021;
1018 lea si,SourceDOS ; point to system file name ;AN021;
1019 rep movsb ; ;AN021;
1020 ; $endif ; ;AN021;
1021 $$IF48:
1022
1023 ret ; ;AN000;
1024
1025 ENDPROC Check_Default_Drive
1026
1027 BREAK <SYS - Check_Target_Drive >
1028 ;******************* START OF SPECIFICATIONS ***********************************
1029 ;Routine name: Check_Target_Drive
1030 ;*******************************************************************************
1031 ;
1032 ;Description: Determine if target drive is valid. To do this, we will make an
1033 ; IOCTL - check media ID call.
1034 ;
1035 ;Called Procedures:
1036 ;
1037 ;Input: Default_Drive
1038 ;
1039 ;Output: no error - CF = 0
1040 ; error - CF = 1 AX = 16d - Can not specify default drive
1041 ;
1042 ;Change History: Created 5/01/87 FG
1043 ;
1044 ;******************* END OF SPECIFICATIONS *************************************
1045 ;******************+ START OF PSEUDOCODE +**************************************
1046 ;
1047 ; START Check_Target_Drive
1048 ;
1049 ; Check media ID (INT21 IOCTL + IOCTL_CHANGEABLE? <4408>)
1050 ; if no error
1051 ; if invalid drive
1052 ; set return code
1053 ; set fail flag
1054 ; else
1055 ; clear fail flag
1056 ; else
1057 ; reset fail flag
1058 ; endif
1059 ; if no error
1060 ; if ASSIGNed or SUBSTd drive
1061 ; set return code
1062 ; set fail flag
1063 ; else
1064 ; clear fail flag
1065 ; else
1066 ; reset fail flag
1067 ; endif
1068 ; ret
1069 ;
1070 ; END Check_Target_Drive
1071 ;
1072 ;******************- END OF PSEUDOCODE -**************************************
1073
1074 public Check_Target_Drive
1075
1076 Check_Target_Drive PROC NEAR
1077
1078 mov bl,TargDrvNum ; get the target drive number ;AN000;
1079 mov ax,(IOCTL SHL 8) + IOCTL_CHANGEABLE? ; do a media check ;AC000;
1080 INT 21h ; IOCtl + 08 <4408> ;AC000;
1081
1082 cmp ax,0fh ; is it invalid - al = F (CF may be set;AC000;
1083
1084 ; $if e ; ;AC000;
1085 JNE $$IF50
1086
1087 mov ax,(DOS_error shl 8) + extended_15 ; load return code ;AC000;
1088 ; - invalid drive
1089 stc ; ;AC000;
1090
1091 ; $else ; if valid device so far - make sure ;AN012;
1092 JMP SHORT $$EN50
1093 $$IF50:
1094 ; its not ASSIGNed or SUBSTed drive
1095 mov si,offset TargSpec ; point to Target Spec ;AN012;
1096 mov di,offset DIR_SECTOR ; point at output buffer ;AN012;
1097 mov ax,(xNameTrans SHL 8) ; check for name translation ;AN012;
1098 int 21h ; get real path ;AN012;
1099 ; $if nc ; ;AC012;
1100 JC $$IF52
1101 mov bl,byte ptr [TargSpec] ; get drive letter from path ;AN012;
1102 cmp bl,byte ptr DIR_SECTOR ; did drive letter change? ;AN012;
1103 ; $if ne ; if not the same, it be bad ;AN012;
1104 JE $$IF53
1105 lea si,sys_ptr ; set insert pointer in SUBLIST ;AN012;
1106 mov [insert_ptr_off],si ; ;AN012;
1107 mov [insert_ptr_seg],ds ; ;AN012;
1108 lea si,sublist ; set pointer to SUBLIST ;AN012;
1109 mov ax,(util_C shl 8) + cant_assign ; load ret cd (Cannot..SUB);AN012;
1110 stc ; tell user ;AN012;
1111 ; $else ; - its ok ;AN012;
1112 JMP SHORT $$EN53
1113 $$IF53:
1114 clc ; keep going ;AN012;
1115 ; $endif ; ;AN012;
1116 $$EN53:
1117 ; $else ; - its a critical error ;AN012;
1118 JMP SHORT $$EN52
1119 $$IF52:
1120 xor ah,ah ; set up for extended error call ;AN012;
1121 inc ah ; ;AN012;
1122 ; $endif ; ;AN012;
1123 $$EN52:
1124 ; $endif ; ;AN012;
1125 $$EN50:
1126
1127 ret ; ;AC000;
1128
1129 ENDPROC Check_Target_Drive
1130
1131 BREAK <SYS - Check_For_Network >
1132 ;******************* START OF SPECIFICATIONS ***********************************
1133 ;Routine name: Check_For_Network
1134 ;*******************************************************************************
1135 ;
1136 ;Description: Verify that the target drive is local, and not a shared drive.
1137 ; If shared,load return code and set fail flag.
1138 ;
1139 ; NOTE: This is a design point on how to determine net
1140 ;
1141 ;CALLed Procedures: None
1142 ;
1143 ;Input: None
1144 ;
1145 ;Output: no error - CF = 0
1146 ; error - CF = 1 AX = return code = 7 - Cannot SYS to a Network drive
1147 ;
1148 ;Change History: Created 5/01/87 FG
1149 ;
1150 ;******************* END OF SPECIFICATIONS *************************************
1151 ;******************+ START OF PSEUDOCODE +**************************************
1152 ;
1153 ; START Check_For_Network
1154 ;
1155 ; IOCtl call to see if target drive is local
1156 ; if target drive not local (INT21 IOCtl + 09 <4409>) and
1157 ; if return code indicates network drive (test 1200h)
1158 ; set insert pointer in SUBLIST
1159 ; set pointer to SUBLIST
1160 ; load return code (Cannot SYS to a Network drive)
1161 ; set fail flag
1162 ; else
1163 ; reset fail flag
1164 ; endif
1165 ; ret
1166 ;
1167 ; END Check_For_Network
1168 ;
1169 ;******************- END OF PSEUDOCODE -**************************************
1170
1171 public Check_For_Network
1172
1173 Check_For_Network PROC NEAR
1174
1175 ; IOCtl call to see if target drive is local
1176 mov bl,TargDrvNum ; x = IOCTL (getdrive, Drive+1) ;AC022;
1177 mov ax,(IOCTL SHL 8) + dev_local
1178 INT 21h ; IOCtl + dev_local <4409>
1179
1180 ; $if nc,and ; target drive local and ;AC000;
1181 JC $$IF59
1182
1183 test dx,1200H ; check if (x & 0x1000)
1184 ; (redirected or shared)
1185 ; $if nz ; return code indicates network drive ;AC000;
1186 JZ $$IF59
1187
1188 lea si,sys_ptr ; set insert pointer in SUBLIST ;AN000;
1189 mov [insert_ptr_off],si ; ;AN000;
1190 mov [insert_ptr_seg],ds ; ;AN000;
1191 lea si,sublist ; set pointer to SUBLIST ;AN000;
1192 mov ax,(util_C shl 8) + cant_network ; load return code (Cannot SYS to.;AC000;
1193 stc ; set fail flag ;AN000;
1194
1195 ; $else ; ;AC000;
1196 JMP SHORT $$EN59
1197 $$IF59:
1198
1199 clc ; reset fail flag ;AC000;
1200
1201 ; $endif ; ;AC000;
1202 $$EN59:
1203
1204 ret ; ;AN000;
1205
1206 ENDPROC Check_For_Network
1207
1208 BREAK <SYS - Get_System_Files >
1209 ;******************* START OF SPECIFICATIONS ***********************************
1210 ;Routine name: Get_System_Files
1211 ;*******************************************************************************
1212 ;
1213 ;Description: Ensure that the the files IBMBIO and IBMDOS are available
1214 ; on the source media. If they are not on the source media,
1215 ; and the media is removeable, a prompt will be issued to
1216 ; insert a new source.
1217 ;
1218 ;Called Procedures: Prompt_For_Media Open_File
1219 ; Check_Removable Fill_Memory
1220 ;
1221 ;Input: IBMBIO and IBMDOS on source media
1222 ;
1223 ;Output: no error - CF = 0
1224 ; error - CF = 1 AX = return code (message #)
1225 ;
1226 ;Change History: Created 5/01/87 FG
1227 ; Major change 1/07/88 FG Ax019 now makes SYS check
1228 ; for the CORRECT version
1229 ; of IBMBIO !
1230 ; IBMBIO looks like this:
1231 ;
1232 ; 1 2 3 4 5
1233 ; ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄ
1234 ; ³ JMP ³ LO ³ HI ³extected_version³
1235 ; ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄ
1236 ;******************* END OF SPECIFICATIONS *************************************
1237 ;******************+ START OF PSEUDOCODE +**************************************
1238 ;
1239 ; START Get_System_Files
1240 ;
1241 ; initalize SourceBIOSNane, SourceDOSName
1242 ; do
1243 ; find IBMBIOS
1244 ; if found and
1245 ; open file (CALL Open_File)
1246 ; if no error and
1247 ; find IBMDOS
1248 ; if found and
1249 ; open file (CALL Open_File)
1250 ; if no error and
1251 ; load memory with files (CALL Fill_Memory)
1252 ; if no error and
1253 ; if correct version of IBMBIO
1254 ; reset fail flag
1255 ; load success return code
1256 ; else
1257 ; check if source media replaceable (CALL Check_Removeable)
1258 ; if fail flag reset (replaceable)
1259 ; load message number (Insert system disk....)
1260 ; and class (utility)
1261 ; set up pointer to insert (drive id)
1262 ; prompt for source media (CALL Prompt_For_Media)
1263 ; if fail flag reset
1264 ; load return code (try again)
1265 ; endif
1266 ; endif
1267 ; endif
1268 ; leave if success return code
1269 ; leave if fail flag set
1270 ; enddo
1271 ; ret
1272 ;
1273 ; END Get_System_Files
1274 ;
1275 ;******************- END OF PSEUDOCODE -**************************************
1276
1277 public Get_System_Files
1278
1279 Get_System_Files PROC NEAR
1280 cld
1281
1282 ; $search ; ;AC018;
1283 $$DO62:
1284
1285 lea si,DOS_BUFFER ; set up addressability
1286 mov dx,OFFSET SourceBIOSName ; look on source for IBMBIOS
1287 mov CX,DOS_system_atrib ; its an 'everything' file
1288 mov ah,Find_First ; do a find first INT21
1289 INT 21h ; Find_First <4Exx>
1290
1291 ; $if nc,and ; if found and..................... ;AC000;
1292 JC $$IF63
1293 mov ax,ds:[si].find_buf_size_l ; move size (low and high) ;AC000;
1294 mov WORD PTR NEWBIO_SIZE_LOW,AX ; from DTA
1295 mov ax,ds:[si].find_buf_size_h ; to ;AC000;
1296 mov WORD PTR NEWBIO_SIZE_HIGH,AX ; SYS data space
1297 mov dx,OFFSET SourceBIOSName ; point to source name
1298 mov di,OFFSET BIOSInFH ; pointer to block of data
1299
1300 call Open_File ; open file
1301
1302 ; $if nc,and ; if no error and.................... ;AC000;
1303 JC $$IF63
1304
1305 mov dx,OFFSET SourceDOSName ; look on source for IBMDOS
1306 mov CX,DOS_system_atrib ; its an 'everything' file
1307 mov ah,Find_First ; do a find first INT21
1308 INT 21h ; Find_First <4Exx>
1309
1310 ; $if nc,and ; if found and....................... ;AC000;
1311 JC $$IF63
1312
1313 mov ax,ds:[si].find_buf_size_l ; move size (low and high) ;AC000;
1314 mov WORD PTR NEWDOS_SIZE_LOW,AX ; from DTA
1315 mov ax,ds:[si].find_buf_size_h ; to ;AC000;
1316 mov WORD PTR NEWDOS_SIZE_HIGH,AX ; SYS data space
1317 mov dx,OFFSET SourceDOSName ; pointer to source of DOS
1318 mov di,OFFSET DOSInFH ; pointer to block of data
1319
1320 call Open_File ; open file
1321
1322 ; $if nc,and ; if no error and......................;AC000;
1323 JC $$IF63
1324
1325 call Fill_Memory ; load memory with files
1326
1327 ; $if nc,and ; if no error..................: ;AC019;
1328 JC $$IF63
1329
1330 cmp WORD PTR BUF+FAT_BUF+3,expected_version ; point to beginning ;AN019;
1331 ; of buffer + near jump instruction
1332
1333 ; $if e ; if correct version of IBMBIO ;AN019;
1334 JNE $$IF63
1335
1336 clc ; reset fail flag ;AN019:
1337 mov al,noerror ; load success return code ;AN000;
1338
1339 ; $else ; ELSE - something wrong with source ;AC000;
1340 JMP SHORT $$EN63
1341 $$IF63:
1342
1343 mov bl,defalt ;; specify drive ;;dcl ;AN001;
1344 call Check_Removeable ; check if source media replaceable ;AC000;
1345
1346 ; $if nc ; fail flag reset (replaceable) ;AC000;
1347 JC $$IF65
1348
1349 mov ax,(util_C shl 8) + sys_disk ; load message number ;AC000;
1350 ; - Insert system disk....
1351 lea si,SourceSpec ; set insert pointer to DRIVE ID ;AC000;
1352 mov bx,SourceSize ; only display correct path length ;AN025;
1353
1354 call Prompt_For_Media ; prompt for source media ;AN000;
1355
1356 ; $if nc ; fail flag reset ;AC000;
1357 JC $$IF66
1358
1359 mov ax,error_RC ; load return code (try again) ;AN000;
1360
1361 ; $endif ; ;AC000;
1362 $$IF66:
1363
1364 ; $endif ; ;AC000;
1365 $$IF65:
1366
1367 ; $endif ; ;AC000;
1368 $$EN63:
1369
1370 ; $leave c ; if fail flag set ;AC018;
1371 JC $$EN62
1372
1373 cmp al,noerror ; is it an error return code? ;AC018;
1374
1375 ; $exitif e ; quit if success return code ;AC018;
1376 JNE $$IF62
1377
1378 mov bx,BIOSInFH ; ;AC018;
1379 mov ah,Close ; ;AC018;
1380 int 21h ; ;AC018;
1381
1382 mov bx,DOSInFH ; ;AC018;
1383 mov ah,Close ; ;AC018;
1384 int 21h ; ;AC018;
1385
1386 ; $orelse ; ;AN018;
1387 JMP SHORT $$SR62
1388 $$IF62:
1389
1390 ; $endloop long ; ;AC018;
1391 JMP $$DO62
1392 $$EN62:
1393 ; $endsrch ; ;AN018;
1394 $$SR62:
1395
1396
1397
1398 ret ; ;AN000;
1399
1400 ENDPROC Get_System_Files
1401
1402 BREAK <SYS - Prompt_For_Media >
1403 ;******************* START OF SPECIFICATIONS ***********************************
1404 ;Routine name: Prompt_For_Media
1405 ;*******************************************************************************
1406 ;
1407 ;Description: Make call to Message to display:
1408 ;
1409 ; Insert system disk in drive %1
1410 ; and strike any key when ready
1411 ;
1412 ;Called Procedures: Message
1413 ;
1414 ;Input: (AL) = message #
1415 ; (BL) = drive/path length
1416 ; (SI) = insert pointer
1417 ;
1418 ;Output: no error - CF = 0
1419 ; error - CF = 1 AX = return code (DOS error)
1420 ;
1421 ;Change History: Created 5/01/87 FG
1422 ;
1423 ;******************* END OF SPECIFICATIONS *************************************
1424 ;******************+ START OF PSEUDOCODE +**************************************
1425 ;
1426 ; START Prompt_For_Media
1427 ;
1428 ; set up for message call
1429 ; call Message - display first line
1430 ; if no error
1431 ; clear insert indicator
1432 ; load Message #x - Press any key to continue
1433 ; ask for keystroke response (direct CON in no echo)
1434 ; call Message - display second line
1435 ; endif
1436 ; if error
1437 ; load return code (DOS extended error)
1438 ; endif
1439 ; ret
1440 ;
1441 ; END Prompt_For_Media
1442 ;
1443 ;******************- END OF PSEUDOCODE -**************************************
1444
1445 public Prompt_For_Media
1446
1447 Prompt_For_Media PROC NEAR
1448
1449 mov [insert_ptr_off],si ; set up for message call ;AN000;
1450 mov [insert_ptr_seg],ds
1451 mov insert_max,bl ; only display correct path length ;AN025;
1452 lea si,sublist ; set pointer to SUBLIST ;AN000;
1453
1454 call Message ; display first line ;AN000;
1455
1456 ; $if nc ; if no error ;AN000;
1457 JC $$IF75
1458
1459 mov ax,(util_D shl 8) + press_key ; load Message ;AN000;
1460 ; - Press any key to continue
1461 ; the class will signal to ask for
1462 ; keystroke response
1463 ; (direct CON in no echo)
1464 call Message ; display second line ;AN000;
1465
1466 ; $endif ; ;AN000;
1467 $$IF75:
1468
1469 ; $if c ; if an error occured ;AN000;
1470 JNC $$IF77
1471
1472 mov ah,DOS_error ; load return code (DOS extended error);AN000;
1473
1474 ; $endif ; ;AN000;
1475 $$IF77:
1476
1477 ret ; ;AN000;
1478
1479 ENDPROC Prompt_For_Media
1480
1481 BREAK <SYS - Check_Removeable >
1482 ;******************* START OF SPECIFICATIONS ***********************************
1483 ;Routine name: Check_Removeable
1484 ;*******************************************************************************
1485 ;
1486 ;Description: Make IOCtl call to see if media in the drive indicated in
1487 ; BX is removable
1488 ;
1489 ;Called Procedures: None
1490 ;
1491 ;Input: BX has drive (0=default, 1=A)
1492 ;
1493 ;Output: removeable - CF = 0
1494 ; nonremovable or error - CF = 1
1495 ; AX = 11d - No system on default drive
1496 ;
1497 ;Change History: Created 5/01/87 FG
1498 ;
1499 ;******************* END OF SPECIFICATIONS *************************************
1500 ;******************+ START OF PSEUDOCODE +**************************************
1501 ;
1502 ; START Check_Removeable
1503 ;
1504 ; if source not specified
1505 ; do an IOCTL changeable check (INT21 IOCtl + 08 <4408>)
1506 ; if no error
1507 ; test if removeable
1508 ; if removeable
1509 ; reset fail flag
1510 ; else
1511 ; load return code (No system on default drive)
1512 ; set fail flag
1513 ; endif
1514 ; endif
1515 ; else
1516 ; load return code (No system on specified path)
1517 ; set fail flag
1518 ; endif
1519 ; ret
1520 ;
1521 ; END Check_Removeable
1522 ;
1523 ;******************- END OF PSEUDOCODE -**************************************
1524
1525 public Check_Removeable
1526
1527 Check_Removeable PROC NEAR
1528
1529 mov ax,(IOCTL SHL 8) + IOCTL_CHANGEABLE? ; do a media check
1530 INT 21h ; IOCtl + 08 <4408>
1531 ; cy set if remote or invalid device ;;dcl;;
1532 ; $if nc ;
1533 JC $$IF79
1534 cmp ax,0 ;
1535 ; $if e ;
1536 JNE $$IF80
1537 clc ;
1538 ; $else ;
1539 JMP SHORT $$EN80
1540 $$IF80:
1541 cmp Spec_Flag,1 ; ;AC025;
1542 ; $if ne ; ;AC025;
1543 JE $$IF82
1544 mov ax,(util_B shl 8) + no_sys_on_def ; No system on... ;AC000;
1545 ; $else ; ;AC025;
1546 JMP SHORT $$EN82
1547 $$IF82:
1548 mov ax,(util_B shl 8) + system_not_found ; Invalid path or Sy..;AN021;
1549 ; $endif ; ;AC025;
1550 $$EN82:
1551 stc ;
1552 ; $endif ;
1553 $$EN80:
1554 ; $endif ;
1555 $$IF79:
1556
1557 ret ; ;AN021;
1558
1559 ENDPROC Check_Removeable
1560
1561 BREAK <SYS - Open_File >
1562 ;******************* START OF SPECIFICATIONS ***********************************
1563 ;Routine name: Open_File
1564 ;*****************************************************************************
1565 ;
1566 ;Description: Opens file and gets size and date
1567 ;
1568 ;Called Procedures: None
1569 ;
1570 ;Input: ES:DI = Data space for DOS operations
1571 ;
1572 ;Output: no error - CF = 0
1573 ; error - CF = 1 AX = DOS extended errors
1574 ;
1575 ;Change History: Created 5/01/87 FG
1576 ;
1577 ;******************* END OF SPECIFICATIONS *************************************
1578 ;******************+ START OF PSEUDOCODE +**************************************
1579 ;
1580 ; START Open_File
1581 ;
1582 ; open file for read (INT21 Read + 00 <3D00>)
1583 ; if no error
1584 ; save handle
1585 ; find End Of File (INT21 LSeak + 02 <4202>)
1586 ; zero offsets
1587 ; get offsets (INT21)
1588 ; save low part of size
1589 ; save high part of size
1590 ; find start of file (INT21 LSeak + 00 <4200>)
1591 ; find last write time(INT21 File_Times + 00 <5700>)
1592 ; save time
1593 ; save date
1594 ; else
1595 ; load return code (DOS extended errors)
1596 ; endif
1597 ; ret
1598 ;
1599 ; END Open_File
1600 ;
1601 ;******************- END OF PSEUDOCODE -**************************************
1602
1603 public open_file
1604
1605 Open_File PROC NEAR
1606
1607 mov ax,(OPEN SHL 8) + not_used ; open file for read
1608 INT 21h ; Read + not_used <3D00>
1609
1610 ; $if nc ; no error ;AC000;
1611 JC $$IF87
1612
1613 mov es:[di].InFH,ax ; save file handle ;AC000;
1614 mov bx,ax ; get ready for seeks
1615 mov ax,(LSeek SHL 8) + LSeek_EOF ; seek relative to eof
1616 xor cx,cx ; zero offset
1617 xor dx,dx ; zero offset
1618 INT 21h ; find End Of File to get offsets
1619 ; LSeak + LSeek_EOF <4202>
1620 mov es:[di].LenLow,ax ; save low part of size ;AC000;
1621 mov es:[di].LenHigh,dx ; save high part of size ;AC000;
1622 xor dx,dx ; zero offset
1623 mov ax,(LSeek SHL 8) + LSeek_Start ; seek relative to beginning
1624 INT 21h ; LSeak + LSeek_Start <4200>
1625 mov ax,(File_Times SHL 8) + 0 ; find last write time
1626 INT 21h ; File_Times + not_used <5700>
1627 mov es:[di].FTime,cx ; save time ;AC000;
1628 mov es:[di].FDate,dx ; save date ;AC000;
1629
1630 ; $else ; ;AC000;
1631 JMP SHORT $$EN87
1632 $$IF87:
1633
1634 mov ah,DOS_error ; load return code (DOS extended error);AC000;
1635
1636 ; $endif ; ;AC000;
1637 $$EN87:
1638
1639 ret
1640
1641 ENDPROC Open_File
1642
1643 BREAK <SYS - Fill_Memory >
1644 ;******************* START OF SPECIFICATIONS ***********************************
1645 ;Routine name: Fill_Memory
1646 ;*******************************************************************************
1647 ;
1648 ;Description: Read in as much of IBMBIOS and IBMDOS as room permits
1649 ;
1650 ;Called Procedures: None
1651 ;
1652 ;Input: None
1653 ;
1654 ;Output: no error - CF = 0
1655 ; error - CF = 1
1656 ;
1657 ;Change History: Created 5/01/87 FG
1658 ;
1659 ;******************* END OF SPECIFICATIONS *************************************
1660 ;******************+ START OF PSEUDOCODE +**************************************
1661 ;
1662 ; START Fill_Memory
1663 ;
1664 ; get length of buffer
1665 ; get BIOS source handle
1666 ; point to beginning of buffer
1667 ; save total buffer length
1668 ; if < 64k to read and
1669 ; if amount to read < buffer
1670 ; set length to IBMBIO length
1671 ; endif
1672 ; if amount to read > 0
1673 ; read the file (INT21 read +00 <3F00>)
1674 ; else
1675 ; set size to zero
1676 ; clear error flag (CF)
1677 ; endif
1678 ; if error or
1679 ; if not all of file read
1680 ; recover size
1681 ; set fail flag
1682 ; else
1683 ; update pointer for dos read
1684 ; recover size
1685 ; calculate remainder
1686 ; get DOS source handle
1687 ; if < 64k to read and
1688 ; if amount to read < buffer
1689 ; set length to IBMBIO length
1690 ; endif
1691 ; read the file (INT21 read +00 <3F00>)
1692 ; if no error and
1693 ; if all of file read
1694 ; update pointer for DOS read
1695 ; reset fail flag
1696 ; endif
1697 ; endif
1698 ; ret
1699 ;
1700 ; END Fill_Memory
1701 ;
1702 ;******************- END OF PSEUDOCODE -**************************************
1703
1704 public fill_memory
1705
1706 Fill_Memory PROC NEAR
1707
1708 mov ax,4200h ; LSEEK to end of last read ;AN001;
1709 mov bx,BIOSInFH ; ;AN001;
1710 mov cx,BIOSPos[2] ; ;AN001;
1711 mov dx,BIOSPos[0] ; ;AN001;
1712 int 21h ; ;AN001;
1713 mov ax,4200h ; LSEEK to end of last read ;AN001;
1714 mov bx,DOSInFH ; ;AN001;
1715 mov cx,DOSPos[2] ; ;AN001;
1716 mov dx,DOSPos[0] ; ;AN001;
1717 int 21h ; ;AN001;
1718
1719 mov cx,cbBuf ; get length of buffer
1720 mov bx,BIOSInFH ; get bios source handle
1721 mov dx,OFFSET BUF+FAT_BUF ; point to beginning of buffer
1722 ; past area to read in boot rec
1723 push cx ; save away total length
1724 cmp BIOSLenHigh,0 ; is there < 64K to read?
1725
1726 ; $if e,and ; if so - or................... ;AC000;
1727 JNE $$IF90
1728 ; :
1729 cmp BIOSLenLow,cx ; more left to read? :
1730 ; ie: is amount to read < buffer
1731 ; $if b ; if amount to read < buffer..: ;AC000;
1732 JNB $$IF90
1733
1734 mov cx,BIOSLenLow ; set length to IBMBIO length
1735
1736 ; $endif ; ;AC000;
1737 $$IF90:
1738
1739 cmp cx,0 ; is there anything to read?
1740
1741 ; $if a ; if so - read it
1742 JNA $$IF92
1743
1744 mov ah,Read ; read the file
1745 int 21h ; read + not_used <3F00>)
1746
1747 ; $else ; don't bother
1748 JMP SHORT $$EN92
1749 $$IF92:
1750
1751 xor ax,ax
1752 clc
1753
1754 ; $endif
1755 $$EN92:
1756
1757 ; $if c,or ; if error or.................. ;AC000;
1758 JC $$LL95
1759
1760 cmp ax,cx ; Did we get it all? :
1761
1762 ; $if nz ; if not all of file read.....: ;AC000;
1763 JZ $$IF95
1764 $$LL95:
1765
1766 pop cx ; recover size
1767 stc ; set fail flag
1768
1769 ; $else ; ;AC000;
1770 JMP SHORT $$EN95
1771 $$IF95:
1772
1773 add BIOSPos[0],ax ; save amount read for later lseek ;AN001;
1774 adc BIOSPos[2],0 ; save amount read for later lseek ;AN001;
1775
1776 add dx,ax ; update pointer for DOS Read
1777 mov pDOS,dx ; point to beginning of DOS
1778 sub BIOSLenLow,ax ; decrement remaining
1779 sbb BIOSLenHigh,0 ; do 32 bit
1780 pop cx ; get original length
1781 sub cx,ax ; this much is left
1782 mov bx,DOSInFH ; get bios source handle
1783 cmp DOSLenHigh,0 ; > 64K to read?
1784 ; $if e,and ; if < 64k to read and.......... ;AC000;
1785 JNE $$IF97
1786 cmp DOSLenLow,cx ; is amount to read < buffer :
1787
1788 ; $if b ; if its less .................: ;AC000;
1789 JNB $$IF97
1790
1791 mov cx,DOSLenLow ; set length to IBMDOS length
1792
1793 ; $endif ; ;AC000;
1794 $$IF97:
1795
1796 mov ah,Read ; read the file
1797 INT 21h ; read + not_used <3F00>)
1798
1799 ; $if nc,and ; no error and................... ;AC000;
1800 JC $$IF99
1801
1802 cmp ax,cx ; is all of file read ? :
1803
1804 ; $if z ; all of file read..............: ;AC000;
1805 JNZ $$IF99
1806
1807 add DOSPos[0],ax ; save amount read for later lseek ;AN001;
1808 adc DOSPos[2],0 ; save amount read for later lseek ;AN001;
1809
1810 add dx,ax ; update pointer for DOS Read
1811 mov pDOSEnd,DX ; point to End of dos DOS
1812 sub DOSLenLow,AX ; decrement remaining
1813 sbb DOSLenHigh,0 ; do 32 bit arithmetic
1814 clc ; reset fail flag
1815
1816 ; $endif ; ;AC000;
1817 $$IF99:
1818
1819 ; $endif ; ;AC000;
1820 $$EN95:
1821
1822 ret
1823
1824 ENDPROC Fill_Memory
1825
1826 BREAK <SYS - Check_SYS_Conditions >
1827 ;******************* START OF SPECIFICATIONS ***********************************
1828 ;Routine name: Check_SYS_Conditions
1829 ;*******************************************************************************
1830 ;
1831 ;Description: Verify that the target disk is in a state that a SYS to it will
1832 ; be allowed. If an error occurs in any of the called routines,
1833 ; the return code will already be loaded by the failing routine.
1834 ;
1835 ;Called Procedures: Verify_File_System
1836 ; Read_Directory
1837 ; Verify_File_Location
1838 ; Determine_Free_Space
1839 ;
1840 ;Input: None
1841 ;
1842 ;Output: no error - CF = 0
1843 ; error - CF = 1 AX = return code (message #)
1844 ;
1845 ;Change History: Created 5/01/87 FG
1846 ;
1847 ;******************* END OF SPECIFICATIONS *************************************
1848 ;******************+ START OF PSEUDOCODE +**************************************
1849 ;
1850 ; START Check_SYS_Conditions
1851 ;
1852 ; verify target is a FAT file system (CALL Verify_File_System)
1853 ; if no error and
1854 ; load root directory of target (CALL Read_Directory)
1855 ; if no error and
1856 ; check that IBMBIO,IBMDOS are in right place (CALL Verify_File_Location)
1857 ; if no error and
1858 ; check for sufficient space for system files (CALL Determine_Free_Space)
1859 ; if no error
1860 ; load return code (success)
1861 ; reset fail flag
1862 ; endif
1863 ; ret
1864 ;
1865 ; END Check_SYS_Conditions
1866 ;
1867 ;******************- END OF PSEUDOCODE -**************************************
1868
1869 public Check_SYS_Conditions
1870
1871 Check_SYS_Conditions PROC NEAR
1872
1873 call Verify_File_System ; verify target is a FAT file system ;AN000;
1874
1875 ; $if nc,and ; no error and ;AN000;
1876 JC $$IF102
1877
1878 call Read_Directory ; load root directory of target ;AN000;
1879
1880 ; $if nc,and ; no error and ;AN000;
1881 JC $$IF102
1882
1883 call Verify_File_Location ; check that IBMBIO,IBMDOS are in right;AN000;
1884 ; place
1885 ; $if nc ; no error and ;AN000;
1886 JC $$IF102
1887
1888 call Determine_Free_Space ; check if enough space for system file;AN000;
1889
1890 ; $endif ; ;AN000;
1891 $$IF102:
1892
1893 ret ; ;AN000;
1894
1895 ENDPROC Check_SYS_Conditions
1896
1897 BREAK <SYS - Verify_File_System >
1898 ;******************* START OF SPECIFICATIONS ***********************************
1899 ;Routine name: Verify_File_System
1900 ;*******************************************************************************
1901 ;
1902 ;Description: Get the file system for the specified drive, then compare to
1903 ; FAT. If not, issue message and exit. Must ensure that target
1904 ; drive has media in it before this routine is called
1905 ;
1906 ;Note: This routine contains code that is specifically required for
1907 ; operation on DOS 3.3. This code must be removed for later releases
1908 ; of DOS.
1909 ;
1910 ;Called Procedures: None
1911 ;
1912 ;Input: Drive Number (0=default, 1=A, 2=B) in BL
1913 ;
1914 ;Output: no error - CF = 0
1915 ; error - CF = 1
1916 ; AX = return code
1917 ; AH = utility messages
1918 ; AL = 15d - Not able to SYS to xxx file system
1919 ; CX = 1 - only one substitution
1920 ; DS:SI = sublist for substitution
1921 ;
1922 ;Change History: Created 5/01/87 FG
1923 ;
1924 ;******************* END OF SPECIFICATIONS *************************************
1925 ;******************+ START OF PSEUDOCODE +**************************************
1926 ;
1927 ; START Verify_File_System
1928 ;
1929 ; if dos = current
1930 ; load drive id (BL)
1931 ; get_extended_device_parameters (INT21 IOCtl + 0Dh <440D> CX=086E) for drive
1932 ; if error - check if old version destination
1933 ; find out what the error was (CALL Get_DOS_Error)
1934 ; if not old version error
1935 ; load return code (DOS Extended Error Class)
1936 ; set fail flag
1937 ; else
1938 ; reset fail flag
1939 ; endif
1940 ; else
1941 ; if returned file system type = "FAT12 " or
1942 ; if returned file system type = "FAT16 "
1943 ; reset fail flag
1944 ; else
1945 ; indicate insert required
1946 ; set up pointer for insert - sublist
1947 ; load return code (Unable to SYS to xxxxxxxx file system)
1948 ; set fail flag
1949 ; endif
1950 ; endif
1951 ; endif
1952 ;
1953 ; ret
1954 ;
1955 ; END Verify_File_System
1956 ;
1957 ;******************- END OF PSEUDOCODE -**************************************
1958
1959 public Verify_File_System
1960
1961 Verify_File_System PROC NEAR
1962
1963 cmp DOS_VER,0 ; running on current DOS ? ;AN019;
1964 ; $if e ; if we are ;AN019;
1965 JNE $$IF104
1966 mov bl,TargDrvNum ; load drive id (BL) ;AN000;
1967 lea dx,IOCtl_Buf ; point to output buffer ;AN000;
1968 mov ax,(GetSetMediaID shl 8) + 0 ; get volid, ser# and filetype ;AC019;
1969 INT 21h ; INT 21 GetSetMediaID request <6900> ;AC019;
1970
1971 ; $if c ; error - check if old version dest ;AN000;
1972 JNC $$IF105
1973
1974 call Get_DOS_Error ; find out what the error was ;AN000;
1975
1976 cmp al,old_type_media ; is it IBM but < 4.0 ? ;AN000;
1977
1978 ; $if ne ; not old version error ;AN000;
1979 JE $$IF106
1980
1981 mov ah,DOS_error ; load return code (DOS Extended Error);AN000;
1982 stc ; set fail flag ;AN000;
1983
1984 ; $else ; ;AN000;
1985 JMP SHORT $$EN106
1986 $$IF106:
1987
1988 clc ; reset fail flag ;AN000;
1989
1990 ; $endif ; ;AN000;
1991 $$EN106:
1992
1993 ; $else ; ELSE it is => 4.00 ;AN000;
1994 JMP SHORT $$EN105
1995 $$IF105:
1996
1997 lea si,IOCtl_File_Sys ; see if file type is fat12 ;AN000;
1998 lea di,fat_12 ; ;AN000;
1999 mov cx,file_sys_size ; ;AN000;
2000 cld ; ;AN000;
2001 repe cmpsb ; ;AN000;
2002 cmp cx,3 ; did it fail at the 2 in fat12 ? ;AN000;
2003
2004 ; $if e,and ; if it did and............ ;AN000;
2005 JNE $$IF110
2006
2007 cmp BYTE PTR ds:[si-1],"6" ; was it a 6 ? : ;AN000;
2008
2009 ; $if e ; if it was...............: ;AN000;
2010 JNE $$IF110
2011
2012 repe cmpsb ; then keep going ;AN000;
2013
2014 ; $endif ; ;AN000;
2015 $$IF110:
2016
2017 cmp cx,0 ; did we reach the end ? ;AN000;
2018
2019 ; $if e ; if we did it was "FAT12 " or ;AN000;
2020 JNE $$IF112
2021 ; "FAT16 " so its OK to SYS
2022
2023 clc ; reset fail flag ;AN000;
2024
2025 ; $else ; ;AN000;
2026 JMP SHORT $$EN112
2027 $$IF112:
2028
2029 lea di,File_Sys_End ; set up pointer to end of insert ;AN000;
2030 dec di ; back up to last character ;AN000;
2031 mov cx,file_sys_size ; strip off trailing blanks ;AN017;
2032 mov al," " ; strip off trailing blanks ;AN017;
2033 std ; scan backwards ;AN017;
2034 repe scas IOCTL_File_Sys ; ;AN017;
2035 cld ; stops at 2 past last " " ;AN017;
2036 inc di ; 1 past ;AN017;
2037 inc di ; last (first) blank ;AN017;
2038 xor al,al ; make it an ASCIIZ ;AN017;
2039 stos IOCTL_File_Sys ; ;AN017;
2040 lea si,IOCTL_File_Sys ; set up pointer to the insert ;AN000;
2041 mov [insert_ptr_off],si ; ;AN017;
2042 mov [insert_ptr_seg],ds ; ;AN017;
2043 lea si,sublist ; set pointer to SUBLIST ;AN017;
2044 mov ax,(util_C shl 8) + cant_sys ; load return code ;AN000;
2045 ; - Unable to SYS to xxx file system
2046 stc ; set fail flag ;AN000;
2047
2048 ; $endif ; ;AN000;
2049 $$EN112:
2050
2051 ; $endif ; ;AN000;
2052 $$EN105:
2053
2054 ; $else ; not running on current DOS ;AN019;
2055 JMP SHORT $$EN104
2056 $$IF104:
2057
2058 clc ; keep going ;AN019;
2059
2060 ; $endif ; running on current DOS ;AN019;
2061 $$EN104:
2062
2063 ret ; ;AN000;
2064
2065 ENDPROC Verify_File_System
2066
2067 BREAK <SYS - Read_Directory >
2068 ;******************* START OF SPECIFICATIONS ***********************************
2069 ;Routine name: Read_Directory
2070 ;*******************************************************************************
2071 ;
2072 ;Description: Read in first sector of directory. The reason that we do the
2073 ; direct read of the directory is the find first/next or search
2074 ; first/next do an exclusive search for volume labels. By using
2075 ; these CALLs, there is no way to determine if a volume label
2076 ; occupies the first location in the directory. Hence we get sleazy
2077 ; and read the directory directly (no pun intended) to get this
2078 ; info. Only read in the first sector of directory. Also, this
2079 ; ensures there is a media in the drive.
2080 ;
2081 ;CALLed Procedures: Prompt_for_Media, Find_DPB
2082 ;
2083 ;Input: None
2084 ;
2085 ;Output: no error - CF = 0
2086 ; error - CF = 1 AX = return code (message #)
2087 ;
2088 ;Change History: Created 5/01/87 FG
2089 ;
2090 ;******************* END OF SPECIFICATIONS *************************************
2091 ;******************+ START OF PSEUDOCODE +**************************************
2092 ;
2093 ; START Read_Directory
2094 ;
2095 ; set up drive letter in destignation filespecs
2096 ; call Find_DPB to get directory location
2097 ; load first DIR sector number
2098 ; point at buffer for directory
2099 ; read first sector of directory (INT 25h)
2100 ; ret
2101 ;
2102 ; END Read_Directory
2103 ;
2104 ;******************- END OF PSEUDOCODE -**************************************
2105
2106 public Read_Directory
2107
2108 Read_Directory PROC NEAR
2109
2110 mov al,TargDrv ; set up drive letter in destignation filespecs
2111 mov BIOSName,al ; point names at destination drive
2112 mov DOSName,al ;
2113
2114 MOV DL,TargDrvNum ; load drive
2115 PUSH DS ; save register
2116 call Find_DPB ; initalize DPB parameters
2117 POP AX
2118 mov ds,ax
2119 mov es,ax
2120 xor ax,ax ; request a read
2121 mov dx,[first_dir_sector] ; read starting dir sector
2122 mov [packet],dx ; get starting dir sector ;AN001;
2123 mov bx,offset DIR_SECTOR
2124 mov PACKET_BUFFER[0],bx ; ;AN001;
2125 mov PACKET_BUFFER[2],ds ; ;AN001;
2126 mov word ptr [packet_sectors],1 ; ;AN001;
2127 call Direct_Access ; to read the sector
2128
2129 mov ax, (util_B shl 8) + write_fail ; load message ;AC000;
2130 ; - Write failure, diskette unuseable
2131 ; in case an error occured
2132 ret
2133
2134 ENDPROC Read_Directory
2135
2136 BREAK <SYS - Verify_File_Location >
2137 ;******************* START OF SPECIFICATIONS ***********************************
2138 ;Routine name: Verify_File_Location
2139 ;*******************************************************************************
2140 ;
2141 ;Last Update: 09/22/87
2142 ;
2143 ;Description: Determines if IBMBIO and IBMDOS are the first two directory
2144 ; entries, or if these entries are empty. If so, find the size
2145 ; of the files if they exist. If spaces not empty and don't
2146 ; contain IBMBIO and IBMDOS, set fail flag and load return code.
2147 ; Also determines if existing IBMBIO starts in cluster 2. If not
2148 ; set fail flag and load return code.
2149 ;
2150 ;CALLed Procedures: None
2151 ;
2152 ;Input: DIR in BUFFER
2153 ;
2154 ;Output: no error - CF = 0
2155 ; error - CF = 1
2156 ; AX = return code
2157 ; AH = utility \1dessages
2158 ; AL = 8 - No room for system on destination disk
2159 ; 9 - Incompatible system size
2160 ;
2161 ;Change History: Created 5/01/87 FG
2162 ;
2163 ;******************* END OF SPECIFICATIONS *************************************
2164 ;******************+ START OF PSEUDOCODE +**************************************
2165 ;
2166 ; START Verify_File_Location
2167 ;
2168 ; if all files deleted (Dir_Name in dir is 00h)
2169 ; reset fail flag
2170 ; else
2171 ; if first file deleted (Dir_Name is 0E5h)
2172 ; reset fail flag
2173 ; else
2174 ; if first file IBMBIO.COM
2175 ; get IBMBIO Size
2176 ; indicate we found IBMBIO
2177 ; clear error flag
2178 ; else
2179 ; call Move_DIR_Entry
2180 ; call Free_Cluster
2181 ; endif
2182 ; endif
2183 ; if no error so far and
2184 ; if IBMBIO found
2185 ; call Free_Cluster
2186 ; endif
2187 ; if no error so far
2188 ; if all files deleted starting at second location or
2189 ; if second file deleted (Dir_Name is 0E5h)
2190 ; reset fail flag
2191 ; else
2192 ; if second file IBMDOS.COM
2193 ; get IBMDOS size
2194 ; indicate we found IBMDOS
2195 ; reset fail flag
2196 ; else
2197 ; call Move_DIR_Entry
2198 ; endif
2199 ; endif
2200 ; endif
2201 ; endif
2202 ;
2203 ; ret
2204 ;
2205 ; END Verify_File_Location
2206 ;******************- END OF PSEUDOCODE -**************************************
2207
2208 public Verify_File_Location
2209
2210 Verify_File_Location PROC NEAR
2211 ;---------------------------------------
2212 ; Now see if the first two directory
2213 ; entries are available...
2214 ; First check for being free:
2215 ;---------------------------------------
2216 mov bp,OFFSET DIR_SECTOR
2217 mov si,bp
2218 cmp BYTE PTR [si],empty ; empty dir?
2219
2220 ; $if e,or ; if all files deleted ;AC012;
2221 JE $$LL118
2222 ; (Dir_Name in dir is 00h)
2223
2224 cmp BYTE PTR [si],deleted ; is first file deleted ?
2225
2226 ; $if e ; if it is ;AC012;
2227 JNE $$IF118
2228 $$LL118:
2229 ; (Dir_Name is 0E5h)................:
2230 clc ; clear error flag ;AN003;
2231 call Free_Cluster ; check the cluster chain just in case ;AC012;
2232
2233 ; $else long ; not empty ;AC000;
2234 JMP $$EN118
2235 $$IF118:
2236 ;---------------------------------------
2237 ; The first entry is not free. See if
2238 ; the BIOS is there.
2239 ;---------------------------------------
2240 mov di,OFFSET FCBBIO ; pointer to name
2241 mov cx,file_spec_length ; length of name
2242 cld ; go forward
2243 rep cmpsb ; check it
2244
2245 ; $if e ; first file IBMBIO.COM ;AC000;
2246 JNE $$IF120
2247
2248 dec BIOSEntFree ; indicate we found IBMBIO ( = 0)
2249 mov si,bp
2250 mov ax,word ptr ds:[si].dir_size_l ; Get the size of IBMBIO ;AC000;
2251 mov word ptr IBMBIO_Low,ax
2252 mov ax,word ptr ds:[si].dir_size_h ; ;AC000;
2253 mov word ptr IBMBIO_High,ax
2254 cmp ds:[si].dir_first,2 ; does IBMBIO own Clust 2? ;AC005;
2255 ; $if e ; if so ;AC005;
2256 JNE $$IF121
2257 inc [bio_owns_it] ; - keep track ;AC005;
2258 ; $endif ; ;AC005;
2259 $$IF121:
2260
2261 call Free_Cluster ; ;AN003;
2262
2263 ; $else ; its not IBMBIO ;AC000;
2264 JMP SHORT $$EN120
2265 $$IF120:
2266
2267 mov si,bp ; restore pointer to start of entry ;AN003;
2268 call Move_DIR_Entry ; move the entry out of the way ;AN003;
2269
2270 ; $if nc,and ; ;AN003;
2271 JC $$IF124
2272
2273 call Free_Cluster ; make sure reqd. clusters are free ;AN003;
2274
2275 ; $if nc ; ;AC000;
2276 JC $$IF124
2277
2278 xor ax,ax ;
2279
2280 ; $else ; ;AC000;
2281 JMP SHORT $$EN124
2282 $$IF124:
2283
2284 mov ax,(util_B shl 8) + no_room ; load return code in case we fail;AN000;
2285 stc ; - No room for system on dest... ;AC000;
2286
2287 ; $endif ; ;AC000;
2288 $$EN124:
2289
2290 ; $endif ; ;AC000;
2291 $$EN120:
2292
2293 ; $endif ; ;AC000;
2294 $$EN118:
2295
2296 ;---------------------------------------
2297 ; Check the second entry
2298 ;---------------------------------------
2299
2300 ; $if nc ; if no errors so far ;AC000;
2301 JC $$IF129
2302
2303 ; ensure that the first sector of root ;AN003;
2304 ; is loaded ;AN003;
2305 mov ax,[first_dir_sector] ; get starting dir sector ;AN001;
2306 mov packet,ax ; ;AN001;
2307 mov [packet_buffer],offset DIR_SECTOR ; ;AN001;
2308 mov word ptr [packet_sectors],1 ; ;AN001;
2309 xor ax,ax ; request a read
2310 call Direct_Access ; to read the root
2311
2312 ; $if nc ; ;AC000;
2313 JC $$IF130
2314
2315 add bp,TYPE dir_entry ; ;AC000;
2316 mov si,bp ; ;AC000;
2317 mov ax,(util_B shl 8) + no_room ; load return code in case we fail ;AC000;
2318 ; - No room for system on dest..
2319 cmp BYTE PTR [si],empty ; empty dir entry?
2320
2321 ; $if e,or ; if deleted starting at 2nd entry or. ;AC000;
2322 JE $$LL131
2323
2324 cmp BYTE PTR [si],deleted ; deleted ? :
2325
2326 ; $if e ; if deleted (0E5h)...................:;AC000;
2327 JNE $$IF131
2328 $$LL131:
2329
2330 clc ; reset fail flag
2331
2332 ; $else ; ;AC000;
2333 JMP SHORT $$EN131
2334 $$IF131:
2335
2336 ; This entry is not free.
2337 mov di,OFFSET FCBDOS ; see if it is IBMDOS
2338 mov cx,file_spec_length ; length of name
2339 rep cmpsb ; compare it
2340 mov si,bp ; restore pointer to start ;AC000;
2341
2342 ; $if e ; if second file is IBMDOS.COM. ;AC000;
2343 JNE $$IF133
2344
2345 dec DOSEntFree ; indicate we found IBMDOS
2346 mov ax,word ptr ds:[si].dir_size_l ; Get the size of ;AC000;
2347 mov word ptr IBMDOS_Low,ax ; file for IBMDOS
2348 mov ax,word ptr ds:[si].dir_size_h ; ;AC000;
2349 mov word ptr IBMDOS_High,ax
2350 clc ; reset fail flag ;AN000;
2351
2352 ; $else ; error condition ;AC000;
2353 JMP SHORT $$EN133
2354 $$IF133:
2355
2356 call Move_DIR_Entry ; ;AN003;
2357
2358 ; $endif ; ;AC000;
2359 $$EN133:
2360
2361 ; $endif ; ;AC000;
2362 $$EN131:
2363
2364 ; $else ; ;AC000;
2365 JMP SHORT $$EN130
2366 $$IF130:
2367 mov ax,(util_B shl 8) + no_room ; load return code in case we fail ;AN000;
2368 ; $endif ; ;AC000;
2369 $$EN130:
2370
2371 ; $endif ; ;AC000;
2372 $$IF129:
2373
2374 ret ; ;AN000;
2375
2376 ENDPROC Verify_File_Location
2377
2378 BREAK <SYS - Determine_Free_Space >
2379 ;******************* START OF SPECIFICATIONS ***********************************
2380 ;Routine name: Determine_Free_Space
2381 ;*******************************************************************************
2382 ;
2383 ;Last Update: 3/18/87
2384 ;
2385 ;Description: Determine if there is enough space on the disk, given the free
2386 ; space and the space taken up by IBMBIO and IBMDOS to install the
2387 ; new IBMBIO and IBMDOS. Routine will set fail flag and load return
2388 ; code if there is not enough room.
2389 ;
2390 ; Here we make some VERY IMPORTANT assumptions.
2391 ;
2392 ; 1) If IBMBIO exists on the disk currently, we assume it is in the
2393 ; correct place, i.e. at the front of the data area & contiguous.
2394 ; 2) The stub loader portion of IBMBIO is less than 2048 bytes long.
2395 ; This number comes about by assuming we will never overlay
2396 ; anything smaller than 1920 bytes (DOS 1.10 IBMBIO size). This
2397 ; can be expanded to 2048 if we also assume the smallest possible
2398 ; cluster length is 512 bytes.
2399 ;
2400 ; Therefore, if we have an empty disk or IBMBIO exists, then we have
2401 ; enough contiguous room to install the portion of IBMBIO that
2402 ; requires itself to be contiguous.
2403 ;
2404 ;CALLed Procedures: None
2405 ;
2406 ;Input: None
2407 ;
2408 ;Output: no error - CF = 0
2409 ; error - CF = 1
2410 ; AX = return code
2411 ; AH = utility messages
2412 ; AL = 8d - No room for system on destination disk
2413 ;
2414 ;Change History: Created 5/01/87 FG
2415 ;
2416 ;******************* END OF SPECIFICATIONS *************************************
2417 ;******************+ START OF PSEUDOCODE +**************************************
2418 ;
2419 ; START Determine_Free_Space
2420 ;
2421 ; get disk free space (INT21 Get_Drive_Freespace + 00 <3600>)
2422 ; compute Bytes/Cluster (32bit math required)
2423 ; convert current IBMBIO into cluster size (CALL Get_Cluster)
2424 ; convert current IBMDOS into cluster size (CALL Get_Cluster)
2425 ; get total number of clusters available
2426 ; convert new IBMBIO into cluster size (CALL Get_Cluster)
2427 ; convert new IBMDOS into cluster size (CALL Get_Cluster)
2428 ; get total number of clusters needed
2429 ; if available clusters < needed clusters
2430 ; load return code (No room for system on destination disk)
2431 ; set fail flag
2432 ; else
2433 ; reset fail flag
2434 ; endif
2435 ; ret
2436 ;
2437 ; END Determine_Free_Space
2438 ;
2439 ;******************- END OF PSEUDOCODE -**************************************
2440
2441 public Determine_Free_Space
2442
2443 Determine_Free_Space PROC NEAR
2444
2445 mov ah,Get_Drive_Freespace ; get disk free space
2446 mov dl,TargDrvNum ; get the drive number
2447 INT 21h ; Get_Drive_Freespace <36xx>
2448 ; compute Bytes/Cluster - 16 bit math ok
2449 ; AX = sectors / cluster
2450 ; CX = bytes / sector
2451 ; BX = available clusters
2452 mul cx ; get bytes/cluster
2453 ; result left in AX
2454 mov Bytes_Per_Cluster,ax ; save this value for Get_Clusters
2455 mov Number_Free_Clusters,bx ; save available space
2456
2457 mov ax,IBMBIO_Low ; low result in AX, High result in DX
2458 mov dx,IBMBIO_High
2459 call Get_Cluster ; convert old IBMBIO into cluster size
2460
2461 add Number_Free_Clusters,ax ; add it to available space
2462
2463 mov ax,IBMDOS_Low ; low result in AX, High result in DX
2464 mov dx,IBMDOS_High
2465 call Get_Cluster ; convert old IBMDOS into cluster size
2466
2467 add Number_Free_Clusters,AX ; get total number of clusters available
2468
2469 mov ax,NEWBIO_Size_Low ; find total size of new DOS and BIOS
2470 mov dx,NEWBIO_Size_High
2471
2472 call Get_Cluster ; convert new IBMBIO into cluster size
2473
2474 mov Need_Clusters,ax ;save new BIO clusters
2475
2476 mov ax,NEWDOS_Size_Low
2477 mov dx,NEWDOS_Size_High
2478
2479 call Get_Cluster ; convert new IBMDOS into cluster size
2480
2481 add AX,Need_Clusters ; get total number of clusters needed
2482
2483 cmp AX,Number_Free_Clusters ;Now see if there is enough room
2484 ; for all of it on the disk
2485 ; $if a ; if needed > available clusters ;AC000;
2486 JNA $$IF140
2487
2488 mov ax,(util_B shl 8) + no_room ; load return code ;AC000;
2489 ; - No room for system on dest..
2490 stc ; set fail flag
2491
2492 ; $else ; ;AC000;
2493 JMP SHORT $$EN140
2494 $$IF140:
2495
2496 clc ; reset fail flag
2497
2498 ; $endif ; ;AC000;
2499 $$EN140:
2500
2501 ret ; ;AN000;
2502
2503 ENDPROC Determine_Free_Space
2504
2505 BREAK <SYS - Get_Cluster >
2506 ;******************* START OF SPECIFICATIONS ***********************************
2507 ;Routine name: Get_Cluster
2508 ;*******************************************************************************
2509 ;
2510 ;Description: Convert bytes to clusters, rounding up to the next
2511 ; cluster size if needed.
2512 ;
2513 ;Called Procedures: None
2514 ;
2515 ;Input: (AX) = Number of bytes
2516 ; Bytes_Per_Cluster = # of bytes per cluster
2517 ;
2518 ;Output: (AX) = Number of clusters
2519 ;
2520 ;Registers used: AX BX DX
2521 ;
2522 ;Change History: Created 5/01/87 FG
2523 ;
2524 ;******************* END OF SPECIFICATIONS *************************************
2525 ;******************+ START OF PSEUDOCODE +**************************************
2526 ;
2527 ; START Get_Cluster
2528 ;
2529 ; divide size by bytes_per_cluster
2530 ; if there is a remainder
2531 ; round up to next cluster
2532 ; endif
2533 ; ret
2534 ;
2535 ; END Get_Cluster
2536 ;
2537 ;******************- END OF PSEUDOCODE -**************************************
2538
2539 public Get_Cluster
2540
2541 Get_Cluster PROC NEAR
2542
2543 mov bx,Bytes_Per_Cluster ; Bytes/cluster
2544 div bx ; divide size by bytes_per_cluster
2545 cmp dx,0 ; is there a remainder in DX?
2546
2547 ; $if ne ; if there is a remainder ;AC000;
2548 JE $$IF143
2549 ; we have another cluster to round up
2550 inc ax ; round up to next cluster
2551
2552 ; $endif ; ;AC000;
2553 $$IF143:
2554
2555 ret
2556
2557 ENDPROC Get_Cluster
2558
2559 BREAK <SYS - Do_SYS >
2560 ;******************* START OF SPECIFICATIONS ***********************************
2561 ;Routine name: Do_SYS
2562 ;*******************************************************************************
2563 ;
2564 ;Description: Control routine to handle the transfer of system files from
2565 ; memory to target drive.
2566 ;
2567 ;Called Procedures: Create_System
2568 ; Fill_Memory
2569 ; Dump_Memory
2570 ;
2571 ;Input: IBMBIO_Size_Loaded
2572 ; IBMDOS_Size_Loaded
2573 ;
2574 ;Output: no error - CF = 0
2575 ; error - CF = 1 AX = return code (message #)
2576 ;
2577 ;Change History: Created 5/01/87 FG
2578 ;
2579 ;******************* END OF SPECIFICATIONS *************************************
2580 ;******************+ START OF PSEUDOCODE +**************************************
2581 ;
2582 ; START Do_SYS
2583 ;
2584 ; create new IBMBIO and IBMDOS, in place if exist (CALL CREATE_SYSTEM)
2585 ; if no error
2586 ; search
2587 ; write out contents of memory to file (CALL Dump_Memory)
2588 ; load error return code (assume error)
2589 ; leave if error
2590 ; exit if if all files copied
2591 ; reset fail flag
2592 ; orelse
2593 ; read in file from source (CALL Fill_Memory)
2594 ; load error return code (assume error)
2595 ; leave if error
2596 ; endloop
2597 ; set fail flag
2598 ; endsearch
2599 ; endif
2600 ; ret
2601 ;
2602 ; END Do_SYS
2603 ;
2604 ;******************- END OF PSEUDOCODE -**************************************
2605
2606 public Do_SYS
2607
2608 Do_SYS PROC NEAR
2609
2610 call CREATE_SYSTEM ; create IBMBIO and IBMDOS, in place ;AN000;
2611
2612 ; $if nc ; no error ;AC000;
2613 JC $$IF145
2614
2615 push ds
2616 lds bx,THIS_DPB ; set up pointer to DPB ;AC000;
2617 mov [bx.dpb_next_free],2 ; reset Allocation to start of disk ;AC000;
2618 pop ds ; so BIOS goes in right place!
2619
2620 ; $search ; ;AC000;
2621 $$DO146:
2622
2623 call Dump_Memory ; write out contents of memory to file
2624
2625 mov ax,(util_B shl 8) + no_room ; load error RC (assume error) ;AC000;
2626
2627 ; $leave c ; quit if error ;AC000;
2628 JC $$EN146
2629
2630 mov ax,DOSLenHigh ; more DOS to move ?
2631 or AX,DOSLenLow ; more low dos
2632 or AX,BIOSLenHigh ; more high BIOS
2633 or AX,BIOSLenLow ; more low BIOS
2634
2635 ; $exitif z ; if all files copied ;AC000;
2636 JNZ $$IF146
2637
2638 clc ; reset fail flag ;AC000;
2639
2640 ; $orelse ; ;AC000;
2641 JMP SHORT $$SR146
2642 $$IF146:
2643
2644 call get_rest_of_system
2645
2646 mov ax,(util_B shl 8) + no_room ; load error RC (assume error) ;AC000;
2647
2648 ; $leave c ; if error ;AC000;
2649 JC $$EN146
2650
2651 ; $endloop ; ;AC000;
2652 JMP SHORT $$DO146
2653 $$EN146:
2654
2655 ; $endsrch ; ;AC000;
2656 $$SR146:
2657
2658 ; $endif ; ;AC000;
2659 $$IF145:
2660
2661 ret ; ;AN000;
2662
2663 ENDPROC Do_SYS
2664
2665 PUBLIC Get_Rest_of_System
2666
2667 Get_Rest_of_System Proc near
2668
2669 pushf ; ;AN001;
2670
2671 mov bx,BIOSOutFH ; ;AN001;
2672 mov ah,Close ; ;AN001;
2673 int 21h ; ;AN001;
2674
2675 mov bx,DOSOutFH ; ;AN001;
2676 mov ah,Close ; ;AN001;
2677 int 21h ; ;AN001;
2678
2679 mov dx,offset SourceBIOSName ; ;AN001;
2680 mov ax,(OPEN SHL 8) + not_used ; open file for read
2681 int 21h ; ;AN001;
2682 mov biosinfh,ax
2683
2684 mov dx,offset SourceDOSName ; ;AN001;
2685 mov ax,(OPEN SHL 8) + not_used ; open file for read
2686 int 21h ; ;AN001;
2687 mov dosinfh,ax
2688
2689 call Fill_Memory ; read in file from source
2690
2691 mov bx,BIOSInFH ; ;AN001;
2692 mov ah,Close ; ;AN001;
2693 int 21h ; ;AN001;
2694
2695 mov bx,DOSInFH ; ;AN001;
2696 mov ah,Close ; ;AN001;
2697 int 21h ; ;AN001;
2698
2699 mov dx,offset BIOSName ; ;AN001;
2700 mov ax,(Open shl 8) + 2 ; Open file
2701 INT 21h
2702 mov BIOSOutFH,ax
2703
2704 mov dx,offset DOSName ; ;AN001;
2705 mov ax,(Open shl 8) + 2 ; Open file
2706 INT 21h
2707 mov DOSOutfh,ax
2708
2709 popf ; ;AN001;
2710
2711 RET
2712
2713 endproc get_rest_of_system
2714
2715 BREAK <SYS - Create_System >
2716 ;******************* START OF SPECIFICATIONS ***********************************
2717 ;Routine name: Create_System
2718 ;*******************************************************************************
2719 ;
2720 ;Description:
2721 ;
2722 ;Called Procedures: Create_File
2723 ;
2724 ;Input: None
2725 ;
2726 ;Output: IBMBIO_Handle
2727 ; IBMDOS_Handle
2728 ;
2729 ;Change History: Created 5/01/87 FG
2730 ;
2731 ;******************* END OF SPECIFICATIONS *************************************
2732 ;******************+ START OF PSEUDOCODE +**************************************
2733 ;
2734 ; START Create_System
2735 ;
2736 ; create IBMBIO (CALL Create_File)
2737 ; if no error and
2738 ; save handle to IBMBIO_Handle
2739 ; create IBMDOS (CALL Create_File)
2740 ; if no error
2741 ; save handle to IBMDOS_Handle
2742 ; reset fail flag
2743 ; endif
2744 ; ret
2745 ;
2746 ; END Create_System
2747 ;
2748 ;******************- END OF PSEUDOCODE -**************************************
2749
2750 public Create_System
2751
2752 Create_System PROC NEAR
2753
2754 mov [open_seg],ds
2755 mov dx,OFFSET BIOSName ; point to IBMBIO ASCIIZ string
2756 mov al,[BIOSEntFree] ; get status of IBMBIO ;AN006;
2757 mov [EntryFree],al ; update file status (0 = found,1 = not;AN006;
2758
2759 call Create_File ; create IBMBIO ;AN000;
2760
2761 ; $if nc,and ; no error and ;AC000;
2762 JC $$IF154
2763
2764 mov BIOSOutFH,ax ; save handle to IBMBIO_Handle
2765 mov dx,OFFSET DOSName ; pointer to IBMDOS ASCIIZ string
2766 mov al,[DOSEntFree] ; get status of IBMDOS ;AN006;
2767 mov [EntryFree],al ; update file status (0 = found,1 = not;AN006;
2768
2769 call Create_File ; create IBMDOS ;AN000;
2770
2771 ; $if nc ; no error ;AC000;
2772 JC $$IF154
2773
2774 mov DOSOutFH,ax ; save handle to IBMDOS_Handle
2775
2776 ; $endif ; ;AC000;
2777 $$IF154:
2778
2779 ret ; ;AN000;
2780
2781 ENDPROC Create_System
2782
2783 BREAK <SYS - Create_File >
2784 ;******************* START OF SPECIFICATIONS ***********************************
2785 ;Routine name: Create_File
2786 ;*******************************************************************************
2787 ;
2788 ;Last Update: 9/23/87
2789 ;
2790 ;Description: Remove the read only attribute from IBMBIO and IBMDOS. If
2791 ; file not found error occurs, it is okay, because it just
2792 ; means the file was not there. Do create with read-only
2793 ; hidden, and system file attributes. This is an in place
2794 ; create if the file exists already.
2795 ;
2796 ;
2797 ;Called Procedures: None
2798 ;
2799 ;Input: DS:DX = pointer to ASCIIZ string for file create
2800 ;
2801 ;Output: no error - CF = 0
2802 ; AX = file handle
2803 ; error - CF = 1
2804 ; AX = return code
2805 ; AH = extended DOS errors
2806 ;
2807 ;Change History: Created 5/01/87 FG
2808 ;
2809 ;******************* END OF SPECIFICATIONS *************************************
2810 ;******************+ START OF PSEUDOCODE +**************************************
2811 ;
2812 ; START Create_File
2813 ;
2814 ; set file attributes to 0 (INT21 CHMod + SetAtrib <4301>)
2815 ; if no error or
2816 ; if error = file not found and
2817 ; ext Open file with attributes of 7 (INT21 ExtOpen + SetAtrib <6C12> CX=7)
2818 ; if no error
2819 ; reset fail flag
2820 ; else
2821 ; load return code (DOS Extended Error)
2822 ; set fail flag
2823 ; endif
2824 ; ret
2825 ;
2826 ; END Create_File
2827 ;
2828 ;******************- END OF PSEUDOCODE -**************************************
2829
2830 public Create_File
2831
2832 Create_File PROC NEAR
2833
2834 mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0
2835 xor cx,cx ; set attributes to 0
2836 mov [open_off],dx ; save pointer to ASCIIZ for OPEN
2837 INT 21h ; CHMod + SetAtrib <4301>)
2838
2839 ; $if nc ; no error ;AC000;
2840 JC $$IF156
2841
2842 cmp [EntryFree],0 ; is file in the correct spot? ;AN006;
2843 ; $if ne ; if it is not - we have a problem ;AN006;
2844 JE $$IF157
2845 mov dx,[open_off] ; get pointer to ASCIIZ for UNLINK ;AN006;
2846 mov ax,(UNLINK shl 8) ; UNLINK the file
2847 INT 21h ; UNLINK <4100>) ;AN006;
2848 ; $endif ; ;AN006;
2849 $$IF157:
2850 ; $else ; - check the error ;AN006;
2851 JMP SHORT $$EN156
2852 $$IF156:
2853 call Get_DOS_Error ; find out what went wrong ;AN000;
2854 cmp al,file_not_found ; not there?
2855
2856 ; $if e ; IBMBIO was not there ;AC000;
2857 JNE $$IF160
2858 clc ; ok to open ;AC000;
2859 ; $else ; ;AC000;
2860 JMP SHORT $$EN160
2861 $$IF160:
2862 stc ; some other error - quit ;AC000;
2863 ; $endif ; ;AC000;
2864 $$EN160:
2865 ; $endif ; ;AC000;
2866 $$EN156:
2867 ; $if nc ; if no error ;AC006;
2868 JC $$IF164
2869
2870 lds si,OPEN_PARMS ; ;AC005;
2871 xor cx,cx ; DOS system file atributes ;AC005;
2872 cmp DOS_VER,0 ; running on current DOS ? ;AN019;
2873
2874 ; $if ne ; if on old DOS ;AN019;
2875 JE $$IF165
2876 mov dx,si ; DS:DX - file name ;AN019;
2877 mov ax,(Creat shl 8) + 0 ; Create file <3D00> ;AN019;
2878 ; $else ; ;AN019;
2879 JMP SHORT $$EN165
2880 $$IF165:
2881 mov di,cx ; ;AC005;
2882 dec di ; ;AC005;
2883 mov bx,open_mode ; set up for mode ;AN000;
2884 mov dx,(openit shl 4) + replaceit ; create if does not exist, ;AN000;
2885 ; replace it if it does
2886 mov ax,(ExtOpen shl 8) + 0 ; ext Open file with attributes of 0 ;AN000;
2887 ; ExtOpen + SetAtrib <6C12> CX=0
2888 ; $endif ; ;AN019;
2889 $$EN165:
2890
2891 INT 21h ; do the open
2892
2893 ; $endif ; ;AC000;
2894 $$IF164:
2895
2896 ; $if c ; if error ;AN000;
2897 JNC $$IF169
2898
2899 call Get_DOS_Error ; find out what went wrong ;AN000;
2900 mov ah,DOS_error ; load return code (DOS Extended Error);AN000;
2901 stc ; ;AN006;
2902
2903 ; $endif ; ;AN000;
2904 $$IF169:
2905
2906 ret ; ;AC000;
2907
2908 ENDPROC Create_File
2909
2910 BREAK <SYS - Dump_Memory >
2911 ;******************* START OF SPECIFICATIONS ***********************************
2912 ;Routine name: Dump_Memory
2913 ;*******************************************************************************
2914 ;
2915 ;Description: Write out as much of IBMBIOS and IBMDOS as is in memory.
2916 ;
2917 ;Called Procedures: None
2918 ;
2919 ;Input: None
2920 ;
2921 ;Output: no error - CF = 0
2922 ; error - CF = 1
2923 ;
2924 ;Change History: Created 5/01/87 FG
2925 ;
2926 ;******************* END OF SPECIFICATIONS *************************************
2927 ;******************+ START OF PSEUDOCODE +**************************************
2928 ;
2929 ; START Dump_Memory
2930 ;
2931 ; get pointer to start of buffer
2932 ; subtract the start of IBMDOS
2933 ; if lenght is non-zero and . . . . . . . . . . . . . . . .
2934 ; load IBMBIOS handle :
2935 ; write out IBMBIOS (INT21 Write + 00 <4000>) :
2936 ; if no error and . . . . . . . . . . . . . . . . . . . . :
2937 ; if not all data written . . . . . . . . . . . . . . . . :
2938 ; set fail flag
2939 ; endif
2940 ; if no error so far
2941 ; get beginning of dos
2942 ; subtract end of dos
2943 ; if lenght is non-zero and
2944 ; load IBMDOS handle
2945 ; write out IBMDOS (INT21 Write + 00 <4000>)
2946 ; if no error and
2947 ; if not all data written . . . . . . . . . . . . . . . . :
2948 ; set fail flag
2949 ; endif
2950 ; endif
2951 ; ret
2952 ;
2953 ; END Dump_Memory
2954 ;
2955 ;******************- END OF PSEUDOCODE -**************************************
2956
2957 public Dump_Memory
2958
2959 Dump_Memory PROC NEAR
2960
2961 mov ax,4202h ; LSEEK to end of file ;AN001;
2962 mov bx,BIOSOutFH ; ;AN001;
2963 xor cx,cx ; ;AN001;
2964 xor dx,dx ; ;AN001;
2965 int 21h ; ;AN001;
2966 mov ax,4202h ; LSEEK to end of file ;AN001;
2967 mov bx,DOSOutFH ; ;AN001;
2968 xor cx,cx ; ;AN001;
2969 xor dx,dx ; ;AN001;
2970 int 21h ; ;AN001;
2971
2972 mov dx,OFFSET BUF+FAT_BUF ; get pointer to start of buffer
2973 mov cx,pDOS ; beginning of next guy
2974 sub cx,dx ; difference is length
2975
2976 ; $if nz,and ; if lenght is non-zero and....... ;AC000;
2977 JZ $$IF171
2978
2979 mov bx,BIOSOutFH ; load IBMBIOS handle :
2980 mov ah,Write ; write out IBMBIOS :
2981 INT 21h ; Write + 00 <4000> :
2982
2983 ; $if nc,and ; if no error and.................: ;AC000;
2984 JC $$IF171
2985
2986 cmp ax,cx ; Did it work? :
2987
2988 ; $if ne ; all data written................: ;AC000;
2989 JE $$IF171
2990
2991 stc ; set fail flag
2992
2993 ; $endif ; ;AC000;
2994 $$IF171:
2995
2996 ; $if nc ; if no error so far ;AC000;
2997 JC $$IF173
2998
2999 mov dx,pDOS ; get beginning of dos
3000 mov cx,pDOSEnd ; subtract end of dos
3001 sub cx,dx ; difference is length
3002
3003 ; $if nz,and ; if lenght is non-zero and........ ;AC000;
3004 JZ $$IF174
3005
3006 mov bx,DOSOutFH ; load IBMDOS handle :
3007 mov ah,Write ; write out IBMDOS :
3008 INT 21h ; Write + 00 <4000> :
3009
3010 ; $if nc,and ; if no error.....................: ;AC000;
3011 JC $$IF174
3012
3013 cmp ax,cx ; Did it work? :
3014
3015 ; $if ne ; all data written................: ;AC000;
3016 JE $$IF174
3017
3018 stc ; set fail flag
3019
3020 ; $endif ; ;AC000;
3021 $$IF174:
3022
3023 ; $endif ; ;AC000;
3024 $$IF173:
3025
3026 ret
3027
3028 ENDPROC Dump_Memory
3029
3030
3031 BREAK <SYS - Do_End >
3032 ;******************* START OF SPECIFICATIONS ***********************************
3033 ;Routine name: Do_End
3034 ;*******************************************************************************
3035 ;
3036 ;Description: Finish off with IBMBIOS and IBMDOS
3037 ;
3038 ;Called Procedures: Close_File
3039 ; Write_Boot_Record
3040 ;
3041 ;Input: None
3042 ;
3043 ;Output: no error - CF = 0
3044 ;
3045 ;Change History: Created 5/01/87 FG
3046 ;
3047 ;******************* END OF SPECIFICATIONS *************************************
3048 ;******************+ START OF PSEUDOCODE +**************************************
3049 ;
3050 ; START Do_End
3051 ;
3052 ; finish off and close IBMBIOS and IBMDOS (CALL Close_Files)
3053 ; update boot record (CALL Write_Boot_Record)
3054 ; ret
3055 ;
3056 ; END Do_End
3057 ;
3058 ;******************- END OF PSEUDOCODE -**************************************
3059
3060 public Do_End
3061
3062 Do_End PROC NEAR
3063
3064 call Close_File ; finish off & close IBMBIOS and IBMDOS;AN000;
3065
3066 call Write_Boot_Record ; update boot record ;AN000;
3067
3068 ret ; ;AN000;
3069
3070 ENDPROC Do_End
3071
3072 BREAK <SYS - Close_File >
3073 ;******************* START OF SPECIFICATIONS ***********************************
3074 ;Routine name: Close_File
3075 ;*******************************************************************************
3076 ;
3077 ;Description: Set date and time on IBMBIOS and IBMDOS and close
3078 ; them.
3079 ;
3080 ;Called Procedures: None
3081 ;
3082 ;Input: BIOSTime, BIOSOutFH, DOSTime. DOSOutFH
3083 ;
3084 ;Output: IBMBIOS and IBMDOS closed
3085 ;
3086 ;Change History: Created 5/01/87 FG
3087 ;
3088 ;******************* END OF SPECIFICATIONS *************************************
3089 ;******************+ START OF PSEUDOCODE +**************************************
3090 ;
3091 ; START Close_File
3092 ;
3093 ; load IBMBIOS time and date
3094 ; load IBMBIOS handle
3095 ; update file times (INT21 File_Times + 01 <5701>)
3096 ; close file (INT21 Close + 00 <3E00>)
3097 ; load IBMDOS time and date
3098 ; load IBMDOS handle
3099 ; update file times (INT21 File_Times + 01 <5701>)
3100 ; close file (INT21 Close + 00 <3E00>)
3101 ; ret
3102 ;
3103 ; END Close_File
3104 ;
3105 ;******************- END OF PSEUDOCODE -**************************************
3106
3107 public Close_File
3108
3109 Close_File PROC NEAR
3110
3111 mov cx,BIOSTime ; load IBMBIOS time and date
3112 mov dx,BIOSTime+2
3113 mov bx,BIOSOutFH ; load IBMBIOS handle
3114 mov ax,(File_Times SHL 8) + set ; update file times
3115 INT 21h ; File_Times + 01 <5701>
3116 mov ah,Close ; close file IBMBIO
3117 INT 21h ; Close + not_used <3Exx>
3118 mov cx,DOSTime ; load IBMDOS time and date
3119 mov dx,DOSTime+2
3120 mov bx,DOSOutFH ; load IBMDOS handle
3121 mov ax,(File_Times SHL 8) + set ; update file times
3122 INT 21h ; File_Times + 01 <5701>
3123 mov ah,Close ; close file IBMDOS
3124 INT 21h ; Close + not_used <3Exx>
3125
3126 mov dx,offset BIOSName ; ;AN001;
3127 mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0
3128 mov cx,DOS_system_atrib ; DOS system file atributes
3129 INT 21h ; CHMod + SetAtrib <4301>)
3130
3131 mov dx,offset DOSName ; ;AN001;
3132 mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0
3133 mov cx,DOS_system_atrib ; DOS system file atributes
3134 INT 21h ; CHMod + SetAtrib <4301>)
3135
3136 ret ; ;AN000;
3137
3138 ENDPROC Close_File
3139
3140 BREAK <SYS - Write_Boot_Record >
3141 ;******************* START OF SPECIFICATIONS ***********************************
3142 ;Routine name: Write_Boot_Record
3143 ;*******************************************************************************
3144 ;
3145 ;Description: Get a best guess EBPB and get the Media ID or fill the
3146 ; information in manually. Write out the canned boot record
3147 ; and then make IOCtl calls to set the EBPB and Media ID.
3148 ;
3149 ;Called Procedures: Create_Serial_ID
3150 ;
3151 ;Input: None
3152 ;
3153 ;Output: Boot record on destination media is installed.
3154 ;
3155 ;Change History: Created 5/01/87 FG
3156 ;
3157 ;******************* END OF SPECIFICATIONS *************************************
3158 ;******************+ START OF PSEUDOCODE +**************************************
3159 ;
3160 ; START Write_Boot_Record
3161 ;
3162 ; get BPB using IOCtl Get Device Parameters (INT21 IOCtl + 0Dh <440d> CX=0860)
3163 ; get volid, ser# and file type using IOCtl Get Media ID (INT21 IOCtl + 0Dh <440d> CX=086E)
3164 ; if error and
3165 ; get Extended error
3166 ; if 'unknown media' - set fields manually
3167 ; compute serial id and put in field (CALL Create_Serial_ID)
3168 ; copy in volume label if available
3169 ; set pointer to FAT1x (CALL FAT_Size)
3170 ; move file system string into Boot_System_ID field
3171 ; else
3172 ; set fail flag
3173 ; load return code (DOS error)
3174 ; endif
3175 ; if no fail flag
3176 ; if fixed media
3177 ; fill in Ext_PhyDrv in canned boot record
3178 ; endif
3179 ; set BPB using data from GET BPB IOCTL
3180 ; write out canned boot record (INT26)
3181 ; set volid, ser# and file type using Set Media ID (INT21 SetID <6900> CX=084E)
3182 ; endif
3183 ; ret
3184 ;
3185 ; END Write_Boot_Record
3186 ;
3187 ;******************- END OF PSEUDOCODE -**************************************
3188
3189 public Write_Boot_Record
3190
3191 Write_Boot_Record PROC NEAR
3192
3193 mov bl,TargDrvNum ; Drive number ;AN000;
3194 mov dx,offset DeviceParameters ; ;AN000;
3195 mov cx,(rawio shl 8) + get_device_parameters ; Generic IOCtl Request ;AN000;
3196 ; CX=0860
3197 mov ax,(IOCtl shl 8) + generic_ioctl ; get BPB using Set Device Parm ;AN000;
3198 INT 21h ; IOCtl + gen_IOCtl_request <440d> ;AN000;
3199
3200 cmp DOS_VER,0ffh ; is it DOS 3.3? ;AN019;
3201 ; $if ne ; only do a GET if DOS 4.00 ;AN019;
3202 JE $$IF177
3203 lea dx,IOCtl_Buf ; point to output buffer ;AN000;
3204 mov ax,(GetSetMediaID shl 8) + 0 ; get volid, ser# and file type ;AC008;
3205 INT 21h ; GetSetMediaID + 0 INT 21 <6900> ;AC008;
3206
3207 ; $if c ; error - see if its 'unknown media' ;AN000;
3208 JNC $$IF178
3209
3210 call Get_DOS_Error ; get error ;AN000;
3211 cmp al,old_type_media ; ;AN000;
3212
3213 ; $if e ; ;AN019;
3214 JNE $$IF179
3215 stc ; do it all manually ;AN019;
3216 ; $else ; ;AN019;
3217 JMP SHORT $$EN179
3218 $$IF179:
3219 clc ; some other dos error occured - le ;AN019;
3220 ; $endif ; it go by ;AN019;
3221 $$EN179:
3222
3223 ; $endif ; ;AN019;
3224 $$IF178:
3225 ; $else ; ;AN019;
3226 JMP SHORT $$EN177
3227 $$IF177:
3228 stc ; do it all manually ;AN019;
3229 ; $endif ; ;AN019;
3230 $$EN177:
3231
3232 ; $if c ; if it is pre 4.00 IBM format ;AN000;
3233 JNC $$IF185
3234
3235 call Create_Serial_ID ; compute serial id and put in field ;AN000;
3236
3237 ; find first with type = VOLUME ID
3238
3239 mov dx,OFFSET ExtFCB ; set up for FCB call ;AN019;
3240 mov ah,Dir_Search_First ; do a find first INT21 ;AN019;
3241
3242 INT 21h ; Find_First <11xx> ;AN000;
3243
3244 cmp al,0 ; was a match found? al = 0 yes ;AN019;
3245 ; al = ff no
3246 ; $if e ; if so - copy it in ;AN000;
3247 JNE $$IF186
3248
3249 lea si,DOS_BUFFER + 8 ; source id is in DTA ;AN019;
3250 lea di,IOCtl_Vol_ID ; destination is in IOCtl_Buf ;AN000;
3251 mov cx,file_spec_length ; move 11 bytes worth ;AN000;
3252 cld ; copy it in ;AN000;
3253 rep movsb ; ;AN000;
3254
3255 ; $else
3256 JMP SHORT $$EN186
3257 $$IF186:
3258
3259 clc ; leave it as default - NO NAME
3260
3261 ; $endif ; endif ;AN000;
3262 $$EN186:
3263
3264 ; NOTE:
3265 ; since the GET MEDIA ID failed - its
3266 ; pre 32 bit fat - so no 32 bit math
3267 ; is required.
3268 call FAT_Size ; set pointer to FAT1x ;AN000;
3269
3270 mov cx,FAT_len ; move file system string into ;AN000;
3271 ; Boot_System_ID field
3272 lea di,IOCTL_File_Sys ; update buffer ;AN000;
3273 cld ; ;AN000;
3274 rep movsb ; ;AN000;
3275 ; $endif
3276 $$IF185:
3277
3278 ; $if nc ; ;AN000;
3279 JC $$IF190
3280
3281 lea si,DeviceParameters.DP_BPB
3282 lea di,boot.EXT_BOOT_BPB
3283 mov cx,type EXT_BPB_INFO
3284 cld
3285 rep movsb
3286
3287 cmp DeviceParameters.DP_BPB.BPB_MediaDescriptor,hard_drive ; is it Hard drive?;AC000;
3288
3289 ; $if e ; if its a hard drive ;AC000;
3290 JNE $$IF191
3291
3292 ; NOTE: The physical hard drive number
3293 ; is placed in the third byte from
3294 ; the end in the boot sector in
3295 ; DOS 3.2. This is a change from
3296 ; the previous DOS versions.
3297
3298 ; fill in PhyDrv in canned boot record
3299 mov al,80h ; (set physical hard drive number) ;AC016;
3300 ; $else
3301 JMP SHORT $$EN191
3302 $$IF191:
3303 xor al,al ; (set physical drive number to zero) ;AC016;
3304 ; $endif ; ;AC000;
3305 $$EN191:
3306
3307 mov BOOT.EXT_PHYDRV,al ; (set physical hard drive number) ;AC016;
3308
3309 cmp DOS_VER,0 ; ;AN019;
3310 ; $if ne ; copy IOCTL stuff into boot record ;AN019;
3311 JE $$IF194
3312 ; (no set ID available for 3.3)
3313 lea si,IOCtl_Ser_No_Low ; point to source buffer (IOCTL) ;AN000;
3314 lea di,BOOT.EXT_BOOT_SERIAL ; point to target buffer (BOOT record) ;AN000;
3315
3316 mov cx,IOCTL_Ser_Vol_SyS ; move serial # , Volid , System ;AN019;
3317 cld ; ;AN019;
3318 rep movsb ; ;AN019;
3319 ; $endif ; ;AN019;
3320 $$IF194:
3321
3322 xor cx,cx ; Sector 0 ;AN019;
3323 mov [packet],cx ; set starting sector as 0 ;AN019;
3324 mov bx,offset BOOT ; ;AN019;
3325 mov packet_buffer[0],bx ; ;AN019;
3326 mov word ptr [packet_sectors],1 ; ;AN019;
3327 mov ah,1 ; request a write ;AN019;
3328 call Direct_Access ; ;AN019;
3329
3330 ; $if c ; ;AC000;
3331 JNC $$IF196
3332 ; $endif ; ;AC000;
3333 $$IF196:
3334
3335 cmp DOS_VER,0 ; ;AN019
3336 ; $if e ; only do a SET if DOS 4.00
3337 JNE $$IF198
3338 mov bl,TargDrvNum ; Drive number ;AN000;
3339 lea dx,IOCtl_Buf ; point to output buffer ;AN000;
3340 mov ax,(GetSetMediaID shl 8) + 1 ; set volid, ser# and filetype ;AC008;
3341 INT 21h ; GetSetMediaID + 1 INT 21 <6901> ;AC008;
3342 ; $endif ;AN019;
3343 $$IF198:
3344
3345 ; $endif ; ;AC000;
3346 $$IF190:
3347
3348 ret
3349
3350 ENDPROC Write_Boot_Record
3351
3352 BREAK <SYS - FAT_Size >
3353 ;******************* START OF SPECIFICATIONS ***********************************
3354 ;Routine name: FAT_Size
3355 ;*******************************************************************************
3356 ;
3357 ;Description: Determine FAT Type (12 or 16)
3358 ;
3359 ; NOTE: This routine is only called if the IOCtl call for
3360 ; Get Media Type FAILS with an extended error of
3361 ; 'Unknown media type'. This indicates it is a
3362 ; pre DOS 4.00 media (ie: it MUST be a 12 or old style
3363 ; 16 bit FAT
3364 ;
3365 ; This is the same algorithm used by FORMAT
3366 ;
3367 ; Algorithm:
3368 ;
3369 ; UsedSectors = number of reserved sectors
3370 ; + number of FAT Sectors ( Number of FATS * Sectors Per FAT )
3371 ; + number of directory sectors ( 32* Root Entries / bytes Per Sector )
3372 ;
3373 ; t_clusters = ( (Total Sectors - Used Sector) / Sectors Per Cluster)
3374 ;
3375 ; if T_Clusters <= 4086 then it a FAT12 - else - its a FAT16
3376 ;
3377 ;Called Procedures: None
3378 ;
3379 ;Input: EBPB of Target media in memory
3380 ;
3381 ;Output: SI: points to "FAT12 "
3382 ; or "FAT16 "
3383 ;
3384 ;Change History: Created 5/01/87 FG
3385 ;
3386 ;******************* END OF SPECIFICATIONS *************************************
3387 ;******************+ START OF PSEUDOCODE +**************************************
3388 ;
3389 ; START FAT_Size
3390 ;
3391 ; Calculate the number of directory sectors
3392 ; Calculate and add the number of FAT sectors
3393 ; Add in the number of boot sectors
3394 ; subtract used sectors from total sectors
3395 ; if <= FAT THRESHOLD then
3396 ; set pointer to FAT12
3397 ; else
3398 ; set pointer to FAT12
3399 ; endif
3400 ;
3401 ; ret
3402 ;
3403 ; END FAT_Size
3404 ;
3405 ;******************- END OF PSEUDOCODE -**************************************
3406
3407 public FAT_Size
3408
3409 FAT_Size PROC NEAR
3410
3411 ;--------------------------
3412 ; Calculate UsedSectors
3413 ;---------------------------
3414
3415 ; Calculate the number of directory sectors
3416
3417 mov ax, deviceParameters.DP_BPB.BPB_RootEntries ; ;AN000;
3418 mov bx, TYPE dir_entry ; ;AN000;
3419 mul bx ; ;AN000;
3420 add ax, deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000;
3421 dec ax ; ;AN000;
3422 xor dx,dx ; ;AN000;
3423 div deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000;
3424 mov cx,ax ; ;AN000;
3425
3426 ; Calculate the number of FAT sectors
3427
3428 mov ax, deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AN000;
3429 mul deviceParameters.DP_BPB.BPB_NumberOfFATs ; ;AN000;
3430
3431 ; Add in the number of boot sectors
3432
3433 add ax, deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AN000;
3434 add cx,ax ; ;AN000;
3435
3436 ;--------------------------
3437 ; Calculate t_clusters
3438 ;--------------------------
3439
3440 mov ax, deviceParameters.DP_BPB.BPB_TotalSectors ; ;AN000;
3441
3442 sub ax,cx ;Get sectors in data area ;AN000;
3443 xor dx,dx ; ;AN000;
3444 xor bx,bx ; ;AN000;
3445 mov bl,deviceParameters.DP_BPB.BPB_SectorsPerCluster ; ;AN000;
3446 div bx ;Get total clusters ;AN000;
3447 cmp ax,BIG_FAT_THRESHOLD ;Is clusters < 4086? ;AN000;
3448
3449 ; $if be ; if less then its a FAT12 ;AN000;
3450 JNBE $$IF201
3451 lea si,FAT_12 ; ;AN000;
3452 ; $else ; ;AN000;
3453 JMP SHORT $$EN201
3454 $$IF201:
3455 lea si,FAT_16 ; ;AN000;
3456 ; $endif ; ;AN000;
3457 $$EN201:
3458
3459 clc ; leave cleanly
3460
3461 return ; ;AN000;
3462
3463 ENDPROC FAT_Size
3464
3465 BREAK <SYS - Create_Serial_ID >
3466 ;******************* START OF SPECIFICATIONS ***********************************
3467 ;Routine name: Create_Serial_ID
3468 ;*******************************************************************************
3469 ;
3470 ;Description: Create unique 32 bit serial number by getting current date
3471 ; and time and then scrambling it around
3472 ;
3473 ;Called Procedures: None
3474 ;
3475 ;Input: None
3476 ;
3477 ;Output: serial number installed in Boot_Serial
3478 ;
3479 ;Change History: Created 5/01/87 FG
3480 ;
3481 ;******************* END OF SPECIFICATIONS *************************************
3482 ;******************+ START OF PSEUDOCODE +**************************************
3483 ;
3484 ; START Create_Serial_ID
3485 ;
3486 ; Get date (INT21 Get_Date + 00 <2A00>)
3487 ; Get time (INT21 Get_Time + 00 <2C00>)
3488 ; Boot_Serial+0 = DX reg date + DX reg date
3489 ; Boot_Serial+2 = CX reg time + CX reg time
3490 ; ret
3491 ;
3492 ; END Create_Serial_ID
3493 ;
3494 ;******************- END OF PSEUDOCODE -**************************************
3495
3496 public Create_Serial_ID
3497
3498 Create_Serial_ID PROC NEAR
3499
3500 mov ax,(Get_Date shl 8) + not_used ; Get date ;AN000;
3501 INT 21h ; Get_Date + not_used <2A00> ;AN000;
3502 mov ax,(Get_Time shl 8) + not_used ; Get time ;AN000;
3503 INT 21h ; Get_Time + not_used <2C00> ;AN000;
3504 add dx,dx ; Boot_Serial+0 = DX (date) + DX (date);AN000;
3505 add cx,cx ; Boot_Serial+2 = CX (time) + CX (time);AN000;
3506 mov IOCtl_Ser_No_Low,dx ; SERIAL # - low ;AN000;
3507 mov IOCtl_Ser_No_Hi,cx ; SERIAL # - hi ;AN000;
3508
3509 ret ; ;AN000;
3510
3511 ENDPROC Create_Serial_ID
3512
3513 BREAK <SYS - Message >
3514 ;******************* START OF SPECIFICATIONS ***********************************
3515 ;Routine name: Message
3516 ;*******************************************************************************
3517 ;
3518 ;Description: Display a message
3519 ;
3520 ;Called Procedures: SYSDISPMSG, Get_DOS_Error
3521 ;
3522 ;Input: (AL) message number
3523 ; (AH) message class
3524 ; = C - DS:SI points to sublist
3525 ;
3526 ;Output: no error AX = 0
3527 ; error - AX = error exit code
3528 ;
3529 ;Change History: Created 5/01/87 FG
3530 ;
3531 ;******************* END OF SPECIFICATIONS *************************************
3532 ;******************+ START OF PSEUDOCODE +**************************************
3533 ;
3534 ; START Message
3535 ;
3536 ; if DOS error
3537 ; call Get_DOS_error
3538 ; endif
3539 ; move message class into place
3540 ; reset insert (CX)
3541 ; reset response (DL)
3542 ; set output handle (BX)
3543 ; if CLASS requires insert
3544 ; load insert required
3545 ; if CLASS requires response
3546 ; flush keystroke buffer
3547 ; load response required (Dir CON in no echo)
3548 ; endif
3549 ; call SysDispMsg to display message
3550 ; if error or
3551 ; call Get_DOS_error
3552 ; call SysDispMsg to try again
3553 ; if not success message
3554 ; load error exit code
3555 ; else
3556 ; load success exit code
3557 ; endif
3558 ; ret
3559 ;
3560 ; END Message
3561 ;
3562 ;******************- END OF PSEUDOCODE -**************************************
3563
3564 public Message
3565
3566 Message PROC NEAR
3567
3568 xor dx,dx ; reset response (DL) ;AN000;
3569 xor cx,cx ; reset insert (CX) ;AC024;
3570 dec dh ; assume CLASS is Utility ;AN000;
3571
3572 cmp ah,PARSE_Error ; ;AN000;
3573
3574 ; $if be,and ; if DOS or PARSE error ;AN000;
3575 JNBE $$IF204
3576
3577 mov dh,ah ; ;AN000;
3578
3579 ; $if e,and ; if PARSE error ;AN024;
3580 JNE $$IF204
3581 cmp al,reqd_missing ; ;AC024;
3582 ; $if ne ; and if theres something there ;AC024;
3583 JE $$IF204
3584
3585 push cs ; set up for insert ;AN024;
3586 pop [insert_ptr_seg] ; (offset set by parse routine) ;AN024;
3587 mov cs:[si],dl ; make it an ASCIIZ string ;AN024;
3588 mov insert_number,dl ; zero out for %0
3589 mov insert_max,030h ; set length to something reasonable ;AN024;
3590 inc cx ; there's an insert ;AC024;
3591 lea si,SUBLIST ; point to the sublist ;AC024;
3592
3593 ; $endif ; ;AN024;
3594 $$IF204:
3595
3596
3597 cmp ah,DOS_Error ; ;AN000;
3598
3599 ; $if be ; if DOS error ;AC019;
3600 JNBE $$IF206
3601
3602 call Get_DOS_error ; to find out what message to display ;AN000;
3603 mov dh,DOS_Error ; ensure message type is DOS_Error ;AN019;
3604
3605 ; $endif ; ;AN000;
3606 $$IF206:
3607
3608 mov bx,STDERR ; set output handle (BX) ;AN000;
3609
3610 cmp ah,util_C ; is it CLASS C ;AN000;
3611
3612 ; $if e ; CLASS C requires insert ;AN000;
3613 JNE $$IF208
3614
3615 inc cx ; load insert required ;AN000;
3616
3617 ; $endif ; ;AN000;
3618 $$IF208:
3619
3620 cmp ah,util_D ; is it CLASS D ;AN000;
3621
3622 ; $if e ; CLASS D requires response ;AN000;
3623 JNE $$IF210
3624
3625 mov dl,DOS_CON_INP ; load response required - con: input ;AN000;
3626
3627 ; $endif ; ;AN000;
3628 $$IF210:
3629
3630 xor ah,ah ; ;AN000;
3631
3632
3633 call SysDispMsg ; to display message ;AN000;
3634
3635 ; $if c,and ; error and............... ;AN000;
3636 JNC $$IF212
3637
3638 call SysDispMsg ; to try again : ;AN000;
3639
3640 ; $if c ; if reaaly bad .........: ;AN000;
3641 JNC $$IF212
3642
3643 mov ax,return_error ; load error exit code ;AN000;
3644
3645 ; $else ; ;AN000;
3646 JMP SHORT $$EN212
3647 $$IF212:
3648
3649 mov ax,success ; load success exit code ;AN000;
3650
3651 ; $endif ; ;AN000;
3652 $$EN212:
3653
3654 ret ; ;AN000;
3655
3656 ENDPROC Message
3657
3658
3659 BREAK <SYS - Get_DOS_Error >
3660 ;******************* START OF SPECIFICATIONS ***********************************
3661 ;Routine name: Get_DOS_Error
3662 ;*******************************************************************************
3663 ;
3664 ;Description: Call DOS to obtain DOS extended error #
3665 ;
3666 ;Called Procedures: None
3667 ;
3668 ;Input: None
3669 ;
3670 ;Output: AX = error number
3671 ;
3672 ;Change History: Created 5/01/87 FG
3673 ;
3674 ;******************* END OF SPECIFICATIONS *************************************
3675 ;******************+ START OF PSEUDOCODE +**************************************
3676 ;
3677 ; START Get_DOS_Error
3678 ;
3679 ; call DOS for extended error (INT21 GetExtendedError + 00 <5900>)
3680 ; set up registers for return
3681 ; ret
3682 ;
3683 ; END Get_DOS_Error
3684 ;
3685 ;******************- END OF PSEUDOCODE -**************************************
3686
3687 public Get_DOS_Error
3688
3689 Get_DOS_Error PROC NEAR
3690
3691 push bx
3692 mov ax,(GetExtendedError shl 8) + not_used ; call DOS for extended error ;AN000;
3693 xor bx,bx
3694 push es ; ;AN000;
3695 INT 21h ; GetExtendedError + not_used <5900>;AN000;
3696 pop es
3697 pop bx ; ;AN000;
3698 xor cx,cx ; reset insert (CX) ;AC024;
3699
3700 ret ; ;AN000;
3701
3702 ENDPROC Get_DOS_Error
3703
3704 CODE ENDS
3705
3706 include msgdcl.inc
3707
3708 END START
3709
3710 \1a