;**************************************************************************
;***                                                                    ***
;***    Screen Dump for the Kaypro 2 and older Kaypro 4's               ***
;***           Original Version Micro Cornucopia Magazine               ***
;***                    Adapted for Kaypro by Monte T. Schmiege         ***
;***		Micro Cornucopia Release 1.....M80 coding...DmC         ***
;***				 Release 2.....Removed hard address     ***
;***					       for KBDIN so it will     ***
;***					       run on both BIOS Versions***
;***					       DmC 5/9/84               ***
;***                                                                    ***
;**************************************************************************

	.z80

	CR	equ	0Dh			; Ascii carriage return
	LF	equ	0Ah			; Ascii line feed
	CHAR	equ	017h			; dump scrn char ( CNTL W )
	CPM	equ	05h			; BDOS
	CRTMEM	equ	03000h			; begin CRT memory
	BITDAT	equ	1Ch			; system bit port

	CONIN	equ	0FA0Ah
	BIOSLST	equ	0FA0FH			; BIOS LST: output
	SDADDR	equ	0E300H			; address of screen dump code
	OFFSET	equ	SDADDR-SDBEG		; offset for address calc


	ASEG
	ORG	100h

; Set up local stack 

	ld	hl,0				; zero hl register
	add	hl,sp				; pickup stack pointer
	ld	(STSTOR),hl			; save the pointer
	ld	sp,SCRSTK			; set up local stack

	ld	a,char				; plug dump screen character
	ld	(dchar),a			; into routine here for easy
						; patching later

; Do block move of screen dump code ***************************************

	ld	hl,(conin)
	ld	a,h
	cp	0E3h
	jr	z,allred			; already loaded
	
	ld	c,9				; print string function
	ld	de,MSG				; message pointer
	call	5				; call BDOS

	ld	hl,SDBEG			; beginning of screen dump
						; code is source
	ld	de,SDADDR			; destination for code
	ld	bc,SDEND-SDBEG			; byte count for LDIR

	ldir					; move the code to high mem

; Setup new vector and change top of TPA address **************************

	ld	hl,CPM				; source code address
	ld	de,SDADDR			; destination address
	ld	bc,3				; byte count

	ldir					; move jump vector

	ld	hl,SDADDR			; take address of new vector
	ld	(CPM+1),hl			; replace old vector

	ld	hl,(conin)			; get conin vector
	ld	(kbdin+OFFSET),hl		; and load into our code
	ld	hl,SDADDR+3			; address of new conin
	ld	(conin),hl			; patch old conin vector

getbak:	ld	hl,(STSTOR)			; get old stack pointer
	ld	sp,hl				; put it back
	ret					; go back to CCP control

MSG:	'Installing Screen Dump$'
MSG1:	'Screen Dump Already Installed$'

allred:	ld	c,9
	ld	de,MSG1
	call	5
	jr	getbak	

SDBEG:	jp	0				; patch in address later
SCRDMP:	DB	0CDH
KBDIN:	DS	2				; get key board character
	push	hl				;
	ld	hl,DCHAR+OFFSET			; see if screen dump char
	cp	(hl)
	pop	hl
	ret	nz				; return if not screendump

SCR:	ld	(STSTOR+OFFSET),sp		; save the stack pointer
	ld	sp,SCRSTK+OFFSET		; new stack pointer
	push	hl
	push	de
	push	bc
	push	ix
	ld	hl,CRTMEM			; hl gets start of CRTMEM
	ld	a,018h
	ld	(LCNT+OFFSET),a			; load a with lines/screen

SCR2:	push	hl				; save the starting location
	pop	ix				; save hl in ix
	ld	b,50h				; b gets character count
SCR3:	DI					; disable interrupts during 
						; other memory bank access
	in	a,(BITDAT)			; switch memory bank to
	set	7,a				; bank where CRT memory 
	out	(BITDAT),a			; resides...............
	ld	c,(hl)				; get char from CRT memory
	in	a,(BITDAT)			; back to normal memory bank
	res	7,a
	out	(BITDAT),a
	EI					; reenable interrupts 
	inc	hl				; point to next character
	push	hl				; save pointer
	push	bc				; save character count
	res	7,C				; clear high bit ( in case 
						; the cursor was here )

	call	BIOSLST				; character to printer
	pop	bc				; get character counter
	pop	hl				; get character pointer
	djnz	SCR3 				; repeat til line is done
	call	CRLF+OFFSET			; and new line at end 

NXTLN:	push	ix				; get start back to hl
	pop	hl
	ld	a,(LCNT+OFFSET)			; find out where we are 
	dec	a				; bump line counter
	ld	(LCNT+OFFSET),a
	jr	z,FIN				; if line count = 0 we are 
	ld	de,080h				; de gets logical line length
	or	a
	add	hl,de				; hl points to next line
	jr	SCR2				; do another line


; Finish Screen Dump ******************************************************

FIN:	call	CRLF+OFFSET
	pop	ix
	pop	bc
	pop	de
	pop	hl
	ld	sp,(STSTOR+OFFSET)		; restore stack
	jr	SCRDMP				; done dumping get next key-
						; board character

; Newline Routine *********************************************************

CRLF:	ld	c,CR
	CALL	BIOSLST	
	ld	c,LF
	call	BIOSLST
	ret

; High memory Scratch Ram *************************************************

	LCNT:	defs	1
	DCHAR:	defs	1
	STSTOR:	defs	2
		defs	24
	SCRSTK:	defs	2
	SDEND:	DEFS	1			; end of program

;**************************************************************************
	end