Uživatelské nástroje

Nástroje pro tento web


hgfx:ink_attr_copy

INK, COPY, ATTR

V tomto příkladu si ukážeme jaký je rozdíl ve vykreslování pomocí režimu INK, ATTR a COPY.

INK, ATTR

Začneme nejprve INK a ATTR.

INK vykreslí nastavenou indexovou barvu v registru HGFX.SColor (Selected Color) tam, kde je při zápisu do videoram logická 1. Pokud je zapisována logická 0, barva se nemění. Tento režim je nejdůležitější, díky němu se vykresluje většina objektů.

ATTR režim se hodí pro používání s Basicem, ideální pro vykreslování základního textu. Tam kde se do videoram zapisuje logická 1 se stejně jako v režimu INK vykreslí barva nastavená v HGFX.SColor. Změna je tam, kde se zapisuje logická nula. Tam se totiž vykreslí barva nastavená v HGFX.SPColor (Selected Paper Color).

Zápis do jednotlivých bitplanů se řídí nastavením HGFX.PMask. V tomto příkladu budeme zapisovat do všech 8 bitplánů, tedy PMask bude nastaven na 0xFF. Pozici textu nastavíme pomocí Offsetů. Připomínám že HGFX nezná klasické ZX barevnostní attributy, pozice nemusí být násobkem 8, může být naprosto kdekoliv. Žádné barevnostní atributové omezení není. Proto v tomto příkladu budu vykreslovat na pozice jako X=10, Y=12 nebo X=10, Y=34.

V první části příkladu nastavíme HGFX podobně, jako jsme to dělali v předchozím příkladu. Proto jej nebudu úplně přesně popisovat. Barev zde máme nastavených 6.

; LnxSpectrum ASM editor (www.ilnx.cz) 28.07.2022
; Example 2 - Text, Ink and Attr mode.

	org	32768

gZxi	equ	0x7C3B	;General ZXI port

FontAdr	equ	0x3D00	;Adresa fontu

;HGFX Init
Start	ld	bc,gZXI

	ld	a,1	;Zapneme režim HGFX LowRes
	out	(c),a
	inc	b
	ld	a,3
	out	(c),a
	dec	b

	ld	a,2	;gZxi 002
	out	(c),a
	inc	b
	ld	a,4	;Barvy v RGB režimu (b2 0=BGR, 1=RGB)
	out	(c),a
	dec	b

	ld	a,32	;HGFX - general settings
	out	(c),a
	inc	b
	ld	a,0b111	;b0=asZXvideoram, b1=BorderZX, b2=TransparencyOff
	out	(c),a
	dec	b

	ld	a,33	;Videoram
	out	(c),a
	inc	b
	ld	a,(h)HGFX.vid	;(highbyte)Videoram (16384/256)
	out	(c),a
	dec	b

	ld	a,34	;Registers
	out	(c),a
	inc	b
	ld	a,(h)HGFX.VParam	;(highbyte)Registers
	out	(c),a
	dec	b

	ld	a,35	;Paleta
	out	(c),a
	inc	b
	ld	a,(h)HGFX.colors	;(highbyte)Color table (22528/256)
	out	(c),a
	dec	b

;Nadefinovat barvy.

	ld	hl,paleta	;zde máme připravené barvy
	ld	de,HGFX.Colors	;adresa HGFX palety
	ld	bc,6*3	;počet barev po třech složkách (BGR)
	ldir

;Nastavíme všechny Buffery na A.

	ld	a,0b000	;b0=Visible Buffer, b1=Destination Buffer, b2=Source Buffer
	ld	(HGFX.VParam),a

;Nastavíme Offsety

	ld	hl,0
	ld	(HGFX.D_OffX),hl
	ld	(HGFX.D_OffY),hl
	ld	(HGFX.S_OffX),hl
	ld	(HGFX.S_OffY),hl

Buffer smažeme do šedé, barva v indexu 0.

;Smažeme obrazovku

	ld	a,0	;Nastavíme INK Mode.
	ld	(HGFX.PMode),a

	ld	a,0	;Nastavíme Indexovou barvu 0 (šedá).
	ld	(HGFX.SColor),a

	ld	a,255	;Zápis se bude týkat všech planar vrstev.
	ld	(HGFX.PMask),a	;(každý bit zastupuje jednu vrstvu)

	ld	hl,HGFX.vid	;CLS
	ld	de,HGFX.vid+1
	ld	bc,6143
	ld	(hl),255	;Vyplníme obrazovku šedou barvou
	ldir
	xor	a	;Černý Border
	out	(254),a

Následuje tisk prvního příkladu v režimu ATTR. Vykreslíme jednou text v barvě žluté, a Paper nastavíme na tmavě červenou. Zde uvidíte, co vše se těmito barvami nahradí v bufferu.

;ATTR tisk
	ld	a,2	;ATTR režim
	ld	(HGFX.PMode),a

	ld	a,1	;Barva Index 1
	ld	(HGFX.SColor),a
	
	ld	a,5	;Barva PAPER index 5
	ld	(HGFX.SPColor),a

	ld	a,10
	ld	(HGFX.D_OffX),a	;X=10 px
	ld	a,12
	ld	(HGFX.D_OffY),a	;Y=12 px

	ld	hl,text
	call	Print

Výsledek je velmi podobný klasickému vytištění textu v Basicu. Pokud budeme chtít tento text přepsat, stačí akci zopakovat. Paper barva zajistí že původní písmena na přepisovaných pozicích se přepíší.

V následující části si vykreslíme stejný text ale v režimu INK. Vykreslíme jej 2x. Nejprve černou barvou, posunutý o 1 pixel doprava a dolů.

;INK tisk
	ld	a,0	;INK režim
	ld	(HGFX.PMode),a

;Tisk "stínu" nápisu
	ld	a,2	;Barva Index 1
	ld	(HGFX.SColor),a
	
	ld	a,11
	ld	(HGFX.D_OffX),a	;X=10 px
	ld	a,34
	ld	(HGFX.D_OffY),a	;Y=33 px

	ld	hl,text
	call	Print

a nyní ho vytiskneme ještě jednou ale bílou barvou, a bez posuvu o pixel.

;Tisk nápisu
	ld	a,3	;Barva Index 1
	ld	(HGFX.SColor),a
	
	ld	a,0	;INK režim
	ld	(HGFX.PMode),a

	ld	a,10
	ld	(HGFX.D_OffX),a	;X=10 px
	ld	a,33
	ld	(HGFX.D_OffY),a	;Y=33 px

	ld	hl,text
	call	Print

Všimněte si že bílý text kreslený jako druhý v pořadí překreslil jen ty pixely, kde se zapisovala logická 1. Ostatní pixely nechal s původní barvou. Takže nám vznikl krásný efekt stínu. V režimu ATTR by se tohle neobjevilo, protože barva SPColor by nám stín všude nahradila červenou barvou.

COPY

A ted se podíváme na režim COPY. Ten je trochu zvláštní. Není určený pro kreslení jako režimy INK a ATTR, ale ke kopírování obsahu v bufferu jinam. Je možné kopírovat i z jednoho bufferu do druhého, ale to v tomto příkladu nepoužijeme, protože vše se odehrává jen v jednom bufferu.

V našem případě zkopírujeme oba vykreslené texty na jinou pozici v bufferu. Konkrétně do pravé spodní čtvrtiny.

COPY potřebuje pro správnou funkci nastavit všechny Offsety. Jak cílové (HGFX.D_OffX/Y) tak zdrojové (HGFX.S_OffX/Y).

Nastavíme režim COPY a zdrojové offsety nastavíme na (X,Y) 0,0.

;Kopie pomocí COPY
	ld	a,0	;INK režim
	ld	(HGFX.PMode),a
	
	ld	a,0	;Zdrojové X,Y
	ld	(HGFX.S_OffX),a
	ld	(HGFX.S_OffY),a

a cílove na (X,Y) 128,96

	ld	a,128	;Cílové X,Y
	ld	(HGFX.D_OffX),a
	ld	a,96
	ld	(HGFX.D_OffY),a

Nyní překopírujeme blok bufferu o rozměru 128×96 px, z levé horní čtvrtiny do pravé spodní čtvrtiny bufferu. Data budeme kopírovat z adresy videoram, tedy 16384. Ukládat je budeme také na adresu 16384. To že zápis bude probíhat do jiné části bufferu zařizují námi nastavené cílové offsety (HGFX.D_OffX/Y). Zdrojová data jsou z pozice 0,0 (HGFX.S_OffX/Y), cílová 128,96 (HGFX.D_OffX/Y). V tomto režimu nezáleží na tom, co Z80 z paměti čte a co do paměti zapisuje. O kopírování 8 pixelů vedle sebe v bufferu se stará HGFX, zkopíruje všech 8 pixelů ze všech bitplánů (dle nastavené HGFX.PMask) najednou nezávisle na hodnotě přečtenou Z80. Nastavení SColor či SPColor není při přenosu důležité.

;Copy blok 128x96 px
	ld	hl,16384	;Adresa videoram
	ld	b,96	;96 linek ke kopírování

.Copy1	push	bc

	ld	d,h	;Zdroj i cíl jsou stejné adresy
	ld	e,l

	ld	bc,16
	ldir		;zkopíruj 16 bajtů (půl obrazovky v jedné lince)

	ld	bc,16	;a 16 bajtů přeskoč (pravá polovina obrazovky v lince)
	add	hl,bc

	pop	bc
	djnz	.Copy1

Nyní náš program zastavíme.

;Stop Processor
	di
	halt

Pro naší ukázku potřebujeme ještě pár věcí. Zde jsem připravil jednoduchou rutinu PRINT, která nám zmiňovaný text na obrazovku vytiskne.

;Jednoduchá PRINT rutina
Print	ld	a,(hl)
	inc	hl
	and	a
	ret	z
	
	push	hl

Char	sub	32	;Font neobsahuje znaky 0-31
	ret	c	;nižší tedy ani nebudeme tisknout

	ld	l,a	;hl=FontAdr + znak * 8
	ld	h,0
	add	hl,hl
	add	hl,hl
	add	hl,hl
	ld	de,FontAdr
	add	hl,de

	ld	b,8	;8 linek
	ld	de,16384	;do Videoram

.smy1	ld	a,(hl)	;copy
	inc	l
	ld	(de),a
	inc	d
	djnz	.smy1

	ld	a,(HGFX.D_OffX)	;Další znak bude o 8 px vpravvo
	add	a,8
	ld	(HGFX.D_OffX),a

	pop	hl

	jr	Print

text	defb	" Hello! ",0

následuje naše paleta barev,

;Paleta barev
paleta	defb	150,150,150	;Index 0 (B,G,R)
	defb	0,255,255	;Index 1
	defb	0,0,0	;Index 2
	defb	255,255,255	;Index 3
	defb	48,48,48	;Index 4
	defb	0,0,170	;Index 5

a ještě HGFX registry.

;HGFX registers
	hfill	0	;Musí začínat na xx00h, vyplníme 0.
!HGFX
.vid	equ	16384	;Videoram
.colors	equ	22528	;Color palette

.VParam	defb	0	;Video parameters
.PMode	defb	0	;Ink/Copy/Attr mode
.ACommand	defb	0	;Advanced commands

.SColor	defb	0	;Selected Color Index	
.PMask	defb	0	;Planar Mask
.D_OffX	defw	0	;Destination OffsetX (W)
.D_OffY	defw	0	;Destination OffsetY (W)
.S_OffX	defw	0	;Source OffsetX (W)
.S_OffY	defw	0	;Source OffsetY (W)
.AGF	defb	0	;Advanced Graphics Feature
.SPColor	defb	0	;Selected Paper Color
.FMask	defb	0	;Fill mode FillMask
	fill	.VParam+32,0	;Fill to 32 

Nyní náš příklad spustíme. Pokud vidíte na obrazovce toto…

…je vše vpořádku.

Na co se COPY režim hodí? Je to nejdůležitější režim pro jakýkoliv scrolling obrazu, časti obrazu, vrstev, libovolným směrem a o libovolný počet pixelů. Proto HGFX umí skvěle a bez velkého zatížení Z80 scrollovat obraz. Nemluvě o tom, že o Scroll se může postarat fDMA (FastDMA), nebo i klasické DMA. O tom ale až později v příkladu pro fDMA.

Každému zápisu do videoram by mělo předcházet čtení. Není možné jednou číst, a vícekrát obsah zapisovat. V takovém případě dojde jen k jednomu kopírování. Pokud před zápisem v tomto režimu nepředcházelo čtení, není co kopírovat a zápis se bude chovat jako režim ATTR. To umožní používat klasickou PRINT rutinu v ROM, a to dokonce včetně scrollingu obrazovky. V Assembleru by se ale tento režim měl využívat jen pro kopírování v bufferech, pro vykreslování by se neměl používat.

hgfx/ink_attr_copy.txt · Poslední úprava: 2025/04/25 14:53 autor: lanex

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki