;BACKUP3/ASM - Backup By Class ; ; Find highest available memory page ; LD HL,0 ;Set up to get HIGH$ LD B,L @@HIGH$ INC HL ;Find highest available DEC H ; memory page LD A,H LD (DOFIL06+1),A ;Save for later testing LD (DOFIL08+1),A LD (LSTBUF1+1),A LD A,0C9H LD (PMTDST1),A ;Ignore dest disk test CALL PMTDST ;Prompt dest drive ; ; Calculate mamximum free space per dest disk type ; LD A,(IY+7) ;P/u # heads & sect/trk LD B,A ;Save heads AND 1FH ;Mask all but sectors LD C,A INC C ;Adj for zero offset XOR B ;Get # of heads RLCA RLCA ; in bits 0-2 RLCA INC A ;Adj to 0 offset LD B,A ;Init loop counter XOR A ;Init sector count to 0 ADD A,C ;Multiply # sectors/track DJNZ $-1 ; x # of heads/cyl LD L,A LD H,0 ;Xfer to 16-bit reg JR NC,NMXSEC ;Go if not 256 sect INC H ; else set to 256 NMXSEC BIT 5,(IY+4) ;If 2-sided diskette JR Z,$+3 ADD HL,HL ; double the # of sectors LD C,(IY+6) ;P/u # cyls & adjust for DEC C ; BOOT & DIR @@MUL16 ;Calc total records LD H,L ;Results to HL LD L,A LD (SIZSAV+1),HL ;Save for later ; ; Read the BOOT sector of dest disk ; LD DE,1 ;Track 0, sector 1 LD HL,BUF2$ ;Disk buffer area CALL RDSEC ;Read the sector JP NZ,EXIT3 ;Quit on read error LD A,(BOOTST$) ;Locn of boot step rate LD L,A LD A,(HL) ;Get the step rate in AND 3 ; bits 0 and 1 LD (BSCLS+1),A ;Save for later LD A,(BUF2$+2) ;P/u dir cyl LD (IY+9),A ;Stuff into DCT ; ; Check id type byte ; CALL CKSWDD ; ; If a system backup, then check the GAT & HIT ; LD A,(PRMTBL$+SYSRSP) OR A ;P/u SYS parm response JP Z,CLSBU5 ; and skip next if not SYS ; ; If already a SYSTEM disk, don't check BOOT space ; IF @MOD2 CALL PMTDST ;Get dest data ; LD A,(IY+3) ;Get DCT data AND 28H ;Bit 5/3 CP 20H ;8" floppy? JR NZ,SETSYS2 ;Go if not LD A,(IY+4) ;Get data AND 50H ;Bit 6/4 CP 40H ;DD not alien? SETSYS2 LD D,0 ;Cyl 0 if not JR NZ,$+3 ;Go if system INC D ;Sysinfo on cyl 1 ENDIF ; LD HL,HITBUF ;Set disk buffer LD E,2 ; and sector 2 ; ; Mod II save sysinfo sector for later check ; IF @MOD2 LD (CKPROT2),DE ;Save cyl/sect ENDIF ; IF @MOD4 CALL RDSEC ;Read the sysinfo sector JP NZ,EXIT3 ;QUit on read error LD A,(HITBUF+0C0H) ;P/u & test the SYSTEM INC A ; disk byte. If already LD D,(IY+9) JP Z,CLSBU01 ; a system disk, bypass ENDIF ; IF @MOD2 ; LD D,(IY+9) ;P/u dir cyl ; ENDIF ; LD E,L ;Set sector 0, dir trk CALL RDSEC ;Read the GAT CP 6 ;Expect error 6 LD A,20 ;Init "GAT read error JP NZ,EXIT3 ;Quit on any other error ; IF @MOD4 LD B,0 ;Need no more BIT 3,(IY+3) ; if rigid drive JR NZ,SETSYS ;NZ = rigid ENDIF ; ; Check GAT byte on Mod2/12 IF @MOD2 LD L,0CDH BIT 7,(HL) LD L,0 JP Z,CLSBU01 ;Go if system disk ENDIF ; ; If ALIEN or NOT 8" space is OK ; IF @MOD2 LD A,(CKPROT2+1) OR A JR Z,SETSYS ;Go if not ENDIF ; ; Mod II must have track 0 fully available ; IF @MOD2 LD A,(HITBUF+60H) ;Track 0 lockout data OR 1 ;Boot/sys allocation CP (HL) ;Anything here? JP NZ,NOTSYS ;Yes, cannot use! ENDIF ; ; Mod II must have 16 sectors available on cyl 1 ; IF @MOD2 INC HL ;Point to cyl 1 LD B,3 ;2 grans SD or DD ENDIF ; ; Check to be sure additional grans needed for boot ; are not already allocated ; IF @MOD4 LD B,2 ;If 8" SDEN or DDEN, then ENDIF ; BIT 5,(IY+3) ; need gran 1 JR NZ,$+4 LD B,6 ;5" needs grans 1 & 2 LD A,(HL) ;P/u GAT byte for BOOT AND B ; & ck for needed space JR NZ,NOTSYS ;Go if no free space LD A,(HL) ;Reserve the GAT space OR B LD (HL),A ; ; Mod II must make force locked/used cyl 0 ; IF @MOD2 LD A,-1 ;Init LD L,0 ;Reset to beginning LD (HL),A ;Allocate cyl 0 LD L,60H ;Lockout table LD (HL),A ;Lockout cyl 0 ENDIF ; ; ; Mask the config byte "data/system" disk bit ; SETSYS LD L,0CDH ;Point to config byte RES 7,(HL) ; & show system disk CALL WRGAT ; ; Adjust the allocation info for BOOT/SYS ; CLSBU0 LD E,2 ;Read the directory CALL RDSEC ; sector containing CP 6 ; BOOT/SYS record LD A,17 ;Init "dir read error JP NZ,EXIT3 INC B ;Code to 7 3 1 INC B ;Code to 8 4 2 SRA B ;Code to 4 2 1 SRA B ;Code to 2 1 0 ; IF @MOD2 LD A,(CKPROT2+1) OR A JR Z,CLSBU01 ENDIF ; ; Mod II must force BOOT/SYS to new cyl 1 ; IF @MOD2 CLSBU00 LD L,16H ;Cylinder start LD (HL),1 ;Force cyl 1 ENDIF ; LD L,17H ;Point to gran alloc LD (HL),B ;Reset alloc LD L,14H ;Point to ERN LD (HL),16 ;Update # BOOT records LD L,0 CALL WRSYS ;Write dir sector back LD A,18 ;Init "dir write error JP NZ,EXIT3 ;Exit if so ; ; If OLD entered No SYS file check needed ; CLSBU01 LD A,(OLDPRM$) ;Check for OLD entered OR A JR NZ,CLSBU5 ;Skip SYS setup if so ; ; ; Now check the HIT positions for /SYS files ; CALL HITRD ;Read in destination HIT JP NZ,EXIT3 LD DE,SYSDEC ;Pt to SYS file hash codes EX DE,HL ;HIT to DE, hash tbl to HL LD B,16 ;Check 16 DECs CLSBU1 LD A,(DE) ;If dest spare, stuff OR A ; with source else JR NZ,CLSBU2 ; test for match LD A,(HL) LD (DE),A CLSBU2 CP (HL) ;Dest match source? JR Z,CLSBU3 ;Continue if so NOTSYS LD HL,NOTSYS$ ;Init"Can't make sys disk... JP EXIT4 ;Display and quit CLSBU3 INC E ;Bump to next DEC INC HL ; & our table LD A,8 ;At midpoint? CP E JR NZ,CLSBU4 ;Skip if not LD E,20H ;Adjust DEC row # CLSBU4 DJNZ CLSBU1 LD D,(IY+9) ;Ok to backup SYSTEM LD E,1 ;Init to HIT sector LD HL,HITBUF CALL WRSYS ;Write back dest HIT LD A,23 ;Init "HIT write error CALL Z,HITRD ;Verify if write OK JP NZ,EXIT3 ;Quit on any error ; ; Set up byte 'C0' in SYSINFO sector ; IF @MOD2 LD DE,(CKPROT2) ;Get sysinfo sector LD E,2 ;Force sector 2 ENDIF ; IF @MOD4 LD DE,02 ;P/u Mod4 SYSINFO sect ENDIF ; ; HL => to HITBUF at this point ; CALL RDSEC ;Read the sector LD L,0C0H ;Point to type flag LD (HL),0FFH ;Set it LD L,0 ;Reset buffer CALL WRSEC ; Write it back ; CLSBU5 CALL PMTSRC ;Set up for source disk CALL HITRD ;Read source HIT JP NZ,EXIT3 ; ; Start the backup of files ; LD HL,HITBUF ;Init to start of HIT JR SCNH3 ;Branch to start OPENIT DB 'R'!80H ;R2 SCNHIT POP HL ;Remove top stack entry SCNH1 POP BC ;Recover DEC posn LD H,HITBUF<-8 ;HIT buf hi-order LD L,B ; and lo-order SCNH2 @@CKBRKC ;Check break hit JP NZ,BREAK ;Quit if so LD A,L ;Get the current DEC posn ADD A,20H ;Advance to next file on LD L,A ; this dir sector until JR NC,SCNH3 ; end, then go to next INC L ; dir sector in the HIT BIT 5,L ;Did we go off the end? JR Z,SCNH3 ; (ie from 1F to 20) LD A,0 SETBIT EQU $-1 OR A JR Z,TOEXIT1 ;If not, all done CALL PMTDST ;Get dest DCT in IY LD HL,HITBUF LD D,(IY+9) ;Get dir cyl LD E,L ;Point to GAT sector CALL RDSEC ; & read it CP 6 LD A,20 ;Init "GAT read error JP NZ,EXIT3 LD L,0CDH ;Point to config byte SET 4,(HL) CALL WRGAT TOEXIT1 JP EXIT1 ; ; Continue to scan the major loop ; SCNH3 LD A,(HL) ;Is HIT entry spare? OR A JR Z,SCNH2 ;Loop back if so LD A,L AND 0FEH ;Bypass if BOOT or DIR JR Z,SCNH2 LD B,L ;Save DEC PUSH BC CALL PMTSRC ;Set up for source disk LD D,(IY+9) ;P/u DIR cyl LD A,B ;Pt to dir sector of AND 1FH ; this file ADD A,2 ;Adj for GAT & HIT LD E,A LD HL,BUF2$ ;Read dir sector CALL RDSEC CP 6 ;Proper errcod? JP NZ,DIRERR LD A,B ;Pt to dir record for AND 0E0H ; the source file LD L,A LD H,BUF2$<-8 ;Pt to hi-order dir buf LD A,(HL) ;Ignore file if not LD (ATTRIB+1),A ; assigned in directory BIT 4,A JR Z,NODOIT BIT 7,A ;Ignore file if FXDE JP NZ,SCNH1 INC L ;Bump to DIR+1 LD A,(MODPRM$) ;Bypass if Mod parm OR A ; not entered JR Z,SCNH4 BIT 6,(HL) ;If Mod parm and bit not set JR Z,NODOIT ; skip the file ; SCNH4 BIT 4,(HL) ;Check date not current JR Z,SCNH4A LD A,(SVCTR) OR A ;Was date set? JR Z,NODOIT ;Bypass if not INC A ;Is date current? JR Z,NODOIT ;Bypass if not ; SCNH4A DEC L ;DIR + 0 LD A,(CLSFLG$) ;P/u CLASS parm byte BIT 6,(HL) ;Bypass if not SYS file JR Z,CKINV BIT 6,A ;Ok, it is, was SYS used? JR Z,NODOIT ;Go if no SYS parm JR CKNAM ; else back it up CKINV BIT 3,(HL) ;Test if file is INV JR Z,CKNAM BIT 3,A ;File is, want INV files? NODOIT JP Z,SCNH1 ;Don't want invisibles CKNAM LD A,(SPCFLD$) ;Now test filespec match CP ' ' ;If blank, don't bother JR NZ,CKNAM0 ; to match, take it LD A,(SPCFLD$+8) ;How about the extension? CP ' ' JR Z,SCNH6 ;Go if no ext either ; ; Test for a filespec match ; CKNAM0 PUSH HL LD A,L ADD A,5 ;Pt to filename in dir LD L,A LD DE,SPCFLD$ ;Pt to user filespec LD B,11 ;11 char max CKNAM1 LD A,(DE) ;P/u user entry CP '$' ;Wild card character? JR Z,CKNAM2 ;Always matches CP (HL) ;Same as filespec? JR Z,CKNAM2 ;Loop if so CP ' ' ;Ignore any further? JP NZ,TSTMFLG ;If not blank, no match CKNAM2 INC HL ;Match so far INC DE DJNZ CKNAM1 ; ; Filespec class matches, check if NOT used ; LD A,(MFLG$) ;Bypass if a match but OR A ; - exclude given JP NZ,SCNHIT ;- was used, skip file JR SCNH5 ; TSTMFLG LD A,(MFLG$) ;Ignore if NG match & OR A ; no exclude given JP Z,SCNHIT SCNH5 POP HL ;Rcvr ptr to DIR+0 SCNH6 PUSH HL ; ; Now check if date matches ; INC HL ;Pt to date field CALL UNPACK ;Alter date for cpr LD A,(FTFLG$) RLCA ;Tst From bit JR NC,SCNH7 LD A,D ;Ignore if date was OR E ; 00/00/00 for file JP Z,SCNHIT LD HL,(FMPAKD$) ;P/u user entry EX DE,HL CALL CPHLDE ;HL-DE EX DE,HL JP C,SCNHIT ;Bypass if date range bad SCNH7 LD A,(FTFLG$) RRCA ;Test TO bit JR NC,MATCHES ;Go if no TOPARM else LD A,D ; ck if file is dated OR E JP Z,SCNHIT ;Bypass if date was 00 LD HL,(TOPAKD$) ;P/u user's packed date CALL CPHLDE ;HL-DE JP C,SCNHIT ;Bypass if out of range MATCHES POP HL DONAM LD A,L ;Pt to start of dir rec AND 0E0H LD L,A ;Make sure it's on stack PUSH HL ADD A,5 ;Pt to start of filename LD L,A LD DE,FCB1$ ;Move filename into fcb LD B,8 ;Init 8 chars for filename DONAM1 LD A,(HL) ;P/u a char from the dir CP ' ' ;Space = end of name JR Z,DONAM2 LD (DE),A ;Move char to FCB INC HL ;Bump both ptrs INC DE DJNZ DONAM1 ;Loop for more DONAM2 LD A,L ;Pt to file extension ADD A,B ; by adding the LD L,A ; loop remainder LD A,(HL) CP ' ' JR Z,DONAM5 ;Bypass if none there LD A,'/' ; else set separator LD (DE),A ; into the FCB INC DE LD B,3 ;Now move in ext DONAM4 LD A,(HL) ;P/u ext char CP ' ' ;End if no more JR Z,DONAM5 LD (DE),A ;Put in in the FCB INC HL ;Bump both ptrs INC DE DJNZ DONAM4 ;Loop for more DONAM5 LD A,3 ;Terminate with ETX LD (DE),A PUSH DE ;Save pointer to spec end ; ; Check for NEW or OLD option ; LD A,(OLDPRM$) ;P/u parm & merge LD HL,NEWPRM$ ; with new OR (HL) ;If neither, bypass JR Z,BYPASS LD HL,FCB1$ ;Save current spec LD DE,FCB3$ LD BC,32 LDIR POP DE ;Recover spec end PUSH DE ; needed to add drivespec CALL MAKSPC ;Make it a file spec CALL GETDST ;Bring in the dest disk LD HL,(BUFFER$) ;Buffer is irrelevant LD DE,FCB2$ ;Pt to dest spec PUSH IY @@FLAGS ;IY => flag table base SET 0,(IY+'S'-'A') ;Inhibit file open bit POP IY @@OPEN ;Attempt to open POP DE ;Keep stack proper JR Z,CKOLD ;If file exists, ck OLD CP 25 ;File access denied? JR Z,CKOLD ; means it exists CP 24 ;File not found? JP NZ,SCNHIT ;Ignore if not LD A,(NEWPRM$) ;Check if NEW requested OR A JR NZ,GODOIT ;Go if NEW & not found JP SCNHIT CKOLD LD A,(OLDPRM$) ;Was found, backup old OR A ; files this time? JP Z,SCNHIT ;Ignore if not OLD GODOIT PUSH DE LD HL,FCB3$ ;Recover the original LD DE,FCB1$ ; file name LD BC,32 LDIR ; ; Check if prompting or not (Q parm) ; BYPASS LD A,(QPARM$+1) ;Query each file? OR A JP Z,NOPRMPT ;Not if not entered @@DSPLY QUERY ;"backup filespec ? ; ; Display file info for user decision ; POP DE ;Rcvr ptr to file buf POP HL ;Rcvr ptr to 1st dir byte PUSH DE INC HL ;Pt to MOD bit BIT 6,(HL) ;Test MOD flag JR Z,SCDAT1 ;Go if not set LD A,' ' ;Put a space LD (DE),A INC DE LD A,'+' LD (DE),A ;Display '+' if MOD INC DE SCDAT1 LD A,' ' ;Write a space LD (DE),A INC DE INC HL ;Advance to date field EX DE,HL LD (HL),'{' ;Stuff left brace INC HL EX DE,HL LD A,(HL) ;If no date, then skip OR A JR Z,SCDAT4 ;Ignore if no date saved RRCA ;Has date, get day RRCA RRCA AND 1FH LD B,2FH ;Convert day to decimal SCDAT2 INC B ; by counting # of 10's SUB 10 ;Sub 10 from day # JR NC,SCDAT2 ADD A,3AH ;Cvrt lo order to ASCII PUSH AF ;Save day low order LD A,B ;Stuff day hi order LD (DE),A INC DE ;Bump POP AF ;Rcvr lo order day # LD (DE),A ;Stuff low order INC DE ;Bump pointer to msg LD A,'-' LD (DE),A ;Stuff '-' INC DE ;Pt tO month field PUSH HL ;Save DIR ptr PUSH AF ;Save separator char DEC HL ;Pt to DIR+1 (month+) LD A,(HL) ;P/u month etc AND 0FH ;Strip off flags DEC A ;(mon-1)*3 to index LD C,A ; string conversion table RLCA ;X2 ADD A,C ;X3 LD C,A ;Results to BC LD B,0 LD HL,MONTBL ;Ptr to month names ADD HL,BC ;Add offset to tbl start LD C,3 LDIR ;Move 3-char month POP AF LD (DE),A INC DE ;Advance to year field POP HL ;Ptr to DIR+2 LD C,'8' ;Init for 1980's LD A,(DVTEST1) OR A JR NZ,NEWDT2 ;Go if new style LD A,(HL) ;Else get old year AND 7 ;Mask it JR THERE NEWDT2 LD A,L ;Offset to year ADD A,17 LD L,A ;DIR+19 LD A,(HL) AND 1FH ;Mask time IF @BLD631 L3B2F: ;<631> ENDIF CP 10 ;1980's? JR C,THERE IF @BLD631 INC C ;<631>was '8', now '9' bump decade ELSE LD C,'9' ;Bump decade ENDIF SUB 10 CP 10 ;Now must be 0-9 JR C,THERE IF @BLD631 SUB 0AH ;<631> LD C,'0' ;<631> JR L3B2F ;<631> ELSE LD A,9 ; else make 1999 ENDIF THERE LD B,A ;Save year offset LD A,C ;Stuff decade for dsply LD (DE),A INC DE LD A,B ;Year ADD A,'0' ;Make ascii LD (DE),A INC DE SCDAT4 LD A,3 ;Show etx for display LD (DE),A @@DSPLY FCB1$ ;Display filename @@DSPLY QMARK$ ;" } ? " LD HL,(BUFFER$) ;Get user response LD BC,3<8 ;3 char max @@KEYIN JP C,ABRTBU ;Quit on Break LD A,(HL) ;Get the 1st char RES 5,A ;Strip lc if present CP 'Y' ;Yes means move the file JR Z,CPYMSG ;Go if so ; ; Accept 'C' for response to set QUERY=N ; SUB 'C' ;Was response "C"? JP NZ,SCNHIT ;Don't backup if not LD (QPARM$+1),A ;Set QUERY=N CPYMSG EX (SP),HL ;Place dummy HL below PUSH HL ; FCB1$ ETX pointer ; ; Display copying file info ; NOPRMPT @@CKBRKC ;Ck if BREAK JP NZ,ABRTBU ;Quit if so @@LOGOT CPYFIL$ ;"copying file... POP HL ;Get pointer where ETX LD (HL),CR ; is & replace with CR PUSH HL @@LOGOT FCB1$ ;Display the filespec POP DE ;Rcvr ptr to CR POP HL ; ; Put in the drive spec ; DOBU CALL MAKSPC ;Make the filespec POP BC ;Get DEC of source PUSH BC LD A,B ;Test if a SYS DEC AND 0D8H JP NZ,DOFIL0 ;Jump if not SYS ATTRIB LD A,0 ;P/u attribute byte BIT 6,A ;Don't do if not SYS JP Z,DOFIL0 ; ; Routine to copy over SYS files ; CALL PMTDST ;Prompt dest drive LD D,(IY+9) ;P/u dir cyl of dest LD A,B ;Get DEC & calc sector AND 1FH ADD A,2 ;Adj for GAT & HIT LD E,A LD HL,(BUFFER$) ;P/u buffer addr CALL RDSEC ;Read dir sect CP 6 ;Proper errcod? JP NZ,DIRERR LD A,B ;Pt to 1st byte of AND 0E0H ; dir record LD L,A BIT 4,(HL) ;Go if already assigned JR NZ,DOSYS1 LD (HL),5FH ;Show assigned, SYS, INV INC HL ; & no access IF @BLD631 LD BC,3 ;<631> LD (HL),B ;<631>B==0 Zero out DIR+1 to DIR+4 LD D,H ;<631> LD E,L ;<631> INC DE ;<631> ELSE LD (HL),0 ;Zero out DIR+1 to DIR+4 LD D,H LD E,L INC DE LD BC,3 ENDIF LDIR LD A,L ;Pt HL to DIR+16 ADD A,12 LD L,A INC A LD E,A ;Pt DE to DIR+17 LD (HL),0FFH ;Stuff X'FF' into extent LD C,15 ; & pswd fields LDIR DOSYS1 LD A,L ;Pt HL to Dir+0 AND 0E0H ; of dest BIT 6,(HL) ;Guard against writing JP Z,NOTSYS ; over a non-SYS file ADD A,5 ;Pt to name field LD L,A LD E,A ;Pt DE to name field of LD H,BUF2$<-8 ; destination LD A,(BUFFER$+1) ;P/u buffer hi-order addr LD D,A LD BC,13 ;Move name/ext into dest LDIR LD D,(IY+9) ;P/u dir cyl of dest POP BC ;Rcvr DEC of source PUSH BC LD A,B ;Calc dir sector for AND 1FH ; source SYS module ADD A,2 LD E,A LD HL,(BUFFER$) ;P/u buffer ptr for dest CALL WRSYS ;Write the dir to dest LD A,18 ;Init "Dir write error JP NZ,EXIT3 ; and quit on bad write ; ; The HIT entries were transferred prior ; POP BC ;Rcvr DEC of source PUSH BC LD A,B ;Test for SYS0 CP 2 JP NZ,DOFIL0 ;Bypass if not SYS0 CALL PMTSRC ;Prompt source IF @MOD4 LD B,16 ;Init to xfer BOOT track LD DE,0 ;Init track 0, sector 0 ENDIF IF @MOD2 LD DE,(PROTSEC) ;Get sysinfo sector LD A,D OR A LD B,5 JR Z,NBTSEC2 LD B,16 NBTSEC2 LD E,0 ENDIF ; LD HL,(BUFFER$) ;Set disk buffer RDBOOT CALL RDSEC ;Read sector and JP NZ,EXIT3 ; quit on error INC H ;Pt to next block INC E ;Point to next sector DJNZ RDBOOT ;Continue reading boot ; ; Turn off CONFIG on destination disk ; LD HL,(BUFFER$) ;Start cyl image LD DE,100H*2+1 ;Offset to sector 2 +1 ADD HL,DE ;HL => config byte LD (HL),0C9H ;Config off ; DOSYS2 CALL PMTDST ;Prompt destination IF @MOD4 LD B,16 ;Sector count for boot LD DE,0 ;Init track and sector 0 ENDIF IF @MOD2 LD DE,(CKPROT2) ;Get dest cyl number LD A,(PROTSEC+1) LD B,5 ;Default 5 sectors OR A JR Z,NBTSECS AND D JR Z,NBTSECS LD B,16 ;Use 16 sectors NBTSECS LD E,0 ENDIF LD HL,(BUFFER$) ;P/u buffer start WRBOOT LD A,E ;If sector 0 or 1, CP 2 ; correct DIRCYL & JR NC,WRBOOT2 ; BOOT step rate OR A JR Z,WRBOOT1 ;If sec 0 only dir cyl ; LD A,(BOOTST$) ;P/u step pointer LD L,A LD A,(HL) ;P/u BOOT step rate AND 0FCH ;Strip the rate BSCLS OR 0 ;Merge dest rate LD (HL),A WRBOOT1 LD A,(IY+9) ;P/u DIR cyl LD L,2 LD (HL),A LD L,0 ;Restart to buf start WRBOOT2 CALL WRSEC ;Write dest boot sector JP NZ,EXIT3 ;Quit on error INC H ;Bump buffer page INC E ;Bump sector DJNZ WRBOOT ; ; Verify this track ; IF @MOD4 LD B,16 ;16 sector just written LD DE,0 ; on track 0 ENDIF IF @MOD2 LD A,(PROTSEC+1) LD B,5 LD DE,(CKPROT2) OR A JR Z,NBTSEC1 AND D JR Z,NBTSEC1 LD B,16 NBTSEC1 LD E,0 ENDIF VRBOOT CALL VERSEC ;Verify a boot sector JP NZ,EXIT3 ;Quit on an error INC E ;Inc sector # DJNZ VRBOOT ; ; Mod II check if cyl 0 to be formatted on dest ; IF @MOD2 LD DE,(CKPROT2) ;Get sysinfo sector LD A,(PROTSEC+1) AND D JR Z,COPY0E ;Go if yes OKWRT0 CALL PMTSRC ;Get source disk CALL READ0 ;Read cyl 0 JP NZ,EXIT3 ;Go on disk error CALL PMTDST ;Get dest disk CALL FORMAT0 ;Format cyl JP NZ,EXIT3 ;Go on disk error ; ; Setup new track length into boot data ; LD HL,(BUFFER$) ;Get I/O buffer PUSH HL ;Save start INC HL ;+1 INC HL ;+2 (dir cyl) LD A,(IY+9) ;Get dir cyl LD (HL),A ;To buffer INC HL ;+3 (boot step rate) LD A,(BSCLS+1) ;Get step rate AND 3 ;Step rate only LD (HL),A ;Load into buffer INC HL ;Bump LD A,(IY+7) ;Get data AND 1FH ;Highest sector # INC A ;Sectors / track LD (HL),A ;To buffer INC HL ;Bump LD A,(IY+3) ;Get data ADD A,A ;Density => bit 7 AND 80H ;Keep only LD (HL),A ;To buffer POP HL ;HL => buffer start LD D,H ;Pass to DE LD E,L ;DE => buffer start LD BC,80H ;Buffer length ADD HL,BC ;HL => dest EX DE,HL ;HL=>source, DE=>dest LDIR ;Copy sector 0 => sec 1 CALL PMTDST ;Re-fetch DCT CALL WRITE0 ;Write the cylinder JP NZ,EXIT3 ;Go on disk error COPY0E EQU $ ENDIF ; ; Routine to perform the file copy to destination ; DOFIL0 LD DE,OPENIT ;Check the name @@RENAM LD B,0 ;Lrl = 256 CALL GETSRC ;Prompt source & set fcb LD HL,(BUFFER$) ;Get buffer addr @@FLAGS SET 0,(IY+'S'-'A') ;Inhibit file open bit @@OPEN ;Open the source file JP NZ,EXIT3 ;Quit on open error ; ; Check if source file can fit on destination disk ; LD HL,(FCB1$+12) ;P/u ERN SIZSAV LD DE,$-$ ;P/u disk capacity EX DE,HL ;flip them around for test SBC HL,DE ;If <= size, then OK JR NC,SIZOK LD HL,SIZBIG$ ; else file to big @@LOGOT ;Inform user & continue JP SCNH1 ;Loop back for another file SIZOK LD DE,OPENIT ;Check the name @@RENAM LD B,0 ;Lrl = 256 CALL GETDST ;Prompt dest & set fcb LD HL,(BUFFER$) ;Get buffer addr @@INIT ;Init the dest JR Z,LRLOK ;If no error, cont. CP 42 ;Was it LRL error? JR Z,LRLOK ;Ignore if so JP EXIT3 ; else real error, abort LRLOK LD A,(FCB2$+7) ;P/u DEC of dest LD (DOFIL11+1),A LD BC,(FCB1$+12) ;P/u ERN & ck for enuf CALL WRERN ; dest space on disk POP BC ;Recover DEC LD L,B ;Reset HL to dir LD H,BUF2$<-8 PUSH BC ;Save DEC JR Z,DOFIL02 ;Go if there was room CALL PMTSRC ; else make source current, loop JP DONAM ; back because dest was swapped DOFIL02 LD A,L ;Check if date current AND 0E0H ;Index to proper direc INC A LD L,A BIT 4,(HL) ;Check if bit set JR Z,$+5 LD (SETBIT),A ; LD HL,0 LD (FCB2$+12),HL ;Set dest ERN to 0 @@REW ;Rewind the dest DOFIL03 LD HL,(BUFFER$) ;Buffer addr DOFIL04 LD (FCB1$+3),HL ;Set buffer addr in fcb CALL GETSRC ;Prompt source & set fcb @@READ ;Read a source file sector JR Z,DOFIL05 ;Go if no error CP 1CH ;Eof? JR Z,DOFIL09 ;Yes, finished loading CP 1DH ;Nrn > ern? JR Z,DOFIL09 ;Also means load done JP EXIT3 ;Abort on any other error DOFIL05 INC H ;Bump the buffer ptr LD A,H DOFIL06 CP $-$ ;Test out of memory JR NZ,DOFIL04 ;Loop if more room LD HL,(BUFFER$) ;P/u buffer start DOFIL07 LD (FCB2$+3),HL ; & set into dest fcb CALL GETDST ;Prompt dest & set fcb @@VER ;Write dest w/verify JP NZ,EXIT3 ;Quit on error INC H ;Bump buffer page LD A,H DOFIL08 CP $-$ ;Out of memory? JR NZ,DOFIL07 ;Write another if not JR DOFIL03 ; else back to loading ; ; Reached the end of the source file ; DOFIL09 CALL LSTBUF ;Write remaining buffer LD HL,(FCB1$+8) ;P/u DEC & LRL LD (FCB2$+8),HL ; & stuff into dest CALL GETDST ;Set for dest fcb @@CLOSE ;Close 'er up JP NZ,EXIT3 ;Abort on close error ; ; Now remove the mod flag from destination ; and do CLONE function ; LD D,(IY+9) ;P/u dir cyl DOFIL11 LD B,$-$ ;P/u DEC LD A,B ;Pt to dir sector AND 1FH ADD A,2 ;Bypass GAT and HIT LD E,A PUSH DE ;Save cyl/sect LD HL,(BUFFER$) ;P/u buffer addr CALL RDSEC ;Read the dir sect CP 6 ;Proper errcod? LD A,17 ;Init "Dir read error JP NZ,EXIT3 LD A,B ;Pt to dir record AND 0E0H LD E,A ;Pt to DIR lo order LD A,(BUFFER$+1) ;P/u hi order buffer pos LD D,A POP HL POP BC ;P/u DEC & buffer of src PUSH BC PUSH HL LD A,B ;Get source DEC AND 0E0H ; and pt to the direc LD L,A ; of the current file LD H,BUF2$<-8 INC L ;Pt to mod flag byte PUSH HL ;Save source DIR+1 RES 6,(HL) ;Reset the MOD bit DEC L ;Point to DIR+0 LD BC,5 ;Transfer up thru LDIR ; DIR+4 BYSPACE LD A,E ;Point DE to the dest ADD A,11 ; password fields LD E,A LD A,L ;Point HL to the source ADD A,11 ; password fields LD L,A IF @BLD631 LD C,4 ;<631>(B==0) Move both pswds ELSE LD BC,4 ;Move both pswds ENDIF LDIR POP HL ;Get source DIR+1 INC HL ;Pt to year field DEC DE ;Pt to new year LD A,(NEWDT) ;Old to new flag CP 4 ;If not old to new, done JR NZ,NEWDT1 LD A,(HL) ;Get old year AND 7 LD (DE),A ;Store in new year posn DEC DE XOR A ;Not time LD (DE),A NEWDT1 LD HL,(BUFFER$) ;P/u buffer addr POP DE ;Rcvr cyl/sect CALL WRSYS ;Write back IF @BLD631 TOEXIT3: ;<631> ENDIF LD A,18 ;Init "Dir write error JP NZ,EXIT3 ;Quit on error ; ; Attempt to clear mod flag of source ; DOFIL12 LD A,0 ;Test for write prot src OR A ;Which implies, can't JP NZ,SCNH1 ; clear mod flags POP BC ;P/u DEC of source PUSH BC LD A,B ;Clear mod flag on source AND 0E0H ;Dir sector is resident INC A ;In a buffer at BUF2 LD L,A LD H,BUF2$<-8 RES 6,(HL) ;Reset mod bit CALL PMTSRC ;Set for source i/o LD D,(IY+9) ;P/u dir cyl LD A,B ;Pt to dir sect of source AND 1FH ADD A,2 ;Adjust for GAT and HIT LD E,A LD HL,BUF2$ CALL WRSYS ;Write it back JP Z,SCNH1 ;Back on good write CP 15 ;Accept only "write prot error IF @BLD631 JR NZ,TOEXIT3 ;<631>and quit ELSE LD A,18 ;Any other, "Dir write error JP NZ,EXIT3 ; and quit ENDIF LD A,0FFH ;Turn off clear mod LD (DOFIL12+1),A ; flag test @@LOGOT CCMOD$ ;"can't clear... JP SCNH1 ;Loop to next file ; ; Routine to compare HL to DE, ret Z if equal ; CPHLDE LD A,H ;Test H=D SUB D RET NZ ;Back if not LD A,L ;Test L=E SUB E RET ;Back with condition ; ; Routine to construct filespec from name/ext ; MAKSPC LD A,':' ;Prepare for drivespec LD (DE),A INC DE PUSH DE ;Save pointer LD A,(DSTDRV$+1) ;P/u dest drive # AND 7 ;Cvrt to ASCII ADD A,'0' LD (DE),A ; & stuff at filespec end INC DE LD A,3 ;Terminate with ETX LD (DE),A LD HL,FCB1$ ;Copy source fcb to LD DE,FCB2$ ; dest fcb LD BC,32 LDIR POP DE ;Rcvr where source spec LD A,(SRCDRV$+1) ;P/u source drive # AND 7 ;Cvrt to ASCII ADD A,'0' LD (DE),A ;Stuff in dest fcb RET ; ; Routine to extract date from directory ; UNPACK LD A,(HL) ;P/u DIR+1 AND 0FH ;Remove flags LD E,0 LD D,A ;Split mont to DE SRL D RR E INC HL ;Pt to day LD A,(HL) AND 0F8H ;Mask off year RRCA ;Bits 2-6 OR E ;Merge w/month LD E,A LD A,(DVTEST2) OR A ;New style year? JR NZ,NEWDT3 ;Go if so LD A,(HL) ;get old year AND 7 SHFTD RLCA RLCA RLCA ;To bits 3-7 OR D ;Merge w/month LD D,A RET NEWDT3 LD A,L ADD A,17 LD L,A ;DIR+19 LD A,(HL) AND 1FH JR SHFTD ; ; Write the GAT back to disk ; WRGAT LD L,0 ;HL to start of buffer CALL WRSYS ;Write dir sector LD A,21 ;Init GAT write error JP NZ,EXIT3 ; and quit on error CALL VERSEC ;Verify good write CP 6 ;Expect error 6 LD A,20 ;Init GAT read error JP NZ,EXIT3 ;Quit on any other error RET ; ; Write last buffer if needed ; LSTBUF LD A,(BUFFER$+1) ;P/u hi order buffer start CP H ;Are we there now? RET Z ;Back if so, nothing loaded LSTBUF1 LD A,$-$ ;P/u last available page CP H ;There now? RET Z ;Already written if so LD B,H ;Need to write to this page LD HL,(BUFFER$) ;P/u buffer start LSTBUF2 LD (FCB2$+3),HL ; and put in dest fcb CALL GETDST ;Prompt dest @@VER ;Write with verify JP NZ,EXIT3 ;Quit on bad write INC H ;Bump buffer page LD A,H CP B ;At the end? JR NZ,LSTBUF2 ;Loop if more RET ; ; Check if enough space on destination disk ; WRERN LD A,B ;If ERN = 0, don't OR C ; write a ERN RET Z DEC BC ;Adjust for 0 offset CALL GETDST ;Prompt dest PUSH DE ;Save fcb pointer @@POSN ;Position to end LD HL,(BUFFER$) ;P/u buffer addr LD D,H ;Construct a format LD E,L ; sector of all X'E5's INC DE LD BC,255 LD (HL),0E5H LDIR POP DE ;Rcvr fcb ptr @@VER ;Write with verify RET Z ;Ret if no error CP 27 ;Disk Full? JR NZ,NOTDF ;No - quit on real error @@REMOV ;Remove what can't fit BIT 3,(IY+3) ;Is this a rigid disk? JR Z,NOTHARD ;Go if not BIT 2,(IY+3) ;Shown as Removable? JR Z,NOTHARD ;Prompt disk swap if so LD HL,FULDRV$ ;Prepare disk full error JR DOING1 NOTHARD @@FLAGS BIT 5,(IY+'S'-'A') ;Can't switch while DOing JR NZ,DOING LD HL,NEWDISK ;"disk full, enter new... CALL FLASH OR 1 ;Show switched dest RET NOTDF EQU $ JP EXIT3 ;Error exit ; GETSRC PUSH BC LD DE,FCB1$ ;Pt to source FCB CALL PMTSRC ;Show source is current POP BC ; for disk I/O RET ; GETDST PUSH BC LD DE,FCB2$ ;Pt to dest FCB CALL PMTDST ;Show dest is current POP BC ; for disk I/O RET ; HITRD LD D,(IY+9) ;P/u dir cyl of source LD E,1 ;Read HIT LD HL,HITBUF ;Into HIT buffer CALL RDSEC CP 6 ;Errcod correct? LD A,16H ;Init "HIT read error RET ;Return w/condition ; DOING LD HL,DOMSG DOING1 JP EXIT4 ; CPYFIL$ DB 29,'Copying file: ',3 QUERY DB 'Backup ',3 FULDRV$ DB 'Disk is full ',CR NEWDISK DB 'Disk is full - Insert new formatted ' DB 'destination disk, ',29,3 DOMSG DB 'Disk is full! - Can''t switch ' DB 'while in effect',CR SIZBIG$ DB ' File is larger than destination ' DB 'capacity - backup is bypassed',CR NOTSYS$ DB 'Can''t create SYSTEM disk - ' DB 'directory slots in use',CR QMARK$ DB '} ? ',3 MONTBL DM 'JanFebMarAprMayJunJulAugSepOctNovDec' SYSDEC DB 0A2H,0C4H,2EH,2FH,2CH,2DH,2AH,2BH DB 28H,29H,26H,27H,27H,0A7H,26H,0A6H ; DC 64,0 ;PATCH space ; ORG $<-8+1<+8 HITBUF DS 256