    ;; 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