Obsah
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.