;********************************************************************
;
;  SOLVID.ASM
;	Sol-20 video memory access demonstration
;
;	03/02/2019, Mike Douglas
;
;********************************************************************
VIDBASE	equ	0CC00H		;start of video RAM
VIDLEN	equ	400h		;1K of video RAM
VIDENDP	equ	(VIDBASE+VIDLEN) shr 8	;end of RAM page number

VIDSCRL	equ	0FEh		;scroll register


; CP/M entry point. Use vidClr subroutine to clear the screen. Use
;   vidRC subroutine to display the first 64 characters from the
;   character ROM on different rows and columns

	org	0100h		;CP/M program location

	call	vidClr		;clear SOL video screen
	lxi	b,63		;Row(B)=0, Col(C)=63 

loop	mov	a,c		;use column number as the byte to display
	call	vidRC		;display the byte in A at Row, Col (B,C)

	mov	a,b		;increment and wrap row
	inr	a
	ani	0Fh		;keep row 0-15
	mov	b,a

	dcr	c		;decrement column number
	jp	loop		;do all 64 columns

; Wait here about 4 seconds to hold the display before returning to CP/M

	mvi	b,5		;hold screen about 4 seconds
	
delay	dcx	h		;takes .79s per full count
	mov	a,h		;reach zero yet?
	ora	l
	jnz	delay		;not yet

	dcr	b
	jnz	delay

	ret			;return to CP/M 

;--------------------------------------------------------------
; vidClr - Clear video display and reset scroll register
; On Entry:
;    none
; On Exit:
;    A=0
; Clobbers H,L
;--------------------------------------------------------------
vidClr	lxi	h,VIDBASE	;HL->start of video RAM

vcLoop	mvi	m,' '		;store a space to clear
	inx	h		;bump to next video location
	mov	a,h		;all done?
	sui	VIDENDP
	jnz	vcLoop		;not yet
	
	out	VIDSCRL		;ensure scroll register is reset
	ret			;exit
	
;--------------------------------------------------------------
; vidRC - Write byte in A to Row, Column in B,C
; On Entry:
;    A=Byte to write to video RAM
;    B=Row (0-15)
;    C=Column (0-63)
; On Exit:
;    none
; Clobbers H,L
;--------------------------------------------------------------
vidRC	push	psw		;save display byte

	mov	a,b		;compute row*64 
	rrc			;MSB is in bits 1,0
	rrc			;  and LSB is in bits 7,6
	mov	l,a		;save result in L
	
	ani	3		;isolate two bits for MSB
	adi	VIDBASE shr 8	;compute MSB of video address
	mov	h,a		;H=MSB of video address
	
	mov	a,l		;get LSB bits of row
	ani	0C0h		;A=LSB bits from row alone
	add	c		;add in the column offset
	mov	l,a		;HL->proper spot in video RAM
	
	pop	psw		;A=byte to display
	mov	m,a		;put byte in video RAM

	ret
	
	end
