;; 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"
.end_filename
