@Krótki: Robię tak:
Ustawiam breakpointa w 1416:
1416: A9 C0 LDA #$C0
1418: 8D 0E D4 STA NMIEN
141B: 20 7D 15 JSR $157D
141E: A9 04 LDA #$04
1420: 85 D3 STA $D3
1422: A9 22 LDA #$22
1424: 8D 2F 02 STA SDMCTL
1427: A9 96 LDA #$96
1429: 85 D5 STA $D5
142B: 20 7D 15 JSR $157D
Przed wykonaniem tego jesteśmy zawsze w linii 287 (już po wykonaniu VBLK) i mamy:
Altirra> .antic
DMACTL = 00 : none 2-line
CHACTL = 02 : invert
DLIST = 401b
HSCROL = 00
VSCROL = 00
PMBASE = 00
CHBASE = e0
NMIEN = 40 : vbi
NMIST = 1f :
PENH/V = 00 ff
w SDMCTL i DLPTRS mamy:
a w 401b czyli w miejscu gdzie była dlista dla winietki podczas ładowania (Loading: Rockman, (c) Mirage itd.) mamy:
401B: 00 E8 00 DB 00 CF 00 C3 00 B8 00 AC 00 A2 00 9A
402B: 00 90 00 88 00 7F 00 78 00 70 00 6A 00 64 00 5E
403B: 00 57 00 52 00 32 00 0A 00 80 A0 20 40 00 01 35
W 1157 czyli tam gdzie ma być nowa dlista dla ekranu Rockmana wg cieni (ale w DLPTR jeszcze jej nie ma) jest:
1157: 70 70 80 10 42 EC 34 02 82 02 02 44 E6 35 04 04
1167: 04 04 04 04 04 04 04 80 50 11 82 11 80 42 A5 1F
1177: 60 52 51 21 10 52 51 21 41 57 11
Więc teraz krok po kroku wykonuję kod:
(30210:287,106) A=18 X=09 Y=18 S=F5 P=31 ( C) 1416: A9 C0 LDA #$C0
(30210:287,108) A=C0 X=09 Y=18 S=F5 P=B1 (N C) 1418: 8D 0E D4 STA NMIEN [$D40E]
(30210:287,112) A=C0 X=09 Y=18 S=F5 P=B1 (N C) 141B: 20 7D 15 JSR $157D [$157D] = $A5
(30210:288, 4) A=C0 X=09 Y=18 S=F3 P=B1 (N C) 157D: A5 14 L157D LDA RTCLOK+2 [$14] = $D7
(30210:288, 7) A=D7 X=09 Y=18 S=F3 P=B1 (N C) 157F: C5 14 L157F CMP RTCLOK+2 [$14] = $D7
(30210:288, 10) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 1581: F0 FC BEQ $157F
(30210:288, 13) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 157F: C5 14 L157F CMP RTCLOK+2 [$14] = $D7
(30210:288, 16) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 1581: F0 FC BEQ $157F
...
aż do rozpoczęcia nowego ekranu:
(30211: 8, 1) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 157F: C5 14 L157F CMP RTCLOK+2 [$14] = $D7
Altirra> .antic
DMACTL = 00 : none 2-line
CHACTL = 02 : invert
DLIST = 401b
HSCROL = 00
VSCROL = 00
PMBASE = 00
CHBASE = e0
NMIEN = c0 : dli vbi
NMIST = 1f :
PENH/V = 00 ff
i lecimy dalej... aż do:
(30211: 22,109) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 1581: F0 FC BEQ $157F
(30211: 22,112) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 157F: C5 14 L157F CMP RTCLOK+2 [$14] = $D7
(30211: 23, 1) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 1581: F0 FC BEQ $157F
(30211: 23, 4) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 157F: C5 14 L157F CMP RTCLOK+2 [$14] = $D7
(30211: 23, 7) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 1581: F0 FC BEQ $157F
(30211: 23, 10) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 157F: C5 14 L157F CMP RTCLOK+2 [$14] = $D7
(30211: 23, 13) A=D7 X=09 Y=18 S=F3 P=33 ( ZC) 1581: F0 FC BEQ $157F
(30211: 23, 20) A=D7 X=09 Y=18 S=F0 P=37 ( IZC) C018: 2C 0F D4 LC018 BIT NMIST [$D40F] = $9F
(30211: 23, 24) A=D7 X=09 Y=18 S=F0 P=B5 (N I C) C01B: 10 03 BPL $C020
(30211: 23, 27) A=D7 X=09 Y=18 S=F0 P=B5 (N I C) C01D: 6C 00 02 JMP (VDSLST) [$180B] = $85
(30211: 23, 34) A=D7 X=09 Y=18 S=F0 P=B5 (N I C) 180B: 85 D0 STA $D0 [$D0]
(30211: 23, 38) A=D7 X=09 Y=18 S=F0 P=B5 (N I C) 180D: 86 D1 STX $D1 [$D1]
(30211: 23, 42) A=D7 X=09 Y=18 S=F0 P=B5 (N I C) 180F: 84 D2 STY $D2 [$D2]
(30211: 23, 46) A=D7 X=09 Y=18 S=F0 P=B5 (N I C) 1811: A9 23 LDA #$23
(30211: 23, 48) A=23 X=09 Y=18 S=F0 P=35 ( I C) 1813: 8D 00 D4 STA DMACTL [$D400]
No i jakim cudem wskakuje tu DLI? Dopiero ono ustawia DMACTL na $23.
Stan ANTIC-a:
DMACTL = 23 : wide 2-line dlist
CHACTL = 02 : invert
DLIST = 401b
HSCROL = 00
VSCROL = 00
PMBASE = 00
CHBASE = e0
NMIEN = c0 : dli vbi
NMIST = 9f : dli
PENH/V = 00 ff
Oczywiście zaufałem Altirrze, że poprawnie emuluje zachowanie ANTIC-a, ale bazując na tym zaufaniu zrobiłem patcha:
który ustawia pustą dlistę jeszcze przed uruchomieniem programu dekompresującego i wszystko działa, bo żadne przerwanie DLI nie jest wtedy uruchamiane.
I o co tutaj chodzi?
Edit: Dla porządku jeszcze dlista winiety:
401B: 70 70 70 70 70 70 70 70 42 2C 40 00 00 02 41 1B
402B: 40
Rozumiem, że ANTIC ma w buforze śmieci, ale dlaczego w takim razie DLI pojawia się w 23 linii skanningowej a nie w 8? Najpierw mamy pustą linię a potem linię 8 ze skrolami i DLI - VSCRL jest 0, więc nawet jeśli ANTIC ma drugi rozkaz zbuforowany to DLI powinno się pojawić w linii 16.
Edit 2: Hmmm $E8 to %11101000 czyli VSCROLL+ LMS + DLI.
Edit 3: Właściwie to zakładając, że Altirra kłamie co do stanu ANTIC-a, można założyć że w buforze jest linia trybu 5 albo 7 z ustawionym DLI - to by tłumaczyło przerwanie w linii 23. Dzięki @Krótki!
Edit 4: I rzeczywiście:
Altirra> .dlhistory
Ycoord DLIP PFAD H V DMACTL MODE
--------------------------------
8: 401b f03c 0 0 00 c5
24: 401b f03c 0 0 00 c5
40: 401b f03c 0 0 00 c5
56: 401b f03c 0 0 00 c5
72: 401b f03c 0 0 00 c5
88: 401b f03c 0 0 00 c5
104: 401b f03c 0 0 00 c5
120: 401b f03c 0 0 00 c5
136: 401b f03c 0 0 00 c5
152: 401b f03c 0 0 00 c5
168: 401b f03c 0 0 00 c5
184: 401b f03c 0 0 00 c5
200: 401b f03c 0 0 00 c5
216: 401b f03c 0 0 00 c5
232: 401b f03c 0 0 00 c5
Niezłe - w ten sposób mając wyłączone DMA i zgaszony ekran można generować przerwania DLI co 16 linii skanningowych. A używając trybu graficznego i VSCROL co 1..16 linii.
hex, code and ror'n'rol
niewiedza buduje, wiedza rujnuje