Programming:An example loader
From CPCWiki - THE Amstrad CPC encyclopedia!
;; 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