    ;; This program will save the ROM of the Multiface 2.
    ;;

    .cas_out_open equ &bc8c
    .cas_out_direct equ &bc98
    .cas_out_close equ &bc8f
    .txt_output equ &bb5a
    .km_wait_char equ &bb06
    .kl_l_rom_enable equ &b906
    .kl_l_rom_disable equ &b909

    ;; &4000-&7fff is used as a buffer to store the Multiface ROM and RAM contents.
    ;; When activated, Multiface ROM is readable in range &0000-&1fff and Multiface
    ;; RAM is readable in range &2000-&3fff.

    org &8000
    nolist

    ;;---------------------------------------------------
    ;; Detect Multiface
    ;;
    ;; Activating the Multiface RAM & ROM is a two stage process:
    ;; 1. Enable lower ROM
    ;; 2. Then use the Multiface's I/O address to activate the RAM & ROM
    ;;
    ;; The method used to detect Multiface exists:
    ;;
    ;; (NOTE: When activated, any write to the Multiface RAM range (&2000-&3fff) is written
    ;; to the Multiface RAM, and not the CPC RAM in the same range. Any read is read
    ;; from the Multiface RAM and not from the CPC RAM.)
    ;;
    ;; 1. Write a byte to the CPC RAM.
    ;; 2. Attempt to activate the Multiface RAM
    ;; 3. Write a different byte to the same location (if Multiface RAM is activated
    ;; then the byte in the Multiface RAM will be effected. The byte in the CPC RAM will
    ;; not be changed).
    ;; 4. De-activate the Multiface RAM
    ;; 5. Test the byte in the CPC RAM. If this byte has changed, then the Multiface RAM
    ;; was not activated, and it is assumed that the Multiface 2 isn't connected.
    ;; If the byte is the same, it is assumed that the Multiface 2 is connected.

    ;; write byte to CPC RAM
    xor a
    ld (&3000),a

    di

    ;; activate Multiface RAM
    call kl_l_rom_enable

    ld bc,&fee8
    out (c),c

    ;; attempt to write byte to Multiface RAM
    ld a,&ff
    ld (&3000),a

    ;; deactivate Multiface RAM
    ld bc,&feea
    out (c),c
    call kl_l_rom_disable

    ;; test byte in CPC RAM. Has it changed?
    ld a,(&3000)
    or a
    jr nz,multiface_not_present

    ;;------------------------------------------------------------
    ;; Byte has not changed. Multiface is assumed to be connected.

    ;;--------------------------------------------------
    ;; Multiface has been detected. Now dump the ROM data.

    ;; enable Multiface ROM and RAM
    call kl_l_rom_enable
    ld bc,&fee8
    out (c),c

    ;; (ROM will now be readable in range &0000-&1fff. RAM will be readable and
    ;; writeable in range &2000-&3fff).

    ;; copy multiface ROM data to buffer in RAM
    ld hl,&0000
    ld de,&4000
    ld bc,&4000
    ldir

    ;; deactivate Multiface ROM and RAM
    ld bc,&feea
    out (c),c
    call kl_l_rom_disable

    ld hl,present
    call print

    ld hl,insert_disk
    call print
    call km_wait_char

    ld hl,saving
    call print

    ;; save the rom data to a file
    ld b,end_filename-filename		;; length of filename in characters
    ld hl,filename					;; start address of filename
    ld de,&c000						;; address of temporary 2k buffer (not used when using
    								;; cas out direct)
    call cas_out_open
    ld hl,&4000				;; start address of data in buffer
    ld de,&2000				;; length of data in buffer
    ld bc,&0000				;; execution address
    ld a,2					;; file type: binary
    call cas_out_direct
    call cas_out_close

    ;; display message
    ld hl,finished
    call print
    ;; wait for a key press
    call km_wait_char
    ;; soft-reset CPC
    rst 0

    ;;---------------------------------------------------
    ;; The byte in CPC RAM changed. Therefore it is assumed that the Multiface
    ;; is not connected.

    .multiface_not_present
    ;; display message
    ld hl,not_present
    call print
    ;; wait for a key press
    call km_wait_char
    ;; soft-reset CPC
    rst 0

    ;;---------------------------------------------------
    ;; display a message terminated with 0
    ;;
    .print
    ld a,(hl)			;; get ASCII code for character
    inc hl				;; increment pointer in text
    or a				;; termination character?
    ret z				;; quit if termination character.

    call txt_output		;; display character
    jr print			;; loop for next character

    ;;---------------------------------------------------
    ;; the messages

    .finished
    defb &11,&0d,&0f,&01,"Image has been saved.",10,13,10,13,"Press any key to reset.",0

    .not_present
    defb &0f,3,"MULTIFACE is not enabled.",10,13,10,13
    defb &0f,1,"Press any key to reset.",0

    .present
    defb &0f,3,"MULTIFACE is enabled.",10,13,10,13,0

    .insert_disk
    defb &0f,1,"Please insert a disk, and press any key.",13,10,0

    .saving
    defb &11,&0d,&0f,&01,"Saving ",&0f,&02,"MULTIFACE.ROM",0

    ;; filename for the ROM data
    .filename
    defb "MULTFACE.ROM"