;
;     APCopy
;     ------
;
;     This program was put together because I wanted a simple and fast
;     file  copier.   It  has  no  bells and whistles but does contain
;     some  rudimentary  error  checking  just  in  case  the  user is
;     overdoing the apple brandy sauce.  It goes something like this...
;
;     Get some memory
;     Open dos and intuition
;     Check we've got CLI parameters
;     Open the files
;     Copy the source file
;     Close the files
;     Free the memory
;     Close dos and intuition
;     Exit
;
;     I  used  PhxAss/PhxLnk  to  put this together, plus CED and some
;     other programs I should mention.
;
;     I hope the annotations are of some use.
;
;     Anthony Peck
;     68 Woralul St
;     Waramanga ACT 2611 
;
;     E-mail: Anthony.Peck@Radford.act.edu.au
;
;     18 DEC 1995
;
;     -----------------------------------------------------------------
;     -----------------------------------------------------------------

;     First some definitions to make the source code a little easier
;     to read (I hope).

;     Memory allocation for AllocMem function

MKBUFFER                = 0        ; The start of the memory block 
MKSOURCE		= 512      ; The start of the source buffer
MKDESTINATION           = 612      ; The start of the dest buffer
MKDOSBASE		= 712      ; The start of dosbase (long)
MKINTUITIONBASE		= 716      ; The start of intuitionbase (long)
MKINFILEHD              = 720      ; The start of the infile handle
MKOUTFILEHD             = 724      ; The start of the outfile handle

TOTALMEM		= 728      ; The total memory required

; Simple equivalents

Execbase                = $04      ; ExecBase (!)
Mode_OLDFILE            = $03ED    ; Access mode for open file
Mode_NEWFILE            = $03EE    ; Access mode for open file
LF                      = $0A      ; Linefeed

; Library Vector Offsets

_LVOOpenlibrary         = -$0228   ; Exec function
_LVOCloselibrary        = -$019E   ; Exec function
_LVOOpen                = -$1E     ; Dos function
_LVOOutput              = -$3C     ; Dos function
_LVOClose               = -$24     ; Dos function
_LVORead                = -$2A     ; Dos function
_LVOWrite               = -$30     ; Dos function
_LVOAllocmem            = -$C6     ; Dos function
_LVOFreemem             = -$D2     ; Dos function
_LVOAutorequest         = -$015C   ; Intuition function

;     Next some Macros to call on, easing the pain of library calls.

EXEC            MACRO
        Move.l  Execbase,A6             ; Move Exec into a6
        Jsr     _LVO\1(A6)              ; Call function
                ENDM

CALLINT         MACRO
        Move.l  MKINTUITIONBASE(A4),A6  ; Move Intuition into a6
        Jsr     _LVO\1(A6)              ; Call function
                ENDM

CALLDOS         MACRO
        Move.l  MKDOSBASE(A4),A6        ; Move Dos into a6
        Jsr     _LVO\1(A6)              ; Call function
                ENDM

;     The real code starts here

start:

        Sub.B   #$01,D0            ; Subtract the first parameter
        Move.l  D0,D5              ; Move the number remaining to D5
        Move.l  A0,A5              ; Move the parameter address to A5

GetMem:

	Move.l	#TOTALMEM,d0       ; The total memory required
	Move.l	#0,d1              ; Any mem will do (we clear it anyway)
	EXEC    Allocmem           ; Go get it
	Beq	Exit               ; Whoops, off we go
	Move.l	D0,A4              ; All OK, so transfer to A4

CleanMem:

;     Just in case we're a bit dirty.

        Move.l  A4,A3              ; Move the dirty stuff to A3
        Move.l  #TOTALMEM-1,D0     ; Counter minus 1
        
1$      Move.b  #0,(A3)+           ; Clear a byte and move it
        Dbf     D0,1$              ; If not zero yet then go back

Openint:

;     Opening intuition (needed for Autorequest).  The return address
;     stored in the appropriate location of the reserved memory.

        Lea      Intname,A1             ; Load library name
        EXEC     Openlibrary            ; Macro opens library
        Beq      Freemem                ; If it doesn't open, we quit
        Move.l   D0,MKINTUITIONBASE(A4) ; Save the return address

Opendos:

;     Ditto for the Dos library

        Lea      Dosname,A1         ; Load dos library into a1
        Move.l   #$00,D0            ; Any version will do
        EXEC     Openlibrary        ; Macro opens library
        Beq      Nodos              ; If there's a problem, close down
        Move.l   D0,MKDOSBASE(A4)   ; Save the return address

CheckParam:

;     Now, did the user actually give us any parameters?

        Tst.L   D5                      ; anyone home?
        Beq     Usage                   ; No, so display Usage message

        Lea     MKSOURCE(A4),A0         ; Load the source buffer
	Lea	MKDESTINATION(A4),A1    ; Load the dest buffer

1$
        Move.b  (a5)+,D0                ; Transfer a byte
        Cmp.b   #$20,D0                 ; Is it a space?
        Beq     2$                      ; Yep, so go on
        Cmp.b   #$0A,D0                 ; Is it a Linefeed?
        Beq     Usage                   ; Yep, a bit early so outta here
        Cmp.b   #$00,D0                 ; Is it nothing?
        Beq     Usage                   ; Yep, got real probs now!
        Move.b  d0,(a0)+                ; Else move it to source buffer
        Bra     1$                      ; and back for next character

2$
        Move.b  (a5)+,D0                ; Transfer a byte
        Cmp.b   #$00,d0                 ; Is it nothing?
        Beq     Usage                   ; Oops, gone now.
        Cmp.b   #$0A,D0                 ; Is it a linefeed?
        Beq     Openfiles               ; Yep so finished parameters
        Move.b  d0,(a1)+                ; Else move it to dest buffer
        Bra     2$                      ; and back for another one

Openfiles:

;     At this stage, theory is that all is well and we can press on
;     with  the file opening.  I do it slightly weirdingly (?), because
;     I like to check to see if the destination file exists, and then 
;     give the user and opportunity to bug out.

        Lea     MKSOURCE(A4),A0         ; Source file address to A0
        Move.l  A0,D1                   ; and move it to D1
        Move.l  #Mode_OLDFILE,D2        ; Opening as an existing file
        CALLDOS Open                    ; Macro calls open function
        Beq     Closedos                ; Oops, outta here!
        Move.l  D0,MKINFILEHD(A4)       ; Save the infile handle

        Lea     MKDESTINATION(A4),A0    ; Dest file address to A0
        Move.l  A0,D1                   ; and move it to D1
        Move.l  #Mode_OLDFILE,D2        ; Opening as a old file first
        CALLDOS Open                    ; Macro calls open function
        Move.l  D0,MKOUTFILEHD(A4)      ; Save the file handle
        Tst.b   D0                      ; Test if file already exists
        Beq     1$                      ; If "NO" then move on ->
        Move.l  #$00,A0                    ; else we start the AutoReq code
        Lea     Atext,A1                ; The main body text to A1
        Lea     Ltext,A2                ; ...and the left text to A2
        Lea     Rtext,A3                ; ...and the right text to A3
        Move.l  #$00,D0                 ; left button clicked
        Move.l  #$00,D1                 ; right button clicked
        Move.l  #$C4,D2                 ; requester length
        Move.l  #$35,D3                 ; requester height
        CALLINT Autorequest             ; call the requester
        Tst.b   D0                      ; Test if right button selected
        Beq     1$                      ; Yes...so move on

;     Closing the files prior to bugout!

        Move.l  MKINFILEHD(A4),D1       ; Infilehandle
        CALLDOS Close                   ; ...and closed
        Move.l  MKOUTFILEHD(A4),D1      ; Outfile handle
        CALLDOS Close                   ; ...and closed
        Bra     Closedos                ; Outtahere

;     Let's try all that again!

1$      Move.l  MKOUTFILEHD(A4),D1      ; Load the outfile handle
        CALLDOS Close                   ; Macro calls function
        Lea     MKDESTINATION(A4),A0    ; Load address of dest file to A0
        Move.l  A0,D1                   ; and move it to D1
        Move.l  #Mode_NEWFILE,D2        ; Opening as a new file
        CALLDOS Open                    ; Macro calls open function
        Bne     2$                      ; All OK so move along
        Move.l  MKINFILEHD(A4),D1       ; If error load infile handle...
        CALLDOS Close                   ; ...and close the file...
        Bra     Closedos                ; ...and gone
2$      Move.l  D0,MKOUTFILEHD(A4)      ; Else save the outfile handle

Copying:

;     The files are open, the birds are singing and it's time for this
;     program to earn its keep.

        Lea     MKBUFFER(A4),A0         ; Address of buffer to A0
        Move.l  A0,D2                   ; and move it to D1
        Move.l  MKINFILEHD(A4),D1       ; Infile handle to D1
        Move.l  #512,D3                 ; Size of buffer to D3
        CALLDOS Read                    ; Read it!
	Beq     Closefiles              ; Oops! I'm gone

        Lea     MKBUFFER(A4),A0         ; Address of buffer to A0
        Move.l  A0,D2                   ; and move it to D2
        Move.l  MKOUTFILEHD(A4),D1      ; Outfile handle to D1
        Move.l  D0,D3                   ; Size of last read to D3
        CALLDOS Write                   ; Macro Writes to file
        Beq     Closefiles              ; No joy so gone...
	Bra	Copying                 ; else back for another read

Closefiles:

;     Phew!  After all that hard work I'll do the dishes and clean up the
;     kitchen.

        Move.l  MKINFILEHD(A4),D1       ; Load the infile handle
        CALLDOS Close                   ; Macro calls function
        Move.l  MKOUTFILEHD(A4),D1      ; Load the outfile handle
        CALLDOS Close                   ; Macro calls function
        Bra     Closedos                ; Then go

Usage:

;     Here we tell the user how to use the program just in case they come
;     from the planet Urgania.

        Calldos Output                  ; Call the output function
        Beq     Closedos                ; No can do, so outta here ->
        Move.l  D0,D1                   ; else shift output handle to D1
        Move.l  #Message,D2             ; Load message...
        Move.l  #SZMess,D3              ; ...plus its length...
        Calldos Write                   ; ..and write it  

Closedos:

;     Closes the dos library!

        Move.l   MKDOSBASE(A4),A1       ; Move dos base into a1
        EXEC     Closelibrary           ; Macro closes dos

Nodos:

;     Closes the intuition library!

        Move.l   MKINTUITIONBASE(A4),A1 ; Move intuition base into a1
        EXEC     Closelibrary           ; Macro closes intuition


Freemem:

;     Just some memory housekeeping.

	Move.l	a4,a1                   ; Move the buffer to A1
	Move.l	#TOTALMEM,d0            ; and its size
	EXEC	Freemem                 ; and be free!

Exit:

;     Sadly now we sing again to each and every one.  Gladly we'll come
;     back and all have more fun.

        Clr.L    D0                     ; Clear D0
        Rts                             ; Return To System

Atext:

; Intuitext structure

        DC.B    $02,$01,$01        ; FrontPen,BackPen,DrawMode

        Even                       ; Fill to make even address for word

        DC.W    $0D,$08            ; Left edge, top edge
        DC.L    $00                ; No special font
        DC.L    Atx                ; The actual text
        DC.L    $00                ; No next text

Ltext:

; Intuitext structure

        DC.B    $02,$01,$01        ; FrontPen,BackPen,DrawMode

        Even                       ; Fill to make even address for word

        DC.W    $06,$03            ; Left edge, top edge
        DC.L    $00                ; No special font
        DC.L    Ltx                ; The actual text
        DC.L    $00                ; No next text 

Rtext:

; Intuitext structure

        DC.B    $02,$01,$01        ; FrontPen,BackPen,DrawMode

        Even                       ; Fill to make even address for word

        DC.W    $06,$03            ; Left edge, top edge
        DC.L    $00                ; No special font
        DC.L    Rtx                ; The actual text
        DC.L    $00                ; No next text 

; Some final definitions

Atx:            DC.B    "Copy over old file?",$00
Ltx:            DC.B    "No",$00
Rtx:            DC.B    "Yes",$00

Intname:	DC.B	"intuition.library",0
Dosname:	DC.B	"dos.library",0

Message:

        Dc.B    LF,"    "                  ;
        Dc.B    "Usage: [33mAPCopy[0m"      ;
        Dc.B    " <source> <destination> "          ; Text of message
        Dc.B    "[32mA N Peck - 1995[0m" ;
        Dc.B    LF,LF                      ;

SZMess  = *-Message                        ; Size of message

        END


