
	.title	'Floppy Copy Program '
	.sbttl  'FDCOPY'
version	==	1 
revision==	5
	.pabs
	.phex
	.loc	100H		; beginning of TPA
	jmp	MAIN		; jump to MAIN 

; DMS DSC 3/4 Floppy Copy Utility.     D. Stein 8/80
; User selects single or double density.
; System(0-1), Data(2-76), or All tracks can be copied.
; Algorithm :
; 5 tracks are copied to destination disk; each track
; will be read back to memory one at a time to be verify
; buffer can only stored 6 tracks ;the first 5 tracks
; are the copied one and the 6th is used to store the
; track read back from destination to be verified.
; A separate sector table is maintained for single and
» doublå density.
; Program loops indefinitely until aborted by a ^C.

;------------------
;  Data and Address definitions
sourcedisk:
	.byte	0	; Source disk
destinationdisk:
	.byte	0	; Destination disk
curdsk:
	.byte	0	; current selected disk

home:	jmp	0	; BIOS addresses are filled in
seldsk:	jmp	0	;during the first part of the
settrk:	jmp	0	;MAIN  execution.
setsec:	jmp	0
setdma:	jmp	0
read:	jmp	0
write:	jmp	0
CPMmap:	jmp	0
setbyt:	jmp	0

bufferlocation:
	.word 	00	; current DMA location
tracknumber:
	.byte	0	; first track read or written
				; per set of 8
firsttrack:
	.byte 	0	; first track to copy
lasttrack:
	.byte	0	; last track to copy
curtrk:
	.byte	0	; current track for R/W
numsecs:
	.byte	0	; sectors per track (26 or 52)
secsONtrk:
	.byte	0	; num of secs on current track
tablstrt:
	.word	00	; start addr of sect tabl
tabladdr:
	.word	00	; current address in sect tabl

MAPbyt:	.byte	0	  ; Holds original MAPbyte
DENSbyt:.byte	0	  ; Holds BIOS density code
DDbyt	=	01000000b ; Double density BIOS code
SDbyt	=	00000000b ; Single density BIOS code
orgdriv:.byte  	0	  ; Current drive number

trackdisplay:
	.ascii	[cr]'Track ' 
trknum:	.ascii	'00h'
	.ascii	' copied'[cr]	; tracknumber display
	.ascii	'$'
base	=	0		; base address
bytepersec =	128		;
bufsize = 	bytepersec*52*6	; 6 trk of DD
trk0bytes =    	bytepersec*26	; # of bytes in track 0
lsttrkrd :	.byte 	0	; lastest track read
bufcomploc :	.word	0	; loc where verify start
tempbufloc :	.word	0	; temporary storage
nofcomp :	.word	0	; # of comp. needed

;------------------

MAIN:

;  Set up addresses for BIOS primitives

	lxi	sp,stack	; Fresh stack

	lhld	base + 1; get the WBOOT address
	mov	D,H
	mov	E,L

	lxi	H,15h	; get the home address
	dad	D
	shld	home +1	; jump loc for home

	lxi	H,18h	; get the seldsk addr
	dad	D	
	shld	seldsk + 1; jum loc for seldsk

	lxi	H,1Bh	; get the settrk addr
	dad	D
	shld	settrk + 1; jump loc for settrk

	lxi	H,1Eh	; get the setsec addr
	dad	D		
	shld	setsec + 1; jump loc for setsec

	lxi	H,21h	; get the setdma addr
	dad	D
	shld	setdma + 1; jump loc for setdma

	lxi	H,24h	; get the read addr
	dad	D	
	shld	read + 1; jump loc for read

	lxi	H,27h	; get the write addr
	dad	D
	shld	write + 1; jump loc for write

	lxi	H,60h	; get the CPMmap addr
	dad	D
	shld	CPMmap + 1; jump loc for CPMmap

	lxi	H,66h	; get the setbyt addr
	dad	D
	shld	setbyt + 1; jump loc for setbyt

;------------------
;  MAIN BODY
;
;
; What follows is a series of sequential routines.
; The subroutines used by these routines are:
;	sourcfind		Obtains source disk
;	destifind		Obtains destination
;	trackfind		Obtains first and last
;				track to copy.
;	getsec			Get next R/W sector 
;				from single or double
;				density sector table.
;	setdisk			Sets disk for next
;				read or write and
;				increments sector and
;				Dma address.
;	restart			Restart program
;	abort			Wboot
;	prtmsg			String output to crt
;	conin			Chr input from crt
;	stoMAPbyt		Save original MAPbyte
;	chaMAPbyt		Change MAPbyte
;	resMAPbyt		Restore original MAPbyt
;

;----------
;print initial messages 

	lxi	D,instr1; greeting
	call	prtmsg	; print

;save the users current MAPbyte

	call	stoMAPbyt	

; Get the source disk, destination disk, 
;density, and copy-info from the user.

getsource:
	call	sourcfind	; get the source
				; disk from user
	sta	sourcedisk	; and save it.

getdestination:
	call	destifind	; get the destination
				; disk from user
	sta	destinationdisk ; and save it.

getdensity:
	call	densfind	; get the density
				; from the user
	sta	DENSbyt		; Save dens code.
	mov	A,B	 	
	sta	numsecs     	; Save num of sectors
	shld	tablstrt	; Save sect tabl addr

gettrackinfo:	
	call	trackfind

	lxi	D,instr4	; ready message
	call	prtmsg		; print it

	call	conin

	cpi	2		; 2 is ^B
	jz	gettrackinfo	; backstep if ^B
 
	cpi	3		; 3 is ^C
	jz	abort		; abort if ^C

;check for ambiguous drive selections

	lda	sourcedisk
	lxi	H,destinationdisk
	cmp	M		; Are source and dest
				; disks identical?
	jrnz	..start		; No. Start copying
	lxi	D,error4	; Yes. Print err msg
	call	prtmsg
	jmp	getsource	; and start over.


..start:
;home the disks
	lda 	destinationdisk
	call	chaMAPbyt	; Select dest disk
	call	HOME		; and home it.
	lda	sourcedisk
	call	chaMAPbyt	; Select source disk
	call	HOME		; and home it.
;get ready to read from the source disk
	lxi	D,instr2
	call	prtmsg	       ; skip a line
	lda	firsttrack
	sta	tracknumber    ; start at appr. track
	sta	curtrk	       ;transcient track number

	call	getnoofcomp	;
;------------------
;------------------
; READ / WRITE LOOP
;------------------
;------------------

READ5:
	lda	sourcedisk	; get source disk
	call	chaMAPbyt	; and select it.

	lhld	bufbegin
	shld	bufferlocation	; for dma addressing

	lda	curtrk
	sta	tracknumber	; keep for check
	cpi	0		; trk0? if not, then go
	jrnz	..rdtrack	; read sect. by sect.
	call	setrk0		; set trk0 ready to
	call	read		; be read
	lxi	b,bytepersec	; reset # of bytes to
	call	setbyt		; 128 for next i/o
	lded	bufferlocation	; increment buffer addr
	lxi	h,trk0bytes	; by the # of bytes in
	dad	d		; track 0
	shld	bufferlocation	;
	jmpr	..next		; next track
..rdtrack:
	call	readtrack	; read one track
	
;test for lasttrack
	lda	curtrk
	lxi	H,lasttrack
	cmp	M		; read last track yet?
	jz	WRRDCP		; write last set
;increment current tracknumber
..next:	lxi	H,curtrk
	inr	M
;test for 5 tracks read
	lda	curtrk
	sta	lsttrkrd	; highest track # read
	lxi	H,tracknumber	; track we started on
	sub	M
	cpi	5		; six tracks read?
	jz	WRRDCP		; write and verify

	jmp	..rdtrack	; read next track
;------------------
; 5 TRACKS HAVE BEEN READ, WRITE AND VERIFY 5 TRACKS
;------------------
WRRDCP:
write1:
	lda	destinationdisk	; get destin. disk
	call	chaMAPbyt	; and select it.

	lhld	bufbegin	; get buffer address
	shld	bufferlocation	; save for dma
	shld	bufcomploc	; add where verify start

	lda	tracknumber
	sta	curtrk		; 1st of 5 tracks
	cpi	0		; is it trk0 ?
	jrnz	writetrack	; if not, regular write
	call	setrk0		; else set trk0
	call 	write		; go write it
	lxi	b,bytepersec	; reset # of bytes to 
	call 	setbyt		; 128 for next i/o
	lded	bufferlocation	;
	lxi	h,trk0bytes	; increment buffer by
	dad	d		; # of bytes inn trk0
	shld	bufferlocation	;
	jmpr	read1		; go read back & verify

writetrack:
	call	setdisk		; set up disk for read

	lda	secsONtrk	; get num of sec on
	mov	B,A		; this track in B.
..1:	push	B

	call	getsec		; Get next sector
	mov	C,A		
	call	setsec		; and select it.

	lbcd	bufferlocation	
	call	setdma		; Set DMA

	call	write		; write one sector

;increment buffer
	lded	bufferlocation
	lxi	H,128		; bytes per sector
	dad	D		; increment buffer to
	shld	bufferlocation	; write the next track

	pop	B
	djnz	..1		; Do all sectors
	shld	tempbufloc	; save it

; read back track just copied and verify it
read1:
	lda	curtrk		; if trk0 then read
	cpi	0		; whole track. if not
	jrnz	..rd1		; read 1 sect. at a time
	mvi	c,1		; first sector
	call	setsec		; set it for read
	lxi	b,buf6		; buffer loc. to store
	call	setdma		; trk to be verified
	lxi	b,trk0bytes	; # of bytes in trk0
	call 	setbyt		; 
	call	read		;
	lxi	b,bytepersec	; reset # of bytes to
	call 	setbyt		; 128 for next i/o
	jmp	verify		; go verify track copied

..rd1:	lxi	h,buf6		; parameter passing to
	shld	bufferlocation	; subroutine readtrack
	call  	readtrack	; read one track
	lhld	tempbufloc	; restore init. value
	shld	bufferlocation	; of bufferlocation
	jmp	verify		; go verify 

; Now we display the track number we just copied

print:	lda	curtrk
	mov	C,A		; save for low bit
	rrc
	rrc
	rrc
	rrc
	ani	0Fh
	adi	30h
	cpi	3Ah
	jc	lsd
	adi	'A'-':'
lsd:	sta	trknum		; for display
	mov	A,C
	ani	0Fh
	adi	30h
	cpi	3Ah		; 10 or greater?
	jc	msd		; skip if not
	adi	'A'-':'
msd:	sta	trknum + 1
	lxi	D,trackdisplay	; load message
	call	prtmsg		; print it

	ret

;------------------
;------------------
; END OF R/W LOOP
;------------------
;------------------

; Successful disk copy has been made.  Loop back.
restart:
	lxi	D,instr7	; job completed msg
	call	prtmsg		; print msg
	lxi	D,crlflf
	call	prtmsg		; Double line feed
	jmp	getsource	; and start over.

	
; END OF MAIN BODY

;------------------
;------------------
;  SUBROUTINES
;------------------
;------------------

;  DISK I/O SUBROUTINES

;----------
; Subroutine:	setrk0
; Regs in:	a = curtrk
; Regs out:	none
; destroyed:	a,bc
;
setrk0:	mov	c,a		; argument for settrk
	call	settrk		;
	mvi	c,1		; arg for setsec
	call	setsec		; set first sector
	lxi	b,trk0bytes	; # of bytes read
	call	setbyt		;
	lbcd	bufferlocation	; dma addr.
	call	setdma		;

	ret			;

;----------
; Subroutine readtrack
; Regs in:	none
; Regs out:	none
; Destroyed:	all
readtrack:
	call	setdisk		; set up disk for read

	lda	secsONtrk	; Get the num of secs
	mov	B,A		; on this track in B.
..1:	push	B		; Use it as a counter.

	call	getsec
	mov	C,A
	call	setsec

	lbcd	bufferlocation	
	call	setdma

	call	read		; read one sector

;increment buffer
	lded	bufferlocation
	lxi	H,128		; bytes per sector 
	dad	D		; increment the buffer
	shld	bufferlocation	; to read the next track

	pop	B		; Restore the counter
	djnz	..1		; Do all sectors


;----------
; Subroutine: 	setdisk
; Regs  in:	none
; Regs out:	none
; Select next track.
; Set number of sectors on track.
; Reset sector table address.
; Abort if ^C is received from the console.
setdisk:

	lda	curtrk
	mov	C,A		; get current track
	call	settrk		; and select it

	lda	numsecs
	sta	secsONtrk	; # of sect on track
	lhld	tablstrt	; Get sect tabl addr
	shld	tabladdr	; to start the start

	mvi	C,0Bh		; CPM constat function
	call	05		; bdos
	ora	A		; Reset carry flag.
	rrc			; Set carry if console
				; chr is ready.
	rnc			; Return. No chr ready.
  	call	conin		; Read con chr
	cpi	3		; 3 is ^C
	jz	abort		; abort if ^C
	ret			; otherwise return


;  CRT I/O SUBOUTINES

;  		Subroutine:  prtmsg  
; This subroutine sends string output to the crt.
;
prtmsg:	
	mvi	C,9	; console output
	call	05	; bdos
	ret			


;----------
;  		Subroutine:  conin
; This subroutine gets character input from the crt.
;
conin:		
	mvi	C,1	; console input
	call	05	; bdos
	ret


;----------
;  		Subroutine:  sourcfind
; Regs  in:	none
; Regs out:	A = source drive ( 0 to 7)
; This subroutine gets the source disk location
; from the operator. (0-7)
; Uses these other subroutines: prtmsg, conin
;
sourcfind:
	lxi	D,query1	; load source query
	call	prtmsg		; print to crt

	call	conin		; get char from crt
				; returned in reg A
; A = chr input from console.
	cpi	3		; 3 is ^C
	jz	abort		; abort if ^C

	cpi	2		; 2 is ^B
	jz	main		; backstep if ^B

	sui	'0'		; Make ascii chr numer
	cpi	08		; Out of range?
	jrnc	..0		; Yes. Ask again.
	ret			; No. Return.

;   If all tests are failed, then an error message #2
;   is generated, and sourcfind is restarted.

..0:	lxi	D,error2
	call	prtmsg		; print err message
	jmp	getsource	; start this over


;----------
;  		Subroutine:	desti<nation>find   
; Regs  in:	none
; Regs out:	destination drive number (0 to 7)
; This subroutine gets the destination disk
; location from the operator. (0-7)
; Uses these other subroutines:
;
destifind:

	lxi	D,query2	; load destin mess.
	call	prtmsg		; print message
	call	conin		; get char. input
; A = chr input from console.
	cpi	2		; 2 is ^B
	jz	getsource	; backstep if ^B

	cpi	3		; 3 is ^C
	jz	abort		; abort if ^C
		
	sui	'0'		; Make ascii numeric
	cpi	08		; Out of range?
	jrnc	..1		; Yes. Ask again.
	ret			; No. Return.

;    If all tests are failed, then an error message #2
;    is generated, and destifind is restarted.

..1:	lxi	D,error2
	call	prtmsg		; print err mess.
	jmp	getdestination  ; and try again.

;----------
;		Subroutine:  trackfind
; Regs  in:	none
; Regs out:	none
;  This subroutine queries the user as to what tracks
; should be copied.  
; The choices are:
;	S	System		tracks 0 and 1
;	D	Data		tracks 2 to 76
;	A	All		tracks 0 to 76
;
trackfind:

	lxi	D,query4	; get copy message
	call	prtmsg		; print message

	call	conin		; get char from crt
				; returned in reg A
; A = chr input from console
	ani	0DFh		; Make it UPPER CASE

	cpi	'S'
	jrz	..sys

	cpi	'D'
	jrz	..data

	cpi	'A'
	jrz	..all

	cpi	2		; 2 is ^B
	jz	getdensity	; backstep if ^B

	cpi	3		; 3 is ^C
	jz	abort		; abort if ^C

;    If all tests are failed, then an error message #5
;    is generated, and trackfind is restarted.

	lxi	D,error5	; load err mess.
	call	prtmsg		; print err mess.
	jmp	gettrackinfo	; start this over

; Tracks used for copying only the operating system.
..sys:	mvi	A,0
	sta	firsttrack
	mvi	A,1
	sta	lasttrack
	ret			; return if System

; Tracks used for only copying the disk data.
..data:	mvi	A,2
	sta	firsttrack
	mvi	A,76
	sta	lasttrack
	ret			; return if Data

; Tracks used for copying all tracks.
..all:	mvi	A,0
	sta	firsttrack
	mvi	A,76
	sta	lasttrack
	ret			; return if All

;----------
; Subroutine: 	densfind
; Regs  in:	none
; Regs out:	A = BIOS density code
;		B = sectors on each track (26 or 52)
;		HL= Appropriate sector table address
; Get the density from the user.
densfind:
	lxi	D,instr3	; load dens question
	call	prtmsg		; and print it.
	call	conin		; Get chr from console
; A = ascii chr input from console
	cpi	3		; 3 is ^C
	jz	abort		; abort if ^C

	cpi	2		; 2 is ^B
	jz	destifind	; backstep if ^B

; Make ascii chr upper case and test.
	ani	0DFh		; Make it UPPER CASE

	cpi	'S'		; S is single density
	mvi	C,SDbyt		; load sing dens code
	mvi	B,26 		; load bytes per sector
	lxi	H,SDscttbl	; load SD table address
	jrz	..rtn		; return if S

	cpi	'D'		; D is double density
	mvi	C,DDbyt		; load doub dens code
	mvi	B,52 		; load bytes per sector
	lxi	H,DDscttbl	; load SD table address
	jrz	..rtn		; return if D

; Incorrect entry has been made. Ask again.
	lxi	D,error3	; Load dens err msg
	call	prtmsg
	jmpr	densfind	; and ask again.

; Valid entry. Numsecs is in B. Put dens code in A.
..rtn:	mov	A,C		; get dens code in A
				; num of secs is in B
	ret

;----------
;Subroutine:	stoMAPbyt
; Regs  in:	none
; Regs out:	none
;Destroyed:	any and/or all registers

; Save the current assignment for restoration.
stoMAPbyt:
	call	CPMmap	; get current assignment
; BIOS address of the byte returns in HL
	sta	MAPbyt	; save it for later restoration
	ret		; and return.

;----------
;Subroutine:	chaMAPbyt
; Regs  in:	A = unit number to assign to
; Regs out:	none
;Destroyed:	any and/or all registers

; Change the assignment to that of a floppy disk
; on the unit number received in the accumulator.
chaMAPbyt:
	push	PSW	; Save unit number
	call	CPMmap	; get current MAPbyte byte addr
; Current unit 0 assignment (network,etc) returns in A
; BIOS address of the byte returns in HL
	pop	B	  ; Restore unit number in B
	lda	DENSbyt	  ; Get floppy density code
	ora	B	  ; A = A <or> B = New MAPbyte
	mov	M,A	  ; Store it in the BIOS
	ret

;----------
;Subroutine:  resMAPbyt
; Regs  in:	none
; Regs out:	none
;Destroyed:	any and/or all registers

; Restore the original disk assignment
resMAPbyt:
	call	CPMmap	; get BIOSmap addr
;Current unit assignment returns in A
;BIOS address of the byte returns in HL
	lda	MAPbyt	; original assignment
	mov	M,A	; restore previous assignment
	ret		; and return.


;----------
; 	Subroutine: abort
; This subroutine loads the abort message, prints it,
; then warm boots.
;
abort:
	call	resMAPbyt	; restore org assmt	
	lxi	D,instr9	; load abort mess.
	call	prtmsg		; print mess.
	jmp	base		; wboot

;----------
; Subroutine:	getsec
; Regs  in:	none
; Regs out:	A = next sector in sector table
; Destroyed:	HL
; Get the next sector from the sector table.
; Increment to next addr in tab
getsec:
	lhld	tabladdr	; get spot in sect tabl
	mov	A,M		; get sector value
	cpi	0FFh		; End of table?
	jrz	..termerr	; Yes. abort.
	inx	H		; get to next table addr
	shld	tabladdr	; and save it.
	ret

..termerr:
	lxi	D,error1	; Print sector fall-
	call	prtmsg		; thru message.
	jmp	abort		; Fatal error. Abort.

VERIFY: 
	lda	curtrk		;
	lxi	h,lasttrack	;
	cmp	m		;
	jz	theend		; end of copy
	cpi	0		; is it track 0 ?
	jrnz	..vf1		;
	lxi	h,trk0bytes	; # of comp for trk0
	shld	noofcomp	;
	jmpr	..vf3		;
..vf1:	lhld	nofcomp		; # of comp for 
	shld	noofcomp	; other tracks
..vf3:	call	compare		; go verify copied trk
	lxi	h,tracknumber	; have we write and
	inr	m		; verify the 5 tracks
	lda	lsttrkrd	; read ? if so, go 
	sub	m		; read another 5 trks
	jz	..vf2		; and repeat same thing
	lda	tracknumber	; else keep copying and
	sta	curtrk		; verifying
	lhld	bufferlocation	; reset next loc in buf
	shld	bufcomploc	; where verify start
	jmp	writetrack	;

..vf2:	mov	a,m		;
	sta	curtrk		; update current track
	jmp	read5		; read another 5 trks

;----------
; this subroutine compare the track just copied with
; the same track read back out to location buf6
; regs in: none		regs out: none
; destroyed: all
compare:
	lxi	d,0		; initialize counter
	sded	compcounter	; save it
	lhld	bufcomploc	; where trk from source
	push	h		; is stored; save it
	lxi	b,buf6		; where dest. track is

..comp1:pop	h		; get one byte
	mov	d,m		; from source
	ldax	b		; get one byte from dest
	cmp	d		; compare the two bytes
	jrnz	badcopy		; copy error!!
	inx	h		; else get next byte 
	inx 	b		; from source & dest.
	push	h		; 
	lded	compcounter	; get current count
	inx	d		; increment it
	sded	compcounter	; save it
	lhld	noofcomp	; max # of comp. needed
	ora	a		; clear carry bit
	dsbc	d		; done? if not,
	jrnz	..comp1		; keep comparing
	pop	h		; pop junk
	call	print 		; print track copied
	ret			; else return to caller
 
; end of copy subroutine
; regs in = none
; regs out = none
; destroyed = all

theend:	lhld	nofcomp		; # of comp. needed
	shld	noofcomp	;
	call 	compare		;
	jmp	restart		; restart copy prog.

; this subroutine finds the # of comp. needed for
; each track ; i.e single density only need 128*26
; comparisons.
; regs in : none
; regs out : none
; destroyed : hl,bc
getnoofcomp:
	lxi	h,numsecs	; # of sectors per track
	mov	a,m		; is it single density ?
	cpi	26		; if not, goto double
	jrnz	..52sectors	; density routine
	lxi	d,trk0bytes	; get # of comparisons
	sded	nofcomp		; save it
	ret
..52sectors:
	lxi	d,52*bytepersec	; # of comp. for DD disk
	sded	nofcomp		; save it
	ret
BADCOPY:
	call	print		; print bad track 
	lxi	d,error6	; print 
	call	prtmsg		; copy error message
	lxi	d,crlflf	;
	call	prtmsg		;
	jmp	getsource	; retry again
;---------
;Staggered sector tables for optimized Reads/Writes

DDscttbl:	; Double Density staggered sector table
	.byte 01,02,33,34,13,14,45,46,25,26,05,06,37,38
	.byte 17,18,49,50,29,30,09,10,41,42,21,22,11,12
	.byte 43,44,23,24,03,04,35,36,15,16,47,48,27,28
	.byte 07,08,39,40,19,20,51,52,31,32,0FFh

SDscttbl:	; Single Density staggered sector table
	.byte 01,03,05,07,09,11,13,15,17,19,21,23,25,02
	.byte 04,06,08,10,12,14,16,18,20,22,24,26,0FFh

;------------------
;  Messages to the operator

cr	=	0Dh
lf	=	0Ah
instr1:	.ascii	[cr][lf]'Floppy Copy Program '
	.byte	version+'0','.'
	.byte	revision/10+'0',revision@10+'0'
instr2:	.ascii	[cr][lf]'$'
instr3:	.ascii	[cr][lf]'Density? (S/D) $'
instr4:	.ascii	[cr][lf]'Hit return when ready$'
instr7:	.ascii	[cr][lf]'**  JOB COMPLETED  **$'
instr8:	.ascii	[cr][lf]'**  JOB TERMINATED  **$'
instr9:	.ascii	[cr][lf]'**  JOB ABORTED **$'

vermsg1:.ascii  [cr][lf]'**  VERIFICATION DONE **$'

query1:	.ascii	[cr][lf]'Source disk (0-7) :$'
query2:	.ascii	[cr][lf]'Destination disk (0-7) :$'
query4:	.ascii	[cr][lf]'COPY: System tracks, Data'
	.ascii	' tracks, or '
	.ascii	[cr][lf]'      All tracks? '
	.ascii	' (S,D, or A)? $'

error1:	.ascii	[cr][lf]'FELL THROUGH SECTOR TABLE$'
error2:	.ascii	[cr][lf]'IMPROPER DISK SELECTION$'
error3:	.ascii	[cr][lf]'IMPROPER DENSITY SELECTION$'
error4:	.ascii	[cr][lf]'SAME SOURCE AND DESTINATION$'
error5: .ascii	[cr][lf]'IMPROPER COPY COMMAND$'
error6: .ascii  [cr][lf]'** BAD TRACK HERE !!! retry--$'

crlflf:	.ascii	[cr][lf][lf]'$'
;----------
; Stack room
	.blkb	40
stack:

;----------
; 6 track disk I/O buffer
bufbegin : .word 2000
compcounter : .word 0		; counter for # of comp.
noofcomp : .word 0		; # of comp. (sd or dd)
buf6 == 2000 + 128*52*5
bufend == 2000 + 128*52*6

.end
