|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 7808 (0x1e80)
Types: TextFile
Names: »FCOPY16.ASM«
└─⟦b445f10af⟧ Bits:30004389 CP/M Plus Source files
└─⟦this⟧ »FCOPY16.ASM«
title 'CR16 FCOPY UTILITY DATE:840401'
PAGE 43
;************************************************************************
;* *
;************************************************************************
MACLIB Z80
MACLIB PORTS
CVERS equ 10 ;version 1.0 for CP/M 3.0
;
maxcount equ 1 ;
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 'G'
jz getc
cpi 'H'
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 'G'
jz putc
cpi 'H'
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 (CR16 format) - 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»