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: CommentAuthortebe
      • CommentTime20 Nov 2019 21:11
       
      #47 powodem jest błąd w optymalizacji

      zabrakło jednego zapisu w kodzie wynikowym
      mwa currentplayer :bp2


      następuje zmiana adresu CURRENTPLAYER, po którym powinno wystąpić kolejne załadowanie CURRENTPLAYER do :BP2, ale optymlizator uznaje że do :BP2 było już ładowane CURRENTPLAYER i usuwa ten zapis

      rozwiązanie na chwilę obecną
      program hello;
      uses crt;

      type
      player = record
      gold : smallInt;
      score : cardinal;
      end;

      var
      players : array[0..3] of ^player;
      playerOne : player;
      PlayerTwo : player;
      currentplayer: ^player;
      currentplayer_: ^player;

      begin


      players[0] := @playerOne;
      players[1] := @playerTwo;

      currentplayer := players[0];
      currentplayer.gold := 3;

      currentplayer_ := players[1];
      currentplayer_.gold := 4;

      writeln('1p gold = ', players[0].gold);
      writeln('2p gold = ', players[1].gold);

      ReadKey;
      end.
      • 2: CommentAuthorzbyti
      • CommentTime20 Nov 2019 21:11 zmieniony
       
      @tebe to co poniżej też działa, chociaż piszesz, że jest błąd kompilatora, rozumiem, że po poprawieniu błędu powinno działać także bez daszka:

      program hello;
      uses crt;

      type
      player = record
      gold : smallInt;
      score : cardinal;
      end;

      var
      players : array[0..3] of ^player;
      playerOne : player;
      PlayerTwo : player;
      currentplayer : ^player;

      begin
      players[0] := @playerOne;
      players[1] := @playerTwo;

      currentplayer := players[0];
      currentplayer^.gold := 1;

      currentplayer := players[1];
      currentplayer^.gold := 8;

      writeln('1p gold = ', players[0].gold);
      writeln('2p gold = ', players[1].gold);

      ReadKey;
      end.

      Wcześniej podałem cały kod. Wkleję jr. bo paginacja przerzuca strony.

      Wydaje się, że jest prawidłowo. Więc nie jest potrzebne takie rozbudowane obejście jakie proponujesz.

      currentplayer ma każdorazowo przypisywany właściwy adres pamięci, po dostawieniu daszka pisze danymi tam gdzie trzeba.

      Powyższy kod drukuje spodziewane 1 i 8.

      EDIT: przez to, że ktoś napisał w tym wątku do mnie na PRIV kompletnie nie wiem jak ktoś podaje nr. postu o który mu chodzi :D Starożytne to forum...
      • 3:
         
        CommentAuthorsun
      • CommentTime20 Nov 2019 22:11
       
      to ja się ośmieliłem napisać i popsuć wątek :)
      • 4: CommentAuthorzbyti
      • CommentTime20 Nov 2019 22:11 zmieniony
       
      @sun spoko, nie wiadomo czy osoba która podaje nr. postów podaje je licząc jako niezalogowany, czy też ma rozjazd w numeracji :D a oglądający musi być wylogowany, czyli qpa ;)

      dla pewności trzeba cytować :)
      • 5: CommentAuthortebe
      • CommentTime20 Nov 2019 23:11
       
      MP po poprawce dla optymalizacji :BP2
      ->link<-
      • 6: CommentAuthorzbyti
      • CommentTime20 Nov 2019 23:11 zmieniony
       
      @tebe działa z rekordami ale teraz przestała działać ta konstrukcja a bez tej poprawki działało, albo w tym branche jest coś więcej:

      p1[0]:= Char(peek(chessman) xor invert); Inc(chessman);

      lib/chessgui.pas (45,13) Error: Array type required

      Kod jest tutaj ->link<-
      • 7: CommentAuthortebe
      • CommentTime20 Nov 2019 23:11
       
      przepraszam, kombinuję przy PByte i zapomniałem zmienić

      teraz powinno być OK

      ->link<-
      • 8: CommentAuthorzbyti
      • CommentTime20 Nov 2019 23:11 zmieniony
       
      @tebe teraz wszystko OK, THX :)
      • 9: CommentAuthorMADRAFi
      • CommentTime21 Nov 2019 11:11
       
      taka konstrukcja dziala:

      ship0: TShip;
      ship1: TShip;
      ship2: TShip;

      shipmatrix: array [0..NUMBEROFSHIPS-1] of pointer = (@ship0, @ship1, @ship2);

      tshp : ^TShip;



      tyko potem uzywam to tak:

      tshp:=shipmatrix[0];
      write(tshp^.speed);
      • 10: CommentAuthorzbyti
      • CommentTime21 Nov 2019 11:11 zmieniony
       
      To już nie musisz (po ostatniej poprawce) daszka robić ;)

      program hello;
      uses crt;

      type
      TShip = record
      gold : smallInt;
      speed : cardinal;
      end;

      var
      ship0: TShip;
      ship1: TShip;
      ship2: TShip;

      tshp : ^TShip;

      shipmatrix: array [0..2] of pointer = (@ship0, @ship1, @ship2);

      begin
      ship0.speed := 5;
      ship1.speed := 10;

      tshp := shipmatrix[0];
      writeln(tshp.speed);
      tshp := shipmatrix[1];
      writeln(tshp.speed);

      ReadKey;
      end.
      • 11: CommentAuthorastrofor
      • CommentTime21 Nov 2019 12:11
       
      Mam pytanie
      type
      player = record
      gold : smallInt;
      inventory: TString;
      end;

      var
      players : array[0..3] of ^player;
      playerOne : player;
      PlayerTwo : player;
      currentplayer : ^player;
      weaponName: TString;
      localinv:TString;

      begin
      players[0] := @playerOne;
      players[1] := @playerTwo;

      currentplayer := players[1];
      currentplayer^.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[1] := 'B';
      currentplayer^.inventory := localinv;

      czemu ostatnia linia wywala mi blad : Error: Incompatible types: got "Array[0..32] Of CHAR" expected "Array[0..6] Of RECORD" ?
      • 12: CommentAuthorzbyti
      • CommentTime21 Nov 2019 13:11 zmieniony
       
      Wygląda na błąd kompilatora.

      Możesz zrobić:
      currentplayer^.inventory := @localinv;

      Ale jest to o tyle bez sensu, że ty chcesz przekazać wartość a nie wskaźnik do niej.

      Jak przekażemy wprost := 'jakiś string' to kompilator chwyta, a jak chce się przekazać wartość zmiennej typu string to faktycznie jest niezgodność typów. Pod maską dzieje się coś nie halo.
      • 13: CommentAuthorastrofor
      • CommentTime21 Nov 2019 14:11
       
      @zbyti: Najlepiej jakbym mogl w ogole nie kozystac ze zmiennej localinv tylko bezposrednio przypisywac : currentplayer^.inventory[1] := 'B'; ale takie cudo niestety nie dziala. Chyba ze mozna to napisac jakos inaczej ?
      • 14: CommentAuthorzbyti
      • CommentTime21 Nov 2019 14:11 zmieniony
       
      Według mnie, żeby posługiwać się wygodnie i efektywnie Mad Pascalem należy porzucić paradygmat obiektowy, zagnieżdżanie struktur etc.

      Inventory potraktuj po prostu jaki 8-bit liczbę i wtedy B--- nadaj jakąś wartość.

      currentplayer^.inventory := $0a;

      Albo jakaś podobna idea ;)

      W ten sposób, jak pokombinujesz, to spokojnie sobie zmieścisz co i na której pozycji masz a zaoszczędzisz operacji na stringach i pamięć.
      • 15: CommentAuthorastrofor
      • CommentTime21 Nov 2019 14:11
       
      Pewnie, mozna nawet prosciej i bardziej czytelnie , jakos tak (to nie jest dzialajacy kod tylko idea ):
      singleinvlength = 5;
      allstringlength := numberofplayers*singleinvlength;
      allinventory := String[allstringlength ];
      inventoryitemtochangeindex := 1;
      allinventory[singleinvlength*currentplayerindex + inventoryitemtochangeindex] = 'B';


      Ale kod obiektowy jest czytelniejszy, latwiejszy do rozbudowy(trudniejszy do optymalizacji i zjadajacy wiecej zasobow ;) ), no i chyba jak autorzy mad pascala zalozyli ze beda elementy obiektowe, to milo by to jakos przetestowac i poprawic bugi na ile sie da.
      • 16: CommentAuthorzbyti
      • CommentTime22 Nov 2019 15:11 zmieniony
       
      @astrofor zajrzałem to kodu kompilatora, czy da się coś tam poprawić, ale to nie na moją głowę, samo udanie się w okolice linii powyżej 13K mnie przeraziło :D

      Zastanowiłem się i w Twoim przypadku zadziała stary trick.

      program hello;
      uses crt;

      type
      player = record
      gold : smallInt;
      inventory : TString;
      end;

      var
      players : array[0..3] of ^player;
      playerOne : player;
      PlayerTwo : player;
      currentplayer : ^player;
      weaponName : TString;
      localinv : TString;

      begin
      players[0] := @playerOne;
      players[1] := @playerTwo;

      currentplayer := players[1];
      currentplayer^.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[1] := 'B';
      currentplayer^.inventory := concat('', localinv);

      writeln('1p inventory = ', players[0].inventory);
      writeln('2p inventory = ', players[1].inventory);

      ReadKey;
      end.
      • 17: CommentAuthortebe
      • CommentTime22 Nov 2019 16:11 zmieniony
       
      po poprawce 'patch-04'

      ->link<-
      type
      TString = string[32];

      player = record
      gold : smallInt;
      inventory: TString;
      end;

      var
      players : array[0..3] of ^player;
      playerOne : player;
      PlayerTwo : player;
      currentplayer : ^player;
      weaponName: TString;
      localinv:TString;

      begin
      players[0] := @playerOne;
      players[1] := @playerTwo;

      currentplayer := players[1];
      currentplayer^.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[1] := 'B';
      currentplayer^.inventory := localinv;

      writeln('1p inventory = ', players[0].inventory);
      writeln('2p inventory = ', players[1].inventory);
      • 18: CommentAuthorzbyti
      • CommentTime22 Nov 2019 16:11 zmieniony
       
      @tebe sprawdziłem, poprawka działa, nic innego mi się nie wywaliło przy okazji ;]

      Warto kod używać już z wszystkimi poprawkami;)

      program hello;
      uses crt;

      type
      player = record
      gold : smallInt;
      inventory: TString;
      end;

      var
      players : array[0..3] of ^player;
      playerOne : player;
      PlayerTwo : player;
      currentplayer : ^player;
      weaponName : TString;
      localinv : TString;

      begin
      players[0] := @playerOne;
      players[1] := @playerTwo;

      currentplayer := players[1];
      currentplayer.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[1] := 'B';
      currentplayer.inventory := localinv;

      writeln('1p inventory = ', players[0].inventory);
      writeln('2p inventory = ', players[1].inventory);

      ReadKey;
      end.

      Ciekawe, że daszek musi być w jeszcze jednym miejscu a z innych można się pozbyć:
      localinv := currentplayer^.inventory;
      • 19:
         
        CommentAuthorsun
      • CommentTime22 Nov 2019 21:11
       
      Też przede mną implementacja dość podobna, bo zarówno kieszeń jak i lokacje. Śledzę z uwagą wątek oraz źródła bocianu :)
      • 20: CommentAuthorastrofor
      • CommentTime22 Nov 2019 21:11 zmieniony
       
      To ja jeszcze mam pytanko:
      players[0] := @playerOne;
      players[1] := @playerTwo;
      currentplayer := players[0];
      currentplayer^.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[1] := 'B';
      currentplayer^.inventory := localinv;

      currentplayer := players[1];
      currentplayer^.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[2] := 'C';
      currentplayer^.inventory := localinv;
      currentplayer := players[0];
      localinv := currentplayer^.inventory;
      localinv[3] := 'D';
      currentplayer^.inventory := localinv;
      writeln('inv1 = ', players[1].inventory);
      writeln('inv0 = ', players[0].inventory);

      inv1 : -CD-
      inv0 : -CD-
      powinno być :
      inv1 : --D-
      inv0 : BC--

      acha zalaczylem patch-04
      • 21: CommentAuthorzbyti
      • CommentTime22 Nov 2019 21:11 zmieniony
       
      @astrofor dlaczego nie wklejasz CAŁEGO kodu by go łatwo uruchomić, dlaczego osoba która chce Ci pomóc musi sobie ten kod składać z kawałków? Oszczędzasz miejsce na serwerze? :D

      Jeśli dobrze liczę miejsca w stringu to spodziewany wynik też powinien być inny ;)

      No to wygląda, że słabo testowałem potwierdzając @tebe, że wszystko OK.

      Zostaje w playerach wskazanie na ten sam localinv.
      • 22: CommentAuthorzbyti
      • CommentTime22 Nov 2019 22:11 zmieniony
       
      program hello;
      uses crt;

      type
      player = record
      gold : smallInt;
      inventory : TString;
      end;

      var
      players : array[0..3] of ^player;
      playerOne : player;
      PlayerTwo : player;
      currentplayer : ^player;
      localinv : TString;

      begin
      players[0] := @playerOne;
      players[1] := @playerTwo;

      currentplayer := players[0];
      currentplayer.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[1] := 'B';
      currentplayer.inventory := localinv;
      writeln(word(@currentplayer));
      writeln(localinv);

      writeln('inv1 = ', players[1].inventory);
      writeln('inv0 = ', players[0].inventory);

      currentplayer := players[1];
      currentplayer.inventory := '----';
      localinv := currentplayer^.inventory;
      localinv[2] := 'C';
      currentplayer.inventory := localinv;
      writeln(word(@currentplayer));
      writeln(localinv);

      writeln('inv1 = ', players[1].inventory);
      writeln('inv0 = ', players[0].inventory);

      currentplayer := players[0];
      localinv := currentplayer^.inventory;
      localinv[4] := 'D';
      currentplayer.inventory := localinv;
      writeln(word(@currentplayer));
      writeln(localinv);

      writeln('inv1 = ', players[1].inventory);
      writeln('inv0 = ', players[0].inventory);

      ReadKey;
      end.
      • 23: CommentAuthorzbyti
      • CommentTime22 Nov 2019 23:11 zmieniony
       
      Tak jak należało przypuszczać, teraz widać ponad wszelką wątpliwość.

      // dodane do powyższego kodu
      localinv := '2---';
      currentplayer := players[0];

      writeln('---->', currentplayer^.inventory);

      Widać, że w playerach jest cały czas ten sam wskaźnik na localinv.
      • 24: CommentAuthorzbyti
      • CommentTime23 Nov 2019 01:11 zmieniony
       
      @tebe sorry za wprowadzanie w błąd, jasne, że ostatnie przypisanie się WYKONUJE, tego problemu NIE MA. Tylko wskaźnik w każdym rekordzie jest ten sam.

      Zastanowię się następnym razem 3x zanim coś takiego napiszę ;)

      EDIT: poprzednie posty wyedytowałem by nie wprowadzały w błąd czytającego kiedyś w kolejności te posty.
      • 25:
         
        CommentAuthorgalu
      • CommentTime24 Nov 2019 21:11
       
      Przysiadłem do MP, żeby kończyć gierkę na Silly Venture, ale mam problem. Udało mi się zdiagnozować go następująco: kod zaczął mi nadpisywać dane albo sam siebie.

      Nie korzystam prawie nigdzie z modyfikatora absolute!

      Załóżmy, że wyjściowo wszystko działa, dopisuję w jakiejś funkcji jednego pustego if-a i przy odpaleniu widzę lekko skopany tileset albo inne artefakty wideo / audio.

      Oprócz kodu-instrukcji (już ponad 1000 linii, docelowo więcej) mam importy ze stałymi, głównie stablicowanymi - np. LUT dla animacji postaci, bardzo duża tablica z zakodowaną definicją poziomów (var levelData: array[0..2850] of byte). Oprócz tego: 2 x zestaw znaków, 3 x DL, player CMC + moduł, pamięć obrazu w trybach "znakowych".

      Jak podejść do tego tematu (mam nadzieję, że to jest do szybkiego ogarnięcia :))?
      • 26: CommentAuthortebe
      • CommentTime24 Nov 2019 21:11
       
      może to Display Lista-a, powinna być umieszczona na samy początku programu

      jak kompilujesz z innym adresem -code:xxxx to coś to zmienia ?
      • 27:
         
        CommentAuthorgalu
      • CommentTime24 Nov 2019 22:11 zmieniony
       
      Już widzę, że tak - sprawdziłem z adresem (code) przesuniętym o 100 bajtów i np. gra się "krzaczy" nie od 68 levelu, tylko od 71. Dzięki!

      A jak mam rozumieć "Display Lista-a powinna być umieszczona na samym początku programu"?
      • 28:
         
        CommentAuthorbocianu
      • CommentTime24 Nov 2019 22:11
       
      Galu; a jak i w które miejsca zaciągasz charsety i inne statyczne dane?
      Display listy masz pod jakim adresem?
      Pokaż output z kompilatora też.
      • 29: CommentAuthortebe
      • CommentTime24 Nov 2019 22:11 zmieniony
       
      albo ustalisz stały adres dla DL, albo umieścisz ją jako pierwszą deklarację na początku programu, aby adres był najbliższy $2000 (domyślny adres)

      p.s.
      zbyti, w rekordach na chwilę obecną nie będą działać tablice, string to tablica znaków
      • 30:
         
        CommentAuthorgalu
      • CommentTime24 Nov 2019 23:11
       
      Spróbuję najpierw uporządkować adresy i dopiero wkleję output z mp.exe i ew. dalsze pytania.
      • 31: CommentAuthorzbyti
      • CommentTime24 Nov 2019 23:11
       
      @tebe spoko, ja raczej takich konstrukcji unikam.
      • 32:
         
        CommentAuthorgalu
      • CommentTime25 Nov 2019 09:11
       
      Czy następujące elementy mają się znajdować w obszarze „code”?
      - DLI
      - Charsety
      - pamięć obrazu
      • 33: CommentAuthorMADRAFi
      • CommentTime25 Nov 2019 10:11
       
      @Galu nie,

      Najlepiej gdybys sobie przygotowal XLS z adresami pamieci gdzie co umieszczasz.
      Wszystko co umieszczasz dodatkowo, czyli DLI, zestawy znakow, pamiec obrazu muszisz umiescic poza pamiecia juz uzyta ( poza obszarem ktory pokazal ci MP w kompilacji )
      • 34:
         
        CommentAuthorgalu
      • CommentTime25 Nov 2019 22:11 zmieniony
       
      Dzięki za pomoc! Pozmieniałem adresy i chyba jest już OK + mogę dopisywać kolejne linie kodu.

      Pytanie:
      Pod SDLSTL ustawiam wskaźnik na Display Listę via
      _dlist := word(@dl_xxxx);
      a same Display Listy importuję jako
      const dl_xxxx: array [0..21] of byte = ( [...] );

      Czy można tu użyć modyfikatora absolute? W jaki (inny) sposób wskazać adres pamięci, pod którym kompilator umieści dane Display Listy? Czy jeżeli się nie da tego adresu z góry ustawić to czy odpalając program na prawdziwym Atari zawsze lokalizacja danych w pamięci będzie ta sama (na różnych konfiguracjach i przy kolejnych odpaleniach na tej samej maszynie)? Ja testuję tylko na Altirze i na domyślnych ustawieniach.
      • 35: CommentAuthorMADRAFi
      • CommentTime25 Nov 2019 23:11
       
      Mozesz uzyc display listy zadeklarowanej jako resource

      const
      DISPLAY_LIST_ADDRESS_CONSOLE = $2000;
      TXT_ADDRESS = $8000;

      {$r 'resources.rc'}


      resources.rc
      DISPLAY_LIST_ADDRESS_CONSOLE rcasm 'dlist_console.asm'


      dlist_console.asm
      dl_start
      dta DL_DLI + DL_BLANK8
      dta DL_MODE_40x24T2 + DL_LMS, a(TXT_ADDRESS)
      :22 dta DL_MODE_40x24T2
      dta DL_BLANK1
      dta DL_MODE_40x24T2
      dta DL_JVB, a(dl_start)
      • 36:
         
        CommentAuthorDracon
      • CommentTime25 Nov 2019 23:11
       
      Galu, powodzenia z projektem, ale mam też nadzieję, że w tym roku usprawnisz emu na Androidzie. ;]
      • 37: CommentAuthortebe
      • CommentTime26 Nov 2019 02:11
       
      MP nie generuje kodu relokowalnego, adresy będą takie jakie ustalisz, na każdej maszynie czy emulatorze

      najstarszym sposobem na ustalenie Display Listy jest jej "kradzież", tzn. ustalasz RAMTOP (albo zostawiasz jak jest) i wywołujesz InitGraph, OS oblicza adres dla Display Listy, tworzy ją, rezerwuje pamięć dla obrazu

      teraz wystarczy odczytać adres DL (560,561), oraz adres pamięci obrazu (88,89), możesz DL napisać swoją własną

      na temat MEMTOP (106)
      ->link<-
      • 38: CommentAuthormono
      • CommentTime26 Nov 2019 03:11 zmieniony
       
      Ryzykownym obszarem pamięci na wpakowanie dlisty jest $4000..$7FFF, ponieważ tam pojawia się bank pamięci dodatkowej (jeśli z tej pamięci program korzysta lub program może doczytywać dane z ramdysku :D).
      Rozsądnie byłoby więc umieścić dlistę w obszarze $0000..$3FFF lub $8000..$FFFF, ALE:
      obszar $C000..$FFFF to obszar ROMu systemowego więc jeśli się z niego nie korzysta to jest ok, ale jeśli ROM jest włączany bo np. potrzebujemy skorzystać z CIO, no to pozostaje obszar $0000..$3FFF i $8000..$BFFF.

      Tak więc najstarszy sposób ustalenia adresu dlisty jest nienajgorszy, bo CIO alokuje obszary dlisty i pamięci ekranu tuż pod RAMTOP więc wyglądałoby, że wszystko jest ok, ACZKOLWIEK:

      w przypadku gdy używa się procedur BASIC-a (np. SIN, COS, które nie zmieściły się w ROM-ie pakietu matematycznego w OS), który zajmuje pamięć $A000..$BFFF (lub np. jakiegoś cartridge'a typu RAMCART), to ten obszar odpada. Więc bezpieczny byłby obszar $0000..$3FFF i $8000..$9FFF, ALE:

      jeśli program planuje używać cartridge typu RAMCART lub Weronika (która zajmuje obszar $8000..$BFFF na swoje banki), no to $8000..$BFFF też odpada :/

      Więc w zasadzie pozostaje $0000..$3FFF. ALE:

      jeśli program korzysta z DOS-a, no to zakłada się że będzie on (ten DOS) zajmował obszar $700..$1FFF (stąd minimalny adres ładowania programu ustalony na $2000), więc i tego obszaru warto by unikać.

      W $200..$3FF siedzą zmienne OS-a, w $100..$1FF stos CPU, a w $0000..$00FF strona zerowa, więc też nie bardzo.

      Czyli w najgorszym przypadku pozostaje obszar $2000..$3FFF :D A tam zmieści się przecież tylko pamięć trybu graficznego, ale dlista już się nie zmieści. A gdzie przerwania?

      Same kłopoty :D

      Można jeszcze użyć obszaru $400..$6FF. Tam zazwyczaj zmieści się dlista i jakieś niewielkie przerwania.

      Edit: Warto też pamiętać, że istnieją sterowniki które potrafią zakładać romdyski właśnie w RAMCART-cie (albo ramdyski w pamięci pod ROM-em), a nikt użytkownikowi przecież nie zabroni.

      No chyba, żeby zabronił :)

      Edit 2: Na szczęście i RAMCART i Weronika i BASIC i ROM OS-a można wyłączyć i włączyć, więc przy umiejętnej żonglerce (przełączanie poza momentami kiedy ANTIC ciągnie dane z pamięci potrzebne do wymalowania obrazu, czyli dlist, dane ekranu, sprajty i ewentualnie generator znaków jeśli jest używany tryb tekstowy) można to wszystko pogodzić.

      Edit 3: Aaaaa. Gdyby ktoś chciał włączyć SELF-TEST i coś z niego brać, to on leży w $5000..$57FF.

      Edit 4: Można też spróbować wykryć czy rozszerzenie pamięci jest kompatybilne ze 130XE i ma oddzielne adresowanie pamięci dodatkowej przez ANTIC-a - wtedy obszar $4000..$7FFF wraca do łask (chyba, że trzeba nam tego SELF-TEST-u).

      Edit 5: Rdzeń FX w VBXE mapuje bank MEMACB w $4000..$7FFF, ale za to MEMACA można położyć w dowolnym obszarze pamięci z granulacją $1000 i na dodatek takie okno może mieć rozmiar od 4, 8, 16 lub 32KB.

      Jak tu pisać programy?
      • 39:
         
        CommentAuthorsun
      • CommentTime26 Nov 2019 08:11
       
      Nie da się, a jednak one ciągle powstają ;)
      • 40: CommentAuthormono
      • CommentTime26 Nov 2019 10:11
       
      Tak jest :) "czmiel latać nie ma prawa" :)
      • 41: CommentAuthorxxl
      • CommentTime26 Nov 2019 13:11
       
      jesli chce sie korzystac z systemowego sterownika ekranu S: to trzeba pamietac o kilku bledach OS... przykladowo kasowanie ekranu skasuje pamiec do RAMTOP a nie tyle ile trzeba ;-) - maja rozmach s...ny.
      • 42:
         
        CommentAuthorbocianu
      • CommentTime26 Nov 2019 14:11
       
      O tak! nadziałem się na to w zeszłym tygodniu. Coś mi czyściło pamięć i dopiero debugger i breakpointy w Altirze mi pokazały, ze to OS mi robi. Zrezygnowałem w systemowego czyszczenia ekranu i problem znikł.
      Szkoda że wcześniej nie wiedziałem, straciłem na to ze 2 godziny :D
      • 43: CommentAuthorastrofor
      • CommentTime27 Nov 2019 02:11 zmieniony
       
      Czy da sie jakos rzutowac z pointera , na typowanego pointera ? Mi wywala blad, a logicznie rzecz biorac byloby to mozliwe i bardzo pozyteczne. I dosc dziwna rzecz, uzywajac wartosci z typowanego pointera do obiektu da sie uzyc jego zmiennych, ale metod juz nie .
      program hello;
      uses crt;


      Type
      DrawingObject = Object
      x, y : byte;
      procedure InitDefaultValues;
      end;
      Rectanglep = ^DrawingObject;

      procedure DrawingObject.InitDefaultValues;
      begin
      x:=2;
      y:=1;
      end;


      Var
      Rectangle : DrawingObject;
      Rectanglepv:Rectanglep;
      ppoiner:pointer;

      begin
      Rectangle.InitDefaultValues;
      ppoiner:=@Rectangle;
      Rectanglepv:=@Rectangle;
      //Rectanglepv:=Rectanglep(ppoiner); {Illegal type conversion: // "POINTER" to //"RECTANGLEP"}
      // secound
      write(Rectanglepv^.x);
      Rectanglepv^.InitDefaultValues; {identifier idents no member 'INITDEFAULTVALUES'}

      ReadKey;
      end.

      • 44: CommentAuthorilmenit
      • CommentTime27 Nov 2019 08:11
       
      Jak dobrze wygląda kod wygenerowany z MadPascala, gdy są używane rekordy i wskaźniki. W CC65 (przy structs) koszmarnie w porównaniu z wykorzystaniem tablic - kod generowany jest kilkukrotnie większy i wolniejszy ->link<-
      • 45: CommentAuthorastrofor
      • CommentTime27 Nov 2019 13:11
       
      Na pewno będzie to wolniejsze. Natomiast w niektórych zastosowaniach. Np. tekstówki(i pewnie tylko tekstówki), nie ma to aż takiego znaczenia, natomiast zapewnia o wiele czytelniejszy kod dla ludzi umiarkowanie zwązanymi z hardcorowym programowaniem atari, oraz o wiele szersze spektrum możliwości.
      • 46:
         
        CommentAuthorgalu
      • CommentTime1 Dec 2019 13:12 zmieniony
       
      Mam kolejne pytanie o składnię (lub możliwości kompilatora) bo nie mogę sie dokopać informacji:

      var p_data: array[0..3] of pointer;
      var p0DataS : array [0..4] of byte = (0,0,0,0,0);


      O ile mogę użyć indeksu z tej drugiej tablicy podczas przypisania wskaźnika, np. p_data[0]:=@p0DataS[2] o tyle nie wiem jak mogę wskazać indeks gdy wcześniej ustawiłem wskaźnik w ten sposób (w jaki sposób przekazać wskaźnik np. trzeci element tablicy wskazywanej przez p_data[0]):
      p_data[0]:=@p0DataS;

      Chodzi o użycie instrukcji move w procedurze kopiującej dane PMG do pamięci - chciałbym w łatwy sposób obsłużyć sytuację, w której postać częściowo nachodzi na górną krawędź ekranu.

      procedure moveP(p, x, y, pmax : byte);
      begin
      // vpos
      move(p_data[p], pointer(pm_mem + pm_offset + pm_size * p + y), pmax);
      // hpos
      Poke(53248 + p, x);
      end;
      • 47:
         
        CommentAuthorgalu
      • CommentTime2 Dec 2019 21:12 zmieniony
       
      Odpowiem sam sobie, działająca składnia to:
      var p_data: array[0..3] of pointer;
      var p0DataS : array [0..4] of byte = (0, 0, 0, 0, 0);
      ...
      p_data[0] := @p0DataS;
      ...
      ...
      ...
      var z : ^byte;
      ...
      z := p_data[p];
      inc(z);
      • 48: CommentAuthorkski
      • CommentTime3 Dec 2019 10:12
       
      Czy można wymusić na kompilatorze żeby (pozornie) nieużywane funkcje zostały skompilowane do pliku wynikowego?
      • 49:
         
        CommentAuthorbocianu
      • CommentTime3 Dec 2019 10:12 zmieniony
       
      kski: można :D.
      Wystarczy wywołania do nich umieścić w jakimś fragmencie kodu który się nigdy nie wykona. Robiłem tak w PacMad, zobacz koniec tego pliku:

      ->link<-

      Wywołania procek są za rozkazem rti
      • 50: CommentAuthorkski
      • CommentTime3 Dec 2019 10:12
       
      dzięki, podobnie robiłem
      if false then
      begin
      proc1;
      proc2;
      ...
      end

      tyle że każde nieużyte wywołanie to jakieś tam bajty zajęte, wcale nie tak mało, więc dlatego pytam