SUBTTL Video Bios (RPVIDEO.ASM) v1.0,(C)26.11.90 OLEO
TITLE  REKLAMNI PANEL

.Z80	;M80 Source - Procesor je Z80A (Z8400)

.XLIST
IF1
	INCLUDE RP.ASI
ENDIF
.LIST
.SALL
	PUBLIC	VSTART
	PUBLIC	MVLEFT
	PUBLIC	WRITE
	PUBLIC	POCPTR
	EXTRN	CA9X7
	

	CSEG

.COMMENT (video bios)

 Video bios vsebuje video krmilnik za upravljanjem displaya.
 Rutine se kli~ejo z RST 20h s tem, da podamo za rst z 
 DEFB {e {tevilko funkcije.
 Parametre podajamo v ragistre, tako kot funkcija zahteva ali pa
 po principu  "inline code parameter passing" tako, da za 
 definicijo funkcije podamo {e vrednosti A,B,E,D,L,H zaporedoma.
 Pri drugem na~inu klicanja se tudi ohranjo prvotni registri,
 parametri pa so le kot podatek.
 ^e vi{jih registrov ni potrebno podajat jih ne kodiramo.
 Kon~amo z definicijo byta NUL oz 0FFh, ki pove, da je konec
 parametrov, in za tem bytom bo program nadaljeval delo.
 Bios ohranja vse registre take kot so bili pred klicem.
 primer klica:
	ld a,'Q'	;vstavi ~rko Q v A register 	
	rst 20h 	;kli~i video bios
	DEFB 0		;funkcija 0;
	DEFB NUL	;ali DEFB 0FFh za konec parametrov
	...
	...


	ali:
	rst 20h		;kli~i bios
	DEFB 7		;funkcja 7
	DEFB 0,1	;nastavi A=0, B=1
	DEFB NUL	;konec
	...
	...

(video bios)

VSTCA	MACRO sreg,ixofs,jmploc
	inc ix
	ld a,(ix+0)
	cp NUL
	ld a,(ix-ixofs)
	jr z,jmploc
	ld sreg,(ix+0)
	ENDM
	

VSTART:	rst CLRWDT	;komplementiraj ~uvaja
	ex (sp),ix	;ix ka`e na {t. funkcije
	push iy
	PUSHALL
	ld c,(ix+0)	;v c je {tevilka funkcije
	VSTCA a,0,v_pa	;sko~i ~e ni podatkov
	VSTCA b,1,v_ca	;sko~i ~e je podan samo A
	VSTCA e,2,v_ca 	;sko~i ~e je podan samo A,B
	VSTCA d,3,v_ca 	;sko~i ~e je podan samo A,B,E
	VSTCA l,4,v_ca	; -""- A,B,E,D 
	VSTCA h,5,v_ca	; -""- A,B,E,D,L
	VSTCA a,6,v_ca	; -""- A,B,E,D,L,H
	jp vsterror	;~e pride do tu je hro{~ {e `iv

v_pa:  	pop af		;obnovi A register
	push af		;vendar ne pacaj sklada

v_ca:	inc ix

vst_p0: push hl		;shrani hl
	ld hl,vstrtn	;nastavi hl na vrnitev po klicu funkcije
	ex (sp),hl	;in vrednost nastavi na skladu, HL je OK
	push bc		;shrani BC
	ld iy,VTABLE 	;IY ka`e na za~etek tabele skokov
	ld b,0		;BC vsebuje {t. funkcije
	sla c		;BC mno`ino z 2
	rl b
	add iy,bc	;sedaj IY ka`e na kazalec za skok
	ld c,(iy+0)
	ld b,(iy+1)	;BC ka`e na funkcijo
	push bc		;kopiramo BC	
	pop iy		;v IY ki ka`e na funkcijo
	pop bc		;vzamemo BC nazaj
	jp (iy)		;JP v funkcijo,ki ne sme pacati IY,IX


vstrtn:	POPALL		;tu se bo za~elo po klicu funkcije
	pop iy
	ex (sp),ix	;nastavimo {e skok
	rst CLRWDT	;ponovno komplementiraj `uvaja
	ret		;in se vrnemo odkoder smo pri{li



VTABLE:	;tabela skokov za vidoeo rutine
	DEFW PO_CHAR	;0  Izpi{e ~rko v A
	DEFW SCRL	;1  premakne levo stran A
	DEFW SCRR	;2  premakne desno stran A
	DEFW SCRUP	;3  premik navzdol A
	DEFW SCRDN	;4  premik navzgor A
	DEFW FILLPAGE	;5  zapolni stran A z B registrom
	DEFW CLRPAGES	;6  bri{e vse video strani
	DEFW CPYB2A	;7  kopira B v A stran
	DEFW CPLPAGE	;8  naredi koplement A strani
	DEFW SETDPAGE	;9  izbere A aktivno stran za displaya
	DEFW PO_TST	;A  izpi{e Testiranje
	DEFW LDROMFONT	;B  nastavi video kontroler
	DEFW VDELAY	;C  zakasnitev  cca. A * ms
	DEFW POTTY	;D  izpis stringa v TTY na~inu
	DEFW POTIME	;E  izpis ~as na stran A
	DEFW PODATE	;F  izpis datuma na stran A
	DEFW SETRTC	;10 nastavitev RTC
	DEFW SETTIME	;11 nastavitev ~asa A,B,E,D,L,H=hh:mm:ss
	DEFW SETDATE  	;12 nastvitev datuma A,B,E,D,L,H=dd/mm/yy
	DEFW SETDAY	;13 nastavitev dneva v tednu A = w
	DEFW SHIFTUP	;14 pomik strani A navzgor 
	DEFW SHIFTDN	;15 pomik strani A navzdol 
	DEFW POAHEX	;16 izpis A registra na aktivno stran v HEX
	DEFW POAASC	;17 izpis kot POAHEX le v ascii obliki
	DEFW SHIFTL	;18 pomik strani levo
	DEFW SHIFTR	;19 pomik strani desno
	DEFW POSTR	;1A izpis DE stringa na stran A
	DEFW FLASH	;1B utripne stran A s pomo~jo B
	DEFW POERROR	;1C izpise napako *BA na tekoco stran
	DEFW MOVELEFT	;1D pomakne v levo s hitrostjo TTY
	DEFW CURSOR	;1E izpis kurzorja na aktivna stran, A=pozicija
	DEFW GOTOX	;1F nastavi cilj za izpis ~rke stran B, poz A


vsterror:
	halt


CLRPAGES: ;bri{e vse video strani
	ld d,0
	ld a,VIDEOPAGES
clrp00:	dec a
	push af
	rst CLRWDT
	call FILLVIDEO
	pop af
	jr nz,clrp00
	ret


;Brisanje in polnjenje strani z B registrim
;Vhod	A = video stran
;	B = byte s katerim polnimo stran

FILLPAGE:
	ld d,b
FILLVIDEO:	;Zapolni A video stran z D registrom
	call GETPAGEPTR
	ld bc,PAGESIZE
	and a		;ali je A==0
	jr z,fv02
fv00:	add hl,bc
	dec a
	jr nz,fv00
fv02:	ld (hl),d
	inc hl
	dec bc
	ld a,b
	or c
	jr nz, fv02
	ret

;Izra~una za~etek video strani
;vhod A = video stran
;izhod HL = kazalec na za~etek strani
GETPAGEPTR: 	
	ld hl,VIDEORAM
	cp 0
	ret z
	ld bc,PAGESIZE
gpag:	add hl,bc
	dec a
	jr nz, gpag
	ret


;Scroll v levo za en piksel stran A
;Vhod A = video stran
SCRL:	
	call GETPAGEPTR
	ld a, VIDEOLINES
scl00:	and a
	ld b, VIDEOPORTS+2
scl01:	rl (hl)
	inc hl
	djnz scl01
	dec a
	jr nz,scl00
	ret

;Scroll v desno za en piksel stran A
;Vhod A = video stran
SCRR:	
	inc a
	call GETPAGEPTR
	dec hl
	ld a, VIDEOLINES
scr00:	and a
	ld b, VIDEOPORTS+2
scr01:	rr (hl)
	dec hl
	djnz scr01
	dec a
	jr nz,scr00
	ret

;Scroll A gor za piksel. 
;Zgornja vrstica se nepovratno izgubi, spodnja pa se polni z 00.
;Vhod A = stran
SCRUP:
scsize	EQU	(VIDEOLINES-1)*(VIDEOPORTS+2)
	call GETPAGEPTR
	ld d,h
	ld e,l
	ld bc,VIDEOPORTS+2
	add hl,bc
	ld bc,scsize
	ldir
	ld b,VIDEOPORTS+2
	xor a
scup:	ld (de),a
	inc de
	djnz scup
	ret

;Scroll A dol za piksel
;Spodnja vrstica se nepovratno izgubi, zgornja se polni z 00.
SCRDN:
	inc a
	call GETPAGEPTR
	dec hl
	ld d,h
	ld e,l
	ld bc,VIDEOPORTS+2
	and a
	sbc hl,bc
	ld bc,scsize
	lddr
	ld b,VIDEOPORTS+2
	xor a
scdn:	ld (hl),a
	inc hl
	djnz scdn
	ret

;pomakne navzgor in izbri{e teko~o stran
SHIFTUP:
	ld b,VIDEOLINES
scuppg:	push bc
	push af
	call SCRUP
	ld a,(SCRUPDNDLY)
	call VDELAY
	pop af
	pop bc
	djnz scuppg
	ret
;pomakne navzdol in izbri{e teko~o stran
SHIFTDN:
	ld b,VIDEOLINES
scdnpg:	push bc
	push af
	call SCRDN
	ld a,(SCRUPDNDLY)
	call VDELAY
	pop af
	pop bc
	djnz scdnpg
	ret




;Kopira vsebino B strani v A stran
;vhod	B = {tevilka izvorne strani
;	A = {tevilka ciljne strani
CPYB2A:
	ld d,b		;shrani b
	call GETPAGEPTR
	ld a,d
	ex de,hl	;de ka`e na ciljno stran
	call GETPAGEPTR	;hl pa na izvor
	ld bc,PAGESIZE	;koliko prena{amo je v bc
	ldir		;prenesemo
	ret		;in se vrnemo

;Naredi komplement  A strani
;Vhod	A = video stran
CPLPAGE:	
	call GETPAGEPTR	;hl ka`e na `eleno stran
	ld bc,PAGESIZE	
cpl00:	ld a,(hl)
	cpl		;invertiramo vse byte cilja
	ld (hl),a
	inc hl
	dec bc
	ld a,b
	or c
	jr nz,cpl00
	ret


;Printout Character
;vhod A = ASCII karakter
;Uporablja (CHARS), kot kazalec na tabelo ~rk vi{ine 9 pikslov
;in {irine max 1 byte, ter (CHARSDE) za cilj kamor naj kopira
;zahtevano ~rko.
PO_CHAR::
	ld h,0		;mno`imo A z 9 da dobomo offset
	ld l,a		;za kazalec na obliko ~rke
	ld b,0
	ld c,a
	add hl,hl	;a=a+a=2a	
	add hl,hl	;a=2a+2a=4a
	add hl,hl	;a=4a+4a=8a
	add hl,bc	;a=9a

	ld bc,(CHARS)
	add hl,bc	;pri{tejemo {e za~etek tabele
	ld bc,VIDEOLINES;koliko bytov kopiramo
	ld de,(CHARSDE)	;beremo, kam naj kopiramo
pochl:	ldi		;prenesemo en byt znaka
	push af
	ld a,e
	add a,VIDEOPORTS+1 ;izra~unamo cilj naslednje video vrstice
	ld e,a
	ld a,d
	adc a,00h
	ld d,a
	pop af
	jp pe,pochl
	ret

PO_TST:	;izpi{e tabelo na ni~to stran
	ld de,VIDEORAM+VIDEOPORTS ;prva ~rka
	ld b,VIDEOPORTS	;koliko crk imamo
	ld hl,potsttbl	;kazalec na prvo ~rko
potstl:	
	ld (CHARSDE),de	;kam naj se izpi{e ~rka
	ld a,(hl)
	rst CLRWDT
	PUSHALL
	call PO_CHAR
	POPALL
	rst CLRWDT
	dec de
	inc hl
	djnz potstl
	ret
potsttbl:	;tabela s sporo~ilom
	DEFM "Testiranje..."


;Izbere aktivno video stran,tako da nastavi spremenljivke
;Vhod A = display page number
SETDPAGE: 
	ld (CURDPAGE),A
	call GETPAGEPTR
	push hl
	ld bc,VIDEOLINES*(VIDEOPORTS+2)-1
	add hl,bc
vsync:	halt
	TSTBIT INT1,P1
	jr nz,vsync
	ld (CURPAGEPTR),hl
	pop hl
	ret

;Nastavi kontroler za izpis ~rk
LDROMFONT:
	ld bc,CA9X7  	;Nastavi kazalec na za~etek tabele
	ld (CHARS),bc	;o obliki ~rk
	ld de,VIDEORAM	;nastavi kazalec za PO_CHAR na stran 0
	ld (CHARSDE),de
	xor a
	call SETDPAGE	;aktivna je stran 0
	ld a,7		;zakasnitev pri POTTY
	ld (TTYDLY),a
	ld a,4		;zakasnitev pri utripanju
	ld (FLASHDLY),a
	ld a,20		;zakanitev pri izpisu casa
	ld (TIMEDLY),a	
	ld a,100	;zakasnitev pri pomiku gor ali dol
	ld (SCRUPDNDLY),a
	ret


;Zakasnitve A*DCLK, ali B*83*DCLK
;Vhod	A = {t. hold ukazov ali
;	A=0 in B={t. (83*hold ukazov)
VDELAY:
	cp 0
	jr z,vdly01	;~e je A==0 potem je zakasnitev dalj{a
vdly:	ld b,a
vdly00:	rst CLRWDT
	halt	;zunanja referenca 1.2ms
	rst CLRWDT
	djnz vdly00
	ret
vdly01: ld a,b
vdly02:	ld b,83
	call vdly00
	dec a
	jr nz,vdly02
	ret



CPSPDP	MACRO dest,source ;Za Teletype printout
	rst CLRWDT
	ld a,dest
	ld b,source
	call CPYB2A
	ld a,dest
	call SCRL
	rst CLRWDT
	ld a,dest
	call SETDPAGE
	ld a,(TTYDLY)
	call vdly
	ENDM

;Print String In Teletype mode na straneh 0 in 1
; Vhod 	A = kazalec LOW, B = kazalec HI
; Kon~a takrat, ko je na koncu QUOTE '"' karakter (22h)
POTTY:

	ld h,b		;HL je kazalec na string
	ld l,a
WRITE:	ld a,(CURDPAGE)	;kopiraj aktivno stran na stran 0 
	ld b,a
	xor a
	push hl
	call CPYB2A
pot00:	TSTBIT INT1,P1
	jr z,pot00
pot01:	TSTBIT INT1,P1
	jr nz,pot01
	xor a
	call SETDPAGE
	ld (CHARSDE),hl
	pop hl
pstty:	
	ld a,(hl)	;poberi ~rko
	cp '"'		;a je `e konc besedila
	ret z
	push hl		;shrani kazalec na tekst
      	call PO_CHAR	;tiskaj ~rko
	CPSPDP 1,0
	CPSPDP 0,1
	CPSPDP 1,0
	CPSPDP 0,1
	CPSPDP 1,0
	CPSPDP 0,1
	CPSPDP 1,0
	CPSPDP 0,1
	pop hl
	inc hl
	jp pstty



;Makroji za Real Time Clock (RTC) sekcijo ukazov

RTCWAIT:
	push af
rtcl:	rst CLRWDT
	in a,(RTC+0Dh)	;;pri`gi HOLD bit
	or 1
	out (RTC+0Dh),a
	in a,(RTC+0Dh)	
	and 10b		;;ali je BUSY==0
	jr z,rtcr		;;~e je sko~i
	in a,(RTC+0Dh)	;;sicer resetiraj HOLD
	and NOT 1
	out (RTC+0Dh),a
	jr rtcl
rtcr:	pop af
	ret

CLRHOLD MACRO	;Bri{e HOLD bit
	  push af
	  in a,(RTC+0Dh)	;;resetiraj HOLD
	  and NOT 1
	  out (RTC+0Dh),a
	  pop af
	ENDM

RTCWRITE MACRO register	;Pi{e v RTC register
	  call RTCWAIT
	  out (RTC+register),a	;;pi{i register
	  CLRHOLD
	ENDM

RTCREAD	MACRO register		;Bere RTC register
	  call RTCWAIT
	  in a,(RTC+register)	;;pi{i register
	  CLRHOLD
	  and 0Fh
	ENDM

PORTCR	MACRO	register	;Pobere register iz ure in izpi{e
	  ld (CHARSDE),hl
          push hl
	  RTCREAD register
	  or 30h		;;Spremenimo v ASCII kodo
	  call PO_CHAR
	  pop hl
	  inc hl
	ENDM

POSIGN	MACRO  sign		;Izpi{e znak
	  ld (CHARSDE),hl
	  push hl
	  ld a,sign
	  call PO_CHAR
	  pop hl
	  inc hl
	ENDM
	
;Izpi{e ~as na stran a v obliki hh:mm:ss
; Vhod A = stran
POTIME:
	call GETPAGEPTR
	REPT 3
	  inc hl
	ENDM
	PORTCR 0
	PORTCR 1
	POSIGN ':'
	PORTCR 2
	PORTCR 3
	POSIGN ':'
	PORTCR 4
	PORTCR 5
	ret

;Iztiska Datum na A stran po vzorcu www dd/mm/yy
;Vhod A = stran
PODATE:
	call GETPAGEPTR
	inc hl
	PORTCR 0Ah
	PORTCR 0Bh
	POSIGN '.'
	PORTCR 8
	PORTCR 9
	POSIGN '.'
	PORTCR 6
	PORTCR 7
	POSIGN ' '
	RTCREAD 0Ch
	and 111b
	cp 0
	jr nz,poned
	POSIGN 'd'
	POSIGN 'e'
	POSIGN 'N'
	ret
poned:	cp 1
	jr nz,torek
	POSIGN 'n'
	POSIGN 'o'
	POSIGN 'P'
	ret
torek:	cp 2
	jr nz,sreda
	POSIGN 'r'
	POSIGN 'o'
	POSIGN 'T'
	ret
sreda:	cp 3
	jr nz,cetrt
	POSIGN 'e'
	POSIGN 'r'
	POSIGN 'S'
	ret
cetrt:	cp 4
	jr nz,petek
	POSIGN 't'
	POSIGN 'e'
	POSIGN '^'
	ret
petek:	cp 5
	jr nz,sobota
	POSIGN 't'
	POSIGN 'e'
	POSIGN 'P'
	ret
sobota:	POSIGN 'b'
	POSIGN 'o'
	POSIGN 'S'
	ret


;Nastavi se RTC za delovanje - 24h, ...
SETRTC:
	ld c,RTC+0Fh
	ld a,0001b
	out (c),a	; 24 urni prikaz
	ld a,0101b
	out (c),a	; 24 urni prikaz
	ld a,0100b
	out (c),a	; 24 urni prikaz
	ld a,0100b
	out (RTC+0Eh),a	; 1 sek STD.P
	ld a,0000b
	out (RTC+0Dh),a	; RUN
	ret


;Nastavi ~as RTC      tt:mm:ss
; Vhod A,B,D,E,H,L tako,da v zaporadju tvorijo ~as
SETTIME:
	ld c,RTC
	IRPC register,hldeba
	  call RTCWAIT
	  out (c),register
	  CLRHOLD
	  inc c
	ENDM
	ret


;Nastavi datum RTC   dd/mm/yy
; Vhod A,B,D,E,H,L tako, da v zaporedju tvorijo datum
SETDATE:
	ld c,RTC+6
	IRPC register,badehl
	  call RTCWAIT
	  out (c),register
	  CLRHOLD
	  inc c
	ENDM
	ret


;Nastavi dan v tednu RTC
;Vhod A = {t. dneva v tednu ; 0=Ned, 1=Pon, 2=Tor ...
SETDAY:
	and 111b
	RTCWRITE 0Ch
	ret

;Izpis vrednosti A registra na aktivno stran v hexadecimalni obliki
;Uporabno pri razhro{~evanju
POAHEX:
	push af
	ld a,(CURDPAGE)
	ld b,0
	call FILLPAGE
	ld a,(CURDPAGE)
	call GETPAGEPTR
	inc hl
	ld (CHARSDE),hl
	pop af
	push af
	HEXASC
	call PO_CHAR
	ld hl, CHARSDE
	inc (hl)
	pop af
	REPT 4
	 rrca
	ENDM
	HEXASC
	call PO_CHAR
	ret

;Izpis vrednosti A registra na aktivno stran v ASCII obliki
;Uporabno pri razhro{~evanju
POAASC:
	push af
	ld a,(CURDPAGE)
	ld b,0
	call FILLPAGE
	ld a,(CURDPAGE)
	call GETPAGEPTR
	inc hl
	ld (CHARSDE),hl
	pop af
	call PO_CHAR
	ret

;Pomik v levo strani A
SHIFTL:
	ld b,VIDEOPORTS*8
shl:	push af
	push bc
	call SCRL
	ld a,(TTYDLY)
	call VDELAY
	pop bc
	pop af
	djnz shl
	ret

;Pomik v desno strani A
SHIFTR:
	ld b,VIDEOPORTS*8
shr:	push af
	push bc
	call SCRR
	ld a,(TTYDLY)
	call VDELAY
	pop bc
	pop af
	djnz shr
	ret

;Ispis stringa na stran A
;Vhod: A=stran, DE=kazalec na string
POSTR:
	push af	  		;bri{i stran
	push de
	ld b,0
	call FILLPAGE
	pop de
	pop af
	call GETPAGEPTR		;nastavi kazalec na levo
	ld bc,VIDEOPORTS
	add hl,bc
	ld b,c			;b je {tevec ~rk
	ld (CHARSDE),hl
	ex de,hl
postr0:	ld a,(hl)		;ponavljaj izpis do "
	cp '"'
	ret z
	PUSHALL
	call PO_CHAR
	POPALL
	dec de
	ld (CHARSDE),de
	inc hl
	djnz postr0		;ali je konec displaya
	ret

;Utrip teksta na strani A, naprej caka preklopi na B stran,
; caka in preklopi nazaj na A stran
;Vhod: A=stran, B=pomozna stran za utrip
FLASH:
	push af
	push bc
	ld c,a
	ld a,b
	ld b,c
	call CPYB2A
	pop bc
	push bc
	ld a,b
	call CPLPAGE
	ld a,(FLASHDLY)
	ld b,a
	xor a
	call VDELAY
	pop bc
	ld a,b
	call SETDPAGE
	ld a,(FLASHDLY)
	ld b,a
	xor a
	call VDELAY
	pop af
	call SETDPAGE
	ret

;Izpise string (napako) BA na tekoco stran in ~aka nekaj ~asa
;Vhod A=low byte kazalca na string, B=high ""
;String se mora kon~ati z "
POERROR:
	ld d,b
	ld e,a
	ld a,(CURDPAGE)
	call POSTR
	ld b,10
	xor a
	call VDELAY
	ret


;Pomik v levo za eno stran
MOVELEFT:
MVLEFT:
	ld hl, spaces
	call POTTY+2
	ret
spaces: REPT VIDEOPORTS
	  DEFB ' '
	ENDM
	DEFB '"'


;Prikaz kurzorja tako, da se invertira pozicija kurzorja na teko~i
;video strani
;Vhod A=polo`aj kurzorja od desne strani
CURSOR:
	cp VIDEOPORTS+2
	ret nc
	push af
	ld a, (CURDPAGE)
	call GETPAGEPTR
	pop af
	ld b,0
	ld c,a
	add hl,bc
	ld bc,VIDEOPORTS+2
	ld e, VIDEOLINES
cursl:	ld a,(hl)
	cpl
	ld (hl),a
	add hl,bc
	dec e
	jr nz,cursl
	ret

POCPTR:	ld hl,(CPTR)
	ld bc,VIDEOPORTS
	srl c
	and a
	sbc hl,bc
	ld de,VIDEORAM+VIDEOPORTS
	ld (CHARSDE),de
	ld b,VIDEOPORTS
pcptr0:	ld a,(hl)
	PUSHALL
	call PO_CHAR
	POPALL
	dec de
	ld (CHARSDE),de
	inc hl
	djnz pcptr0		;ali je konec displaya
	ret
	

;Nastavi CHARSDE kazalec za izpis teksta
;Vhod A=pozicija od desne strani, B=videostran
GOTOX:	
	cp VIDEOPORTS+2
	jr c,gotox1
	xor a
gotox1:	push af
	ld a,b
	call GETPAGEPTR
	pop af
	ld b,0
	ld c,a
	add hl,bc
	ld (CHARSDE),hl
	ret

	END