5,634 bytes added,
07:35, 13 March 2007 <pre>
;; This example shows a disc loader program which is a executable binary
;; file.
;;
;; This loader can be run direct from BASIC using:
;; RUN"<loader> [RETURN]
;; replace <loader> with the name of the loader file
;; (e.g. RUN"SOLOMONS")
;;
;; 1. assemble the loader using MAXAM or other compatible assembler
;; 2. note the start and end addressess; use this to calculate the length of the data
;; 3. in BASIC type: SAVE"<loader>",B,<start>,<length>,<execution>
;; replace <loader> with the name of the loader file
;; <start> with the start address of the loader file
;; <length> with the length of the loader file
;; <execution> with the execution/start address of the loader file
;;
;; Loader supports:
;; - loading from disc drive A and B.
;; - loading using AMSDOS and other DOSs (e.g. ROMDOS).
;;---------------------------------------------------------------------------
.scr_set_mode equ &bc0e
.scr_set_border equ &bc38
.scr_set_ink equ &bc32
.cas_in_open equ &bc77
.cas_in_direct equ &bc83
.cas_in_close equ &bc7a
.mc_start_program equ &bd16
.kl_rom_walk equ &bccb
;;---------------------------------------------------------------------------
org &100 ;; example loader address
nolist ;; maxam command to stop listing of assembly
;;------------------------------------------------------------------------
;; store the drive number the loader was run from
ld hl,(&be7d)
ld a,(hl)
ld (drive+1),a
;;------------------------------------------------------------------------
ld c,&ff ;; disable all roms
ld hl,start ;; execution address for program
call mc_start_program ;; start it
;;------------------------------------------------------------------------
.start
call kl_rom_walk ;; enable all roms
;;------------------------------------------------------------------------
;; when AMSDOS is enabled, the drive reverts back to drive 0!
;; This will restore the drive number to the drive the loader was run from
.drive ld a,0
ld hl,(&be7d)
ld (hl),a
;;------------------------------------------------------------------------
;; set screen mode 0
;; (replace this with the screen mode of your screen)
ld a,0
call scr_set_mode
;;------------------------------------------------------------------------
;; setup colours
call setup_colours
;;--------------------------------------------------------------------
;; sequence:
;; 1. load file
;; 2. decompress data (if compressed)
;; 3. relocate data (if required)
;;
;; NOTE:
;; If data should be relocated to &A600-&BFFF then this must be done last
;; otherwise the firmware jumpblock will be corrupted and no more files can be loaded.
;;
;; If we have data to load which must be relocated we can do the following:
;; 1. set colours to black
;; 2. load data to screen area (not seen because all colours are the same)
;; 3. relocate data to destination address
;;
;; Normal load sequence:
;; - screen
;; - main file
;; - extra file to relocate to firmware jumpblock area
;; - execute program
;;--------------------------------------------------------------------
;; load block
call load_next_block
;; could have code here to decompress block if it is compressed, and
;; then relocate it
di ;; disable interrupts
; do any memory relocation here.
jp &103 ;; and execute the code. (change this for the execution address
;; used by your game)
;;------------------------------------------------------------------------
;; load the next block, updating filename for next block
.load_next_block
ld b,end_filename-filename
ld hl,filename
call load_block
;; update filename for next block
ld hl,end_filename-1 ; add 1 to digit in filename
inc (hl)
ret
;;------------------------------------------------------------------------
;; B = length of filename
;; HL = address of filename
.load_block
ld de,&c000
call cas_in_open
ex de,hl ; load file to location stored in the file header
call cas_in_direct
call cas_in_close
ret
;;------------------------------------------------------------------------
;; setup colours
;;
;; HL = address of palette
;;
;; order: pen 0, pen 1,...,pen15,border
.setup_colours
ld b,16 ;; 16 colours
xor a ;; start with pen 0
.do_colours
push bc
push af
ld c,(hl) ;; colour value
inc hl
ld b,c ;; B=C so colours will not flash
push hl
;; A = pen number
;; B,C = colour
call scr_set_ink ;; set colour for pen
pop hl
pop af
pop bc
;; increment pen number
inc a
djnz do_colours
;; set border colour
ld c,(hl)
ld b,c
call scr_set_border
ret
;;------------------------------------------------------------------------
;; set all colours to black
.set_to_black
ld b,16 ;; 16 colours
xor a ;; initial pen index
.stb1
push af
push bc
ld bc,0 ;; black
call scr_set_ink ;; set colour
pop bc
pop af
inc a ;; increment pen index
djnz stb1
ld bc,0 ;; black
call scr_set_border ;; set border colour
ret
;;------------------------------------------------------------------------
;; a colour palette defined using firmware colour numbers
;;
;; (replace this with your own colours)
;;
;; order: pen 0, pen 1,...,pen15,border
.colour_palette
defb 0,4,&10,&b,6,&1a,&18,&d,&c,&12,1,&b,4,&f,3,6,0
;;------------------------------------------------------------------------
;; name of first filename, next filename is SOLOMONS.BI1, then
;; SOLOMONS.BI2 etc...
;;
;; (replace this with your own filename)
.filename
defb "SOLOMONS.BI0"
.end_filename
list ;; maxam command to show listing
.end equ $+1 ;; will show the last assembled address; we can use this
;; to calculate the length of the data created
</pre>