Programowanie: Pełny 240-liniowy hires

From Atariki

(Różnice między wersjami)
Jump to: navigation, search
Wersja z dnia 12:15, 14 sie 2023
Mono (Dyskusja | wkład)
(D40B)
← Previous diff
Aktualna wersja
Krótki (Dyskusja | wkład)
(Skoro zmieniamy nazwy rejestrów z Zientary na oficjalne, to konsekwentnie zmieniam wszystkie przypadki.)
Linia 1: Linia 1:
-ANTIC potrafi wyrysować na ekranie 240 linii skanningowych począwszy od 8 linii ekranowej do 247 włącznie. Robi to na podstawie [[ANTIC Display List|Display List]]y.+{{grafr|Vbxe_lcd_asus_t1eh_broken.png}}
 +{{grafr|Vbxe_lcd_asus_t1eh_fixed.png}}
 +{{grafr|Svideo_lcd_asus_t1eh_broken.png}}
 +{{grafr|Svideo_lcd_asus_t1eh_fixed.png}}
 +{{grafr|Svideo_crt_commodore_1084s-p1_broken.png}}
 +{{grafr|Svideo_crt_commodore_1084s-p1_fixed.png}}
-O ile dla trybów kolorowych można wykorzystać pełne 240 linii, o tyle [[Tryby monochromatyczne ANTIC-a|tryby hires]] ([[Graphics 0|ANTIC 2]], [[ANTIC 3]] i [[Graphics 8|ANTIC F]]), ale również tryby GTIA ([[Graphics 9]], [[Graphics 10]] i [[Graphics 11]]) bazowane właśnie na trybie [[Graphics 15|ANTIC F]] w takim przypadku powodują zerwanie synchronizacji pionowej, przez co prawidłowa lista wyświetlania może składać się z 239 linii i skoku JVB skutkującego wyświetlaniem jednej pustej linii na samym dole ekranu.+ANTIC potrafi [[Ramka|wyrysować na ekranie]] 240 linii skanningowych począwszy od 8 linii ekranowej do 247 włącznie. Robi to na podstawie [[ANTIC Display List|Display List]]y.
 + 
 +O ile dla [[Tryby niskiej rozdzielczości|trybów niskiej rozdzielczości]] można wykorzystać pełne 240 linii, o tyle [[Tryby wysokiej rozdzielczości|tryby hires]] ([[Graphics 0|ANTIC 2]], [[ANTIC 3]] i [[Graphics 8|ANTIC F]]), ale również [[Tryby GTIA|tryby GTIA]] ([[Graphics 9]], [[Graphics 10]] i [[Graphics 11]]) bazowane właśnie na trybie [[Graphics 15|ANTIC F]] w takim przypadku powodują zerwanie synchronizacji pionowej, przez co prawidłowa lista wyświetlania może składać się z 239 linii i skoku JVB skutkującego wyświetlaniem jednej pustej linii na samym dole ekranu.
<pre> <pre>
dlist: dlist:
.byte $0F | $40 ;LMS .byte $0F | $40 ;LMS
- .word screen_part1+ .word screen.?part1
:99 .byte $0F :99 .byte $0F
.byte $0F | $40 ;LMS .byte $0F | $40 ;LMS
- .word screen_part2+ .word screen.?part2
:99 .byte $0F :99 .byte $0F
.byte $0F | $40 ;LMS .byte $0F | $40 ;LMS
- .word screen_part3+ .word screen.?part3
:38 .byte $0F :38 .byte $0F
Linia 21: Linia 28:
</pre> </pre>
-Sposób na poradzenie sobie z problemem opisał [[Rybags]] w wątku [https://forums.atariage.com/topic/165509-overcoming-the-scanline-240-bug Overcoming the Scanline 240 lines "bug"]: sztuczka polega na wyłączeniu DMA dla ekranu przed końcem linii 247 - ostatniej linii kreślonej przez ANTIC, po czym przywróceniu go na początku linii 8 - pierwszej linii rysowanej przez ANTIC.+Sposób na poradzenie sobie z problemem opisał [[Rybags]] w wątku [https://forums.atariage.com/topic/165509-overcoming-the-scanline-240-bug Overcoming the Scanline 240 lines "bug"]: sztuczka polega na wyłączeniu [[DMA|DMA dla ekranu]] przed końcem linii 247 - ostatniej kreślonej przez ANTIC, po czym przywróceniu go na początku linii 8 - pierwszej rysowanej przez ANTIC.
<pre> <pre>
Linia 29: Linia 36:
ldx #<dlist ldx #<dlist
ldy #>dlist ldy #>dlist
- sta DMACTLS ;$22F+ sta SDMCTL ;$22F
- stx DLPTRS ;$230+ stx SDLSTL ;$230
- sty DLPTRS+1+ sty SDLSTH ;$231
ldy #<vbint ldy #<vbint
ldx #>vbint ldx #>vbint
- lda #VBLKD ;7+ lda #7 ;set VVBLKD
- jsr JSETVBV ;$E45C+ jsr SETVBV ;$E45C
ldy #<dlint ldy #<dlint
Linia 43: Linia 50:
sty VDSLST ;$200 sty VDSLST ;$200
stx VDSLST+1 stx VDSLST+1
- sta NMIEN+ sta NMIEN ;$D40E
... ...
Linia 53: Linia 60:
lda #%00100010 lda #%00100010
sta DMACTL ;$D400 sta DMACTL ;$D400
- jmp JEXITVB ;$E462+ jmp XITVBV ;$E462
dlint: dlint:
Linia 73: Linia 80:
W powyższym przykładzie: W powyższym przykładzie:
-* do uzyskania 240 lini hires wykorzystano 30 wierszy trybu [[Graphics 0|ANTIC 2]] (30*8=240),+* do uzyskania 240 lini hires wykorzystano 30 wierszy trybu [[Graphics 0|ANTIC 2]] (30*8=240), ale równie dobrze można użyć też 240 linii [[Graphics 0|ANTIC F]], jak i 24 wierszy [[ANTIC 3]] (24*10=240),
* do wyłączenia DMA ekranu używane jest przerwanie DLI w ostatnim wierszu ekranu (zajmującego linie 240-247, a zgłaszającego DLI w linii 247), * do wyłączenia DMA ekranu używane jest przerwanie DLI w ostatnim wierszu ekranu (zajmującego linie 240-247, a zgłaszającego DLI w linii 247),
-* a do przywrócenia DMA ekranu przerwanie VBLK (a konkretnie opóźniona faza procedury obsługi przerwania [[SYSVBL|VBLK]]).+* a do przywrócenia DMA ekranu przerwanie [[VBL]] (a konkretnie opóźniona faza procedury obsługi przerwania [[SYSVBL|VBLK]]).
 + 
 +Warto zwrócić uwagę na to, że w SDMCTL (czyli cieniu [[Rejestry ANTIC-a#DMACTL|DMACTL]]) DMA dla ekranu jest wyłączone (bity 0 i 1 równe %00) a to z tego powodu, że przed wykonaniem opóźnionej fazy VBLK rejestry ANTIC-a (między innymi DMACTL i DLISTL/H) są ustawiane na podstawie rejestrów-cieni, zaś włączenie DMA ekranu przed linią 8 spowoduje zerwanie synchronizacji (VBLK zgłaszane jest przez ANTIC w 248 linii skanningowej).
-Warto zwrócić uwagę na to, że w DMACTLS (czyli cieniu [[Rejestry ANTIC-a#DMACTL|DMACTL]]) DMA dla ekranu jest wyłączone (bity 0 i 1 równe %00) a to z tego powodu, że przed wykonaniem opóźnionej fazy VBLK rejestry ANTIC-a (między innymi DMACTL i DLPTR) są ustawiane na podstawie rejestrów-cieni, zaś włączenie DMA ekranu przed linią 8 spowoduje zerwanie synchronizacji (VBLK zgłaszane jest przez ANTIC w 248 linii skanningowej).+Ostatni skok JVB w Display List jest zbędny ponieważ w międzyczasie na przerwaniu [[SYSVBL|VBLK]] zostaje ustawiona nowa wartość [[Rejestry ANTIC-a#DLPTR|DLISTL/H]] i ANTIC tego rozkazu już nie czyta.
-Ostatni skok JVB w Display List jest zbędny ponieważ w międzyczasie na przerwaniu [[SYSVBL|VBLK]] zostaje ustawiona nowa wartość DLPTR i ANTIC rozkazu JVB już nie czyta.+== Linki ==
 +* [[ANTIC Display List|Display List]]
 +* [[Ramka]]
 +* [[NTSC vs PAL]]
 +* [[DMA]]
 +* [[VBL|Przerwanie VBLK]]
 +* [[Tryby wysokiej rozdzielczości]]
 +* [[Tryby niskiej rozdzielczości]]
 +* [[Tryby GTIA]]
 +* [[Generator znaków]]
[[Kategoria:Niezbędnik kodera]] [[Kategoria:Niezbędnik kodera]]

Aktualna wersja

Grafika:Vbxe_lcd_asus_t1eh_broken.png

Grafika:Vbxe_lcd_asus_t1eh_fixed.png

Grafika:Svideo_lcd_asus_t1eh_broken.png

Grafika:Svideo_lcd_asus_t1eh_fixed.png

Grafika:Svideo_crt_commodore_1084s-p1_broken.png

Grafika:Svideo_crt_commodore_1084s-p1_fixed.png

ANTIC potrafi wyrysować na ekranie 240 linii skanningowych począwszy od 8 linii ekranowej do 247 włącznie. Robi to na podstawie Display Listy.

O ile dla trybów niskiej rozdzielczości można wykorzystać pełne 240 linii, o tyle tryby hires (ANTIC 2, ANTIC 3 i ANTIC F), ale również tryby GTIA (Graphics 9, Graphics 10 i Graphics 11) bazowane właśnie na trybie ANTIC F w takim przypadku powodują zerwanie synchronizacji pionowej, przez co prawidłowa lista wyświetlania może składać się z 239 linii i skoku JVB skutkującego wyświetlaniem jednej pustej linii na samym dole ekranu.

dlist:
    .byte $0F | $40  ;LMS
    .word screen.?part1
:99 .byte $0F

    .byte $0F | $40  ;LMS
    .word screen.?part2
:99 .byte $0F

    .byte $0F | $40  ;LMS
    .word screen.?part3
:38 .byte $0F

    .byte $41        ;JVB
    .word dlist

Sposób na poradzenie sobie z problemem opisał Rybags w wątku Overcoming the Scanline 240 lines "bug": sztuczka polega na wyłączeniu DMA dla ekranu przed końcem linii 247 - ostatniej kreślonej przez ANTIC, po czym przywróceniu go na początku linii 8 - pierwszej rysowanej przez ANTIC.

init:
    ...
    lda #%00100000
    ldx #<dlist
    ldy #>dlist
    sta SDMCTL    ;$22F
    stx SDLSTL    ;$230
    sty SDLSTH    ;$231

    ldy #<vbint
    ldx #>vbint
    lda #7        ;set VVBLKD
    jsr SETVBV    ;$E45C

    ldy #<dlint
    ldx #>dlint
    lda #%11000000
    sty VDSLST    ;$200
    stx VDSLST+1
    sta NMIEN     ;$D40E
    ...

vbint:
    lda #8/2
?w  cmp VCOUNT    ;$D40B
    bne ?w

    lda #%00100010
    sta DMACTL    ;$D400
    jmp XITVBV    ;$E462

dlint:
    pha
    lda #%00100000
    sta WSYNC     ;$D40A
    sta DMACTL    ;$D400
    pla
    rti
 
dlist:
    .byte $02 | $40  ;LMS
    .word screen
:28 .byte $02
    .byte $02 | $80  ;DLI
;    .byte $41        ;JVB
;    .word dlist

W powyższym przykładzie:

  • do uzyskania 240 lini hires wykorzystano 30 wierszy trybu ANTIC 2 (30*8=240), ale równie dobrze można użyć też 240 linii ANTIC F, jak i 24 wierszy ANTIC 3 (24*10=240),
  • do wyłączenia DMA ekranu używane jest przerwanie DLI w ostatnim wierszu ekranu (zajmującego linie 240-247, a zgłaszającego DLI w linii 247),
  • a do przywrócenia DMA ekranu przerwanie VBL (a konkretnie opóźniona faza procedury obsługi przerwania VBLK).

Warto zwrócić uwagę na to, że w SDMCTL (czyli cieniu DMACTL) DMA dla ekranu jest wyłączone (bity 0 i 1 równe %00) a to z tego powodu, że przed wykonaniem opóźnionej fazy VBLK rejestry ANTIC-a (między innymi DMACTL i DLISTL/H) są ustawiane na podstawie rejestrów-cieni, zaś włączenie DMA ekranu przed linią 8 spowoduje zerwanie synchronizacji (VBLK zgłaszane jest przez ANTIC w 248 linii skanningowej).

Ostatni skok JVB w Display List jest zbędny ponieważ w międzyczasie na przerwaniu VBLK zostaje ustawiona nowa wartość DLISTL/H i ANTIC tego rozkazu już nie czyta.

Linki

Personal tools