;; "INSTALL.S"
;;
;; Assemble this code with Maxam, or compatible assembler.
;;
;; ** INSTALL ROUTINE TO PUT YOUR CODE INTO THE MULTIFACE RAM **
;;
;; - example code to show how the multiface ram can be used for your
;;   own programs
;;
;; - this code is not optimized.
;;
;; Code released under the Gnu Public License v1
;;
;; Code by Kevin Thacker

.km_wait_char             equ &bb06

.txt_output               equ &bb5a

.cas_in_open              equ &bc77
.cas_in_direct            equ &bc83
.cas_in_close             equ &bc7a

org &4000                 ;install code can be located any where except
                          ;&0000-&4000, because this memory range is
                          ;used by the multiface. So if this memory address
                          ;was used when the multiface
                          ;is enabled your program will not be there
                          ;to execute and the CPU would execute the multiface
                          ;ROM code.
nolist


;; ** LOAD YOUR CODE (TO BE PUT INTO MULTIFACE RAM) INTO BUFFER **

ld b,end_filename-filename
ld hl,filename
ld de,two_k_buffer
call cas_in_open          ;...open file
ld (start_address),de
ld hl,buffer              ;address to store code in installer
call cas_in_direct        ;...load data
ld (length),bc            ;length of code
call cas_in_close         ;...close file


;; ** DETECT IF MULTIFACE IS VISIBLE **
;; - this works by poking a value into the ram area which is also
;;   used by the multiface ram.
;; - if the multiface is visible, and the RAM is enabled, and we poke
;;   a value in, this will not effect the original value we poked.
;; - if the multiface is invisible, even if the RAM is enabled, the original
;;   value we poked will now be different.

xor a
ld (&3000),a              ;memory address which is in the range used by
                          ;the multiface RAM

ld bc,&FEE8               ;enable ram
out (c),c

dec a
ld (&3000),a              ;store a different value

ld bc,&FEEA
out (c),c                 ;disable ram

ld a,(&3000)              ;check value in normal ram
or a                      ;if it is not zero, then the multiface is not
                          ;"visible"
jp nz,multiface_not_visible


;; ** INSTALL MY CODE **

ld hl,install_text
call print

;; ** switch in multiface RAM/ROM **

di
ld bc,&FEE8
out (c),c                 ;initialise multiface RAM

;; ** INITIALISE MULTIFACE PARAMETERS NEEDED FOR MY CODE TO BE EXECUTED **

ld hl,(start_address)     ;address of my code within the multiface ram.
ld (&2000),hl

ld a,%10001101            ;rom configuration and mode I would like when code
ld (&2002),a              ;is executed.

ld a,&11000000            ;ram configuration I would like when my code is
ld (&2003),a              ;executed

ld a,"R"                  ;the magic "RUN". Without this the code is NOT
ld (&2005),a              ;executed
ld a,"U"
ld (&2006),a
ld a,"N"
ld (&2007),a

;; ** COPY MY CODE INTO THE MULTIFACE RAM **

ld hl,buffer
ld de,(start_address)
ld bc,(length)
ldir                      ;copy our code into the multiface ram

;; ** switch out multiface ROM/RAM **

ld bc,&FEEA               ;disable RAM
out (c),c
rst 0                     ;and reset

.multiface_not_visible
ld hl,not_visible_text    
call print
call km_wait_char
rst 0                      ;reset

.print
ld a,(hl)
or a
ret z
inc hl
call txt_output
jr print


.install_text
defb "Multiface present, installing code..",0

.not_visible_text
defb "Multiface not found. If it is connected, please make sure it is visible",0

.buffer
defs 8192                 ;buffer to store my code to be put into multiface
                          ;ram

.start_address            ;start address is also the address within the
defw 0                    ;multiface ram to load my_code.

.length 
defw 0

.filename
defb "MYCODE.BIN"         ;filename for my code!
.end_filename

.two_k_buffer
defs 2048


;; The example code that is loaded is:
;; "MYCODE.BIN"
;; 
;; A simple piece of code to be installed into the Multiface RAM.

;;org &3B12
;;write "mycode.bin"
;;nolist

;;di
;;ld bc,&7f10               ;;select border
;;out (c),c

;;.loop
;;and 31                    ;;colour
;;or %01000000
;;out (c),a                 ;;output colour
;;inc a
;;jp loop