Forum ContraBanda.eu
8-BITOWY WARSZTAT DOMOWY => Hardware => Wątek zaczęty przez: mono w Sierpnia 20, 2022, 21:37:49
-
Mam kod, który liczy mi ile mogę sobie pętelek zrobić w jednej ramce
detecttv:
bit PPUSTATUS
ldx #0
ldy #0
?wait1 bit PPUSTATUS
bpl ?wait1
?wait2 inx
sne
iny
bit PPUSTATUS
bpl ?wait2
rts
W YX mam tu różne wartości zależne od systemu TV (PAL/NTSC/DENDY).
Przerwanie VBLK mam zablokowane na czas pomiaru (nmien=$FF), a IRQ w ogóle nieaktywne (i pomiar odbywa się przy zapalonym I)
nmiint bit nmien
spl
irqint rti
...
więc ta ilość pętelek nie powinna być jakoś nadmiernie zakłócana.
Okazało się jednak że zależnie od użytego mappera (testowałem dla 001 MMC1 i 030 UNROM) ilość pętelek jest różna co oznaczałoby, że mapper potrafi wpłynąć na ilość cykli dla CPU na magistrali. Czy spotkaliście się z czymś takim?
Testowałem to na emulatorach FCEUX i MESEN - obydwa zachowują się tak samo. Nie mam chwilowo jak zrobić testu na prawdziwym sprzęcie.
W przypadku gdyby ktoś chciał porobić jakieś testy, to mogę przygotować pliczki .nes dla obydwu mapperów.
-
Tak. Oczywiście nie ma różnej ilości cykli dla CPU. Kod dla jednego mappera mieścił się na stronie, więc skoki względne zabierały 3 cykle, a dla drugiego leżał na granicy stron więc skoki względne zabierały 4 cykle - stąd mniejsza ilość obiegów pętli.
Przepraszam za zawracanie głowy.
-
To fakt, kod liczący ilość cykli CPU jest delikatny. Ja użyłem sobie tego, co polecają na NesDev: https://forums.nesdev.org/viewtopic.php?p=163258#p163258
Dostosowałem pod siebie, pamiętam coś tam mi nie trybiło jak chciałem żeby kod był ładnie ustrukturyzowany procedurami / skokami, jednak ja tylko eksperymentowałem z NROM, także inna sytuacja.
W związku z tym to oczekiwanie na rozgrzanie PPU (2 klatki) zostawiłem takie normalne, a ustalanie regionu wyodrębniłem jako czekanie po raz trzeci na vblank i w tej pętelce było tylko to.
Instrukcja sne to co to?
-
Dzięki @Verteks za linka do forum - to ciekawe co tam piszą o przetaktowanych systemach. Widzę że kod detekcji mają praktycznie taki sam, jak mój :)
Wspomniałeś o "rozgrzaniu" PPU - zmieniają się zauważalnie parametry pracy konsoli zależnie od czasu pracy? Można to jakoś wykryć?
Instrukcja sne to co to?
To jest makro znane jako "skip if ..." i są podefiniowane dla wszystkich skoków warunkowych na zasadzie (tu dla SNE):
bne ?skip
... ;tu dowolna instrukcja
?skip
Skip opuszcza następną instrukcję.
Podobnie można się spotkać z warunkowymi "jump if ..." czyli np. dla JNE, które wstawiają Bxx jeśli skok jest w zakresie -128..127 a jeśli dłuższy to SEQ:JMP. Taki tam lukier syntaktyczny (tu akurat w assemblerze MADS https://mads.atari8.info/ którego używam).
-
Pisali żeby czekać ileś tam cykli to po prostu czekałem, bez wchodzenia w szczegóły. Działa? Działa. Bez tego nie działało, nawet w emulatorze.
Tutaj: https://www.nesdev.org/wiki/PPU_power_up_state piszą o tym, najważniejsze to to, że zapisy do rejestrów PPU są ignorowane przez ileś tam cykli.
Nesdev (forum + wiki) to największa skarbnica wiedzy na temat programowania NES na świecie, polecam.
Makro rozumiem, dopiero teraz jak napisałeś to zauważyłem że przecież tam jest pętla w pętli. "jump if" brzmi przydatnie - nie ma potrzeby zastanawiać się, czy zmieścisz się ze skokiem relatywnym, jak kiedyś znów przysiąde do ASM to przyswoję tą technikę.
-
Pisali żeby czekać ileś tam cykli to po prostu czekałem, bez wchodzenia w szczegóły. Działa? Działa. Bez tego nie działało, nawet w emulatorze.
Tutaj: https://www.nesdev.org/wiki/PPU_power_up_state piszą o tym, najważniejsze to to, że zapisy do rejestrów PPU są ignorowane przez ileś tam cykli.
Wszystko jasne. Jeszcze raz dziękuję.
Nesdev (forum + wiki) to największa skarbnica wiedzy na temat programowania NES na świecie, polecam.
O tak. Macie naprawdę mnóstwo informacji i to na bardzo wysokim poziomie szczegółowości.
-
SNE to po rozwinięciu zdaje się Skip if Not Equal
-
Tak. Powiem więcej:
Branch if / Jump if / Skip if
BCC JCC SCC - Carry Clear
BCS JCS SCS - Carry Set
BNE JNE SNE - Not Equals (Z clear)
BEQ JEQ SEQ - EQuals (Z set)
BPL JPL SPL - PLus (N clear)
BMI JMI SMI - MInus (N set)
BVC JVC SVC - oVerflow Clear
BVS JVS SVS - oVerflow Set
Nie przyjęły się za to jakoś te wszystkie
* LT - Less Than
* GT - Greater Than
* LE - Less or Equal than
* GE - Great or Equal than
może dlatego, że nie ma do GT i LE odpowiednich skoków a trzeba to sobie zrobić kolejnością porównywania/odejmowania. Choć w sumie makro rozwijało by się do dwóch skoków... tylko który pierwszy? :)
-
Fajne te macro-rozkazy skoków długich warunkowych w MADS.
Tak z ciekawości dopytam - JCC działa to pewnie zamiennie do:
macro rozkaz:
sprawdzCarry
jcc warunekCarryClear
oryginalnie bez macro:
sprawdzCarry
bcs warunekCarrySet
jmp warunekCarryClear
warunekCarrySet:
Co do:
BLT - Less Than
BGT - Greater Than
BLE - Less or Equal than
BGE - Great or Equal than
To przydatne sa w ASM68K, tam oczywiscie sa realnymi rozkazami skokow warunkowych.
-
Dokładnie tak to działa.