Je krásné vidět, jak je ten kód v Action! čitelný, i když je to vlastně jen "assembler na steroidech". Pomáhá tomu i že nechali klíčové slovo return a nenahradili ho slovem corp :D
Chtěl jsem si před spaním přečíst víc, a tak hlásím, že položka č. 141 z Odkazů na internetu mi nejde stáhnout :)
P.S.: K té chybě v algoritmu: už se fakt těším do postele, tak jsem to tolik nezkoumal, ale chyba je už v tom testu kláves, ne? Když nahradíme logické AND porovnáním "je větší", tak nás můžou zmást ty horní bity. Nevím tedy, jestli se do nich něco ukládá, ale obecně to tak je.
Tak ne, tohle není chyba, protože v $D01F jsou na horních pěti bitech vždy nuly, alespoň podle všech knih s popisem paměti Atari.
Action Manual alias položku 141 jsem našel na
https://www.atarimania.com/documents/atari-action-reference-manual.pdf
(teda pokud je to to stejné, co je pod tím myšleno)
Z hlediska programování je otázka, jestli je pravda, co jsem někde v propagačních materiálech zahlédl, a to že program v Action! se musí spouštět v prostředí Action!, pokud obsahuje použití jakékoliv knihovní funkce. Samostatně nabootovatelné programy potřebovaly překlad s externí knihovnou (slinkovat?), kterou prý prodávali zvlášť.
Sákryš, omlouvám se, že píšu takto místo abych šel a vyzkoušel to. Ale já se k tomu dostanu nejdřív v neděli...
Ano, tak to bylo. Existuje runtime, asi s těmi knihovními funkcemi - viz https://web.archive.org/web/20120309213853/http://retrobits.net/atari/action.shtml
OT: A ejhle, letos vyšel cross compiler https://github.com/jhusak/atari_action_compiler/ :-)
PROC MAIN()
BYTE RTC1=18
BYTE RTC2=19
BYTE RTC3=20
CARD TIME
RTC1=0
RTC2=0
RTC3=0
...
...
...
TIME=RTC2*256+RTC3 ; problem je kdy ze vysledek se muze lisit o 256
PRINT("FINISHED IN ")
PRINTC(TIME/50)
PRINTE(" SECONDS")
WAITKEY()
RETURN
reseni 1
PROC MAIN()
BYTE RTC1=18
BYTE RTC2=19
BYTE RTC3=20
CARD TIME
BYTE TMP_RTC1
RTC1=0 ; cas se pocita od tohoto okamziku
RTC2=0 ; po vynulovani RTC1 se v pohode stiha vynulovat zbytek nez RTC1 pretece a udela chaos...
RTC3=0
...
...
...
DO
TIME=RTC2
TMP_RTC1=RTC1 ; mereni casu MOZNA konci ted
UNTIL TIME=RTC2
TIME=TIME*256+TMP_RTC1
PRINT("FINISHED IN ")
PRINTC(TIME/50)
PRINTE(" SECONDS")
WAITKEY()
RETURN
reseni 2
PROC MAIN()
BYTE RTC1=18
BYTE RTC2=19
BYTE RTC3=20
CARD TIME
BYTE TMP_RTC2
RTC1=0 ; cas se pocita od tohoto okamziku
RTC2=0 ; po vynulovani RTC1 se v pohode stiha vynulovat zbytek nez RTC1 pretece a udela chaos...
RTC3=0
...
...
...
TMP_RTC2=RTC2
TIME=RTC1 ; mereni casu konci ted
IF TMP_RTC2<>RTC2 AND TIME<128
TIME=TIME+256
FI
TIME=TIME+TMP_RTC2*256
PRINT("FINISHED IN ")
PRINTC(TIME/50)
PRINTE(" SECONDS")
WAITKEY()
RETURN
Vse neovereno a ani neznam syntaxi ACTION! .)
Ale problem je klasicky shodny s ctenim pouku na ZX.
Mozna je u druheho prikladu lepsi rozdelit ten IF na dva vnorene, protoze nechci premyslet jak to muze rozlozit a zda tam nevznika kolize podle toho co prvni vyhodnocuje. Ale asi by nemela...
Jeste jsem zapomnel umazat RTC3 a jeho nulovani, kdyz ho nepouzivame a predpokladame vysledek testu do cca 21 minut (PAL) nebo 18 minut (NTSC).
Ani se me nechce premyslet jak udelat nejkratsi spravny test pro vsechny 3 hodnoty... .)
To nechavam na ty co jsem zkazil hadanku.
Syntax Action! přesně neznám a jen v rychlosti: šel bych na to přes zjištění okamžiku VBI:
TMP_RTC1=RTC1
DO
OD
UNTIL TMP_RTC1==RTC1
SAVE_RTC1=RTC1
SAVE_RTC2=RTC2
SAVE_RTC3=RTC3
Tj.: počkej na VBI a následně přečti všechny 3 hodnoty, protože víme, že až do dalšího VBI se nezmění. Tak to jde rozšířit na libovolný malý počet hodnot.
Pockej to budes cekat az 5 vterin, jen abys pockal kdy se zrovna navysi RTC2?
To uz je lepsi reseni 1, kde proste pridas dalsi cteni a opakujes to jen kdyz si vsimnes preteceni. Tam pridavas chybu/prodlevu jen o to opakovani cteni.
Problem je spis to presne resni, protoze resis zaroven mozne preteceni jak RTC2 tak RTC3 a asi bys mel znat implementaci, ale naivne predpokladam ze nekde v tvem programu nastane preruseni a v nem se nastavi vsechny 3 citace, takze nastane jen preteceni RTC2 nebo obou (jakoby najednou) nebo zadne.
17. 9. 2026, 15:39 editováno autorem komentáře
A co jednoduše počkat, až se inkrementuje nejnižší čítač a pak hned čítače vyčíst? To by se v pohodě stihlo, než by došlo k dalšímu přerušení. Něco jako
LDA 18
LOOP:
CMP 18
BEQ LOOP
A pak od výsledné hodnoty měření času odečíst 1, pokud by se tedy počítalo i s nejrychlejším čítačem.
Ech, totéž psal MilanV, tak nic nového.
17. 9. 2026, 16:36 editováno autorem komentáře
Aha, az ted me doslo jak to myslel.
Neni tam chyba az 5 sekund, ale az 0.02s.
Na rozdil od cteni znova kdyz to nevyslo, tam je chyba jen par taktu (zaokrouhleni nahoru), kdy se to prehoupne proste na dalsi 0.02s schod.
Díky za podporu zatímco jsem byl mimo internet :) Ano, to je základ mé jednoduché myšlenky: jelikož víme, kdo ty hodnoty mění a kdy, tak taky víme, že jindy nám je nikdo jiný pod rukama nemění.
A už zadání úlohy byla přesnost na 1/50, resp. 1/60 vteřiny. Kdybych chtěl lepší přesnost nad rámec původního zadání, začne to být zajímavé... Tedy samozřejmě kromě nejsnazší metody spustit test 10x za sebou a celkový čas vydělit deseti. Přímé měření neznámého kódu jiným kódem mi vždycky přišlo celkem obtížné. Nešlo by na to využít POKEY čítače přepnuté do toho režimu s vysokou frekvencí?
17. 9. 2026, 23:34 editováno autorem komentáře