home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog-asm / assemtls.lzh / ASSEMTOOLS / ASOURCE / BACKUP.ASM < prev    next >
Encoding:
Assembly Source File  |  1991-08-16  |  38.7 KB  |  1,853 lines

  1. ;
  2. ; ### Backup v 1.221 ###
  3. ;
  4. ; - Created 881109 by JM -
  5. ;
  6. ;
  7. ; Copyright © 1988, 1989 by Supervisor Software
  8. ;
  9. ;
  10. ; For backuping a harddisk.  Written because it's a good habit to make some
  11. ; backups of one's harddisks from time to time.
  12. ;
  13. ;
  14. ; NOTES:
  15. ;
  16. ; - Trackdisk seems to need CMD_UPDATE ALWAYS after a track write although
  17. ;   some would think that is only needed after writing just few sectors.
  18. ;
  19. ; - I'm planning to visit... THERE!
  20. ;
  21. ; - I ain't any longer ... because of the ... CRASH
  22. ;
  23. ; - 1.22 Life goes on...  Where's Miki?
  24. ;
  25. ;
  26. ; BUGS:
  27. ;
  28. ; - None, I hope (And I REALLY DO because if my hard disk fails I will
  29. ;   need this to restore it...)
  30. ;
  31. ;
  32. ; Edited:
  33. ;
  34. ; - 881109 by JM -> v0.001    - Already loads and prints Dir (hew-hew).
  35. ;            v0.002    - Should handle subdirectories correctly.
  36. ;            v0.003    - If error, now UnLock()s correctly.
  37. ; - 881110 by JM -> v0.004    - File copy PushAway written, uses only 1 disk
  38. ; - 881110 by JM -> v0.005    - File copy RdMain started, uses only 1 disk
  39. ; - 881111 by JM -> v0.010    - File copy RdMain ready, uses many disks
  40. ;                - PushAway uses many disks
  41. ; - 881112 by JM -> v0.020    - CMD_UPDATE added to WriteCyl().  Now seems
  42. ;                  to work correctly.
  43. ;                - BackupAll and SetArchive options added.
  44. ;                - CmdLine parsing written by TM.
  45. ;                - Check mode added.
  46. ; - 881112 by JM -> v0.15    - Finally a version that seems to work.
  47. ; - 881113 by JM -> v0.30    - Disk ids added.
  48. ;                - CMDLine parser re-written by TM.
  49. ; - 881113 by JM -> v0.34    - Retry option added to trackdisk routines.
  50. ; - 881113 by JM -> v0.36    - Trackdisk Format added.
  51. ; - 881113 by JM -> v0.37    - Bug fixed in retry().
  52. ; - 881113 by JM -> v0.38    - Sets/checks A-flags of directories, too.
  53. ; - 881113 by JM -> v0.40    - Now only affects Archive flag.  Other
  54. ;                  flags remain unchanged.
  55. ; - 881113 by JM -> v0.50    - Some cleaning still made.
  56. ;                - Now counts the cylinders formatted and
  57. ;                  prints the # if not zero.
  58. ;                - Now also asks for the first backup disk,
  59. ;                  so it doesn't have to be in drive when
  60. ;                  the program is first started.
  61. ; - 881113 by JM -> v0.60    - Disk # mismatch fixed.
  62. ; - 881114 by JM -> v0.70    - Now writes fib_Protect and fib_DateStamp
  63. ;                  onto disk, too.  During restore sets prot
  64. ;                  flags.
  65. ;                - Does not start trackdisk.device at the
  66. ;                  beginning before asking for the first disk.
  67. ; - 881121 by JM -> v0.75    - After the Earthquake:
  68. ;                  Now option ALL causes all files to be read
  69. ;                  from a backup.  If the option is not used,
  70. ;                  only the files that don't exist on HD will
  71. ;                  be read.
  72. ; - 881121 by JM -> v0.80    - Verify added to WriteCyl().
  73. ;                - Now WriteCyl() always formats the cylinders.
  74. ;                - Now WriteCyl() automatically retries three
  75. ;                  times before asking the User to select
  76. ;                  retry or cancel.
  77. ; - 881122 by JM -> v1.0    - Minor bug fixes.
  78. ;                - Now writes DateStamp onto disk and checks
  79. ;                  it when reading (must be same on all disks
  80. ;                  of a backup).
  81. ;                - Now prints the drive which is being used
  82. ;                  when asking for backup disks.
  83. ;                - Now doesn't try to write EOP onto disk if
  84. ;                  an error has occurred.
  85. ;                - Now doesn't calc lengths of files not
  86. ;                  copied from backup.
  87. ; - 881203 by JM -> v1.1    - Now ALL directories are ALWAYS searched for
  88. ;                  files without Archive flags set.  This is
  89. ;                  because the Archive flag of parentparent
  90. ;                  dir a is not cleared if a/b/file is changed.
  91. ;                  This must be a bug of AmigaDOS (this system
  92. ;                  is not sensible).
  93. ; - 890121 by JM -> v1.2    - If a read error during backupping is encoun-
  94. ;                  tered the user can select Abort to exit the
  95. ;                  program or Continue to continue backupping
  96. ;                  with the next file.
  97. ;                - .s's added to relative branch intructions.
  98. ; - 890122 by JM -> v1.21    - If Read() gets less than fib_Size bytes from
  99. ;                  the file the user is informed and the space
  100. ;                  is filled with $ff's.
  101. ; - 890312 by JM -> v1.22    - Short branches, A68k compatibility.
  102. ; - 890706 by JM -> v1.221    - Converted to use relative.i.  Untested.
  103. ;
  104. ;
  105.  
  106.  
  107.         include    "dos.xref"
  108.         include    "exec.xref"
  109.         include "JMPLibs.i"
  110.         include    "string.i"
  111.         include    "numeric.i"
  112.         include    "relative.i"
  113.  
  114.         include "exec/types.i"
  115.         include "exec/nodes.i"
  116.         include "exec/lists.i"
  117.         include "exec/memory.i"
  118.         include "exec/interrupts.i"
  119.         include "exec/ports.i"
  120.         include "exec/libraries.i"
  121.         include "exec/io.i"
  122.         include "exec/tasks.i"
  123.         include "exec/execbase.i"
  124.         include "exec/devices.i"
  125.         include "devices/trackdisk.i"
  126.         include    "dos.i"
  127.  
  128.  
  129.  
  130. *************************************************************************
  131. *                                    *
  132. * Stack allocation for WrMain():                    *
  133. *                                    *
  134. *************************************************************************
  135.  
  136.         .var                alloc backwards
  137.         dl    bufmem            start of temp buffer
  138.         dl    lockptr            pointer to a lock
  139.         dl    locknam            pointer to new name of lock
  140.         dl    oldlock            pointer to original name of lock
  141.  
  142.  
  143.  
  144. CYL_SIZE    equ    512*11*2        bytes per cylinder
  145. TEMPSTR        equ    256
  146. PATHSTR        equ    256
  147. NAMESTR        equ    256
  148. TRACKBUF    equ    CYL_SIZE+TEMPSTR+NAMESTR+PATHSTR+256
  149. VERBUF        equ    CYL_SIZE+256
  150. WRMEM        equ    fib_SIZEOF+256
  151.  
  152. MAXUCYL        equ    79+1            highest + 1
  153.  
  154. LF        equ    10
  155. CR        equ    13
  156. CSI        equ    155
  157.  
  158. ;DEBUG        equ    1
  159.  
  160.  
  161.  
  162. *************************************************************************
  163. *                                    *
  164. * Macro definitions:                            *
  165. *                                    *
  166. *************************************************************************
  167.  
  168. strcpy        macro    *src,dst
  169. strcpy\@    move.b    (\1)+,(\2)+
  170.         bne    strcpy\@
  171.         endm
  172.  
  173. strcmp        macro    *src,dst
  174.         push    a0/a1/d0/d1
  175.         ifnc    '\1','a0'
  176.         move.l    \1,a0
  177.         endc
  178.         ifnc    '\2','a1'
  179.         move.l    \2,a1
  180.         endc
  181.         bsr    StrCmp
  182.         pull    a0/a1/d0/d1
  183.         endm
  184.  
  185.  
  186. dcbne        macro    hlong,llong,label
  187.         cmp.l    \1,d1
  188.         bne    \3
  189.         cmp.l    \2,d0
  190.         bne    \3
  191.         endm
  192.  
  193.  
  194. bug        macro
  195.         ifd    DEBUG
  196.         print    <\1>
  197.         endc
  198.         endm
  199.  
  200.  
  201.  
  202. *************************************************************************
  203. *                                    *
  204. * Program main entry:                            *
  205. *                                    *
  206. *************************************************************************
  207.  
  208. Start        push    d2-d7/a2-a6        save regs
  209.         move.l    d0,_CMDLen        len of cmd line
  210.         move.l    a0,_CMDBuf        start addr of cmd line
  211.         clr.b    -1(a0,d0.l)        add null
  212.         openlib Dos,cleanup        open Dos library
  213.  
  214.         print    <'Backup v1.221 © JM 1988,89',LF>
  215.  
  216.  
  217.         bsr    CreatePort
  218.         bcs    cleanup
  219.         ifd    DEBUG
  220.         bug    <'port created',10>
  221.         endc
  222.  
  223.         bsr    CreateIO
  224.         bcs    cleanup
  225.         ifd    DEBUG
  226.         bug    <'ioreq created',10>
  227.         endc
  228.  
  229.         bsr    Allocmem
  230.         bcs    cleanup
  231.         ifd    DEBUG
  232.         bug    <'mem reserved',10>
  233.         endc
  234.  
  235.         bsr    parse            parse command line parameters
  236.         bcs    cleanup
  237.         bsr    printvalues
  238.  
  239.  
  240.         lea    TDname(pc),a0        device name
  241.         move.l    unit(pc),d0        unit number
  242.         move.l    ioreq(pc),a1        *IORequest
  243.         moveq.l    #0,d1            flags (normally zero)
  244.         lib    Exec,OpenDevice
  245.         move.l    d0,TDOflag        flag: error opening TD.device
  246.         beq.s    TDopened
  247.         print    <'Can''t open trackdisk.device',LF>
  248.         bra.s    cleanup
  249.  
  250.  
  251. TDopened    move.b    command(pc),d0
  252.         cmp.b    #'w',d0
  253.         beq.s    BUWrite
  254.         cmp.b    #'r',d0
  255.         beq.s    BURead
  256.         cmp.b    #'c',d0
  257.         beq.s    BUCheck
  258.         bra.s    cleanup
  259.  
  260. BUWrite        clr.w    chkflag        make backup
  261.         bsr    WriteBup
  262.         bra.s    done
  263.  
  264. BURead        clr.w    chkflag        read backup
  265.         bsr    ReadBup
  266.         bra.s    done
  267.  
  268. BUCheck        move.w    #-1,chkflag    check backup
  269.         bsr    ReadBup
  270.         ;bra    done
  271.  
  272.  
  273.  
  274.  
  275. done        bsr    MotorOff
  276.  
  277. cleanup        move.l    TDOflag(pc),d0
  278.         bne.s    clean01
  279.         move.l    ioreq(pc),a1
  280.         lib    Exec,CloseDevice
  281.  
  282. clean01        bsr    DeleteIO
  283.         bsr    DeletePort
  284.         bsr    Freemem
  285.  
  286. clean99        closlib    Dos
  287.         pull    d2-d7/a2-a6
  288.         rts
  289.  
  290.  
  291.  
  292.  
  293. *************************************************************************
  294. *                                    *
  295. * Main subroutines etc.                            *
  296. *                                    *
  297. *************************************************************************
  298.  
  299. printvalues    
  300.         ifd    DEBUG
  301.         print    <LF,LF,'Parameter dump:',LF>
  302.         print    <'Path: "'>
  303.         printa    pbuf(pc)
  304.         print    <'"',LF,'Unit:'>
  305.         move.l    unit(pc),d0
  306.         bsr    print10
  307.         print    <LF,'Cmd:'>
  308.         printa    #command
  309.         print    <LF,'chkflag,allflag,verbose,arcflag:'>
  310.         moveq.l    #0,d0
  311.         move.w    chkflag(pc),d0
  312.         bsr    print10
  313.         moveq.l    #0,d0
  314.         move.w    allflag(pc),d0
  315.         bsr    print10
  316.         moveq.l    #0,d0
  317.         move.w    verbose(pc),d0
  318.         bsr    print10
  319.         moveq.l    #0,d0
  320.         move.w    arcflag(pc),d0
  321.         bsr    print10
  322.         print    <LF,LF>
  323.         endc
  324.         rts
  325.  
  326.  
  327.  
  328. CreatePort    push    d1-d3/a0-a3
  329.         moveq.l    #-1,d0
  330.         lib    Exec,AllocSignal
  331.         move.l    d0,d2
  332.         bmi.s    CreatePort_e
  333.         move.b    d0,signalbit
  334.         moveq.l    #MP_SIZE,d0
  335.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  336.         lib    Exec,AllocMem
  337.         move.l    d0,msgport
  338.         beq.s    CreatePort_e
  339.  
  340.         sub.l    a1,a1
  341.         lib    Exec,FindTask
  342.         move.l    d0,a0            my task
  343.  
  344.         move.l    msgport(pc),a1
  345.         move.l    a0,MP_SIGTASK(a1)
  346.         move.b    signalbit(pc),MP_SIGBIT(a1)
  347.         move.b    #NT_MSGPORT,LN_TYPE(a1)
  348.         move.b    #PA_SIGNAL,MP_FLAGS(a1)
  349.         move.l    a1,d0
  350.         lea    MP_MSGLIST(a1),a1
  351.         NEWLIST    a1
  352.         pull    d1-d3/a0-a3
  353.         clrc
  354.         rts
  355.  
  356. CreatePort_e    bsr.s    DeletePort
  357.         pull    d1-d3/a0-a3
  358.         setc
  359.         rts
  360.  
  361.  
  362. DeletePort    push    d0-d3/a0-a3
  363.         moveq.l    #0,d0
  364.         move.b    signalbit(pc),d0
  365.         bmi.s    DeletePort1
  366.         lib    Exec,FreeSignal
  367. DeletePort1    move.l    msgport(pc),d0
  368.         beq.s    DeletePort2
  369.         move.l    d0,a1
  370.         moveq.l    #MP_SIZE,d0
  371.         lib    Exec,FreeMem
  372. DeletePort2    move.b    #-1,signalbit
  373.         clr.l    msgport
  374.         pull    d0-d3/a0-a3
  375.         rts
  376.  
  377.  
  378.  
  379. CreateIO    push    d1-d3/a0-a3
  380.         moveq.l    #IOSTD_SIZE,d0
  381.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  382.         lib    Exec,AllocMem
  383.         move.l    d0,ioreq
  384.         beq.s    CreateIO_e
  385.         move.l    d0,a0
  386.         move.l    msgport(pc),MN_REPLYPORT(a0)
  387.         move.b    #NT_MESSAGE,LN_TYPE(a0)
  388.         move.w    #IOSTD_SIZE,MN_LENGTH(a0)
  389.         pull    d1-d3/a0-a3
  390.         clrc
  391.         rts
  392.  
  393. CreateIO_e    pull    d1-d3/a0-a3
  394.         setc
  395.         rts
  396.  
  397. DeleteIO    push    d1-d3/a0-a3
  398.         move.l    ioreq(pc),d0
  399.         beq.s    DeleteIO1
  400.         move.l    d0,a1
  401.         moveq.l    #IOSTD_SIZE,d0
  402.         lib    Exec,FreeMem
  403.         clr.l    ioreq
  404. DeleteIO1    pull    d1-d3/a0-a3
  405.         rts
  406.  
  407.  
  408.  
  409. Allocmem    push    all
  410.         move.l    #TRACKBUF,d0    alloc mem for trackbuf & other
  411.         move.l    #MEMF_CHIP,d1     buffers
  412.         lib    Exec,AllocMem
  413.         move.l    d0,trackbuf
  414.         move.l    d0,trackpoi
  415.         beq.s    Allocmem_e
  416.         add.l    #CYL_SIZE,d0
  417.         move.l    d0,trackend
  418.         add.l    #128,d0
  419.         move.l    d0,sbuf        for temp strings
  420.         add.l    #TEMPSTR,d0
  421.         move.l    d0,pbuf        for pathname
  422.         add.l    #PATHSTR,d0
  423.         move.l    d0,nbuf        for filename
  424.  
  425.         move.l    #VERBUF,d0    alloc mem for verify track buffer
  426.         move.l    #MEMF_CHIP,d1
  427.         lib    Exec,AllocMem
  428.         move.l    d0,verbuf
  429.         beq.s    Allocmem_e
  430.  
  431.         pull    all
  432.         clrc
  433.         rts
  434.  
  435. Allocmem_e    pull    all
  436.         setc
  437.         rts
  438.  
  439.  
  440.  
  441. Freemem        push    all
  442.         move.l    trackbuf(pc),d0
  443.         beq.s    Freemem1
  444.         move.l    d0,a1
  445.         move.l    #TRACKBUF,d0
  446.         lib    Exec,FreeMem
  447.         clr.l    trackbuf
  448. Freemem1    move.l    verbuf(pc),d0
  449.         beq.s    Freemem2
  450.         move.l    d0,a1
  451.         move.l    #VERBUF,d0
  452.         lib    Exec,FreeMem
  453.         clr.l    verbuf
  454. Freemem2    pull    all
  455.         rts
  456.  
  457.  
  458.  
  459.  
  460. MotorOn        push    all
  461.         move.l    ioreq(pc),a1
  462.         move.l    #1,IO_LENGTH(a1)
  463.         move.w    #TD_MOTOR,IO_COMMAND(a1)
  464.         lib    Exec,DoIO
  465.         pull    all
  466.         rts
  467.  
  468. MotorOff    push    all
  469.         move.l    ioreq(pc),a1
  470.         move.l    #0,IO_LENGTH(a1)
  471.         move.w    #TD_MOTOR,IO_COMMAND(a1)
  472.         lib    Exec,DoIO
  473.         pull    all
  474.         rts
  475.  
  476.  
  477. ReadCyl        push    all            cyl=d0
  478.         move.l    ioreq(pc),a1
  479.         mulu.w    #44,d0            multiply by 512*11*2
  480.         asl.l    #8,d0
  481.         move.l    d0,IO_OFFSET(a1)
  482.         move.l    #CYL_SIZE,IO_LENGTH(a1)    length = 1 cyl
  483.         move.l    trackbuf(pc),IO_DATA(a1)
  484.         move.w    #CMD_READ,IO_COMMAND(a1)
  485.         lib    Exec,DoIO
  486.         tst.l    d0
  487.         beq.s    ReadCyl_ok
  488.         print    <'*** Trackdisk error #'>
  489.         bsr    print10
  490.         print    <LF>
  491.         bra.s    ReadCyl_e
  492. ReadCyl_ok    pull    all
  493.         clrc
  494.         rts
  495.  
  496. ReadCyl_e    pull    all
  497.         move.l    d0,-(sp)
  498.         bsr    retry
  499.         bne.s    ReadCyl_ee
  500.         move.l    (sp)+,d0
  501.         bra    ReadCyl
  502. ReadCyl_ee    move.l    (sp)+,d0
  503.         setc
  504.         rts
  505.  
  506.  
  507.  
  508. WriteCyl    push    all                cyl=d0
  509.         move.l    d0,d7                save cyl#
  510. WriteCyl_Retry    moveq.l    #2,d6                retry counter
  511. WriteCyl_Rtr    move.l    ioreq(pc),a1
  512.         move.l    d7,d0
  513.         mulu.w    #44,d0                multiply by 512*11*2
  514.         asl.l    #8,d0
  515.         move.l    d0,IO_OFFSET(a1)
  516.         move.l    #CYL_SIZE,IO_LENGTH(a1)        length = 1 cyl
  517.         move.l    trackbuf(pc),IO_DATA(a1)
  518.         move.w    #TD_FORMAT,IO_COMMAND(a1)
  519.         move.l    a1,a2
  520.         lib    Exec,DoIO            write this cyl
  521.         tst.l    d0
  522.         bne.s    WriteCyl_e1            could not write it
  523.  
  524.         move.l    a2,a1
  525.         move.w    #CMD_UPDATE,IO_COMMAND(a1)    try to update
  526.         lib    Exec,DoIO
  527.         tst.l    d0
  528.         bne    WriteCyl_e2            could not update
  529.  
  530.         move.l    d7,d0                verify it
  531.         bsr    VeriCyl
  532.         bcs.s    WriteCyl_e3            verify error
  533.  
  534.         pull    all                OK, written ok
  535.         clrc
  536.         rts
  537.  
  538. WriteCyl_e1    cmp.w    #TDERR_WriteProt,d0
  539.         bne.s    WriteCyl_e2
  540.         print    <'*** Error: Disk write protected',LF>
  541.         bra.s    WriteCyl_ask
  542. WriteCyl_e3    print    <'*** Verify error -'>
  543. WriteCyl_e2    print    <' Retrying...',LF>
  544.         addq.l    #1,retrycnt
  545.         dbf    d6,WriteCyl_Rtr        retry operation
  546. WriteCyl_ask    bsr    retry
  547.         beq    WriteCyl_Retry        user wants us to retry again
  548.         pull    all
  549.         setc                - no success
  550.         rts
  551.  
  552.  
  553.  
  554.  
  555. VeriCyl        push    all            cyl=d0
  556.         move.l    verbuf(pc),a0        verify buffer
  557.         move.l    ioreq(pc),a1
  558.         mulu.w    #44,d0            multiply by 512*11*2
  559.         asl.l    #8,d0
  560.         move.l    d0,IO_OFFSET(a1)
  561.         move.l    #CYL_SIZE,IO_LENGTH(a1)    length = 1 cyl
  562.         move.l    a0,IO_DATA(a1)
  563.         move.w    #CMD_READ,IO_COMMAND(a1)
  564.         lib    Exec,DoIO
  565.         tst.l    d0
  566.         bne.s    VeriCyl_e    could not even read it
  567.         move.l    verbuf(pc),a0
  568.         move.l    trackbuf(pc),a1
  569.         move.w    #(CYL_SIZE/4)-1,d0
  570. VeriLoop    cmpm.l    (a0)+,(a1)+    compare each and every LONG
  571.         dbne    d0,VeriLoop
  572.         tst.w    d0
  573.         bpl.s    VeriCyl_e    error in data
  574. VeriCyl_ok    pull    all
  575.         clrc
  576.         rts
  577.  
  578. VeriCyl_e    pull    all
  579.         setc
  580.         rts
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587. *************************************************************************
  588. *                                    *
  589. * This routine reads files back from backup disks            *
  590. *                                    *
  591. *************************************************************************
  592.  
  593. ReadBup        push    all
  594.         moveq.l    #0,d0
  595.         move.w    d0,cyl            start at cyl#0
  596.         move.w    d0,dsk            start from disk #0
  597.         move.l    d0,files
  598.         move.l    d0,bytes
  599.         move.l    d0,dirs
  600.         moveq.l    #0,d7            filehandle*
  601.  
  602.         bsr    AskNextDisk
  603.  
  604.         move.l    trackbuf(pc),a4
  605.         move.l    a4,trackpoi
  606.  
  607.         moveq.l    #1,d0
  608.         bsr    ck_dsk            read in the first cylinder
  609.         bcs    RdMain_e
  610.  
  611. *************************************************************************
  612. *                                    *
  613. * NOTE:                                    *
  614. * If -a or ALL is not selected during restore operation, only those    *
  615. * files that don't exist on hard disk will be copied from backup.  This    *
  616. * is flagged by chkflag bit#0 which is set to 1 if the current file    *
  617. * should not be copied.                            *
  618. *                                    *
  619. *************************************************************************
  620.  
  621. RdMainLoop    bsr    ck_stop
  622.         bne    RdMain_e
  623.         andi.w    #-2,chkflag        reset special flag bit #0
  624.         move.l    sbuf(pc),a0
  625.         moveq.l    #16,d1
  626. RdMainPath    bsr    istr            read path chunk name
  627.         bcs    RdMain_e
  628.         lea    TYPE_PATH(pc),a0
  629.         move.l    sbuf(pc),a1
  630.         strcmp    a0,a1
  631.         bne    RdMainFile        path not found
  632.  
  633.         move.l    pbuf(pc),a0
  634.         moveq.l    #96,d1
  635. RdMain10    bsr    istr            get pathname
  636.         bcs    RdMain_e
  637.  
  638.         move.w    verbose(pc),d0
  639.         beq.s    RdMaVe1
  640.         print    <'Path "'>
  641.         printa    pbuf(pc)
  642.         print    <'"',LF>
  643.  
  644. RdMaVe1        move.l    sbuf(pc),a0        check for EOP
  645.         moveq.l    #16,d1
  646.         bsr    istr
  647.         lea    TYPE_EOP(pc),a0
  648.         move.l    sbuf(pc),a1
  649.         strcmp    a0,a1
  650.         bne    RdMain_e2        path syntax error
  651.         addq.l    #1,dirs
  652.         move.w    chkflag(pc),d0        if check, don't CreDir()
  653.         bne    RdMainLoop
  654.         bsr    CreDir            create dir if necessary
  655.         bra    RdMainLoop
  656.  
  657. RdMainFile    lea    TYPE_FILE(pc),a0
  658.         move.l    sbuf(pc),a1
  659.         strcmp    a0,a1
  660.         bne    RdMainEnd    is it the end then?
  661.  
  662.         move.l    nbuf(pc),a0
  663.         move.l    pbuf(pc),a1
  664.         strcpy    a1,a0        copy path into name buffer
  665.         subq.l    #1,a0
  666.         moveq.l    #64,d1
  667.         bsr    istr        input filename
  668.         bcs    RdMain_e4    cannot get filename
  669.  
  670.         move.w    verbose(pc),d0
  671.         beq.s    RdMaVe2
  672.         print    <'File "'>
  673.         printa    nbuf(pc)
  674.         print    <'"',LF>
  675.  
  676. RdMaVe2        bsr    ilong        get length of file
  677.         bcs    RdMain_e5
  678.         move.l    d0,d6        save length
  679.  
  680.         bsr    ilong        get protection status
  681.         bcs    RdMain_e5
  682.         move.l    d0,d5        save it in d5
  683.  
  684.         lea    mydate(pc),a0
  685.         bsr    ilong        get DateStamp
  686.         bcs    RdMain_e5
  687.         move.l    d0,(a0)+
  688.         bsr    ilong
  689.         bcs    RdMain_e5
  690.         move.l    d0,(a0)+
  691.         bsr    ilong
  692.         bcs    RdMain_e5
  693.         move.l    d0,(a0)
  694.  
  695.         move.w    chkflag(pc),d0    check if check mode
  696.         beq.s    RdMainCkAll
  697.         add.l    d6,bytes    add bytes in real check mode
  698.         bra.s    RdMainCopy
  699.  
  700. RdMainCkAll    move.w    allflag(pc),d0    check if all files should be read
  701.         bne.s    RdMainOpAlways    yes -> don't check if already exists
  702.  
  703.         move.l    nbuf(pc),d1    check if file already exists
  704.         moveq.l    #ACCESS_READ,d2
  705.         lib    Dos,Lock
  706.         move.l    d0,d1
  707.         beq.s    RdMainOpAlways    it doesn't exist
  708.         moveq.l    #1,d0
  709.         move.w    d0,chkflag    prevent copying file
  710.         lib    Dos,UnLock
  711.         bra.s    RdMainCopy    don't open file!
  712.  
  713. RdMainOpAlways    move.l    nbuf(pc),d1
  714.         move.l    #MODE_NEWFILE,d2
  715.         lib    Dos,Open
  716.         move.l    d0,d7
  717.         beq    RdMain_e6
  718.  
  719. RdMainCopy    bsr    ck_stop
  720.         bne    RdMain_e
  721.  
  722.         move.l    d7,d1        file
  723.         move.l    a4,d2        buffer
  724.         move.l    d6,d3        length needed
  725.         move.l    trackend(pc),d4
  726.         sub.l    a4,d4        max length that can be got now
  727.         cmp.l    d3,d4
  728.         bhs.s    RdMainCopy0    OK, we can get all we need
  729.         move.l    d4,d3        sorry, we can get only d4 bytes!
  730.  
  731. RdMainCopy0    move.w    chkflag(pc),d0    if check mode, don't write anything!
  732.         beq.s    RdMainCopy0Wr
  733.         move.l    d3,d0
  734.         bra.s    RdMainCopy0NWr
  735. RdMainCopy0Wr    lib    Dos,Write
  736.         add.l    d0,bytes    these bytes actually read
  737.         cmp.l    d0,d3
  738.         bne    RdMain_e7
  739. RdMainCopy0NWr    add.l    d0,a4
  740.         sub.l    d0,d6        sub from total length
  741.         cmp.l    trackend(pc),a4
  742.         blo.s    RdMainCopy1
  743.         bsr    RCyl
  744.         bcs    RdMain_e
  745. RdMainCopy1    tst.l    d6        still bytes left for this file?
  746.         bne    RdMainCopy    do all blocks
  747.  
  748.         move.l    d7,d1
  749.         beq.s    RdMainNoClose
  750.         lib    Dos,Close
  751. RdMainNoClose    moveq.l    #0,d7
  752.  
  753.         move.l    sbuf(pc),a0
  754.         moveq.l    #16,d1
  755.         bsr    istr
  756.         bcs    RdMain_e8
  757.         move.l    sbuf(pc),a0
  758.         lea    TYPE_EOF(pc),a1
  759.         strcmp    a0,a1
  760.         bne    RdMain_e9        no EOF found
  761.         addq.l    #1,files
  762.  
  763.         move.w    chkflag(pc),d0        check -> goto loop
  764.         bne    RdMainLoop
  765.  
  766.         move.l    nbuf(pc),d1        name
  767.         move.l    d5,d2            flags
  768.         move.w    arcflag(pc),d0        no set arc -> do not set it!
  769.         beq.s    RdMainDNS
  770.         bset    #FIBB_ARCHIVE,d2
  771. RdMainDNS    lib    Dos,SetProtection
  772.  
  773.         bra    RdMainLoop
  774.  
  775.  
  776. RdMainEnd    lea    TYPE_END(pc),a0
  777.         move.l    sbuf(pc),a1
  778.         strcmp    a0,a1        not path, end, nor file
  779.         bne    RdMain_e3     - what is it then?
  780.  
  781.         print    <LF,'End of Backup found.',LF,'All done.',LF>
  782.  
  783.         bsr    PrintStat
  784.  
  785. RdMain_x    clrc
  786.         pull    all
  787.         rts
  788.  
  789. RdMain_e1    print    <'*** Path not found',LF>
  790.         bra    RdMain_e
  791. RdMain_e2    print    <'*** End of path not found',LF>
  792.         bra    RdMain_e
  793. RdMain_e3    print    <'*** Unknown Chunk',LF>
  794.         bra    RdMain_e
  795. RdMain_e4    print    <'*** Cannot get filename',LF>
  796.         bra    RdMain_e
  797. RdMain_e5    print    <'*** Cannot get file parameters',LF>
  798.         bra    RdMain_e
  799. RdMain_e6    print    <'*** Cannot create file',LF>
  800.         bra    RdMain_e
  801. RdMain_e7    print    <'*** Error writing file',LF>
  802.         bra.s    RdMain_e
  803. RdMain_e8    print    <'*** Cannot read EOF',LF>
  804.         bra.s    RdMain_e
  805. RdMain_e9    print    <'*** No EOF found',LF>
  806.  
  807. RdMain_e    move.l    d7,d1
  808.         beq.s    RdMain_ee
  809.         lib    Dos,Close
  810.         moveq.l    #0,d7
  811. RdMain_ee    setc
  812.         pull    all
  813.         rts
  814.  
  815.  
  816.  
  817. *************************************************************************
  818. *                                    *
  819. * This routine creates the backup (this is the main entry).        *
  820. *                                    *
  821. *************************************************************************
  822.  
  823. WriteBup    lea    ctime(pc),a0        obtain current time
  824.         move.l    a0,d1
  825.         lib    Dos,DateStamp
  826.  
  827.         moveq.l    #0,d0
  828.         move.w    d0,cyl            start at cyl #0
  829.         move.w    d0,dsk            start from disk #0
  830.         move.l    d0,retrycnt        no retries done yet
  831.         addq.l    #1,d0
  832.         move.l    d0,dirs            already in first dir
  833.  
  834.         bsr    AskNextDisk
  835.  
  836.         bsr    WID            write disk ID
  837.  
  838.         move.l    pbuf(pc),a1
  839.         tst.b    (a1)
  840.         beq.s    WrMp_ok            if path=NULL, no slash needed!
  841. WrMp1        tst.b    (a1)+
  842.         bne.s    WrMp1
  843.         move.b    -2(a1),d0
  844.         cmp.b    #':',d0
  845.         beq.s    WrMp_ok
  846.         cmp.b    #'/',d0
  847.         beq.s    WrMp_ok
  848.         move.b    #'/',-1(a1)        add slash if needed
  849.         clr.b    (a1)
  850.  
  851. WrMp_ok        move.l    pbuf(pc),a1
  852.         bsr    PushPath
  853.  
  854.         move.l    pbuf(pc),d1        main lock name ###
  855.         moveq.l    #ACCESS_READ,d2
  856.         lib    Dos,Lock
  857.         tst.l    d0
  858.         bne.s    WrMLock_ok
  859.         print    <'*** Cannot get Main lock ***',LF>
  860.         setc
  861.         rts
  862.  
  863. WrMLock_ok    move.l    pbuf(pc),a0        lock path; d0=lockptr ###
  864.         bsr.s    WrMain
  865.         bcs.s    WrMain_rror
  866.  
  867.         bsr    PushEnd            don't try this if already error
  868.  
  869. WrMain_rror    move.l    d0,d1
  870.         lib    Dos,UnLock
  871.  
  872.         bsr    PrintStat
  873.  
  874.         clrc
  875.         rts
  876.  
  877.  
  878.  
  879. *************************************************************************
  880. *                                    *
  881. * This routine creates the backup (this is the re-entrant subroutine)    *
  882. *                                    *
  883. *************************************************************************
  884.  
  885. WrMain        .begin            alloc mem for temp usage
  886.         push    a0-a3/a5/d0-d7
  887.  
  888.         move.l    d0,lockptr(a4)        save lock
  889.         move.l    a0,oldlock(a4)        pathname of old lock
  890.  
  891.         moveq.l    #0,d5            files
  892.         moveq.l    #0,d6            dirs
  893.         moveq.l    #0,d7            bytes in files
  894.  
  895.         move.l    #WRMEM,d0
  896.         move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  897.         lib    Exec,AllocMem
  898.         move.l    d0,bufmem(a4)
  899.         beq    WrMain_e
  900.  
  901.         add.l    #fib_SIZEOF,d0
  902.         move.l    d0,locknam(a4)        space for lock dir pathname
  903.  
  904.         move.l    oldlock(a4),a0        backup name path
  905.         move.l    locknam(a4),a1
  906.         strcpy    a0,a1            get a copy of lock name
  907.         subq.l    #1,a1
  908.         move.l    a1,oldlock(a4)        now points to end of oldlock
  909.  
  910.         move.l    lockptr(a4),d1
  911.         move.l    bufmem(a4),d2        space for fib
  912.         lib    Dos,Examine
  913.         tst.l    d0
  914.         beq    WrMain_e1        can't Examine()
  915.  
  916.         move.l    bufmem(a4),a5        fib
  917.         tst.l    fib_DirEntryType(a5)    a dir?
  918.         bmi    WrMain_e2        this is a file!
  919.  
  920. WrMainNextFile    bsr    ck_stop            *Handle files in this loop
  921.         bne    WrMain_e        stopped?
  922.         move.l    lockptr(a4),d1
  923.         move.l    a5,d2
  924.         lib    Dos,ExNext
  925.         tst.l    d0
  926.         beq.s    WrMain_Dir        no_more_entries maybe
  927.  
  928.         tst.l    fib_DirEntryType(a5)    a dir?
  929.         bpl.s    WrMainNextFile        yes, skip it
  930.  
  931.         lea    fib_FileName(a5),a0
  932.         move.l    oldlock(a4),a1
  933.         strcpy    a0,a1
  934.  
  935.         move.w    allflag(pc),d0        check if all files must be
  936.         bne.s    WrMainAlw         copied (or only those with
  937.         move.l    fib_Protection(a5),d0     archive=0)
  938.         btst    #FIBB_ARCHIVE,d0
  939.         bne.s    WrMainNThis        
  940.  
  941. WrMainAlw    move.l    a5,a0            fib*
  942.         move.l    locknam(a4),a1        path/file
  943.         bsr    PushAway
  944.         bcs    WrMain_e        if error or stopped
  945.         addq.l    #1,d5            one more file!
  946.         add.l    fib_Size(a5),d7        more bytes...
  947.  
  948. WrMainNThis    move.l    oldlock(a4),a0
  949.         clr.b    (a0)            remove filename
  950.  
  951.         bra    WrMainNextFile        handle all files on this level
  952.  
  953.  
  954. WrMain_Dir    move.l    lockptr(a4),d1        Start at beginning for Dirs
  955.         move.l    bufmem(a4),d2        space for fib
  956.         lib    Dos,Examine
  957.         tst.l    d0
  958.         beq    WrMain_e1        can't Examine()
  959.  
  960. WrMainNextDir    bsr    ck_stop            *Handle directories in this loop
  961.         bne    WrMain_e        stopped?
  962.         move.l    lockptr(a4),d1
  963.         move.l    a5,d2
  964.         lib    Dos,ExNext
  965.         tst.l    d0
  966.         beq    WrMain_x        no_more_entries maybe
  967.  
  968.         tst.l    fib_DirEntryType(a5)    a file?
  969.         bmi.s    WrMainNextDir        yes, skip it
  970.  
  971.         addq.l    #1,d6            one more dir!
  972.  
  973.         lea    fib_FileName(a5),a0    start of path extension
  974.         move.l    oldlock(a4),a1        end of previous path
  975.  
  976.         strcpy    a0,a1            add a new name
  977.         subq.l    #1,a1
  978.         move.b    -1(a1),d0        If ends with / or : no slash
  979.         cmp.b    #'/',d0             must be added!
  980.         beq.s    WrMain_NoLPath
  981.         cmp.b    #':',d0
  982.         beq.s    WrMain_NoLPath
  983.         move.b    #'/',(a1)+        add a slash!
  984.         clr.b    (a1)            ...and a NULL
  985.  
  986. WrMain_NoLPath    move.w    allflag(pc),d0        check if all dirs must be
  987. ;        bne    WrMainAlDir         copied (or only those with
  988. ;        move.l    fib_Protection(a5),d0     archive=0)
  989. ;        btst    #FIBB_ARCHIVE,d0
  990. ;        bne    WrMainNextDir
  991.  
  992. *************************************************************************
  993. *                                    *
  994. * NOTE:  There seems to be a bug in AmigaDOS 1.2:            *
  995. *     When a file A in dir B is changed, the Archive flags of both    *
  996. *     the file and the dir B are reset.  That's perfectly well.    *
  997. *     But if the dir B was located in dir C, the Archive flag of dir    *
  998. *     C was NOT reset!!!  So we need to search through all direct-    *
  999. *     ories ALTHOUGH their A-flags have been set.            *
  1000. *     Maybe that'll change on 1.3.                    *
  1001. *                                    *
  1002. *************************************************************************
  1003.  
  1004.  
  1005. WrMainAlDir    move.l    locknam(a4),a1
  1006.         bsr    PushPath        write new path name
  1007.         bcs    WrMain_e
  1008.  
  1009.         move.l    locknam(a4),d1
  1010.         moveq.l    #ACCESS_READ,d2
  1011.         lib    Dos,Lock
  1012.         tst.l    d0
  1013.         beq    WrMain_e3        can't Lock()
  1014.         move.l    locknam(a4),a0
  1015.         bsr    WrMain
  1016.         bcs.s    WrMain__e
  1017.         move.l    d0,d1
  1018.         lib    Dos,UnLock
  1019.  
  1020.         move.w    arcflag(pc),d0        need A-flag?
  1021.         beq    WrMainNextDir        no -> jump
  1022.  
  1023.         move.l    locknam(a4),a0
  1024.         move.l    sbuf(pc),a1
  1025.         strcpy    a0,a1            copy dir name
  1026.         cmp.b    #'/',-2(a1)
  1027.         bne.s    1$
  1028.         clr.b    -2(a1)            remove '/'
  1029. 1$        move.l    sbuf(pc),d1
  1030.         move.l    fib_Protection(a5),d2
  1031.         bset    #FIBB_ARCHIVE,d2    set A-flag, others unchanged
  1032.         lib    Dos,SetProtection    set flag: archived
  1033.         bra    WrMainNextDir
  1034.  
  1035. WrMain__e    move.l    d0,d1            Remember to UnLock() also if
  1036.         lib    Dos,UnLock         an error occurred!
  1037.         bra    WrMain_e
  1038.  
  1039.  
  1040.  
  1041. WrMain_e1    print    <'*** Cannot Examine()',LF>
  1042.         bra.s    WrMain_e
  1043. WrMain_e2    print    <'*** This is a file!',LF>
  1044.         bra.s    WrMain_e
  1045. WrMain_e3    print    <'*** Cannot Lock()',LF>
  1046.  
  1047. WrMain_e    bsr    addstat            adds # of files, dirs and bytes
  1048.         move.l    bufmem(a4),d0
  1049.         beq.s    WrMain_ee1
  1050.         move.l    d0,a1
  1051.         move.l    #WRMEM,d0
  1052.         lib    Exec,FreeMem
  1053. WrMain_ee1    pull    a0-a3/a5/d0-d7
  1054.         .end
  1055.         setc
  1056.         rts
  1057.  
  1058.  
  1059. WrMain_x    bsr    addstat
  1060.         move.l    bufmem(a4),d0
  1061.         beq.s    WrMain_x1
  1062.         move.l    d0,a1
  1063.         move.l    #WRMEM,d0
  1064.         lib    Exec,FreeMem
  1065. WrMain_x1    pull    a0-a3/a5/d0-d7
  1066.         .end
  1067.         clrc
  1068.         rts
  1069.  
  1070.  
  1071.  
  1072. *************************************************************************
  1073. *                                    *
  1074. * This routine copies a given file onto disk.                *
  1075. *                                    *
  1076. *************************************************************************
  1077.  
  1078. PushAway    push    all
  1079.         move.l    a0,a5            fib*
  1080.         move.l    a1,a3            path/name*
  1081.         moveq.l    #0,d7
  1082.         move.l    trackpoi(pc),a4
  1083.         lea    TYPE_FILE(pc),a0    data type: FILE
  1084.         bsr    ostr
  1085.         bcs    PushAw_e
  1086.  
  1087.         lea    fib_FileName(a5),a0    write name
  1088.         bsr    ostr
  1089.         bcs    PushAw_e
  1090.  
  1091.         move.l    fib_Size(a5),d0        size of file
  1092.         move.l    d0,d6
  1093.         bsr    olong            output it
  1094.         bcs    PushAw_e
  1095.  
  1096.         move.l    fib_Protection(a5),d0    protection of file
  1097.         bsr    olong            output it
  1098.         bcs    PushAw_e
  1099.  
  1100.         move.l    fib_DateStamp(a5),d0    creation date of file
  1101.         bsr    olong            output it
  1102.         bcs    PushAw_e
  1103.         move.l    fib_DateStamp+4(a5),d0    creation date of file
  1104.         bsr    olong            output it
  1105.         bcs    PushAw_e
  1106.         move.l    fib_DateStamp+8(a5),d0    creation date of file
  1107.         bsr    olong            output it
  1108.         bcs    PushAw_e
  1109.  
  1110.         move.w    verbose(pc),d0
  1111.         beq.s    PushVe1
  1112.         print    <'Copying "'>
  1113.         printa    a3
  1114.  
  1115. PushVe1        move.l    a3,d1
  1116.         move.l    #MODE_OLDFILE,d2
  1117.         lib    Dos,Open
  1118.         move.l    d0,d7            file handle
  1119.         beq    PushAw_e1        not found
  1120.  
  1121.         move.w    verbose(pc),d0
  1122.         beq.s    PushAw1
  1123.         print    <'"',LF>
  1124.  
  1125. PushAw1        bsr    ck_stop
  1126.         bne    PushAw_e
  1127.         move.l    d7,d1            file
  1128.         move.l    a4,d2            buffer
  1129.         move.l    trackend(pc),d3        length
  1130.         sub.l    d2,d3
  1131.         lib    Dos,Read
  1132.         tst.l    d0
  1133.         bls.s    PushAw2            end-of-file or error
  1134.         add.l    d0,a4
  1135.         sub.l    d0,d6            sub from total length
  1136.         cmp.l    trackend(pc),a4
  1137.         blo.s    PushAw3            track buffer not yet full
  1138.         bsr    WCyl
  1139.         bcc.s    PushAw1            next block of file
  1140.         bra    PushAw_e
  1141.  
  1142. PushAw2        bmi.s    PushAw_e2        read error
  1143. PushAw3        tst.l    d6
  1144.         bne.s    PushAw_e2        should be more bytes!
  1145. PushReco    lea    TYPE_EOF(pc),a0
  1146.         bsr    ostr            end of file!
  1147.         move.l    d7,d1
  1148.         lib    Dos,Close
  1149.         moveq.l    #0,d7
  1150.  
  1151.         move.w    arcflag(pc),d0        need to set A-flag?
  1152.         beq.s    PushNSet        no -> jump
  1153.         move.l    a3,d1
  1154.         move.l    fib_Protection(a5),d2
  1155.         bset    #FIBB_ARCHIVE,d2    set A-flag, others unchanged
  1156.         lib    Dos,SetProtection    set flag: archived
  1157.  
  1158. PushNSet    move.l    a4,trackpoi
  1159.         pull    all
  1160.         clrc
  1161.         rts
  1162.  
  1163. PushAw_e2    move.l    d7,d1        read error. must fill the spc with $ff's
  1164.         beq.s    PushAw_e21
  1165.         lib    Dos,Close
  1166.         moveq.l    #0,d7
  1167. PushAw_e21    print    <'*** Error reading file.  Press A ',60,'return',62,LF>
  1168.         print    <'    to abort or ',60,'return',62,' to continue. '>
  1169.         bsr    getret
  1170.         cmp.b    #'A',d0
  1171.         beq    PushAw_eq
  1172.         cmp.b    #'a',d0
  1173.         beq    PushAw_eq
  1174.         tst.l    d6
  1175.         beq    PushReco
  1176. PushDummy    moveq.l    #-1,d0            write dummy bytes
  1177.         bsr    ochr
  1178.         bcs    PushAw_e
  1179.         subq.l    #1,d6
  1180.         bne.s    PushDummy
  1181.         bra    PushReco
  1182.  
  1183. PushAw_e1    move.w    verbose(pc),d0
  1184.         beq.s    PushVe2
  1185.         print    <'" *** not found',LF>
  1186.         bra.s    PushAw_eq
  1187. PushVe2        print    <'*** Internal Error: File not Found',LF>
  1188. PushAw_eq    move.l    a4,trackpoi
  1189. PushAw_e    move.l    d7,d1
  1190.         beq.s    PushAw_ee
  1191.         lib    Dos,Close
  1192.         moveq.l    #0,d7
  1193. PushAw_ee    pull    all
  1194.         setc
  1195.         rts
  1196.  
  1197.  
  1198.  
  1199.  
  1200. *************************************************************************
  1201. *                                    *
  1202. * Miscellaneous subroutines.                        *
  1203. *                                    *
  1204. *************************************************************************
  1205.  
  1206. PushPath    push    all            writes path onto disk
  1207.         move.l    trackpoi(pc),a4
  1208.         move.l    a1,a3            pathname*
  1209.         lea    TYPE_PATH(pc),a0
  1210.         bsr    ostr
  1211.         bcs.s    PushPa_e
  1212.         move.l    a3,a0
  1213.         bsr    ostr
  1214.         bcs.s    PushPa_e
  1215.         lea    TYPE_EOP(pc),a0
  1216.         bsr    ostr
  1217.         bcs.s    PushPa_e
  1218.         move.l    a4,trackpoi
  1219.         pull    all
  1220.         rts
  1221. PushPa_e    move.l    a4,trackpoi
  1222.         pull    all
  1223.         setc
  1224.         rts
  1225.  
  1226.  
  1227. PushEnd        push    all            writes endmark onto disk
  1228.         move.l    trackpoi(pc),a4
  1229.         lea    TYPE_END(pc),a0
  1230.         bsr    ostr
  1231.         bcs.s    PushEnd_e
  1232.         cmp.l    trackbuf(pc),a4
  1233.         beq.s    PushEnd_ok
  1234.         bsr    WCyl
  1235.         move.l    a4,trackpoi
  1236. PushEnd_ok    clrc
  1237.         pull    all
  1238.         rts
  1239. PushEnd_e    move.l    a4,trackpoi
  1240.         pull    all
  1241.         setc
  1242.         rts
  1243.  
  1244.  
  1245.  
  1246. CreDir        push    all        creates a directory if needed
  1247.         move.l    pbuf(pc),a0
  1248.         move.l    sbuf(pc),a1
  1249.         strcpy    a0,a1        copy of new path        
  1250.         cmp.b    #'/',-2(a1)
  1251.         bne.s    CreDir1
  1252.         clr.b    -2(a1)
  1253. CreDir1        move.l    sbuf(pc),d1
  1254.         moveq.l    #ACCESS_READ,d2
  1255.         lib    Dos,Lock
  1256.         move.l    d0,d7        lock*
  1257.         bne.s    CreDir2        it already exists!
  1258.  
  1259.         move.l    sbuf(pc),d1
  1260.         lib    Dos,CreateDir
  1261.         move.l    d0,d7
  1262.         beq.s    CreDir_e
  1263.  
  1264.         move.w    verbose(pc),d0
  1265.         beq.s    CreDir2
  1266.         print    <'# Directory created...',LF>
  1267.  
  1268. CreDir2        move.l    d7,d1
  1269.         beq.s    CreDir3
  1270.         lib    Dos,UnLock
  1271. CreDir3        pull    all
  1272.         rts
  1273. CreDir_e    print    <'*** Cannot create directory "'>
  1274.         printa    sbuf(pc)
  1275.         print    <'"',LF>
  1276.         bra    CreDir3
  1277.  
  1278.  
  1279.  
  1280. ostr        move.b    (a0)+,d0
  1281.         bsr.s    ochr
  1282.         bcs.s    ostr_e
  1283.         bne.s    ostr
  1284. ostr_e        rts
  1285.  
  1286.  
  1287. ochr        push    a0-a1/d0-d1
  1288.         move.b    d0,(a4)+
  1289.         cmp.l    trackend(pc),a4
  1290.         blo.s    ochr_ok
  1291.         bsr.s    WCyl
  1292.         bcs.s    ochr_e
  1293. ochr_ok        pull    a0-a1/d0-d1
  1294.         tst.b    d0
  1295.         clrc
  1296.         rts
  1297. ochr_e        pull    a0-a1/d0-d1
  1298.         tst.b    d0
  1299.         setc
  1300.         rts
  1301.  
  1302.  
  1303. olong        push    d0-d1
  1304.         move.l    d0,d1
  1305.         rol.l    #8,d1
  1306.         move.b    d1,d0
  1307.         bsr.s    ochr        MSB
  1308.         bcs.s    olong_e
  1309.         rol.l    #8,d1
  1310.         move.b    d1,d0
  1311.         bsr.s    ochr        2. MSB
  1312.         bcs.s    olong_e
  1313.         rol.l    #8,d1
  1314.         move.b    d1,d0
  1315.         bsr.s    ochr        3. MSB
  1316.         bcs.s    olong_e
  1317.         rol.l    #8,d1
  1318.         move.b    d1,d0
  1319.         bsr.s    ochr        LSB
  1320. olong_e        pull    d0-d1
  1321.         rts
  1322.  
  1323.  
  1324.  
  1325. WCyl        push    a0-a1/d0-d1
  1326.         move.l    trackbuf(pc),a0
  1327.         lea    cyl(pc),a1
  1328.         move.l    a0,a4
  1329.         moveq.l    #0,d0
  1330.         move.w    (a1),d0
  1331.         bsr    WriteCyl
  1332.         bcs.s    WCyl_e
  1333.         addq.w    #1,(a1)
  1334.         cmp.w    #MAXUCYL,(a1)
  1335.         blo.s    WCyl_ok
  1336.         clr.w    (a1)
  1337.         bsr    AskNextDisk
  1338.         print    <'### Thanks... continuing',LF,LF>
  1339.         bsr    WID        write ID
  1340.         bcs.s    WCyl_e
  1341. WCyl_ok        clrc
  1342.         pull    a0-a1/d0-d1
  1343.         rts
  1344. WCyl_e        pull    a0-a1/d0-d1
  1345.         setc
  1346.         rts
  1347.  
  1348.  
  1349. RCyl        push    a0-a1/d0-d1
  1350.         lea    cyl(pc),a1
  1351.         cmp.w    #MAXUCYL,(a1)
  1352.         blo.s    RCyl_1
  1353.         clr.w    (a1)
  1354.         bsr.s    AskNextDisk
  1355.         move.l    trackbuf(pc),a4
  1356.         moveq.l    #0,d0
  1357.         move.w    dsk(pc),d0
  1358.         bsr    ck_dsk
  1359.         bcs.s    RCyl_e
  1360.         print    <'### Thanks... continuing',LF,LF>
  1361.         bra.s    RCyl_ok
  1362. RCyl_1        move.l    trackbuf(pc),a0
  1363.         move.l    a0,a4
  1364.         moveq.l    #0,d0
  1365.         move.w    (a1),d0
  1366.         bsr    ReadCyl
  1367.         bcs.s    RCyl_e
  1368.         addq.w    #1,(a1)
  1369. RCyl_ok        clrc
  1370.         pull    a0-a1/d0-d1
  1371.         rts
  1372. RCyl_e        pull    a0-a1/d0-d1
  1373.         setc
  1374.         rts
  1375.  
  1376.  
  1377.  
  1378. AskNextDisk    push    all
  1379.         bsr    MotorOff
  1380.         addq.w    #1,dsk
  1381.         print    <LF,'### Please insert backup disk #'>
  1382.         moveq.l    #0,d0
  1383.         move.w    dsk(pc),d0
  1384.         bsr    print10
  1385.         print    <' into drive DF'>
  1386.         move.l    unit(pc),d0
  1387.         bsr    print10
  1388.         print    <': and hit RETURN:'>
  1389.         bsr    getret
  1390.         bsr    MotorOn
  1391.         pull    all
  1392.         rts
  1393.  
  1394.  
  1395.  
  1396. ck_dsk        push    a0/a1/d0-d7
  1397.         move.l    d0,d7            dsk number
  1398. ck_dsk0        moveq.l    #0,d0
  1399.         move.l    trackbuf(pc),a0
  1400.         move.l    a0,a4
  1401.         bsr    ReadCyl
  1402.         bcs    ck_dsk_e
  1403.         move.l    sbuf(pc),a0
  1404.         move.l    #TEMPSTR-2,d1
  1405.         bsr    istr
  1406.         move.l    sbuf(pc),a0
  1407.         lea    DSKID(pc),a1
  1408.         strcmp    a0,a1
  1409.         beq.s    ck_dsk1            id ok.
  1410.         bsr    MotorOff
  1411.         print    <'*** Disk id mismatch - not a backup disk',LF>
  1412.         bra    ck_dsk_q
  1413.  
  1414. ck_dsk1        bsr    ilong            disk#
  1415.         cmp.l    d0,d7
  1416.         beq.s    ck_dsk2
  1417.         bsr    MotorOff
  1418.         print    <'*** Wrong backup disk number',LF>
  1419.         bra.s    ck_dsk_q
  1420.  
  1421. ck_dsk2        lea    ctime(pc),a0        addr of DateStamp
  1422.         tst.l    (a0)
  1423.         bpl.s    ck_dsk3            -> check if same date/time
  1424.         bsr    ck_dsk9
  1425.         bcs.s    ck_dsk_e
  1426.         move.l    d1,(a0)+        read DateStamp from first disk
  1427.         move.l    d2,(a0)+
  1428.         move.l    d3,(a0)+
  1429.         bra.s    ck_dsk_ok
  1430.  
  1431. ck_dsk3        bsr    ck_dsk9            compare DateStamps
  1432.         cmp.l    (a0)+,d1
  1433.         bne.s    ck_dsk_ed
  1434.         cmp.l    (a0)+,d2
  1435.         bne.s    ck_dsk_ed
  1436.         cmp.l    (a0)+,d3
  1437.         bne.s    ck_dsk_ed
  1438.  
  1439. ck_dsk_ok    move.w    #1,cyl
  1440.         clrc
  1441.         pull    a0/a1/d0-d7
  1442.         rts
  1443.  
  1444. ck_dsk_ed    bsr    MotorOff
  1445.         print    <'*** Wrong date of backup on disk',LF>
  1446.  
  1447. ck_dsk_q    bsr    retry
  1448.         bne.s    ck_dsk_e
  1449.         bsr    MotorOn
  1450.         bra    ck_dsk0
  1451.  
  1452. ck_dsk_e    move.w    #1,cyl            error: this disk won't do!
  1453.         setc
  1454.         pull    a0/a1/d0-d7
  1455.         rts
  1456.  
  1457. ck_dsk9        bsr    ilong        read date when backup was created
  1458.         bcs.s    ck_dsk9e
  1459.         move.l    d0,d1
  1460.         bsr    ilong
  1461.         bcs.s    ck_dsk9e
  1462.         move.l    d0,d2
  1463.         bsr    ilong
  1464.         bcs.s    ck_dsk9e
  1465.         move.l    d0,d3
  1466. ck_dsk9e    rts
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472. WID        push    a0/a1/d0-d7
  1473.         move.l    trackbuf(pc),a4
  1474.         lea    DSKID(pc),a0        write disk id
  1475.         bsr    ostr
  1476.         bcs.s    WID_e
  1477.         moveq.l    #0,d0
  1478.         move.w    dsk(pc),d0        write disk number
  1479.         bsr    olong
  1480.         bcs.s    WID_e
  1481.  
  1482.         lea    ctime(pc),a0        write backup time
  1483.         move.l    (a0)+,d0
  1484.         bsr    olong
  1485.         bcs.s    WID_e
  1486.         move.l    (a0)+,d0
  1487.         bsr    olong
  1488.         bcs.s    WID_e
  1489.         move.l    (a0)+,d0
  1490.         bsr    olong
  1491.         bcs.s    WID_e
  1492.  
  1493.         move.l    a4,trackpoi
  1494.         pull    a0/a1/d0-d7
  1495.         rts
  1496. WID_e        pull    a0/a1/d0-d7
  1497.         rts
  1498.  
  1499.  
  1500. retry        print    <' - press R ',60,'return',62,' to retry: '>
  1501.         bsr.s    getret
  1502.         print    <LF>
  1503.         cmp.b    #'r',d0
  1504.         beq.s    retry_1
  1505.         cmp.b    #'R',d0
  1506. retry_1        rts
  1507.  
  1508.  
  1509. getret        push    a0/a1/d1-d3        waits for a RETURN
  1510.         lib    Dos,Input
  1511.         move.l    d0,d1
  1512.         lea    temp(pc),a0
  1513.         clr.l    (a0)
  1514.         move.l    a0,d2
  1515.         moveq.l    #4,d3
  1516.         lib    Dos,Read
  1517.         move.b    temp(pc),d0
  1518.         pull    a0/a1/d1-d3
  1519.         rts
  1520.  
  1521.  
  1522. ichr        push    a0-a1/d1        gets a char from TD to d0
  1523.         move.b    (a4)+,d0
  1524.         cmp.l    trackend(pc),a4
  1525.         blo.s    ichr_ok
  1526.         bsr    RCyl
  1527.         bcs.s    ichr_e
  1528. ichr_ok        pull    a0-a1/d1
  1529.         tst.b    d0
  1530.         clrc
  1531.         rts
  1532. ichr_e        pull    a0-a1/d1
  1533.         tst.b    d0
  1534.         setc
  1535.         rts
  1536.  
  1537.  
  1538. istr        bsr.s    ichr        input a string @a0, maxlen d1
  1539.         bcs.s    istr_e
  1540.         move.b    d0,(a0)+
  1541.         dbeq    d1,istr
  1542.         clrc
  1543. istr_e        rts
  1544.  
  1545.  
  1546. ilong        push    d1-d2/a0    input a long value into d0
  1547.         lea    temp(pc),a0
  1548.         bsr    ichr
  1549.         bcs.s    ilong_e
  1550.         move.b    d0,(a0)+    get MSB
  1551.         bsr    ichr
  1552.         bcs.s    ilong_e
  1553.         move.b    d0,(a0)+    2. MSB
  1554.         bsr    ichr
  1555.         bcs.s    ilong_e
  1556.         move.b    d0,(a0)+    3. MSB
  1557.         bsr    ichr
  1558.         bcs.s    ilong_e
  1559.         move.b    d0,(a0)+    LSB
  1560.         move.l    -4(a0),d0
  1561.         pull    d1-d2/a0
  1562.         clrc
  1563.         rts
  1564. ilong_e        pull    d1-d2/a0
  1565.         setc
  1566.         rts
  1567.  
  1568.  
  1569.  
  1570. addstat        add.l    d5,files        add information to statistics
  1571.         add.l    d6,dirs
  1572.         add.l    d7,bytes
  1573.         rts
  1574.  
  1575.  
  1576. PrintStat    print    <LF,LF,' Processing Status:',LF>
  1577.         print    <'====================',LF,LF,'# of files:       '>
  1578.         move.l    files(pc),d0
  1579.         bsr    print10
  1580.  
  1581.         print    <LF,'# of directories: '>
  1582.         move.l    dirs(pc),d0
  1583.         bsr    print10
  1584.  
  1585.         print    <LF,'# of bytes:       '>
  1586.         move.l    bytes(pc),d0
  1587.         bsr    print10
  1588.  
  1589.         move.l    retrycnt(pc),d0
  1590.         beq.s    PrintStat1
  1591.         print    <LF,'NOTE: Number of retries during write: '>
  1592.         bsr    print10
  1593. PrintStat1    print    <LF,LF>
  1594.         rts
  1595.  
  1596.  
  1597.  
  1598.  
  1599. StrCmp        moveq.l    #0,d0        compare strings at (a0) and (a1)
  1600.         moveq.l    #0,d1
  1601. StrCmp1        move.b    (a0)+,d0    cmp str(a0),str(a1)
  1602.         beq.s    eofs1
  1603.         move.b    (a1)+,d1
  1604.         beq.s    eofs2
  1605.         cmp.w    d0,d1
  1606.         beq.s    StrCmp1
  1607. StrEqu        rts
  1608. eofs1        tst.b    (a1)+
  1609.         beq.s    StrEqu
  1610.         moveq.l    #1,d0
  1611.         rts
  1612. eofs2        moveq.l    #-1,d0
  1613.         rts
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620. ck_stop        push    d0-d1/a0-a1        checks if CTRL_C pressed
  1621.         moveq.l    #0,d0
  1622.         moveq.l    #0,d1
  1623.         lib    Exec,SetSignal
  1624.         btst    #SIGBREAKB_CTRL_C,d0
  1625.         beq.s    ck_nostop
  1626.         moveq.l    #0,d0
  1627.         moveq.l    #0,d1
  1628.         bset    #SIGBREAKB_CTRL_C,d1
  1629.         lib    Exec,SetSignal
  1630.         print    <'*** User break',LF>
  1631.         moveq.l    #1,d0            NE: STOP!!!
  1632.         pull    d0-d1/a0-a1
  1633.         rts
  1634. ck_nostop    moveq.l    #0,d0            EQ: no stop
  1635.         pull    d0-d1/a0-a1
  1636.         rts
  1637.  
  1638.  
  1639.  
  1640.  
  1641. print10        push    all
  1642.         lea    bcd_10(pc),a0
  1643.         numlib    put10
  1644.         lea    bcd_10(pc),a0
  1645.         printa    a0
  1646.         pull    all
  1647.         rts
  1648.  
  1649.  
  1650. *************************************************************************
  1651. *                                    *
  1652. * Command line parser written by TM.  New version.  Seems to work.    *
  1653. *                                    *
  1654. *************************************************************************
  1655.  
  1656. parse        push    all
  1657.         move.l    _CMDBuf(pc),a0
  1658.         cmp.b    #'?',(a0)
  1659.         beq    parseINFO
  1660.         cmp.b    #'!',(a0)
  1661.         beq    parseFURINFO
  1662.         strlib    skipblk
  1663.         tst.b    (a0)
  1664.         beq.s    parseMORPAR
  1665.         move.l    a0,a2
  1666.         strlib    getiwordu
  1667.         cmp.w    #'R',d0
  1668.         beq.s    parseR
  1669.         dcbne    #'RES',#'TORE',parse1
  1670. parseR        move.b    #'r',command
  1671.         bra    parse0
  1672. parseMORPAR    print    <'*** More parameters expected',10>
  1673.         bra.s    parserr
  1674. parseCMDEXP    print    <'*** COMMAND must be of R[ESTORE] B[ACKUP] C[HECK]',10>
  1675. parserr        setc
  1676.         pull    all
  1677.         rts
  1678. parse1        cmp.w    #'B',d0
  1679.         beq.s    parseW
  1680.         dcbne    #'BA',#'CKUP',parse2
  1681. parseW        move.b    #'w',command
  1682.         bra.s    parse_1
  1683. parse2        cmp.w    #'C',d0
  1684.         beq.s    parseC
  1685.         dcbne    #'C',#'HECK',parseCMDEXP
  1686. parseC        move.b    #'c',command
  1687.         bra.s    parse0
  1688. parse_1        strlib    skipblk
  1689.         tst.b    (a0)
  1690.         beq    parseMORPAR
  1691.         move.l    pbuf(pc),a1
  1692.         strlib    blkcpy
  1693. parse0        strlib    skipblk
  1694.         tst.b    (a0)
  1695.         beq    parseMORPAR
  1696.         move.b    (a0)+,d0
  1697.         strlib    ucase
  1698.         cmp.b    #'D',d0
  1699.         bne.s    parseUNITIL
  1700.         move.b    (a0)+,d0
  1701.         strlib    ucase
  1702.         cmp.b    #'F',d0
  1703.         bne.s    parseUNITIL
  1704.         move.b    (a0)+,d0
  1705.         cmp.b    #'0',d0
  1706.         blo.s    parseUNITIL
  1707.         cmp.b    #'3',d0
  1708.         bhi.s    parseUNITIL
  1709.         and.l    #15,d0
  1710.         move.l    d0,unit
  1711.         cmp.b    #':',(a0)+
  1712.         beq.s    parse3
  1713. parseUNITIL    print    <'*** UNIT must be of DF0: DF1: DF2: DF3:',10>
  1714.         bra    parserr
  1715. parse3        strlib    skipblk
  1716.         move.l    a0,a2
  1717.         tst.b    (a0)
  1718.         beq    parsend
  1719.         strlib    getiwordu
  1720. parse4        cmp.b    #'-',(a2)
  1721.         bne.s    parse5
  1722.         move.l    a2,a0
  1723.         addq.l    #1,a0
  1724.         move.b    (a0)+,d0
  1725.         strlib    ucase
  1726.         cmp.b    #'A',d0
  1727.         bne.s    parseo1
  1728. parseA        move.w    #1,allflag
  1729.         bra    parse3
  1730. parseo1        cmp.b    #'S',d0
  1731.         bne.s    parseo2
  1732. parseS        move.w    #1,arcflag
  1733.         bra    parse3
  1734. parseo2        cmp.b    #'V',d0
  1735.         bne.s    parseo3
  1736. parseV        move.w    #1,verbose
  1737.         bra    parse3
  1738. parseo3        print    <'*** OPTION must be of -A -S -V',10>
  1739.         bra    parserr
  1740. parse5        cmp.w    #'A',d0
  1741.         beq    parseA
  1742.         cmp.w    #'S',d0
  1743.         beq    parseS
  1744.         cmp.w    #'V',d0
  1745.         beq    parseV
  1746.         cmp.l    #'ALL',d0
  1747.         beq    parseA
  1748.         dcbne    #'SE',#'TARC',parse6
  1749.         bra    parseS
  1750. parse6        dcbne    #'VER',#'BOSE',parseSYNERR
  1751.         bra    parseV
  1752. parseSYNERR    print    <'*** Syntax error',10>
  1753.         bra    parserr
  1754. parseINFO    lea    USAGE(pc),a0
  1755. parseFINFO    printa    a0
  1756.         bra    parserr
  1757. parseFURINFO    lea    KNOWLEDGE(pc),a0
  1758.         bra    parseFINFO
  1759. parsend        pull    all
  1760.         clrc
  1761.         rts
  1762.  
  1763.  
  1764. *************************************************************************
  1765. *                                    *
  1766. * Some libraries by TM.                            *
  1767. *                                    *
  1768. *************************************************************************
  1769.  
  1770.         strlib
  1771.         numlib
  1772.  
  1773.  
  1774.  
  1775. *************************************************************************
  1776. *                                    *
  1777. * Variables, strings, other storage                    *
  1778. *                                    *
  1779. *************************************************************************
  1780.  
  1781. bcd_10        ds.l    4        buffers for bin -> ASCII conversion
  1782.  
  1783. _CMDLen        dc.l    0        The famous ones
  1784. _CMDBuf        dc.l    0
  1785. TDOflag        dc.l    1        error flag: trackdisk.device opened
  1786. msgport        dc.l    0        ptr to MsgPort struct
  1787. signalbit    dc.l    -1        signalbit number
  1788. ioreq        dc.l    0        ptr to IORequest
  1789.  
  1790. cyl        dc.w    0        current cyl#
  1791. dsk        dc.w    0        current disk#
  1792. files        dc.l    0        # of files
  1793. dirs        dc.l    0        # of directories
  1794. bytes        dc.l    0        # of bytes in files
  1795. retrycnt    dc.l    0        # of retries during WriteCyl()
  1796. trackbuf    dc.l    0        ptr to cylinder buffer
  1797. trackpoi    dc.l    0        pointer for track buffer
  1798. trackend    dc.l    0        end of trackbuf
  1799. verbuf        dc.l    0        ptr to verify buffer
  1800. temp        dc.l    0,0        temporary storage for long integers
  1801. sbuf        dc.l    0        pointer to string buffer used by RdMain()
  1802. pbuf        dc.l    0        pointer to pathname (used by RdMain)
  1803. nbuf        dc.l    0        pointer to filename (used by RdMain)
  1804. unit        dc.l    0        drive# for trackdisk.device
  1805. command        dc.w    0        command (r/w/c)
  1806. verbose        dc.w    0        flag: print verbose msgs
  1807. arcflag        dc.w    0        flag: 1 -> set archive flags
  1808. allflag        dc.w    0        flag: 1 -> backup all files
  1809. chkflag        dc.w    0        flag: -1 -> just check if backup is ok.
  1810. mydate        dc.l    0,0,0        DateStamp from backup
  1811. ctime        dc.l    -1,-1,-1    DateStamp when backup was made
  1812.  
  1813. TDname        TD_NAME            device name
  1814.  
  1815. TYPE_FILE    dc.b    'File',0
  1816. TYPE_EOF    dc.b    'EoF',0
  1817. TYPE_PATH    dc.b    'Path',0
  1818. TYPE_EOP    dc.b    'EoP',0
  1819. TYPE_END    dc.b    'EndOfBackup',0
  1820.  
  1821.  
  1822. KNOWLEDGE
  1823.     dc.b    '*** Hard Disk Backup ***',LF,LF
  1824.     dc.b    '© Supervisor Software 1988, 1989',LF
  1825.     dc.b    'Written by Jukka Marin 890312',LF
  1826.     dc.b    'Use Backup ? for help',LF,0
  1827.  
  1828. DSKID    dc.b    'HDBP  ',167,167,'  © Supervisor Software 1988  '
  1829.     dc.b    'Written by JM 8811xx',LF,LF,0
  1830.  
  1831. USAGE    dc.b    'Usage:  Backup B[ACKUP]  <srcpath> <drive> [-opt]',LF
  1832.     dc.b    '        Backup R[ESTORE] <drive> [-opt]',LF
  1833.     dc.b    '        Backup C[HECK]   <drive> [-opt]',LF,LF
  1834.     dc.b    'where',LF
  1835.     dc.b    ' - BACKUP  copies files from hard disk to disk',LF
  1836.     dc.b    ' - RESTORE copies files from disk back to hard disk',LF
  1837.     dc.b    ' - CHECK   checks if the files on disks are ok.',LF
  1838.     dc.b    ' - opt is any combination of:',LF
  1839.     dc.b    '   [-]A[LL]     causes all files to be copied from HD',LF
  1840.     dc.b    '                regardless of the archive-flag',LF
  1841.     dc.b    '                OR all files to be read from backup',LF
  1842.     dc.b    '                without checking if they already exist',LF
  1843.     dc.b    '   [-]S[ETARC]  causes the archive flag of files copied',LF
  1844.     dc.b    '                to be set',LF
  1845.     dc.b    '   [-]V[ERBOSE] causes verbose listing of files processed',LF,LF
  1846.     dc.b    'Note: When backuping a hard disk, all subdirectories of the',LF
  1847.     dc.b    '      given path will also be copied.',LF,0,0
  1848.  
  1849.         libnames        libraries & pointers
  1850.  
  1851.         end
  1852.  
  1853.