mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-29 17:15:47 +00:00
287 lines
6.5 KiB
NASM
287 lines
6.5 KiB
NASM
TITLE DISKCOPY MSDOS Disk Copier
|
||
;----------------------------------------------------------
|
||
;
|
||
; Diskcopy - Program to copy entire diskettes
|
||
;
|
||
; Copyright 1982 by Microsoft Corporation
|
||
; Written by Chris Peters, August 1982
|
||
;
|
||
;-----------------------------------------------------------
|
||
;
|
||
; Rev 1.00 Initial instance
|
||
; Rev 1.20
|
||
; Read in > 64K hunks
|
||
|
||
FALSE EQU 0
|
||
TRUE EQU NOT FALSE
|
||
|
||
|
||
bdos equ 21h
|
||
boot equ 20h
|
||
aread equ 25h
|
||
awrite equ 26h
|
||
|
||
INCLUDE DOSSYM.ASM
|
||
|
||
fcb equ 5ch
|
||
|
||
CODE SEGMENT PUBLIC
|
||
CODE ENDS
|
||
|
||
CONST SEGMENT PUBLIC BYTE
|
||
CONST ENDS
|
||
|
||
DATA SEGMENT PUBLIC BYTE
|
||
DATA ENDS
|
||
|
||
DG GROUP CODE,CONST,DATA
|
||
|
||
CODE segment PUBLIC
|
||
assume cs:DG,ds:DG,es:DG,ss:DG
|
||
|
||
EXTRN dskrd:NEAR,dskwrt:NEAR,promptyn:NEAR
|
||
PUBLIC PRINT,PCRLF,ASKANOTHER,sec64k,secsiz
|
||
|
||
org 100h
|
||
|
||
diskcopy:
|
||
jmp disk_entry
|
||
|
||
HEADER DB "Vers 1.20"
|
||
|
||
source db 0
|
||
dest db 0
|
||
count dw 0
|
||
start dw 0
|
||
secsiz dw 0
|
||
passcnt dw 0
|
||
sec64k dw 0
|
||
media db 0
|
||
buffer dw 0
|
||
bufsiz dw 0
|
||
|
||
pcrlf: mov dx,OFFSET DG: crlf
|
||
print: mov ah,STD_CON_STRING_OUTPUT
|
||
int bdos
|
||
pret: ret
|
||
|
||
getkey: mov dx,OFFSET DG: keymsg
|
||
call print
|
||
mov ah,12 ;wait for key press
|
||
mov al,1
|
||
int 21h
|
||
ret
|
||
;
|
||
; returns number of sectors on the disk in cx, sector size in ax
|
||
;
|
||
getdpb: push ds
|
||
inc dl
|
||
mov ah,GET_DPB
|
||
int bdos
|
||
mov al,[bx+dpb_cluster_mask]
|
||
cbw
|
||
inc ax
|
||
mov cx,[bx+dpb_max_cluster]
|
||
dec cx
|
||
mul cx
|
||
add ax,[bx+dpb_first_sector]
|
||
mov cx,[bx+dpb_sector_size]
|
||
mov bl,[bx+dpb_media]
|
||
pop ds
|
||
ret
|
||
|
||
getdrv: mov al,[bx]
|
||
dec al
|
||
cmp al,-1
|
||
jnz get1
|
||
mov ah,19h
|
||
int 21h
|
||
get1: ret
|
||
;
|
||
; set zero flag if drives the same
|
||
;
|
||
compare:push ax
|
||
mov al,[dest]
|
||
cmp al,[source]
|
||
pop ax
|
||
ret
|
||
|
||
printerr:
|
||
call print
|
||
int boot
|
||
|
||
disk_entry:
|
||
cli ;set up local stack
|
||
mov sp,100h
|
||
sti
|
||
|
||
|
||
;Code to print header
|
||
; PUSH AX
|
||
; MOV DX,OFFSET DG: HEADER
|
||
; CALL print
|
||
; POP AX
|
||
|
||
mov dx,OFFSET DG: drverr1
|
||
inc al
|
||
jz printerr
|
||
inc ah
|
||
jz printerr
|
||
|
||
mov bx,fcb
|
||
call getdrv
|
||
mov [source],al
|
||
add [srclet],al
|
||
mov bx,fcb+16
|
||
call getdrv
|
||
mov [dest],al
|
||
add [dstlet],al
|
||
add [fdstlet],al
|
||
mov ah,DISK_RESET
|
||
int bdos ;empty buffer queue
|
||
|
||
mov bx,OFFSET DG:progsiz + 15
|
||
shr bx,1
|
||
shr bx,1
|
||
shr bx,1
|
||
shr bx,1
|
||
mov ah,setblock
|
||
int 21h ;give back extra memory
|
||
|
||
mov bx,0FFFFh ;ask for Biggest hunk
|
||
mov ah,alloc
|
||
int 21h
|
||
jnc gotmem
|
||
mov ah,alloc
|
||
int 21h
|
||
gotmem:
|
||
mov [buffer],ax
|
||
mov [bufsiz],bx
|
||
|
||
copyagn:
|
||
mov [start],0 ;Initialize start sector
|
||
call compare
|
||
jz onedrv1
|
||
mov dx,OFFSET DG: srcmsg
|
||
call print
|
||
onedrv1:mov dx,OFFSET DG: fdstmsg
|
||
call print
|
||
call getkey
|
||
|
||
mov dl,[dest]
|
||
call getdpb
|
||
mov [count],ax
|
||
mov [secsiz],cx
|
||
mov [media],bl
|
||
|
||
call compare
|
||
jnz twodrv1
|
||
mov dx,OFFSET DG: srcmsg
|
||
call print
|
||
call getkey
|
||
|
||
twodrv1:mov dl,[source]
|
||
call getdpb
|
||
mov dx,OFFSET DG: drverr3
|
||
cmp [media],bl ;make sure media and sizes match
|
||
jnz errv
|
||
cmp [count],ax
|
||
jz sizeok
|
||
errv: jmp printerr
|
||
|
||
sizeok:
|
||
mov bx,[secsiz]
|
||
add bx,15
|
||
mov cl,4
|
||
shr bx,cl
|
||
xor dx,dx
|
||
mov ax,1000H
|
||
div bx
|
||
mov [sec64k],ax ;set number of sectors in 64K bytes
|
||
xor dx,dx
|
||
mov ax,[bufsiz]
|
||
div bx
|
||
mov [passcnt],ax ;set number of sectors per pass
|
||
|
||
call compare ;print copying....
|
||
jz loop
|
||
mov dx,OFFSET DG: cpymsg
|
||
call print
|
||
|
||
loop: push ds
|
||
|
||
mov al,[source]
|
||
xor bx,bx
|
||
mov cx,[passcnt]
|
||
cmp cx,[count]
|
||
jbe countok
|
||
mov cx,[count]
|
||
countok:mov dx,[start]
|
||
mov ds,[buffer]
|
||
call dskrd
|
||
pop ds
|
||
|
||
push ds
|
||
push cx
|
||
|
||
call compare
|
||
jnz twodrv2
|
||
mov dx,OFFSET DG: dstmsg
|
||
call print
|
||
call getkey
|
||
|
||
twodrv2:mov al,[dest]
|
||
xor bx,bx
|
||
mov dx,[start]
|
||
mov ds,[buffer]
|
||
call dskwrt
|
||
pop cx
|
||
pop ds
|
||
|
||
add [start],cx
|
||
sub [count],cx
|
||
jbe quitcopy
|
||
|
||
call compare
|
||
jnz loop
|
||
mov dx,OFFSET DG: srcmsg
|
||
call print
|
||
call getkey
|
||
jmp loop
|
||
|
||
quitcopy:
|
||
mov ah,DISK_RESET
|
||
int bdos ;empty buffer queue
|
||
mov dx,OFFSET DG: goodmsg
|
||
call compare
|
||
jnz twodrv3
|
||
mov dx,OFFSET DG: good1
|
||
|
||
ASKANOTHER:
|
||
twodrv3:call print
|
||
mov dx,OFFSET DG:anoprompt
|
||
call promptyn
|
||
jnz alldone
|
||
jmp copyagn
|
||
alldone:
|
||
int boot ;home, james...
|
||
|
||
CODE ENDS
|
||
|
||
CONST SEGMENT PUBLIC BYTE
|
||
|
||
EXTRN fdstmsg:BYTE,dstmsg:BYTE,fdstlet:BYTE,dstlet:BYTE
|
||
EXTRN cpymsg:BYTE,good1:BYTE,goodmsg:BYTE,srcmsg:BYTE,srclet:BYTE
|
||
EXTRN keymsg:BYTE,drverr1:BYTE,drverr3:BYTE,crlf:BYTE
|
||
EXTRN anoprompt:BYTE
|
||
|
||
db ' MICROSOFT - PETERS '
|
||
CONST ENDS
|
||
|
||
DATA SEGMENT BYTE
|
||
|
||
progsiz LABEL BYTE
|
||
|
||
DATA ends
|
||
end diskcopy
|
||
|