;; This program will dump the CPC+ System cartridge.
;;
;; This program will save 8 files.
;; CARTROM1.BIN, CARTROM2.BIN, CARTROM3.BIN, CARTROM4.BIN,
;; CARTROM5.BIN, CARTROM6.BIN, CARTROM7.BIN and CARTROM8.BIN
;; 
;; Each file will be 16K. The total data will be 128K.
;; 
;; The files should be joined together into a single binary file to
;; create the complete ROM image. Join the files in numeric order:
;; e.g. CARTROM1.BIN+CARTROM2.BIN+CARTROM3.BIN+...+CARTROM8.BIN
;; 
;; This final binary file can be converted to a .CPR cartridge file for use
;; with emulators using the BUILDCPR utility.
;;
;; Kev Thacker, 1997-2002
;; 
;; This source is released under the GNU public license.

;; firmware function to enable upper rom (rom will be readable in range &c000-&ffff)
kl_u_rom_enable	equ &b900
;; firmware function to disable upper rom (rom data can't be read)
kl_u_rom_disable equ &b903

;; firmware function to open a file for output
cas_out_open	equ &bc8c
;; firmware function to write a block of data to a file
cas_out_direct	equ &bc98
;; firmware function to close a file opened for output
cas_out_close	equ &bc8f

kl_rom_select equ &b90f

;; NOTE: ROM Data from &4000-&7FFF. Program code starts at &8000.
;; Upper ROM can be read in range &c000-&ffff (when activated).
;; Firmware area between &A600 (approximatly; depends on ROMs connected) to &bfff.
;; Lower firmware area between &0000-&0040. 

org &8000

start:

save_cart:
;; There are 8 x 16K blocks in the system cartridge.
ld b,8

;; ROM's with ID's of 128-255 will select a 16K block in the cartridge ROM
;; if a cartridge is less than 512K, then more than one ID will select the same
;; 16K block of the cartridge ROM. e.g. if the cartridge is 128K, then selections
;; 128 and 136 will select the same 16K block.

ld e,&80

save_loop:
push de
push bc

push de

;;----------------------------------------------------------------
;; select rom using firmware
;; we restore this after selecting cart page
;; firmware will remember this selection
ld c,1
call kl_rom_select

;;----------------------------------------------------------------
;; enable upper rom
call kl_u_rom_enable

;;----------------------------------------------------------------
;; disable interrupts - will stop firmware from enabling any roms
di
pop de
;;----------------------------------------------------------------
;; select upper rom - cart page
ld c,e
ld b,&df
out (c),c

;; copy rom data to ram
ld hl,&c000
ld de,&4000
ld bc,&4000
ldir

;; restore rom 1 for firmware
ld bc,&df01
out (c),c

ei

;;----------------------------------------------------------------
;; disable upper rom
call kl_u_rom_disable

;;----------------------------------------------------------------
;; save rom data using firmware
ld hl,&4000
ld de,&4000
call save_file

pop bc
pop de

inc e ;; increment rom page
djnz save_loop
ret


;;----------------------------------------------------------

save_file:
push hl
push de

ld hl,end_filename-1		;; update digit in filename
inc (hl)

ld b,end_filename-filename	;; B = length of filename
ld hl,filename			;; HL = address of filename
ld de,two_k_buffer		;; DE = address of 2k buffer (not used
					;; with cas_out_direct)

call cas_out_open			;; firmware function: open output file
pop de
pop hl
					;; HL = start address
					;; DE = length
					;; BC = execution address
ld bc,0
ld a,2				;; binary file
call cas_out_direct		;; firmware function: write a entire block

call cas_out_close		;; firmware function: close output file
ret

;; the initial filename, this is updated for 
;; each file saved
filename:
defb "CARTROM0"
end_filename:

two_k_buffer equ $+1

end start
