DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦91d7e65e6⟧ TextFile

    Length: 7808 (0x1e80)
    Types: TextFile
    Names: »FCOPY3.ASM«

Derivation

└─⟦b445f10af⟧ Bits:30004389 CP/M Plus Source files
    └─ ⟦this⟧ »FCOPY3.ASM« 

TextFile


	title	'FCOPY UTILITY DATE:840401'
	PAGE 43

;************************************************************************
;*									*
;************************************************************************
	MACLIB	Z80

	MACLIB	PORTS

CVERS		equ	10	;version 1.0 for CP/M 3.0
;
maxcount	equ	2	;
max$trk		equ	154

SECSIZ	equ	512		;size of sector
;
TPA	equ	0100h		;Transient Program Area
LOADP	equ	1000h		;LOAD Point for system
BDOS	equ	05h		;DOS entry point

BOOT	equ	00h		;reboot for system
CONI	equ	1h		;console input function
CONO	equ	2h		;console output function
SELD	equ	14		;select a disk
RETDSK	equ	25		;return current disk
DRBIOS	equ	50		;Direct BIOS call function
EIGHTY	equ	080h		;value of 80
CTLC	equ	'C'-'@'		;ConTroL C
Y	equ	89		;ASCII value of Y
;
MAXTRY	equ	01		;maximum number of tries
STACKSIZE equ	016h		;size of local stack
;
WBOOT	equ	0		;address of warm boot
;
SELDSK	equ	9		;BIOS func #9 SELect DiSK
SETTRK	equ	10		;BIOS func #10 SET TRacK
SETSEC	equ	11		;BIOS func #11 SET SECtor
SETDMA	equ	12		;BIOS func #12 SET DMA address
READF	equ	13		;BIOS func #13 READ selected sector
WRITF	equ	14		;BIOS func #14 WRITe selected sector
utility	equ	30		;BIOS func #30 format / rd_trk / wr_trk

rd$track	equ	2
wr$track	equ	3
;*******************
;*
;*	MAIN ROUTINE
;*
;*******************
;
START:

	lxi	sp,STACK
	lxi	d,SIGNON
	call	OUTMSG
;
;get version number to check compatability
	mvi	c,12		;version check
	call	BDOS
	mov	a,l		;version in Acc
	cpi	30h		;version 3 or newer?
	jc	NOEXEC		;
start1:
	call	SOURCE		;find out source drive
	call	DESTIN		;get dest drive
	jmp	getsys

NOEXEC:	
	LXI	D,REQCPM3	;PRINT "REQUIRES CP/M PLUS"
	CALL	OUTMSG		;
	MVI	C,WBOOT		;
	JMP	BDOS		;


GETSYS:
;------
	lxi	h,0
	shld	track
trk$loop:
	xra	a		;zero out a
	sta	RW		;RW = 0 to signify read
	LDA	GDISK
	call	GETPUT		;get or read system

	lxi	h,RW		;load address
	mvi	m,1
	LDA	PDISK
	call	GETPUT		;to put system back on disk

	lhld	track
	lxi	d,maxcount
	dad	d
	shld	track
	mvi	a,maxtrk
	cmp	l
	jz	done$exit
	jmp	trk$loop


done$exit:
;------
	lxi	d,DONE
	call	crmsg		;print out end prompt
	lxi	d,copymsg
	call	crmsg		;
	call	getchar
	cpi	'Y'
	jz	start1

REBOOT:
	mvi	c,13
	call	BDOS
	call	CRLF
	jmp	BOOT


BADDISK:
	lxi	d,QDISK
	call	CRMSG
	ret


;========================================================================
; Utility subroutines							=
;========================================================================
BIOS:
	STA	BIOSFC		;DIRECT BIOS CALL 
	MVI	C,DRBIOS	;
	LXI	D,BIOSPB	;
	CALL	BDOS		;
	RET			;
;=========================================================================
GETCHAR:			; Read console character to rA
	mvi	c,CONI
	call	BDOS
				; Convert to upper case
	cpi	'A' or 20h
	rc
	cpi	('Z' or 20h)+1
	rnc
	ani	05Fh
	ret

;=============================================================================
PUTCHAR:			; Write character from rA to console
	mov	e,a
	mvi	c,CONO
	call	BDOS
	ret

;=============================================================================
CRLF:				; Send Carriage Return, Line Feed
	mvi	a,CR
	call	PUTCHAR
	mvi	a,LF
	call	PUTCHAR
	ret

;=============================================================================
CRMSG:				;Print message addressed by the HL
				; until zero with leading CRLF
	push	d
	call	CRLF
	pop	d		;drop through to OUTMSG
OUTMSG:
	mvi	c,9
	jmp	BDOS

;=============================================================================
SELCT:				; Select disk given by rE
	mvi	c,0Eh
	jmp	BDOS
;=============================================================================
SOURCE:
	lxi	d,GETPRM	;ask user for source drive
	call	CRMSG
	call	GETCHAR		;obtain response
	cpi	CR		;is it CR?
	jz	DFLTDR		;skip if CR only
	cpi	CTLC		;is it ^C?
	jz	REBOOT
;
	cpi	'A'
	jz	getc
	cpi	'B'
	jz	getc
;
; Invalid drive
	call	BADDISK		;tell user bad drive
	jmp	SOURCE		;try again
;
GETC:
; Select disk given by Acc.
	sta	GDISK		;store source disk
	jmp	GETVER
;
DFLTDR:
	mvi	c,25		;func 25 for current disk
	call	BDOS		;get curdsk
	adi	'A'
	sta	GDISK
	call	CRLF
	lxi	d,VERGET
	call	OUTMSG
	jmp	VERCR
;
GETVER:	
; Getsys set r/w to read and get the system
	call	CRLF
	lxi	d,VERGET	;verify source disk
	call	OUTMSG
VERCR:	call	GETCHAR
	cpi	CR
	jnz	REBOOT		;jmp only if not verified
	call	CRLF
	ret

;=============================================================================
DESTIN:
	lxi	d,PUTPRM	;address of message
	call	CRMSG		;print it
	call	GETCHAR		;get answer
	cpi	CR
	jz	REBOOT		;all done
	cpi	'A'
	jz	putc
	cpi	'B'
	jz	putc
;
; Invalid drive
	call	BADDISK		;tell user bad drive
	jmp	destin		;to try again

;
PUTC:
; Set disk from rA
	sta	PDISK		;message sent

; Put system, set r/w to write
	lxi	d,VERPUT	;verify dest prmpt
	call	CRMSG		;print it out
	call	GETCHAR		;retrieve answer
	cpi	CR	
	jnz	REBOOT		;exit to system if error
	call	CRLF
	ret
;
;------------------------------------------------
GETPUT:
; Get or put CP/M (rw = 0 for read, 1 for write)
; disk is already selected

	SUI	'A'
	MVI	D,0
	MOV	E,A
	CALL	SELCT		;SELECT DRIVE


	lxi	h,LOADP		;load point in RAM for DMA address
	shld	DMADDR
	lhld	track
	dcx	h
	shld	mtrack
	mvi	a,-1
	sta	count
RWTRK: 				; Read or write next track
	lda	count
	inr	a
	sta	count
	cpi	maxcount
	rz
	lhld	mtrack		;track no
	inx	h
	shld	mtrack
	SHLD	BCREG		;set up PB
	mvi	a,SETTRK	;settrk func #
	CALL	BIOS

	lhld	DMADDR		;base DMA
	SHLD	BCREG		;
	LXI	D,512*8		;
	DAD	D		;
	SHLD	DMADDR		;SAVE NEW ADDR
	MVI	A,SETDMA
	CALL	BIOS
	xra	a
	sta	RETRY		;to set zero retries
;
TRYSEC:
; Try to read or write current sector
	lda	RETRY
	cpi	MAXTRY
	jc	TRYOK
;
; Past MAXTRY, message and ignore
	lxi	d,ERRMSG
	call	OUTMSG
	call	GETCHAR
	cpi	CR
	jnz	REBOOT
;
; Typed a CR, ok to ignore
	call	CRLF
	jmp	rwtrk
;
TRYOK:
; ok to try read write
	inr	a
	sta	RETRY	
	lda	RW
	ora	a
	jz	TRYREAD
;
; Must be write
				; Perform write track operation
	lxi	h,wr$track
	shld	bcreg
	mvi	a,utility
	CALL	BIOS
	jmp	CHKRW

TRYREAD:			; Perform read track operation
	lxi	h,rd$track
	shld	bcreg
	mvi	a,utility
	CALL	BIOS
CHKRW:
	ora	a
	jz	RWtrk		;zero flag if read/write ok
;
;Error, retry operation
	jmp	TRYSEC
;
;
;****************************
;*
;*
;*	DATA STRUCTURES     
;*
;*
;****************************
;
BIOSPB:
; BIOS Parameter Block
BIOSFC:	db	0		;BIOS function number
AREG:	db	0		;A register contents
BCREG:	DW	0		;BC register contents
DEREG:	DW	0		;DE register contents
HLREG:	dw	0		;HL register contents
;
;
SDISK:	ds	1		;selected disk
BEGIN:	dw	0
DFLAG:	db	0
mtrack:	dw	0
track:	dw	0		;current track
count:	db	0
CRNREC:	db	0		;current rec count
SECTOR:	ds	1		;current sector
RW:	ds	1		;read if 0 write if 1
DMADDR:	ds	2		;current DMA address
RETRY:	ds	1		;number of tries on this sector

SIGNON:	db	'CP/M PLUS FCOPY  - Version '
	db	CVERS/10+'0','.',CVERS mod 10 +'0'
	db	'$'
GETPRM:	db	cr,lf,'Source drive name (or return for default) $'
VERGET:	db	'Source on '
GDISK:	ds	1
	db	' then type return $'
PUTPRM:	db	'Destination drive name (or return to reboot) $'
VERPUT:	db	'Destination on '
PDISK:	ds	1
	db	' then type return $'
COPYMSG:db	'Copy another (Y/N)? $'
DONE:	db	'Copy complete',cr,lf,'$'
;
; Error messages......
;
REQCPM3:db	'Requires CP/M PLUS.$'
qdisk:	db	'ERROR: Invalid drive name.$'
FSPACE:	db	'ERROR: Out of data space.$'
WRPROT:	db	'ERROR: Write protected?$'
ERRMSG: db	'ERROR: Possible incompatible disk format.'
	db	CR,LF,' Type return to ignore.$' 
;
	ds	STACKSIZE * 3
STACK:
	end
«eof»