; BIGBURST--BIG FILE BACKUP/RESTORE
; COPYRIGHT 1982, G. YOUNG, INC.
; UPDATED 10/9/82
*
* TO EXECUTE, ENTER THE PROGRAM NAME FOLLOWED BY THE FILE MASK:
*       A>BIGBURST FILENAME.TYP/B (FOR BACKUP) OR
*       A>BIGBURST FILENAME.TYP/R (FOR RESTORE)
* THE PURPOSE OF THIS PROGRAM IS TO BACKUP AND RESTORE FILES FROM/TO
* A HARD DISK WHERE THE FILE IS TOO BIG TO FIT ON ONE FLOPPY DISK.
* IT BACKS UP BY COPYING THE LARGE FILE TO MULTIPLE SMALL FILES
* WHICH WILL FIT ON THE FLOPPY.  THE FILE TYPE OF EACH OF THESE SMALL
* FILES IS A SEQUENTIAL NUMBER FROM 001 TO 255 WITH THE LAST RECORD
* ON THE LAST FILE CONTAINING AN INDICATOR THAT THIS IS THE LAST FILE.
* THE RESTORE PROCESS IS DONE BY COMBINING THESE SMALL FILES BACK INTO
* THE LARGE FILE.
* CHANGED 10/9/82 TO ASK QUESTIONS ON FLOPPY DRIVE #

* WRITTEN BY GARY YOUNG, BOX 3218, NO. HOLLYWOOD, CA 91609

       TITLE   '*** BIG FILE BACKUP/RESTORE ***'
BDOS    EQU     5
CR      EQU     0DH
LF      EQU     0AH
TBUF    EQU     80H
TFCB    EQU     5CH
BOOT    EQU     0
       ORG     100H
       JMP     START
       DB      'COPYRIGHT 1982, G. YOUNG, INC.'
START   LXI     SP,STACK+80
       LDA     TFCB+1          ;SEE IF A MASK WAS ENTERED
       CPI     20H             ;BUFFER WILL BE BLANK IF NOT
       JZ      INPUTERR
       LXI     H,TFCB          ;SAVE THE INPUT FILE NAME
       LXI     D,HOLDFCB
       MVI     B,16
       CALL    MOVE
       LXI     D,HOLDFCB+16
       MVI     B,20
       CALL    CLEAR
       LXI     H,TBUF          ;SEARCH FOR /B OR /R
       MVI     B,80
FINDSLSH MOV    A,M
       CPI     '/'
       JZ      BORR
       INX     H
       DCR     B
       JNZ     FINDSLSH
INPUTERR LXI    D,ERROR1
ERROR   CALL    OUTPUT
       JMP     BOOT
BORR    INX     H               ;NEXT CHAR MUST BE A B OR R
       MOV     A,M
       CPI     'B'
       JZ      QUEST1
       CPI     'R'
       JNZ     INPUTERR
QUEST2  LXI     D,SRCFLPMSG
       CALL    QUESTION
       ORA     A
       JNZ     QUEST2A
       LDA     SRCFLP
       JMP     QUEST2B
QUEST2A LDA     INREC
QUEST2B STA     FLOPPY
       JMP     RESTORE

QUEST1  LXI     D,DESTFLPMSG
       CALL    QUESTION
       ORA     A
       JNZ     QUEST1A
       LDA     DESTFLP
       JMP     QUEST1B
QUEST1A LDA     INREC
QUEST1B STA     FLOPPY
       JMP     BACKUP

RESTORE LXI     H,TFCB
       LXI     D,HDFCB
       MVI     B,12            ;CREATE A HARD DISK FCB
       CALL    MOVE
       LXI     D,HDFCB+12
       MVI     B,24
       CALL    CLEAR
       LXI     H,0000
       SHLD    RECCNT
       XRA     A
       STA     FILECNT
       MVI     A,'$'           ;CREATE A TEMPORARY FILE
       STA     HDFCB+9
       STA     HDFCB+10
       STA     HDFCB+11
       LXI     H,MSG3A         ;MARK AS "RESTORE" IN MESSAGE
       LXI     D,MSG3
       MVI     B,8
       CALL    MOVE
       LXI     H,MSG0A
       LXI     D,MSG0          ;CHANGE THE PROMPT MESSAGE
       MVI     B,10
       CALL    MOVE
       LXI     D,HDFCB         ;SEE IF THE TEMP FILE IS THERE ON
       MVI     C,0FH           ;THE HARD DISK
       CALL    BDOS
       INR     A
       JZ      MAKEHD
       LXI     D,HDFCB         ;DELETE IT IF IT IS
       MVI     C,13H
       CALL    BDOS
MAKEHD  LXI     D,HDFCB         ;MAKE THE HARD DISK FILE
       MVI     C,16H
       CALL    BDOS
       LXI     D,ERROR4        ;ERROR IF DIRECTORY FULL
       INR     A
       JZ      ERROR
LOADFLP CALL    GENFCB
LOAD2   CALL    MOUNT
       LXI     D,FLPFCB        ;SEE IF FLOPPY FILE IS ON THAT DISK
       MVI     C,0FH
       CALL    BDOS
       INR     A
       JNZ     OPEN2           ;YES, THE RIGHT ONE IS MOUNTED
       LXI     D,MESSAGE2      ;NO, WRONG DISK IS MOUNTED
       CALL    OUTPUT
       JMP     LOAD2
OPEN2   LXI     D,HDFCB+12      ;OPEN THE HARD DISK AGAIN
       MVI     B,24
       CALL    CLEAR
       LXI     D,HDFCB
       MVI     C,0FH
       CALL    BDOS
       LHLD    RECCNT          ;POSITION TO END OF FILE
       SHLD    HDFCB+33
       LXI     D,HDFCB         ;RANDOM READ
       MVI     C,21H
       CALL    BDOS
COPYLOOP2 CALL  LOADBUFF2       ;ACTUAL COPY IS DONE HERE
       CALL    WRITEBUF2
       CALL    DEBUG
       LDA     EOF
       CPI     2
       JZ      ENDOFFILE2
       CPI     1
       JZ      DISKMPTY
       JMP     COPYLOOP2
ENDOFFILE2 LXI  D,HDFCB         ;CLOSE HARD DISK
       MVI     C,10H
       CALL    BDOS
       LXI     D,HOLDFCB       ;SEE IF THE FILE IS THERE
       MVI     C,0FH
       CALL    BDOS
       INR     A
       JZ      RENAME          ;NO, RENAME THE TEMP VERSION AS THE FINAL NAME
       LXI     D,BAKFCB        ;SEE IF THERE IS A BACKUP FILE NAME THERE
       MVI     B,36
       CALL    CLEAR
       LXI     H,HOLDFCB
       LXI     D,BAKFCB
       MVI     B,36
       CALL    MOVE
       LXI     H,BAK
       LXI     D,BAKFCB+9
       MVI     B,3
       CALL    MOVE            ;CREATE THE BACKUP FILE NAME
       LXI     D,BAKFCB        ;DELETE IT IF IT IS THERE
       MVI     C,13H
       CALL    BDOS
       LXI     H,BAKFCB
       LXI     D,HOLDFCB+16
       MVI     B,16
       CALL    MOVE
       LXI     D,HOLDFCB       ;RENAME THE FINAL FILE NAME AS .BAK
       MVI     C,17H
       CALL    BDOS
RENAME  LXI     H,HOLDFCB
       LXI     D,HDFCB+16      ;RENAME THE TEMP FILE TO THE PERMANENT NAME
       MVI     B,16
       CALL    MOVE
       LXI     D,HDFCB
       MVI     C,17H           ;RENAME .$$$ AS .XXX (FINAL NAME)
       CALL    BDOS
       LXI     D,ERROR5        ;FINISHED
       JMP     ERROR
DISKMPTY        LXI     D,FLPFCB        ;CLOSE THE CURRENT FLOPPY FILE
       MVI     C,10H
       CALL    BDOS
       LXI     D,HDFCB         ;CLOSE THE HARD DISK FILE ALSO, WILL OPEN
       MVI     C,10H           ;AGAIN LATER, BUT MOUNTING THE NEW FLOPPY
       CALL    BDOS            ;REQUIRES A RESET WHICH ASSUMES ALL CLOSED
       JMP     LOADFLP



BACKUP LXI      H,TFCB
       LXI     D,HDFCB
       MVI     B,12
       CALL    MOVE
       LXI     D,HDFCB+12
       MVI     B,24
       CALL    CLEAR
       LXI     H,0000
       SHLD    RECCNT
       LXI     D,HDFCB         ;MAKE SURE HARD DISK FILE IS THERE
       MVI     C,0FH
       CALL    BDOS
       INR     A
       JNZ     CLEARCNT
       LXI     D,ERROR2        ;FILE NOT FOUND
       JMP     ERROR
CLEARCNT XRA    A
       STA     FILECNT
CREATEFLP CALL  GENFCB          ;CREATE FLOPPY FCB
       CALL    MOUNT
       LHLD    RECCNT          ;POSITION FILE
       SHLD    HDFCB+33
       LXI     D,HDFCB         ;RANDOM READ
       MVI     C,21H
       CALL    BDOS
       LXI     D,FLPFCB        ;LOOK FOR FLOPPY NAME
       MVI     C,0FH
       CALL    BDOS
       INR     A
       JZ      MAKEFLOP
       LXI     D,FLPFCB        ;DELETE IT IF IT IS THERE
       MVI     C,13H
       CALL    BDOS
MAKEFLOP LXI    D,FLPFCB        ;CREATE THE FILE
       MVI     C,16H
       CALL    BDOS
       LXI     D,ERROR4
       INR     A
       JZ      ERROR           ;DIRECTORY FULL
COPYLOOP1 CALL  LOADBUFF1       ;DO ACTUAL COPYING HERE
       CALL    WRITEBUF1
       CALL    DEBUG
       LDA     EOF
       CPI     1
       JZ      ENDOFFILE1
       CPI     2
       JZ      DISKFULL
       JMP     COPYLOOP1
ENDOFFILE1      LXI     D,LASTREC       ;ADD END OF ALL FILES RECORD
       MVI     C,1AH
       CALL    BDOS
       LXI     D,FLPFCB
       MVI     C,15H           ;WRITE IT
       CALL    BDOS
       LXI     D,FLPFCB
       MVI     C,10H           ;CLOSE FLOPPY
       CALL    BDOS
       LXI     D,ERROR5
       JMP     ERROR           ;FINISHED
DISKFULL LXI    D,FLPFCB
       MVI     C,10H           ;CLOSE FLOPPY
       CALL    BDOS
       JMP     CREATEFLP

GENFCB  LXI     D,FLPFCB        ;CREATE THE FLOPPY NAME
       MVI     B,36
       CALL    CLEAR
       LXI     H,HOLDFCB+1
       LXI     D,FLPFCB+1
       MVI     B,11
       CALL    MOVE
       LDA     FLOPPY
       ANI     0FH
       STA     FLPFCB
       LXI     D,ERROR3
       LDA     FILECNT
       INR     A
       STA     FILECNT
       JZ      ERROR           ;TOO MANY FLOPPIES
       MVI     H,0
       MOV     L,A
       SHLD    MPTY
       LXI     D,FLPFCB+9      ;SET FILE TYPE TO SEQUENCE NUMBER
       LXI     H,64H
       SHLD    TEMP2
       CALL    DIVID2
       LXI     H,0AH
       SHLD    TEMP2
       CALL    DIVID2
       LDA     MPTY
       ADI     '0'
       STAX    D
       RET

DEBUG   LHLD    RECCNT          ;THIS PRINTS THE RECORD # JUST WRITTEN
       SHLD    MPTY            ;FOR DEBUG PURPOSES
       LXI     D,DBMSG+2
       LXI     H,2710H
       SHLD    TEMP2
       CALL    DIVID2
       LXI     H,03E8H
       SHLD    TEMP2
       CALL    DIVID2
       LXI     H,64H
       SHLD    TEMP2
       CALL    DIVID2
       LXI     H,0AH
       SHLD    TEMP2
       CALL    DIVID2
       LDA     MPTY
       ADI     '0'
       STAX    D
       LXI     D,DBMSG
       CALL    OUTPUT
       RET

DIVID2  PUSH    D
       MVI     E,0
       LHLD    MPTY
       SHLD    TEMP
SB22    LXI     B,TEMP
       LXI     H,TEMP2
       XRA     A
       LDAX    B
       SBB     M
       STAX    B
       INX     B
       INX     H
       LDAX    B
       SBB     M
       STAX    B
       JC      NEG2
       INR     E
       PUSH    H
       LHLD    TEMP
       SHLD    MPTY
       POP     H
       JMP     SB22
NEG2    MOV     A,E
DIV2    ADI     '0'
       POP     D
       STAX    D
       INX     D
       RET

MOUNT   LXI     H,FLPFCB+1
       LXI     D,MSG1
       MVI     B,8
       CALL    MOVE
       LXI     D,MSG4
       CALL    MOVE
       LXI     H,FLPFCB+9
       LXI     D,MSG2
       MVI     B,3
       CALL    MOVE
       LXI     D,MSG5
       CALL    MOVE
       LXI     D,MESSAGE1
       CALL    OUTPUT
       LXI     D,INBUF
       MVI     C,0AH
       CALL    BDOS
       MVI     C,0DH           ;RESET THE DISK SYSTEM
       CALL    BDOS
       RET

CLEAR   XRA     A
CLEAR2  STAX    D
       INX     D
       DCR     B
       JNZ     CLEAR2
       RET

;FOR BACKUP...LOAD FROM HARD DISK, WRITE TO FLOPPY
LOADBUFF1 EQU   $       ;THIS ROUTINE LOADS AS MUCH OF
       LXI     H,0000          ;MEMORY WITH THE FILE AS POSSIBLE
       SHLD    MAX1
       LXI     H,ADDR3
       SHLD    TEMP
       XRA     A
       STA     EOF             ;CLEAR EOF FLAG
LOADNEXT        LHLD    TEMP
       XCHG                    ;SET DMA ADDRESS
       MVI     C,1AH
       CALL    BDOS
       LXI     D,HDFCB         ;READ HARD DISK
       MVI     C,14H
       CALL    BDOS
       ORA     A
       JNZ     HDEOF           ;EOF?
       LHLD    MAX1
       INX     H               ;INCREMENT RECORD COUNT
       SHLD    MAX1
       LHLD    TEMP            ;SEE IF NEXT RECORD WOULD EXCEED THE
       LXI     D,128           ;TPA AREA
       DAD     D
       SHLD    TEMP
       DAD     D               ;WILL THE NEXT RECORD OVERWRITE BDOS?
       XCHG
       LHLD    BDOS+1          ;FIND THE TOP OF MEMORY
       CALL    COMPREG         ;COMPARE REGISTERS
       RC                      ;RETURN IF MEMORY ALREADY FULL
       JMP     LOADNEXT        ;GET ANOTHER RECORD
HDEOF   MVI     A,1             ;SET FILE EOF
       STA     EOF
       RET

WRITEBUF1 EQU   $       ;WRITE FROM THE MEMORY BUFFER
       LXI     H,ADDR3
       SHLD    TEMP
       LHLD    MAX1            ;ALLOW FOR FILES THAT HAVE NO
       LXI     D,0000          ;RECORDS SUCH AS RESTART
       CALL    COMPREG
       RZ
WRITENEXT       LHLD    TEMP
       XCHG                    ;SET DMA ADDRESS
       MVI     C,1AH
       CALL    BDOS
       LXI     D,FLPFCB
       MVI     C,15H           ;WRITE SEQUENTIAL
       CALL    BDOS
       ORA     A
       JNZ     FPFULL2
       LHLD    RECCNT
       INX     H
       SHLD    RECCNT
       LHLD    MAX1            ;DECREASE RECORD COUNT
       DCX     H
       SHLD    MAX1
       LXI     D,0000          ;CHECK FOR NO MORE TO WRITE
       CALL    COMPREG
       RZ
       LHLD    TEMP
       LXI     D,128           ;INCREMENT WRITE ADDRESS
       DAD     D
       SHLD    TEMP
       JMP     WRITENEXT
FPFULL2 MVI     A,2             ;FULL DISKETTE
       STA     EOF
       RET

;FOR RESTORE, LOAD FROM FLOPPY, WRITE TO HARD DISK
LOADBUFF2 EQU   $       ;THIS ROUTINE LOADS AS MUCH OF
       LXI     H,0000          ;MEMORY WITH THE FILE AS POSSIBLE
       SHLD    MAX1
       LXI     H,ADDR3
       SHLD    TEMP
       XRA     A
       STA     EOF             ;CLEAR EOF FLAG
LOADNEXT2 LHLD  TEMP
       XCHG                    ;SET DMA ADDRESS
       MVI     C,1AH
       CALL    BDOS
       LXI     D,FLPFCB        ;READ THE FLOPPY
       MVI     C,14H
       CALL    BDOS
       ORA     A
       JNZ     HDEOF2          ;EOF?
       LHLD    TEMP
       LXI     D,LASTREC
       MVI     B,26            ;SEE IF THIS IS THE LASTREC OF LAST FILE
       CALL    COMPARE
       JZ      EOFHD
       LHLD    MAX1
       INX     H               ;INCREMENT RECORD COUNT
       SHLD    MAX1
       LHLD    TEMP            ;SEE IF NEXT RECORD WOULD EXCEED THE
       LXI     D,128           ;TPA AREA
       DAD     D
       SHLD    TEMP
       DAD     D               ;WILL THE NEXT RECORD OVERWRITE BDOS?
       XCHG
       LHLD    BDOS+1          ;FIND THE TOP OF MEMORY
       CALL    COMPREG         ;COMPARE REGISTERS
       RC                      ;RETURN IF MEMORY ALREADY FULL
       JMP     LOADNEXT2       ;GET ANOTHER RECORD
EOFHD   MVI     A,2
       STA     EOF
       RET
HDEOF2  MVI     A,1             ;SET FILE EOF
       STA     EOF
       RET

WRITEBUF2 EQU   $       ;WRITE FROM THE MEMORY BUFFER
       LXI     H,ADDR3
       SHLD    TEMP
       LHLD    MAX1            ;ALLOW FOR FILES THAT HAVE NO
       LXI     D,0000          ;RECORDS SUCH AS RESTART
       CALL    COMPREG
       RZ
WRITENEXT2 LHLD TEMP
       XCHG                    ;SET DMA ADDRESS
       MVI     C,1AH
       CALL    BDOS
       LXI     D,HDFCB
       MVI     C,15H           ;WRITE SEQUENTIAL
       CALL    BDOS
       ORA     A
       JNZ     FPFULL          ;FLOPPY DISK FULL
       LHLD    RECCNT
       INX     H
       SHLD    RECCNT
       LHLD    MAX1            ;DECREASE RECORD COUNT
       DCX     H
       SHLD    MAX1
       LXI     D,0000          ;CHECK FOR NO MORE TO WRITE
       CALL    COMPREG
       RZ
       LHLD    TEMP
       LXI     D,128           ;INCREMENT WRITE ADDRESS
       DAD     D
       SHLD    TEMP
       JMP     WRITENEXT2
FPFULL  MVI     A,2             ;FULL DISKETTE
       STA     EOF
       RET

COMPREG MOV     A,H             ;COMPARE HL TO DE
       CMP     D
       RNZ
       MOV     A,L
       CMP     E
       RET

OUTPUT  PUSH    D               ;PUT OUT A CRLF
       LXI     D,CRLF
       MVI     C,09
       CALL    BDOS
       POP     D               ;NOW PUT OUT THE MESSAGE
OUT1    MVI     C,09
       JMP     BDOS


QUESTION        CALL    OUTPUT  ;PUT OUT THE QUESTION
       LXI     D,INBUF
       MVI     C,0AH           ;INPUT THE REPLY
       CALL    BDOS
       LDA     INCNT
       RET

MOVE    PUSH    H               ;MOVE DATA POINTED TO IN HL
       PUSH    D               ;TO THE AREA POINTED TO IN DE
       PUSH    B               ;BY THE BYTE COUNT IN B
MOVE1   MOV     A,M
       STAX    D
       INX     H
       INX     D
       DCR     B
       JNZ     MOVE1
       POP     B               ;RESTORE THE TOTAL ENVIRONMENT
       POP     D
       POP     H
       RET

COMPARE PUSH    H               ;COMPARE THE STRINGS POINTED TO IN HL
       PUSH    D               ;TO THE STRING POINTED TO IN DE
       PUSH    B               ;FOR A LENGTH OF B CHARACTERS
COMP1   LDAX    D               ; JC IF HL > DE
       CMP     M               ; JZ IF HL = DE
       JNZ     COMP2           ;JNC IF HL < DE
       INX     H
       INX     D
       DCR     B
       JNZ     COMP1
COMP2   POP     B
       POP     D
       POP     H
       RET


CRLF    DB      CR,LF,'$'
ERROR1  DB      'INPUT ERROR...ENTER FILENAME.TYP/B OR /R',CR,LF,LF,'$'
ERROR2  DB      'FILE NOT FOUND',CR,LF,LF,'$'
ERROR3  DB      'NEEDS MORE THAN 255 FLOPPY DISKS',CR,LF,LF,'$'
ERROR4  DB      'DIRECTORY FULL',CR,LF,LF,'$'
ERROR5  DB      'FINISHED',CR,LF,LF,'$'
MSG0A   DB      'CONTAINING'
BAK     DB      'BAK'
MSG3A   DB      'RESTORE '
LASTREC DB      'ENDENDENDBIGBURSTENDENDEND'
MESSAGE1 DB     CR,LF,LF,'MOUNT THE DISKETTE '
MSG0    DB      'TO CONTAIN '
MSG1    DS      8
       DB      '.'
MSG2    DS      3
       DB      ' FOR '
MSG3    DB      'BACKUP  '
       DB      'AND HIT RETURN$'
MESSAGE2 DB     CR,LF,'FILE '
MSG4    DS      8
       DB      '.'
MSG5    DS      3
       DB      ' IS NOT ON THIS DISKETTE$'
SRCFLPMSG DB    'SOURCE FLOPPY DRIVE (DEFAULT='
SRCFLP  DB      'D) $'
DESTFLPMSG DB   'DESTINATION FLOPPY DRIVE (DEFAULT='
DESTFLP DB      'D) $'
DBMSG   DB      CR,LF
       DB      '00000$'
INBUF   DB      30
INCNT   DS      1
INREC   DS      30
FLOPPY  DS      1
RECCNT  DS      2
HOLDFCB DS      36
HDFCB   DS      36
BAKFCB  DS      48
FILECNT DS      1
FLPFCB  DS      36
TEMP    DS      2
TEMP2   DS      2
MPTY    DS      2
MAX1    DS      2
EOF     DS      1
STACK   DS      90
ADDR3   EQU     $
       END     100H