;; A simple file copier.
;;
;; This example will install a RSX command:
;;
;; |SCOPY, "<source>","<dest>"
;;
;;
;; This will copy the source file to the destination file.
;; The destination file must have a name which is different to the source file.
;; Single floppy disc drive copy is not supported.
;; 
;; This example shows:
;; - how to install your own RSX commands
;; - accessing BASIC string variables that have been passed from BASIC
;;   to your program
;; - how to read/write a file byte-by-byte

;;-------------------------------------------------
;; operating system functions used

.cas_in_open equ &bc77
.cas_in_close equ &bc7a
.cas_in_char equ &bc80
.cas_test_eof equ &bc89
.cas_out_open equ &bc8c
.cas_out_close equ &bc8f
.cas_out_char equ &bc95
.cas_out_direct equ &bc98
.cas_in_abandon equ &bc7d
.cas_out_abandon equ &bc92
.kl_log_ext     equ &bcd1

;;-------------------------------------------------

org &8000     ;; location for program code
nolist     ;; MAXAM command: disable listing
write"scopy.bin"    ;; MAXAM command: write output to a file

;;-------------------------------------------------

;; install RSX command
ld hl,work_space
ld bc,rsx_table
jp kl_log_ext

.work_space defs 4

.rsx_table
defw name_table
jp copy_file

.name_table
defb "SCOP","Y"+&80   ;; name of the RSX command "SCOPY"
defb 0

;;-------------------------------------------------

.copy_file
cp 2
jr nz,error

;; get string descriptor for source file
ld l,(ix+2)
ld h,(ix+3)
;; get sting length
ld b,(hl)     
inc hl
;; get string address
ld a,(hl)
inc hl
ld h,(hl)
ld l,a

;; open input file
ld de,in_2k_buffer
call cas_in_open
jr nc,error

;; get string descriptor for dest file
ld l,(ix+0)
ld h,(ix+1)
;; get string length
ld b,(hl)
inc hl
;; get sting address
ld a,(hl)
inc hl
ld h,(hl)
ld l,a

;; open output file
ld de,out_2k_buffer
call cas_out_open
jr nc,error

;; read data from input file

.next_byte
;; end of file?
call cas_test_eof
jr nc,got_eof
;; not eof

.not_eof
;; read char from input file
call cas_in_char
call cas_out_char
jr next_byte

.real_eof
call cas_out_close
call cas_in_close
ret

.got_eof
cp &f    ;; hard end of file
jr z,real_eof
cp &e
jr z,real_eof
jp not_eof

;; abandon both files if there is a error

.error
call cas_in_abandon
call cas_out_abandon
ret

;;------------------------------------------
;; 2k buffer used for storing input data
.in_2k_buffer
defs 2048
;;------------------------------------------
;; 2k buffer used for storing output data
.out_2k_buffer
defs 2048