1 PAGE
90,132 ;\ f\eA\b\e2
2 TITLE DISKCOMP
.SAL - COPY COMPLETE DISKETTE
3 ;****************** START OF SPECIFICATIONS *****************************
4 ; MODULE NAME: DISKCOMP
6 ; DESCRIPTIVE NAME: Diskette to diskette complete compare Utility
8 ;FUNCTION: DISKCOMP is to compare the contents of the diskette in the
9 ; specified first drive to the diskette in the second
10 ; drive. If the first drive has a vol serial number, that
11 ; field in both diskettes is ignored in the comparison
12 ; of that one sector, because DISKCOPY will create a unique
13 ; volume serial number when it duplicates a diskette.
15 ; Multiple compares may be performed with one load of DISKCOMP.
16 ; A prompt, "Compare another (Y/N)?" permits additional
17 ; executions, all with the same drive specifications.
19 ; ENTRY POINT: "DISKCOMP" at ORG 100h, jumps to "BEGIN".
21 ; INPUT: (DOS command line parameters)
23 ; [d:][path] DISKCOMP [d: [d:]] [/1] [/8]
26 ; [d:][path] - Path where the DISKCOMP command resides.
28 ; [d:] - To specify the First drive
30 ; [d:] - To specify the Second drive
32 ; [/1] - To compare only the first side of the diskette,
33 ; regardless of the diskette or drive type.
35 ; [/8] - To compare only the first 8 sectors per track,
36 ; even if the first diskette contains 9/15 sectors
39 ; EXIT-NORMAL: Errorlevel = 0
40 ; Function completed successfully.
42 ; EXIT-ERROR: Errorlevel = 1
43 ; Abnormal termination due to error, wrong DOS,
44 ; invalid parameters, unrecoverable I/O errors on
47 ; Termination requested by CTRL-BREAK.
49 ; EFFECTS: The entire diskette is compared, including the unused
50 ; sectors. There is no awareness of the separate files
51 ; involved. A unique volume serial number is ignored
52 ; for the comparison of the first sector.
55 ; PATHMAC.INC - PATHGEN MACRO
56 ; INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
57 ; INCLUDE DISKCOMP.EQU ;EQUATES
59 ; INTERNAL REFERENCES:
61 ; BEGIN - entry point from DOS
62 ; SET_LOGICAL_DRIVE - set log. drive letter as owner of drive
63 ; COMP - compare the diskette image
64 ; TEST_REPEAT - see if user wants to compare another
65 ; READ_SOURCE - read from first drive as much as possible
66 ; CHECK_SOURCE - determine first diskette type
67 ; READ_A_SECTOR - use IOCTL read to get a sector
68 ; CALC_TRACK_SIZE - find mem size to hold one track
69 ; CHECK_MEMORY_SIZE - be sure enuf memory to compare 1 track
70 ; COMP_TARGET - compare memory data with secon diskette
71 ; CHECK_TARGET - compare second disk boot record
72 ; SET_DRV_PARM - request IOCTL to set device parm
73 ; COMP_TRACK - read and compare specified track
74 ; SWAP_DRIVE - setup for diskette swapping
75 ; READ_TRACK - read a track to memory
76 ; READ_OP - IOCTL to read a track
77 ; SET_FOR_THE_OLD - use pre 2.0 BPB
78 ; SET_TRACKLAYOUT - determine sectors per track
79 ; GENERIC_IOCTL - perform specified IOCTL function
80 ; EXTENDED_ERROR_HANDLER - determine and service extended errors
81 ; SET_DRV_PARM_DEF - set drive parms via IOCTL
83 ; VOLSER - during compare of first sector, avoid vol ser #
84 ; SENDMSG - passes parms to regs and invokes the system message routine.
87 ; PSP - Contains the DOS command line parameters.
88 ; WORKAREA - Temporary storage
90 ; EXTERNAL REFERENCES:
92 ; SYSDISPMSG - Uses the MSG parm lists to construct the messages
94 ; SYSLOADMSG - Loads messages, makes them accessable.
95 ; SYSPARSE - Processes the DOS Command line, finds parms.
98 ; DCOMPSM.SAL - Defines the control blocks that describe the messages
99 ; DCOMPPAR.SAL - Defines the control blocks that describe the
100 ; DOS Command line parameters.
103 ; This module should be processed with the SALUT preprocessor
104 ; with the re-alignment not requested, as:
108 ; To assemble these modules, the alphabetical or sequential
109 ; ordering of segments may be used.
111 ; Sample LINK command:
115 ; Where the DISKCOMP.ARF is defined as:
123 ; These modules must be linked in this order. The load module is
124 ; a COM file, to be converted to COM with EXE2BIN.
127 ; A000 Version 4.00: add PARSER, System Message Handler,
128 ; Ignore vol serial number differences.
130 ; A002 Avoid duplicate switches
131 ; A003 PTM 540 Show parm in error
132 ; A004 PTM 752 Add close door after drive not ready
133 ; A005 PTM 756 Add help msg after parm error message
134 ; A006 PTM1100 Clear keyboard buffer before input response
135 ; A007 PTM1464 Delete unused msgs: 22,23,24
136 ; A008 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID
137 ; A009 PTM1605 PUT A BLANK LINE OUT BEFORE PRESS ANY KEY MSG
138 ; A010 PTM1821 move INCLUDE COPYRIGH.INC to MSG_SERVICE macro
139 ; A011 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO
140 ; REMOVE USE OF GET/SET MEDIA ID
141 ; A012 PTM3262 Specify BASESW EQU 1 before PARSE.ASM
142 ; A013 PTM3512 PATHGEN
144 ; COPYRIGHT: The following notice is found in the OBJ code generated from
145 ; the "DCOMPSM.SAL" module:
147 ; "Version 4.00 (C) Copyright 1988 Microsoft"
148 ; "Licensed Material - Property of Microsoft "
150 ;PROGRAM AUTHOR: Original written by: Jin K.
151 ; 4.00 modifications by: Edwin M. K.
152 ;****************** END OF SPECIFICATIONS *****************************
154 %
OUT COMPONENT
=DISKCOMP
, MODULE
=DISKCOMP
.SAL
156 ;*****************************************************************************
160 ; UPDATE HISTORY: 8-21, 8-22, 8-30, 9-4, 9-20, 9-21, 12-19 *
161 ; 2-15-84, 2-17, 4-29, 6-20,7-24,3-27-85 *
163 ;*****************************************************************************
165 INCLUDE PATHMAC
.INC ;AN013;
166 INCLUDE DCMPMACR
.INC ;(FORMERLY CALLED MACRO.DEF)
167 INCLUDE DISKCOMP
.EQU
;EQUATES
169 ; $salut (4,16,22,36) ; ;AN000;
170 ;THIS MESSAGE DESCRIPTOR CONTROL BLOCK IS GENERATED, ONE PER MESSAGE,
171 ;TO DEFINE THE SEVERAL PARAMETERS THAT ARE EXPECTED TO BE PASSED IN
172 ;CERTAIN REGISTERS WHEN THE SYSDISPMSG FUNCTION IS TO BE INVOKED.
174 MSG_DESC
STRUC ; ;AN000;
175 MSG_NUM
DW ?
;MESSAGE NUMBER (TO AX) ;AN000;
176 MSG_HANDLE
DW ?
;HANDLE OF OUTPUT DEVICE (TO BX) ;AN000;
177 MSG_SUBLIST
DW ?
;POINTER TO SUBLIST (TO SI) ;AN000;
178 MSG_COUNT
DW ?
;SUBSTITUTION COUNT (TO CX) ;AN000;
179 MSG_CLASS
DW ?
;MESSAGE CLASS (IN HIGH BYTE, TO DH) ;AN000;
180 ;LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL) ;AN000;
181 MSG_DESC ENDS
; ;AN000;
184 CBYTE_SECT
DW 0 ; 200H ;BYTES / SECTOR
185 CSECT_CLUSTER
DB 0 ; 2h ;SECTORS / CLUSTER
186 CRESEV_SECT
DW 0 ; 1h ;RESERVED SECTORS
187 CFAT
DB 0 ; 2h ;# OF FATS
188 CROOTENTRY
DW 0 ; 70h ;# OF ROOT ENTRIES
189 CTOTSECT
DW 0 ; 02D0h ;TOTAL # OF SECTORS INCLUDING
190 ; BOOT SECT, DIRECTORIES
191 MEDIA_DESCRIP
DB 0 ;0FDh ;MEDIA DISCRIPTOR
192 CSECT_FAT
DW 0 ; 2h ;SECTORS / FAT
200 CSEG
SEGMENT PARA
PUBLIC 'CODE' ; ;AN000;
201 ASSUME
CS:CSEG
, DS:CSEG
, ES:CSEG
, SS:CSEG
203 ;*****************************************************************************
205 ; EXTERNAL VARIABLES *
207 ;*****************************************************************************
211 ;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE
212 ;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE
213 ;EXTRN COMPAT_ERROR :NEAR
214 ;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE
217 ;EXTRN MSG_FIRST_BAD_PTR :BYTE
220 EXTRN SYSLOADMSG
:NEAR ;SYSTEM MSG HANDLER INTIALIZATION ;AN000;
221 EXTRN SYSDISPMSG
:NEAR ;SYSTEM MSG HANDLER DISPLAY ;AN000;
223 EXTRN INIT
:NEAR ;INITIALIZATION ROUTINE
225 EXTRN MSG_TRACKS
:WORD ; ;AN000;
226 EXTRN MSG_SECTRK
:WORD ; ;AN000;
227 EXTRN MSG_SIDES
:WORD ; ;AN000;
229 EXTRN ASCII_DRV1_ID
:BYTE ; ;AN000;
230 EXTRN ASCII_DRV2_ID
:BYTE ; ;AN000;
232 EXTRN SUBLIST_78
:WORD ; ;AN000;
233 EXTRN SUBLIST_17B
:WORD ; ;AN000;
235 EXTRN MSGNUM_EXTERR
:WORD ;EXTENDED ERROR MSG DESCRIPTOR ;AN000;
236 EXTRN MSGNUM_LOAD_FIRST
:BYTE ; ;AC000;
237 EXTRN MSGNUM_LOAD_SECOND
:BYTE ; ;AC000;
238 EXTRN MSGNUM_NOT_COMPATIBLE
:BYTE ; ;AC000;
239 EXTRN MSGNUM_COMP_ANOTHER
:BYTE ; ;AC000;
240 EXTRN MSGNUM_GET_READY
:BYTE ; ;AC000;
241 EXTRN MSGNUM_CLOSE_DOOR
:BYTE ; ;AN004;
242 EXTRN MSGNUM_FATAL_ERROR
:BYTE ; ;AC000;
243 EXTRN MSGNUM_UNSUF_MEMORY
:BYTE ; ;AC000;
244 EXTRN MSGNUM_BAD_FIRST
:BYTE ; ;AC000;
245 EXTRN MSGNUM_BAD_SECOND
:BYTE ; ;AC000;
246 EXTRN MSGNUM_HARD_ERROR_READ
:BYTE ; ;AC000;
247 EXTRN MSGNUM_HARD_ERROR_COMP
:BYTE ; ;AC000;
248 EXTRN MSGNUM_COMPARING
:BYTE ; ;AC000;
249 EXTRN MSGNUM_STRIKE
:BYTE ; ;AC000;
250 EXTRN MSGNUM_WRITE_PROTECT
:BYTE ; ;AC000;
251 EXTRN MSGNUM_COMP_OK
:BYTE ; ;AC000;
252 EXTRN MSGNUM_NEWLINE
:BYTE ;
253 EXTRN DRIVE_LETTER
:BYTE ;
254 EXTRN SKIP_MSG
:BYTE ;NULL REPLACEMENT FOR DRIVE LETTER ;AN000;
256 ;*****************************************************************************
260 ;*****************************************************************************
262 PUBLIC DISKCOMP_BEGIN
264 PUBLIC RECOMMENDED_BYTES_SECTOR
270 PUBLIC S_DRV_SECT_TRACK
273 PUBLIC T_DRV_SECT_TRACK
290 PUBLIC ORG_SOURCE_DRIVE
291 PUBLIC ORG_TARGET_DRIVE
297 PUBLIC DS_IOCTL_DRV_PARM
;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
298 PUBLIC DT_IOCTL_DRV_PARM
;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
299 PUBLIC DS_specialFunctions
;AND THEIR CONTENTS
300 PUBLIC DT_specialFunctions
303 PUBLIC DS_deviceAttributes
304 PUBLIC DT_deviceAttributes
305 PUBLIC DS_numberOfCylinders
306 PUBLIC DT_numberOfCylinders
312 PUBLIC MS_IOCTL_DRV_PARM
;DRIVE PARM FROM SOURCE MEDIUM
313 PUBLIC MT_IOCTL_DRV_PARM
;DRIVE PARM FROM TARGET MEDIUM
315 ;*****************************************************************************
316 ORG 100H
;PROGRAM ENTRY POINT ;
320 ;*****************************************************************************
321 EVEN
;PUT STACK ONTO A WORD ALIGNMENT BOUNDARY ;AN000;
324 DB 64 DUP ('STACK ') ;512 BYTES
326 MY_STACK_PTR
LABEL WORD
328 ;*****************************************************************************
330 ; INTERNAL VARIABLES *
332 ;*****************************************************************************
334 ; $salut (4,22,26,36) ; ;AN000;
335 ;DEFAULT BPB FOR OLD MEDIA
336 ;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK)
337 BPB48_SINGLE
DW 512 ;BYTES/SECTOR
339 DW 1 ;# OF RESERVED SECTORS
341 DW 40h
;# OF ROOT ENTRY
342 DW 168h
;TOTAL # OF SECTORS IN THE MEDIA
346 ;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK)
347 BPB48_DOUBLE
DW 512 ;BYTES/SECTOR
349 DW 1 ;# OF RESERVED SECTORS
351 DW 70h
;# OF ROOT ENTRY
352 DW 2D0h
;TOTAL # OF SECTORS IN THE MEDIA
356 ;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK)
357 BPB96
DW 512 ;BYTES/SECTOR
359 DW 1 ;# OF RESERVED SECTORS
361 DW 0E0h ;# OF ROOT ENTRY
362 DW 960h
;TOTAL # OF SECTORS IN THE MEDIA
365 BPB96_LENG EQU
$-BPB96
;THIS LENGTH WILL BE USED FOR BPB48 ALSO.
369 ; INPUT PARMETERS FROM INIT SUBROUTINE:
371 S_OWNER_SAVED
DB 0 ;DRIVE LETTER THAT OWNED
372 ; SOURCE DRIVE OWNERSHIP
374 RECOMMENDED_BYTES_SECTOR
DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA
376 ;IT IS ASSUMED THE NEXT TWO BYTES ARE CONSECUTIVE,
377 ;AND DEFINED IN SOURCE/TARGET ORDER, BY DCOMPPAR.SAL.
378 SOURCE_DRIVE
DB 0 ;1=A:, 2=B:,...
381 ORG_SOURCE_DRIVE
DB ?
;ORIGINAL SOURCE DRIVE
382 ORG_TARGET_DRIVE
DB ?
;ORIGINAL TARGET DRIVE
387 BUFFER_BEGIN
DW 1000H
;BEGINNING OF BUFFER ADDR [IN SEGMENT]
388 BUFFER_END
DW 3FF0H
;END OF BUFFER ADDR [IN SEGMENT]
390 SECT_TRACK_LAYOUT
DW 0
392 S_DRV_SECT_TRACK
DB ?
;SECT/TRACK, device informations.
393 S_DRV_HEADS
DB ?
;# OF HEADS
394 S_DRV_TRACKS
DB ?
;# OF TRACKS
395 T_DRV_SECT_TRACK
DB ?
400 FIRST_TIME
DB 0 ;SWITCH TO ACTIVATE VOLSER CHECK ;AN000;
401 EXITFL
DB EXOK
;ERRORLEVEL VALUE ;AN000;
402 PUBLIC EXITFL
; ;AN000;
403 EXCBR EQU
2 ;CONTROL-BREAK REQUESTED TERMINATION ;AN000;
404 EXVER EQU
1 ;BAD DOS VERSION ERRORLEVEL CODE ;AN000;
405 EXPAR EQU
1 ;ERROR IN INPUT PARMS IN COMMAND LINE ;AN000;
406 EXOK EQU
0 ;NORMAL ERRORLEVEL RET CODE ;AN000;
407 PUBLIC EXPAR
; ;AN000;
409 IOCTL_SECTOR
DW 1 ;used for READ_A_SECTOR routine.
410 IOCTL_TRACK
DW 0 ;IN THE TRACK
411 IOCTL_HEAD
DW 0 ;HEAD 0
412 SAV_CSECT
DW 0 ;TEMPORARY SAVING PLACE
414 BOOT_SECT_TRACK
DW 0 ;TEMP SAVING PLACE OF SECTOR/TRACK
415 BOOT_TOT_TRACK
DW 0 ;FOUND FROM THE BOOT SECTOR. max # of tracks
416 BOOT_NUM_HEAD
DW 0 ;NUMBER OF HEADS
417 BOOT_BYTE_SECTOR
DW 0 ;BYTES / SECTOR
419 READ_S_BPB_FAILURE
DB 0 ;GET MEDIA BPB. SUCCESS=0, FAILURE=1
420 READ_T_BPB_FAILURE
DB 0
422 ;*** Informations gotten from CHECK_SOURCE.
423 ;*** These will be used as a basis for the comp process.
424 LAST_TRACK
DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79)
425 END_OF_TRACK
DB 15 ;END OF TRACK
426 bSECTOR_SIZE
DW 512 ;BYTES/SECTOR in bytes
427 NO_OF_SIDES
DB ?
;0=SINGLE SIDED, 1=DOUBLE SIDED
431 TRACK_SIZE
DW 0 ;BYTES/CYLINDER [IN SEGMENTS]
432 SECTOR_SIZE
DB 0 ;BYTES/SECTOR [IN SEGMENTS]
433 BYTES_IN_TRACK
DW ?
;BYTES/ONE SIDE TRACK (USED IN COMP_TRACK)
439 USER_INPUT
DB ?
;DISKCOMP AGAIN?
440 SEC_BUFFER
DW ?
;SECONDARY BUFFER SEG ADDR
441 COMPARE_PTR
DW ?
;COMPARE POINTER
442 IO_ERROR
DB 0 ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE
444 S_DRV_SET_FLAG
DB 0 ;SOURCE DEVICE PARM HAS BEEN SET?
447 ;---------------------------------------
448 ;DEVICE PARAMETER TABLE
449 ;the returned info. still has the following format.
451 DS_IOCTL_DRV_PARM
LABEL BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
452 DS_specialFunctions db ?
453 DS_deviceType db ?
;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
454 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
455 DS_deviceAttributes dw ?
;0001h - NOT REMOVABLE, 0002h - CHANGE
457 DS_numberOfCylinders dw ?
459 DS_BPB_PTR
LABEL BYTE
460 DS_deviceBPB my_bpb
<>
461 DS_trackLayout
LABEL WORD ; ;AC000;
462 my_trackLayout
; ;AC000;
463 ;---------------------------------------
465 DT_IOCTL_DRV_PARM
LABEL BYTE
466 DT_specialFunctions db ?
467 DT_deviceType db ?
;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
468 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
469 DT_deviceAttributes dw ?
;0001h - NOT REMOVABLE, 0002h - CHANGE
471 DT_numberOfCylinders dw ?
473 DT_BPB_PTR
LABEL BYTE
474 DT_deviceBPB my_bpb
<>
475 DT_trackLayout
LABEL WORD ; ;AC000;
476 my_trackLayout
; ;AC000;
478 ;---------------------------------------
480 MS_IOCTL_DRV_PARM
LABEL BYTE ;DRIVE PARM FROM SOURCE MEDIUM
481 MS_specialFunctions db ?
482 MS_deviceType db ?
;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
483 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
484 MS_deviceAttributes dw ?
;0001h - NOT REMOVABLE, 0002h - CHANGE
486 MS_numberOfCylinders dw ?
488 MS_BPB_PTR
LABEL BYTE
489 MS_deviceBPB my_bpb
<>
490 MS_deviceBPB_leng equ
$-MS_deviceBPB
491 MS_trackLayout
LABEL WORD ; ;AC000;
492 my_trackLayout
; ;AC000;
493 ;---------------------------------------
494 MT_IOCTL_DRV_PARM
LABEL BYTE ;DRIVE PARM FROM TARGET MEDIUM
495 MT_specialFunctions db ?
496 MT_deviceType db ?
;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
497 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
498 MT_deviceAttributes dw ?
;0001h - NOT REMOVABLE, 0002h - CHANGE
500 MT_numberOfCylinders dw ?
502 MT_BPB_PTR
LABEL BYTE
503 MT_deviceBPB my_bpb
<>
504 MT_trackLayout
LABEL WORD ; ;AC000;
505 my_trackLayout
; ;AC000;
507 ;IOCTL read/write a track.
509 specialFunctions db 0
517 ;(deleted ;AN011;) MEDIA_ID_BUFFER A_MEDIA_ID_INFO <> ;BUFFER FOR GET/SET MEDIA ID ;AN000;
518 PATHLABL DISKCOMP
;AN013;
519 HEADER
<BEGIN
- VERSION CHECK
, SYSMSG INIT
, EXIT TO DOS
> ; ;AN000;
520 PUBLIC DISKCOMP_BEGIN
; ;AN000;
521 DISKCOMP_BEGIN
LABEL BYTE
522 ;*****************************************************************************
524 ; D I S K C O M P M A I N P R O G R A M *
526 ;*****************************************************************************
528 ; $salut (4,4,10,36) ; ;AN000;
530 PUBLIC BEGIN
; ;AN000;
531 ;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE
533 MOV SP, OFFSET MY_STACK_PTR
;MOVE SP TO MY STACK AREA
534 CALL SYSLOADMSG
;INIT SYSMSG HANDLER ;AN000;
536 ; $IF C ;IF THERE WAS A PROBLEM ;AN000;
538 CALL SYSDISPMSG
;LET HIM SAY WHY HE HAD A PROBLEM ;AN000;
540 MOV EXITFL
,EXVER
;TELL ERRORLEVEL BAD DOS VERSION ;AN000;
541 ; $ELSE ;SINCE SYSDISPMSG IS HAPPY ;AN000;
544 CALL INIT
;RUN INITIALIZATION ROUTINE
546 CMP DX,FINE
;CHECK FOR ERROR DURING INIT
547 ; $IF E ;IF NO ERROR THEN PROCEED TO COMP
551 CALL COMP
;PERFORM DISKCOMP
553 CALL TEST_REPEAT
;COMP ANOTHER ?
557 ;NORMAL RETURN CODE ALREADY IN "EXITFL"
558 ; $ELSE ;ELSE IF ERROR DETECTED IN INIT
561 MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000;
562 ;DI HAS OFFSET OF MESSAGE DESCRIPTOR
563 CALL SENDMSG
;DISPLAY THE ERROR MESSAGE ;AC000;
565 MOV EXITFL
,EXVER
;ERROR RETURN CODE ;AC000;
568 JMP SHORT EXIT_TO_DOS
570 MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK
571 MOV EXITFL
,EXCBR
; FOR CONTROL-BREAK EXIT ;AC000;
576 MOV BL, S_OWNER_SAVED
;RESTORE ORIGINAL SOURCE,
577 ; TARGET DRIVE OWNER.
578 CALL SET_LOGICAL_DRIVE
580 MOV BL, T_OWNER_SAVED
581 CALL SET_LOGICAL_DRIVE
583 CMP S_DRV_SET_FLAG
, 0
586 MOV BL, S_OWNER_SAVED
587 MOV DS_specialFunctions
, SET_SP_FUNC_DOS
;=0
588 MOV DX, OFFSET DS_IOCTL_DRV_PARM
589 CALL SET_DRV_PARM_DEF
;RESTORE SOURCE DRIVE PARM
594 CMP T_DRV_SET_FLAG
, 0
597 MOV BL, T_OWNER_SAVED
598 MOV DT_specialFunctions
, SET_SP_FUNC_DOS
;=0
599 MOV DX, OFFSET DT_IOCTL_DRV_PARM
600 CALL SET_DRV_PARM_DEF
;RESTORE TARGET DRIVE PARM
605 MOV AL,EXITFL
;PASS ERRORLEVEL RET CODE ;AN000;
606 ; $ENDIF ;OK WITH SYSDISPMSG? ;AN000;
608 MOV AL,EXITFL
;PASS BACK ERRORLEVEL RET CODE ;AN000;
609 DOSCALL RET_CD_EXIT
;RETURN TO DOS WITH RET CODE ;AN000;
611 INT 20H
;IF ABOVE NOT WORK, ;AN000;
613 ; = = = = = = = = = = = = = = = = =
614 HEADER
<MORE_INIT
- FINISH INIT
, DO COMP
> ; ;AN000;
615 MORE_INIT PROC
NEAR ; ;AN000;
616 RET ;RETURN TO CALLER ;AN000;
617 MORE_INIT ENDP
; ;AN000;
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 ;*****************************************************************************
627 CMP BL, 0 ;IS THIS DRIVE ZERO?
628 ;IF BL = 0, THEN JUST RETURN
631 DOSCALL IOCTL_FUNC
,SET_LOG_DRIVE
; ;AC000;
632 ;SET BL AS AN OWNER OF THAT DRIVE
636 SET_LOGICAL_DRIVE ENDP
637 ; = = = = = = = = = = = =
638 HEADER
<COMP
- PERFORM THE OVERALL COMPARISON
> ; ;AN000;
639 ;*****************************************************************************
641 ;*****************************************************************************
642 MOV AL,ORG_SOURCE_DRIVE
;INITIALIZE THE FIRST AND SECOND
643 MOV SOURCE_DRIVE
,AL ;DRIVE IN THE ORDER THE USER
644 MOV AL,ORG_TARGET_DRIVE
;ENTERED ON THE COMMAND LINE
646 MOV AX, RECOMMENDED_BYTES_SECTOR
647 MOV bSECTOR_SIZE
, AX ;USE RECOMMENDED SECTOR SIZE
649 MOV READ_S_BPB_FAILURE
, 0 ;RESET GET BPB FAILURE FLAG
650 MOV READ_T_BPB_FAILURE
, 0
651 MOV COMP_ERROR
,0 ;RESET COMPARE ERROR COUNT
652 MOV COMP_STATUS
,OK
;RESET COMP STATUS BYTE
653 CMP COPY_TYPE
,2 ;IF TWO DRIVE COMP
656 CALL DISPLAY_LOAD_FIRST
;"Insert FIRST diskette in drive %1:" ;AN000;
658 CALL DISPLAY_LOAD_SECOND
;"Insert SECOND diskette in drive %1:" ;AN000;
660 CALL PRESS_ANY_KEY
;"Press any key to continue . . ." ;AC009;
664 MOV TRACK_TO_READ
,0 ;INITIALIZE TRACK NUMBERS
668 MOV AL,TRACK_TO_COMP
;WHILE TRACK_TO_COMP<=LAST_TRACK
674 CMP COMP_STATUS
,FATAL
;MAKE SURE DRIVES WERE COMPATIBLE
679 CMP COMP_STATUS
,FATAL
;MAKE SURE TARGET AND SOURCE
680 JE COMP_EXIT
;DISKETTES ARE COMPATIBLE
685 CMP COMP_ERROR
,0 ;IF ERROR IN COMP
688 PRINT MSGNUM_COMP_OK
;"Compare OK" ;AC000;
690 ;kiser note: this is a warning????
696 CMP COMP_STATUS
,FATAL
;WAS COMP ABORTED ?
699 ;"Compare process ended"
700 PRINT MSGNUM_FATAL_ERROR
;IF SO THEN TELL USER ;AC000;
707 ; = = = = = = = = = = = =
708 HEADER
<DISPLAY_LOAD_FIRST
- MOUNT FIRST DISKETTE
> ; ;AN000;
709 DISPLAY_LOAD_FIRST PROC
NEAR ; ;AN000;
710 PUBLIC DISPLAY_LOAD_FIRST
; ;AN000;
711 ; = = = = = = = = = = = =
713 MOV SUBLIST_78
.SUB_VALUE
,OFFSET ASCII_DRV1_ID
;PASS CHAR DRIVE ID ;AN000;
714 ;"Insert FIRST diskette in drive %1:"
715 PRINT MSGNUM_LOAD_FIRST
;OUTPUT LOAD FIRST DISKETTE MESSAGE ;AC000;
718 RET ;RETURN TO CALLER ;AN000;
719 DISPLAY_LOAD_FIRST ENDP
; ;AN000;
720 ; = = = = = = = = = = = =
721 HEADER
<DISPLAY_SECOND
- MOUNT FIRST DISKETTE
> ; ;AN000;
722 DISPLAY_LOAD_SECOND PROC
NEAR ; ;AN000;
723 PUBLIC DISPLAY_LOAD_SECOND
; ;AN000;
724 ; = = = = = = = = = = = =
726 MOV SUBLIST_78
.SUB_VALUE
,OFFSET ASCII_DRV2_ID
;PASS CHAR DRIVE ID ;AN000;
727 ;CR,LF,"Insert SECOND diskette in drive %1:",CR,LF
728 PRINT MSGNUM_LOAD_SECOND
;OUTPUT LOAD SECOND DISKETTE MESSAGE ;AC000;
731 RET ;RETURN TO CALLER ;AN000;
732 DISPLAY_LOAD_SECOND ENDP
; ;AN000;
733 ; = = = = = = = = = = = =
734 HEADER
<TEST_REPEAT
- PROMPT FOR ANOTHER COMPARE
> ; ;AN000;
735 ;*****************************************************************************
737 PUBLIC TEST_REPEAT
;MAKE ENTRY IN LINK MAP ;AN000;
738 TEST_REPEAT PROC
NEAR ;TEST IF USER WANTS TO COMP ANOTHER *
740 ; INPUT : USER_INPUT ("Y" OR "N")
741 ; OUTPUT: NC = COMP AGAIN *
743 ;*****************************************************************************
744 ; $SEARCH ;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED ;AC000;
746 ;"Compare another diskette (Y/N)?"
747 PRINT MSGNUM_COMP_ANOTHER
;SEE IF USER WANTS TO COMPARE ANOTHER ;AC000;
748 ; AND READ RESPONSE TO AL
749 PUSH AX ;SAVE THE RESPONSE ;AN000;
750 PRINT MSGNUM_NEWLINE
;CR,LF,LF ;AC000;
752 POP DX ;RESTORE THE REPONSE CHAR TO DL ;AN000;
753 CALL YESNO
;CHECK FOR (Y/N) ;AN000;
755 ; $EXITIF C,NUL ;QUIT IF OK ANSWER ;AN000;
757 CMP AL,BAD_YESNO
;WAS THE RESPONSE INVALID? ;AN000;
758 ; $ENDLOOP B ;QUIT IF OK ANSWER (AX=0 OR 1) ;AN000;
760 CMP AL,YES
;WAS "YES" SPECIFIED ;AN000;
761 ; $IF E ;IF "YES" ;AN000;
763 MOV FIRST_TIME
,ZERO
;SET UP TO DO ANOTHER VOLSER CHECK ;AN000;
764 CLC ;CLEAR CARRY TO INDICATE COMPARE AGAIN ;AN000;
765 ; $ELSE ;SINCE NOT "YES" ;AN000;
768 STC ;SET CARRY TO INDICATE NO REPEAT ;AN000;
776 ; = = = = = = = = = = = =
777 HEADER
<READ_SOURCE
- FILL AVAIL MEM WITH FIRST DISKETTE
> ; ;AN000;
778 ;*****************************************************************************
780 PUBLIC READ_SOURCE
;MAKE ENTRY IN LINK MAP ;AN000;
781 READ_SOURCE PROC
NEAR ;FILL ALL AVAILABLE MOMORY WITH SOURCE DATA
783 ;*****************************************************************************
785 CMP TRACK_TO_READ
,0 ;1ST TRACK ?
788 CMP COPY_TYPE
,1 ;IF SINGLE DRIVE COMP
791 CALL DISPLAY_LOAD_FIRST
;"Insert FIRST diskette in drive %1:" ;AN000;
793 CALL PRESS_ANY_KEY
;"Press any key to continue . . ." ;AC000;
797 CALL CHECK_SOURCE
;DO NECESSARY CHECKING
801 CALL CHECK_MEMORY_SIZE
803 CMP COMP_STATUS
,FATAL
809 MOV BUFFER_PTR
,BX ;INITIALIZE BUFFER POINTER
813 MOV AL,TRACK_TO_READ
;DID WE FINISH READING ALL TRACKS?
818 MOV AX,BUFFER_PTR
;DID WE RUN OUT OF BUFFER SPACE
824 CALL READ_TRACK
;NO, GO READ ANOTHER TRACK
835 ; = = = = = = = = = = = =
836 HEADER
<CHECK_SOURCE
- DETERMINE FIRST DISKETTE TYPE
> ; ;AN000;
837 ;*****************************************************************************
839 PUBLIC CHECK_SOURCE
;MAKE ENTRY IN LINK MAP ;AN000;
840 CHECK_SOURCE PROC
NEAR ;CHECK SOURCE DISKETTE TYPE *
841 ; SET END_OF_TRACK, LAST_TRACK *
842 ; NO_OF_SIDES, bSECTOR_SIZE *
843 ; ** this routine will call "Get dev parm" with "BUILD BPB BIT" on. If it *
844 ; ** fails to get that info, then the source medium must be bad(vergin) or *
845 ; ** below DOS 2.0 level diskette, and will jmp to the old logic. *
846 ; ** For compatibility reasons (in case of non IBM formatted media), this *
847 ; ** routine covers old diskcopy routines. But this will only supports
848 ; ** 5.25" 48 tpi 8, 9 sectors, 40 tracks and 5.25" 96 tpi, 15 sectors, 80 tracks
849 ; ** media. Other non IBM formatted media which are formatted differenty
850 ; ** from those values will result in unpreditable copy process.
851 ;*****************************************************************************
856 MOV MS_specialFunctions
, GET_SP_FUNC_MED
;=00000001b
857 MOV CL, GETDEVPARM
;=60h
858 MOV DX, OFFSET MS_IOCTL_DRV_PARM
859 CALL GENERIC_IOCTL
;TRY TO GET MEDIA BPB INFO TOGETHER
860 ;WITH DEFAULT DEVICE INFO.
861 CMP IO_ERROR
, SOFT_ERROR
;TRY AGAIN?
864 CMP IO_ERROR
, HARD_ERROR
;CANNOT GET MEDIA BPB?
867 JMP CS_OLD
;ASSUME OLD FORMATTED DISKETTE, FIRST. ;AC000;
869 cmp ms_deviceBPB
.csect_track
,0 ;patch 1/16/86 J.K.
872 cmp ms_deviceBPB
.chead
,0 ;cannot trust the info. from DOS.
873 je cs_old
;sanity check for devide by 0.
875 MOV AX, MS_deviceBPB
.CTOTSECT
876 CWD ;CONVERT IT TO A DOUBLE WORD
877 DIV MS_deviceBPB
.CSECT_TRACK
878 DIV MS_deviceBPB
.CHEAD
;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
879 CMP AL, T_DRV_TRACKS
;IF # OF TRACKS FOR SOURCE MEDIA > # OF
880 ; TRACKS FOR TARGET DEVICE
881 JA CS_FATAL
;THEN, NOT COMPATIBLE
883 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM'S USE.
884 MOV LAST_TRACK
, AL ;SET LAST_TRACK
885 MOV AX, MS_deviceBPB
.CSECT_TRACK
886 MOV SECT_TRACK_LAYOUT
, AX ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
887 CMP USER_OPTION_8
, ON ;/8 OPTION SPECIFIED?
890 CMP AX, 8 ;SOURCE MEDIA # OF SECTORS/TRACK < 8 ?
891 JB CS_FATAL
;IF IT IS, THEN FATAL ERROR.
893 MOV AX, 8 ;ELSE SET IT TO 8
895 CMP AL, T_DRV_SECT_TRACK
898 MOV END_OF_TRACK
, AL ;SET END_OF_TRACK
899 MOV AX, MS_deviceBPB
.CBYTE_SECT
900 MOV bSECTOR_SIZE
, AX ;set the sector size in bytes.
904 MOV AX, MS_deviceBPB
.CHEAD
;HEAD=1, 2
905 CMP AL, T_DRV_HEADS
;COMPARE SOURCE MEDIA SIDE WITH TARGET
907 JA CS_FATAL
;SOURCE MEDIUM IS DOUBLE SIDED AND
908 ; TARGET DRIVE IS SINGLE SIDED.
911 MOV NO_OF_SIDES
, AL ;NO_OF_SIDES=0, 1
915 MOV COMP_STATUS
, FATAL
916 ;"Drive types or diskette types"
918 PRINT MSGNUM_NOT_COMPATIBLE
; ;AC000;
923 MOV COMP_STATUS
, FATAL
924 PRINT MSGNUM_BAD_FIRST
;"FIRST diskette bad or incompatible" ;AC000;
930 MOV READ_S_BPB_FAILURE
, 1 ;SET FLAG
931 MOV bSECTOR_SIZE
, 512 ;OLD SECTOR SIZE MUST BE 512 BYTES
934 MOV IOCTL_TRACK
, 0 ;TRACK=0
935 MOV IOCTL_SECTOR
, 8 ;SECTOR=8
936 MOV IOCTL_HEAD
, 0 ;HEAD = 0
939 JC CS_BAD
;SOURCE BAD
941 MOV IOCTL_SECTOR
, 9 ;TRY TO READ SECTOR=9
944 JC CS_SECT8
;YES, 8 SECTORS. ASSUME 40 TRACKS
946 MOV IOCTL_SECTOR
, 15 ;try to read sector=15
949 JC CS_SECT9
;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA
954 MOV NO_OF_SIDES
, 0 ;1 SIDE COPY
958 MOV SECT_TRACK_LAYOUT
, 15 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
959 MOV END_OF_TRACK
, 15 ;ELSE END_OF_TRACK = 15
964 MOV SECT_TRACK_LAYOUT
, 8 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
965 MOV END_OF_TRACK
, 8 ;SOURCE 8 SECTORS
966 MOV LAST_TRACK
, 39 ;ASSUME 40 TRACKS.
970 MOV SECT_TRACK_LAYOUT
, 9 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
972 MOV LAST_TRACK
, 39 ;ASSUME 5.25 DISKETTE
974 CMP USER_OPTION_8
, ON
982 MOV IOCTL_HEAD
, 1 ;HEAD 1
984 MOV AL, END_OF_TRACK
;READ MATCHING END_OF_TRACK
985 ; OF THE OTHER SURFACE.
989 JC CS_OPTION_1
;1 SIDED SOURCE
991 MOV NO_OF_SIDES
, 1 ;2 SIDED SOURCE
992 CMP T_DRV_HEADS
, 2 ;SOUCE=2 SIDED MEDIUM. IS TARGET
996 JMP CS_FATAL
;NOT COMPATIBLE
999 CMP READ_S_BPB_FAILURE
, 1 ;diskette without BPB info?
1000 JNE CS_SET_TABLE_NEXT
1002 CALL SET_FOR_THE_OLD
;set deviceBPB info for before 2.0 level
1005 MOV BX, OFFSET MS_trackLayout
;SET TRACKLAYOUT OF SOURCE
1006 CALL SET_TRACKLAYOUT
1008 MOV S_DRV_SET_FLAG
, 1 ;indicate SOURCE DRIVE
1009 ; PARAMETER HAS BEEN SET
1011 MOV BL, SOURCE_DRIVE
1012 MOV DX, OFFSET MS_IOCTL_DRV_PARM
1013 MOV MS_specialFunctions
, SET_SP_FUNC_DEF
1014 CALL SET_DRV_PARM_DEF
;set device parameter for read
1017 MOV AL, END_OF_TRACK
1018 MOV numberOfSectors
, AX ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE
1020 MOV AL, LAST_TRACK
;NOW, SHOW THE MESSAGE "COMPARING ..."
1022 MOV BYTE PTR MSG_TRACKS
,AL ;HOW MANY TRACKS? ;AC000;
1024 MOV AL, END_OF_TRACK
1025 MOV BYTE PTR MSG_SECTRK
,AL ;HOW MANY SECTORS? ;AC000;
1027 MOV AL, NO_OF_SIDES
;TELL USER HOW MANY SIDE TO COPY
1029 MOV BYTE PTR MSG_SIDES
,AL ; ;AC000;
1030 ;CR,LF,"Comparing %1 tracks",CR,LF
1031 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
1032 PRINT MSGNUM_COMPARING
; ;AC000;
1038 ; = = = = = = = = = = = =
1039 HEADER
<READ_A_SECTOR
- USE IOCTL READ TO GET A SECTOR
> ; ;AN000;
1040 ;*****************************************************************************
1041 PUBLIC READ_A_SECTOR
;MAKE ENTRY IN LINK MAP ;AN000;
1042 READ_A_SECTOR PROC
NEAR
1044 ;TRY TO READ A SECTOR USING IOCTL READ FUNCTION CALL.
1045 ;THIS ROUTINE WILL STEAL "IOCTL_R_W" TABLE TEMPORARILY.
1046 ;INPUT: BX - LOGICAL DRIVE NUMBER
1047 ; IOCTL_SECTOR - SECTOR TO READ
1048 ; IOCTL_TRACK - TRACK
1049 ; IOCTL_HEAD - HEAD TO READ
1050 ; bSECTOR_SIZE - SECTOR SIZE IN BYTES
1052 ; IF NOT A SUCCESS, CARRY WILL BE SET
1053 ; ALL REGISTORS SAVED
1054 ;*****************************************************************************
1060 MOV AX, numberOfSectors
;SAVE IOCTL_R_W TABLE VALUES
1066 MOV Head
, AX ;SURFACE TO READ
1068 MOV Cylinder
, AX ;TRACK TO READ
1069 MOV AX, IOCTL_SECTOR
1070 dec ax ;????? currently firstsector=0 =>
1072 MOV FirstSectors
, AX ;SECTOR TO READ
1073 MOV numberOfSectors
, 1 ;read just one sector
1074 MOV AX, offset INIT
;READ IT INTO INIT (CURRELTLY, MAX 1K)
1075 MOV TAddress_off
, AX
1076 MOV TAddress_seg
, DS
1078 MOV DX, OFFSET IOCTL_R_W
;POINTS TO CONTROL TABLE
1081 CMP IO_ERROR
, SOFT_ERROR
;TRY ONCE MORE?
1085 CMP IO_ERROR
, HARD_ERROR
;HARD ERROR?
1094 STC ;READ FAILURE, SET CARRY
1097 MOV AX, SAV_CSECT
;RESTORE ORIGINAL IOCTL_R_W TABLE
1098 MOV numberOfSectors
, AX
1105 ; = = = = = = = = = = = =
1106 HEADER
<CALC_TRACK_SIZE
- FIND MEM SIZE TO HOLD ONE TRACK
> ; ;AN000;
1107 ;*****************************************************************************
1109 PUBLIC CALC_TRACK_SIZE
;MAKE ENTRY IN LINK MAP ;AN000;
1110 CALC_TRACK_SIZE PROC
NEAR ;CALCULATE MEMORY SIZE REQUIRED TO STORE ONE
1111 ; TRACK (IN SEGMENTS) *
1112 ;CALCULATE SECTOR_SIZE IN PARA FROM bSECTOR_SIZE. IF bSECTOR_SIZE CANNOT BE
1113 ;CHANGED TO SECTOR_SIZE IN PARA EXACTLY, THEN ADD 1 TO THE SECTOR_SIZE.
1114 ;SECTOR_SIZE IS USED FOR MEMORY MANAGEMANT ONLY. THE ACTUAL COPY OR FORMAT
1115 ;SHOULD BE DEPENDS ON bSECTOR_SIZE TO FIGURE OUT HOW BIG A SECTOR IS.
1116 ;ALSO, CURRENTLY, THIS ROUTINE ASSUME A BSECTOR SIZE BE LESS THAN 0FFFh.
1117 ;*****************************************************************************
1123 MOV AX, bSECTOR_SIZE
1126 MOV BL, END_OF_TRACK
1128 MOV BYTES_IN_TRACK
,AX ;BYTES/TRACK ON A SIDE OF THE DISKETTE
1130 MOV AX, bSECTOR_SIZE
1132 DIV CL ;AX / 16 = AL ... AH
1133 CMP AH, 0 ;NO REMAINER?
1137 INC AL ;THERE REMAINER IS. INC AL
1140 MOV SECTOR_SIZE
, AL ;SECTOR_SIZE+ IN PARA.
1141 MOV AL,NO_OF_SIDES
;TRACK_SIZE = (NO OF SIDES
1143 MUL END_OF_TRACK
; * END_OF_TRACK
1144 MOV BL,SECTOR_SIZE
; * SECTPR_SIZE
1145 MUL BL ;AMOUNT OF MEMORY REQUIRED (IN SEG)
1146 MOV TRACK_SIZE
,AX ;TO STORE A TRACK
1148 MOV BX,START_BUFFER
;SET SECONDARY AT START OF BUFFER SPACE
1149 MOV SEC_BUFFER
,BX ;SET THE SECONDARY BUFFER SEG ADDR
1150 ADD BX,AX ;MOVE THE PRIMARY BUFFER BELOW THE
1151 MOV BUFFER_BEGIN
,BX ;SECONDARY BUFFER
1158 CALC_TRACK_SIZE ENDP
1159 ; = = = = = = = = = = = =
1160 HEADER
<CHECK_MEMORY_SIZE
- BE SURE ENUF ME TO COMPARE
1 TRACK
> ; ;AN000;
1161 ;*****************************************************************************
1163 PUBLIC CHECK_MEMORY_SIZE
;MAKE ENTRY IN LINK MAP ;AN000;
1164 CHECK_MEMORY_SIZE PROC
NEAR ;MAKE SURE WE HAVE ENOUGH TO COMP 1 TRACK INTO
1165 ; TO BUFFER ELSE ABORT COMP *
1166 ;*****************************************************************************
1172 MOV COMP_STATUS
,FATAL
1173 ;"Insufficient memory"
1174 PRINT MSGNUM_UNSUF_MEMORY
; ;AC000;
1180 CHECK_MEMORY_SIZE ENDP
1181 ; = = = = = = = = = = = =
1182 HEADER
<COMP_TARGET
- COMPARE MEM
DATA WITH SECOND DISKETTE
> ; ;AN000;
1183 ;*****************************************************************************
1185 PUBLIC COMP_TARGET
;MAKE ENTRY IN LINK MAP ;AN000;
1186 COMP_TARGET PROC
NEAR ;COMPARE DATA FROM MEMORY TO TARGET DISKETTE
1188 ;*****************************************************************************
1190 CMP COPY_TYPE
,1 ;IF SINGLE DRIVE COMP
1196 CALL DISPLAY_LOAD_SECOND
;"Insert SECOND diskette in drive %1:" ;AN000;
1201 CALL DISPLAY_LOAD_FIRST
;"Insert FIRST diskette in drive %1:" ;AN000;
1205 CALL PRESS_ANY_KEY
;"Press any key to continue . . ." ;AC009;
1210 MOV COMPARE_PTR
,BX ;INITIALIZE BUFFER POINTER
1211 CMP TRACK_TO_COMP
,0 ;IF TRK 0, CHECK COMPATIBILITY
1216 CMP COMP_STATUS
,FATAL
;IF INCOMPATIBLE, THEN EXIT
1226 CALL COMP_TRACK
;NO, GO READ ANOTHER TRACK
1229 MOV AL,TRACK_TO_READ
;DID WE FINISH READING ALL TRACKS?
1234 MOV AX,COMPARE_PTR
;DID WE RUN OUT OF BUFFER SPACE
1244 ; = = = = = = = = = = = =
1245 HEADER
<CHECK_TARGET
- COMPARE SECOND DISK BOOT RECORD
> ; ;AN000;
1246 ;*****************************************************************************
1247 PUBLIC CHECK_TARGET
;MAKE ENTRY IN LINK MAP ;AN000;
1248 CHECK_TARGET PROC
NEAR ; *
1249 ; ** CHECK_SOURCE PROCEDURE ALREADY CHECKS OUT THE INCOMPATIBILITY BETWEEN *
1250 ; ** SOURCE MEDIA AND TARGET DRIVE. (CHECKING SOURCE MEDIA SECTOR/TRACK *
1251 ; ** EXCEEDS TARGET DRV SECTOR/TRACK, AND SOURCE MEDIA # OF TRACKS WITH *
1252 ; ** THAT OF TARGET DRV.) *
1253 ; ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD. *
1254 ; ** IF A SUCCESS,THEN COMPARE BPB INFO WITH THAT OF SOURCE MEDIA. *
1255 ; ** IF THEY ARE DIFFERENT, THEN ERROR - NOT COMPATIBLE *
1256 ; ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR *
1257 ; ** COMPATIBILITY REASONS. *
1258 ;*****************************************************************************
1262 MOV BL, TARGET_DRIVE
1263 MOV MT_specialFunctions
, GET_SP_FUNC_MED
;=00000001b
1265 MOV DX, OFFSET MT_IOCTL_DRV_PARM
1266 CALL GENERIC_IOCTL
;TRY TO GET MEDIA BPB INFO TOGETHER
1267 ;WITH THE DEFAULT DEVICE INFO.
1268 CMP IO_ERROR
, SOFT_ERROR
;TRY AGAIN?
1272 CMP IO_ERROR
, HARD_ERROR
;ASSUME OLD DISKTETTE. OR DISKETTE BAD
1275 cmp mt_deviceBPB
.csect_track
,0 ;patch 1/16/86, J.K.
1278 cmp mt_deviceBPB
.chead
,0 ;cannot trust the info from DOS.
1279 je cht_old
;sanity check for devide by 0
1281 MOV AX, MT_deviceBPB
.CTOTSECT
1282 CWD ;CONVERT IT TO A DOUBLE WORD
1283 DIV MT_deviceBPB
.CSECT_TRACK
1284 DIV MT_deviceBPB
.CHEAD
;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1285 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM
1286 CMP LAST_TRACK
, AL ;COMPARE WITH SOURCE LAST TRACK
1287 JNE CHT_FATAL_BRIDGE
;IF LAST_TRACK IS DIFFERENT,
1288 ; THEN INCOMPATIBLE.
1290 MOV AX, MT_deviceBPB
.CSECT_TRACK
1291 MOV SECT_TRACK_LAYOUT
, AX ;VARIBLE FOR MT_trackLayout.CSECT_F
1293 CMP END_OF_TRACK
, AL
1294 JA CHT_FATAL_BRIDGE
;IF SOURCE END_OF_TRACK > TARGET
1295 ; END_OF_TRACK, THEN ERROR
1297 ;8 SECTORED SOURCE AND 9 SECTORED TARGET
1298 ; IS OK AS FAR AS THE COMPATIBILITY GOES.
1299 MOV AX, MT_deviceBPB
.CBYTE_SECT
1300 CMP AX, bSECTOR_SIZE
;IF SECTOR SIZE ARE DIFFERENT, THEN
1302 JNE CHT_FATAL_BRIDGE
1304 CMP NO_OF_SIDES
, 1 ;TWO SIDED COPY?
1305 JNE CHT_SET_BRIDGE
;NO, ONE SIDED. DON'T
1306 ; CARE ABOUT TARGET SIDES.
1308 CMP MT_deviceBPB
.CHEAD
, 2 ;TARGET FORMATTED INTO TWO SIDES?
1309 JNE CHT_FATAL_BRIDGE
;NO, NOT COMPATIBLE
1311 JMP CHT_SET_DRV
;OK. SOURCE, TARGET MEDIA ARE MATCHING. SET
1312 ; DRV PARM FOR READING
1321 MOV COMP_STATUS
, FATAL
1322 PRINT MSGNUM_BAD_SECOND
;"SECOND diskette bad or incompatible" ;AC000;
1326 CHT_OLD: ;SAME OLD. ;AGAIN, THIS DOES
1327 ; NOT RECOGNIZE 3.5 MEDIA
1328 MOV READ_T_BPB_FAILURE
, 1 ;SET THE FLAG.
1330 MOV BL, TARGET_DRIVE
1333 MOV IOCTL_HEAD
, 0 ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8
1336 JC CHT_SECOND_BAD
;ASSUME TARGET MEDIA NOT FORMATTED.
1338 MOV IOCTL_SECTOR
, 9 ;TRY TO READ SECTOR 9
1341 JC CHT_8_SECTOR
;TARGET IS 8 SECTOR MEDIA
1343 MOV IOCTL_SECTOR
, 15
1346 JC CHT_9_SECTOR
;TARGET IS 9 SECTOR MEDIA
1348 ;CHT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA
1349 MOV SECT_TRACK_LAYOUT
, 15
1350 CMP END_OF_TRACK
, 15 ;IS SOUCE ALSO 96 TPI?
1351 JNE CHT_FATAL
;NO, FATAL ERROR
1353 JMP SHORT CHT_CHK_SIDE
;YES, OK.
1356 MOV SECT_TRACK_LAYOUT
, 8
1357 CMP END_OF_TRACK
, 15
1358 JE CHT_FATAL
;IF SOURCE IS 96 TPI, THEN FATAL ERROR
1361 JE CHT_FATAL
;IF SOURCE IS 9 SECTOR, THEN
1362 ; SHOULD FORMAT TARGET
1364 JMP SHORT CHT_CHK_SIDE
;ELSE ASSUME SOURCE IS 8 SECTOR.
1367 MOV SECT_TRACK_LAYOUT
, 9
1368 CMP END_OF_TRACK
, 15 ;IS SOURCE 96 TPI? THEN ERROR
1369 JE CHT_FATAL
;ELSE SOUCE IS 8 OR 9 SECTORED
1372 CHT_CHK_SIDE: ;CHECK THE TARGET DISKETTE # OF SIDES
1373 CMP NO_OF_SIDES
, 0 ;1 SIDE COMP?
1376 MOV IOCTL_HEAD
, 1 ;ELSE TWO SIDE COMP
1378 MOV AL, END_OF_TRACK
;TRY TO READ MATCHING TARGET SECTOR
1379 MOV IOCTL_SECTOR
, AX ;OF THE OTHERSIDE
1382 JNC CHT_EXIT_OLD
;SUCCESS? OK
1390 CALL SET_FOR_THE_OLD
;SET MT_deviceBPB INFO.
1393 MOV BX, OFFSET MT_trackLayout
;SET TARGET TRACK LAYOUT
1394 CALL SET_TRACKLAYOUT
1396 JC CHT_FATAL
;IF FAILED, THEN, NOT COMPATIBLE
1398 MOV T_DRV_SET_FLAG
, 1 ;INDICATES THE TARGET DEFAULT
1399 ; DEVICE PARM HAS BEEN SET
1401 mov bl, last_track
;To make sure the number of
1402 ; cyl. of target. 3/27/86,J.K.
1404 mov MT_numberOfCylinders
, bx
1405 MOV BL, TARGET_DRIVE
1406 MOV DX, OFFSET MT_IOCTL_DRV_PARM
1407 MOV MT_specialFunctions
, SET_SP_FUNC_DEF
1408 CALL SET_DRV_PARM_DEF
1414 ; = = = = = = = = = = = =
1415 HEADER
<SET_DRV_PARM
- REQUEST IOCTL TO SET DEVICE PARM
> ; ;AN000;
1416 ;*****************************************************************************
1417 PUBLIC SET_DRV_PARM_DEF
;MAKE ENTRY IN LINK MAP ;AN000;
1418 SET_DRV_PARM_DEF PROC
NEAR
1419 ;INPUT: BL - DRIVE NUMBER
1420 ; DX - POINTER TO THE PARAMETER TABLE
1421 ; specialFunction should be set before this call
1422 ;*****************************************************************************
1424 MOV CL, SETDEVPARM
;=40H
1429 SET_DRV_PARM_DEF ENDP
1430 ; = = = = = = = = = = = =
1431 HEADER
<COMP_TRACK
- READ
AND COMPARE SPECIFIED TRACK
> ; ;AN000;
1432 ;*****************************************************************************
1434 PUBLIC COMP_TRACK
;MAKE ENTRY IN LINK MAP ;AN000;
1435 COMP_TRACK PROC
NEAR ;COMPARE TRACK SPECIFIED IN TRACK_TO_COMP
1437 ;*****************************************************************************
1438 MOV AX,SEC_BUFFER
;READ IN THE TRACK TO BE COMPARED
1439 MOV BUFFER_PTR
,AX ;INTO THE SECONDARY BUFFER
1442 MOV SIDE
,0 ;START ON SIDE ZERO
1443 MOV CX,BYTES_IN_TRACK
;GET NUMBER TO COMPARE
1446 MOV ES,COMPARE_PTR
;SET DESTINATION SEG ADDR
1447 MOV DS,SEC_BUFFER
;SET SOURCE SEG ADDR
1452 XOR DI,DI ;SET TO START OF TRACK
1454 CMP FIRST_TIME
,ZERO
;IF THIS IS THE FIRST SECTOR TO BE COMPARED ;AN000;
1457 CALL VOLSER
;SPECIAL HANDLING FOR VOL SER # ;AN000;
1459 MOV FIRST_TIME
,ONE
;FLAG FIRST TIME AS "DONE" ;AN000;
1462 CALL DO_COMPARE
;COMPARE STRING ;AN000;
1472 PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT
1473 MOV OPERATION
,COMPARE_FUNC
1480 CMP NO_OF_SIDES
,1 ;TWO SIDED COMPARE?
1483 MOV SIDE
,1 ;MARK IT AS SUCH
1484 MOV SI,BYTES_IN_TRACK
;BUMP UP BUFFER POINTERS
1485 MOV DI,BYTES_IN_TRACK
;TO START OF SECOND SIDE
1486 MOV CX,BYTES_IN_TRACK
;GET NUMBER TO COMPARE
1489 MOV ES,COMPARE_PTR
;SET DESTINATION SEG ADDR
1490 MOV DS,SEC_BUFFER
;SET SOURCE SEG ADDR
1491 CALL DO_COMPARE
;COMPARE STRING ;AN000;
1497 PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT
1498 MOV OPERATION
,COMPARE_FUNC
1507 MOV AX,TRACK_SIZE
;ADVANCE COMPARE POINTER
1511 ; = = = = = = = = = = = =
1512 HEADER
<DO_COMPARE
- PERFORM THE COMPARISON
> ; ;AN000;
1513 DO_COMPARE PROC
NEAR ; ;AN000;
1514 PUBLIC DO_COMPARE
;ADD ENTRY TO LINK MAP ;AN000;
1515 ;INPUT: DS:[SI] POINTS TO ONE BUFFER, ES:[DI] POINTS TO THE OTHER
1516 ; CX HAS THE BYTE COUNT
1517 ;OUTPUT:CONDITION CODE IN CONDITION FLAGS REFLECT RESULT OF COMPARISON
1518 ; = = = = = = = = = = = =
1519 SHR CX,1 ;DIVIDE BY TWO, CHANGE TO WORD COUNT ;AN000;
1521 PUBLIC PATCH_386
;SO INIT CAN DO FIXUP ;AN001;
1522 PATCH_386
LABEL BYTE
1523 SHR CX,1 ;CONVERT WORD COUNT TO DWORD COUNT ;AN001;
1524 DB 66H
;PREFIX FOR A DWORD COMPARE ;AN001;
1525 ; END OF PATCH AREA. IF THIS IS NOT A 386, THE ABOVE 3 BYTES ARE CHANGED
1526 ; TO NOP BY DISKINIT.SAL DURING INITIALIZATION.
1528 REPE CMPSW ;PERFORM THE COMPARISON ;AN000;
1530 RET ;RETURN TO CALLER ;AN000;
1531 DO_COMPARE ENDP
; ;AN000;
1532 ; = = = = = = = = = = = =
1533 HEADER
<SWAP_DRIVE
- SETUP FOR DISKETTE SWAPPING
> ; ;AN000;
1534 ;*****************************************************************************
1535 PUBLIC SWAP_DRIVE
;MAKE ENTRY IN LINK MAP ;AN000;
1536 SWAP_DRIVE PROC
NEAR ;SWAP SOURCE, TARGET DRIVE
1537 ;*****************************************************************************
1539 XCHG AL,TARGET_DRIVE
1541 MOV AL,TRACK_TO_COMP
1542 XCHG AL,TRACK_TO_READ
1543 MOV TRACK_TO_COMP
,AL
1547 HEADER
<READ_TRACK
- READ A TRACK TO MEMORY
> ; ;AN000;
1548 ;*****************************************************************************
1550 PUBLIC READ_TRACK
;MAKE ENTRY IN LINK MAP ;AN000;
1551 READ_TRACK PROC
NEAR ;READ A TRACK AND STORE IT INTO MEMORY
1553 ;*****************************************************************************
1560 CMP NO_OF_SIDES
, 0 ;SINGLE SIDE COPY?
1564 ; $ELSE ;NO, DOUBLE SIDE
1576 CMP AL, NO_OF_SIDES
;FINISHED WITH THE LAST SIDE?
1582 ; = = = = = = = = = = = =
1583 HEADER
<READ_OP
- IOCTL TO READ A TRACK
> ; ;AN000;
1584 ;*****************************************************************************
1586 PUBLIC READ_OP
;MAKE ENTRY IN LINK MAP ;AN000;
1587 READ_OP PROC
NEAR ;IOCTL READ A TRACK OPERATION
1589 ;*****************************************************************************
1595 MOV Head
, AX ;HEAD TO READ
1596 MOV AL, TRACK_TO_READ
1597 MOV Cylinder
, AX ;TRACK TO READ
1598 MOV FirstSectors
, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
1600 MOV Taddress_seg
, AX ;BUFFER ADDRESS
1603 MOV BL, SOURCE_DRIVE
1604 MOV CL, READ_FUNC
;=61h
1605 MOV DX, OFFSET IOCTL_R_W
1608 CMP IO_ERROR
, NO_ERROR
;OK?
1612 CMP IO_ERROR
, SOFT_ERROR
;TRY AGAIN?
1616 MOV OPERATION
, READ_FUNC
1621 INC COMP_ERROR
;INCREASE COPY_ERROR COUNT
1626 ; = = = = = = = = = = = =
1627 HEADER
<SET_FOR_THE_OLD
- USE PRE
2.0 BPB
> ; ;AN000;
1628 ;*****************************************************************************
1629 PUBLIC SET_FOR_THE_OLD
;MAKE ENTRY IN LINK MAP ;AN000;
1630 SET_FOR_THE_OLD PROC
NEAR
1631 ;set MS_deviceBPB or MT_deviceBPB for before-2.0 formatted media.
1632 ;*****************************************************************************
1635 CMP SECT_TRACK_LAYOUT
,9 ;IF SECTORS/TRACK <= 9, THEN CHECK
1636 ;NO_OF_SIDES. IF SINGLE SIDE COPY
1637 ; THEN USE BPB48_SINGLE
1638 ;ELSE USE BPB48_DOUBLE.
1639 ; $IF A ;SECTORS/TRACK > 9 THEN USE BPB96 TABLE
1641 MOV SI, OFFSET BPB96
1645 CMP NO_OF_SIDES
, 0 ;SINGLE SIDE COPY?
1648 MOV SI, OFFSET BPB48_DOUBLE
;ELSE USE BPB48 DOUBLE
1652 MOV SI, OFFSET BPB48_SINGLE
1657 MOV AX, SECT_TRACK_LAYOUT
1658 CMP READ_S_BPB_FAILURE
, 1 ;FAILURE ON THE SOURCE?
1661 MOV MS_deviceBPB
.CSECT_TRACK
,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM
1662 MOV DI, OFFSET MS_deviceBPB
1664 REP MOVSB ;OLD DEFAULT BPB INFO => MS_deviceBPB
1668 CMP READ_T_BPB_FAILURE
, 1 ;FAILURE ON THE TARGET?
1671 MOV MT_deviceBPB
.CSECT_TRACK
,AX
1672 MOV DI, OFFSET MT_deviceBPB
1674 REP MOVSB ;OLD DEFAULT BPB INTO => MT_deviceBPB
1681 SET_FOR_THE_OLD ENDP
1682 ; = = = = = = = = = = = =
1683 HEADER
<SET_TRACKLAYOUT
- DETERMINE SECTORS PER TRACK
> ; ;AN000;
1684 ;*****************************************************************************
1685 PUBLIC SET_TRACKLAYOUT
;MAKE ENTRY IN LINK MAP ;AN000;
1686 SET_TRACKLAYOUT PROC
NEAR
1687 ;INPUT: BX - POINTER TO DESTINATION
1689 ;*****************************************************************************
1690 MOV CX, SECT_TRACK_LAYOUT
;MEDIA SECTORS/TRACK
1691 MOV WORD PTR [BX], CX ;SET CSECT_F TO THE NUMBER OF SECTORS
1693 ADD BX, 2 ;NOW BX POINTS TO THE FIRST SECTORNUMBER
1695 MOV AX, bSECTOR_SIZE
1699 CMP CX, SECT_TRACK_LAYOUT
1703 MOV WORD PTR [BX], CX
1706 MOV WORD PTR [BX], AX
1716 SET_TRACKLAYOUT ENDP
1717 ; = = = = = = = = = = = =
1718 HEADER
<GENERIC_IOCTL
- PERFORM SPECIFIED IOCTL FUNCTION
> ; ;AN000;
1719 PUBLIC GENERIC_IOCTL
1720 ;******************************************************************************
1721 GENERIC_IOCTL PROC
NEAR
1722 ;INPUT: CL - MINOR CODE; 60 - GET DEVICE PARM, 40 - SET DEVICE PARM
1723 ; 61 - READ TRACK, 41 - WRITE TRACK,
1724 ; 42 - FORMAT AND VERIFY TRACK
1726 ; BL - LOGICAL DRIVE LETTER
1727 ; DS:DX - POINTER TO PARAMETERS
1728 ;******************************************************************************
1730 MOV IO_ERROR
, NO_ERROR
;reset io_error
1731 MOV AH, IOCTL_FUNC
;IOCTL FUNC = 44H
1732 MOV AL, GENERIC_IOCTL_CODE
;GENERIC IOCTL REQUEST = 0DH
1733 MOV CH, MAJOR_CODE
;MAJOR CODE=08H, REMOVABLE
1737 CALL EXTENDED_ERROR_HANDLER
;ERROR, SEE WHAT IT IS!
1743 ; = = = = = = = = = = = =
1744 HEADER
<EXTENDED_ERROR
- DETERMINE
AND SERVICE EXTENDED ERRORS
> ; ;AN000;
1745 ;******************************************************************************
1746 PUBLIC EXTENDED_ERROR_HANDLER
;MAKE ENTRY IN LINK MAP ;AN000;
1747 EXTENDED_ERROR_HANDLER PROC
NEAR
1748 ;INPUT: BL - LOGICAL DRIVE LETTER
1749 ;******************************************************************************
1765 ; CMP BL, 5 ;ACTION=IMMEDIATE EXIT?
1768 POP BX ;RESTORE BL FOR DRIVE LETTER
1772 CMP AX, 21 ;DRIVE NOT READY?
1775 CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED?
1778 JMP EEH_HARD_ERROR
;OTHERWISE, HARD_ERROR
1781 MOV DRIVE_LETTER
, 'A'
1782 DEC BL ;CHANGE LOGICAL TO PHYSICAL
1783 ADD DRIVE_LETTER
, BL
1784 ;"Drive not ready - X:"
1785 PRINT MSGNUM_GET_READY
; ;AC000;
1787 PRINT MSGNUM_CLOSE_DOOR
;"Make sure a diskette is inserted into ;AN004;
1788 ; the drive and the door is closed"
1792 ;"Attempt to write to write-protected diskette"
1793 PRINT MSGNUM_WRITE_PROTECT
; ;AC000;
1796 CALL PRESS_ANY_KEY
;"Press any key to continue . . ." ;AC009;
1799 MOV IO_ERROR
, SOFT_ERROR
;INDICATE THE CALLER TO TRY AGAIN
1803 MOV IO_ERROR
, HARD_ERROR
1816 ; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT
1818 EXTENDED_ERROR_HANDLER ENDP
1820 ; HEADER <CALL_PRINTF - COMMON DRIVER TO PRINTF, DISPLAY MESSAGE>
1821 ;CALL_PRINTF PROC NEAR
1822 ; PUBLIC CALL_PRINTF
1823 ;;INPUT - DX HAS OFFSET INTO DS OF MESSAGE PARM LIST
1831 ; = = = = = = = = = = = =
1832 HEADER
<ERROR_MESSAGE
- DISPLAY THE ERROR MESSAGE
> ; ;AN000;
1833 ERROR_MESSAGE PROC
NEAR ;DISPLAY ERROR MESSAGE
1834 PUBLIC ERROR_MESSAGE
1836 ; FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE)
1837 ; AND WHERE IT FAILED (TRACK NO. AND SIDE).
1839 ; INPUT: OPERATION = IOCTL DISKETTE READ(=61H) OR COMPARE_FUNC(59H)
1840 ; = = = = = = = = = = = =
1842 CMP OPERATION
,READ_FUNC
;ERROR DURING READ ?
1846 ; MOV BX,OFFSET READ_ERROR ;TELL USER ERROR DURING READ OP
1847 ; MOV MSG_HARD_ERROR_PTR+2,BX
1849 MOV DL,SOURCE_DRIVE
;WHICH DRIVE IS BAD
1850 dec dl ;change logical letter to phisical
1851 ADD DL,"A" ;CORRESPONDANT ALPHABET
1853 MOV SUBLIST_17B
.SUB_VALUE
,OFFSET DRIVE_LETTER
;
1855 MOV BL,TRACK_TO_READ
;SAVE BAD TRACK NUMBER FOR READ
1856 ;CR,LF,"Unrecoverable read error on drive %2",CR,LF
1857 ;"side %3, track %4",CR,LF
1858 ;%2 IS "DRIVE_LETTER", AND
1859 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
1860 MOV DI,OFFSET MSGNUM_HARD_ERROR_READ
; ;AN000;
1865 ; MOV BX,OFFSET COMPARE_ERROR ;TELL USER ERROR DURING COMPARE OP
1866 ; MOV MSG_HARD_ERROR_PTR+2,BX
1868 MOV BL,TRACK_TO_READ
;SAVE BAD TRACK NUMBER FOR WRITE
1869 ;CR,LF,"Compare error on",CR,LF
1870 ;"side %3, track %4",CR,LF
1871 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
1872 MOV DI,OFFSET MSGNUM_HARD_ERROR_COMP
; ;AN000;
1877 MOV BYTE PTR MSG_SIDES
,AL
1878 MOV BYTE PTR MSG_TRACKS
,BL
1879 CALL SENDMSG
;PRINT MSG SELECTED ABOVE ;AN000;
1883 ; = = = = = = = = = = = =
1884 HEADER
<COMBAT_ERROR
- DISPLAY INCOMPATIBLE MSG
> ; ;AN000;
1885 COMPAT_ERROR PROC
NEAR ;DISPLAY COMPAT MSG
1887 ; = = = = = = = = = = = =
1889 MOV COMP_STATUS
,FATAL
;INCOMPATIBLE, ABORT
1890 ;"Drive types or diskette types"
1892 PRINT MSGNUM_NOT_COMPATIBLE
1896 ; = = = = = = = = = = = =
1897 HEADER
<PRESS_ANY_KEY
- PUTS A BLANK LINE BEFORE PROMPT
> ; ;AN009;
1898 PRESS_ANY_KEY PROC
NEAR ;
1899 ;THE CANNED MESSAGE "PRESS ANY KEY..." DOES NOT START WITH CR,LF.
1900 ;THIS PUTS OUT THE CR LF TO CAUSE SEPARATION OF THIS PROMP FROM
1901 ;PRECEEDING MESSAGES.
1902 ; = = = = = = = = = = = =
1903 PRINT MSGNUM_NEWLINE
;SKIP A SPACE ;AN009;
1905 PRINT MSGNUM_STRIKE
;"Press any key when ready..." ;AN009;
1907 RET ;RETURN TO CALLER ;AN009;
1908 PRESS_ANY_KEY ENDP
; ;AN009;
1909 ; = = = = = = = = = = = =
1910 HEADER
<SENDMSG
- PASS
IN REGS
DATA FROM MSG DESCRIPTOR TO DISP MSG
> ; ;AN000;
1911 SENDMSG PROC
NEAR ; ;AN000;
1912 PUBLIC SENDMSG
; ;AN000;
1913 ; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
1914 ; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
1915 ; IF CARRY CLEAR, ALL OK
1916 ; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
1918 ; = = = = = = = = = = = =
1920 PUSH BX ; SAVE CALLER'S REGS ;AN000;
1925 ; PASS PARMS TO MESSAGE HANDLER IN
1926 ; THE APPROPRIATE REGISTERS IT NEEDS.
1927 MOV AX,[DI].MSG_NUM
;MESSAGE NUMBER ;AN000;
1928 MOV BX,[DI].MSG_HANDLE
;HANDLE TO DISPLAY TO ;AN000;
1929 MOV SI,[DI].MSG_SUBLIST
;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000;
1930 MOV CX,[DI].MSG_COUNT
;NUMBER OF %PARMS, 0 IF NONE ;AN000;
1931 MOV DX,[DI].MSG_CLASS
;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000;
1932 CALL SYSDISPMSG
;DISPLAY THE MESSAGE ;AN000;
1934 ; $IF C ;IF THERE IS A PROBLEM ;AN000;
1936 ;AX=EXTENDED ERROR NUMBER ;AN000;
1937 LEA DI,MSGNUM_EXTERR
;GET REST OF ERROR DESCRIPTOR ;AN000;
1938 MOV BX,[DI].MSG_HANDLE
;HANDLE TO DISPLAY TO ;AN000;
1939 MOV SI,[DI].MSG_SUBLIST
;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000;
1940 MOV CX,[DI].MSG_COUNT
;NUMBER OF %PARMS, 0 IF NONE ;AN000;
1941 MOV DX,[DI].MSG_CLASS
;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000;
1942 CALL SYSDISPMSG
;TRY TO SAY WHAT HAPPENED ;AN000;
1944 STC ;REPORT PROBLEM ;AN000;
1945 ; $ENDIF ;PROBLEM WITH DISPLAY? ;AN000;
1948 POP SI ;RESTORE CALLER'S REGISTERS ;AN000;
1953 RET ;RETURN TO CALLER ;AN000;
1954 SENDMSG ENDP
; ;AN000;
1955 ; = = = = = = = = = = = =
1956 HEADER
<YESNO
- DETERMINE
IF A RESPONSE IS YES
OR NO
> ; ;AN000;
1957 YESNO PROC
NEAR ; ;AN000;
1958 PUBLIC YESNO
;MAKE ENTRY IN LINK MAP ;AN000;
1959 ;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED
1960 ;OUTPUT: AX=0=NO; AX=1=YES ; AX=2=INVALID RESPONSE, NEITHER Y NOR N
1961 ; IF CARRY SET, PROBLEM WITH THE FUNCTION, CALLER SHOULD ASSUME "NO"
1962 ; = = = = = = = = = = = =
1963 ;AL=SUBFUNCTION, AS:
1964 ; 20H=CAPITALIZE SINGLE CHAR
1965 ; 21H=CAPITALIZE STRING
1966 ; 22H=CAPITALIZE ASCIIZ STRING
1968 ; 80H BIT 0=USE NORMAL UPPER CASE TABLE
1969 ; 80H BIT 1=USE FILE UPPER CASE TABLE
1970 ;DL=CHAR TO CAP (FUNCTION 23H) ;AN000;
1971 MOV AX,(GET_EXT_CNTRY_INFO
SHL 8) + YESNO_CHECK
;(6523H) GET EXTENDED ;AN000;
1972 ; COUNTRY INFORMATION, (Y/N)
1973 INT 21H
;SEE IF Y OR N ;AN000;
1975 RET ;RETURN TO CALLER ;AN000;
1976 YESNO ENDP
; ;AN000;
1977 ; = = = = = = = = = = = =
1978 HEADER
<VOLSER
- VERIFY FIRST SECTOR
, IGNORE VOL SER
#> ; ;AN000;
1979 VOLSER PROC
NEAR ;VERIFY FIRST SECTOR, IGNORING VOL SER # ;AN000;
1980 PUBLIC VOLSER
; ;AN000;
1981 ;IF THE FIRST DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN
1982 ;COPY IT TO THE SECOND DISKETTE BUFFER AREA (NOT THE DISKETTE).
1983 ;INPUT: FIRST DRIVE NUMBER
1984 ; DS:=SEGID OF BUFFER OF FIRST DISKETTE, FIRST SECTOR, SIDE 0
1985 ; ES:=SEGID OF BUFFER OF SECOND DISKETTE, FIRST SECTOR, SIDE 0
1986 ; SI AND DI = 0, INDEX OF WHERE IN BUFFERS TO START LOOKING
1987 ; CX="BYTES_IN_TRACK"; NUMBER OF BYTES TO BE EVENTUALLY COMPARED
1988 ;OUTPUT: BUFFER OF 2ND DISKETTE ALTERED TO MATCH THE VOL SERIAL NUMBER OF 1ST.
1989 ; = = = = = = = = = = = = = = = = = =
1991 ASSUME
DS:NOTHING
;BUFFER OF FIRST DISKETTE ;AN000;
1992 ASSUME
ES:NOTHING
;BUFFER OF SECOND DISKETTE ;AN000;
1994 PUSH CX ;SAVE CALLER'S REGS ;AN000;
1997 ;(deleted ;AN011;) PUSH DS ;SAVE BUFFER OF FIRST DISKETTE ;AN000;
1999 ;(deleted ;AN011;) PUSH CS ;RESTORE ADDRESSABILITY TO COMMON SEG ;AN000;
2000 ;(deleted ;AN011;) POP DS ; TO ACCESS GET MEDIA ID BUFFER AREA ;AN000;
2001 ;(deleted ;AN011;) ASSUME DS:CSEG ;AN000;
2003 ;(deleted ;AN011;); ISSUE GET MEDIA ID FROM SOURCE
2004 ;(deleted ;AN011;) MOV BH,0 ;BH=0, RES ;AN000;
2005 ;(deleted ;AN011;) MOV BL,SOURCE_DRIVE ;BL=DRIVE NUM (A:=1, B:=2, ETC.) ;AN000;
2006 ;(deleted ;AN011;) MOV DX,OFFSET MEDIA_ID_BUFFER ;DS:DX=BUFFER
2007 ;(deleted ;AN011;) DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID ;AC008;
2008 ;(deleted ;AN011;) ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
2009 ;(deleted ;AN011;) POP DS ;RESTORE THIS BACK TO BUFFER OF FIRST DISKETTE;AN000;
2010 ;(deleted ;AN011;) ASSUME DS:NOTHING ; LIKE IT WAS AT ENTRY TO THIS PROC ;AN000;
2012 ;(deleted ;AN011;) $IF NC ;IF THERE IS NO PROBLEM ;AN000;
2013 ;(deleted ;AN011;) ; THEN THIS DISKETTE HAS A VOL SER #
2016 LEA BX,DS:[DI].EXT_BOOT_BPB
;AN011;POINT TO BPB PORTION OF BOOT RECORD
2017 MOV AL,DS:[BX].EBPB_MEDIADESCRIPTOR
;AN011;GET TYPE OF MEDIA
2018 AND AL,0F0H ;AN011;SAVE LEFT NIBBLE ONLY
2019 CMP AL,0F0H ;AN011;IF DISKETTE HAS PROPER DESCRIPTOR
2022 MOV AL,DS:[DI].EXT_BOOT_SIG
;AN011;GET "SIGNATURE" OF BOOT RECORD
2023 CMP AL,28H
;AN011;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1?
2024 ; $IF E,OR ;AN011;YES, IS A BOOT WITH A SERIAL IN IT
2026 CMP AL,29H
;AN011;IS THIS A BOOT STYLE OF OS/S 1.2?
2027 ; $IF E ;AN011;YES, IS A BOOT WITH A SERIAL IN IT
2031 ;THE PURPOSE HERE IS TO CAUSE DISKCOMP TO IGNORE ANY DIFFERENCES IN THE
2032 ;VOL SERIAL NUMBER FIELD. THIS IS DONE BY TAKING ONE VOL SERIAL NUMBER
2033 ;FROM ONE BUFFER, ALREADY LOADED WITH THE FIRST TRACK OF ONE DISKETTE,
2034 ;AND MOVING THAT SERIAL NUMBER TO THE CORRESPONDING POSITION IN THE OTHER
2035 ;BUFFER, ALREADY LOADED WITH THE SIMILAR TRACK FROM THE OTHER DISKETTE.
2036 ;WHEN THIS RETURNS TO THE MAIN ROUTINE, THE ENTIRE TRACK (INCUDING THIS
2037 ;VOL SERIAL NUMBER FIELD) WILL BE COMPARED. IF THERE ARE ANY DIFFERENCES,
2038 ;THEY WILL BE OTHER THAN IN THE VOL SERIAL NUMBERS.
2040 MOV SI,OFFSET VOL_SERIAL
;GET WHERE VOL SERIAL NUMBER IS
2041 MOV DI,OFFSET VOL_SERIAL
;GET WHERE VOL SERIAL NUMBER IS
2042 MOV CX,TYPE VOL_SERIAL
;GET NUMBER BYTES IN VOL SER FIELD
2043 REP MOVSB ;FORCE THE SERIAL NUMBERS TO BE ALIKE
2052 POP CX ;RESTORE COUNT
2053 RET ;RETURN TO CALLER ;AN000;
2055 ; = = = = = = = = = = = = = = = = = = =
2056 DISKCOMP_END
LABEL BYTE
2057 PATHLABL DISKCOMP
;AN013;