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