Changes

Jump to: navigation, search

Programming:An example loader

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>
12,273
edits