atarionline.pl Moje boje z Action! i VBXE - 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:
       
      CommentAuthorGeorge
    • CommentTime10 Nov 2021
     
    Mam nadzieję, że to początek dłuższej przygody, oby też częstej.
    Poniżej programik w Action! do detekcji gdzie jest lub nie VBXE.
    BYTE MEMAC_B_CTL_D6 = $D65D
    BYTE MEMAC_B_CTL_D7 = $D75D
    BYTE MEMAC_B = $4000
    BYTE OLD_MEMAC, NEW_MEMAC
    BYTE det = [0]
    PROC Main()
    det = 0
    MEMAC_B_CTL_D6 = 0
    OLD_MEMAC = MEMAC_B
    MEMAC_B_CTL_D6 = $80
    NEW_MEMAC = MEMAC_B
    IF OLD_MEMAC <> NEW_MEMAC THEN
    PRINTE("VBXE under $D6")
    det = 1
    FI
    MEMAC_B_CTL_D7 = 0
    OLD_MEMAC = MEMAC_B
    MEMAC_B_CTL_D7 = $80
    NEW_MEMAC = MEMAC_B
    IF OLD_MEMAC <> NEW_MEMAC THEN
    PRINTE("VBXE under $D7")
    det = 1
    FI
    IF det = 0 THEN
    PRINTE("VBXE not detected.")
    FI
    RETURN

    Każda merytoryczna uwaga mile widziana.
    Testowane na Altirrze i działa.
    W następnym kroku idzie użycie pointerów, żeby nie musieć powtarzać kodu oraz drukowanie wersji rdzenia (>=1.2).

    Oczywiście nie jest to nic nowego, ale dla mnie wielki skok w wiedzy, udało mi się zrozumieć zawiłego assemblera by KMK/DLT, na podstawie którego sprokurowałem ten programik w ACTION! - znajomość którego z kolei jest pokłosiem własnej pracy i zeszłorocznych warsztatów.
    Tak więc dla mnie, jest to duży krok w stronę programowania VBXE.
    • 2: CommentAuthortebe
    • CommentTime10 Nov 2021
     
    chwalmy Pana :)
    • 3:
       
      CommentAuthorGeorge
    • CommentTime10 Nov 2021
     
    Buk zapłać! :)
    • 4:
       
      CommentAuthorKaz
    • CommentTime10 Nov 2021
     
    Brawo George! Świetnie, że tak jak zapowiadałeś - wracasz "na ostro" do programowania.
    • 5:
       
      CommentAuthortdc
    • CommentTime10 Nov 2021
     
    Fajnie, fajnie.

    George a zastanawiałeś się jaki model przyjąć z bankami pamięci dla nieco większych programów w Action!?
    • 6:
       
      CommentAuthorGeorge
    • CommentTime11 Nov 2021
     
    @tdc - nie zastanawiałem się. A o jaką wielkość programu chodzi?
    Mam jeszcze przed sobą zastanawianie się jak skompilować program do pliku binarnego uruchamianego samodzielnie.

    Może dla osób, które chciałyby wiedzieć, a są na etapie takim jak ja parę chwil wcześniej wyjaśnię z grubsza, co tam się dzieje.

    Pod adresem MEMAC_B ($4000) jest umieszczone okno pamięci, które wymiennie może być widziane przez CPU jako RAM komputera, albo pamięcią VBXE. Przez to okno wymienia się dane pomiędzy RAM<->VBXE.

    Z kolei rejestr MEMAC_B_CTL służy do przełączania tego okna pomiędzy tymi dwom stanami (RAM,VBXE). Ale VBXE może być zainstalowane tak, że ten rejestr jest na $D6-ej stronie pamięci, albo na $D7-ej. Czyli albo pod adresem $D65D albo $D75D. A zatem sprawdzenie polega na porównaniu zawartości pierwszej komórki okna czyli komórki $4000 w momencie gdy jest tam RAM z zawartością gdy jest tam RAM VBXE.
    Zakłada się, że te wartości powinny się różnić.
    Jeśli się nie różnią oznacza to, że przełączenie się nie było skuteczne, bo VBXE steruje się tym drugim rejestrem, albo w ogóle go nie ma podłączonego.

    Samo przełączenie polega na ustawieniu lub wyzerowaniu najbardziej znaczącego bitu rejestru MEMAC_B_CTL, czyli wpisaniu wartości $80 (wtedy CPU widzi RAM VBXE) lub $0 (wtedy CPU widzi swój RAM).
    Trochę to uprościłem, bo jeszcze jest ANTIC i banki VBXE, ale na początek to mi wystarczyło.
    • 7:
       
      CommentAuthorGeorge
    • CommentTime11 Nov 2021
     
    @Kaz - tak, spotkania na Zoomie inspirują mnie, żeby kontynuować rozwój Atarowski.
    • 8:
       
      CommentAuthorKaz
    • CommentTime11 Nov 2021
     
    O! Miło to słyszeć, bo te spotkania mają taki właśnie cel.
    • 9:
       
      CommentAuthorjhusak
    • CommentTime12 Nov 2021 zmieniony
     
    Fajnie, że powstają procki do obsługi VBXE.
    Skąd wziąłeś tę metode testowania istnienia VBXE?

    Warto też zadbać o przywrócenie poprzednich wartości.
    Zamień prockę na funckę i wywal te printey ze środka.
    Zwróć jedną z wartości 0, $d6, $d7.
    I nie wprowadzaj wskaźników w tym przypadku, bo kod sporo spuchnie.
    • 10: CommentAuthortebe
    • CommentTime12 Nov 2021
     
    Biblioteczka kodera na atari.area

    ->link<-

    od wielu dekad
    • 11:
       
      CommentAuthorjhusak
    • CommentTime12 Nov 2021 zmieniony
     
    @tebe, poniewczasie skojarzyłem, że to ta sama metoda :)
    • 12:
       
      CommentAuthorGeorge
    • CommentTime15 Nov 2021
     
    @jhusak - tak, to ta sama metoda.
    @tebe - mam tylko wrażenie, że tam jest błąd,
    JEST: "bit 4-6, główny numer rewizji zapisany w kodzie BCD (cyfry od 0 do 9)."
    POWINNO BYĆ: "bit 4-6, główny numer rewizji zapisany w kodzie BCD (cyfry od 0 do 7)."

    Tymczasem pozmieniałem kod zgodnie z sugestiami @jhusak i napisałem funkcje dekodujące numery rewizji rdzenia.

    BYTE MEMAC_B_CTL_D6 = $D65D
    BYTE MEMAC_B_CTL_D7 = $D75D
    BYTE MEMAC_B = $4000

    BYTE FUNC vbxe_detect()
    BYTE OLD_MEMAC, NEW_MEMAC

    MEMAC_B_CTL_D6 = 0
    OLD_MEMAC = MEMAC_B
    MEMAC_B_CTL_D6 = $80
    NEW_MEMAC = MEMAC_B
    MEMAC_B_CTL_D6 = 0
    IF OLD_MEMAC <> NEW_MEMAC THEN
    RETURN ($D6)
    FI
    MEMAC_B_CTL_D7 = 0
    OLD_MEMAC = MEMAC_B
    MEMAC_B_CTL_D7 = $80
    NEW_MEMAC = MEMAC_B
    MEMAC_B_CTL_D7 = 0
    IF OLD_MEMAC <> NEW_MEMAC THEN
    RETURN($D7)
    FI
    RETURN (0)

    BYTE FUNC vbxe_core_magic(BYTE page)
    BYTE POINTER magic_ptr
    magic_ptr=page*256+$40
    RETURN (magic_ptr^)

    BYTE FUNC vbxe_is_rambo(BYTE page)
    BYTE POINTER rambo_ptr
    rambo_ptr=page*256+$41
    RETURN (rambo_ptr^ RSH 7)

    BYTE FUNC vbxe_core_rev(BYTE page)
    BYTE POINTER rev_ptr
    BYTE rev
    rev_ptr=page*256+$41
    rev = (rev_ptr^&$0F) + 10 * ((rev_ptr^&$70) RSH 4)
    RETURN (rev)

    PROC Main()
    BYTE vbxe_page = [0]
    BYTE magic = [0]
    BYTE rev = [0]
    BYTE POINTER rev_ptr
    vbxe_page = vbxe_detect()
    rev_ptr = vbxe_page*256+$41
    IF vbxe_page = 0 THEN
    PRINTE("VBXE not detected.")
    RETURN
    ELSE
    PRINTF("VBXE under %H%E", vbxe_page*256)
    FI
    magic = vbxe_core_magic(vbxe_page)
    IF vbxe_page <> 0 THEN
    PRINTF("VBXE's magic number is: %H%E", magic)
    PRINTF("Revision byte: %H %E", rev_ptr^)
    IF vbxe_is_rambo(vbxe_page) THEN
    PRINTE("Rambo emulation enabled.")
    ELSE
    PRINTE("Rambo emulation disabled.")
    FI
    rev = vbxe_core_rev(vbxe_page)
    PRINTF("Revision number: %I%E", rev)
    FI
    RETURN


    Wszelkie merytoryczne uwagi, jak zwykle mile widziane. Głaski też ;)

    To już dużo kodu, więc raczej będę zapraszał na mojego GitHuba:
    ->link<-

    Teraz wypadałoby było coś wyświetlić za pomocą tej karty :)
    • 13:
       
      CommentAuthorjhusak
    • CommentTime15 Nov 2021 zmieniony
     
    Tak, zauważyłem ten błąd (bity 4-6) w atariki i zgłosiłem w dyskusji.

    Jakby co, to procedury biblioteczne powinny być w miarę bezbibliotekowe.

    Np taki urywek kodu pokazuje jak obejść się bez mnożenia *256 czy przesuwania LSH 8:
    CARD C

    PROC M256XC(BYTE A)
    BYTE B=C+1
    B=A
    RETURN

    PROC M()
    M256XC($7B)
    PRINTF("%I%E",C)
    RETURN


    co daje przyjemny kodzik:

    0ECB: 4C CE 0E  JMP $0ECE
    0ECE: 8D CA 0E STA $0ECA
    0ED1: AD CA 0E LDA $0ECA
    0ED4: 8D C9 0E STA $0EC9
    0ED7: 60 RTS
    // tu start
    0ED8: 4C DB 0E JMP $0EDB
    0EDB: A9 7B LDA #$7B
    0EDD: 20 CB 0E JSR $0ECB
    0EE0: 4C E8 0E JMP $0EE8
    0EE1: E8 0E 04 25 49 25 45
    0EE8: AD C9 0E LDA $0EC9
    0EEB: 85 A3 STA $A3 ;MVLNG+1
    0EED: AC C8 0E LDY $0EC8
    0EF0: A2 0E LDX #$0E
    0EF2: A9 E3 LDA #$E3
    0EF4: 20 CC A3 JSR $A3CC
    0EF7: 60 RTS
    0EF8: 60 RTS


    i brak skoków do biblioteki (poza printf rzecz jasna)
    • 14:
       
      CommentAuthorGeorge
    • CommentTime15 Nov 2021 zmieniony
     
    Kurczaczek, jaka jest kompatybilność Action 3.6! ze Sparta DOS X 4.49? Nie mogę wczytać na real Atari mojego kodu źródłowego do edytora Action! :(
    Error 137
    Dobra, na razie widzę, że inne pliki się wczytują do Action!, czyli coś z tym plikiem nie tak chyba.
    O, matko, oczywiście, przegrałem bez zmiany formatu z ASCII.
    Teraz zrobiłem, że spod Action! zapisałem do .atr i na real Atari się wczytało.
    I Sparta DOS X zaczął mi współpracować z H6 na emulatorze, więc jest nieźle.

    Czasem wykładam się na jakiś prostych użytkowych rzeczach, nie zawsze wiem, o co chodzi, ale na szczęście jest coraz lepiej.
    Przy okazji programik mój się przydał, bo wykryłem, że na Atari ma core 1.20 - dziwne, wydawało mi się, że przełączałem core na najnowszy, będę musiał sprawdzić.
    • 15:
       
      CommentAuthorGeorge
    • CommentTime15 Nov 2021
     
    @jhusak - fajna optymalizacja.
    Dobrze rozumiem, że to bezpośrednie wpisanie do starszego bajtu CARD, co załatwia nam mnożenie przez 256?
    Jesteśmy pewni, że bez inicjalizacji w C na początku będzie zero?
    • 16:
       
      CommentAuthorKaz
    • CommentTime15 Nov 2021
     

    George:

    To już dużo kodu, więc raczej będę zapraszał na mojego GitHuba


    Nerwosolek? Czyżby miłośnik twórczości Tadeusza Baranowskiego? :)
    • 17:
       
      CommentAuthorjhusak
    • CommentTime15 Nov 2021 zmieniony
     
    Tak. Widać to wyraźnie w dizasemblistingu w 4 i 5 rozkazie od góry.

    Przy pierwszym uruchomieniu, ponieważ zmienne (czy to globalne, czy lokalne) siedzą w kodzie, to będzie tam 0 po uruchomieniu, więc inicjowanie na zero nic nie robi. Inicjowanie na inne wartości nie zwiększa gługości kodu.
    • 18:
       
      CommentAuthorKaz
    • CommentTime15 Nov 2021
     

    jhusak:

    nie zwiększa gługości kodu.


    Lubię neologizmy, nawet powstałe przypadkowo :). "Gługość" mogłaby oznaczać np. stopień nieczytelności kodu, od wyrażenia "głupi kod, za długi" :)
    • 19:
       
      CommentAuthorGeorge
    • CommentTime15 Nov 2021
     
    @jhusak - PRINTF("%H%E",C) polecam od razu widać szesnastkowo, że 7B się przesunęło do starszego bajtu.

    @Kaz - Zaiste. Liczyłem na to, że w tym gronie niedługo to zajmie skojarzenie tego faktu ;)
    • 20:
       
      CommentAuthorGeorge
    • CommentTime15 Nov 2021 zmieniony
     

    jhusak:

    Tak. Widać to wyraźnie w dizasemblistingu w 4 i 5 rozkazie od góry.


    Tylko dziwnie bo to $7B zapisuje tam i w starszym i młodszym bajcie. Dalej nie rozumiem, co się dzieje. Hmmm...
    • 21:
       
      CommentAuthorjhusak
    • CommentTime16 Nov 2021
     
    Bo Ci się mieni w oczach:) C jest pod adresem $ec8, B pod $ec9 a A jako parametr aktualny procki m256xa jest zapisane pod $eca.
    • 22:
       
      CommentAuthorGeorge
    • CommentTime16 Nov 2021
     
    OK. Teraz to widzę. Adres C jest dopiero używany przy PrintF.
    Swoją drogą nie wszystkie linie są dla mnie jasne, skąd je kompilator wyprowadził i do czego służą, ale z czasem pewnie wyrobię się :)
    • 23:
       
      CommentAuthorjhusak
    • CommentTime16 Nov 2021 zmieniony
     
    Kompilator jest prymitywny, to w zasadzie translator. Ale działa. I ma jakieś proste optymalizacje. Ale nie można liczyć, że 2*3 zapisze jako 6; wywoła mnożenie 2 i 3. Ja Action traktuję trochę jak taki super wypaśny asembler. Jednak przy większych projektach potrafi dać w kość. Trzeba robić mniejsze moduły jak się chce np. grę pisać. No, chyba, że taka Speedmaza, która jest dość prosta.
    • 24:
       
      CommentAuthorGeorge
    • CommentTime17 Nov 2021
     
    BYTE ARRAY MEM($4000)=$4000

    PROC MAIN()
    CARD CNT
    FOR CNT=0 TO 20
    DO
    PRINTC(CNT):PRINT(" "):PRINTBE(MEM(CNT))
    OD
    FOR CNT=1024 TO 1343
    DO
    PRINTC(CNT):PRINT(" "):PRINTBE(MEM(CNT))
    MEM(CNT)=99
    OD
    FOR CNT=0 TO 20
    DO
    PRINTC(CNT):PRINT(" "):PRINTBE(MEM(CNT))
    OD
    RETURN


    Taka ciekawostka, nie wiem, co tutaj się dzieje, mocno mnie to zmyliło podczas próby zapisu do VBXE przez MEMAC_B.
    Otóż mimo, że zapis do pamięci przy pomocy tablicy MEM następuje tylko w pętli drugiej,
    od indeksu 1024, to wartość wpisana pojawia się również na początku tablicy (pod adresem $4000)
    Ten problem nie pojawia się gdy zmniejszę rozmiar tablicy MEM do rozmiaru np. $1000.
    Dzieje się tak zarówno jak mam włączony RAM jak i VRAM w oknie MEMB.
    Odpalane na Altirra z VBXE bez dodatkowej pamięci.
    Czy ktoś wie, o co kaman?
    • 25:
       
      CommentAuthorGeorge
    • CommentTime17 Nov 2021
     
    Coś się już wyświetla. Muszę jakąś paletę zdefiniować, bo na razie dodałem jeden kolor ręcznie.
    • 26:
       
      CommentAuthorGeorge
    • CommentTime17 Nov 2021
     
    No comments!!!
    • 27:
       
      CommentAuthorpirx
    • CommentTime17 Nov 2021
     
    na serio pytanie - przed szarym paskiem jest kolor przezroczysty?
    • 28:
       
      CommentAuthorGeorge
    • CommentTime17 Nov 2021
     
    Tak, zero. Zacząłem od jakiejś losowej liczby iterację po kolorach, może lepiej zacząć od zera, żeby ładnie było?
  1.  
    Dawno nie widziałem na Atari poziomej tenchi, brawo!
    • 30:
       
      CommentAuthorGeorge
    • CommentTime18 Nov 2021
     
    Zmienne lokalne funkcji w Action! są inicjowane w deklaracji tylko przy kompilacji, nieprawdaż?
    Tak by wynikało z rozmów na spotkaniu z Amarokiem i tego, co mi się wyprawia na ekranie.
    Trzeba jeszcze inicjować zmienną jawnie w kodzie funkcji.
    • 31:
       
      CommentAuthorjhusak
    • CommentTime18 Nov 2021
     
    Tak. W Action! lokalne zmienne to tylko widoczność, nie ma alokacji na stosie przy wywołaniu. Więc w funkcjach trzeba je inicjalizować, jeśli to konieczne, lub można je traktować tak jak zmienne statyczne w funkcji w C.

    Ja ze swej strony uważam to za pozytywne uproszczenie, rekurencja w grach jest baaaardzo rzadko stosowana i jest rozrzutna pamięciowo, więc jawne pozbycie się jej by design zmusza programistę (jeśli jej potrzebuje) do użycia własnego stosu tylko w celu pamiętania lokalnych stanów i tylko tam, gdzie to potrzebne, co jest ekonomiczne.

    Co prawda w CC65 można ten sam efekt osiągnąć nie używając zmiennych lokalnych automatycznych, ale jednak tylko jeden parametr bajtowy w akumulatorze można przekazać do funkcji bez użycia stosu (w Action bodajże 3: A,X,Y.). Ale wtedy zmniejszamy stos do np. 32 bajtów (a nie jak domyślnie ~2kB).
    • 32:
       
      CommentAuthorGeorge
    • CommentTime18 Nov 2021
     
    @jhusak - Dzięki za wyjaśnienie. Mógłbyś się jeszcze wypowiedzieć w kwestii tej tablicy na MEMB, wpis #24?
    Nie wiem, co tam się może dziać.
    • 33:
       
      CommentAuthorKaz
    • CommentTime18 Nov 2021
     

    mgr_inz_Rafal:

    Dawno nie widziałem na Atari poziomej tenchi, brawo!


    A ostatnio gdzie widziałeś? :)
    • 34: CommentAuthorAdam
    • CommentTime18 Nov 2021
     
    Nie wiem jak mgr inżynier, ale ja np. widziałem tutaj poziomą tęczę na XL/XE: ->link<-
    • 35:
       
      CommentAuthorKaz
    • CommentTime18 Nov 2021
     
    Fajne! A gdzieś jeszcze były takie tęcze, ktoś pamięta?
    • 36:
       
      CommentAuthorGeorge
    • CommentTime18 Nov 2021 zmieniony
     
    W XDL jest po prostu bit i bajt RPTL, dzięki którym określasz ile razy powtórzyć tą samą linię, a dodatkowo jeśli OVARD_STEP wpisze się zero, to używa cały czas tej samej "linii" z pamięci VRAM, dzięki czemu powtórzony jest efekt z poprzednich linii. W pamięci VRAM za to wpisane są liczby po kolei kolor od 0-255 i abarot.

    Jak to zrobić w DL, to nie wiem, zakładam, że tutaj trzeba palet w locie podmieniać?
    • 37:
       
      CommentAuthorGeorge
    • CommentTime18 Nov 2021 zmieniony
     
    A skośna tęcza?
    • 38:
       
      CommentAuthormav
    • CommentTime18 Nov 2021
     
    @Kaz - jak się w Ataroidzie umiera (gubi piłkę) to jest pionowa tęcza :)
    • 39:
       
      CommentAuthorKaz
    • CommentTime28 Dec 2021 zmieniony
     
    A tu kolega AtariFan wrzucił taki oto filmik, na którym jest porównanie generowania "labiryntów" w Atari Basic, Turbo Basic XL, Action! oraz Quick Assemblerze, jest też wersja na VBXE:

    • 40:
       
      CommentAuthorjhusak
    • CommentTime29 Dec 2021
     
    @George, wpis #24. Ja używam byte Array m=0.
    Tam jest jakiś ficzer - uproszczenie, ale nie zgłębiałem (byte array mem($4000)=$4000)