home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
disks
/
tools
/
bfc
/
bfc.asm
< prev
next >
Wrap
Assembly Source File
|
1996-08-25
|
13KB
|
714 lines
**********************************************************************
Section BFC,Code
**********************************************************************
Include System.gs
Include Macros.i
**********************************************************************
;TaskPriority Equ 0
NOWBCD
Include Start.i
**********************************************************************
Dc.B '$VER: Big File Copy (BFC) V1.0 by Shamus Husheer',0
Even
RESTORE EQU 0 ;(BFC DEV: Filename)
BACKUP EQU 1 ;(BFC Filename DEV:)
NUMCYLS EQU 80
CYLSIZE EQU 512*11*2
**********************************************************************
*
* Disk Structure created with BFC: (Not a DOS readable structure)
* Every cyl (11k) has the following structure:
* 11260 bytes of data
* 4 bytes checksum
* On track0 the last 2 bytes of data (before checksum) is the disk number
* On the disk 0, track 0 the last 4 bytes before disknum is filesize.
* All other data is file data.
* Thus each disk holds 900798 bytes of file data at most, with
* disk 1 holding 900798 bytes at most.
*
**********************************************************************
Main:
Lea.L VBase,A5
Clr.B -1(A0,D0.L)
Move.L A0,ArgsPtr-VBase(A5)
Lea.L MessagePort-VBase(A5),A0
Move.B #4,LN_TYPE(A0)
Lea.L MP_MSGLIST+LH_TAIL(A0),A1
Move.L A1,-4(A1)
Subq.L #4,A1
Move.L A1,MP_MSGLIST+LH_TAILPRED(A0)
Sub.L A1,A1
EXEC FindTask
Move.L D0,MP_SIGTASK+MessagePort-VBase(A5)
Moveq.L #-1,D0
EXEC AllocSignal
Move.B D0,MP_SIGBIT+MessagePort-VBase(A5)
Bmi .exit
Lea.L IORequest-VBase(A5),A1
Move.B #5,LN_TYPE(A1)
Move.L A0,MN_REPLYPORT(A1)
Move.W #IOSTD_SIZE,MN_LENGTH(A1)
Lea.L DOSLibName(PC),A1
Moveq.L #0,D0
EXEC OpenLibrary
Move.L D0,_DOSBase
Beq .freesig
DOS Output
Move.L D0,OutputHD-VBase(A5)
Move.L D0,D1
Lea.L IntroStr(PC),A0
Move.L A0,D2
Move.L #IntroStrLen,D3
DOS Write
Bsr ParseArgs
Tst.L D0
Bne .badargs
Move.L DevName-VBase(A5),A0
Bsr GetDevName
Tst.L D0
Beq .nodev
Move.L D0,A0
Move.L DevUnit-VBase(A5),D0
Move.L DevFlags-VBase(A5),D1
Lea.L IORequest-VBase(A5),A1
EXEC OpenDevice
Tst.L D0
Bne .nodevopen
Move.L #CYLSIZE,D0
Move.L #MEMF_CHIP|MEMF_CLEAR,D1
EXEC AllocMem
Move.L D0,Buffer-VBase(A5)
Beq .nomem
Tst.B Operation-VBase(A5)
Beq.S .restore01
Move.L #MODE_OLDFILE,D2
Bra.S .openfile
.restore01
Move.L #MODE_NEWFILE,D2
.openfile
Move.L FileName-VBase(A5),D1
DOS Open
Move.L D0,FileHD-VBase(A5)
Beq .nofile
Tst.B Operation-VBase(A5)
Beq.S .restore02
Bsr DoBackup
Bra.S .freeallocs
.restore02
Bsr DoRestore
.freeallocs
Move.L D0,D7
Move.L OutputHD-VBase(A5),D1
Tst.L D7
Beq.S .noerrors
Lea.L ErrorsStr(PC),A0
Move.L A0,D2
Move.L #ErrorsStrLen,D3
Bra.S .dofinal
.noerrors
Lea.L NoErrorsStr(PC),A0
Move.L A0,D2
Move.L #NoErrorsStrLen,D3
.dofinal
DOS Write
.closefile
Move.L FileHD-VBase(A5),D1
DOS Close
.freemem
Move.L Buffer-VBase(A5),A1
Move.L #CYLSIZE,D0
EXEC FreeMem
.closedev
Lea.L IORequest-VBase(A5),A1
EXEC CloseDevice
.closedos
Move.L _DOSBase(PC),A1
EXEC CloseLibrary
.freesig
Moveq #0,D0
Move.B MessagePort+MP_SIGBIT-VBase(A5),D0
EXEC FreeSignal
.exit
Moveq.L #0,D0
Rts
.badargs
Move.L OutputHD-VBase(A5),D1
Lea.L ArgStr(PC),A0
Move.L A0,D2
Move.L #ArgStrLen,D3
DOS Write
Bra.S .closedos
.nodev
Move.L OutputHD-VBase(A5),D1
Lea.L NoDevStr(PC),A0
Move.L A0,D2
Move.L #NoDevStrLen,D3
DOS Write
Bra.S .closedos
.nodevopen
Move.L OutputHD-VBase(A5),D1
Lea.L NoDevOpenStr(PC),A0
Move.L A0,D2
Move.L #NoDevOpenStrLen,D3
DOS Write
Bra.S .closedos
.nomem
Move.L OutputHD-VBase(A5),D1
Lea.L NoMemStr(PC),A0
Move.L A0,D2
Move.L #NoMemStrLen,D3
DOS Write
Bra .closedev
.nofile
Move.L OutputHD-VBase(A5),D1
Lea.L NoFileStr(PC),A0
Move.L A0,D2
Move.L #NoFileStrLen,D3
DOS Write
Bra .freemem
**********************************************************************
DoBackup:
Move.B #-1,Operation-VBase(A5)
Move.L #WritingStr,OpType-VBase(A5)
Clr.W DiskCounter-VBase(A5)
Bsr GetFileSize
Move.L D0,FileSize-VBase(A5)
Beq .error
Bsr DevClear
.diskloop
Bsr PromptDisk
Tst.L D0
Beq .error
Moveq.L #1,D0
Bsr Motor
Clr.W TrackCounter-VBase(A5)
Move.L Buffer-VBase(A5),A0
Lea.L 11258(A0),A0
Move.W DiskCounter-VBase(A5),D0
Move.W D0,(A0)
Tst.W D0
Bne.S .datadisk
Move.L FileSize-VBase(A5),-4(A0) ;File Size if disk0
Move.L #CYLSIZE-10,D7
Bra.S .read
.datadisk
Move.L #CYLSIZE-6,D7
Bra.S .read
.trackloop
Move.L #CYLSIZE-4,D7
.read
Move.L FileSize-VBase(A5),D0
Sub.L FileDone-VBase(A5),D0
Cmp.L D0,D7
Blo.S .readfile
Move.L D0,D7
Clr.B Operation-VBase(A5)
.readfile
Move.L D7,D0
Bsr ReadFileToBuffer
Cmp.L D7,D0
Bne.S .error
Bsr CheckSumData
Move.L Buffer-VBase(A5),A0
Move.L D0,11260(A0)
Bsr PrintProgress
Move.W #CMD_WRITE,D0
Bsr DoTrack
Tst.L D0
Bne.S .diskerror
Add.L D7,FileDone-VBase(A5)
Cmp.W #79,TrackCounter-VBase(A5)
Bhs.S .endtrackloop
Addq.W #1,TrackCounter-VBase(A5)
Tst.B Operation-VBase(A5)
Bne.S .trackloop
.endtrackloop
Bsr DevUpdate
Moveq.L #0,D0
Bsr Motor
Tst.B Operation-VBase(A5)
Beq.S .trackloopend
Addq.W #1,DiskCounter-VBase(A5)
Bra .diskloop
.trackloopend
Move.L FileDone-VBase(A5),D0
Cmp.L FileSize-VBase(A5),D0
Bne.S .error
.finished
Moveq.L #0,D0
Rts
.error
Moveq.L #-1,D0
Rts
.diskerror
Bsr PrintDiskError ;Remove the amount of file done so far
Bra.S .endtrackloop
DoRestore:
Move.B #-1,Operation-VBase(A5)
Move.L #ReadingStr,OpType-VBase(A5)
Clr.W DiskCounter-VBase(A5)
Bsr DevClear
.diskloop
Bsr PromptDisk
Tst.L D0
Beq .error
Moveq.L #1,D0
Bsr Motor
Clr.W TrackCounter-VBase(A5)
.trackloop
Bsr PrintProgress
Move.W #CMD_READ,D0
Bsr DoTrack
Tst.L D0
Bne .diskerror
Bsr CheckSumData
Move.L Buffer-VBase(A5),A0
Lea.L 11260(A0),A0
Cmp.L (A0),D0
Bne .diskerror
Tst.W TrackCounter-VBase(A5)
Bne.S .datatrack
Move.W DiskCounter-VBase(A5),D0
Cmp.W -2(A0),D0
Bne.S .diskloop ;Disks out of order
Tst.W -2(A0)
Bne.S .datadisk
Move.L -6(A0),FileSize-VBase(A5)
Move.L #CYLSIZE-10,D7
Bra.S .write
.datadisk
Move.L #CYLSIZE-6,D7
Bra.S .write
.datatrack
Move.L #CYLSIZE-4,D7
.write
Move.L FileSize-VBase(A5),D0
Sub.L FileDone-VBase(A5),D0
Cmp.L D0,D7
Blo.S .writefile
Move.L D0,D7
Clr.B Operation-VBase(A5)
.writefile
Move.L D7,D0
Bsr WriteBufferToFile
Cmp.L D7,D0
Bne.S .error
Add.L D7,FileDone-VBase(A5)
Cmp.W #79,TrackCounter-VBase(A5)
Bhs.S .endtrackloop
Addq.W #1,TrackCounter-VBase(A5)
Tst.B Operation-VBase(A5)
Bne .trackloop
.endtrackloop
Moveq.L #0,D0
Bsr Motor
Tst.B Operation-VBase(A5)
Beq.S .trackloopend
Addq.W #1,DiskCounter-VBase(A5)
Bra .diskloop
.trackloopend
Move.L FileDone-VBase(A5),D0
Cmp.L FileSize-VBase(A5),D0
Bne.S .error
.finished
Moveq.L #0,D0
Rts
.error
Moveq.L #-1,D0
Rts
.diskerror
Bsr PrintDiskError ;Remove the amount of file done so far
Bra.S .endtrackloop
**********************************************************************
CheckSumData:
Move.L Buffer-VBase(A5),A0
Moveq.L #0,D0
Move.L #2816,D1
.loop
Subq.L #1,D1
Beq.S .fin
Add.L (A0)+,D0
Bcc.S .loop
Addq.L #1,D0
Bra.S .loop
.fin
Rts
DoTrack:
Move.W D0,IO_COMMAND+IORequest-VBase(A5)
Move.W TrackCounter-VBase(A5),D0
Mulu #44,D0
Lsl.L #8,D0
Move.L D0,IO_OFFSET+IORequest-VBase(A5)
Move.L #CYLSIZE,IO_LENGTH+IORequest-VBase(A5)
Move.L Buffer-VBase(A5),IO_DATA+IORequest-VBase(A5)
Lea.L IORequest-VBase(A5),A1
EXEC DoIO
Moveq.L #0,D0
Move.B IO_ERROR+IORequest-VBase(A5),D0
Rts
ReadFileToBuffer:
Move.L FileHD-VBase(A5),D1
Move.L Buffer-VBase(A5),D2
Move.L D0,D3
DOS Read
Rts
WriteBufferToFile:
Move.L FileHD-VBase(A5),D1
Move.L Buffer-VBase(A5),D2
Move.L D0,D3
DOS Write
Rts
Motor:
Move.W #TD_MOTOR,IO_COMMAND+IORequest-VBase(A5)
Move.L D0,IO_LENGTH+IORequest-VBase(A5)
Lea.L IORequest-VBase(A5),A1
EXEC DoIO
Rts
DevClear:
Move.W #CMD_CLEAR,IO_COMMAND+IORequest-VBase(A5)
Lea.L IORequest-VBase(A5),A1
EXEC DoIO
Rts
DevUpdate:
Move.W #CMD_UPDATE,IO_COMMAND+IORequest-VBase(A5)
Lea.L IORequest-VBase(A5),A1
EXEC DoIO
Rts
ParseArgs:
Move.L ArgsPtr-VBase(A5),A0
.find1starg
Move.B (A0)+,D0
Tst.B D0
Beq.S .badargs
Cmp.B #' ',D0
Bne.S .find1starg
Lea.L -2(A0),A1
Cmp.B #':',(A1)
Bne.S .write
Clr.W (A1)+
Move.L ArgsPtr-VBase(A5),DevName-VBase(A5)
Move.L A1,FileName-VBase(A5)
Move.B #RESTORE,Operation-VBase(A5)
Bra.S .doneargs
.write
Clr.B 1(A1)
Move.L ArgsPtr-VBase(A5),FileName-VBase(A5)
Move.L A0,DevName-VBase(A5)
Move.B #BACKUP,Operation-VBase(A5)
.find2ndarg
Cmp.B #':',(A0)
Beq.S .found
Tst.B (A0)+
Bne.S .find2ndarg
Bra.S .badargs
.found
Clr.W (A0)
.doneargs
Moveq.L #0,D0
Rts
.badargs
Moveq.L #-1,D0
Rts
GetDevName: ;In: A0 - Dev Name (eg FF0) Out: D0 = aptr Device
Move.L A0,A2
Moveq.L #-1,D1
.lenloop
Cmp.B #'a',(A0)
Blo.S .noand
Cmp.B #'z',(A0)
Bhi.S .noand
And.B #$DF,(A0)
.noand
Tst.B (A0)+
DBeq D1,.lenloop
Neg.L D1
Subq.L #1,D1
Beq.S .notfound
Move.L _DOSBase(PC),A0
EXEC Forbid
Move.L 34(A0),A0
Move.L 24(A0),D0
Lsl.L #2,D0
Move.L D0,A0
Addq.L #4,A0
.loop
Move.L (A0),D0
Beq.S .notfound
Lsl.L #2,D0
Move.L D0,A0
Tst.L dol_Type(A0)
Bne.S .loop
Move.L dol_Name(A0),D0
Lsl.L #2,D0
Move.L D0,A1
Cmp.B (A1)+,D1
Bne.S .loop
Move.L D1,D0
Subq.L #1,D0
Move.L A2,A3
.cmploop
Cmp.B (A1)+,(A3)+
Bne.S .loop
DBra D0,.cmploop
Move.L dol_Startup(A0),D0
Beq.S .loop
Lsl.L #2,D0
Move.L D0,A1
Move.L 4(A1),D0
Beq.S .loop
Move.L (A1),DevUnit-VBase(A5)
Move.L 12(A1),DevFlags-VBase(A5)
Lsl.L #2,D0
Addq.L #1,D0
Move.L D0,DeviceName-VBase(A5)
Bra.S .permit
.notfound
Moveq.L #0,D0
.permit
EXEC Permit
Rts
PrintDiskError:
Lea.L DiskErrorStr(PC),A0
Lea.L OpType-VBase(A5),A1
Bsr.S PrintF
Move.W DiskCounter-VBase(A5),D0
Move.W D0,D1
Mulu #55,D0
Lsl.L #7,D0
Lsl.L #7,D0 ;Number of bytes assuming full disk
Mulu #328,D1 ;Number of non-data bytes per disk
Sub.L D1,D0
Move.L D0,FileDone-VBase(A5)
Move.L FileHD-VBase(A5),D1
Moveq.L #OFFSET_BEGINNING,D2
Move.L D0,D3
DOS Seek
Subq.W #1,DiskCounter-VBase(A5)
Moveq.L #0,D0
Bsr Motor
Rts
PromptDisk:
Lea.L PromptDiskStr(PC),A0
Lea.L DiskCounter-VBase(A5),A1
Bsr.S PrintF
Move.L OutputHD-VBase(A5),D1
Lea.L TextBuffer-VBase(A5),A0
Move.L A0,D2
Moveq.L #1,D3
DOS Read
Cmp.B #'!',TextBuffer-VBase(A5)
Beq.S .ctlc
Moveq.L #-1,D0
Rts
.ctlc
Moveq.L #0,D0
Rts
PrintProgress:
Lea.L ProgressStr(PC),A0
Lea.L OpType-VBase(A5),A1
Bsr.S PrintF
Rts
PrintF: ;A0/A1 as rawdofmt
Lea.L .stuffchar(PC),A2
Lea.L TextBuffer-VBase(A5),A3
EXEC RawDoFmt
Move.L OutputHD-VBase(A5),D1
Lea.L TextBuffer-VBase(A5),A0
Move.L A0,D2
Moveq.L #-1,D3
.lenloop
Tst.B (A3)+
DBeq D3,.lenloop
Not.L D3
DOS Write
Rts
.stuffchar
Move.B D0,(A3)+
Rts
GetFileSize:
Move.L FileName-VBase(A5),D1
Moveq.L #ACCESS_READ,D2
DOS Lock
Move.L D0,D1
Beq.S .error
Move.L D0,D7
Lea.L FileInfo-VBase(A5),A0
Move.L A0,D2
DOS Examine
Move.L D7,D1
Move.L D0,D7
DOS UnLock
Move.L D7,D0
Beq.S .error
Move.L fib_Size+FileInfo-VBase(A5),D0
.error
Rts
**********************************************************************
IntroStr:
Dc.B 'Big File Copy V1.0 by Shamus Husheer',10
IntroStrLen Equ *-IntroStr
ArgStr:
Dc.B 'Command Line Parameters INCORRECT. Try:',10
Dc.B 'BFC <source> <dest>',10
Dc.B 'Where, for backing up, <source> is a file and <dest> is a device, eg DF0,',10
Dc.B 'or for restoring <source> is a device, and <dest> is a file.',10
ArgStrLen Equ *-ArgStr
NoDevStr:
Dc.B 'Unable to locate the device you have requested.',10
NoDevStrLen Equ *-NoDevStr
NoDevOpenStr:
Dc.B 'The device you have requested failed allocation.',10
NoDevOpenStrLen Equ *-NoDevOpenStr
NoMemStr:
Dc.B 'Unable to allocate 11KB of memory for track buffer.',10
NoMemStrLen Equ *-NoMemStr
NoFileStr:
Dc.B 'Unable to open your requested file.',10
NoFileStrLen Equ *-NoFileStr
ErrorsStr:
Dc.B 13,'There were errors in the operation.',10
ErrorsStrLen Equ *-ErrorsStr
NoErrorsStr:
Dc.B 13,'No errors were encountered.',10
NoErrorsStrLen Equ *-NoErrorsStr
ProgressStr:
Dc.B 13,'%s disk %d, cyl %d',0
DiskErrorStr:
Dc.B 13,'Error %s disk %d, cyl %d',10,0
ReadingStr:
Dc.B 'Reading',0
WritingStr:
Dc.B 'Writing',0
PromptDiskStr:
Dc.B 13,'Please Insert disk %d in drive and press return. ! = Abort',0
DOSLibName:
DOSNAME
EVEN
_DOSBase
Dc.L 0 ;Frequently used, so PC relative.
*******
Section Variables,BSS
VBase:
ArgsPtr:
Ds.L 1
OutputHD:
Ds.L 1
DevName:
Ds.L 1
DeviceName:
Ds.L 1
DevUnit:
Ds.L 1
DevFlags:
Ds.L 1
Buffer:
Ds.L 1
FileName:
Ds.L 1
FileHD:
Ds.L 1
FileSize:
Ds.L 1
FileDone:
Ds.L 1
OpType: ;Do not separate
Ds.L 1
DiskCounter: ;Do not separate
Ds.W 1
TrackCounter: ;Do not separate
Ds.W 1
TextBuffer:
Ds.B 40
Ds.L 0 ;Long Align
FileInfo:
Ds.B fib_SIZEOF
MessagePort:
Ds.B MP_SIZE
IORequest:
Ds.B IOSTD_SIZE
Operation:
Ds.B 1