FWA

From Atariki

Jump to: navigation, search

Format obrazu zapisywanego przez program graficzny Fun with Art.

offsetdługośćopis
$0000$0002Identyfikator pliku $FE $FE.
$0002$0001Wartość rejestru koloru ramki COLBAKS ($02C8).
$0003$0001Wartość rejestru koloru COLPF0S ($02C4).
$0004$0001Wartość rejestru koloru COLPF1S ($02C5).
$0005$0001Wartość rejestru koloru COLPF2S ($02C6).
$0006$0100Dane programu Display List, kod przerwania VBL, a także kod wspierający obsługę DLI - ładowane na 6-tą stronę pamięci ($0600-$06FF).
$0106$1E10Dane obrazu ładowane w obszar $5000-$6E0F.
$1F16$0002Długość programu DLI (kolejno młodszy LSB i starszy MSB bajt).
$1F18...Kod programu DLI o maksymalnej długości 2300 bajtów.

Spis treści

Kolory

Wartości rejestrów cienii dla kolorów COLBAKS, COLPF0S, COLPF1S i COLPF2S definiują początkowe ustawienia rejestrów, które będą obowiązywać począwszy od góry ekranu. Każda późniejsza zmiana rejestrów kolorów odbywa się w przerwaniach DLI i jest realizowana przez specjalny program.

6 strona

Fragment danych znajdujący się na 6 stronie pamięci ($0600-$06FF) zawiera program Display List

0600 70        8 BLANK
0601 70        8 BLANK
0602 70        8 BLANK
0603 4E 00 50  LMS 5000 MODE E
0606 0E        MODE E -+
...                    +- 101 x MODE E
066A 0E        MODE E -+
066B 4E 00 60  LMS 6000 MODE E
066E 0E        MODE E ------------------+
066F 0E        MODE E                   +
0670 0E        MODE E                   +
0671 0E        MODE E                   +
0672 0E        MODE E                   +
0673 8E        DLI MODE E               +
0674 0E        MODE E                   +- 89 x MODE E
0675 0E        MODE E                   +
0676 0E        MODE E                   +
0677 0E        MODE E                   +
0678 8E        DLI MODE E               +
0679 0E        MODE E -+                +
...                    +- 78 x MODE E   +
06C6 0E        MODE E -+----------------+
06C7 41 00 06  JVB 0600

służący do wyświetlenia obrazu, który prócz informacji o liniach trybu (MODE) oraz początkowych adresach bloków danych (LMS) składających się na zawartość ekranu zawiera też znaczniki przerwań (DLI) używanych do redefinicji kolorów umieszczone w odpowiadających im rozkazach tworzenia linii trybu.

Dalej znaduje się kod programu instalującego kolejny handler przerwania DLI (sposób jego użycia zostanie omówiony dalej)

06CA: 68        PLA
06CB: AA        TAX
06CC: 68        PLA
06CD: 8D 01 02  STA $0201   ;VDSLST+1
06D0: E8        INX
06D1: D0 03     BNE $06D6
06D3: EE 01 02  INC $0201   ;VDSLST+1
06D6: 8E 00 02  STX $0200   ;VDSLST
06D9: 68        PLA
06DA: AA        TAX
06DB: 68        PLA
06DC: 40        RTI

Następnie umieszczony jest kod przerwania VBLKI instalujący pierwsze przerwanie DLI

06DD: A9 00     LDA #$00
06DF: 8D 00 02  STA $0200   ;VDSLST
06E2: A9 00     LDA #$00
06E4: 8D 01 02  STA $0201   ;VDSLST+1
06E7: A9 C0     LDA #$C0
06E9: 8D 0E D4  STA $D40E   ;NMIEN
06EC: 4C 5F E4  JMP $E45F   ;JSYSVBV

UWAGA! Należy zauważyć, że adres przerwania DLI (LSB w $06DE, MSB w $06E3) nie jest określony i wymaga uzupełnienia zanim zainstalowane zostanie przerwanie VBLKI.

Reszta strony, czyli 17 bajtów w obszarze $06EF-$06FF dopełniona jest zerami.

Obraz

Dane obrazu zorganizowane są w dwa bloki (zgodnie z tym co widać w programie Display List ANTIC-a):

  • 102 linie po 40 bajtów w obszarze $5000-$5FEF
  • 90 linii po 40 bajtów w obszarze $6000-$6E0F

Między nimi znajduje się obszar $5FF0-$5FFF zawierający 16 nieużywanych bajtów o wartości $00.

DLI

Blok procedur przerwań DLI znajduje się na samym końcu pliku poprzedzony jedynie dwoma bajtami rozmiaru (w tym przypadku $21 $00).

Jest on w pełni relokowalny i może być umieszczony w dowolnym miejscu pamięci (tu załadowany jest pod adres $3000):

3000: 48        PHA
3001: 8A        TXA
3002: 48        PHA
3003: A9 E0     LDA #$E0
3005: 8D 0A D4  STA $D40A   ;WSYNC
3008: 8D 1A D0  STA $D01A   ;COLBAK
300B: 20 CA 06  JSR $06CA

300E: 48        PHA
300F: 8A        TXA
3010: 48        PHA
3011: A9 18     LDA #$18
3013: 8D 0A D4  STA $D40A   ;WSYNC
3016: 8D 17 D0  STA $D017   ;COLPF1
3019: A9 E6     LDA #$E6
301B: 8D 1A D0  STA $D01A   ;COLBAK
301E: 20 CA 06  JSR $06CA

Jak widać mamy tu dwie procedury przerwania zakończone bardzo oryginalnym (bo realizowanym przez JSR) wywołaniem procedury znajdującej się pod adresem $06CA.

Analiza programu Display List ANTIC-a pokazuje że faktycznie mamy DWA znaczniki żądania obsługi przerwania DLI w bajtach $0673 i $0678 odpowiadających 109 i 114 linii obrazu.

Pierwsza procedura zachowuje rejestry A i X na stosie, zmienia wartość rejestru tła COLBAK po czym skacze do procedury ustawiającej kolejny adres przerwania DLI. Druga również skacze pod $06CA uprzednio ustawiając COLPF1 i COLBAK.

Skok JSR odbywa się z tzw. "śladem", czyli na stosie zapisywany jest adres kolejnej instrukcji znajdującej się za JSR-em zmniejszony o 1. W następnej instrukcji jak widać znajduje się kolejna procedura DLI, tak więc jej adres jest po prostu odłożony na stosie, a zdejmuje go właśnie procedura pod adresem $06CA, zwiększa o 1 i zapisuje w wektorze obsługi przerwania DLI VDSLST ($0200). Taka sztuczka pozwala na skrócenie każdej z procedur DLI, bo zamiast każdorazowego

nextDLI = $yyxx

A9 xx     LDA #<nextDLI
8D 00 02  STA VDSLST
A9 yy     LDA #>nextDLI
8D 01 02  STA VDSLST+1
68        PLA
AA        TAX
68        PLA
40        RTI

mamy tylko 3-bajtowy JSR.

UWAGA! Ostatnie przerwanie DLI również kończy się skokiem ustawiającym nowe DLI, a przecież dalej mogą znajdować się przysłowiowe maliny. Jakkolwiek trzecie przerwanie DLI nie powinno zostać nigdy wywołane, to dla bezpieczeństwa można za blokiem procedur DLI umieścić rozkaz RTI (opkod $40) nie pozwalający w razie czego na utratę kontroli nad maszyną.

Instalacja

Aby poprawnie wyświetlić obraz należy bloki pliku załadować pod adresy docelowe (czyli na 6-tą stronę, a dane obrazu pod $5000), zaś blok procedur DLI w dowolnie wybrane wolne miejsce pamięci RAM (przykładowo pod adres $3000). Następnie uzupełnić adres pierwszej procedury DLI (będącej adresem bloku procedur DLI) w komórkach $06DE i $06E3

  ldx #<$3000
  ldy #>$3000
  stx $06DE
  sty $06E3

zainicjalizować kolory wartościami załadowanymi z początku pliku

  ldx #$xx
  ldy #$yy
  stx $02C8   ;COLBAKS
  sty $02C4   ;COLPF0S
  ldx #$xx
  ldy #$yy
  stx $02C5   ;COLPF1S
  sty $02C6   ;COLPF2S

zainstalować program Display List i ustawić szerokość ekranu

  lda #%00100010
  ldx #<$0600
  ldy #>$0600
  sta $022F   ;DMACTLS
  stx $0230   ;DLPTRS
  sty $0231   ;DLPTRS+1

i zainstalować przerwanie VBLKI

  ldy #<$06DD
  ldx #>$06DD
  lda #$06
  jsr $E45C   ;JSETVBV

Przykład

Przykładowy program napisany w Turbo BASIC XL umożliwiający wyświetlenie obrazka w formacie Fun with Art.

10 DIM N$(32)
11 PICADR=((PEEK($02E6) DIV 16)-2)*16:DLIADR=PICADR-9
12 DO:GRAPHICS 0:TRAP 40
13 ?: ? "--- Fun with Art Viewer v.1.01 ---"
14 ? "- done by: Seban/Code3, (p) 1992 -"
15 ?: ? "Input filename: ";:INPUT N$:OPEN #1,4,0,N$
16 REM - GET & CHECK HEADER DATA -
17 GET #1,A:GET #1,B
18 IF (A<>B) OR (A<>$FE)
19 ?:? N$;": is not an FwA file!":END 
20 ENDIF:POKE $22F,0:PAUSE 0 
21 REM - GET COLORS
22 BGET #1,$02C8,1:BGET #1,$02C4,3
23 REM - GET DISPLAY LIST
24 BGET #1,$0600,256
25 REM - GET IMAGE DATA
26 BGET #1,PICADR*256,$1E10
27 REM - GET DLI CODE LENGTH
28 GET #1,DLO:GET #1,DLH
29 REM - GET DLI CODE
30 BGET #1,DLIADR*256,256*DLH+DLO
31 CLOSE #1
32 REM - SETUP DL, DLI
33 POKE $0605,PICADR:POKE $066D,PICADR+16
34 POKE $06DE,0:POKE $06E3,DLIADR:DPOKE $0230,$0600
35 POKE $06E8,$C0:POKE $D40E,$00:DPOKE $0222,$06DD:DPOKE $D40E,$C0
36 POKE $022F,$22:GET X:POKE $022F,0:PAUSE 0
37 POKE $06E8,$40:POKE $D40E,$00:DPOKE $0222,$E45F:POKE $D40E,$40
38 LOOP
40 ?:? "Error #";ERR;" at line ";ERL
41 ?:? "Press any key to restart."
42 CLOSE #1:GET K:LOOP

Linki

Personal tools