1 PAGE
90,132 ;\ f\eA\b\e2
2 TITLE DISKCOPY
.SAL - DISKETTE DUPLICATION UTILITY
;
3 ;****************** START OF SPECIFICATIONS *****************************
4 ; MODULE NAME: DISKCOPY
6 ; DESCRIPTIVE NAME: Diskette to diskette complete copy Utility
8 ;FUNCTION: DISKCOPY is to copy the contents of the diskette in the
9 ; specified source drive to the diskette in the target
10 ; drive. If necessary, the target diskette is also
14 ; Multiple copies may be performed with one load of DISKCOPY.
15 ; A prompt, "Copy another (Y/N)?" permits additional
16 ; executions, all with the same drive specifications.
18 ; ENTRY POINT: "DISKCOPY" at ORG 100h, jumps to "BEGIN".
20 ; INPUT: (DOS command line parameters)
21 ; [d:][path]DISKCOPY [d: [D:]][/1]
25 ; [d:][path] before DISKCOPY to specify the drive and path that
26 ; contains the DISKCOPY command file.
28 ; [d:] to specify the source drive id
30 ; [D:] to specify the destination drive id
32 ; [/1] to request single sided operations only
34 ; EXIT-NORMAL: Errorlevel = 0
35 ; Function completed successfully.
37 ; EXIT-ERROR: Errorlevel = 1
38 ; Abnormal termination due to error, wrong DOS,
39 ; invalid parameters, unrecoverable I/O errors on
43 ; Termination requested by Cntrl-Break.
45 ; EFFECTS: The entire source diskette is copied, including the unused
46 ; sectors. There is no awareness of the separate files
47 ; involved. A unique volume serial number is generated
48 ; for the target diskette.
51 ; INCLUDE DCPYMACR.INC ;(formerly called MACRO.DEF)
52 ; INCLUDE DISKCOPY.EQU ;EQUATES
53 ; INCLUDE BOOTFORM.INC ;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
54 ; INCLUDE PATHMAC.INC ;PATHGEN MACRO
56 ; INTERNAL REFERENCES:
58 ; BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS
59 ; SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE
60 ; COPY - COPY THE DISKETTE IMAGE
61 ; TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER
62 ; READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE
63 ; WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE
64 ; READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY
65 ; READ_OP - IOCTL READ A TRACK OPERATION
66 ; MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT
67 ; WRITE_OP - IOCTL WRITE A TRACK OPERATION
68 ; FORMAT_ALL - FORMATS ALL TRACKS TO END
69 ; FORMAT_TRACK - IOCTL FORMAT A TRACK
70 ; CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE
71 ; READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ
72 ; CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK
73 ; CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK
74 ; SET_FOR_THE_OLD - SET BPB FOR BEFORE-2.0 FMTTED MEDIA
75 ; SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE
76 ; CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?
77 ; CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA
78 ; SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL
79 ; CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT
80 ; GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER
81 ; EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS
82 ; TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY
83 ; ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE
84 ; SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG
85 ; YESNO - DETERMINE IF A RESPONSE IS YES OR NO
86 ;(DELETED ;AN013;)READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE
87 ; WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET
89 ; PSP - Contains the DOS command line parameters.
90 ; WORKAREA - Temporary storage
92 ; EXTERNAL REFERENCES:
94 ; SYSDISPMSG - Uses the MSG parm lists to construct the messages
96 ; SYSLOADMSG - Loads messages, makes them accessable.
97 ; SYSPARSE - Processes the DOS Command line, finds parms.
100 ; DCOPYSM.SAL - Defines the control blocks that describe the messages
101 ; DCOPYPAR.SAL - Defines the control blocks that describe the
102 ; DOS Command line parameters.
105 ; This module should be processed with the SALUT preprocessor
106 ; with the re-alignment not requested, as:
110 ; To assemble these modules, the alphabetical or sequential
111 ; ordering of segments may be used.
113 ; Sample LINK command:
117 ; Where the DISKCOPY.ARF is defined as:
125 ; These modules must be linked in this order. The load module is
126 ; a COM file, to be converted to COM with EXE2BIN.
129 ; A000 Version 4.00: add PARSER, System Message Handler,
130 ; Make new unique vol serial number on new diskette.
131 ; A001 DCR 27, display vol serial number, if present.
132 ; A002 ptm473 Flag duplicate switches as error
133 ; A003 Display parm in error
134 ; A004 PTR752 Add close door to drive not ready
135 ; A005 PTR756 After bad parms, specify help info
136 ; A006 DCR210 SELECT, if present, handles all msgs
137 ; A007 PTM1100 Clear keyboard buffer before input response
138 ; A008 PTM1434 CR,LF MISSING FROM MSGS 22 AND 23
139 ; A009 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID
140 ; A010 PTM1821 Move INCLUDE COPYRIGH.INC into MSG_SERVICE macro.
141 ; A011 PTM1837 ADD CHECK FOR UNKNOWN MEDIA TO TRIGGER FORMAT
142 ; A012 PTM2441 COPY FROM 360 TO 1.2 CLOBBERS 1.2
143 ; A013 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO
144 ; REMOVE USE OF GET/SET MEDIA ID
145 ; A014 PTM3262 specify BASESW EQU 1 before PARSE.ASM
146 ; A015 PTM3512 PATHGEN
148 ; COPYRIGHT: The following notice is found in the OBJ code generated from
149 ; the "DCOPYSM.SAL" module:
151 ; "Version 4.00 (C) Copyright 1988 Microsoft"
152 ; "Licensed Material - Property of Microsoft "
154 ;PROGRAM AUTHOR: Original written by: JK
155 ; 4.00 modifications by: EMK
156 ;****************** END OF SPECIFICATIONS *****************************
158 %
OUT COMPONENT
=DISKCOPY
, MODULE
=DISKCOPY
.SAL ;
161 ;*****************************************************************************
165 ; UPDATE HISTORY: 7-31, 8-3, 8-5A, 8-6, 8-7, 8-8, 8-10, 8-11, 8-13, 8-14 *
166 ; 8-16, 8-17, 8-18, 8-20, 8-28, 9-3, 9-11, 10-6, 10-11 *
167 ; 11-7,11-12, 11-17, 11-18, 12-19, 2-16-84, 3-27, 4-5, 4-7 *
168 ; 6-20,7-23,10-31,3-27,4-24 *
170 ;*****************************************************************************
174 ;*****************************************************************************
178 ;*****************************************************************************
180 INCLUDE PATHMAC
.INC ;AN015;PATHGEN MACRO
181 INCLUDE DCPYMACR
.INC ;(formerly called MACRO.DEF)
182 INCLUDE DISKCOPY
.EQU
;EQUATES
184 ; $salut (4,16,22,36) ;AN000;
186 CBYTE_SECT
DW 0 ; 200H BYTES / SECTOR
187 CSECT_CLUSTER
DB 0 ; 2h SECTORS / CLUSTER
188 CRESEV_SECT
DW 0 ; 1h RESERVED SECTORS
189 CFAT
DB 0 ; 2h # OF FATS
190 CROOTENTRY
DW 0 ; 70h # OF ROOT ENTRIES
191 CTOTSECT
DW 0 ; 02D0h TOTAL # OF SECTORS INCLUDING
192 ; BOOT SECT, DIRECTORIES ...
193 MEDIA_DESCRIP
DB 0 ;0FDh MEDIA DISCRIPTOR
194 CSECT_FAT
DW 0 ; 2h SECTORS / FAT
202 INCLUDE BOOTFORM
.INC ;AN013;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
204 CSEG
SEGMENT PARA
PUBLIC 'CODE' ;AN000;
205 ASSUME
CS:CSEG
, DS:CSEG
, ES:CSEG
, SS:CSEG
;
207 ;*****************************************************************************
209 ; EXTERNAL VARIABLES *
211 ;*****************************************************************************
212 ;$salut (4,2,9,36) ;AN000;
213 EXTRN SYSLOADMSG
:NEAR ;AN000;SYSTEM MSG HANDLER INTIALIZATION
214 EXTRN SYSDISPMSG
:NEAR ;AN000;SYSTEM MSG HANDLER DISPLAY
216 EXTRN INIT
:NEAR ;INITIALIZATION ROUTINE
218 ;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE
219 ;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE
220 ;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE
221 ;EXTRN MSG_SOURCE_BAD_PTR :BYTE
225 EXTRN ASCII_DRV1_ID
:BYTE ;AN000;SOURCE DRIVE LETTER CHARACTER
226 EXTRN ASCII_DRV2_ID
:BYTE ;AN000;TARGET DRIVE LETTER CHARACTER
227 EXTRN MSG_TRACKS
:WORD ;AN000;NUMBER OF TRACKS
228 EXTRN MSG_SECTRK
:WORD ;AN000;SECTORS PER TRACK
229 EXTRN MSG_SIDES
:WORD ;AN000;NUMBER OF SIDES
230 EXTRN ERROR_SIDE_NUMBER
:WORD ;AN000;NUMBER OF SIDES (SUBFIELD OF MSG 19)
231 EXTRN ERROR_TRACK_NUMBER
:WORD ;AN000;NUMBER OF TRACKS (SUBFIELD OF MSG 19)
233 EXTRN MSGNUM_EXTERR
:WORD ;AN000;EXTENDED ERROR MSG DESCRIPTOR
234 EXTRN MSGNUM_HARD_ERROR_READ
:WORD ;AN000;"Unrecoverable read/write error on drive %1",CR,LF
235 EXTRN MSGNUM_HARD_ERROR_WRITE
:WORD ;AN000;"Side %2, track %3" ;
236 EXTRN MSGNUM_LOAD_SOURCE
:WORD ;AC000;"Insert SOURCE diskette in drive %2:"
237 EXTRN MSGNUM_LOAD_TARGET
:WORD ;AC000;"Insert TARGET diskette in drive %2:"
238 EXTRN MSGNUM_TARGET_MB_UNUSABLE
:WORD ;AC000;"Target diskette may be unusable"
239 EXTRN MSGNUM_NOT_COMPATIBLE
:WORD ;AC000;"Drive types or diskette types",CR,LF
241 EXTRN MSGNUM_BAD_SOURCE
:WORD ;AC000;"SOURCE diskette bad or incompatible"
242 EXTRN MSGNUM_BAD_TARGET
:WORD ;AC000;"TARGET diskette bad or incompatible"
243 EXTRN MSGNUM_COPY_ANOTHER
:WORD ;AC000;"Copy another diskette (Y/N)?"
244 EXTRN MSGNUM_FORMATTING
:WORD ;AC000;"Formatting while copying"
245 EXTRN MSGNUM_GET_READY
:WORD ;AC000;"Drive not ready - %0"
246 EXTRN MSGNUM_CLOSE_DOOR
:WORD ;AN004;"Make sure a diskette is inserted into
247 ; the drive and the door is closed"
248 EXTRN MSGNUM_FATAL_ERROR
:WORD ;AC000;"Copy process ended"
249 EXTRN MSGNUM_UNSUF_MEMORY
:WORD ;AC000;"Insufficient memory"
250 EXTRN MSGNUM_COPYING
:WORD ;AC000;"Copying %1 tracks",CR,LF
251 ;"%2 Sectors/Track, %3 Side(s)"
252 EXTRN MSGNUM_STRIKE
:WORD ;AC000;"Press any key to continue . . ."
253 EXTRN MSGNUM_WRITE_PROTECT
:WORD ;AC000;"Attempt to write to write-protected diskette"
254 EXTRN MSGNUM_CR_LF
:WORD ;AC000;
255 EXTRN MSGNUM_SERNO
:WORD ;AN001;"VOLUME SERIAL NUMBER IS %1-%0"
256 EXTRN SUBLIST_26A
:WORD ;AN001;POINTS TO FIRST PART OF SERIAL NUMBER
257 EXTRN SUBLIST_26B
:WORD ;AN001;POINTS TO SECND PART OF SERIAL NUMBER
259 EXTRN DRIVE_LETTER
:BYTE ;AN000;
260 ;*****************************************************************************
264 ;*****************************************************************************
266 PUBLIC RECOMMENDED_BYTES_SECTOR
;
268 PUBLIC S_OWNER_SAVED
;
269 PUBLIC T_OWNER_SAVED
;
270 PUBLIC SOURCE_DRIVE
;
271 PUBLIC TARGET_DRIVE
;
272 PUBLIC S_DRV_SECT_TRACK
;
274 PUBLIC S_DRV_TRACKS
;
275 PUBLIC T_DRV_SECT_TRACK
;
277 PUBLIC T_DRV_TRACKS
;
280 PUBLIC BUFFER_BEGIN
;
282 PUBLIC TRACK_TO_READ
;
283 PUBLIC TRACK_TO_WRITE
;
290 PUBLIC DS_IOCTL_DRV_PARM
;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
291 PUBLIC DT_IOCTL_DRV_PARM
;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
292 PUBLIC DS_specialFunctions
;AND THEIR CONTENTS
293 PUBLIC DT_specialFunctions
;
294 PUBLIC DS_deviceType
;
295 PUBLIC DT_deviceType
;
296 PUBLIC DS_deviceAttributes
;
297 PUBLIC DT_deviceAttributes
;
298 PUBLIC DS_numberOfCylinders
;
299 PUBLIC DT_numberOfCylinders
;
300 PUBLIC DS_mediaType
;
301 PUBLIC DT_mediaType
;
305 PUBLIC MS_IOCTL_DRV_PARM
;DRIVE PARM FROM SOURCE MEDIUM
306 PUBLIC MT_IOCTL_DRV_PARM
;DRIVE PARM FROM TARGET MEDIUM
308 ;*****************************************************************************
309 ORG 100H
;PROGRAM ENTRY POINT
313 ;*****************************************************************************
316 EVEN
;AN000;MAKE STACK WORD ALIGNED
317 DB 64 DUP ('STACK ') ;512 BYTES
318 MY_STACK_PTR
LABEL WORD ;
320 ;*****************************************************************************
322 ; INTERNAL VARIABLES *
324 ;*****************************************************************************
325 ; $salut (4,22,26,36) ;AN000;
326 ; INPUT PARMETERS FROM INIT SUBROUTINE:
328 S_OWNER_SAVED
DB 0 ;DRIVE LETTER THAT OWNED SOUCE DRIVE OWNERSHIP
331 RECOMMENDED_BYTES_SECTOR
DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA
332 SOURCE_DRIVE
DB 0 ;SOURCE DRIVE ID: 1=DRV A, 2=DRV B ETC.
333 TARGET_DRIVE
DB 0 ;TARGET DRIVE ID
334 USER_OPTION
DB 0 ;=1 OF /1 OPTION IS ENTERED
335 COPY_TYPE
DB 1 ;SINGLE DRV COPY=1, DOUBLE DRIVE COPY=2
336 BUFFER_BEGIN
DW 1000H
;BEGINNING OF BUFFER ADDR [IN SEGMENT]
337 BUFFER_END
DW 3FF0H
;END OF BUFFER ADDR [IN SEGMENT]
338 S_DRV_SECT_TRACK
DB ?
;SECT/TRACK, device informations.
339 S_DRV_HEADS
DB ?
;# OF HEADS
340 S_DRV_TRACKS
DB ?
;# OF TRACKS
341 T_DRV_SECT_TRACK
DB ?
;
345 ;DEFAULT BPB FOR OLD MEDIA
346 ;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK)
347 BPB48_SINGLE
DW 512 ;BYTES/SECTOR
349 DW 1 ;# OF RESERVED SECTORS
351 DW 40h
;# OF ROOT ENTRY
352 DW 168h
;TOTAL # OF SECTORS IN THE MEDIA
356 ;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK)
357 BPB48_DOUBLE
DW 512 ;BYTES/SECTOR
359 DW 1 ;# OF RESERVED SECTORS
361 DW 70h
;# OF ROOT ENTRY
362 DW 2D0h
;TOTAL # OF SECTORS IN THE MEDIA
366 ;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK)
367 BPB96
DW 512 ;BYTES/SECTOR
369 DW 1 ;# OF RESERVED SECTORS
371 DW 0E0h ;# OF ROOT ENTRY
372 DW 960h
;TOTAL # OF SECTORS IN THE MEDIA
375 BPB96_LENG EQU
$-BPB96
;THIS LENGTH WILL BE USED FOR BPB48 ALSO.
378 VOLSER_FLAG
DB 0 ;AN000;0=EITHER MEDIA NOT READ YET, OR
379 ; SOURCE VOL SER ID NOT AVAILABLE
380 ; 1=TARGET NEEDS VOL SER WRITTEN
381 SERIAL
DD 0 ;AN013;SERIAL NUMBER OF NEW DISKETTE
382 EXITFL
DB EXOK
;AN000;ERRORLEVEL VALUE
383 PUBLIC EXITFL
;AN000;
385 EXCBR EQU
2 ;AN000;CONTROL BREAK
386 EXVER EQU
1 ;AN000;BAD DOS VERSION ERRORLEVEL CODE
387 EXPAR EQU
1 ;AN000; BAD PARMS, OR OTHER ERRORS
388 EXOK EQU
0 ;AN000;NORMAL ERRORLEVEL RET CODE
390 S_DRV_SET_FLAG
DB 0 ;1 = SOURCE DRIVE PARM HAD BEEN SET
391 T_DRV_SET_FLAG
DB 0 ;1 = TARGET DRIVE PARM HAD BEEN SET
393 IOCTL_SECTOR
DW 1 ;used for READ_A_SECTOR routine.
394 IOCTL_TRACK
DW 0 ;IN THE TRACK
395 IOCTL_HEAD
DW 0 ;HEAD 0
396 SAV_CSECT
DW 0 ;TEMPORARY SAVING PLACE
401 BOOT_SECT_TRACK
DW 0 ;TEMP SAVING PLACE OF SECTOR/TRACK
402 BOOT_TOT_TRACK
DW 0 ;FOUND FROM THE BOOT SECTOR. max # of tracks
403 BOOT_NUM_HEAD
DW 0 ;NUMBER OF HEADS
404 BOOT_BYTE_SECTOR
DW 0 ;BYTES / SECTOR
406 READ_S_BPB_FAILURE
DB 0 ;GET MEDIA BPB. SUCCESS=0, FAILURE=1
407 READ_T_BPB_FAILURE
DB 0 ;
409 ;*** Informations from CHECK_SOURCE.
410 ;*** These will be used as a basis for the copy process.
411 LAST_TRACK
DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79)
412 END_OF_TRACK
DB 15 ;END OF TRACK, 8,9 OR 15 CURRENTLY.
413 bSECTOR_SIZE
DW 512 ;BYTES/SECTOR in bytes
414 NO_OF_SIDES
DB ?
;0=SINGLE SIDED, 1=DOUBLE SIDED
416 FORMAT_FLAG
DB 0 ;(ON/OFF) FORMAT BEFORE WRITE IF TURNED ON
417 TRACK_TO_READ
DB 0 ;NEXT TRACK TO READ
418 TRACK_TO_WRITE
DB 0 ;NEXT TRACK TO WRITE
419 TRACK_TO_FORMAT
DB 0 ;STARTS FORMAT WITH THIS TRACK
421 TRACK_SIZE
DW ?
;BYTES/CYLINDER [IN SEGMENTS]
422 SECTOR_SIZE
DB ?
;BYTES/SECTOR [IN SEGMENTS]
423 BUFFER_PTR
DW ?
;BUFFER POINTER FOR READ/WRITE OP
424 COPY_ERROR
DB 0 ;=0 IF NO ERROR, >0 IF ERROR DETECTED
425 SIDE
DB ?
;NEXT SIDE TO READ/WRITE (0,1)
426 SIDE_TO_FORMAT
DB 0 ;NEXT SIDE TO FORMAT (0, 1)
427 OPERATION
DB ?
;READ/WRITE/VERIFY OPERATION
428 COPY_STATUS
DB ?
;(OK OR FATAL) ABORT COPY PROCESS IF FATAL
429 USER_INPUT
DB ?
;DISKCOPY AGAIN?
430 IO_ERROR
DB 0 ;SET BY EXTENDED_ERROR_HANDLER
431 UKM_ERR
DB 0 ;AN011;IF ON, HARD ERROR IS TYPE: "UNKNOWN MEDIA"
432 MSG_FLAG
DB ?
;USED TO INDICATE IF READ/WRITE ERROR MESSAGE
433 ;IS TO BE DISPLAYED (ON/OFF)
434 TARGET_OP
DB 0 ;FLAG TO INDICATE ANY OPERATIONS ON TARGET
435 TRY_FORMAT_FLAG
DB 0 ;FLAG TO INDICATE "TRY_FORMAT" PROCEDURE TO
436 ; CHECK THE "TIME OUT ERROR"
437 TIME_OUT_FLAG
DB 0 ;FLAG TO INDICATE THE "TIME OUT" ERROR
438 ; WAS A REAL "TIME OUT ERROR"
439 SELECT_FLAG
DB 0 ;INDICATES SELECT IS PRESENT
441 ; DEVICE PARAMETER TABLE
442 ;the returned info. still has the following format.
444 DS_IOCTL_DRV_PARM
LABEL BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
445 DS_specialFunctions db ?
;
446 DS_deviceType db ?
;0 - 5.25"(48tpi), 1 - 5.25"(96tpi),
448 DS_deviceAttributes dw ?
;0001h - NOT REMOVABLE,
449 ; 0002h - CHANGE LINE SUPPORTED
450 DS_numberOfCylinders dw ?
;
452 DS_BPB_PTR
LABEL BYTE ;
453 DS_deviceBPB my_bpb
<> ;
454 DS_trackLayout
LABEL WORD ;AC000;
455 my_trackLayout
;AC000;
456 ;---------------------------------------
458 DT_IOCTL_DRV_PARM
LABEL BYTE ;
459 DT_specialFunctions db ?
;
461 DT_deviceAttributes dw ?
;0001h - NOT REMOVABLE,
462 ; 0002h - CHANGE LINE SUPPORTED
463 DT_numberOfCylinders dw ?
;
465 DT_BPB_PTR
LABEL BYTE ;
466 DT_deviceBPB my_bpb
<> ;
467 DT_trackLayout
LABEL WORD ;AC000;
468 my_trackLayout
;AC000;
470 ;---------------------------------------
472 MS_IOCTL_DRV_PARM
LABEL BYTE ;DRIVE PARM FROM SOURCE MEDIUM
473 MS_specialFunctions db ?
;
475 MS_deviceAttributes dw ?
;0001h - NOT REMOVABLE,
476 ; 0002h - CHANGE LINE SUPPORTED
477 MS_numberOfCylinders dw ?
;
479 MS_BPB_PTR
LABEL BYTE ;
480 MS_deviceBPB my_bpb
<> ;
481 MS_deviceBPB_leng equ
$-MS_deviceBPB
;
482 MS_trackLayout
LABEL WORD ;AC000;
483 my_trackLayout
;AC000;
484 ;---------------------------------------
485 MT_IOCTL_DRV_PARM
LABEL BYTE ;DRIVE PARM FROM TARGET MEDIUM
486 MT_specialFunctions db ?
;
488 MT_deviceAttributes dw ?
;0001h - NOT REMOVABLE,
489 ; 0002h - CHANGE LINE SUPPORTED
490 MT_numberOfCylinders dw ?
;
492 MT_BPB_PTR
LABEL BYTE ;
493 MT_deviceBPB my_bpb
<> ;
494 MT_trackLayout
LABEL WORD ;AC000;
495 my_trackLayout
;AC000;
498 ; IOCTL format a track function control string.
499 IOCTL_FORMAT
LABEL BYTE ;
500 FspecialFunctions db 0 ;
504 ; IOCTL read/write a track.
505 IOCTL_R_W
LABEL BYTE ;
506 specialFunctions db 0 ;
510 numberOfSectors dw ?
;
513 ; = = = = = = = = = = = =
514 ; GET/SET MEDIA ID - FUNCTION OF GENERIC IOCTL
515 ; (USED BY VOLSER PROC)
516 ;(Deleted ;AN013;) MEDIA_ID_BUF A_MEDIA_ID_INFO <> ; ;AN000;
517 ; = = = = = = = = = = = =
518 PATHLABL DISKCOPY
;AN015;
519 HEADER
<BEGIN
- VERSION CHECK
, SYSMSG INIT
, EXIT TO DOS
> ;AN000;
520 PUBLIC DISKCOPY_BEGIN
;
521 DISKCOPY_BEGIN
LABEL NEAR ;
523 ;*****************************************************************************
525 ; D I S K C O P Y M A I N P R O G R A M *
527 ;*****************************************************************************
528 ; $salut (4,4,10,36) ;AN000;
531 ;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE
533 MOV SP, OFFSET MY_STACK_PTR
;MOVE SP TO MY STACK PTR
534 CALL SYSLOADMSG
;AN000;INIT SYSMSG HANDLER
536 ; $IF C ;AN000;IF THERE WAS A PROBLEM
538 CALL SYSDISPMSG
;AN000;LET HIM SAY WHY HE HAD A PROBLEM
540 MOV EXITFL
,EXVER
;AN000;TELL ERRORLEVEL BAD DOS VERSION
541 ; $ELSE ;AN000;SINCE SYSDISPMSG IS HAPPY
544 CALL INIT
;RUN INITIALIZATION ROUTINE
546 CMP DX,FINE
;CHECK FOR ERROR DURING INIT
547 ; $IF E ;IF NO ERROR THEN PROCEED TO COPY
551 CALL COPY
;PERFORM DISKCOPY
553 CALL TEST_REPEAT
;COPY ANOTHER ?
557 ;NORMAL RETURN CODE ALREADY IN "EXITFL"
558 ; $ELSE ;ELSE IF ERROR DETECTED IN INIT
564 ; CALL PRINTF ;DISPLAY ERROR MESSAGE
566 MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000;
567 ;DI HAS OFFSET OF MESSAGE DESCRIPTOR
568 CALL SENDMSG
;AC000;DISPLAY THE ERROR MESSAGE
570 MOV EXITFL
,EXVER
;AC000;ERROR RETURN CODE
573 JMP SHORT EXIT_TO_DOS
;
575 MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK
576 MOV EXITFL
,EXCBR
;AC000; FOR CONTROL-BREAK EXIT
581 MOV BL, S_OWNER_SAVED
;RESTORE ORIGINAL SOURCE,
582 ; TARGET DRIVE OWNER.
583 CALL SET_LOGICAL_DRIVE
;
585 MOV BL, T_OWNER_SAVED
;
586 CALL SET_LOGICAL_DRIVE
;
588 CMP S_DRV_SET_FLAG
, 0 ;
591 MOV BL, SOURCE_DRIVE
;
592 MOV DS_specialFunctions
, SET_SP_FUNC_DOS
;=0
593 MOV DX, OFFSET DS_IOCTL_DRV_PARM
;
594 CALL SET_DRV_PARM_DEF
;RESTORE SOURCE DRIVE PARM
599 CMP T_DRV_SET_FLAG
, 0 ;
602 MOV BL, TARGET_DRIVE
;
603 MOV DT_specialFunctions
, SET_SP_FUNC_DOS
;=0
604 MOV DX, OFFSET DT_IOCTL_DRV_PARM
;
605 CALL SET_DRV_PARM_DEF
;RESTORE TARGET DRIVE PARM
611 ; $ENDIF ;AN000;OK WITH SYSDISPMSG?
613 MOV AL,EXITFL
;AN000;PASS BACK ERRORLEVEL RET CODE
614 DOSCALL RET_CD_EXIT
;AN000;RETURN TO DOS WITH RET CODE
616 INT 20H
;AN000;IF ABOVE NOT WORK,
618 ; = = = = = = = = = = = = = = = = =
619 HEADER
<SET_LOGICAL_DRIVE
- SET LOG
. DRV LETTER THAT OWNS DRIVE
> ;AN000;
620 PUBLIC SET_LOGICAL_DRIVE
;
621 ;*****************************************************************************
622 SET_LOGICAL_DRIVE PROC
NEAR ;
623 ; *** SET THE LOGICAL DRIVE LETTER THAT WILL BE THE OWNER OF THE DRIVE
624 ; INPUT: BL - DRIVE LETTER
625 ; OUTPUT: OWNER WILL BE SET ACCORDINGLY.
626 ;*****************************************************************************
628 ; $IF NE ;IF BL = 0, THEN JUST RETURN
630 ;ELSE SET BL AS AN OWNER OF THAT DRIVE
631 MOV AX,(IOCTL_FUNC
SHL 8)+SET_LOGIC_DRIVE
;AC000;
636 SET_LOGICAL_DRIVE ENDP
;
637 ; = = = = = = = = = = = =
638 HEADER
<COPY
- COPY THE DISKETTE IMAGE
> ;AN000;
639 ;*****************************************************************************
642 ; INPUT: COPY_TYPE BYTE 1=SINGLE DRIVE COPY *
643 ; 2=DOUBLE DRIVE COPY *
646 ;*****************************************************************************
647 COPY PROC
NEAR ;COPY DISKETTE IMAGE
648 MOV VOLSER_FLAG
,0 ;AN000;RESET MEDIA ID VOL SERIAL NUMBER FLAG
649 MOV COPY_ERROR
,0 ;RESET COPY ERROR FLAG
650 MOV COPY_STATUS
,OK
;RESET COPY STATUS BYTE
652 MOV TRY_FORMAT_FLAG
, OFF
;
653 MOV TIME_OUT_FLAG
, OFF
;
654 MOV FORMAT_FLAG
,OFF
;ASSUME FORMAT IS NOT REQUIRED
655 MOV READ_S_BPB_FAILURE
, 0 ;RESET GET BPB FAILURE FLAG
656 MOV READ_T_BPB_FAILURE
, 0 ;
657 MOV AX, RECOMMENDED_BYTES_SECTOR
;
658 MOV bSECTOR_SIZE
, AX ;USE RECOMMENDED SECTOR SIZE TO READ A SECTOR
659 CMP COPY_TYPE
,2 ;IF TWO DRIVE COPY
662 PRINT MSGNUM_LOAD_SOURCE
;AC000;OUTPUT LOAD SOURCE DISKETTE MESSAGE
663 ;"INSERT SOURCE DISKETTE INTO DRIVE X:"
665 PRINT MSGNUM_LOAD_TARGET
;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
667 CALL PRESS_ANY_KEY
;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
671 MOV TRACK_TO_READ
,0 ;INITIALIZE TRACK NUMBERS
672 MOV TRACK_TO_WRITE
,0 ;
677 MOV AL,TRACK_TO_WRITE
;WHILE TRACK_TO_WRITE<=LAST_TRACK
681 CALL READ_SOURCE
;READ AS MANY TRACK AS POSSIBLE
683 CMP COPY_STATUS
,FATAL
;MAKE SURE DRIVES WERE COMPATIBLE
686 CALL WRITE_TARGET
;WRITE THE CONTENT OF BUFFER TO TARGET
688 CMP COPY_STATUS
,FATAL
;MAKE SURE TARGET AND SOURCE
695 CMP COPY_ERROR
,FALSE
;IF ERROR IN COPY
698 ;CR,LF,"Target diskette may be unusable",CR,LF
699 PRINT MSGNUM_TARGET_MB_UNUSABLE
;AC000;
705 CMP COPY_STATUS
,FATAL
;WAS COPY ABORTED ?
708 ;CR,LF,"Copy process ended",CR,LF
709 PRINT MSGNUM_FATAL_ERROR
;AC000;IF SO THEN TELL USER
711 ; $ELSE ;AN000;SINCE NOT ABORTED,
714 CALL WRITE_VOLSER
;AN000;GO CHANGE VOLID OF TARGET
721 ; = = = = = = = = = = = =
722 HEADER
<TEST_REPEAT
- SEE
IF USER WANTS TO COPY ANOTHER
> ;AN000;
723 ;*****************************************************************************
725 PUBLIC TEST_REPEAT
;AN000;MAKE ENTRY IN LINK MAP
726 TEST_REPEAT PROC
NEAR ;TEST IF USER WANTS TO COPY ANOTHER *
728 ; INPUT : USER_INPUT ("Y" OR "N")
729 ; OUTPUT: NC = COPY AGAIN *
731 ;*****************************************************************************
732 ; $SEARCH COMPLEX ;AC000;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED
735 PRINT MSGNUM_CR_LF
;AC000;
739 ;CR,LF,"Copy another diskette (Y/N)?"
740 PRINT MSGNUM_COPY_ANOTHER
;AC000;SEE IF USER WANTS TO COPY ANOTHER
741 ; AND READ RESPONSE TO AL
742 PUSH AX ;AN000;SAVE THE RESPONSE
743 PRINT MSGNUM_CR_LF
;AC000;
745 POP DX ;AN000;RESTORE THE REPONSE CHAR TO DL
746 CALL YESNO
;AN000;CHECK FOR (Y/N)
747 ;AX=0,NO; AX=1,YES; AX=2,INVALID
748 ; $EXITIF C,NUL ;AN000;IF CARRY SET, PROBLEM,PRETEND "NO"
751 CMP AX,BAD_YESNO
;AN000;WAS THE RESPONSE INVALID?
752 ; $ENDLOOP B ;AN000;QUIT IF OK ANSWER (AX=0 OR 1)
754 CMP AL,YES
;AN000;WAS "YES" SPECIFIED
755 ; $IF E ;AN000;IF "YES"
757 CLC ;AN000;CLEAR CARRY TO INDICATE COPY AGAIN
758 ; $ELSE ;AN000;SINCE NOT "YES"
761 STC ;AN000;SET CARRY TO INDICATE NO REPEAT
768 ; AND AL,11011111B ;MAKE USER INPUT UPPER CASE
769 ; CMP AL,YES ;IF YES THEN COPY AGAIN
771 ; CLC ;CLEAR CARRY TO INDICATE COPY AGAIN
773 ; CMP AL,NO ;IF NOT "N" OR "Y" THEN PROMPT AGAIN
775 ; STC ;SET CARRY TO INDICATE NO REPEAT
781 ; = = = = = = = = = = = =
782 HEADER
<READ_SOURCE
- READ
FROM SOURCE
AS MUCH
AS POSSIBLE
> ;AN000;
783 ;*****************************************************************************
785 PUBLIC READ_SOURCE
;AN000;MAKE ENTRY IN LINK MAP *
786 READ_SOURCE PROC
NEAR ;READ AS MANY TRACKS AS POSSIBLE FROM SOURCE*
787 ; ;DISKETTE TO FILL THE AVAILABLE BUFFER SPACE *
788 ;*****************************************************************************
790 CMP COPY_TYPE
,1 ;IF SINGLE DRIVE COPY
793 PRINT MSGNUM_LOAD_SOURCE
;AN000;"INSERT SOURCE DISKETTE INTO DRIVE X:"
795 CALL PRESS_ANY_KEY
;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
799 CMP TRACK_TO_READ
,0 ;1ST TRACK ?
803 CALL CHECK_SOURCE
;DO NECESSARY CHECKING
805 CALL CALC_TRACK_SIZE
;
807 CALL CHECK_MEMORY_SIZE
;
809 CMP COPY_STATUS
,FATAL
;
813 ;(deleted ;AN013;) CALL READ_VOLSER ;GO READ THE MEDIA ID TO GET SERIAL NUMBER ;AN000;
815 MOV BX,BUFFER_BEGIN
;
816 MOV BUFFER_PTR
,BX ;INITIALIZE BUFFER POINTER
820 MOV AL,TRACK_TO_READ
;DID WE FINISH READING ALL TRACKS?
824 MOV AX,BUFFER_PTR
;DID WE RUN OUT OF BUFFER SPACE
829 MOV OPERATION
,READ_FUNC
;
830 CALL READ_WRITE_TRACK
;NO, GO READ ANOTHER TRACK
840 ; = = = = = = = = = = = =
841 HEADER
<WRITE_TARGET
- WRITE
DATA FROM MEMORY TO TARGET DISKETTE
> ;AN000;
842 ;*****************************************************************************
844 PUBLIC WRITE_TARGET
;AN000;MAKE ENTRY IN LINK MAP
845 WRITE_TARGET PROC
;WRITE DATA FROM MEMORY TO TARGET DISKETTE*
847 ;*****************************************************************************
849 CMP COPY_TYPE
,1 ;IF SINGLE DRIVE COPY
852 PRINT MSGNUM_LOAD_TARGET
;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
854 CALL PRESS_ANY_KEY
;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
858 MOV TARGET_OP
, ON ;INDICATE A OPERATION ON TARGET
859 MOV BX,BUFFER_BEGIN
;
860 MOV BUFFER_PTR
,BX ;INITIALIZE BUFFER POINTER
861 CMP TRACK_TO_WRITE
,0 ;IF TRK 0, CHECK COMPATIBILITY
868 CMP COPY_STATUS
,FATAL
;IF INCOMPATIBLE, THEN EXIT
875 MOV AL,TRACK_TO_WRITE
;DID WE FINISH WRITING ALL TRACKS?
879 MOV AX,BUFFER_PTR
;DID WE RUN OUT OF BUFFER SPACE
884 MOV OPERATION
,WRITE_FUNC
;
885 CALL READ_WRITE_TRACK
;NO, GO WRITE ANOTHER TRACK
887 CMP COPY_STATUS
,FATAL
;IF INCOMPATIBLE, THEN EXIT
899 ; = = = = = = = = = = = =
900 HEADER
<READ_WRITE_TRACK
- READ A TRACK
AND STORE IT
INTO MEMORY
> ;AN000;
901 ;*****************************************************************************
903 PUBLIC READ_WRITE_TRACK
;AN000;MAKE ENTRY IN LINK MAP
904 READ_WRITE_TRACK PROC
NEAR ;READ A TRACK AND STORE IT INTO MEMORY *
906 ;INPUT: OPERATION = 61h THEN READ OPERATION *
907 ; 41h THEN WRITE OPERATION *
908 ;*****************************************************************************
914 CMP OPERATION
, READ_FUNC
;
924 CMP COPY_STATUS
, FATAL
;
929 CMP NO_OF_SIDES
, 0 ;SINGLE SIDE COPY?
933 ; $ELSE ;NO, DOUBLE SIDE
945 CMP AL, NO_OF_SIDES
;FINISHED WITH THE LAST SIDE?
950 READ_WRITE_TRACK ENDP
;
951 ; = = = = = = = = = = = =
952 HEADER
<READ_OP
- IOCTL READ A TRACK OPERATION
> ;AN000;
953 ;*****************************************************************************
955 PUBLIC READ_OP
;AN000;MAKE ENTRY IN LINK MAP
956 READ_OP PROC
NEAR ;IOCTL READ A TRACK OPERATION *
958 ;*****************************************************************************
964 MOV Head
, AX ;HEAD TO READ
965 MOV AL, TRACK_TO_READ
;
966 MOV Cylinder
, AX ;TRACK TO READ
967 MOV FirstSectors
, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
969 MOV Taddress_seg
, AX ;BUFFER ADDRESS
970 MOV Taddress_off
, 0 ;
972 MOV BL, SOURCE_DRIVE
;
973 MOV CL, READ_FUNC
;=61h
974 MOV DX, OFFSET IOCTL_R_W
;
977 CMP IO_ERROR
, NO_ERROR
;OK?
978 ; $EXITIF E ;AC013;IF NO ERROR SO FAR, GOOD
980 CMP CYLINDER
,0 ;AN013;IS THIS THE FIRST READ?
981 ; $IF E,AND ;AN013;IF THIS IS THE FIRST TRACK, AND
983 CMP HEAD
,0 ;AN013;IS THIS THE FIRST SIDE?
984 ; $IF E ;AN013;AND IF THIS IS THE FIRST SIDE
986 CALL MAYBE_ADJUST_SERIAL
;AN013;IF BOOT HAS SERIAL, GENERATE NEW ONE
988 ; $ENDIF ;AN013;FIRST TRACK AND HEAD?
990 ; $ORELSE ;AN013;SINCE SOME KIND OF ERROR, OOPS
993 CMP IO_ERROR
, SOFT_ERROR
;TRY AGAIN?
997 CMP MSG_FLAG
, ON ;ELSE HARD ERROR. SEE IF
998 ; MESSAGE TO BE DISPLAYED
1003 mov dl, source_drive
;
1004 CALL ERROR_MESSAGE
;
1006 INC COPY_ERROR
;INCREASE COPY_ERROR COUNT
1014 ; = = = = = = = = = = = =
1015 HEADER
<MAYBE_ADJUST_SERIAL
- MAKE NEW SERIAL
IN BOOT
> ;AN013;
1016 MAYBE_ADJUST_SERIAL PROC
NEAR ;AN013;
1017 ;INPUT: TADDRESS_OFF/_SEG HAS TRACK BUFFER WHICH HAS BOOT RECORD
1018 ; "VOLSER_FLAG" IS FALSE.
1019 ;OUTPUT:SERIAL NUMBER FIELD IS MODIFIED TO HAVE NEW SERIAL NUMBER
1020 ; A COPY OF WHICH IS PRESERVED IN "SERIAL" FOR LATER DISPLAY IN MSG.
1021 ; "VOLSER_FLAG" SET TO TRUE TO INDICATE NEW SERIAL GENERATED.
1022 ; IF THIS BOOT DOES NOT HAVE A SERIAL, NO CHANGE MADE, AND
1023 ; "VOLSER_FLAG" LEFT AS FALSE.
1025 ; A BOOT RECORD IS ASSUMED TO HAVE A SERIAL NUMBER IF:
1026 ; EBPB_MEDIADESCRIPTOR=0F?H AND EXT_BOOT_SIG IS EITHER 28H OR 29H.
1028 PUSH ES ;AN013;SAVE EXTRA SEG REG TEMPORARILY
1029 PUSH BX ;AN013;AND SAVE THE BASE POINTER
1030 PUSH SI ;AN013; AND THE INDEX
1031 LES BX,DWORD PTR TADDRESS_OFF
;AN013;POINT TO BUFFER AREA CONTAINING BOOT RECORD
1032 LEA SI,ES:[BX].EXT_BOOT_BPB
;AN013;POINT TO BPB PORTION OF BOOT RECORD
1033 MOV AL,ES:[SI].EBPB_MEDIADESCRIPTOR
;AN013;GET TYPE OF MEDIA
1034 AND AL,0F0H ;AN013;SAVE LEFT NIBBLE ONLY
1035 CMP AL,0F0H ;AN013;IF DISKETTE HAS PROPER DESCRIPTOR
1036 ; $IF E ;AN013;IF OK DESCRIPTOR
1038 MOV AL,ES:[BX].EXT_BOOT_SIG
;AN013;GET "SIGNATURE" OF BOOT RECORD
1039 CMP AL,28H
;AN013;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1?
1040 ; $IF E,OR ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
1042 CMP AL,29H
;AN013;IS THIS A BOOT STYLE OF OS/S 1.2?
1043 ; $IF E ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
1047 DOSCALL GET_DATE
;AN013;READ SYSTEM DATE
1048 ;OUTPUT: DL = DAY (1-31)
1049 ; AL = DAY OF WEEK (0=SUN,6=SAT)
1050 ; CX = YEAR (1980-2099)
1052 PUSH CX ;AN013;SAVE THESE FOR
1053 PUSH DX ;AN013; INPUT INTO HASH ALGORITHM
1055 DOSCALL GET_TIME
;AN013;READ SYSTEM TIME CLOCK
1056 ;OUTPUT: CH = HOUR (0-23)
1057 ; CL = MINUTES (0-59)
1058 ; DH = SECONDS (0-59)
1059 ; DL = HUNDREDTHS (0-99)
1061 ; HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
1062 ; SERIAL+0 = DX FROM DATE + DX FROM TIME
1063 ; SERIAL+2 = CX FROM DATE + CX FROM TIME
1065 POP AX ;AN013;GET THE DX FROM DATE
1066 ADD AX,DX ;AN013;ADD IN THE DX FROM TIME
1067 MOV WORD PTR SERIAL
,AX ;AN013;SAVE FIRST RESULT OF HASH
1068 MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL
,AX ;AN013;AND IN BOOT RECORD ITSELF
1070 POP AX ;AN013;GET THE CX FROM DATE
1071 ADD AX,CX ;AN013;ADD IN THE CX FROM TIME
1072 MOV WORD PTR SERIAL
+WORD,AX ;AN013;SAVE SECOND RESULT OF HASH
1073 MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL
+WORD,AX ;AN013;AND IN BOOT RECORD
1075 MOV VOLSER_FLAG
,TRUE
;AN013;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN
1077 ; $ENDIF ;AN013;BOOT HAVE SERIAL?
1079 ; $ENDIF ;AN013;PROPER DESCRIPTOR?
1081 POP SI ;AN013;RESTORE THE INDEX REG
1082 POP BX ;AN013;RESTORE THE BASE POINTER
1083 POP ES ;AN013;RESTORE EXTRA SEG REG
1084 RET ;AN013;RETURN TO CALLER
1085 MAYBE_ADJUST_SERIAL ENDP
;AN013;
1086 ; = = = = = = = = = = = =
1087 HEADER
<WRITE_OP
- IOCTL WRITE A TRACK OPERATION
> ;AN000;
1088 ;*****************************************************************************
1090 PUBLIC WRITE_OP
;AN000;MAKE ENTRY IN LINK MAP
1091 WRITE_OP PROC
NEAR ;IOCTL WRITE A TRACK OPERATION *
1093 ;*****************************************************************************
1100 MOV Head
, AX ;HEAD TO WRITE
1101 MOV AL, TRACK_TO_WRITE
;
1102 MOV Cylinder
, AX ;TRACK TO WRITE
1103 MOV FirstSectors
, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
1104 MOV AX, BUFFER_PTR
;
1105 MOV Taddress_seg
, AX ;BUFFER ADDRESS
1106 MOV Taddress_off
, 0 ;
1108 MOV BL, TARGET_DRIVE
;
1109 MOV CL, WRITE_FUNC
;= 41h
1110 MOV DX, OFFSET IOCTL_R_W
;
1111 CALL GENERIC_IOCTL
;
1113 CMP IO_ERROR
, NO_ERROR
;OK?
1114 ; $LEAVE E ;YES, SUCCESS. EXIT THIS ROUTINE
1117 CMP IO_ERROR
, SOFT_ERROR
;TRY AGAIN?
1120 ;WRITE FAILURE, LET'S TRY TO FORMAT.
1121 CMP FORMAT_FLAG
, ON ;WAS THIS TRACK FORMATTED BEFORE?
1122 ; $EXITIF E ;YES, GIVE UP WRITING AND
1124 ; CHECK WHEN IT HAPPENDED.
1125 ;GIVE UP WRITING AND SHOW ERROR MESSAGE.
1126 INC COPY_ERROR
;INDICATE ERROR OCCURS DURING COPY.
1127 MOV AH, WRITE_FUNC
;
1128 mov dl, target_drive
;
1129 CALL ERROR_MESSAGE
;SHOW MESSAGE 'WRITE ERROR SIDE, TRACK...'
1132 ; $ORELSE ;ELSE TRY FORMAT AND TRY WRITE AGAIN
1136 ;CR,LF,"Formatting while copying",CR,LF
1137 PRINT MSGNUM_FORMATTING
;AN000;SHOW MESSAGE
1139 MOV FORMAT_FLAG
, ON ;FORMAT ALL TRACKS FROM THIS TRACK
1140 CALL FORMAT_ALL
;format all the rest of the tracks
1142 CMP COPY_STATUS
, FATAL
;
1147 ;this next is dead code, nobody calls WO_FATAL, so the move copy_status
1148 ;and the print not compatible msg should be removed, and just the JMP WO_EXIT
1149 ;will no longer be needed to skip stuff that is not there. Kiser
1150 ; JMP WO_EXIT ;AND EXIT THIS ROUTINE
1152 ; MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM
1153 ; PRINT MSG_NOT_COMPATIBLE ;SHOW NOT COMPATIABLE MESSAGE
1161 ; = = = = = = = = = = = =
1162 HEADER
<FORMAT_ALL
- FORMATS ALL TRACKS TO
END> ;AN000;
1163 ;*****************************************************************************
1165 PUBLIC FORMAT_ALL
;AN000;MAKE ENTRY IN LINK MAP
1166 FORMAT_ALL PROC
NEAR ;
1168 ;Format all tracks starting from TRACK_TO_WRITE to the end. *
1169 ;This routine will set MT_deviceBPB to that of MS_deviceBPB. *
1170 ;trackLayout had been all set correctly. *
1171 ;If error, then fail to diskcopy. *
1172 ;*****************************************************************************
1174 MOV CX, MS_deviceBPB_leng
;set length of BPB
1175 MOV SI, OFFSET MS_deviceBPB
;
1176 MOV DI, OFFSET MT_deviceBPB
;
1178 CALL CHK_MEDIATYPE
;set MT_mediaTYPE for FORMAT operation
1180 MOV MT_specialFunctions
, SET_SP_BF_FORM
;=00000101B
1181 MOV CL, SETDEVPARM
;=40h
1182 MOV DX, OFFSET MT_IOCTL_DRV_PARM
;
1184 mov bl, last_track
;patch 3/27/86 for 3.2 diskcopy. J.K.
1186 mov MT_numberOfCylinders
, bx ;make sure target # of cyl.
1187 MOV BL, TARGET_DRIVE
;
1188 CALL GENERIC_IOCTL
;
1192 MOV FspecialFunctions
, STATUS_CHK
;check to see if the parameters set
1193 ;by "SET DEVICE PARM" func above are
1195 MOV AX,(IOCTL_FUNC
SHL 8)+GENERIC_IOCTL_CODE
;AC000;(440DH)
1196 MOV CH, MAJOR_CODE
;=8
1197 MOV CL, FORMAT_FUNC
;=42H
1199 MOV BL, TARGET_DRIVE
;
1200 MOV DX, OFFSET IOCTL_FORMAT
;result is in Fspecialfunction
1201 INT 21H
;0 - Thre is ROM support of AH=18h, INT 13h, and
1202 ; it is a valid combination
1204 MOV AL, FspecialFunctions
;1 - No ROM support. 2 - There is ROM support,
1205 ; but invalid combination
1206 MOV FspecialFunctions
, FORMAT_SP_FUNC
;restore specialfunction value
1207 CMP AL, 2 ;ROM support, but this combination is not valid?
1210 MOV AL, TRACK_TO_WRITE
;
1211 MOV TRACK_TO_FORMAT
, AL ;
1213 MOV SIDE_TO_FORMAT
, AL ;
1214 CMP AL, NO_OF_SIDES
;
1215 JE FA_SIDE_WHILE
;STARTS WITH THE OTHER SIDE TO FORMAT
1218 MOV AL, LAST_TRACK
;
1219 CMP TRACK_TO_FORMAT
, AL ;
1223 MOV AL, NO_OF_SIDES
;
1224 CMP SIDE_TO_FORMAT
, AL ;
1227 CALL FORMAT_TRACK
;FORMAT THIS TRACK
1229 CMP IO_ERROR
, HARD_ERROR
;
1232 CMP SIDE_TO_FORMAT
, 1 ;HARD ERROR AT SIDE 1?
1233 JNE FA_TARGET_BAD
;THEN ASSUME TARGET DISKETTE BAD
1235 CMP TRACK_TO_FORMAT
, 0 ;AT CYLINDER 0?
1238 JMP FA_FATAL
;THEN, SOURCE IS TWO SIDED AND
1239 ; TARGET IS SINGLE SIDE DISKETTE
1242 INC SIDE_TO_FORMAT
;
1246 MOV SIDE_TO_FORMAT
, 0 ;RESET SIDE_TO_FORMAT
1247 INC TRACK_TO_FORMAT
;
1248 JMP FA_TRACK_WHILE
;
1251 MOV COPY_STATUS
, FATAL
;WE ARE GOING TO ABORT PROGRAM
1252 ;"Drive types or diskette types"
1254 PRINT MSGNUM_NOT_COMPATIBLE
;AC000;SHOW NOT COMPATIBLE MESSAGE
1259 MOV COPY_STATUS
, FATAL
;WE ARE GOING TO ABORT PROGRAM
1260 ;CR,LF,"TARGET diskette bad or incompatible"
1261 PRINT MSGNUM_BAD_TARGET
;AC000;SHOW TARGET BAD MESSAGE
1265 MOV BL, TARGET_DRIVE
;
1266 MOV T_DRV_SET_FLAG
, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET
1267 MOV DX, OFFSET MT_IOCTL_DRV_PARM
;
1268 MOV MT_specialFunctions
, SET_SP_FUNC_DEF
;
1269 CALL SET_DRV_PARM_DEF
;SET IT BACK FOR WRITING.
1273 ; = = = = = = = = = = = =
1274 HEADER
<FORMAT_TRACK
- IOCTL
FORMAT A TRACK
> ;AN000;
1275 ;******************************************************************************
1276 ; SUBROUTINE NAME : FORMAT_TRACK - IOCTL FORMAT A TRACK *
1277 ; (BOTH SIDES IF 2-SIDED DSKT) *
1279 ; INPUT : TRACK_TO_FORMAT *
1280 ; : SIDE BYTE 0, 1 (HEAD NUMBER) *
1281 ; : END_OF_TRACK BYTE 8, 9, 15 *
1282 ; : TARGET_DRIVE BYTE 1 = A, 2 = B, ETC *
1284 ; OUTPUT : none. This routine does not report format error. *
1285 ; Write routine will detect the error consequently. *
1286 ; REGISTER(S) AFFECTED: *
1287 ;******************************************************************************
1288 PUBLIC FORMAT_TRACK
;AN000;MAKE ENTRY IN LINK MAP
1289 FORMAT_TRACK PROC
NEAR ;
1295 MOV AL, SIDE_TO_FORMAT
;
1296 MOV FHead
, AX ;HEAD TO FORMAT
1297 MOV AL, TRACK_TO_FORMAT
;
1298 MOV FCylinder
, AX ;TRACK TO FORMAT
1301 MOV BL, TARGET_DRIVE
;DRIVE TO FORMAT
1302 MOV CL, FORMAT_FUNC
;=42h
1303 MOV DX, OFFSET IOCTL_FORMAT
;
1304 CALL GENERIC_IOCTL
;
1306 CMP IO_ERROR
, SOFT_ERROR
;TRY FORMAT AGAIN?
1307 ; (DRIVE NOT READY OR WRITE PROTECTED)
1313 ; = = = = = = = = = = = =
1314 HEADER
<CHECK_SOURCE
- CHECK SOURCE DISKETTE TYPE
> ;AN000;
1315 ;*****************************************************************************
1317 PUBLIC CHECK_SOURCE
;AN000;MAKE ENTRY IN LINK MAP
1318 CHECK_SOURCE PROC
NEAR ;CHECK SOURCE DISKETTE TYPE *
1319 ; SET END_OF_TRACK, LAST_TRACK *
1320 ; NO_OF_SIDES, bSECTOR_SIZE *
1321 ; ** this routine will call "Get dev parm" with "BUILD BPB BIT" on. If it *
1322 ; ** fails to get that info, then the source medium must be bad(vergin) or *
1323 ; ** below DOS 2.0 level diskette, and will jmp to the old logic. *
1324 ; ** For compatibility reasons (in case of non IBM formatted media), this *
1325 ; ** routine covers old diskcopy routines. But this will only supports
1326 ; ** 5.25" 48 tpi 8, 9 sectors, 40 tracks and 5.25" 96 tpi, 15 sectors, 80 tracks
1327 ; ** media. Other non IBM formatted media which are formatted differenty
1328 ; ** from those values will result in unpreditable copy process.
1329 ;*****************************************************************************
1334 MOV BL, SOURCE_DRIVE
;
1335 MOV MS_specialFunctions
, GET_SP_FUNC_MED
;=00000001b
1336 MOV CL, GETDEVPARM
;=60h
1337 MOV DX, OFFSET MS_IOCTL_DRV_PARM
;
1338 CALL GENERIC_IOCTL
;TRY TO GET MEDIA BPB INFO TOGETHER
1339 ;WITH DEFAULT DEVICE INFO.
1340 CMP IO_ERROR
, SOFT_ERROR
;TRY AGAIN?
1344 CMP IO_ERROR
, HARD_ERROR
;CANNOT GET MEDIA BPB?
1345 JE CS_OLD
;ASSUME OLD FORMATTED DISKETTE, FIRST.
1347 cmp ms_deviceBPB
.csect_track
,0 ;patch 1/16/86
1350 cmp ms_deviceBPB
.chead
,0 ;cannot trust the info from dos
1351 je cs_old
;sanity check for divide by 0
1353 MOV AX, MS_deviceBPB
.CTOTSECT
;
1354 CWD ;CONVERT IT TO A DOUBLE WORD
1355 DIV MS_deviceBPB
.CSECT_TRACK
;
1356 DIV MS_deviceBPB
.CHEAD
;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1357 CMP AL, T_DRV_TRACKS
;SOURCE MEDIA # OF TRACK > TARGET
1358 ; DEVICE # OF TRACKS?
1359 JA CS_FATAL
;THEN, NOT COMPATIBLE.
1361 DEC AX ;DECREASE BY 1 FOR THE USE OF THIS PROGRAM.
1362 MOV LAST_TRACK
, AL ;SET LAST_TRACK
1363 MOV AX, MS_deviceBPB
.CSECT_TRACK
;
1364 CMP AL, T_DRV_SECT_TRACK
;SOURCE MEDIA # OF SECT/TRACK > TARGET
1365 ; DEVICE # OF SECT/TRACK?
1366 JA CS_FATAL
;THEN, NOT COMPATIBLE
1368 MOV END_OF_TRACK
, AL ;
1369 MOV AX, MS_deviceBPB
.CBYTE_SECT
;
1370 MOV bSECTOR_SIZE
, AX ;set the sector size in bytes.
1371 CMP USER_OPTION
, 1 ;
1374 MOV AX, MS_deviceBPB
.CHEAD
;HEAD=1, 2
1375 CMP AL, T_DRV_HEADS
;COMPARE SOURCE MEDIA SIDE WITH
1376 ; TARGET DRIVE HEAD NUMBER
1377 JA CS_FATAL
;SOURCE MEDIUM IS DOUBLE SIDED AND
1378 ; TARGET DRIVE IS SINGLE SIDED.
1381 MOV NO_OF_SIDES
, AL ;NO_OF_SIDES=0, 1
1383 ; = = = = = = = = = = =
1385 MOV COPY_STATUS
, FATAL
;
1386 ;CR,LF,"Drive types or diskette types",CR,LF
1387 ;"not compatible",CR,LF
1388 PRINT MSGNUM_NOT_COMPATIBLE
;AC000;
1391 ; = = = = = = = = = = =
1393 MOV COPY_STATUS
, FATAL
;
1394 PRINT MSGNUM_BAD_SOURCE
;CR,LF,"SOURCE diskette bad or incompatible"
1398 ; = = = = = = = = = = =
1400 MOV READ_S_BPB_FAILURE
, 1 ;SET FLAG
1401 MOV bSECTOR_SIZE
, 512 ;OLD SECTOR SIZE MUST BE 512 BYTES
1403 MOV BL, SOURCE_DRIVE
;
1404 MOV IOCTL_TRACK
, 0 ;TRACK=0
1405 MOV IOCTL_SECTOR
, 8 ;SECTOR=8
1406 MOV IOCTL_HEAD
, 0 ;HEAD = 0
1407 CALL READ_A_SECTOR
;
1409 JC CS_BAD
;SOURCE BAD
1411 MOV IOCTL_SECTOR
, 9 ;TRY TO READ SECTOR=9
1412 CALL READ_A_SECTOR
;
1414 JC CS_SECT8
;YES, 8 SECTORS. ASSUME 40 TRACKS
1416 MOV IOCTL_SECTOR
, 15 ;try to read sector=15
1417 CALL READ_A_SECTOR
;
1419 JC CS_SECT9
;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA
1421 JMP SHORT CS_SECT15
;
1423 ; = = = = = = = = = = =
1425 MOV NO_OF_SIDES
, 0 ;1 SIDE COPY
1426 JMP SHORT CS_SET_TABLE
;
1428 ; = = = = = = = = = = =
1430 MOV END_OF_TRACK
, 15 ;ELSE END_OF_TRACK = 15
1431 MOV LAST_TRACK
, 79 ;
1432 JMP SHORT CS_CHK_SIDE
;
1434 ; = = = = = = = = = = =
1436 MOV END_OF_TRACK
, 8 ;SOURCE 8 SECTORS
1437 MOV LAST_TRACK
, 39 ;ASSUME 40 TRACKS.
1438 JMP SHORT CS_CHK_SIDE
;
1440 ; = = = = = = = = = = =
1442 MOV END_OF_TRACK
, 9 ;
1443 MOV LAST_TRACK
, 39 ;ASSUME 5.25 DISKETTE
1444 JMP SHORT CS_CHK_SIDE
;
1446 ; = = = = = = = = = = =
1448 CMP USER_OPTION
, 1 ;
1451 MOV IOCTL_HEAD
, 1 ;HEAD 1
1453 MOV AL, END_OF_TRACK
;READ MATCHING END_OF_TRACK
1454 ; OF THE OTHER SURFACE.
1455 MOV IOCTL_SECTOR
, AX ;
1456 CALL READ_A_SECTOR
;
1458 JC CS_OPTION_1
;1 SIDED SOURCE
1460 MOV NO_OF_SIDES
, 1 ;2 SIDED SOURCE
1461 CMP T_DRV_HEADS
, 2 ;SOUCE=2 SIDED MEDIUM. IS TARGET
1465 JMP CS_FATAL
;NOT COMPATIBLE
1467 ; = = = = = = = = = = =
1469 CMP READ_S_BPB_FAILURE
, 1 ;DISKETTE WITHOUT BPB INFO?
1472 CALL SET_FOR_THE_OLD
;
1476 MOV BX, OFFSET MS_trackLayout
;SET TRACKLAYOUT OF SOURCE
1477 CALL SET_TRACKLAYOUT
;
1479 MOV BX, OFFSET MT_trackLayout
;YES, ASSUME TARGET IS SAME
1480 CALL SET_TRACKLAYOUT
;
1482 MOV S_DRV_SET_FLAG
, 1 ;
1484 MOV BL, SOURCE_DRIVE
;
1485 MOV MS_specialFunctions
, SET_SP_FUNC_DEF
;=00000100B
1486 MOV DX, OFFSET MS_IOCTL_DRV_PARM
;
1487 CALL SET_DRV_PARM_DEF
;NOW, SET SOURCE DRIVE PARM
1488 ; FOR READ OPERATION.
1491 MOV AL, END_OF_TRACK
;
1492 MOV numberOfSectors
, AX ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE
1494 MOV AL, LAST_TRACK
;NOW, SHOW THE MESSAGE "COPYING ..."
1497 ; MOV BYTE PTR MSG_COPYING_PTR+2, AL ;HOW MANY TRACKS?
1499 MOV BYTE PTR MSG_TRACKS
, AL ;AC000;HOW MANY TRACKS?
1501 MOV AL, END_OF_TRACK
;
1503 ; MOV BYTE PTR MSG_COPYING_PTR+4, AL ;HOW MANY SECTORS?
1505 MOV BYTE PTR MSG_SECTRK
,AL ;AC000;HOW MANY SECTORS?
1507 MOV AL, NO_OF_SIDES
;TELL USER HOW MANY SIDE TO COPY
1510 ; MOV BYTE PTR MSG_COPYING_PTR+6, AL
1512 MOV BYTE PTR MSG_SIDES
,AL ;AC000;HOW MANY SIDES?
1513 ;CR,LF,"Copying %1 tracks",CR,LF
1514 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
1515 PRINT MSGNUM_COPYING
;AC000;
1521 ; = = = = = = = = = = = =
1522 HEADER
<READ_A_SECTOR
- GET ONE SECTOR WITH IOCTL READ
> ;AN000;
1523 ;******************************************************************************
1524 PUBLIC READ_A_SECTOR
;AN000;MAKE ENTRY IN LINK MAP
1525 READ_A_SECTOR PROC
NEAR ;
1527 ;TRY TO READ A SECTOR USING IOCTL READ FUNCTION CALL. *
1528 ;THIS ROUTINE WILL STEAL "IOCTL_R_W" TABLE TEMPORARILY. *
1529 ;INPUT: BX - LOGICAL DRIVE NUMBER *
1530 ; IOCTL_SECTOR - SECTOR TO READ *
1531 ; IOCTL_TRACK - TRACK *
1532 ; IOCTL_HEAD - HEAD TO READ *
1533 ; bSECTOR_SIZE - SECTOR SIZE IN BYTES *
1535 ; IF NOT A SUCCESS, CARRY WILL BE SET *
1536 ; ALL REGISTORS SAVED *
1538 ;******************************************************************************
1545 MOV AX, numberOfSectors
;SAVE IOCTL_R_W TABLE VALUES
1551 MOV AX, IOCTL_HEAD
;
1552 MOV Head
, AX ;SURFACE TO READ
1553 MOV AX, IOCTL_TRACK
;
1554 MOV Cylinder
, AX ;TRACK TO READ
1555 MOV AX, IOCTL_SECTOR
;
1556 dec ax ;????? currently
1557 ; firstsector=0 => 1st sector ????
1558 MOV FirstSectors
, AX ;SECTOR TO READ
1559 MOV numberOfSectors
, 1 ;read just one sector
1560 MOV AX, offset INIT
;READ IT INTO INIT
1561 ; (CURRELTLY, MAX 1K)
1562 MOV TAddress_off
, AX ;
1563 MOV TAddress_seg
, DS ;
1565 MOV DX, OFFSET IOCTL_R_W
;POINTS TO CONTROL TABLE
1566 call generic_ioctl
;
1568 CMP IO_ERROR
, SOFT_ERROR
;TRY ONCE MORE?
1572 CMP IO_ERROR
, HARD_ERROR
;HARD ERROR?
1583 MOV AX, SAV_CSECT
;RESTORE ORIGINAL IOCTL_R_W TABLE
1584 MOV numberOfSectors
, AX ;
1591 READ_A_SECTOR ENDP
;
1592 ; = = = = = = = = = = = =
1593 HEADER
<CALC_TRACK_SIZE
- GET MEM SIZE TO
STORE ONE TRACK
> ;AN000;
1594 ;*****************************************************************************
1595 PUBLIC CALC_TRACK_SIZE
;AN000;MAKE ENTRY IN LINK MAP
1596 CALC_TRACK_SIZE PROC
NEAR ;CALCULATE MEMORY SIZE REQUIRED TO STORE ONE
1597 ; TRACK (IN SEGMENTS) *
1599 ;CALCULATE SECTOR_SIZE IN PARA FROM bSECTOR_SIZE. IF bSECTOR_SIZE CANNOT BE *
1600 ;CHANGED TO SECTOR_SIZE IN PARA EXACTLY, THEN ADD 1 TO THE SECTOR_SIZE. *
1601 ;SECTOR_SIZE IS USED FOR MEMORY MANAGEMANT ONLY. THE ACTUAL COPY OR FORMAT *
1602 ;SHOULD BE DEPENDS ON bSECTOR_SIZE TO FIGURE OUT HOW BIG A SECTOR IS. *
1603 ;ALSO, CURRENTLY, THIS ROUTINE ASSUME A BSECTOR SIZE BE LESS THAN 0FFFh. *
1604 ;*****************************************************************************
1610 MOV AX, bSECTOR_SIZE
;
1612 DIV CL ;AX / 16 = AL ... AH
1613 CMP AH, 0 ;NO REMAINER?
1617 INC AL ;THERE REMAINER IS. INC AL
1621 MOV SECTOR_SIZE
, AL ;SECTOR_SIZE+ IN PARA.
1622 MOV AL,NO_OF_SIDES
;TRACK_SIZE = (NO OF SIDES
1624 MUL END_OF_TRACK
; * END_OF_TRACK
1625 MOV BL,SECTOR_SIZE
; * SECTPR_SIZE
1626 MUL BL ;AMOUNT OF MEMORY REQUIRED (IN SEG)
1627 MOV TRACK_SIZE
,AX ;TO STORE A TRACK
1633 CALC_TRACK_SIZE ENDP
;
1634 ; = = = = = = = = = = = =
1635 HEADER
<CHECK_MEMORY_SIZE
- VERIFY WE HAVE ENUF TO COPY
1 TRACK
> ;AN000;
1636 ;*****************************************************************************
1637 PUBLIC CHECK_MEMORY_SIZE
;AN000;MAKE ENTRY IN LINK MAP
1638 CHECK_MEMORY_SIZE PROC
NEAR ;MAKE SURE WE HAVE ENOUGH TO COPY 1 TRACK INTO
1639 ; TO BUFFER ELSE ABORT COPY *
1640 ;*****************************************************************************
1641 MOV AX,BUFFER_END
;CALCULATE AVAILABLE MEMORY
1642 SUB AX,BUFFER_BEGIN
;IN SEGMENTS
1643 CMP AX,TRACK_SIZE
;DO WE HAVE ENOUGH TO STORE A CYLINDER?
1646 MOV COPY_STATUS
,FATAL
;NO, ABORT COPY
1647 PRINT MSGNUM_UNSUF_MEMORY
;AC000;AND TELL USER WHY
1653 CHECK_MEMORY_SIZE ENDP
;
1654 ; = = = = = = = = = = = =
1655 HEADER
<SET_FOR_THE_OLD
- SET BPB FOR BEFORE
-2.0 FMTTED MEDIA
> ;AN000;
1656 ;*****************************************************************************
1657 PUBLIC SET_FOR_THE_OLD
;AN000;MAKE ENTRY IN LINK MAP
1658 SET_FOR_THE_OLD PROC
NEAR ;
1660 ;set MS_deviceBPB for before-2.0 formatted media
1661 ;*****************************************************************************
1664 CMP END_OF_TRACK
,9 ;IF SECTORS/TRACK <= 9, THEN CHECK
1665 ;NO_OF_SIDES. IF SINGLE SIDE
1666 ; COPY THEN USE BPB48_SINGLE
1667 ;ELSE USE BPB48_DOUBLE.
1668 ; $IF A ;SECTORS/TRACK > 9 THEN USE BPB96 TABLE
1670 MOV SI, OFFSET BPB96
;
1674 CMP NO_OF_SIDES
, 0 ;SINGLE SIDE COPY?
1677 MOV SI, OFFSET BPB48_DOUBLE
;USE BPB48 DOUBLE
1681 MOV SI, OFFSET BPB48_SINGLE
;
1687 MOV AL, END_OF_TRACK
;
1689 MOV MS_deviceBPB
.CSECT_TRACK
,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM
1690 MOV DI, OFFSET MS_deviceBPB
;
1691 MOV CX, BPB96_LENG
;
1692 REP MOVSB ;OLD DEFAULT BPB INFO => MS_deviceBPB
1696 SET_FOR_THE_OLD ENDP
;
1697 ; = = = = = = = = = = = =
1698 HEADER
<SET_TRACKLAYOUT
- MOVE
DATA TO TRACK IMAGE
> ;AN000;
1699 ;*****************************************************************************
1700 PUBLIC SET_TRACKLAYOUT
;AN000;MAKE ENTRY IN LINK MAP
1701 SET_TRACKLAYOUT PROC
NEAR ;
1703 ;INPUT: BX - POINTER TO DESTINATION
1704 ;*****************************************************************************
1707 MOV CL, END_OF_TRACK
;
1708 MOV WORD PTR [BX], CX ;SET CSECT_F TO THE NUMBER OF
1709 ; SECTORS IN A TRACK
1710 ADD BX, 2 ;NOW BX POINTS TO
1711 ; THE FIRST SECTORNUMBER
1713 MOV AX, bSECTOR_SIZE
;
1717 CMP CL, END_OF_TRACK
;
1721 MOV WORD PTR [BX], CX ;
1724 MOV WORD PTR [BX], AX ;
1734 SET_TRACKLAYOUT ENDP
;
1735 ; = = = = = = = = = = = =
1736 HEADER
<CHECK_TARGET
- READ TARGET BOOT RCD
, NEEDS
FORMAT?
> ;AN000;
1737 ;*****************************************************************************
1738 PUBLIC CHECK_TARGET
;AN000;MAKE ENTRY IN LINK MAP
1739 CHECK_TARGET PROC
NEAR ; *
1740 ; ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD. *
1741 ; ** IF A SUCCESS,THEN COMPARES BPB INFO WITH THAT OF SOURCE MEDIA. *
1742 ; ** IF THEY ARE DIFFERENT, THEN SET FORMAT_FLAG AND RETURN. *
1743 ; ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR *
1744 ; ** COMPATIBILITY REASON. *
1745 ;*****************************************************************************
1750 MOV BL, TARGET_DRIVE
;
1751 MOV MT_specialFunctions
, GET_SP_FUNC_MED
;=00000001b
1752 MOV CL, GETDEVPARM
;=60h
1753 MOV DX, OFFSET MT_IOCTL_DRV_PARM
;
1754 CALL GENERIC_IOCTL
;TRY TO GET MEDIA BPB INFO TOGETHER
1755 ;WITH DEFAULT DEVICE INFO.
1756 CMP IO_ERROR
, SOFT_ERROR
;TRY AGAIN?
1760 CMP IO_ERROR
, HARD_ERROR
;CANNOT GET MEDIA BPB?
1761 JE CT_OLD
;ASSUME OLD FORMATTED DISKETTE, FIRST.
1763 cmp mt_deviceBPB
.csect_track
,0 ;patch 1/16/86 for 3.2 diskcopy
1766 cmp mt_deviceBPB
.chead
,0 ;cannot belive the info from dos
1767 je ct_old
;sanity check for divide by 0.
1769 MOV AX, MT_deviceBPB
.CTOTSECT
;
1770 CWD ;CONVERT IT TO A DOUBLE WORD
1771 DIV MT_deviceBPB
.CSECT_TRACK
;
1772 DIV MT_deviceBPB
.CHEAD
;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1773 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM.
1774 CMP LAST_TRACK
, AL ;COMPARE WITH THE LAST TRACK OF SOURCE
1775 JE CT_SECTOR_TRACK
;IF SAME, THEN CHECK SECTOR PER TRACK
1776 ;SINCE NOT THE SAME, CONTINUE...
1778 CMP MT_deviceBPB
.CSECT_TRACK
,0FH ;AN012;IS TARGET 15 SEC / TRK?
1779 JNE CT_FORMAT
;AN012;NO, SOMETHING ELSE...
1780 ;YES, 15 SEC/TRACK, CONTINUE...
1782 CMP LAST_TRACK
,27H
;AN012;IS SOURCE ORIGINALLY 40 TRACK?
1783 JNE CT_FORMAT
;AN012;NO, SOMETHING ELSE...
1784 ;YES, 40 TRACK, CONTINUE...
1785 JMP CT_FATAL
;AN012;ABORT THIS, DO NOT MESS UP THE 1.2M
1786 ; WITH NOBLE ATTEMPTS TO FORMAT
1788 MOV AX, MT_deviceBPB
.CSECT_TRACK
;
1789 CMP END_OF_TRACK
, AL ;
1793 MOV AX, MT_deviceBPB
.CBYTE_SECT
;
1794 CMP AX, bSECTOR_SIZE
;
1798 MOV AX, MT_deviceBPB
.CHEAD
;
1800 CMP AL, NO_OF_SIDES
;
1801 JB CT_FORMAT
;IF TARGET SIDE < SOURCE SIDE
1804 JMP CT_SET_DRV
;TARGET IS O.K. SET DRIVE PARM
1808 PRINT MSGNUM_FORMATTING
;AC000;"Formatting while copying"
1810 MOV FORMAT_FLAG
, ON ;
1811 CALL FORMAT_ALL
;FORMAT ALL TRACKS STARTING
1812 ; FROM TRACK_TO_WRITE
1816 CMP UKM_ERR
,ON ;AN011;IS THIS HARD ERROR "UNKNOWN MEDIA"?
1817 JE CT_FORMAT
;AN011; IF SO, GO TRY FORMATTING
1818 ;SAME OLD... ;AGAIN, THIS DOES
1819 ; NOT RECOGNIZE 3.5 MEDIA
1820 MOV READ_T_BPB_FAILURE
, 1 ;SET THE FLAG
1822 MOV BL, TARGET_DRIVE
;
1823 MOV IOCTL_TRACK
, 0 ;
1824 MOV IOCTL_SECTOR
, 8 ;
1825 MOV IOCTL_HEAD
, 0 ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8
1826 CALL READ_A_SECTOR
;
1828 JC CT_FORMAT
;ASSUME TARGET MEDIA NOT FORMATTED.
1830 MOV IOCTL_SECTOR
, 9 ;TRY TO READ SECTOR 9
1831 CALL READ_A_SECTOR
;
1833 JC CT_8_SECTOR
;TARGET IS 8 SECTOR MEDIA
1835 MOV IOCTL_SECTOR
, 15 ;
1836 CALL READ_A_SECTOR
;
1838 JC CT_9_SECTOR
;TARGET IS 9 SECTOR MEDIA
1840 ;CT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA
1841 CMP END_OF_TRACK
, 15 ;IS SOURCE ALSO 96 TPI?
1842 JNE CT_FATAL
;NO, FATAL ERROR
1847 CMP END_OF_TRACK
, 15 ;
1848 JE CT_FATAL
;IF SOURCE IS 96 TPI, THEN FATAL ERROR
1850 CMP END_OF_TRACK
, 9 ;
1851 JE CT_FORMAT
;IF SOURCE IS 9 SECTOR, THEN
1852 ; SHOULD FORMAT TARGET
1854 JMP CT_EXIT_OLD
;ELSE ASSUME SOURCE IS 8 SECTOR.
1857 CMP END_OF_TRACK
, 15 ;IS SOURCE 96 TPI ?
1858 JNE CT_EXIT_OLD
;NO. SOUCE IS 8 OR 9
1859 ; SECTORED 48 TPI DISKETTE
1862 MOV COPY_STATUS
, FATAL
;
1863 ;"Drive types or diskette types"
1864 PRINT MSGNUM_NOT_COMPATIBLE
;AC000;"not compatible"
1869 MOV CX, MS_deviceBPB_leng
;
1870 MOV SI, OFFSET MS_deviceBPB
;
1871 MOV DI, OFFSET MT_deviceBPB
;
1872 REP MOVSB ;set MT_deviceBPB to MS_deviceBPB
1874 MOV T_DRV_SET_FLAG
, 1 ;INDICATE THE TARGET DEFAULT
1875 ; DEVICE PARM HAS BEEN SET.
1877 mov bl, last_track
;patch for 3.2 diskcopy, 3/27/86 J.K.
1879 mov MT_numberOfCylinders
, bx ;make sure the # of cyl of the target
1880 MOV BL, TARGET_DRIVE
;
1881 MOV DX, OFFSET MT_IOCTL_DRV_PARM
;
1882 MOV MT_specialFunctions
, SET_SP_FUNC_DEF
;
1883 CALL SET_DRV_PARM_DEF
;
1889 ; = = = = = = = = = = = =
1890 HEADER
<CHK_MULTI_MEDIA
- CHECK
IF DRIVE IS MULTI
-MEDIA
> ;AN000;
1891 ;*****************************************************************************
1892 PUBLIC CHK_MULTI_MEDIA
;AN000;MAKE ENTRY IN LINK MAP
1893 CHK_MULTI_MEDIA PROC
NEAR ;
1894 ;IF THE SOURCE IS 96 TPI DISKETTE, AND TARGET IS 48 TPI
1895 ;DISKETTE, OR VICE VERSA, THEN SET THE CARRY BIT.
1896 ;THIS ROUTINE BE CALLED WHEN BPB INFORMATIONS OF TARGET HAS BEEN SUCCESSFULLY
1898 ;*** CURRENTLY, ONLY 96 TPI DRIVE IN PC_AT CAN HAVE MULTI_MEDIA.
1899 ;INPUT: AX - TARGET MEDIA CYLINDER NUMBER - 1
1900 ; LAST_TRACK - SOURCE MEDIA CYLINDER NUMBER - 1
1901 ;*****************************************************************************
1903 CMP LAST_TRACK
, 39 ;SOURCE IS 48 TPI MEDIA?
1906 CMP AL, 79 ;AND TARGET IS 96 TPI MEDIA?
1913 CMP LAST_TRACK
, 79 ;SOURCE IS 96 TPI MEDIA?
1916 CMP AL, 39 ;AND TARGET IS 48 TPI?
1925 CHK_MULTI_MEDIA ENDP
;
1926 ; = = = = = = = = = = = =
1927 HEADER
<SET_DRV_PARM_DEF
- SET DRIVE PARMS VIA IOCTL
> ;AN000;
1928 ;*****************************************************************************
1929 PUBLIC SET_DRV_PARM_DEF
;AN000;MAKE ENTRY IN LINK MAP
1930 SET_DRV_PARM_DEF PROC
NEAR ;
1931 ;SET THE DRV PARMAMETERS
1932 ;INPUT: BL - DRIVE NUMBER
1933 ; DX - POINTER TO THE DEFAULT PARAMETER TABLE
1934 ; specialfunc should be set before calling this routine
1935 ;*****************************************************************************
1936 MOV CL, SETDEVPARM
;=40H
1937 CALL GENERIC_IOCTL
;
1940 SET_DRV_PARM_DEF ENDP
;
1941 ; = = = = = = = = = = = =
1942 HEADER
<CHK_MEDIATYPE
- DETERMINE MEDIATYPE OF TARGET FOR
FORMAT> ;AN000;
1943 ;*****************************************************************************
1944 PUBLIC CHK_MEDIATYPE
;AN000;MAKE ENTRY IN LINK MAP
1945 CHK_MEDIATYPE PROC
NEAR ;
1946 ;SET THE mediaType OF IOCTL_DRV_PARM FOR TARGET DRIVE IN CASE OF FORMAT.
1947 ;IF TARGET IS A MULTI-MEDIA DEVICE, mediaType SHOULD BE SET CORRECTLY
1948 ;TO FORMAT THE TARGET MEDIA.
1949 ;IF EITHER OF LAST_TRACK OR END_OF_TRACK IS LESS THAN THAT OF TARGET
1950 ;DRIVE, THEN mediaType WILL BE SET TO 1. OTHERWISE, IT WILL BE 0 FOR
1952 ;*****************************************************************************
1954 MOV AL, T_DRV_TRACKS
;TARGET DEVICE MAXIUM TRACKS
1956 CMP LAST_TRACK
, AL ;COMPARE SOURCE MEDIA # OF TRACKS TO IT
1959 MOV AL, T_DRV_SECT_TRACK
;
1960 CMP END_OF_TRACK
, AL ;SOURCE # OF SECT/TRACK < TARGET DEVICE?
1964 MOV MT_mediaType
, 1 ;
1968 CHK_MEDIATYPE ENDP
;
1969 ; = = = = = = = = = = = =
1970 HEADER
<GENERIC_IOCTL
- COMMUNICATE WITH THE DEVICE DRIVER
> ;AN000;
1971 ;*****************************************************************************
1972 PUBLIC GENERIC_IOCTL
;AN000;MAKE ENTRY IN LINK MAP
1973 GENERIC_IOCTL PROC
NEAR ;
1974 ;INPUT: CL - MINOR CODE; 60 - GET DEVICE PARM, 40 - SET DEVICE PARM
1975 ; 61 - READ TRACK, 41 - WRITE TRACK,
1976 ; 42 - FORMAT AND VERIFY TRACK, 43 - SET MEDIA ID
1977 ; 62 - VERIFY TRACK, 63 - GET MEDIA ID
1978 ; BL - LOGICAL DRIVE LETTER
1979 ; DS:DX - POINTER TO PARAMETERS
1980 ;*****************************************************************************
1981 MOV IO_ERROR
, NO_ERROR
;reset io_error
1982 MOV CH, MAJOR_CODE
;MAJOR CODE, REMOVABLE = 08H
1983 DOSCALL IOCTL_FUNC
,GENERIC_IOCTL_CODE
;AC000;(440DH) CALL THE DEVICE DRIVER
1987 CALL EXTENDED_ERROR_HANDLER
;ERROR, SEE WHAT IT IS!
1992 GENERIC_IOCTL ENDP
;
1993 ; = = = = = = = = = = = =
1994 HEADER
<EXTENDED_ERROR_HANDLER
- RESPOND TO DOS ERRORS
> ;AN000;
1995 ;*****************************************************************************
1996 PUBLIC EXTENDED_ERROR_HANDLER
;AN000;MAKE ENTRY IN LINK MAP
1997 EXTENDED_ERROR_HANDLER PROC
NEAR ;
1998 ;INPUT: BL - LOGICAL DRIVE LETTER
1999 ;*****************************************************************************
2012 MOV AH, EXTENDED_ERROR
;59H
2016 POP BX ;RESTORE BL FOR DRIVE LETTER
2020 CMP AX, 21 ;DRIVE NOT READY? (TIME_OUT ERROR?)
2021 JE EEH_CHK_TIMEOUT
;
2023 CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED?
2026 JMP EEH_HARD_ERROR
;OTHERWISE, HARD_ERROR
2028 EEH_CHK_TIMEOUT: ;BECAUSE OF THE INACCURACY
2029 ; OF TIME OUT ERROR,
2030 ;IN READING AND WRITING OPERATION,
2031 ; CHECK OUT CAREFULLY WITH "FORMAT"
2032 CMP FORMAT_FLAG
, ON ;AFTER OR DURING FORMAT OPERATION,
2033 JE WARN_USER_1
; TIME OUT ERROR IS
2034 ; ASSUMED TO BE CORRECT.
2036 CMP TRY_FORMAT_FLAG
, ON ;HAPPENED AT "TRY_FORMAT" PROCEDURE?
2039 CMP TARGET_OP
, ON ;HAPPENED ON TARGET DRIVE?
2040 JNE WARN_USER_1
;IF NOT, THEN ASSUME TIME OUT ERROR
2042 MOV TRY_FORMAT_FLAG
, ON ;
2043 CALL TRY_FORMAT
;JUST TRY TO FORMAT THE TRACK.
2045 MOV TRY_FORMAT_FLAG
, OFF
;
2046 CMP TIME_OUT_FLAG
, ON ;REAL TIME OUT?
2047 JE WARN_USER_1
;YES, A SOFT ERROR.
2049 CMP IO_ERROR
, SOFT_ERROR
;IT HAPPENED AT TRY_FORMAT PROC AND
2050 ; PC_AT WHEN THE DRIVE DOOR OPENED ABRUPTLY.
2051 JE EEH_EXIT
;IT WAS WRITE PROTECTED ERROR.
2053 JMP EEH_HARD_ERROR
;NO, "ADDRESS MARK NOT OUT". A HARD ERROR.
2056 MOV TIME_OUT_FLAG
, ON ;SET TIME_OUT_FLAG AND EXIT THIS ROUTINE
2060 MOV DRIVE_LETTER
, 'A' ;
2061 DEC BL ;CHANGE LOGICAL TO PHYSICAL
2062 ADD DRIVE_LETTER
, BL ;
2063 PRINT MSGNUM_GET_READY
;AC000;"Drive not ready - %0"
2065 PRINT MSGNUM_CLOSE_DOOR
;AN004;"Make sure a diskette is inserted into
2066 ; the drive and the door is closed"
2070 PRINT MSGNUM_WRITE_PROTECT
;AC000;"Attempt to write to write-protected diskette"
2073 ;"Press any key when ready . . ."
2074 CALL PRESS_ANY_KEY
;AC000; THEN WAIT FOR ANY RESPONSE
2076 MOV IO_ERROR
, SOFT_ERROR
;INDICATE THE CALLER TO TRY AGAIN
2077 JMP SHORT EEH_EXIT
;
2080 MOV IO_ERROR
, HARD_ERROR
;
2081 MOV UKM_ERR
,OFF
;AN011;ASSUME NOT "UNKNOWN MEDIA" TYPE ERROR
2082 CMP AX,26 ;AN011;IS THE ERROR TYPE IS "UNKNOWN MEDIA"?
2083 ; $IF E ;AN011;IF "UNKNOWN MEDIA" TYPE ERROR
2085 MOV UKM_ERR
,ON ;AN011;SET FLAG TO INDICATE "UNKNOWN MEDIA"
2086 ; TO CAUSE FORMATTING OF TARGET DISKETTE
2101 ; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT (IN MAIN PROC)
2103 EXTENDED_ERROR_HANDLER ENDP
;
2104 ; = = = = = = = = = = = =
2105 HEADER
<TRY_FORMAT
- ATTEMPT TRACK
FORMAT, TRY FOR ERROR RECOVERY
> ;AN000;
2106 ;*****************************************************************************
2107 PUBLIC TRY_FORMAT
;AN000;MAKE ENTRY IN LINK MAP
2108 TRY_FORMAT PROC
NEAR ;
2109 ;*** TRY TO FORMAT A TRACK.
2110 ;*** CALLED BY "EXTENDED_ERROR_HANDLER" TO CHECK THE TIME OUT ERROR IS A REAL
2111 ;*** ONE OR CAUSED BY "ADDR MARK NOT FOUND" ERROR.(THIS IS HARDWARE ERROR THAT
2112 ;*** DOES NOT GIVE CORRECT ERROR CODE).
2113 ;*** THIS ROUTINE WILL CALL "GENERIC_IOCTL" WHICH IN TURN WILL CALL "EXTENDED_
2114 ;*** ERROR_HANDLER" WHERE THE ERROR WILL BE REEXAMINED.
2115 ;*****************************************************************************
2121 MOV CX, MS_deviceBPB_leng
;set length of BPB
2122 MOV SI, OFFSET MS_deviceBPB
;
2123 MOV DI, OFFSET MT_deviceBPB
;
2125 CALL CHK_MEDIATYPE
;set MT_mediaTYPE for FORMAT operation
2127 MOV MT_specialFunctions
, SET_SP_BF_FORM
;=00000101B
2128 MOV CL, SETDEVPARM
;=40h
2129 MOV DX, OFFSET MT_IOCTL_DRV_PARM
;
2131 MOV BL, TARGET_DRIVE
;
2132 CALL GENERIC_IOCTL
;
2135 MOV AL, SIDE
;SIDE TO FORMAT
2137 MOV AL, TRACK_TO_WRITE
;TRACK TO FORMAT
2141 MOV BL, TARGET_DRIVE
;
2142 MOV CL, FORMAT_FUNC
;=42h
2143 MOV DX, OFFSET IOCTL_FORMAT
;
2144 CALL GENERIC_IOCTL
;
2146 MOV AL, IO_ERROR
;SAVE IO_ERROR, IN CASE FOR PC_AT CASE.
2150 MOV BL, TARGET_DRIVE
;
2151 MOV T_DRV_SET_FLAG
, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET
2152 MOV DX, OFFSET MT_IOCTL_DRV_PARM
;
2153 MOV MT_specialFunctions
, SET_SP_FUNC_DEF
;
2154 CALL SET_DRV_PARM_DEF
;SET IT BACK FOR NORMAL
2155 ; OPERATION, EX. WRITING
2158 MOV IO_ERROR
, AL ;RESTORE IO_ERROR
2165 ; = = = = = = = = = = = =
2166 HEADER
<ERROR_MESSAGE
- SAY WHAT
AND WHERE FAILURE
> ;AN000;
2167 ;*****************************************************************************
2169 ERROR_MESSAGE PROC
NEAR ;DISPLAY ERROR MESSAGE *
2170 PUBLIC ERROR_MESSAGE
;AN000;MAKE ENTRY IN LINK MAP
2172 ; FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE) *
2173 ; AND WHERE IT FAILED (TRACK NO. AND SIDE). *
2175 ; INPUT: AH = IOCTL I/O COMMAND CODE (3=READ, 4=WRITE) *
2177 ;*****************************************************************************
2178 CMP AH,READ_FUNC
;ERROR DURING READ ?
2181 ; MOV BX,OFFSET READ_ERROR
2182 ; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING READ OP
2183 ; MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ
2185 ; MOV BX,OFFSET WRITE_ERROR
2186 ; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING WRITE OP
2187 ; MOV BL,TRACK_TO_WRITE ;SAVE BAD TRACK NUMBER FOR WRITE
2190 ; $IF E ;AN000;YES, READ ERROR
2192 MOV BL,TRACK_TO_READ
;SAVE BAD TRACK NUMBER FOR READ
2193 MOV DI,OFFSET MSGNUM_HARD_ERROR_READ
;AN000;
2194 ; $ELSE ;AN000;NO, NOT READ, MUST BE WRITE ERROR
2197 MOV BL,TRACK_TO_WRITE
;SAVE BAD TRACK NUMBER FOR WRITE
2198 MOV DI,OFFSET MSGNUM_HARD_ERROR_WRITE
;AN000;
2199 ; $ENDIF ;AN000;READ ERROR?
2202 MOV DRIVE_LETTER
,"A" ;
2203 dec dl ;change logical drive letter to physical one.
2204 ADD DRIVE_LETTER
,DL ;SHOW DRIVE LETTER
2206 ; MOV BYTE PTR MSG_HARD_ERROR_PTR+8,AL ;SIDE NUMBER
2207 ; MOV BYTE PTR MSG_HARD_ERROR_PTR+10,BL ;TRACK NUMBER WHERE THE ERROR
2209 MOV BYTE PTR ERROR_SIDE_NUMBER
,AL ;AC000;SIDE NUMBER
2210 MOV BYTE PTR ERROR_TRACK_NUMBER
,BL ;AC000;TRACK NUMBER WHERE THE ERROR
2211 ;CR,LF,"Unrecoverable read/write error on drive %1",CR,LF
2212 CALL SENDMSG
;"Side %2, track %3",CR,LF ;ACN000;
2215 ERROR_MESSAGE ENDP
;
2217 ; HEADER <PROMPT - READ RESPONSE FROM KEYBOARD>
2218 ;KB_INPUT_FUNC EQU 0C01H ;DOS KEYBOARD INPUT
2219 ;*****************************************************************************
2221 ;PROMPT PROC NEAR ;DISPLAY MESSAGE *
2222 ; AND GET A USER INPUT CHARACTER *
2225 ; INPUT: DX = MESSAGE POINTER *
2226 ; OUTPUT: BYTE USER_INPUT *
2228 ;*****************************************************************************
2230 ; MOV AX,KB_INPUT_FUNC ;KEYBOARD INPUT
2232 ; MOV USER_INPUT,AL ;SAVE USER'S RESPONSE
2236 ; HEADER <CALL_PRINTF - COMMON DRIVER TO PRINTF, DISPLAY MESSAGE>
2237 ;CALL_PRINTF PROC NEAR
2238 ; PUBLIC CALL_PRINTF
2239 ;INPUT - DX HAS OFFSET INTO DS OF MESSAGE PARM LIST
2246 ; = = = = = = = = = = = =
2248 HEADER
<SENDMSG
- PASS
IN REGS
DATA FROM MSG DESCRIPTOR TO DISP MSG
> ;AN000;
2249 SENDMSG PROC
NEAR ;AN000;
2250 PUBLIC SENDMSG
;AN000;
2251 ; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
2252 ; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
2253 ; IF CARRY CLEAR, ALL OK
2254 ; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
2255 ; = = = = = = = = = = = =
2257 PUSH BX ;AN000;SAVE CALLER'S REGS
2262 ; PASS PARMS TO MESSAGE HANDLER IN
2263 ; THE APPROPRIATE REGISTERS IT NEEDS.
2264 MOV BX,[DI].MSG_NUM
;AC006;MESSAGE NUMBER
2265 MOV SI,[DI].MSG_SUBLIST
;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
2266 MOV CX,[DI].MSG_COUNT
;AN000;NUMBER OF %PARMS, 0 IF NONE
2267 MOV DX,[DI].MSG_CLASS
;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
2268 MOV AX,SELECT_MPX
;AN006;REQUEST THE SELECT MULTIPLEXOR, IF PRESENT
2269 INT MULTIPLEXOR
;AN006;CALL THE MULTIPLEXOR FUNCTION
2271 CMP AL,SELECT_PRESENT
;AN006;CHECK MULTIPLEXOR RESPONSE CODE
2272 ; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
2274 MOV AX,[DI].MSG_NUM
;AN000;MESSAGE NUMBER
2275 MOV BX,[DI].MSG_HANDLE
;AN006;HANDLE TO DISPLAY TO
2276 CALL SYSDISPMSG
;AN000;DISPLAY THE MESSAGE
2278 ; $IF C ;AN000;IF THERE IS A PROBLEM
2280 ;AX=EXTENDED ERROR NUMBER ;AN000;
2281 LEA DI,MSGNUM_EXTERR
;AN000;GET REST OF ERROR DESCRIPTOR
2282 MOV BX,[DI].MSG_HANDLE
;AN000;HANDLE TO DISPLAY TO
2283 MOV SI,[DI].MSG_SUBLIST
;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
2284 MOV CX,[DI].MSG_COUNT
;AN000;NUMBER OF %PARMS, 0 IF NONE
2285 MOV DX,[DI].MSG_CLASS
;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
2286 CALL SYSDISPMSG
;AN000;TRY TO SAY WHAT HAPPENED
2288 STC ;AN000;REPORT PROBLEM
2289 ; $ENDIF ;AN000;PROBLEM WITH DISPLAY?
2291 ; $ELSE ;AN006;SINCE SELECT DID THE MESSAGE
2294 MOV SELECT_FLAG
,TRUE
;AN006;INDICATE SELECT IS DOING THE MESSAGES
2295 CLC ;AN006;GENERATE A "NO PROBLEM" RESPONSE
2296 ; $ENDIF ;AN006;DID SELECT HANDLE THE MESSAGE?
2299 POP SI ;AN000;RESTORE CALLER'S REGISTERS
2305 SENDMSG ENDP
;AN000;
2306 ; = = = = = = = = = = = =
2307 HEADER
<YESNO
- DETERMINE
IF A RESPONSE IS YES
OR NO
> ;AN000;
2308 YESNO PROC
NEAR ;AN000;
2309 PUBLIC YESNO
;AN000;MAKE ENTRY IN LINK MAP
2310 ;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED
2311 ; SELECT_FLAG - IF SELECT IS DOING MESSAGES, ALWAYS ASSUME "NO"
2312 ;OUTPUT: AX=0=NO; AX=1=YES ; AX=2=INVALID RESPONSE, NEITHER Y NOR N
2313 ; IF CARRY SET, PROBLEM WITH THE FUNCTION, CALLER SHOULD ASSUME "NO"
2314 ; = = = = = = = = = = = =
2316 CMP SELECT_FLAG
,TRUE
;AN006;IS SELECT DOING THE MESSAGES?
2317 ; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
2319 ;AL=SUBFUNCTION, AS:
2320 ; 20H=CAPITALIZE SINGLE CHAR
2321 ; 21H=CAPITALIZE STRING
2322 ; 22H=CAPITALIZE ASCIIZ STRING
2324 ; 80H BIT 0=USE NORMAL UPPER CASE TABLE
2325 ; 80H BIT 1=USE FILE UPPER CASE TABLE
2326 ;DL=CHAR TO CAP (FUNCTION 23H) ;AN000;
2327 MOV AX,(GET_EXT_CNTRY_INFO
SHL 8) + YESNO_CHECK
;AN000;(6523H) GET EXTENDED
2328 ; COUNTRY INFORMATION, (Y/N)
2329 INT 21H
;AN000;SEE IF Y OR N
2331 ; $ELSE ;AN006;SINCE SELECT IS NOT PRESET
2334 MOV AX,NO
;AN006;ASSUME RESPONSE WAS 'NO'
2337 RET ;AN000;RETURN TO CALLER
2339 ; = = = = = = = = = = = =
2340 ;(deleted ;AN013;) HEADER <READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE> ;AN000;
2341 ;(deleted ;AN013;) READ_VOLSER PROC NEAR ; ;AN000;
2342 ;(deleted ;AN013;) PUBLIC READ_VOLSER ; ;AN000;
2343 ;(deleted ;AN013;) ;IF THE SOURCE DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN MAKE A NEW ONE
2344 ;(deleted ;AN013;) ; AND SEND IT TO THE TARGET DISKETTE. FOR OLD STYLE DISKETTES THAT DID NOT
2345 ;(deleted ;AN013;) ; HAVE ANY VOL SERIAL NUMBER, MAKE NO CHANGE AFTER THE TRADITIONAL FULL COPY.
2346 ;(deleted ;AN013;) ;INPUT: SOURCE AND TARGET DRIVE ID
2347 ;(deleted ;AN013;) ; THE TARGET DISKETTE IS A COMPLETE COPY OF THE SOURCE.
2348 ;(deleted ;AN013;) ;REFERENCED: A_MEDIA_ID_INFO STRUC (DEFINED IN DISKCOPY.EQU)
2349 ;(deleted ;AN013;) ; = = = = = = = = = = = = = = = = = =
2350 ;(deleted ;AN013;) ; ISSUE GET MEDIA ID FROM SOURCE
2351 ;(deleted ;AN013;) MOV BH,ZERO ;BH=0, RES ;AN000;
2352 ;(deleted ;AN013;) MOV BL,SOURCE_DRIVE ;BL=DRIVE NUM (1=A:, 2=B:, ETC);AN000;
2353 ;(deleted ;AN013;) MOV DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC);AN000;
2354 ;(deleted ;AN013;) DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID ;AC009;
2355 ;(deleted ;AN013;) ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
2357 ;(deleted ;AN013;) $IF NC ;IF THERE IS NO PROBLEM ;AN000;
2358 ;(deleted ;AN013;) ; GET CURRENT DATE
2359 ;(deleted ;AN013;) DOSCALL GET_DATE ;READ SYSTEM DATE ;AN000;
2360 ;(deleted ;AN013;) ;OUTPUT: DL = DAY (1-31)
2361 ;(deleted ;AN013;) ; AL = DAY OF WEEK (0=SUN,6=SAT)
2362 ;(deleted ;AN013;) ; CX = YEAR (1980-2099)
2363 ;(deleted ;AN013;) ; DH = MONTH (1-12)
2364 ;(deleted ;AN013;) PUSH CX ;SAVE THESE FOR ;AN000;
2365 ;(deleted ;AN013;) PUSH DX ; INPUT INTO HASH ALGORITHM ;AN000;
2366 ;(deleted ;AN013;) ; GET CURRENT TIME
2367 ;(deleted ;AN013;) DOSCALL GET_TIME ;READ SYSTEM TIME CLOCK ;AN000;
2368 ;(deleted ;AN013;) ;OUTPUT: CH = HOUR (0-23)
2369 ;(deleted ;AN013;) ; CL = MINUTES (0-59)
2370 ;(deleted ;AN013;) ; DH = SECONDS (0-59)
2371 ;(deleted ;AN013;) ; DL = HUNDREDTHS (0-99)
2373 ;(deleted ;AN013;) ; HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
2374 ;(deleted ;AN013;) ; MI_SERIAL+0 = DX FROM DATE + DX FROM TIME
2375 ;(deleted ;AN013;) ; MI_SERIAL+2 = CX FROM DATE + CX FROM TIME
2377 ;(deleted ;AN013;) POP AX ;GET THE DX FROM DATE ;AN000;
2378 ;(deleted ;AN013;) ADD AX,DX ;ADD IN THE DX FROM TIME ;AN000;
2379 ;(deleted ;AN013;) MOV WORD PTR MEDIA_ID_BUF.MI_SERIAL,AX ;SAVE FIRST RESULT OF HASH;AN000;
2381 ;(deleted ;AN013;) POP AX ;GET THE CX FROM DATE ;AN000;
2382 ;(deleted ;AN013;) ADD AX,CX ;ADD IN THE CX FROM TIME ;AN000;
2383 ;(deleted ;AN013;) MOV WORD PTR MEDIA_ID_BUF.MI_SERIAL+WORD,AX ;SAVE SECOND RESULT OF HASH;AN000;
2385 ;(deleted ;AN013;) MOV VOLSER_FLAG,TRUE ;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN;AN000;
2386 ;(deleted ;AN013;) $ENDIF ; ;AN000;
2387 ;(deleted ;AN013;) RET ;RETURN TO CALLER ;AN000;
2388 ;(deleted ;AN013;) READ_VOLSER ENDP ; ;AN000;
2389 ; = = = = = = = = = = = = = = = = = = =
2390 HEADER
<WRITE_VOLSER
- PUT NEW VOL SER NUMBER TO TARGET
> ;AN000;
2391 WRITE_VOLSER PROC
NEAR ;AN000;
2392 PUBLIC WRITE_VOLSER
;AN000;MAKE ENTRY IN LINK MAP
2393 CMP VOLSER_FLAG
,TRUE
;AN000;IF NEW NUMBER READY TO BE WRITTEN
2394 ; $IF E ;AN000;THEN WRITE IT
2398 ;THERE IS NO NEED TO DO A SET MEDIA ID TO WRITE OUT THE MODIFIED SERIAL NUMBER
2399 ;BECAUSE THAT NUMBER WAS CHANGED IN THE IMAGE OF THE BOOT RECORD WHEN THE
2400 ;ORIGINAL BOOT RECORD WAS READ IN, SO WHEN THAT TRACK IMAGE WAS WRITTEN,
2401 ;IT CONTAINED THE NEW SERIAL NUMBER ALREADY.
2403 ;(deleted ;AN013;) ; ISSUE SET MEDIA ID TO TARGET
2404 ;(deleted ;AN013;) MOV BH,ZERO ;BH=0, RES ;AN000;
2405 ;(deleted ;AN013;) MOV BL,TARGET_DRIVE ;BL=DRIVE NUM ;AN000;
2406 ;(deleted ;AN013;) MOV DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see STRUC above);AN000;
2407 ;(deleted ;AN013;) DOSCALL GSET_MEDIA_ID,SET_ID ;(6901H) SET MEDIA ID ;AC009;
2409 ; NOTE: IN THE FOLLOWING TWO SUBLISTS, WE ARE GOING TO DISPLAY, IN HEX,
2410 ; A CONSECUTIVE SET OF 4 BYTES, THE VOLUME SERIAL NUMBER. THE ORDER OF
2411 ; THESE TWO WORDS OF HEX IS, LEAST SIGNIFICANT WORD FIRST, THEN THE
2412 ; MOST SIGNIFICANT WORD. WHEN DISPLAYED, THE MOST SIGNIFICANT IS TO BE
2413 ; DISPLAYED FIRST, SO THE VALUE AT SERIAL+2 GOES TO THE 26A SUBLIST,
2414 ; AND THE LEAST SIGNIFICANT VALUE AT SERIAL+0 GOES TO THE SECOND POSITION,
2415 ; REPRESENTED BY THE 26B SUBLIST.
2417 LEA AX,SERIAL
;AC013;GET POINTER TO DATA TO BE PRINTED
2418 MOV SUBLIST_26B
.SUB_VALUE
,AX ;AN001; INTO THE SUBLIST
2420 LEA AX,SERIAL
+WORD ;AC013;GET POINTER TO DATA TO BE PRINTED
2421 MOV SUBLIST_26A
.SUB_VALUE
,AX ;AN001; INTO THE SUBLIST
2423 PRINT MSGNUM_CR_LF
;AN000;SKIP A SPACE
2425 ;"Volume Serial Number is %1-%2"
2426 PRINT MSGNUM_SERNO
;AN001;DISPLAY THE NEW SERIAL NUMBER
2430 RET ;AN000;RETURN TO CALLER
2431 WRITE_VOLSER ENDP
;AN000;
2432 ; = = = = = = = = = = = = = = = = = = =
2433 HEADER
<PRESS_ANY_KEY
- PUTS A BLANK LINE BEFORE PROMPT
> ;AN000;
2434 PRESS_ANY_KEY PROC
NEAR ;
2435 ;THE CANNED MESSAGE "PRESS ANY KEY..." DOES NOT START WITH CR,LF.
2436 ;THIS PUTS OUT THE CR LF TO CAUSE SEPARATION OF THIS PROMP FROM
2437 ;PRECEEDING MESSAGES.
2438 ; = = = = = = = = = = = =
2439 PRINT MSGNUM_CR_LF
;AN000;SKIP A SPACE
2441 PRINT MSGNUM_STRIKE
;AN000;"Press any key when ready..."
2443 RET ;AN000;RETURN TO CALLER
2444 PRESS_ANY_KEY ENDP
;AN000;
2445 ; = = = = = = = = = = = =
2446 PUBLIC DISKCOPY_END
;
2447 DISKCOPY_END
LABEL NEAR ;
2449 PATHLABL DISKCOPY
;AN015;