FWA
From Atariki
Wersja z dnia 07:41, 4 sie 2022 Mono (Dyskusja | wkład) (→DLI) ← Previous diff |
Wersja z dnia 07:42, 4 sie 2022 Mono (Dyskusja | wkład) (→DLI) Next diff → |
||
Linia 88: | Linia 88: | ||
== DLI == | == DLI == | ||
- | Procedury przerwań DLI znajdują się na samym końcu pliku poprzedzone jedynie dwoma bajtami rozmiaru bloku. | + | Procedury przerwań DLI znajdują się na samym końcu pliku poprzedzone jedynie dwoma bajtami rozmiaru bloku (w tym przypadku $21 $00). |
Przykładowy blok procedur obsługi DLI (przykładowo załadowany pod adres $3000) wygląda tak: | Przykładowy blok procedur obsługi DLI (przykładowo załadowany pod adres $3000) wygląda tak: |
Wersja z dnia 07:42, 4 sie 2022
Format obrazu zapisywanego przez program graficzny Fun with Art.
offset | długość | opis |
$0000 | $0002 | Identyfikator pliku $FE $FE. |
$0002 | $0001 | Wartość rejestru koloru ramki COLBAKS ($02C8). |
$0003 | $0001 | Wartość rejestru koloru COLPF0S ($02C4). |
$0004 | $0001 | Wartość rejestru koloru COLPF1S ($02C5). |
$0005 | $0001 | Wartość rejestru koloru COLPF2S ($02C6). |
$0006 | $0100 | Dane 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 | $1E10 | Dane obrazu ładowane w obszar $5000-$6E0F. |
$1F16 | $0002 | Dł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
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
Procedury przerwań DLI znajdują się na samym końcu pliku poprzedzone jedynie dwoma bajtami rozmiaru bloku (w tym przypadku $21 $00).
Przykładowy blok procedur obsługi DLI (przykładowo załadowany pod adres $3000) wygląda tak:
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 by 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 przez nas 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
- Format bloku zapisywanego przez program Fun with Art