atarionline.pl MAD-Pascal - Początki - 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:
         
        CommentAuthorbocianu
      • CommentTime3 Dec 2019 10:12
       
      no niestety, innego wyjścia raczej nie ma.
      No chyba że Tebe coś wie, czego my nie wiemy ;)
      • 2: CommentAuthortebe
      • CommentTime3 Dec 2019 11:12
       
      świetnie sobie radzicie :)
      • 3: CommentAuthorkski
      • CommentTime3 Dec 2019 11:12
       
      ok nie ma problemu
      • 4:
         
        CommentAuthorgalu
      • CommentTime3 Dec 2019 13:12 zmieniony
       
      Skończyła mi się pamięć i dopiero zacząłem "optymalizować" program (przypomnę - przeniesiony z Javy). Na początek widzę, że każdorazowe odpytanie tablicy 2D [0..5][0..9] to aż 19 bajtów, więc w konstrukcji w rodzaju if (costam[y][x]=A) or (costam[y][x]=B) or (costam[y][x]=C) strata pamięci i czasu procesora była oczywista.
      A czy samo odczytanie wartości z tablicy i przypisanie nowej - jak na tym przykładzie - można załatwić w jakiś lepszy sposób?
      if (blockTimer[y][x] = BT_NULL) then blockTimer[y][x] := BT_TRIGGER;
      • 5: CommentAuthortebe
      • CommentTime3 Dec 2019 17:12
       
      sprawdziłeś kompilując z najnowszą wersją ?

      ->link<-
      • 6:
         
        CommentAuthorgalu
      • CommentTime3 Dec 2019 19:12
       
      Wynikowy XEX o 1,5KB mniejszy (plik 33KB, CODE: $2000..$6A96). Czy jest możliwe, że kod szybciej się wykonuje?
      Dzięki!
      • 7: CommentAuthortebe
      • CommentTime3 Dec 2019 20:12
       
      krótszy kod szybciej się wykonuje
      • 8:
         
        CommentAuthorgalu
      • CommentTime4 Dec 2019 17:12
       
      Przy okazji (nie wiem czy to jest zamierzone):

      const INDX_0 = 40;
      Test(10);


      procedure Test(offset : byte);
      begin
      CRT_Goto(INDX_0 + 123 + 20 + offset);
      end;


      34884 bytes written to the object file

      procedure Test(offset : byte);
      begin
      CRT_Goto(INDX_0 + 143 + offset);
      end;


      34874 bytes written to the object file

      procedure Test(offset : byte);
      begin
      CRT_Goto(183 + offset);
      end;


      34864 bytes written to the object file
      • 9: CommentAuthortebe
      • CommentTime4 Dec 2019 18:12
       
      nie wiem skąd jest CRT_GOTO. W bibliotece BLIBS jest moduł B_CRT, tam jest procedura CRT_GOTOXY(a,b)

      może umieść kompletny fragment programu
      • 10: CommentAuthorkski
      • CommentTime5 Dec 2019 10:12 zmieniony
       
      Czy zrobienie loadera wyświetlającego obrazek z Atari Graphics Studio i następnie ładującego właściwą grę (Mad Pascal) może być na tyle proste żeby początkujący programista atari nie wiedzący o jeszcze NIC o temacie zrobił to w 1-2 wieczory?
      Może ktoś dysponuje jakimś przykładem lub jest w stanie pomóc? Chodzi o Alberta.
      • 11: CommentAuthortebe
      • CommentTime5 Dec 2019 11:12
       
      nowe wersje Graph2Font zapisują plik *.PAS z obrazkiem (MODE = DLI), tryb znakowy jest możliwy podczas transmisji pod warunkiem że wszystko zmieści się w jednym zestawie znaków

      AGS (Atari Graphics Studio) może być prostsze bo to tylko tryby bitmapowe, chyba że ma jeszcze mrugać interlace

      przykłady wczytania obrazka i jego wyświetlenia dla MIC, PIC są w przykładach MP
      • 12: CommentAuthorMADRAFi
      • CommentTime5 Dec 2019 11:12
       
      Jestem ciekaw odpowiedzi na temat loaderea :)
      Mialem ten sam problem :)
      • 13: CommentAuthorkski
      • CommentTime5 Dec 2019 11:12
       
      Ok, popatrzę na przykłady, pytanie jak zrobić z tego loadera który wyświetla obrazek, czeka na naciśnięcie klawisza i dopiero ładuje grę. Sam albert to plik 38 kb i tam już obrazka nie wcisnę. Albo inaczej, ładuje go do pamięci pod os'a, skąd mogę wyświetlić przed pierwszym rozpoczęciem gry.
      W swoim czasie oczywiście sam nad tym posiedzę, ale pytam na szybko może coś ktoś robił i udało by się przed SV.

      Madrafi rozwiązałeś problem xBiosem? Jakieś sugestie które mogłyby mi pomóc?
      • 14: CommentAuthortebe
      • CommentTime5 Dec 2019 13:12
       
      czegoś takiego jak "splash screen" w MP nie ma, tworzysz blok wykonywalny, zmieniasz mu RUN na INI i łączysz ze swoim głównym programem

      kolejne bloki które będą ładowane do pamięci muszą omijać obszar pamięci która jest wykorzystywana do wyświetlenia obrazka, dlatego oszczędniej wypadają tryby znakowe, równie dobrze może to być ATASCII art

      G2F ma opcję zamiany bitmapy na kody znaków ATASCII
      • 15: CommentAuthorkski
      • CommentTime5 Dec 2019 14:12
       
      nie ma pamięci na dołączenie go do mojego programu... Chodzi więc o to żeby go załadować, pokazać, a potem olać - może zniknąć podczas ładowania głównego programu, lub żeby załadować pod os'a (też zniknie po pierwszym uruchomieniu gry).
      • 16:
         
        CommentAuthorgalu
      • CommentTime5 Dec 2019 20:12 zmieniony
       
      @tebe: Faktycznie - procedura (niepotrzebna) dopisana przeze mnie - przyjmuje inta zamiast pary bajtów (czy choćby smallinta).

      procedure CRT_Goto(offset : integer);
      begin
      CRT_cursor := CRT_vram + offset;
      end;
      • 17: CommentAuthortebe
      • CommentTime5 Dec 2019 21:12
       
      const INDX_0 = 40;

      var CRT_cursor, CRT_vram: word;

      procedure CRT_Goto(offset : integer);
      begin
      CRT_cursor := CRT_vram + offset;
      end;

      procedure Test(offset : byte);
      begin
      CRT_Goto(INDX_0 + 123 + 20 + offset);
      end;

      begin

      Test(10);

      end.


      261 bajtów

      gdy asemblujesz mads-em, istotny jest parametr -x, który usuwa procedury do których nie nastąpiło odwołanie
      • 18: CommentAuthorkski
      • CommentTime5 Dec 2019 22:12 zmieniony
       
      No i okazało się proste to o co prosiłem, poniżej z xbiosem, ale za chwilę sprawdzę "normalnego" dosa. Najpierw uruchamia się intro, po naciśnięciu klawisza wraca do loadera i ładuje grę. Loader i intro nie używają tej samej pamięci. W momencie jak ładowana gra zacznie pisac po pamięci obraziu będą śmieci dlatego umieściłem ją (pamięć obrazu) najdalej.

      program albert;
      uses xbios;
      var
      path1: TString = 'INTRO XEX';
      path2: TString = 'MAIN XEX';

      begin
      xBiosOpenFile(path1);
      if xBiosIOresult <> 0 then Writeln('IOerror: ', xBiosIOerror)
      else xBiosLoadBinaryFile;

      xBiosOpenFile(path2);
      if xBiosIOresult <> 0 then Writeln('IOerror: ', xBiosIOerror)
      else xBiosLoadBinaryFile;
      end.
      • 19: CommentAuthorkski
      • CommentTime6 Dec 2019 13:12 zmieniony
       
      Mały update, dzięki pomocy Yolka i Integratorowi Larka, zamiana RUN na INIT i połączenie dwóch xex'ów (o czym pisał wyżej Tebe, tylko potrzeba najpierw troszkę wiedzy żeby zrozumieć) okazała się najlepszym rozwiązaniem do wyświetlenia obrazka przed załadowaniem gry - powstaje xex łatwiejszy w obsłudze niż atr w przypadku historii z dosami/xbiosami. A Ci którzy będą jutro na SV zobaczą efekt.
      • 20: CommentAuthorMADRAFi
      • CommentTime7 Dec 2019 11:12
       
      To co pisalem.
      Ale fajnie by bylo jakbys zrobil opis i tutaj wkleil. Przyda sie tez innym :)
      • 21: CommentAuthorxxl
      • CommentTime7 Dec 2019 11:12
       
      zapisujesz w g2f obrazek przez export xex format. zmieniasz ostatni blok z RUN na INI. kodlejasz do swojego kodu na POCZATKU i tyle.
      • 22: CommentAuthorMADRAFi
      • CommentTime7 Dec 2019 11:12
       
      Kluczowe jest to jak w gotowym juz pliku XEX zmienic ten blok :)
      • 23: CommentAuthortebe
      • CommentTime7 Dec 2019 12:12
       
      Graph2Font, przechodzimy do zakładki Special -> Options -> ASM file, zaznaczamy INI zamiast RUN

      innym sposobem jest użycie Super Packera, można blok RUN zmienić na INI, można usuwać, łączyć, dodawać bloki
      • 24: CommentAuthorMADRAFi
      • CommentTime7 Dec 2019 12:12
       
      no i git!
      • 25: CommentAuthorkski
      • CommentTime7 Dec 2019 22:12
       
      no i trzeba było tak od razu
      • 26: CommentAuthornosty
      • CommentTime31 Dec 2019 11:12 zmieniony
       
      Zachęcony na SV przez Bociana zrobiłem podejście do MadPascala. Zbudowałem środowisko, zacząłem analizować i odpalać przykłady, wszystko bangla pięknie.
      Ale po 1 dniu mam już kilka pierwszych wątpliwości i pytań, (wynikających pewnie z tego, że do pacala podchodzę po doświadczeniach z assemblerem):

      1. Mapa pamięci.
      Nie widzę w przykładach jak decydować gdzie w pamięci ma się znaleźć skompilowany kod. A jeśli nie mam na to wpływu, to nie wiem skąd kompilator wie, które miejsca zarezerwowałem? Albo których obszarów nie powinienem używać na dane czy pamięć ekranu?
      W przykładach są deklaracje takie jak:
      PMGBASE = $C000;
      CHARSET_GAME_ADDRESS = PMGBASE + $400;
      ale to przecież tylko deklaracje stałych.
      Króko mówiąc: jaki jest tu odpowiednik "org" lub jak sobie radzić bez niego, by kod nie wlazł mi na dane?

      2. W przykładach nie znalazłem nic, co by wymuszało synchronizację głównej pętli gry z VBI. Nie wyobrażam sobie jak żyć i animować bez tego? :)
      Tzn wiem oczywiście jak to uzyskać. Nie rozumiem czemu twórcy przykładów o to nie dbają?

      3. Do umieszczania zmiennych w konkretnych miejscach służy zdaje się deklaracja ABSOLUTE. Ale nie widzę by w przykładach ktoś dbał o to by umieszczać zmienne na stronie zerowej. Dlaczego?

      4. Nie rozumiem chyba idei tabeli z jednym elementem:
      levelData: array [0..0] of byte;
      Szczególnie, że wg dokumentacji dostęp do niej jest realizowany w najgorszy możliwy sposób: lda (bp),y
      Dokumentacja pisze, ze jest możliwość relokacji takiej tabeli. Ale po co?
      Z przykładów widzę, że mimo, że jest to tabela jednoelementowa, to następują próby odczytów z indexów innych niż 0, co powinno spowodować błąd.

      Bardzo dziękuję za pomoc!
      • 27:
         
        CommentAuthorbocianu
      • CommentTime31 Dec 2019 11:12
       
      @nosty:

      1:
      Jako tako odpowiednika samego org nie ma. Możemy definiować indywidualnie położenie zmiennych korzystając z "absolute", ale dla kodu (procedur i funkcji) to nie zadziała - tu jesteśmy zdani na kompilator.
      Domyślnie kod kompilowany jest od $2000 i zaraz za nim pakowane są dane. Ile miejsca zajmują widzimy w konsoli podczas kompilacji. Ale można to zmienić przełącznikami kompilatora:
      -code:$address  adres uruchomienia programu
      -data:$address adres pamięci dla zmiennych, tablic
      -stack:$address adres pamięci dla stosu programowego (64 bajty)
      -zpage:$address adres na stronie zerowej dla zmiennych (24 bajty)


      2:
      Wystarczy w głównej pętli dać rozkaz "Pause" i wszystko co damy bezpośrednio za nim powinno sie wykonywać poza okresem rysowania obrazu (oczywiscie o ile nie przesadzimy z długością). To najprostszy sposób.

      3:
      Mi się zdarzało umieszczać zmienne na stronie zerowej korzystając z absolute i to działa. Może słabo szukałeś :D

      4:
      tabela typu [0..0] to tak naprawdę wskaźnik na tablice o dowolnym rozmiarze. Możemy ten wskaźnik dowolnie relokować, przykładowo na dane binarne dołączone w zewnętrznym pliku, żeby wygodniej i bardziej kulturalnie się do nich dobrać.

      Czyli przykładowo dołączamy sobie plik binarny pod adres $6000, deklarujemy tablicę:
      var dane: array [0..0] of byte;

      potem ustawiamy jej lokalizację:
      dane := pointer($6000);

      i wtedy pobieramy kulturalnie dane korzystając z:
      wartosc_danej := dane[index_danej];

      Możemy tez adres tej tabeli przypisać na stałe przez "absolute" przy deklaracji, jeśli nie zamierzamy go już zmieniać.

      Korzystam z tego często - wygodne.
      • 28: CommentAuthortebe
      • CommentTime31 Dec 2019 12:12
       
      ad.1
      domyślny adres ładowania programu to $2000, można to zmienić poprzez parametr -code:hexaddress

      wszystkie informacje dotyczące mapy pamięci pojawiają się na wyjściu

      CODE to nasz program, DATA to zmienne, tablice itd.

      214 lines compiled, 1.01 sec, 5738 tokens, 613 idents, 180 blocks, 7 types
      1 warning(s) issued
      25 note(s) issued
      ZPFREE: $0000..$007F / $00D8..$00FF
      RUNLIB: $20CF..$20D3
      SYSTEM: $20F2..$20F5
      CRT: $20F6..$2109
      CODE: $2000..$215B
      DATA: $215C..$2220


      ad.2
      procedura PAUSE czeka ramkę

      ad.3
      ZPFREE: $0000..$007F / $00D8..$00FF

      obszar $0080..$00D7 MP rezerwuje na swoje potrzeby

      ad.4
      tablica reprezentowana jest przez wskaźnik

      dostęp do tablic które nie przekraczają 256 bajtów jest najszybszy, bo nie jest realizowana przez wskaźnik, wskaźnik jest ignorowany, to taki tryb "absolutny"

      są sytuacje kiedy potrzebujemy zmienić, ustalić nowy adres tablicy, albo nie chcemy podawać rozmiaru takiej tablicy
      podanie rozmiaru tablicy spowoduje zarezerwowanie pamięci
      • 29: CommentAuthornosty
      • CommentTime31 Dec 2019 13:12
       
      Bardzo Wam dziękuję za błyskawiczne odpowiedzi.
      Rozjaśniło mi się znacznie. Dwie wątpliwości:

      Jeszcze a propos strony zerowej:
      "obszar $0080..$00D7 MP rezerwuje na swoje potrzeby"

      a Bocianu opisał (jak widzę, zgodnie z dokumentacją):
      -zpage:$address adres na stronie zerowej dla zmiennych (24 bajty)

      Tymczasem od $80 do $D7 to znacznie więcej niż 24 bajty.

      Czy ilość zajętej przez MP strony zerowej jest zmienna zależnie od programu, czy też dokumentacja dotyczyła wcześniejszej wersji i jest nieaktualna?

      I a propos Pause, żeby mieć pewność:
      Po komendzie Pause program staje aż do najbliższego VBI, czyli zakończenia rysowania ekranu, tak?
      Tak rozumiem wyjaśnienie Bocianu.

      W dokumentacji jest:
      procedure Pause;
      procedure Pause(n: word);
      Zatrzymuje działanie programu na N * 1.50 sek

      Rozumiem literówkę (powinno być zapewne 1/50 sek.), ale to też nie jest zgodne z opisem Bocianiu, bo tu już jednoznacznie jest podany czas pauzy jako wielokrotność 1/50 sek.
      • 30: CommentAuthortebe
      • CommentTime31 Dec 2019 13:12 zmieniony
       
      -stack:address  Software stack hex address (size = 64 bytes)
      -zpage:address Variables on the zero page hex address (size = 24 bytes)


      w sumie 88 bajty na stronie zerowej

      PAUSE (unit SYSTEM)
      procedure Pause; assembler; overload;
      (*
      @description:
      Delay program execution (1/50 second).
      *)
      asm
      { lda:cmp:req :rtclok+2
      };
      end;
      • 31:
         
        CommentAuthorbocianu
      • CommentTime31 Dec 2019 13:12 zmieniony
       
      Opis procedury pause nie jest do końca poprawny :D
      Tak naprawdę to pause czeka na zmianę zawartości rtclok+2
      procedure Pause; assembler; overload;
      (*
      @description:
      Delay program execution (1/50 second).
      *)
      asm
      { lda:cmp:req :rtclok+2
      };
      end;


      I trzeba pamiętać, że nie będzie działała jak wyłączymy OS. No chyba ze sami będziemy sobie inkrementować rtclok co ramkę :)
      • 32: CommentAuthornosty
      • CommentTime31 Dec 2019 15:12
       
      Pięknie.
      W takim razie próbuję przenieść do MP prostą grę, którą zacząłem pisać w asm.
      Szczęśliwego Nowego! :)