;driver for videx card
;general philosophy
;BC register for character
;DE to work stuff
;HL for writing
FALSE	EQU	00h
TRUE	EQU	NOT FALSE
CPM56	EQU	TRUE
CPM60	EQU	FALSE
space	equ	20h
data	equ	0e0b1h
reg	equ	0e0b0h
speaker	equ	0e030h
videx	equ	0e300h
ram0	equ	0ec00h
ram1	equ	0ed00h
offrom	equ	0efffh
@gendd	macro	?dd
	if (?dd gt 7fh) and (?dd lt 0ff80h)
	db	100h
	else
	db	?dd
	endif
	endm
jr	macro	?n
	db	18h
	@gendd	?n-$-1
	endm
jrc	macro	?n
	db	38h
	@gendd	?n-$-1
	endm
jrnc	macro	?n
	db	30h
	@gendd	?n-$-1
	endm
jrz	macro	?n
	db	28h
	@gendd	?n-$-1
	endm
jrnz	macro	?n
	db	20h
	@gendd	?n-$-1
	endm
ldir	macro	;;LDIR
	db	0edh,0b0h
	endm
	org	100h
	jmp	mover
	offset	equ	0f300h
	org	180h
begin:	equ	$+offset
	lda	offrom	;turns off roms
	lda	videx	;turns on videx
	call	putchar ;
	ora	a	;clear carry
	lhld	basel
	xchg
	lhld	chorz	;store chorz offoffset
	mov	a,e
	adc	l	;add chorz
	mvi	l,0fh	;register f
	mov	h,a
	shld	reg
	mov	a,d	;cvertoffoffset
	aci	00h	;
	dcr	l	;0eh
	mov	h,a
	shld	reg	
	lda	offrom 	;turn off rom
	ret
;**************************
putchar:	equ	$+offset
	lda	escflag	;are we ready to process an escape sequence 
	ora	a
	jnz	escxy
notesc:	equ	$+offset
	mov	a,c
	cpi	' '
	jc	control	;handle control if less than SPACE
	lda	chorz
	mov	b,a
	call	chrput
	jmp	done
;*********************************
;ring the bell
bell:	equ	$+offset
	mvi	b,0c0h
bell1:	equ	$+offset
	mvi	c,080h
bell2:	equ	$+offset
	dcr	c
	jrnz	bell2-offset
	lda	speaker
	dcr	b
	jrnz	bell1-offset
	ret
ebegin	equ	$+offset
;***************************************************
	org	2b0h
escxy: 	equ	$+offset
	lxi	h,escflag
	inr	m
	mov	a,m
	cpi	02h
	jrnz	xy-offset
notxy:	equ	$+offset
	mov	a,c
	cpi	'='
	rz
	mvi	m,00h
	cpi	'Y'
	jz	cleareos
	cpi	'*'
	jz	formfeed
	cpi	'T'
	jz	cleareol
	ret
xy:	equ	$+offset
	mov	a,c	;move the character
	sui	' '
	mov	c,a
	mov	a,m
	cpi	1h
	rz
	cpi	04h
	jrz	bknext-offset
	inx	h	;points to tempx(now used for tempy)
	mov	m,c
	dcx	h
bkhome:	equ	$+offset
	ret
;***************************************************
bknext:	equ	$+offset
;this is the second character after escape
	inx	h	;points to tempx
	mov	b,m	;
	dcx	h	;points to escflag
	mvi	m,00h	;offset escflag to zero
	jmp	gotoxy
eescxy	equ	$+offset
;****************************************************
	org	330h
tab:	equ	$+offset
	lxi	h,chorz
	mov	a,m
	ani	0f8h
	ora	a
	adi	08h
	cpi	050h	;chorz number
	jrc	backtab-offset
	mvi	a,04fh	;
backtab:	equ	$+offset
	mov	m,a
	ret
;****************************************************
control:	equ	$+offset
	cpi	'G'-40h	;ctrl-G=BEL
	jz	bell
	cpi	'I'-40h	;ctrl-I=TAB
	jz	tab
	cpi	'['-40h	;ctrl-[=ESC=software leadin
	jz	escxy
	cpi	'H'-40h	;ctrl-H=BS
	jz	bs
	cpi	'M'-40h	;ctrl-M=CR
	jz	cr
	cpi	'^'-40h	;ctrl-^=RS=software home cursor
	jz	homecursor
	cpi	'L'-40h	;ctrl-L=FF=software cursor forward
	jz	done
	cpi	'K'-40h	;ctrl-K=VT=software cursor up
	jz	cursorup
	cpi	'J'-40h	;ctrl-J=LF=software cursor down
	jz	lf
	ret
etab	equ	$+offset
;************************************
	org	380h
formfeed:	equ	$+offset
	call	homecursor
cleareos:	equ	$+offset
	call	cleareol
	lxi	h,cvert
	mov	a,m
	push	a
clloop:	equ	$+offset
	lxi	h,cvert
	inr	m
	mov	a,m
	cpi	018h	;24 columns
	jrnc	clback-offset
	call	vtabz
	call	etb
	jmp	clloop
clback:	equ	$+offset
	pop	a
	jmp	vtab
;****************************************
etb:	equ	$+offset
	mvi	b,0h
	jr	etbloop-offset
cleareol:	equ	$+offset
	lda	chorz
	mov	b,a
etbloop:	equ	$+offset
	mvi	c,' '
	call	chrput
	inr	b
	mov	a,b
	cpi	050h
	jrc	etbloop-offset
	ret
;**************************************************
homecursor:	equ	$+offset
	xra	a
	mov	b,a
	mov	c,a
gotoxy:	equ	$+offset
;when entered from escxy b=cvert, c=chorz
	mov	h,b
	mov	l,c
	shld	chorz
	mov	a,b
vtab:	equ	$+offset
	sta	cvert
vtabz:	equ	$+offset
	lhld	chorz
	mov	a,h
	add	a
	add	a	;x4
	add	h	;x5
	ora	a	;clear carry
	mov	h,a
	lda	start
	adc	h
bascal1:	equ	$+offset
	mov	l,a
	rrc
	rrc
	rrc
	rrc
	ani	0fH	;x80
	mov	h,a
	mov	a,l
	rlc
	rlc
	rlc
	rlc
	ani	0f0H	;x80
	mov	l,a
	shld	basel 
	ret			
;*************************
cr:	equ	$+offset
	mvi	a,0h
	sta	chorz
	ret
;********************************************
bs:	equ	$+offset
	lxi	h,chorz
	mov	a,m
	sui	01h
	jrnc	backbs-offset
	mvi	m,4fh
	jmp	cursorup
backbs:	equ	$+offset
	mov	m,a
	ret
eformfeed	equ	$+offset
;*******************************************
	org	400h
done:	equ	$+offset
	lxi	h,chorz
	inr	m
	mov	a,m
	cpi	050h	;width
	rc
	call	cr
	jmp	lf
	ret
;***********************************
cursorup:	equ	$+offset
	lxi	h,cvert
	dcr	m
	jp	backcu
	inr	m
backcu:	equ	$+offset
	jmp	vtabz
;**********************************
lf:	equ	$+offset
	lxi	h,cvert
	inr	m
	mov	a,m
	cpi	018h	;height
	jrc	backlf-offset
	dcr	m
	jrnz	scroll-offset
backlf:	equ	$+offset
	jmp	vtabz
scroll:	equ	$+offset
	lda	cvert
	sta	tempy
	ora	a
	lda	start
	adi	05h
	ani	07fh
	sta	start
	call	bascal1
	lda	basel
	mvi	l,0dh
	mov	h,a
	shld	reg
	dcr	l
	lda	baseh
	mov	h,a
	shld	reg
	mvi	a,17h
	call	vtab
	call	etb
	lda	tempy
	jmp	vtab
psncalc:	equ	$+offset
;************
; calculates position in page
;and offsets the videx card
;B contains the chorz
;returns the result in E and the carry flag
	mov	a,b
	ora	a	;clear carry
	lhld	basel
	xchg
	adc	e
	mov	e,a
	mvi	a,00h
	adc	d
	rrc		;determine the carry flag
	push	psw
	ani	03h
	rlc		;x2
	rlc		;x4
	lxi	h,reg
	ora	l	;a=a+l
	mov	l,a
	mov	a,m	;toggle the correct page
	pop	psw
	ret
edone	equ	$+offset
;******************************
;CHRPUT   B contains chorz, C contains the character
;
;destroys HLchrput:	equ	$+offset
	org	480h
chrput:	equ	$+offset
	call	psncalc
	jrnc	lowpage-offset
hipage:	equ	$+offset
	lxi	h,ram1
	jr 	writeit-offset
lowpage:	equ	$+offset
	lxi	h,ram0
writeit:	equ	$+offset
	mov	a,e
	ora	l
	mov	l,a
	mov	a,c
	ani	7fh
	mov	m,a
	ret
;********************************
temp:	equ	$+offset
	db	0
chorz:	equ	$+offset
	db	0
cvert:	equ	$+offset
	db	0
basel:	equ	$+offset
	db	0
baseh:	equ	$+offset
	db	0
escflag:	equ	$+offset
	db	0
tempx:	equ	$+offset
	db	0
tempy:	equ	$+offset
	db	0
start:	equ	$+offset
	db	0
echrput	equ	$+offset
	org	500h
initseq:	equ	$
	db	07bh,050h,062h,029h,01bh,8,018h,019h,0,8,0c0h
	db	8,0,0,0,0
initflag:	equ	$
	db	0
init:	equ	$
	lda	initflag
	ora	a
	jrnz	backinit
	lda	offrom	;turn off card
	lda	videx	;and on again
	lxi	b,1000h	;16 registers to initialize
	lxi	d,initseq
loop2:	equ	$
	xchg	;h contains initialization
	mov	a,m	;in the accumulator
	xchg		;back agian
	mov	h,a
	mov	l,c
	shld	reg
	inr	c
	dcr	b
	inx	d
	jrnz	loop2
	mvi	a,0h
	sta	escflag
	sta	tempx
	sta	start
	call	formfeed
	lda	offrom
	lda	initflag
	dcr	a
	sta	initflag
backinit:	equ	$
	ret
mover:
	lxi	d,begin
	lxi	h,begin-offset
	lxi	b,ebegin-begin
	ldir
	lxi	d,escxy
	lxi	h,escxy-offset
	lxi	b,eescxy-escxy
	ldir
	lxi	d,tab
	lxi	h,tab-offset
	lxi	b,etab-tab
	ldir
	lxi	d,formfeed
	lxi	h,formfeed-offset
	lxi	b,eformfeed-formfeed
	ldir
	lxi	d,done
	lxi	h,done-offset
	lxi	b,edone-done
	ldir
	lxi	d,chrput
	lxi	h,chrput-offset
	lxi	b,echrput-chrput
	ldir
	call	init
	lxi	h,0f480h
;ONE OF THE FOLLOWING EQUATES SHOULD BE TRUE
	IF CPM56
	shld	0da0dh
	ENDIF
	IF CPM60
	shld	0fa0dh
	ENDIF
	jmp	0000	;WARM BOOT
	end



