;; Here is some code to initialise the firmware and load a file
;; it is very useful to use this in a multiload game to load the
;; levels (after you have cracked it and saved them out).
;; 
;; I do not authorise cracking software and piracy. 
;;
;; NOTE:
;;
;; 1. Routine cannot be in &0000-&3fff (lower rom initialised into this 
;;    area)
;; 2. You cannot load a file into a area used by firmware (0000-&0040)
;;    or &a600-&c000. If the program requires this, then load it to
;;    somewhere else and LDIR/LDDR it to it's place.
;; 3. This code will initialise the firmware for it's loading, so you
;;    must copy the data areas used by the firmware, load the file,
;;    and copy them back, (or the game will crash).
;;    Use the screen memory or the 2nd bank of 64k.
;; 4. Put this code where the loader for the levels is in the original game
;; 5. Dont forget to modify this code appropiatly. This is just an example.


.routine_address          equ &a600

org routine_address
nolist
write"loader"

let mode=0                          ;screen mode

.load_address             equ &0040 ;address to put file

.km_initialise            equ &bb00
.txt_output               equ &bb5a
.cas_in_open              equ &bc77
.cas_in_direct            equ &bc83
.cas_in_close             equ &bc7a
.cas_in_abandon           equ &bc7d

.kl_init_back             equ &bcce
.kl_l_rom_disable         equ &b909

;; ** STORE DATA USED BY PROGRAM THAT WILL BE CORRUPTED BY INITIALISATION OF **
;; ** FIRMWARE **

di
ld (stack+1),sp             ;save stack used by program
ld sp,&c000                 ;new stack used by firmware and load routines

;; ** SAVE DATA OVERWRITTEN BY FIRMWARE **
;; !!EXAMPLE!!

ld hl,&a800                  
ld de,&c000                 ;upper firmware area (&a800?-&c000)

ld a,4
.next push af
push de
ld bc,&600
ldir
pop de
ld a,d
add a,8
ld d,a
pop af
dec a
jr nz,next

ld h,&00                    ;firmware lower jumpblock (&0000-&0040)
ld l,0
ld c,&40
ldir

;; ** INITIALISE ALTERNATE REGISTER SET FOR FIRMWARE **

exx
ld bc,&7f00+%10001000+mode  ;initialise lower rom and select mode
out (c),c                   ;this routine must be located above &4000
exx  
ex af,af'
xor a
ex af,af'

;; ** INITIALISE FIRMWARE **

call &0044                  ;initialise lower jumpblock (&0000-&0040)
                            ;and high kernal jumpblock (&b800-&bae4)
call &08bd                  ;initialise firmware jumpblock entries
                            ;(&bb00- ...)
call km_initialise          ;initialise keyboard manager
call kl_l_rom_disable       ;disable lower rom

;; ** INITIALISE DISK ROM FOR LOADING/SAVING **

ld c,7                      ;disk rom
ld de,&0040                 ;lowest useable byte of memory
ld hl,&b0ff                 ;highest useable byte of memory
call kl_init_back           ;initialise disk rom

xor a                       ;select drive (A)
ld (&ac00),a

ld a,&ff
ld (&be78),a                ;turn of disc error messages

ld a,&c9
ld (txt_output),a           ;prevent printing of text characters
                            ;don't get error messages corrupting screen

;; ** LOAD FILE USING FIRMWARE **

ld b,end_filename-filename  ;length of filename
ld hl,filename              ;address of filename in memory
ld de,load_address          ;address to put file/2k buffer to use (unused since
                            ;read direct used
push de
call cas_in_open            ;open file

pop hl                      ;HL = load address, BC = length of file
call cas_in_direct          ;read it
call cas_in_close           ;close it


;; ** RESTORE DATA WHICH WOULD HAVE BEEN OVERWRITTEN BY FIRMWARE **
;; !!EXAMPLE!!
di
ld hl,&c000                 ;copy back data
ld de,&a800

ld a,4
.next2 push af
push hl
ld bc,&0600
ldir  
pop hl
ld a,h
add a,8
ld h,a
pop af
dec a
jr nz,next2

ld d,&00                    ;copy back &0000-&0040
ld e,0
ld c,&40
ldir  

.stack ld sp,0              ;old stack back and...
ret                         ;...exit to program!!

.filename
defb "loadfile.dat"