speccy.pl
Facebook Like


SPECCY.PL

[SPECCY.PL PARTY 2023.1]

[WIKI SPECCY.PL]
Polecamy

KOMITET SPOŁECZNY KRONIKA POLSKIEJ DEMOSCENY
PIXEL HEAVEN 2023
AYGOR
Forum ZX Spectrum
Zawartość panelu chwilowo niedostępna
Archiwum plików ZX Spectrum
Nawigacja
Tryby graficzne Timexa część 1.

Tryby graficzne Timexa część 1.

Możliwości ma Spectruma...

Historia komputerów amerykańskiej firmy joint-venture Timex Sinclair rozpoczyna się w roku 1982, kiedy do produkcji trafia Timex Sinclair 1000 - klon ZX81 wyprodukowany w porozumieniu z Sinclair Research. Na kolejne owoce współpracy między amerykańską firmą a Sinclair nie trzeba było długo czekać i tak na rynku pojawiają się wyprodukowany pod koniec roku 1983 - Timex Sinclair 2068, a następnie produkowane już w Europie od 1984 roku - Timex Computer 2068 i Timex Computer 2048. Komputer ten jest w 99% kompatybilny z oryginalnym ZX Spectrum, a do tego oferuje coś ekstra – dodatkowe tryby graficzne. Zastosowany układ PAL2068 (odpowiednik ULA z ZX Spectrum) potrafi wyświetlić dwukolorową grafikę w rozdzielczości 512x192 pixeli, 15 (a niektórzy twierdzą że i 16) kolorową grafikę w rozdzielczości 256x192 z większą gęstością kolorów , tj. kafelki 8x1 zamiast 8x8. Dodatkowo udostępnia programiście drugi obszar pamięci video, który znamy z ZX Spectrum 128 (wyprodukowany dopiero w 1986r). W ninejszym artykule przybliżę sposób organizowania i funkcjonowania dwóch z trzech dodatkowych trybów graficznych. Ze względu na pewien stopień zawiłości omawianej tematyki, początkujący użytkownicy mogą mieć nieco trudności ze zrozumieniem niektórych kwestii, dlatego byłoby dobrze, żeby przed przeczytaniem posiadali już pewną wiedzę na temat organizacji pamięci graficznej w ZX Spectrum.

Emulatory Timexa i edytor grafiki.

Do testów dodatkowych trybów graficznych najlepiej używać prawdziwego sprzętu. Jeżeli nie mamy takiej możliwości, musimy do tego celu użyć emulatorów. Istnieje kilka emulatorów ZX Spectrum, które emulują również Timexa. Są to między innymi Fuse (http://fuse-emulator.sourceforge.net/) moim zdaniem najlepszy, SpecEmu (http://www.zophar.net/sinclair/specemu.html), Eighty One (https://www.aptanet.org/eightyone/). W każdym z nich należy wybrać Timexa spośród emulowanych modeli komputerów. Jeżeli dodatkowo interesuje nas tworzenie grafiki, to warto zainteresować się ZX Paintbrush (http://www.zx-modules.de/zxpaintbrush/zxpaintbrush.html) - programem graficznym dla systemu Windows oferującym tworzenie, konwersję grafiki w standardowym trybie ZX Spectrum, jak również obsługę dodatkowego trybu graficznego, zwanego multikolorem.

Port 255 ($FF).

Do ustawiania trybów graficznych służy port 255. Wykorzystywane są w nim wszystkie bity, lecz nas interesować będzie jedynie sześć pierwszych. Oto ich rozpiska

Każdy z bitów zaczynając od najmłodszego zostanie omówiony przy opisywaniu poszczególnych trybów graficznych.

Zaczynamy!

Dodatkowy obszar pamięci VIDEO.

Bit zerowy ustawia obszar pamięci, z której ma być wyświetlany obraz. Jeżeli bit ma wartość 0 to obraz jest wyświetlany z adresu 16384 ($4000), jeżeli ma wartość 1 to z obszaru pamięci rozpoczynającego się od adresu 24576 ($6000). Istotną informacją ułatwiającą oprogramowanie drugiej pamięci ekranu oraz pozostałych trybów graficznych jest fakt, że rozpoczyna się dokładnie 8192 ($2000) bajty po pierwszej. Organizacja pamięci jest w obu przypadkach identyczna. Pierwsze 6144 bajty to dane o pixelach, kolejne 768 bajtów to informacja o mapie kolorów (atrybutach).

Aby włączyć wyświetlanie z dodatkowego obszaru VRAM, należy wydać polecenie (tu w BASIC):

  OUT 255,1

Powrót do podstawowej pamięci następuje po:

  OUT 255,0

Aby przekonać się, że sposób działania drugiego ekranu jest identyczny, jak z pierwszym, należy napisać prosty program w BASIC (przykładowy listing zamieszczam poniżej).

  10 CLEAR 24575: BORDER 0
  20 OUT 255,1
  30 LET src=0: LET add=8192
  40 FOR d=23295+add TO 16384+add STEP -1
  50 POKE d,PEEK src
  60 LET src=src+1
  70 NEXT d
  80 PAUSE 0: OUT 255,0

Co on robi? Kopiuje zawartość ROM do pamięci drugiego obszaru VIDEO. Robi to od końca pamięci ekranu, czyli najpierw zapełnia obszar atrybutów, a następnie stawia pixele. Zaczynamy od atrybutów, aby szybciej uwidocznić działanie programu, gdyż po starcie komputera w pamięci kolorów zapisana jest wartość 0 - co przekłada się na czarny kolor pixeli i tła. Po skończeniu działania, czeka na naciśnięcie dowolnego klawisza, a następnie wraca do podstawowej pamięci VRAM.

Jeżeli zmodyfikujemy linię 30 poprzez zmianę wartości zmiennej 'add' na 0 oraz komentując (dodając instrukcję REM na początku linii) lub usuwając linię 20, możemy obejrzeć ten sam efekt dla podstawowej pamięci ekranu w ZX Spectrum.

Bardziej praktyczne zastosowanie dodatkowego VRAM prezentuje kolejny program. Ładuje on jeden obrazek do podstawowego obszaru pamięci video (adres 16384), a następnie do dodatkowego (adres 24576). Po załadowaniu danych, następuje w nieskończonej pętli przełączanie wyświetlania obrazu z podstawowego i dodatkowego obszaru VIDEO RAM, czego widocznym efektem są widoczne fragmenty dwóch różnych obrazków.

   5 CLEAR 24575: BORDER 0
  10 LOAD ""CODE 24576
  20 LOAD ""CODE 16384
  30 OUT 255,0: OUT 255,1: GO TO 30

To tylko przykład, który ma zainspirować do eksperymentów. Można to samo próbować robić w BASIC-u, lecz aby wyszło z tego coś efektownego, powinno się napisać program w assemblerze Z80. Dodatkowo należy mieć odpowiednio przygotowane obrazki lub też generować je w czasie rzeczywistym, a w w odpowiednim momencie modyfikować bit 0 na porcie 255.

Kolory w obszarze 8x1

Ten tryb często określa się jako multicolor. Jego główną cechą jest to, że definiuje kolory w obszarze 8x1 pixeli zamiast standardowo 8x8. Pełnie jego możliwości pokazuje demo Timmy wydane przez grupę Speccy.pl w 2014 roku z okazji 30-lecia wypuszczenia na rynek modelu Timex 2048. Poniżej przedstawiono kilka screenshotów z dema.

Bardziej szczegółowa mapa kolorów niesie za sobą jednak określone konsekwencje. Standardowo w ZX Spectrum atrybuty (kolory) zajmują 768 bajty (32 bajty w 24 liniach), lecz dla trybu 8x1 to aż 6144 bajty (32x192), czyli tyle samo co obszar pamięci dedykowany pixelom. Jak łatwo się domyślić, dane kolorów znajdują się pod adresem 24576, a ich organizacja jest identyczna z organizacją pixeli, a nie jak atrybutów. Dla programisty oznacza to tylko tyle, że adres dla kolorów oblicza dodając 8192 do adresu pixeli. Należy sobie uświadomić fakt, że teraz do obsłużenia będziemy mieć nie 6144 (6912 z kolorami) bajtów pamięci, lecz aż 12288. Tworzenie zaawansowanych efektów wymaga zmodyfikowania co najmniej dwukrotnie większej ilości pamięci RAM, niż to miało miejsce w standardowym trybie graficznym. Dla lepszego zobrazowania problemu podpowiem, że procesor Z80 taktowany zegarem 3.5MHz (takim jak w ZX), który jest w stanie w ciągu 1/50 sekundy zmodyfikować od 2 do 4kB danych w zależności od użytej metody przenoszenia danych do VRAM. Mało? Nie jest jednak tak źle, co dobitnie pokazuje wspomniane wcześniej demo.

Różnice w grafice prezentuje zrzut ekranu z programu ZX Paintbrush, gdzie w powiększeniu widać różnicę między 2 kolorami w obszarze 8x8 pixeli (na dole), oraz w 8x1 (na górze).

Do włączenia trybu 8x1 służy bit 1 na porcie 255. Bit ten przełącza pobieranie danych o kolorach, a zarazem włącza dodatkowy tryb. Jeżeli jego wartość jest = 0 to kolory pobierane są z adresu 22528 i są wyświetlane jako 8x8, zaś kiedy wartość bitu równa się 1 to dane czerpane będą z adresu 24576 i wyświetlane jako 8x1.

Włączenie trybu odbywa się poprzez:

  OUT 255,2

Poniżej znajduje się krótki program demonstrujący sposób organizacji pamięci kolorów, a przy okazji generujący kolorowe paski, świetnie widoczne na tle listingu. Ustawiany jest kolor tła (PAPER), zaś kolor pixeli (INK) pozostaje czarny.

  10 CLEAR 24575: BORDER 0: OUT 255,2
  20 LET c=8
  25 LET d=24576
  30 FOR t=0 TO 2
  40 FOR y=0 TO 7
  50 FOR z=0 TO 255: POKE d,c: LET d=d+1: NEXT z
  60 LET c=c+8
  70 IF c > 63 THEN LET c=0
  80 NEXT y
  90 NEXT t

Możemy zmodyfikować program tak, aby działał odwrotnie niż poprzedni, czyli kolor pixeli był zmienny, zaś kolor tła stały. Aby uzyskać taki efekt, należy zmodyfikować następujące linie:

  20 LET c=1
  60 LET c=c+1
  70 IF c > 7 THEN LET c=0

W wyniku uruchomienia programu otrzymamy następujący efekt.

Program może być zmodyfikowany również w ten sposób, że kolory pixeli i tła będą zmienne. To jednak pozostawię jako ćwiczenie dla żądnych eksperymentów Czytelników.

A co się stanie, jeżeli włączymy również drugą stronę VRAM? Wtedy pixele oraz kolory będą pobierane z dodatkowego obszaru pamięci i na ekranie nie zobaczymy nic sensownego. Jeżeli chcemy się o tym przekonać wystarczy po wykonaniu któregoś z wyżej przedstawionych programów wydać polecenie:

OUT 255,3

ZX Paintbrush i format .mtl

Program ten pozwala na tworzenie i zapisywanie obrazków w trybie Timex Multicolor 8x1. Format ten jest dość prosty, a sposób obsługi w assemblerze przedstawię poniżej. Aby zapisać plik w formacie .mtl, należy najpierw utworzyć obrazek w tym trybie. Można to zrobić na dwa sposoby.

Pierwszy polega na utworzeniu nowego obrazka i wybranie 'Timex Screen Files (*.mtl)', drugi polega na konwersji plików jpg/png/gif do trybu Timex. Niezależnie od tego, którą opcję wybierzemy, po tym należy przy zapisie wybrać 'Timex Screen files (*.mtl)'.

Sam plik .mtl ma długość 12288 bajtów. Jego struktura jest następująca:

  • pierwsze 6144 bajty do dane o pixelach.
  • kolejne 6144 bajty to informacja o kolorach.

Z pixelami nie powinno być problemu - ich organizacja jest identyczna jak organizacja pamięci video, zatem wystarczy je skopiować bez zmian do pamięci obrazu. Atrybuty niestety już nie są ułożone zgodnie z organizacją pamięci. Są ułożone liniowo, zatem tak samo jak standardowa pamięć kolorów. Należy zatem przerzucać dane w odpowiedniej kolejności obliczając dla każdych 32 bajtów nowy docelowy adres pamięci. Nie jest to trudne, co demonstruje program w assemblerze mojego autorstwa.

; Timex Multicolor 256x192 8x1
; Tygrys / speccy.pl
;
	org 32768
    xor a
    out (254),a

    ; ustawianie trybu multicolor
    ld a,2
    out (255),a

; pierwsze 6144 bajty to pixele, zgodne z organizacja pamieci ZX Spectrum
    ld hl,obrazek
    ld de,16384
    ld bc,6144
    ldir

; Kolory zapisywane są liniowo, a w pamieci musza byc zorganizowane w taki
; sam sposob jak pixele, zatem przeliczamy adres VRAM.
    ld de,16384 + 8192
    ex af,af'
    ld a,192
loop:
    ex af,af'

    ld bc,32

    push de
    ldir
    pop de
	
    inc d
    ld a,d
    and 7
    jp nz,$+14
    ld a,e
    add a,32
    ld e,a
    jp c,$+7
    ld a,d
    sub 8
    ld d,a 	

    ex af,af'
    dec a
    jp nz,loop
    ret

obrazek:
    incbin "obrazek.mlt"	
end 32768

Program oczekuje danych o obrazku pod nazwą 'obrazek.mtl'. Kompilacja i wygenerowanie pliku .tap z loaderem basicowym:

  pasmo --tapbas decodeMTL.asm program.tap

W następnej części artykułu, zajmiemy się trybem Hi-Res.

Artykuł ukazał się w #1 numerze pisma RetroKomp

sect0r
sect0r dnia 19.11.2016 00:58:01

Dzięki!

Dodaj komentarz
Zaloguj się, aby móc dodać komentarz.
Oceny
Tylko zarejestrowani użytkownicy mogą oceniać zawartość strony
Zaloguj się , żeby móc zagłosować.

Brak ocen. Może czas dodać swoją?