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
     
    #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 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
     
    to ja się ośmieliłem napisać i popsuć wątek :)
    • 4: CommentAuthorzbyti
    • CommentTime20 Nov 2019 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
     
    MP po poprawce dla optymalizacji :BP2
    ->link<-
    • 6: CommentAuthorzbyti
    • CommentTime20 Nov 2019 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
     
    przepraszam, kombinuję przy PByte i zapomniałem zmienić

    teraz powinno być OK

    ->link<-
    • 8: CommentAuthorzbyti
    • CommentTime20 Nov 2019 zmieniony
     
    @tebe teraz wszystko OK, THX :)
    • 9: CommentAuthorMADRAFi
    • CommentTime21 Nov 2019
     
    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 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
     
    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 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
     
    @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 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
     
    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 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 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 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
     
    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 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 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 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 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 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
     
    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
     
    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 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
     
    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 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
     
    Spróbuję najpierw uporządkować adresy i dopiero wkleję output z mp.exe i ew. dalsze pytania.
    • 31: CommentAuthorzbyti
    • CommentTime24 Nov 2019
     
    @tebe spoko, ja raczej takich konstrukcji unikam.
    • 32:
       
      CommentAuthorgalu
    • CommentTime25 Nov 2019
     
    Czy następujące elementy mają się znajdować w obszarze „code”?
    - DLI
    - Charsety
    - pamięć obrazu
    • 33: CommentAuthorMADRAFi
    • CommentTime25 Nov 2019
     
    @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 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
     
    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
     
    Galu, powodzenia z projektem, ale mam też nadzieję, że w tym roku usprawnisz emu na Androidzie. ;]
    • 37: CommentAuthortebe
    • CommentTime26 Nov 2019
     
    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 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
     
    Nie da się, a jednak one ciągle powstają ;)
    • 40: CommentAuthormono
    • CommentTime26 Nov 2019
     
    Tak jest :) "czmiel latać nie ma prawa" :)
    • 41: CommentAuthorxxl
    • CommentTime26 Nov 2019
     
    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
     
    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 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
     
    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
     
    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 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 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
     
    Czy można wymusić na kompilatorze żeby (pozornie) nieużywane funkcje zostały skompilowane do pliku wynikowego?
    • 49:
       
      CommentAuthorbocianu
    • CommentTime3 Dec 2019 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
     
    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