; this program works only for Banked version of BIOS22
; it loads a new CCP in the warm boot area in bank 0 (0x8000)
; so that subsequent warm boots load the new CCP from there.
;  it works by DMA moving a 2k block from NewCCP bank 1 to 0x8000 bank 0
	z80
False	equ	0
True	equ	not false

FillOutPage	equ	False

DmaCmd		equ 	0xe0
DmaFill		equ	0xe1
DmaSrcBnk	equ	0xe2
DmaDstBnk	equ	0xe3
DmaSrcLow	equ	0xe4
DmaSrcHgh	equ	0xe5
DmaDstLow	equ	0xe6
DmaDstHgh	equ	0xe7
DmaCntLow	equ	0xe8
DmaCntHgh	equ	0xe9

DmaMove		equ	0x01
DmaSrcFill	equ	0x02
DmaDstFill	equ	0x03

DmaMoveIC	equ	0x04
DmaSrcFillIC	equ	0x05
DmaDstFillIC	equ	0x06

DmaStsBusy	equ	0x00
DmaStsNBusy	equ	0x01

Bank0		equ	0
Bank1		equ	1

SelBnk	equ	0xc0
SelCMS	equ	0xc1

WarmBoot	equ	0x0000
Bdos		equ	0x05

CR	equ	13
LF	equ	10

	org	0x100
Entry	jmp 	Start
	
MessageErr
	db	CR,LF,"Will only run on the Z80 Emulator's Banked CPM2.2 BIOS",CR,LF
	db	CR,LF,"This Program copies a new CCP over the Warm Boot copy in Bank 0"
	db	CR,LF,"The banked CPM 2.2 BIOS does warm boots from a copy of CCP/BDOS in Bank 0"
	db	CR,LF,0,'$',0x1a
MessageOK
	db	CR,LF,"New copy of Warm CCP installed in Bank 0 at 0x8000",CR,LF
	db	CR,LF,0,'$'
WrongOS	db	CR,LF,'No CPM 1.x, CPM 3.x or MPM support',CR,LF,0,'$'


OldStack	db	0,0	

Start
	sspd	OldStack
	lxi	sp,NewStack

;get version number to check compatability
	mvi	c,12		;version check
	call	BDOS
	mov	a,h
	cpi	01
	jz	its$mpm
	
	mov	a,l		;version in A
	cpi	0
	jz	its$cpm1
	cpi	30h		;version 3 or newer?
	jc	its$cpm2
its$cpm1
its$cpm3
its$mpm:
	lxi	d,WrongOS	
	mvi	c,09h
	call	bdos
	jmp	exitpgm
	
its$cpm2:	

	in	SelBnk
	cmpi	bank1
	jrz	OK

	lxi	d,MessageErr	
	mvi	c,09h
	call	bdos
	
exitpgm	lspd	OldStack
	ret

OK
	mvi	a,Bank1
	out 	DmaSrcBnk
	mvi	a,Bank0
	out 	DmaDstBnk

	mvi	a,low(NewCCP)
	out 	DmaSrcLow
	mvi	a,high(NewCCP)
	out 	DmaSrcHgh

	mvi	a,low(0x8000)
	out 	DmaDstLow
	mvi	a,high(0x8000)
	out 	DmaDstHgh

	mvi	a,low(2048)
	out 	DmaCntLow
	mvi	a,high(2048)
	out 	DmaCntHgh

	mvi	a,DmaMove
	out	DmaCmd

	lxi	d,MessageOK	
	mvi	c,09h
	call	bdos

	jmp	WarmBoot

	db	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
NewStack

EndOfCode	equ	$

	if	FillOutPage

	ifz 	low(EndOfCode)
Bump	equ	0
	else
Bump	equ	1
	endif

NextPage	equ	(high(EndOfCode)+Bump) shl 8

	rept	NextPage-EndOfCode
	db	0
	endm
	endif

EndOfFile	equ	$

NewCCP	equ	EndOfFile

	end	Entry