atarionline.pl Mad Pascal. Fine scroll + PMG (plus początki w c) - 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: CommentAuthorPecet
      • CommentTime22 Jul 2018 12:07 zmieniony
       
      Cześć,
      zacząłem się uczyć c. Udało mi się narysować takie kolorowe bary od lewej do prawej w gr.15. Tylko, że zanim cały ekran sie wypełni mija trochę czasu. Pomysł jest taki, żeby podmienić adres pamięci ekranu, pamięć właściwą wypełnić czym trzeba i jak będzie gotowe, to podmienić adres ekranu z powrotem i wyświetlić.

      #include<atari.h>
      #include<stdio.h>
      #include<peekpoke.h>

      int main(void) {
      unsigned char loop;
      unsigned char loop2;
      unsigned char *video_ptr;
      unsigned *dli_ptr;
      unsigned row;

      _graphics(15);
      video_ptr=(unsigned char*)(PEEKW( PEEKW(560)+4));
      dli_ptr=(unsigned*)(PEEKW(560));
      POKEW(dli_ptr[4],0x3000);

      for (loop2=0;loop2<160;loop2+=1) {
      row = loop2*40;
      for(loop=0;loop<40;loop++)
      video_ptr[row+loop]=108;
      }

      POKEW(dli_ptr[4],video_ptr);
      //printf(", %d",video_ptr[0]);
      return 0;
      }


      I teraz tak, w komórkach 560 i 561 mamy mlodszy i starszy bajt adresu Display listy. Display Lista jest tak skonstruowana, że pierwsze 3 linie (czyli indeksy 0, 1, 2) to puste linie, potem mamy load memory scan (indeks 3) a następne dwa bajty (czyli indeks 4 i 5) to... no właśnie pierwsze pytanie co tam jest? Bo według mnie jest to wskażnik do adresu pamięci ekranu. A nie sam adres. Zgadza się?
      Co próbuję zrobić dalej, to wpisać pod ten wskaźnik nową wartość (0x3000), potem wypełniam "stary" ekran i na końcu poprzez POKEW zamieniam ponownie adresy.
      Oczywiście to nie dziala. Pomijam na razie co się znajduje w pamięci pod adresem 0x3000 (pewnie jakieś smieci). Chodzi o to, że nadal widać jak ekran się rysuje.
      Naprowadźcie mnie proszę, gdzie robię błąd. Bo już nie ogarniam.
      • 2: CommentAuthorantrykot
      • CommentTime22 Jul 2018 13:07 zmieniony
       
      Po pierwsze, display list w gr.15 ma w dwóch miejscach instrukcje ładujące adres danych do wyświetlenia. Jak zmienisz tylko w jednym miejscu, to zniknie tylko górna część obrazu.

      A po drugie, dli_ptr jest typu unsigned* więc dli_ptr[4] to nie jest piąty bajt display listy, ale bajty dziewiąty i dziesiąty. Zmień typ dli_ptr na unsigned char*, a poke rób tak: POKEW(dli_ptr + 4, 0x3000);
      • 3:
         
        CommentAuthorbocianu
      • CommentTime22 Jul 2018 13:07
       
      Na pierwszy rzut oka to dli_ptr powinien być wskaźnikiem na typ Word.
      Po drugie zamieniłbym mnożenie *40 na cykliczne dodawanie tej wartości do row. Powinno zauważalnie przyspieszyć.

      Ekran też da się wyłączyć prościej za pomocą rejestru sdmctl. Nie trzeba się bawić w modyfikacje dl ;)
      • 4: CommentAuthorPecet
      • CommentTime22 Jul 2018 15:07
       
      Ok, dzięki panowie. Zrobiłem tak i śmiga (zgodnie z tym co napisał antrykot, tylko górna połowa ekranu jest zamazana śmieciami spod adresu 0x3000, ale chodzi o sprawdzenie samego mechanizmu).
      #include<atari.h>
      #include<stdio.h>
      #include<peekpoke.h>

      int main(void) {
      unsigned row;
      unsigned char loop;
      unsigned char loop2;
      unsigned char *video_ptr;
      unsigned dl_addr;

      _graphics(15);
      video_ptr=(unsigned char*)(PEEKW( PEEKW(560)+4));
      //POKE(559,0); //turn ANTIC off, screen goes black
      dl_addr=(unsigned)(PEEKW(560));
      POKEW(dl_addr+4,0x3000);

      for (loop2=0;loop2<160;loop2++) {
      row = loop2*40;
      for(loop=0;loop<40;loop++){
      video_ptr[row+loop]=108;
      }
      }
      //POKE(559,34); //turn ANTIC ON, and display graphics
      POKEW(dl_addr+4,(unsigned)video_ptr);
      return 0;
      }


      porada bociana oczywiście też bardzo dobra (dwie zakomentowane linie z POKE, rozwiązuje to sprawę dla całego ekranu).
      Pytanie, gdzie mogę poczytać o podzielonej Display List dla gr.15.

      Druga sprawa, to linię:
      row = loop2*40;

      mogę zastąpić przez:
      row=loop2<<5;
      row+=loop2<<3;

      ale tak:
      row= loop2<<5 + loop2<<3;

      już nie zadziała - wartości robią zbyt duże. Dlaczego?
      • 5:
         
        CommentAuthorbocianu
      • CommentTime22 Jul 2018 16:07 zmieniony
       
      To że druga wersja nie działa, to może być wina kolejności działan w kompilatorze. Spróbuj dać nawiasy.

      A ja bym dał tak jak mówiłem:

      row += 40;

      To najszybsza opcja.

      ->link<-

      A tutaj znajdziesz informacje dlaczego liniowy obszar pamięci obrazy nie może mieć więcej niż 4kb (w opisie rozkazu LMS)
      • 6: CommentAuthorPecet
      • CommentTime22 Jul 2018 19:07
       
      Dzięki.
      Ogólnie rozjaśniło mi się parę rzeczy, szczególnie jeśli chodzi o wskaźniki.
    1.  

      bocianu:

      To że druga wersja nie działa, to może być wina kolejności działan w kompilatorze.

      A dokładniej to w języku, nie w kompilatorze :)

      row= loop2<<5 + loop2<<3;

      oznacza dokładnie to samo co:
      row= loop2<<(5 + loop2)<<3;


      + ma w C większy priorytet niż <<.
      O małą pipkę, ale jednak większy :)
      • 8:
         
        CommentAuthorbocianu
      • CommentTime22 Jul 2018 21:07
       
      @inż: masz rację - to cecha języka, z której wynika działanie kompilatora ;) poleciałem skrótem myślowym.

      Co ciekawe, już w Pascalu operacje przesunięć bitowych mają wyższy priorytet niż dodawanie. I też o pipkę.
      • 9: CommentAuthorPecet
      • CommentTime30 Jul 2018 21:07
       
      oki, mam kolejne pytanko.

      mam 3 pliki

      //plik: myLib.h
      #ifndef __MY_LIB_H
      #define __MY_LIB_H

      unsigned char var;
      unsigned char setVar(unsigned char v);
      #endif


      //plik: myLib.c
      #include "myLib.h"

      unsigned char setVar(unsigned char v) {
      var=v;
      return var;
      }


      //plik: main.c
      #include "myLib.h"
      #include <stdio.h>

      int main(void) {
      printf("value: %d",setVar(3));
      return 0;
      }


      i do tego mam batcha
      cl65 -t atari -c myLib.c
      cl65 -t atari -c main.c
      cl65 -O -t atari -o main.xex myLib.o main.o
      pause


      działa, ale dostaję taki komunikat:
      ld65.exe: Warning: Duplicate external identifier: `_var'


      pytanie, jak pozbyć się tego ostrzeżenia.
      • 10: CommentAuthorbob_er
      • CommentTime30 Jul 2018 22:07
       
      W pliku .h nie powinieneś instancjonować obiektów.
      Zatem z pliku myLib.h wywal linię "unsigned char var;" i dodaj ją do pliku .C.
      • 11: CommentAuthorbob_er
      • CommentTime30 Jul 2018 22:07
       
      Jeszcze dwie uwagi ogólne:
      1. Zgodnie ze standardem, guardy (#ifdefy w H) nie powinny się zaczynać od '_'.
      2. Na wypadek, gdybyś kiedyś kod chciał przenieść na inny kompilator/platformę, wygodnie jest zrobić sobie serię #typedefów definiujących podstawowe typy, np. uint8_t, uint16_t. Zwłaszcza dla 'int' który jest zdefiniowany bardzo ogólnie.
      • 12: CommentAuthorPecet
      • CommentTime30 Jul 2018 22:07
       
      dzięki za porady.
      poszedłem tym tropem (zmienne w nagłówkach) i przypomniałem sobie o extern.

      wygląda na to, że dodanie extern w nagłowku
      extern unsigned char var;


      oraz dodanie linii w pliku myLib.c
      unsigned char var;


      rozwiązuje problem.
      • 13: CommentAuthorilmenit
      • CommentTime1 Aug 2018 15:08
       
      Kiedyś napisałem krótki kurs pisania w C na Atari, może będzie przydatny:
      ->link<-
      • 14: CommentAuthorPecet
      • CommentTime16 Aug 2018 17:08
       
      Mam kolejny problem. Próbuje użyć TGI. Kod wygląda tak:
      #include <peekpoke.h>
      #include <stdio.h>
      #include <atari.h>
      #include <tgi.h>


      extern char atrx15;
      char c[30];

      int main(void) {
      unsigned char errCode;
      _graphics(15);
      tgi_install(&atrx15);
      errCode = tgi_geterror();
      printf("error code: %d, message: %s \n",errCode, tgi_geterrormsg(errCode));
      gets(c);
      tgi_init();
      errCode = tgi_geterror();
      printf("error code: %d, message: %s \n",errCode, tgi_geterrormsg(errCode));
      gets(c);
      tgi_setcolor(COLOR_BLACK);
      tgi_clear();
      tgi_outtext("Ala spirala");
      tgi_line (1, 1, 20, 20);
      printf("%u",tgi_getmaxx());
      return 0;
      }


      driver atrx15.tgi znajduje się w tym samym katalogu co źródło.

      kompilowane/linkowane jest tak:
      co65 --code-label _atrx15 atrx15.tgi
      ca65 atrx15.s
      cl65 -C atarixl.cfg -O -t atarixl tgi_test.c atrx15.s -o tgi_test.xex
      pause


      I teraz tak, z tego co widzę ataryna włącza gr.15, wypisuje brak błędów po tgi_install, potem wraca do gr.0 (?), brak błędów po tgi_init i potem czyści ekran i koniec.

      atarixl.cfg ma zmienioną jedną linie tzn.
      FEATURES {
      STARTADDRESS: default = $3000;
      }


      Jakieś pomysły? Fakt, że mam przeskok z gr.15 do gr.0 wg. mnie wskazuje, że coś źle skonfigurowałem.
      • 15: CommentAuthorbob_er
      • CommentTime16 Aug 2018 21:08
       
      Się nie znam na tgi nie wiem również jak dokładnie działa gets(), ale daj może gdzieś tam jakąś pętlę nieskonczoną.
      Może program po prostu szybko się kończy?
      • 16: CommentAuthorPecet
      • CommentTime17 Aug 2018 07:08
       
      nie, to nie to.
      Chyba szybciej zrobie swoj wlasny algorytm na linie, niz rozgryze o co jest kaman. Tylko pewnie i tak predzej, czy pozniej ten problem ugryzie mnie ponownie w tylek :\
      • 17:
         
        CommentAuthorbocianu
      • CommentTime17 Aug 2018 11:08
       
      A jesteś bardzo zafiksowany na C? Bo jak koniecznie chcesz pisać na Atari w czymś innym niż assembler, to Mad-Pascal nadaje się lepiej. Wiem o czym mówię, bo pisałem i w C65 i w assemblerze :D

      Pozdrawiam ;)
      • 18: CommentAuthorPecet
      • CommentTime17 Aug 2018 11:08
       
      a mozesz tak w skrocie powiedziec w czym mad-pascal jest lepszy od cc65? Ja generalnie bardzo lubie skladnie c.
      No i nie ukrywam, ze drazni mnie ten moj nierozwiazany problem z TGI w c65. Pewnie jakas drobna pierdola, ktorej nie widze:)
    2.  
      Pa na to :)

      Najpierw install(), potem init() [który przywraca tryb 0], potem _graphics() i dopiero potem lecimy z koksem :)



      #include "peekpoke.h"
      #include "stdio.h"
      #include "atari.h"
      #include "tgi.h"


      extern char atrx15;
      char c[30];

      int main(void) {
      unsigned char errCode;
      tgi_install(&atrx15);
      tgi_init();
      _graphics(15);
      errCode = tgi_geterror();
      printf("error code: %d, message: %s \n",errCode, tgi_geterrormsg(errCode));
      gets(c);
      tgi_clear();
      tgi_gotoxy(40,40);
      tgi_outtext("Ala spirala");
      tgi_line (1, 1, 20, 20);
      printf("tgi_getmax()=%u",tgi_getmaxx());
      for(;;);
      return 0;
      }
      • 20: CommentAuthorPecet
      • CommentTime17 Aug 2018 12:08
       
      ja pier..., wiedzialem, ze to jakas pierdola.

      Dziekuje bardzo:)
      powiedz mi jeszcze, prosze, skad wiedziales, ze trzeba to zrobic wlasnie w takiej kolejnosci? Moze mi to oszczedzic troche siwych wlosow w przyszlosci:)
    3.  
      Educated guess :)
      • 22:
         
        CommentAuthorbocianu
      • CommentTime17 Aug 2018 12:08 zmieniony
       
      "a mozesz tak w skrocie powiedziec w czym mad-pascal jest lepszy od cc65?"

      - ma już sporo bibliotek sprofilowanych pod atari
      - potrafi korzystać z pamieci rozszezonej, VBXE, Sparta dos
      - jest juz sporo przykładów i kilka gier z udostepnionymi źródłami
      - ma więcej typów zmiennych (w tym 32 bitowy cardinal i float)
      - kod wynikowy jest lepiej zoptymalizowany (szybszy)
      - nie trzeba grzebać w konfiguracji linkera jak chcesz dołączać zewnętrzne zasoby
      - umożliwia łatwe mieszanie go z assemblerem (inline)
      - i przede wszystkim jest wciąż rozwijany.

      Ja tez wolę składnię C, do szału doprowadzaja mnie pascalowe przypisania ":=", ale powyższe argumenty powodują, że jednak lepiej i szybciej mi się w nim pisze.
      • 23:
         
        CommentAuthormav
      • CommentTime17 Aug 2018 12:08
       
      Istnieje jakaś paczka, którą po prostu wypakuję i będę mógł używać
      i po prostu jakieś wprowadzenie, które da się zrozumieć? :)
      • 24: CommentAuthorPecet
      • CommentTime17 Aug 2018 12:08
       
      dziekuje panowie za odpowiedzi:)
      zerkne przy okazji na pascala, moze rzeczywiscie to bedzie lepszy wybor.
      • 25:
         
        CommentAuthorbocianu
      • CommentTime17 Aug 2018 13:08
       
      Nie istnieje taka paczka z Mad-Pascale, ale może sie kiedyś pokuszę o spreparowanie ;)

      Tymczasem zrobiłem takie małe wprowadzenie:
    4.  
      Rozdział 1?
      • 27: CommentAuthorPecet
      • CommentTime17 Aug 2018 14:08
       
      o, swietny poradnik, nawet jezeli nie bede pisal w mad pascalu, to skorzystam ze wskazowek tworzenia plikow bat. Edytor tez zobacze, moze bedzie wygodniejszy niz notepad++.
      • 28:
         
        CommentAuthorbocianu
      • CommentTime17 Aug 2018 14:08
       
      @mgr. tak, zwykle numerację zaczyna się od 1 :D
      • 29: CommentAuthorPecet
      • CommentTime17 Aug 2018 15:08
       
      to pewnie bylo pytanie o to, czy poradnik bedzie kontynuowany:)
    5.  

      bocianu:

      tak, zwykle numerację zaczyna się od 1


      Chyba w Pascalu :>
      • 31:
         
        CommentAuthorbocianu
      • CommentTime17 Aug 2018 15:08
       
      @mgr: no dobra. Wygrałeś :D
      @pecet: tak, mam już kolejne 4 rozdziały i ambitny plan napisania następnych.
    6.  
      Cool!
      Zamawiam egzemplarz :)
    7.  
      A tak na marginesie... Pecet, mam nadzieję, że pociągniesz temat, bo "Ala spirala" świetnie nadaje się na tytuł oryginalnej gry :)
      • 34: CommentAuthorPecet
      • CommentTime17 Aug 2018 20:08
       
      Mówisz, że to dobry tytuł? No w sumie, można z tego zrobić jakiegoś klona Giany;)
      Generalnie jeśli chodzi o Atari, to mam traumę z dzieciństwa. Nic nie ujmując polskim twórcom gier z przełomu lat 80 i 90, to jednak sporo tytułów było dość miernych jeśli chodzi o kolorystykę. Wiecie, często w zasadzie 1 kolor w 4 odcieniach (albo coś w tym stylu) w głownym polu gry, pod tym przerwanie i jakieś pole z energią, przedmiotami itd. już z zupełnie inna paletą.
      W skrócie brakuje mi kolorowych gier na atarynę. Więc na początek zrobiłem taki mockup.
      No, a potem to zacząłem uczyć się programowania:) Ale jak widać jeszcze długa droga przede mną. Na razie myślę o czymś prostszym, jakiś tunel pseudo 3d animowany przez rotację palety, do tego powiększające się sprity, które trzeba by omijać. Taki endless runner tylko w czyde.
      • 35:
         
        CommentAuthorplyr0
      • CommentTime30 Oct 2018 12:10
       
      Bocianu, czy ten pierwszy rozdział jest jeszcze dostępny? Bo jak pobieram załącznik to ma 0 bajtów.
      • 36: CommentAuthorPecet
      • CommentTime30 Oct 2018 13:10
       
      U mnie jest tak samo, na szczescie mialem jeszcze na dysku.
      • 37:
         
        CommentAuthorbocianu
      • CommentTime30 Oct 2018 16:10 zmieniony
       
      no coś nie tak jest z forum - obcięło załącznik :/
      spróbuje dodać jeszcze raz:
      • 38:
         
        CommentAuthorCOR/ira4
      • CommentTime30 Oct 2018 19:10
       
      @ Pecet
      Fajnie , widzę że chcesz coś wnieść , trzymam kciuki .
      Pobaw się edytorem znaków ...
      ->link<-

      Przydatna rzecz ;-).
      • 39: CommentAuthorPecet
      • CommentTime6 Nov 2018 18:11 zmieniony
       
      Mad Pascal problem z kodem w asm.

      Skopiowałem źródło starfield z tej strony: ->link<-

      dostałem błąd:

      stx @sp
      asm_test.a65 (717) ERROR: Undeclared label @SP (BANK=0)
      ldx @sp
      asm_test.a65 (855) ERROR: Undeclared label @SP (BANK=0)

      skopiowałem procedurkę DLI z tej strony ->link<-

      {
      Program : 3D Starfield by Thomas Havemeister (converted to Mad Pascal)
      Original date : 07 Mar 2002
      Source : ->link<-
      }
      uses crt, graph;

      procedure StarField;
      begin
      asm {
      PHA
      TXA
      PHA
      LDX $D1
      DEX
      LDA #0400,X
      STA $D40A ; WSYNC
      CPX #$00
      BNE $0612
      LDX #$04
      STA $D018 ; BGCLR
      STX $D1
      PLA
      TAX
      PLA
      RTI
      };
      end;

      begin
      InitGraph(0); CursorOff;
      gotoxy(4, 5); writeln('3D Starfield by Thomas Havemeister');
      gotoxy(4, 6); writeln('Original date: 07 Mar 2002');
      gotoxy(4, 7); writeln('Converted to Mad Pascal');
      StarField;
      end.


      na szybko wkleiłem to w pierwszy program i dostaję błąd:

      LDA #0400,X
      smallTest.a65 (722) ERROR: Extra characters on line

      Generalnie asma to ogarniam na tyle, że gotową procedurę mogę przerobić pod swoje potrzeby, ale te błędy mnie przerastają.

      Generalnie w obu przypadkach tworzone są pliki lst i a65, brak jest natomiast pliku xex.
      • 40: CommentAuthorVidol
      • CommentTime6 Nov 2018 21:11
       
      lda #0400,x

      powinno byc

      lda $0400,x

      # - oznacza liczbe 0-255
      $ - oznacza adres w pamieci

      Blad w listingu zwlaszcza ze na stronie jest:
      Load the accumulator with the X offset into the color table stored in memory location 1024 ($0400)

      CPX #$00
      BNE $0612
      LDX #$04
      STA $D018 ; BGCLR

      to bne $612 tez nie jest ok.Lepiej zrobic to tak:
      CPX #$00
      BNE L1
      LDX #$04
      L1 STA $D018 ; BGCLR
      • 41: CommentAuthorPecet
      • CommentTime7 Nov 2018 19:11
       
      Dzięki. A ja szukałem jakiś ekstra spacji i innych tabulacji:)
      • 42: CommentAuthorPecet
      • CommentTime12 Nov 2018 12:11
       
      Mam jeszcze takie pytanie. Prawdopodobnie proste, ale zasadnicze.
      Załóżmy, że początek pamięci ekranu to $600. Tworzę jakąś zmienną w mad pascalu. Pytanie, jak mogę sprawdzić (bądź ustawić) adres takiej zmiennej? I jaką mam pewność, że ta zmienna nie zacznie mi "mazać" po pamięci ekranu?
      Wiem, że np. jak się tworzyło pamięć dla duszków to obniżało się ramtop, atari myślało, że ma mniej pamięci dostępnej i duszki były bezpieczne.
      Generalnie w jaki sposób przydzielana jest pamięć pod zmienne w mad pascalu, czy można mieć na ten proces wpływ.
      • 43:
         
        CommentAuthorbocianu
      • CommentTime12 Nov 2018 15:11 zmieniony
       
      @Pecet

      Hej! Domyślnie zmienne globalne ustawiane są na końcu kompilowanego kodu, i przy kompilacji masz informację gdzie znajduje się blok danych:

      Przykład:
      Mad Pascal Compiler version 1.5.8 [2018/10/27] for 6502
      Compiling hoppe.pas
      hoppe.pas (11) Note: Local const 'FRAME0' not used
      195 lines compiled, 1.03 sec, 7235 tokens, 713 idents, 208 blocks, 4 types
      1 note(s) issued
      ZPFREE: $0000..$007F
      ZPFREE: $00D8..$00FF
      SYSTEM: $2095..$2147
      CRT: $2148..$216C
      B_PMG: $216D..$224B
      B_DL: $224C..$2312
      JOYSTICK: $2313..$2316
      CODE: $2000..$281E
      DATA: $281F..$2859
      Writing listing file...
      Writing object file...
      8568 lines of source assembled in 5 pass
      2141 bytes written to the object file


      więc nasze zmienne lokowane są w obszarze:
      DATA: $281F..$2859

      Ale nic nie stoi na przeszkodzie, aby przy deklaracji zmiennej wskazać w którym miejscu ma się ona znajdować. Służy do tego dyrektywa absolute:
      var zmienna: byte absolute $6000;


      Możemy nawet deklarować całe tablice wskazując ich adres:
      pmg: array [0..0] of byte absolute $8000;


      i teraz zapisując wartość:
      pmg[5]:=12;


      wpisujemy wartość dwanaście pod komórkę $8005.

      Natomiast jeżeli chcemy znać dokładny adres zadeklarowanej wcześniej zmiennej, możemy użyć operatora @, który zwraca wskaźnik do dowolnej zmiennej.

      przykład:

      program test;
      uses crt;
      var
      i: byte;
      begin
      writeln('adres zmiennej i: ', word(@i));
      Readkey;
      end.


      Rzutowanie word(@i) jest potrzebne, gdyż procedura writeln nie potrafi drukować wartości wskaźników i musimy rzutować go na liczbę 16 bitową.

      Mam nadzieję, że pomogłem ;)
      • 44: CommentAuthorPecet
      • CommentTime12 Nov 2018 19:11
       
      Dzięki, teraz wiem już wszystko;)
      • 45: CommentAuthortebe
      • CommentTime12 Nov 2018 20:11
       
      tak na szybko, bez przerwań, tylko unit ATARI musiałem uzupełnić o kilka rejestrów

      uses crt, atari;

      var
      i: byte;
      tab, add: array [0..255] of byte;

      begin

      for i:=0 to 255 do begin
      tab[i]:=random(0);
      add[i]:=random(0) and 3 + 1;
      end;

      sizep0:=0;
      grafp0:=1;

      repeat

      i:=vcount;

      hposp0:=tab[i];

      inc(tab[i], add[i]);

      wsync:=0;

      until keypressed;

      end.
      • 46: CommentAuthorPecet
      • CommentTime25 Nov 2018 20:11 zmieniony
       
      Pomóżcie proszę, bo czegoś nie ogarniam.

      Chciałem zrobić scroll w poziomie. W trybie gr.0. Tak jak to rozumiem, to rezerwujemy na każdą linię ekranu więcej pamięci, układamy display list w ten sposób, że w każdej linii mamy LMS i potem w pętli o bajt przesuwamy adres. No więc zrobiłem coś takiego:
      uses crt, graph;

      var
      savmsc : word absolute 88;
      i,j : byte;
      dl4, dl4Temp: word;
      dlStart: word = $8000;
      lmsStart: word = $8100;
      offset: byte = 80;
      scrPtr: word;

      procedure populateDL2;
      Begin
      Poke(dlStart,112);
      Poke(dlStart+1,112);
      Poke(dlStart+2,112);

      for i:=1 to 24 do
      begin
      Poke(dlStart+3*i,66);
      DPoke(dlStart+3*i+1,lmsStart);
      lmsStart:=lmsStart+offset;
      end;

      Poke(dlStart+3*25,65);
      DPoke(dlStart+3*25+1,dlStart);
      End;

      procedure scroll;
      begin
      for j:=1 to 80 do
      begin
      dl4Temp:=dl4;
      for i:=1 to 24 do
      begin
      scrPtr:=DPeek(dl4Temp);
      DPoke(dl4Temp,scrPtr+1);
      dl4Temp:=dl4Temp+3;
      end;
      //savmsc := $8100+j;
      delay(120);
      end;
      end;

      begin

      PopulateDl2;
      DPoke(560,dlStart);

      savmsc := $8100;

      dl4:= dlStart + 4;

      for i:=0 to 77 do begin
      writeln(Peek(dlStart+i));
      end;

      //scroll;

      repeat until keypressed;
      end.


      W gr.0 mamy 40 znaków w linii, czyli potrzebne 40 bajtów na linię. Ja dałem dwa razy więcej (zmienna offset). Gdybym dał 40 bajtów, to w sumie uzyskałbym to samo, co przy jednym rozkazie LMS i potem same dwójki w kolejnych liniach display list. Dałem więc dwa razy tyle, czyli 80. Efekt jest taki, że wyświetla się tylko połowa ekranu. Pod Altirrą widzę, że kolejne linie i tak są umieszczane co 40 bajtów, a przecież LMS wskazuje, że powinno to być co 80. I nie wiem czemu tak się dzieje.

      I jeszcze jedno pytanie: SAVMSC, po co to w zasadzie jest? Przecież początek pamięci ekranu jest zapisany w display list. Czy jeżeli będę robił scrolla, to muszę SAVMSC również uaktualniać? Z tego co widzę to chyba nie.
      • 47: CommentAuthortebe
      • CommentTime26 Nov 2018 00:11 zmieniony
       
      ->link<-

      uses crt, atari;

      const
      dlist = $be00;

      scroll = $bf00; // bufor na scroll ma 256 bajtow

      dl: array [0..8] of byte = (
      $70,$70,$70, // 0,1,2 bajt
      $42+$30, // 3 bajt
      lo(scroll), // 4 bajt - mlodszy adres wiersza obrazu
      hi(scroll), // 5 bajt - starszy adres wiersza obrazu
      $41,lo(dlist),hi(dlist)
      );

      var
      hsc: byte = 3;
      cnt: byte = 1;

      idx: byte;


      txt: string = ' to jest przykladowy tekst w kodach ANTIC-a '~;

      begin
      move(dl, pointer(dlist), sizeof(dl));

      dpoke($230, dlist);

      repeat

      pause;

      if hsc=$ff then begin

      idx:=cnt+44;

      poke(scroll+idx, ord(txt[cnt]));


      inc(cnt);
      if cnt > length(txt) then begin
      cnt:=1; // od nowa
      poke(dlist+4, 0);
      end;

      poke(dlist+4, peek(dlist+4)+1);
      hsc:=3;
      end;

      hscrol:=hsc;

      dec(hsc);

      until keypressed;
      end.
      • 48: CommentAuthorPecet
      • CommentTime26 Nov 2018 08:11
       
      Strone znam, jedyny problem jest taki, ze nie umiem w asemblery. Dlatego wzialem sie za pascala.
      No i z checia dowiedzialbym sie, co jest nie tak w kodzie, ktory w wkleilem, bo gdzies bladze i nie wiem gdzie:)
      • 49:
         
        CommentAuthorbocianu
      • CommentTime26 Nov 2018 11:11 zmieniony
       
      zaraz zrobię sobie przerwę na herbate i rzucę okiem co tam jest popsute ;)

      jeżeli chodzi o savmsc, to musisz go ustawiać jak chcesz żeby działały systemowe funkcje piszące po ekranie (takie jak Writeln właśnie).
      • 50: CommentAuthorPecet
      • CommentTime26 Nov 2018 13:11
       
      dzieki tebe za kod, widze tu pare rozwiazan ktore wywowaly reakcje "a to tak mozna?:O", wiec nawet jezeli nie rozwiaze to mojego problemu, to chociaz moze cos ciekawego wpadnie mi do glowy.

      @bocianu
      ok, czyli z savmsc w sumie sprawa jasna. Czekam, co ciekawego znajdziesz.

      Przy okazji jeszcze raz dziekuje wszystkim uczestnikom tego topicu za dotychczasowa pomoc i sugestie:)