atarionline.pl Rust - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1: CommentAuthormrk
    • CommentTime1 Jan 2022 zmieniony
     
    Dzięki temu że od niedawna llvm potrafi generować kod dla procesora 6502 ->link<- ->link<- pojawiła się interesująca możliwość kompilowania do 6502 języków używających LLVM jako backendu do generowania kodu. Jednym z takich języków jest Rust.

    Pierwsze próby zrobione jakieś pół roku temu wypadły pomyślnie ->link<- więc zrobiłem fork'a rust'a i dodałem eksperymentalne wsparcie dla nowego targetu o wdzięcznej nazwie: 'mos-unknown-none'. Zmiany w samym rust są małe: ->link<- co jest o tyle istotne że pozwala na łatwe uaktualnianie (rebase'owanie) forka z macierzystym projektem.

    Ostrzeżenie: całość jest ciągle bardzo eksperymentalna, rust potrafi często wygenerować llvm bitcode na którym się jeszcze wykłada llvm-mos, wygenerowane binarki mogą być duże / nieoptymalne lub po prostu nie działać :) Dodatkowo brak na razie biblioteki standardowej (rust std) i programy ktore piszemy muszą być #![no_std]

    W praktyce można się już tym nieźle pobawić - zgłoszone bug'i w llvm-mos są dość szybko poprawiane, działa Cargo (więc jest dostęp do bardzo dużej ilości 'krat' na ->link<- (muszą to być biblioteki dostosowane do #[no_std], ale jest ich całkiem sporo)

    Zbudowanie całości samodzielnie jest nieco uciążliwe i czasochłonne (wymaga zbudowania ze źródeł llvm-mos i rust'a), dlatego by nieco to ułatwić przygotowałem obraz docker'a który może być użyty jako DevContainer w Visual Studio Code lub samodzielnie (polecam vscode bo potrafi uruchomić też w kontenerze plugin rust-analyser, będący niesamowitym wsparciem w trakcie programowania): ->link<-

    Powyższy obraz zawiera także clang z llvm-mos + llvm-mos-sdk, więc można go użyć także do programowania w C/C++

    Opis jak skonfigurować Visual Studio Code do pracy z devcontainers jest tu: ->link<-

    Przykłady:
    - Ferris Demo: ->link<- (w konsoli `make`, wynikowy xex: target/mos-unknown-none/debug/ferris.xex)
    - rozwiązanie Day01 z tegorocznego AoC, przeportowane na małe atari: ->link<- - w konsoli `cargo build`

    Dajcie znać czy udało się coś skompilować przy użyciu powyższego obrazu.
    • 2: CommentAuthorilmenit
    • CommentTime2 Jan 2022
     
    Świetny projekt! Chętnie się pobawię, ale najpierw trzeba się nauczyć Rusta, a jak czytałem ma dosyć wysoki próg wejścia.
    • 3: CommentAuthormrk
    • CommentTime2 Jan 2022
     
    Zgadza się, na początku najłatwiej nie jest, trzeba trochę czasu by 'kliknęło'. Ale są dostępne bardzo fajne materiały do nauki, na przykład oficjalny Rust Book: ->link<- A sam kompilator już słynie z najlepszych chyba komunikatów błędów.

    6502 dostępny jako target to po prostu dodatkowa okazja / pretekst do nauki. A brak biblioteki standardowej / ograniczone zasoby atarynki można potraktować jako wprawkę do programowania 'embeded' :)
    • 4: CommentAuthormuro
    • CommentTime2 Jan 2022
     
    Super! Doskonała robota.
    • 5:
       
      CommentAuthorKaz
    • CommentTime2 Jan 2022
     
    Mrk - i kolejny projekcik "wow!" :D. Gratulacje - a może dasz się namówić na spotkanie typu Q&A?
    • 6: CommentAuthormrk
    • CommentTime2 Jan 2022
     
    @muro @Kaz - dzięki.
    Co do Q&A - myślę że możemy coś ustawić (może uda się kogoś przekonać do zabawy z llvm-mos / Rust)
    • 7: CommentAuthorilmenit
    • CommentTime2 Jan 2022
     
    A sam kompilator już słynie z najlepszych chyba komunikatów błędów.


    I to jest coś, co mnie do niego zachęca, jako C++ replacement :) Ostatnio odświerzałem sobie C++ i po błędzie w dowolnej nowej konstrukcji z C++11 do C++20 kompilator (niezależnie czy Visual, Clang czy GCC) zamiast prostego wyjaśnienia co jest nie tak, wyrzuca dla każdego błędu 50-100 linii błędów z szablonów. Co za koszmar...
    Fox mi podesłał niedawno ->link<-
    • 8: CommentAuthorlaoo
    • CommentTime2 Jan 2022
     
    Można się przyzwyczaić. Po paru latach już się tego nie zauważa i te komunikaty stają się całkiem normalne ;)

    Podobno "concepts" ma coś pomóc, pożyjemy, zobaczymy.
    • 9: CommentAuthormrk
    • CommentTime7 Jan 2022 zmieniony
     
    Update:
    - W kompilatorze pojawiły się trzy dodatkowe 'targety' dla kompilacji: mos-a800xl-none, mos-c64-none oraz mos-sim-none, co pozwala na dużo prostszą konfigurację (wcześniej trzeba było podawać ścieżkę do pliku konfiguracyjnego dla danej platformy).
    - Obrazy dokera generowane są teraz z github Actions, co pozwoli na częstsze (docelowo automatyczne) update'y
    - Zacząłem portować kolejne rozwiązania z tegorocznego Advent of Code: ->link<- - co pozwoliło już znaleźć i (w części poprawić) kilka błędów w kompilatorze, na przykład: ->link<-
    Powyższy błąd powodował złe działanie memcmp i w związku z tym wywalanie się programów w najdziwniejszych miejscach (wyprodukowane binarki po prostu nie działały dobrze) - ale wygląda na to że teraz jest już ok.

    BTW portowanie rzeczy pisanych i uruchamianych na współczesnym komputerze na małe Atari to niezłe wyzwanie :) Przykładowo program 'day07' który na dużym komputerze zwraca wynik w ułamku sekundy, na symulatorze 6502 (skompilowany na mos-sim-none) zwraca wynik po 30 sekundach a szacowany czas działania na real atari to jakieś 2h :)

    Fajne jest to że większych zmian w samym algorytmach nie musiałem robić i programy zwracają poprawne wyniki (operując czasami na 64-bitowych liczbach, co jest dla atari już prawdziwym bigint'em :)
    • 10: CommentAuthorastrofor
    • CommentTime8 Jan 2022
     
    No nie wierzę. Functional programming na małym atari.
    • 11: CommentAuthormrk
    • CommentTime17 Jan 2022
     
    @astrofor jak obiecałem w sąsiednim wątku ->link<- - pierwsza 'krata' dla atari opublikowana na crates.io: ->link<- - Zebrałem trochę funkcji / stałych których używałem w innych projektach + kilka funkcji do rysowania w gr.0: (gotoxy, clrscr, show_cursor). Pełniejsza lista w automatycznie generowanej dokumentacji: ->link<-

    W README jest opis jak zbudować przykładowy program (w załączniku), jak zwykle zachęcam do użycia devcontainer w vscode (pozwala na postawienie środowiska w czystym systemie (Win/Linux/Mac) przy użyciu kilku kliknięć)
    • 12: CommentAuthorastrofor
    • CommentTime17 Jan 2022
     
    Super, zastanawiam sie czy nie uprościc czegos takiego jak :
    ->link<-
    i zrobic switcha na atari i pc.(tak jak w adam is me) Ta biblioteka wydaje sie troche za bardzo skomplikowana, i nie wyobrazam sobie optymalizacji tych wszystkich stuktur na kompilator 6501. Tak czy inaczej rusta mozna w miare ludzko debugowc kod z poziomu ide, docker gotowy, takze nic tylko programowac ;)
    • 13: CommentAuthormrk
    • CommentTime17 Jan 2022 zmieniony
     
    @astrofor na razie jest jeszcze kilka ograniczeń jeżeli chodzi o wykorzystanie zewnętrznych bibliotek dostępnych na crates.io:

    * chwilowo nie działa jeszcze dynamiczna alokacja pamięci, więc nie działają rzeczy typu String, Vec itd. Co niekoniecznie musi być wadą przy ograniczonych zasobach pamięciowych Atari. Ale malloc / free właśnie wylądował w llvm-mos-sdk, więc podpięcie tego do rust'a powinno być proste (i nauczę się wreszcie jak działa w Rust `alloc`)

    * biblioteka musi być dostosowana do no_std, czyli nie używać nic z namespace std::* Całe szczęście jest spora lista rzeczy pisanych pod no_std (do zastosować embeded), na przykład:
    - ->link<- - alternatywa dla core::fmt (odpowiednik printf / sprintf z C) zoptymalizowana jeśli chodzi o zużycie zasobów
    - ufmt-stdio - ->link<- - alternatywna implementacja makr print! / println! wykorzystująca `ufmt`. Zacząłem tego używać niedawno i działa fajnie.
    - staticvec - ->link<- - implementacja Vec ale bez dynamicznej alokacji, na stosie.

    Co do pisania kodu wieloplatformowego - działa to bardzo fajnie. Day25 z AoC można bez zmian skompilować na target `mos-a800xl-none` z pełnoekranową wizualizacją, skompilowany na `mos-sim-none` można uruchomić na symulatorze z przełącznikiem --cycles i zobaczyć ile całość zajęła cykli emulowanego 6502 albo skompilować na `x86_64-unknown-linux-gnu` i zamiast ~1h zakończyć program w 0.2 sek :)
    • 14: CommentAuthormrk
    • CommentTime18 Jan 2022
     
    Dynamiczna alokacja pamięci już działa: ->link<- co powinno też znacznie powiększyć ilość bibliotek z crates.io które będzie można spróbować wykorzystać.
    • 15: CommentAuthormrk
    • CommentTime19 Jan 2022
     
    A to najdziwniejsza rzecz jaką udało mi się na razie zbudować :) Ktoś zainteresowany generatorem kodów QR na atari? :]
    • 16: CommentAuthortebe
    • CommentTime19 Jan 2022 zmieniony
     
    datamatrix - 6502

    ->link<-

    ->link<-
    • 17: CommentAuthorastrofor
    • CommentTime19 Jan 2022
     
    Kody qr na atari występują w grze asteroida jako źródło.. ale chyba były generowane na pc, a szkoda.
    Rozumiem że ostatni post to zachęta do przeportowania blibsów do rusta ;)
    • 18: CommentAuthormrk
    • CommentTime24 Jan 2022 zmieniony
     
    Nowa wersja a800xl-utils-0.1.4: ->link<-

    Zmiany:
    * narzędzia do niskopoziomowych operacji na CIO / IOCB. Przykładowo zapis znaków do 'stdout' można zrobić tak:
    IOCB::new(0).cmd(0x0b).buffer(b"CIO: hello").call()


    * obsługa plików na bazie powyższej implementacji CIO: ->link<-
    * obsługa trybów graficznych dostarczanych przez 'S:' (tak jak w BASICu):
    ->link<- - funkcje init_graphics, plot, drawto

    Przykłady wykorzystania w katalogu examples (polecam jak zwykle vscode + devcontainer, do zbudowania examples.atr wystarczy wtedy dać w konsoli `make`)



    Źródła: ->link<-
    Dokumentacja: ->link<-
    • 19: CommentAuthormrk
    • CommentTime24 Jan 2022 zmieniony
     
    Dodam jeszcze że integracja w tym samym projekcie rust'a, C i asm to jakaś igraszka. Przykładowo by wołać CIOV musiałem napisać ten kod w asemblerze: ->link<- kompilacja i linkowanie z rust odbywa się tak: ->link<- i po deklaracji ->link<- już można używać w/w funkcji (na tej samej zasadzie można skompilować i dołączyć do projektu kod napisany w clang)
    • 20: CommentAuthorilmenit
    • CommentTime24 Jan 2022
     
    genialne
    • 21: CommentAuthortebe
    • CommentTime24 Jan 2022
     
    będzie prawdziwy float ?

    ->link<-

    float16 (half-single) w C, mógłbyś to zintegrować

    możesz przeciążać operatory? nauczyć nowej arytmetyki?
    • 22: CommentAuthormrk
    • CommentTime24 Jan 2022 zmieniony
     
    @tebe
    Rust natywnie obsługuje tylko f32 i f64 (i typy te na razie w llvm-mos (i co za tym idzie rust-mos) nie są zaimplementowane)

    Ale widzę że jest po prostu paczka dostarczająca f16 na crates.io ->link<- i jest spora szansa że może działać (po zerknięciu w kod widzę że pewnie potrzebne by były małe poprawki - na przykład trzeba by warunkowo wyłączyć wszystko co odwołuje się tam do f32 / f64). Z ciekawości w wolnej chwili spróbuję to zbudować i dam znać.
    EDIT - po drugim spojrzeniu doczytałem że:
    Because f16 is primarily for efficient storage, floating point operations such as addition, multiplication, etc. are not implemented. Operations should be performed with f32 or higher-precision types and converted to/from f16 as necessary.

    Więc trochę więcej pracy niż myślałem :) Ta biblioteka zresztą implementuje te operacje castując do/z f32: ->link<-


    Przeciążanie operatorów robi się implementując dla nowego typu odpowiednie 'traits', tu przykład jak to robi powyższa biblioteka: ->link<-
    • 23: CommentAuthormrk
    • CommentTime24 Jan 2022
     
    Z innej beczki: przed chwilą opublikowałem nową wersję mos-alloc: ->link<- Jedyna poprawka to implementacja `realloc` która woła `realloc` świeżo zaimplementowany w llvm-mos-sdk: ->link<-
    • 24: CommentAuthorastrofor
    • CommentTime25 Jan 2022
     
    Float 16 całkowicie rozumiem. Ale po przeciążanie operatorów na atari? W sensie czy to może mieć jakieś praktyczne zastosowanie ?
    • 25: CommentAuthormrk
    • CommentTime25 Jan 2022 zmieniony
     
    @astrofor myślę że wygoda i ergonomia użycia nowo definiowanych typów to wystarczająco praktyczne zastosowanie:

    val c: f16 = a + b * b;


    vs

    val c: f16 = a.add(b.mul(b));


    Jake znaczenie ma że targetem jest małe atari? Te dwa zapisy wyżej są równoznaczne i skompilują się do identycznego kodu maszynowego.
    • 26:
       
      CommentAuthorKaz
    • CommentTime25 Jan 2022
     
    Niezłe! Brawo mrk :)

    mrk:

    A to najdziwniejsza rzecz jaką udało mi się na razie zbudować :) Ktoś zainteresowany generatorem kodów QR na atari? :]


    O, ciekawa rzecz, bo tak jak pisał Astrofor, w grze "Asteroida" wygenerowaliśmy kody QR, które w grze występują - na pececie. A teoretycznie można by je generować dynamicznie przy każdym przechodzeniu...
    • 27: CommentAuthorastrofor
    • CommentTime26 Jan 2022
     
    A może dało by się jakiegoś prostego sokobana napisać w ruscie ? Jako Proof of concept, i prosty szablon do pisania tego typu gierek ?
    • 28: CommentAuthormrk
    • CommentTime30 Jan 2022
     
    @astrofor Z pewnością by się dało, zachęcam :) W razie problemów pomogę.
    • 29: CommentAuthormrk
    • CommentTime1 Feb 2022
     
    konsolowy klon 2048, dodałem jako przykład do a800xl-utils: ->link<-

    • 30: CommentAuthorastrofor
    • CommentTime2 Feb 2022
     
    Stare przysłowie mówi że dobrego programistę poznaje się nie po tym jak zaczyna, a jak kończy. Dodanie show_cursor(true); na zakończenie programu mówi samo za siebie. ;)
    A poważnie to po każdym ruchu przerysowujesz całego boarda w pętli używając:
    fn write_line(text: &[u8]) {
    IOCB::new(0).cmd(Cmd::PutBytes as u8).buffer(text).call();
    }
    I wygląda to dobrze, w sensie nie skacze. Ja robiłem coś podobnego w mad pascalu, i rysowanie całego boarda powodowało mruganie ekranu - elementów które pozostawały bez zmian też. Dlatego używałem gotoxy i putchar zdaje suę, wtedy było ok.
    Czy twoje write_line jest jakoś zoptymalizowane?
    • 31: CommentAuthormrk
    • CommentTime2 Feb 2022
     
    Nie, robi dokładnie to co widać: PutBytes do E:
    • 32:
       
      CommentAuthorjhusak
    • CommentTime2 Feb 2022 zmieniony
     
    @Kaz, jest generator kodów Datamatrix by 0xF. Kod zajmuje 2 strony pamięci.
    ->link<-
    • 33: CommentAuthormrk
    • CommentTime2 Feb 2022 zmieniony
     
    @jhusak
    To ja tylko dodam że binarka którą zbudowałem do generowania tych qrcodes miała jakieś 30kB z optymalizacją -Os, i jakieś 50 kB z -O3, hehe :]), więc raczej ciężko o użycie w grze :]
    Na usprawiedliwienie rust-mos'a dodam że jest to port 1:1 biblioteki targetowanej na raczej duże współczesne maszyny, z zerową ilością zmian pod rust-mos'a (dokładnie ten sam kod może być skompilowany zarówno na współczesnym PC i na małym atari). I biblioteka ma masę ficzerów, na pewno dało by się dużo urwać z tej wielkości:

    ->link<-

    BTW właśnie zauważyłem że jest też wersja "C language (99 and above)" - prawdopodobnie clang z llvm-mos jest w stanie też ją zbudować bez żadnych poprawek, co pozwoliło by na porównanie wielkości binarek z rust'em. Ciekawe jest też to jak poradziłby sobie z tym cc65 (czy potrzebne duże zmiany w bibliotece, jak z wielkością binarki / szybkością).
    • 34:
       
      CommentAuthorjhusak
    • CommentTime2 Feb 2022
     
    Na 6502 nie wygrasz kompilatorem z biegłym programistą, niestety. Ale warto próbować.
    • 35: CommentAuthorilmenit
    • CommentTime3 Feb 2022 zmieniony
     
    @mrk - kiedyś skompilowałem z użyciem CC65 kod wygenerowany z ->link<- , tutaj: ->link<-