.title	'Monitor for Cartback'
	.ident	CARTMN
	.pabs
	.phex
	version	==	3
	revision==	05 ;last changed 5/23/83 Doug
;----------------
; Monitor for Cartback
;
;    Memory Map:
;
;  0 	 - FFh	: CPM area (perm)
;  100h  - 48FFh: CARTBACK (3000h+ is unused)
;  4900h - 4CFFh: 1K monitor (this program)
;  4D00h - 4DFFh: 0-100 (when compressed, temp)
;  4E00h - 79FFh: DDT, CPM, BIOS (when compressed)
;  7A00h - C500h: HARDHELP (initially) & Buffer space
;  D400h - FFFFh: DDT, CPM, BIOS (perm)
;
;---------------
; Update History:
;
; Version 3.0   This is a one-shot monitor.  It lets
;		the user run Hardhelp, Cartback or
;		use DDT.  When one or the other has
;		been loaded it becomes the only option
;		besides DDT.  This is necessary because
;		Cartback's read write buffers reside
;		in Hardhelp's program area.  If
;	     	Hardhelp is chosen, this monitor
;		is over-written, leaving the user with
;		DDT over his head, and Hardhelp in TPA.
;
;				    D.Stein 7/82
;
; 3.01 02/10/83	Reduce length of code prior to adding
;		code to start CTC chip.  DBrentlinger
;
; 3.02 02/14/83 Revamp routine to get users request.
;
; 3.03 02/14/83 Add code for clock timer for hardhelp.
;
; 3.04 02/18/83 Add code to routine that gets users
;		request. This version installed in 
;		Cartback.  D Brentlinger
; 3.05 05/23/83 Bump up version number to keep it
;		even with Cartback.com  DRB
.page
CBacklength==	3000h	; Version 3.0 ***Unused
HHelplength==	5000h	; Version 3.18
cr	==	0Dh
lf	==	0Ah
BDOS	==	5
SIO1AC	==	2Ah	; port 0 control (for init)
SIO1BC	==	2Bh	; port 1 control (for ints)
CTC0	==	30h
CTC3	==	33h
ticsec	==	48h
ticks	==	40h	; time in low memory
	.loc	4900h
	jmp	wboot	; new warm boot
	jmp	cboot	; jump here if from prom
;
; Do not have any interrupts from here to EI.
; This code does not execute here.  It is LDIR'd into
; CPM's read write buffer and executed there.  This
; leaves the code in a safe location to be executed
; after hardhelp loads into memory.
;
loadcode:
	ldir		; to run it at 100h.
	jmp	100h
lenloadcode == . - loadcode
movglobal==	80h+lenloadcode 
global:
	exaf		;***different registers,
	exx		;be careful!!!!!
;
	lxi	H,ticks ; Update fractions of a second
	lda	ticsec	; 60 for U.S., 50 for Europe
	inr	M
	cmp	M
	jrnz	..timeout
	mvi	M,0
	inx	H
	mvi	A,60	; Update seconds
	inr	M
	cmp	M
	jrnz	..timeout
	mvi	M,0
	inx	H
	inr	M	; Update minutes
	sub	M
	jrnz	..timeout
	mov	M,A
	inx	H
..timeout:
	exx		;back to old registers
	exaf		
	ei
	reti
lenglobal== . - loadcode
.page
wboot:	lxi	SP,stack
loop:	lxi	H,MNUmsg ; ask what to run next
	call	prtmsg
	lda	lastreq	; If last request is blank,
	cpi	' '	; print the complete menu
	jrz	..all	; ELSE
	cpi	'D'	; If DDT, ok too
	jrnz	..noHH	; ELSE, tape selected so
..all:	lxi	H,HHmsg	; no hardhelp available
	call	prtmsg	
..noHH: lxi	H,selmsg ;ask user for selection
	call	prtmsg
	call	conin	; get answer
	cpi	'D'	; check for ddt
	jrnz	..cont	; If DDT, do a restart, but
	lda	lastreq	; If last request is tape,
	cpi	'T'	; do not change
	jrz	..rst	; 'T' in last request
	sta 	lastreq	; ELSE, stuff the 'D'
..rst:	rst	6	; and do a restart
..cont:	cpi	'H'	; ELSE, check for hardhelp
	jrz	newhard ; IF hardhelp, we are thru
	cpi	'T'	
	jrz	tape	; ELSE, check for cartback
err:	lxi	H,error	; IF none of above, error
	jmpr	loop
tape:
	sta	lastreq	; store last request of user
	lxi	H,0	; COMPRESS as inline code
	lxi	D,4D00h
	lxi	B,100h	; setup 0-100h
	ldir
	lxi	H,0D400h
	lxi	D,4E00h
	lxi	B,2C00h	; setup DDT, BDOS, BIOS
	ldir		; end of COMPRESS code	
	jmp	103h	; OS, then run it.
.page
; If the user loads Hardhelp this moniter is
; overwritten and it is not available.  Therefore,
; We need to save global, which sets the clock bytes
; at 40h in low memory.  The 2nd LDIR saves it.
;
newhard:
	lxi	H,crlf
	call	prtmsg	   ; Do a carriage ret first
	lda	lastreq	   ; If already loaded tape
	cpi	'T'	   ; back up, can not come
	jrz	err	   ; back here, Else cont
	lded	1	   ; First, change our warm
	lxi	H,HHwbaddr ; boot address when running
	lxi	B,3	   ; hardhelp so you can not
	ldir		   ; exit it.
;
	lxi	D,80h	    ;dest of LDIR for clock
	lxi	H,loadcode  ;source to LDIR
	lxi	B,lenglobal ;length of LDIR
	LDIR
;
; Get the high byte of the interrupt vector.  56h is
; the low byte of the interrupt vector.  Then, stuff
; the addr of our timing routine (global) there.
;
	ldai		;high addr of interrupt vector
	mov	H,A	;in the accum
	mvi	L,56h	;CTC vector in BIOS
	mvi	m,movglobal&0FFh ;global is in CPM's
	inx	H		 ;read buffer now
	mvi	m,(movglobal>8)&0FFh
;
; Internal fixed hertz rate (62 hertz)
;Set up the counter timer chip so Hardhelp works
;
	mvi	A,0A5h	; enable real-time interrupts
	out	CTC3
	mvi	A,252	; interrupt at 4Mhz/(256*252)
	out	CTC3
	mvi	A,50h 	; interrupt vector
	out	CTC0	; must send to channel zero
;
; Set up to move hardhelp from 7A00h to 100h, then
; jump to 80 to execute the code because it would
; be overwritten if it was here.
;
	lxi	H,7A00h	 ; set up for next ldir of
	lxi	D,100h	 ; hardhelp from high memory
	lxi	B,Hhelplength ;then jump to 80 to
	jmp	80h	   ; execute the LDIR
;
HHwbaddr:jmp	100h	   ; This becomes HH's wboot addr
.page
;------------
; We arrive here from a prom bc command.
cboot:	di		; make sure no ints
	lxi	SP,stack
	lxi	H,4D00h  
	lxi	D,0
	lxi	B,100h
	ldir
	lxi	H,4E00h
	lxi	D,0D400h
	lxi	B,2C00h
	ldir		; end of expand code
	lda	2	; get BIOS addr for I reg
	stai
	lxi	H,SIOi	; init SIO
	lxi	B,SIO$<8+SIO1BC
	outir
	mvi	A,11h
	out	SIO1AC
	mvi	A,18h
	out	SIO1AC
	im2
	ei		; now enable interupts
	mvi	A,' '
	sta	lastreq ; necessary
	jmp	wboot	; warm boot
.page
.sbttl	'CRT I/O routines'
;-------------
; print message at HL
;
prtmsg:
	mov	A,M
	ora	A
	rz		; not zero so there is a char
	mov	C,A
	push	H	; so print it using BDOS
	push	PSW	; save A
	mov	E,C	; char is in C
	mvi	C,2	; command 2
	call	BDOS	; print the char
	pop	PSW	; get A back
	pop	H
	inx	H	; next char
	jmpr	prtmsg
;---------
; get character from console (using BDOS) then
; convert lower to upper case.
;
conin:	mvi	C,1	; command 1
	call	BDOS	; read a char
	cpi	'a'	; convert upper to lower case
	jm	..up
	cpi	'z'+1
	jp	..up	
	sui	'a'-'A'
..up:	ret		; then return
.page
;
MNUmsg:	.ascii	[cr][lf]'CARTBACK Monitor '
	.byte	version+'0','.',revision/10+'0'
	.byte	revision@10+'0'
	.ascii	[cr][lf][lf]'Please select one of:'
	.ascii	[cr][lf]
	.ascii	[cr][lf]'  D - DDT (Debugger)'
	.asciz	[cr][lf]'  T - Tape Backup/Restore'
HHmsg: 	.asciz	[cr][lf]'  H - Hardhelp'
selmsg:	.ascii	[cr][lf]
	.asciz	[cr][lf]'Selection: '
error:	.asciz	[cr][lf]'Only one of the above: '
crlf:	.asciz	[cr][lf]
;
lastreq:.byte	' '	; Blank, T, or D

SIOi:	.byte	2,30h,11h,4
SIO$	==	.-SIOi
;
	.blkb	30
stack	==	.
	.end
 