Programowanie: Plot w Graphics 0

From Atariki

Jump to: navigation, search

Procedury poniżej opisują, jak w trybie Graphics 0 zrobić plota o precyzji podpixelowej - o rozdzielczości 80x48 używając standardowego zestawu znaków. W całym artykule operuję na kodach wewnętrznych Antica.

Odrobina teorii

Tryb ten nie był pomyślany do wyświetlania rastrowej grafiki, co wiąże się z kilkoma problemami. Głównym jest nieliniowość pamięci - podobnie jak w trybach bitowych jeden bajt określa stan kilku pixli (tutaj: czterech), jednakże w przeciwieństwie do nich tutaj jeden bajt określa stan pixli sąsiadujących ze sobą w poziomie jak i w pionie (a nie tylko w poziomie jak to zwykle bywa). Zakładając, ze lewy, górny pixel ma pozycje 0.0 a prawy dolny - 79.47 to pierwszy bajt pamięci określa pixle: 0.0, 1.0, 0.1, 1.1, drugi bajt: 2.0, 3.0, 2.1 i 3.1 itd... Kolejny problem to nieliniowość samego zestawu znaków. Bajt wyszyszczony to $00 (spacja). Chcąc zapalić pixel 0.0 - wpisujemy wartość $4c (kod znaku z jedną ćwiartką) do pierwszej komórki pamięci obrazu. Jeśli następnie zapalimy pixel 1.0 - pod ten sam adres trzeba wpisać wartość $d5 (górna połowa znaku jest zapalona), itd..

W ten sposób mamy już koncepcję, jak podbić rozdzielczość. Jest jeszcze jeden drobny problem: jaki znak wyświetlić dla dwóch układów pixli: 0.0 i 1.1 oraz 0.1 i 1.0. Atari nie ma znaku szachownicy. Ja (ze względu na podobieństwo wyglądu) wybrałem znaki o kodach: $47 oraz $46 (grube wersje znaków \ oraz /).

Praktyka, czyli mięso

Plot używa czterech tablic, każda o rozmiarze 256 bajtów. Dokładniej rzecz biorąc, nie całe 256 bajtów jest zajęte, tylko wybrane 16 bajtów. Pomiędzy nimi są dziury - można je użyć do własnych celów. Są jeszcze dwie mniejsze tablice, każda o długości 48 bajtów (lub innej, jeśli operujemy na niestandardowym ekranie) - młodsze oraz starsze bajty adresów linii ekranu. Każdy wiersz w tablicy jest podwojony.

Stałe używane przez procedury:

addr - wektor (2 kolejne bajty) na stronie 0
screen - adres ekranu
screen_lo - tablica na młodsze bajty adresów dla kolejnych linii ekrany,
screen_hi - jak wyżej, ale dla starszych bajtów,
plot00 do plot11 - tablice do zapalania kolejnych ćwiartek.

Do wygenerowania wspomnianych tablic można użyć poniższej procedury:

plot0_init equ *
		lda <screen             ; wartości początkowe
		sta addr
		lda >screen
		sta addr+1
		ldx #$00
init_1 equ *
		lda addr                ; dwukrotnie zapisz adres wiersza do tablic screen_lo i screen_hi
		sta screen_lo,x
		lda addr+1
		sta screen_hi,x
		inx
		lda addr
		sta screen_lo,x
		lda addr+1
		sta screen_hi,x
		clc                     ; przesun sie na nastepny wiersz pamieci ekranu
		lda addr
		adc #$28                ; szerokość ekranu w bajtach
		sta addr
		lda addr+1
		adc #$00
		sta addr+1
		inx
		cpx #$30                ; wysokość ekranu w bajtach*2
		bne init_1

; 00 10 - układ pixli w bajcie
; 01 11
; plot00
		lda #$4c                ; ustaw poprawne wartości dla zapalania poszczególnych ćwiartek
		sta plot00+$00
		sta plot00+$4c
		lda #$d5
		sta plot00+$4b
		sta plot00+$d5
		lda #$47
		sta plot00+$49
		sta plot00+$47
		lda #$59
		sta plot00+$4f
		sta plot00+$59
		lda #$80
		sta plot00+$cc
		sta plot00+$80
		lda #$cb
		sta plot00+$55
		sta plot00+$cb
		lda #$cf
		sta plot00+$d9
		sta plot00+$cf
		lda #$c9
		sta plot00+$46
		sta plot00+$c9
; plot10
		lda #$4b
		sta plot10+$00
		sta plot10+$4b
		lda #$d5
		sta plot10+$4c
		sta plot10+$d5
		lda #$d9
		sta plot10+$49
		sta plot10+$d9
		lda #$46
		sta plot10+$4f
		sta plot10+$46
		lda #$cc
		sta plot10+$55
		sta plot10+$cc
		lda #$c9
		sta plot10+$59
		sta plot10+$c9
		lda #$80
		sta plot10+$cb
		sta plot10+$80
		lda #$cf
		sta plot10+$47
		sta plot10+$cf
; plot01
		lda #$4f
		sta plot01+$00
		sta plot01+$4f
		lda #$59
		sta plot01+$4c
		sta plot01+$59
		lda #$46
		sta plot01+$4b
		sta plot01+$46
		lda #$55
		sta plot01+$49
		sta plot01+$55
		lda #$c9
		sta plot01+$d5
		sta plot01+$c9
		lda #$cc
		sta plot01+$d9
		sta plot01+$cc
		lda #$cb
		sta plot01+$47
		sta plot01+$cb
		lda #$80
		sta plot01+$cf
		sta plot01+$80
; plot11
		lda #$49
		sta plot11+$00
		sta plot11+$49
		lda #$47
		sta plot11+$4c
		sta plot11+$47
		lda #$d9
		sta plot11+$4b
		sta plot11+$d9
		lda #$55
		sta plot11+$4f
		sta plot11+$55
		lda #$cf
		sta plot11+$d5
		sta plot11+$cf
		lda #$cb
		sta plot11+$59
		sta plot11+$cb
		lda #$cc
		sta plot11+$46
		sta plot11+$cc
		lda #$80
		sta plot11+$c9
		sta plot11+$80
		rts

Teraz możemy użyć plota właściwego:

; parametry:
;  rejestry x, y - własciwa pozycja pixla do zapalenia
plot0 equ *
		lda screen_lo,y         ; zapisz adres wiersza pamieci ekranu w addr
		sta addr
		lda screen_hi,y
		sta addr+1
		tya                     ; określ, o którą ćwiartkę chodzi (tutaj badamy współrzędną Y)
		lsr @
		bcs plot0_0
		txa                     ; jak wyżej, ale badamy współrzędna X
		lsr @
		tay
		bcc plot0_1
		lda (addr),y            ; używając wcześniej przygotowanych tablic zapisz odpowiednią wartość do pamięci ekranu.
		tax
		lda plot10,x
		sta (addr),y
		rts
plot0_1 equ *
		lda (addr),y
		tax
		lda plot00,x
		sta (addr),y
		rts
plot0_0 equ *
		txa
		lsr @
		tay
		bcc plot0_2
		lda (addr),y
		tax
		lda plot11,x
		sta (addr),y
		rts
plot0_2 equ *
		lda (addr),y
		tax
		lda plot01,x
		sta (addr),y
		rts

Jak to działa w praktyce, można zobaczyć w demach: Unplugged oraz Unfused.

Personal tools