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: CommentAuthorzbyti
      • CommentTime15 Nov 2019 00:11 zmieniony
       
      O coś takiego mi chyba szło ;) Napisałem tak na szybko i działa.

      program pointerTest;
      uses crt, graph;

      type TChessman = array[0..56] of byte;

      const
      {* White square, invert Black square *}
      WHITE_SQUARE : TChessman = (
      $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$ff
      );

      {* White pawn on black, invert Black pawn on white *}
      PAWN_SE : TChessman = ( $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$00,$00,$3C,$00,$00,$3C,$00,$00,$18,$00,$00,$3C,$00,$00,$7E,$00,$00,$7E,$00,$00,$3C,$00,$00,$18,$00,$00,$18,$00,$00,$3C,$00,$00,$3C,$00,$01,$FF,$80,$01,$FF,$80
      );

      var chessboard : array[0..2] of word = (
      @WHITE_SQUARE, @PAWN_SE, @WHITE_SQUARE
      );
      i0b, color : byte;
      bmpAdr, tmpBmpAdr : word;

      procedure renderChessman(var chessman: word; x, y, invert: byte);
      var i0b : byte;
      tempY : word;
      begin
      tempY := (y * 760) + 40;
      tmpBmpAdr := bmpAdr + 1 + (x * 3);
      for i0b := 0 to 18 do begin
      poke(tmpBmpAdr + tempY, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + tempY + 1, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + tempY + 2, peek(chessman) xor invert);
      Inc(chessman);
      Inc(tempY, 40);
      end;
      end;

      begin
      InitGraph(8);
      bmpAdr := dpeek(88);
      SetColor(1);
      color := 2;
      SetBKColor(color);
      TextBackground(color);

      for i0b := 0 to 2 do begin
      renderChessman(chessboard[i0b], 4, i0b, 0);
      writeln(chessboard[i0b]);
      end;

      ReadKey;
      end.

      Teraz to usprawnię / skrócę i zastąpię stary kod :)
      • 2: CommentAuthorzbyti
      • CommentTime15 Nov 2019 01:11 zmieniony
       
      Niby kod bardziej zwięzły ale chyba przerzucanie się WORD-ami sporo kosztuje.

      procedure renderChessman(var chessman: word; x, y, invert: byte);
      var i0b : byte;
      tempY : word;
      begin
      tempY := (y * 760) + 40;
      tmpBmpAdr := bmpAdr + 1 + (x * 3);
      for i0b := 0 to 18 do begin
      poke(tmpBmpAdr + tempY, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + tempY + 1, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + tempY + 2, peek(chessman) xor invert);
      Inc(chessman);
      Inc(tempY, 40);
      end;
      end;

      procedure drawBoard;
      var i0b, i1b : byte;
      invert, piece : byte;
      begin
      drawRectangle;
      piece := 0;
      for i1b := 0 to 7 do begin
      for i0b := 0 to 7 do begin
      if (odd(i0b + i1b)) then invert := 0 else invert := $ff;
      if ((i1b > 1) and (i1b < 6)) then invert := not invert;
      renderChessman(CHESSBOARD[piece], i0b, i1b, invert);
      Inc(piece);
      end;
      end;
      end;

      Z 17 tików zrobiło się 27 :(

      Jaki się wybredny zrobiłem, jeszcze 2 dni temu 110 mnie urządzało a teraz 27 wydaje mi się wiecznością :D
      • 3: CommentAuthortebe
      • CommentTime15 Nov 2019 07:11
       
      trochę szybciej
      procedure renderChessman(var chessman: word; x, y, invert: byte);
      var i0b : byte;
      tempY : word;
      begin
      tempY := (y * 760) + 40;
      tmpBmpAdr := bmpAdr + 1 + (x * 3) + tempY;
      for i0b := 0 to 18 do begin
      poke(tmpBmpAdr, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + 1, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + 2, peek(chessman) xor invert);
      Inc(chessman);

      Inc(tmpBmpAdr, 40);
      end;
      end;
      • 4: CommentAuthorzbyti
      • CommentTime15 Nov 2019 08:11 zmieniony
       
      @tebe faktycznie ;) muszę przestać pisać po nocach bo mi umykają takie rzeczy :D

      Ta poprawka oszczędza 3 tiki.

      Postaram się zrobić tak by się nie przerzucać całym WORD-em.

      Starszy kod dzięki zaoszczędzeniu tych trzech dodawań też przyspieszył i zszedł z rysowaniem z 17 do 14 ;)
      • 5: CommentAuthorzbyti
      • CommentTime15 Nov 2019 10:11 zmieniony
       
      Mission accomplished! :D

      W starym kodzie jak chessman był tablicą to var przyspieszało sprawę.

      procedure renderChessman(var chessman: TChessman; x, y, invert: byte);

      Teraz gdy stał się typem word i przekazywał wartość wskaźnika do odpowiedniej tablicy to var robiło duży narzut.

      Prawidłowe jest teraz:

      procedure renderChessman(chessman: word; x, y, invert: byte);

      Pamięć jaka poszła na przygotowanie tablicy CHESSBOARD składającej się z 33 elementów typu word na pewno jest mniejsza niż ta którą wcześniej zajmował zawiły kod rysowania planszy w pozycji wyjściowej.

      Znów mam 14 tików a kod znacznie krótszy i bardziej elegancki :)

      procedure renderChessman(chessman: word; x, y, invert: byte);
      var i0b : byte;
      begin
      tmpBmpAdr := bmpAdr + 1 + (x * 3) + (y * 760) + 40;
      for i0b := 0 to 18 do begin
      poke(tmpBmpAdr, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + 1, peek(chessman) xor invert);
      Inc(chessman);
      poke(tmpBmpAdr + 2, peek(chessman) xor invert);
      Inc(chessman);
      Inc(tmpBmpAdr, 40);
      end;
      end;

      procedure drawRectangle;
      var i0b : byte;
      y : word ;
      begin
      y := 0;
      tmpBmpAdr := bmpAdr + 25;
      for i0b := 0 to 153 do begin
      poke(bmpAdr + y, %00000001);
      poke(tmpBmpAdr + y, %10000000);
      Inc(y, 40);
      end;
      tmpBmpAdr := bmpAdr + 6120; // 19*8*40 + 40
      for i0b := 1 to 24 do begin
      poke(bmpAdr + i0b, $ff);
      poke(tmpBmpAdr + i0b, $ff);
      end;
      end;

      procedure drawBoard;
      var i0b, i1b : byte;
      invert, chessman : byte;
      begin
      drawRectangle;
      chessman := 1;
      for i1b := 0 to 7 do begin
      for i0b := 0 to 7 do begin
      if (Odd(i0b + i1b)) then invert := 0 else invert := $ff;
      if ((i1b > 1) and (i1b < 6)) then begin
      renderChessman(CHESSBOARD[0], i0b, i1b, not invert);
      end else begin
      renderChessman(CHESSBOARD[chessman], i0b, i1b, invert);
      Inc(chessman);
      end;
      end;
      end;
      end;

      Rysuję szachownicę szybciej od Colossus 3.0! Nigdy bym nie przypuszczał, że tak będzie :D

      Komplet w załączniku. Oczywiście serwer pododawał swoje '2' do nazwy.
      • 6: CommentAuthorzbyti
      • CommentTime15 Nov 2019 11:11 zmieniony
       
      @tebe czy z tym komunikatem jaki mam podczas kompilacji powinienem coś zrobić po swojej stronie?

      pieces.inc (81) Warning: Range check error while evaluating constants (8192 must be between 0 and 65535)
      • 7: CommentAuthortebe
      • CommentTime15 Nov 2019 11:11 zmieniony
       
      kompilator nie powinien się tutaj czepiać, wymaga to poprawy

      tmpBmpAdr := bmpAdr + (x * 3) + (y * 760) + 40 + 1;


      krótszy, szybszy kod :)
      • 8: CommentAuthorzbyti
      • CommentTime15 Nov 2019 11:11 zmieniony
       
      @tebe akurat tego skrótu nie rozumiem ;)

      //old
      tmpBmpAdr := bmpAdr + 1 + (x * 3) + (y * 760) + 40;

      //new
      tmpBmpAdr := bmpAdr + (x * 3) + (y * 760) + 40 + 1;


      A na czym polega różnica? W tym jak to działa pod spodem?

      Tak przy okazji dla mniej wtajemniczonych. To +1 jest po to by szachownica była w ramce, i jak będę animował to by przerysowanie pola nie zamalowało ramki.
      • 9: CommentAuthortebe
      • CommentTime15 Nov 2019 11:11
       
      pogrupowanie operacji wpływa na optymalizację kodu, dwie operacje dodawania (+1 ; +40) zostają zastąpione jedną (+41)

      jeszcze szybciej
      procedure renderChessman(chessman: word; x, y, invert: byte);
      var i0b : byte;
      p : PChar;
      begin
      p := pointer(bmpAdr + (x * 3) + (y * 760) + 40 + 1);

      for i0b := 0 to 18 do begin
      p[0]:= chr(peek(chessman) xor invert); inc(chessman);
      p[1]:= chr(peek(chessman) xor invert); inc(chessman);
      p[2]:= chr(peek(chessman) xor invert); inc(chessman);

      Inc(p, 40);
      end;
      end;
      • 10: CommentAuthorzbyti
      • CommentTime15 Nov 2019 12:11 zmieniony
       
      @tebe dzięki, to cenna informacja do zanotowania :)

      No ale czy ten PChar to nie jest pieśń przyszłości? Nie kompiluje się na razie ;)

      A tak przy okazji kolega @urborg zrobił nowy zestaw bierek, według mnie wyglądają rewelacyjnie i już nie jestem plagiatorem CC3 :D
      • 11: CommentAuthorzbyti
      • CommentTime15 Nov 2019 14:11 zmieniony
       
      Aaaaa.... O to chodziło :D Jest szybciej ;)

      procedure renderChessman(chessman: word; x, y, invert: byte);
      var i0b : byte;
      p : ^char;
      begin
      p := pointer(bmpAdr + (x * 3) + (y * 760) + 40 + 1);
      for i0b := 0 to 18 do begin
      p[0]:= chr(peek(chessman) xor invert); Inc(chessman);
      p[1]:= chr(peek(chessman) xor invert); Inc(chessman);
      p[2]:= chr(peek(chessman) xor invert); Inc(chessman);
      Inc(p, 40);
      end;
      end;

      Pamiętałem, że pisałeś coś takiego:

      tebe:

      w nowej wersji MP będzie PChar, nie ma ograniczeń STRING-a

      Ale jeszcze nie ma ;)

      Korzystając z tej podpowiedzi przerobiłem kod na:

      procedure renderChessman(chessman: word; x, y, invert: byte);
      var i0b : byte;
      p : ^byte;
      begin
      p := pointer(bmpAdr + (x * 3) + (y * 760) + 40 + 1);
      for i0b := 0 to 18 do begin
      p[0]:= peek(chessman) xor invert; Inc(chessman);
      p[1]:= peek(chessman) xor invert; Inc(chessman);
      p[2]:= peek(chessman) xor invert; Inc(chessman);
      Inc(p, 40);
      end;
      end;

      procedure drawRectangle;
      var i0b : byte;
      p1, p2 : ^byte;
      begin
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 25);
      for i0b := 0 to 153 do begin
      p1[0]:= %00000001; Inc(p1, 40);
      p2[0]:= %10000000; Inc(p2, 40);
      end;
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 6120); // 19*8*40 + 40
      for i0b := 1 to 24 do begin
      p1[i0b] := $ff;
      p2[i0b] := $ff;
      end;
      end;


      Świetny pomysł!
      • 12: CommentAuthorzbyti
      • CommentTime15 Nov 2019 20:11 zmieniony
       
      @tebe a tak z ciekawości, na czuja - jak bym umiał napisać to efektywnie w czystym asm (załóżmy przez chwilę, że mam takie umiejętności jak Ty) to o ile by się zmniejszył memory footprint i do ilu tików mógłbym jeszcze zejść? Oczywiście pytam o szacunki.

      Interesuje mnie to bo moja szachownica naprawdę rysuje się szybciej niż ta z CC3 a przecież ta z Colossusa jest w czystym ASM. Efekt w MP przeszedł moje najśmielsze oczekiwania ;)

      -----------------------------------------------------------

      EDIT: zrobiłem ten test ->link<-

      System          UCSD version    Time (sec)
      ------ ------------ ----------

      Sage II IV.1 57 (68000 at 8 MHz)
      WD uEngine III.0 59 (fillchar is so slow on uE)

      LSI-11/23 IV.01 92-122 (depends on memory speed)
      LSI-11/23 II.0 105 (98 seconds under IV.01)
      LSI-11/23 IV.1 107 (non-extended memory)
      LSI-11/23 IV.1 128 (extended memory)

      NEC APC IV.1 144 8086 at 4.9 Mhz extended memory

      JONOS IV.03 ? 162 (pretty good for a 4 MHz Z-80A)
      NorthStar I.5 183 (Z-80 at 4 MHz)
      OSI C8P-DF II.0 ? 197 (6502 at 2 MHz)
      H-89 II.0 200 (4 MHz Z-80A)
      LSI-11/2 IV.0 202
      IBM PC IV.03 203 (4.77 MHz 8088)
      LSI-11/2 II.0 220

      Apple ][ II.1 390 (1 MHz 6502)
      H-89 II.0 455 (2 MHz Z-80)

      Mi wyszło ~22 sek. Wynik powala! :D Kompilator @tebe musi być najwyższej klasy! :) Na emulatorze może jest dostęp do pamięci szybszy? Ktoś ma możliwość puścić to na real Atari?
      • 13:
         
        CommentAuthorbocianu
      • CommentTime15 Nov 2019 21:11
       
      Kompilator @tebe musi być najwyższej klasy!


      potwierdzam :)
      i nadal jest rozwijany!
      • 14: CommentAuthortebe
      • CommentTime15 Nov 2019 23:11
       
      kompilator generuje plik A65, który jest listingiem w ASM
      można dokonać dalej idących optymalizacji na jego podstawie
      • 15: CommentAuthorzbyti
      • CommentTime15 Nov 2019 23:11 zmieniony
       
      @tebe jeszcze trzeba umieć :D Dla mnie większość tego pliku to wciąż czarna magia :D

      Mój ostatni kontakt z mnemonikami to jak 3 lata temu przechodziłem TIS-100 ->link<-

      • 16:
         
        CommentAuthorbocianu
      • CommentTime16 Nov 2019 12:11
       
      Och tis-100 jest świetny.
      Zabrał mi kilkanaście godzin życia :)
      Muszę kiedyś do niego wrócić, bo pamiętam że nie rozwiązałem wszystkich.
      • 17: CommentAuthorzbyti
      • CommentTime16 Nov 2019 12:11
       
      @bocianu dzięki, że źródła zamieszczasz "Mister Hoppe" pomógł mi parę razy :D
      • 18:
         
        CommentAuthorbocianu
      • CommentTime16 Nov 2019 14:11
       
      No właśnie po to zamieszczam :)
      Cieszę się, że się przydają.
      • 19: CommentAuthorzbyti
      • CommentTime16 Nov 2019 17:11 zmieniony
       
      Jako, że szachy które planuję pisać działają w trybie 8 i nie chciałem (bo nie umiem) pisać obsługi przerwań by mieszać tryby graficzne to potrzebowałem czegoś do pisania po ekranie.

      Poniżej kod, który można łatwo przerobić na w pełni 80 kolumnowy wyświetlacz :)

      Jak zawsze praktyków proszę o krytykę, nie masterowałem tego kodu jakoś bardzo, starałem się wyważyć między rzeczami które robię w pętli a tymi które warto z ręki powtórzyć kosztem zajętej pamięci (tak to sobie wyobrażam).

      Nie sprawdzam ilości wierszy, także pisanie po za 38 wiersz może wywalić maszynę ;)

      Docelowo ten kod będzie mi wyświetlał obok szachownicy zapis partii.

      program EightyColumnMode;

      uses crt, graph;

      type TForBitChar = array[0..4] of byte;

      const
      CHAR_A : TForBitChar = (
      %1110,%1010,%1110,%1010,%1010
      );
      CHAR_B : TForBitChar = (
      %1100,%1010,%1110,%1010,%1110
      );

      CHAR_C : TForBitChar = (
      %1110,%1000,%1000,%1000,%1110
      );
      CHAR_D : TForBitChar = (
      %1100,%1010,%1010,%1010,%1100
      );
      CHAR_E : TForBitChar = (
      %1110,%1000,%1110,%1000,%1110
      );
      CHAR_F : TForBitChar = (
      %1110,%1000,%1110,%1000,%1000
      );
      CHAR_G : TForBitChar = (
      %1110,%1000,%1010,%1010,%1110
      );
      CHAR_H : TForBitChar = (
      %1010,%1010,%1110,%1010,%1010
      );
      CHAR_SPACE : TForBitChar = (
      %0000,%0000,%0000,%0000,%0000
      );
      FOR_BIT_CHARS : array[0..7] of word = (
      CHAR_A,CHAR_B,CHAR_C,CHAR_D,CHAR_E,CHAR_F,CHAR_G,CHAR_H
      );

      var
      ba, tba : word;
      col, row, i0b, left : byte;
      pressedKey : byte;
      charToDraw : word;

      begin
      // There are 192 rows of 320 dots in the full screen mode.
      InitGraph(8);
      ba := dpeek(88);
      tba := ba - 1;
      SetColor(1);

      col := 1;
      row := 1;

      WriteLn('Start typing a,b,c,d,e,f,g ...');

      repeat
      pressedKey := Ord(ReadKey) - 97;
      charToDraw := FOR_BIT_CHARS[pressedKey];

      WriteLn(pressedKey, ' --> ', pressedKey);

      if ((pressedKey >= 0) and (pressedKey < 8)) then begin
      if (Odd(col)) then begin
      Inc(tba);
      left := 4;
      end else left := 0;
      for i0b := 0 to 4 do begin
      poke(tba, peek(tba) or peek(charToDraw) shl left);
      Inc(charToDraw);
      Inc(tba, 40);
      end;
      Dec(tba, 200);
      Inc(col);
      if (col = 81) then begin
      Inc(tba, 200);
      Inc(row);
      col := 1;
      end;
      end;
      until false;
      end.
      • 20:
         
        CommentAuthorsun
      • CommentTime16 Nov 2019 19:11 zmieniony
       
      Ja zmotałem coś takiego jakiś czas temu. Nie jest o piękny kod niestety ;)

      procedure Print80(x,y:word;s:String);overload;
      var
      adr,tmp: ^byte;
      tl : byte;
      chara: ^byte;
      charindex : byte;
      posindex : byte;
      xx : byte;
      ch : byte;
      d : byte;
      ekr: byte;
      inv: byte;
      begin
      // s := Atascii2Antic(s);
      inv := 0;
      // oblicz adres startowy
      posindex := not (x and 1);
      adr:=pointer(VIDEO_RAM_ADDRESS+ypos[y]+ (x div 2));
      // dlugosc stringa
      tl := length(s);
      // petla po stringu
      charindex := 1;
      // posindex := 1;
      // posindex wg x, zeby obsluzyc start od drugiej polowki bajtu.

      repeat
      // adres tmp
      tmp := adr;
      // adres znaku w zestawie
      if (s[charindex]='~') then
      begin
      inc(charindex,1);
      inv := not inv;
      end;
      chara := pointer(CHARSET_ADDRESS + Atascii2Antic(byte(s[charindex]))*8);
      // 8 linii znaku
      xx := 0;
      repeat
      // skopiuj 1 linię znaku (bajt)
      move(chara,@ch,1);
      d := ch;
      // jesli znaki sa juz 4 bitowe, nie roluj
      // d := ch and %11000000;
      // d := d or (ch shl 1 and %01100000);
      // d := d or (ch shl 2 and %00110000);
      // d := d or (ch shl 3 and %00010000);

      // inwers (ale tylko na polowie znaku)
      if (inv <> 0) then
      begin
      d := d xor %11110000;
      d := d and %11110000;
      end;

      //bajt ekranu do ekr
      move(tmp,@ekr,1);
      //jesli to druga polowa znaku, przekrec go w prawo
      if (posindex and 1) = 0 then d := d shr 4;
      //oruj ze znakiem
      ekr := ekr or d;
      // przepisz na ekran
      move(@ekr,tmp,1);
      // nowa linia ekranu
      inc(tmp,stp);
      // nowy bajt znaku
      inc(chara,1);
      inc(xx,1);
      until (xx>7);
      // nastepna pozycja znaku
      if ((posindex and 1) = 0) then inc(adr,1);
      inc(posindex,1);
      inc(charindex,1);
      until (charindex>tl);
      end;
      • 21: CommentAuthorzbyti
      • CommentTime16 Nov 2019 19:11 zmieniony
       
      @sun chętnie obadam :)

      EDIT:
      No fajnie, coś z tego kodu jednak podpatrzę dla siebie :)
      • 22: CommentAuthormono
      • CommentTime16 Nov 2019 20:11 zmieniony
       
      Skoro definicje znaków i tak zajmują bajt, to zduplikuj kształt w młodszej i starszej połówce bajtu. A potem zależnie czy będziesz malował w parzystej lub nieparzystej kolumne rób tylko AND $F0 lub AND $0F na takim kształcie i wypluwaj na ekran z OR-em. Możliwe, że będzie szybciej niż przy SHL. W asm taka sztuczka przyspiesza malowanie.
      • 23: CommentAuthorzbyti
      • CommentTime16 Nov 2019 20:11 zmieniony
       
      @mono sprawdzę ten pomysł :) Obadam.

      EDIT: znakomita idea, wdrażam :)

      Na tyle na ile to rozumiem ten AND faktycznie da szybszy kod.

      Proponowane przez @mono rozwiązanie jest bardziej eleganckie od mojego:

      program EightyColumnMode;

      uses crt, graph;

      type TForBitChar = array[0..4] of byte;

      const
      CHAR_A : TForBitChar = (
      %11101110,%10101010,%11101110,%10101010,%10101010
      );
      CHAR_B : TForBitChar = (
      %11001100,%10101010,%11101110,%10101010,%11101110
      );
      CHAR_C : TForBitChar = (
      %11101110,%10001000,%10001000,%10001000,%11101110
      );
      CHAR_D : TForBitChar = (
      %11001100,%10101010,%10101010,%10101010,%11001100
      );
      CHAR_E : TForBitChar = (
      %11101110,%10001000,%11101110,%10001000,%11101110
      );
      CHAR_F : TForBitChar = (
      %11101110,%10001000,%11101110,%10001000,%10001000
      );
      CHAR_G : TForBitChar = (
      %11101110,%10001000,%10101010,%10101010,%11101110
      );
      CHAR_H : TForBitChar = (
      %10101010,%10101010,%11101110,%10101010,%10101010
      );
      CHAR_SPACE : TForBitChar = (
      0,0,0,0,0
      );
      FOR_BIT_CHARS : array[0..7] of word = (
      CHAR_A,CHAR_B,CHAR_C,CHAR_D,CHAR_E,CHAR_F,CHAR_G,CHAR_H
      );

      var
      ba, tba : word;
      col, row, i0b, even : byte;
      pressedKey : byte;
      charToDraw : word;

      begin
      // There are 192 rows of 320 dots in the full screen mode.
      InitGraph(8);
      ba := dpeek(88);
      tba := ba - 1;
      SetColor(1);

      col := 1;
      row := 1;

      WriteLn('Start typing a,b,c,d,e,f,g ...');

      repeat
      pressedKey := Ord(ReadKey) - 97;
      charToDraw := FOR_BIT_CHARS[pressedKey];
      if ((pressedKey >= 0) and (pressedKey < 8)) then begin
      if (Odd(col)) then begin
      Inc(tba);
      even := $f0;
      end else even := $0f;
      for i0b := 0 to 4 do begin
      poke(tba, peek(tba) or (peek(charToDraw) and even));
      Inc(tba, 40); Inc(charToDraw);
      end;
      Dec(tba, 200); Inc(col);
      if (col = 81) then begin
      Inc(tba, 200); Inc(row);
      col := 1;
      end;
      end;
      until false;
      end.
      • 24: CommentAuthorzbyti
      • CommentTime16 Nov 2019 23:11 zmieniony
       
      Compiler Explorer is an interactive compiler. The left-hand pane shows editable C, C++, Rust, Go, D, Haskell, Swift, Pascal (and some more!) code. The right, the assembly output of having compiled the code with a given compiler and settings. Multiple compilers are supported, and the UI layout is configurable (thanks to GoldenLayout). There is also an ispc compiler ? for a C variant with extensions for SPMD.

      ->link<-

      Jak się wybierze C to można wybrać jako target 6502 :) może tak się kiedyś nauczę maszynowego? ;)

      -------------------------------------------------------------

      A to jakie cudo LemonSpawn ->link<-

      Ale ja zostaję przy MP :)
      • 25: CommentAuthorMADRAFi
      • CommentTime17 Nov 2019 18:11
       
      Przepraszam, ale ja nie widze tu 80 kolumn. Dla mnie ten kod wypisuje max 40 znakow w 1 linii :)
      • 26: CommentAuthorzbyti
      • CommentTime17 Nov 2019 19:11 zmieniony
       
      @MADRAFi a na czy polega sedno Twojego dowcipu? Rozumiem, że chodzi Ci o interpretację tego co widzisz a nie o fakt ;) Ja widzę 80 znaków w linii wypisanych na 40x5 bajtach.
      • 27: CommentAuthortebe
      • CommentTime17 Nov 2019 21:11
       
      ->link<-
      - nowy unit EFAST dla przyspieszenia wyprowadzania znaków na urządzenie E:
      - SYSTEM: function Copy(var S: String; Index: Byte; Count: Byte): String;
      - SYSTEM: Palette, HPalette
      - dodana obsługa tablic jednowymiarowych typu ^RECORD (wskaznik do rekordu)
      - optymalizacja bloków warunkowych, generowany jest możliwie najkrótszy, najszybszy kod wynikowy
      - dodany typ PChar, ->link<-
      - dodana możliwość zwracania wartości funkcji przez typ wyliczeniowy
      - dodany nowy przełącznik -define:symbol
      - dodany nowy przełącznik -ipath:includepath
      • 28: CommentAuthorzbyti
      • CommentTime17 Nov 2019 21:11 zmieniony
       
      @tebe świetna informacja! Już pobieram i testuję! :)

      Fajnie, że jest Copy, czekałem na to, w FPC używałem ;)

      EDIT:

      w nowej wersji przestało mi działać:
      p[0]:= peek(chessman) xor invert; Inc(chessman);

      Teraz domaga się tablicy ;)
      • 29: CommentAuthorzbyti
      • CommentTime17 Nov 2019 22:11 zmieniony
       
      Tym razem na pewno pobrałem 'master'... Już wcześniej branch-10 to rzucał przy tablicach ->link<-

      ➜  playground mp 80col.pas 
      Mad Pascal Compiler version 1.6.2 [2019/11/17] for 6502
      Compiling 80col.pas
      An unhandled exception occurred at $000000000045A21C:
      EAccessViolation: Access violation
      $000000000045A21C
      $00000000004AA991
      • 30: CommentAuthortebe
      • CommentTime18 Nov 2019 00:11
       
      pod Windowsem nie wywala, jeden błąd znalazłem i poprawiłem pod linuxem (lubuntu), pewnie to jest tego typu sytuacja

      obecnie nie mam dostępu do lubuntu, jeśli masz czas to możesz sprawdzić przy pomocy GDB

      najpierw kompilacja z parametrem -g
      fpc -Mdelphi -g mp.pas


      odpalasz debugger
      gdb mp.exe


      uruchamiasz program który się sypie w konsoli GDB
      run path\80col.pas

      i jak dobrze pójdzie to wyświetli informację o linii która powoduje błąd
      • 31: CommentAuthorzbyti
      • CommentTime18 Nov 2019 00:11 zmieniony
       
      @tebe ok, sprawdzę, a dockera nie używasz? Albo wirtualnej maszyny? Przecież starczy Ci sama wersja z terminalem + vim do testowania kompilacji na linuchu.
      • 32: CommentAuthorzbyti
      • CommentTime18 Nov 2019 00:11
       
      (gdb) run 80col.pas
      Starting program: /home/zbyti/Temp/mp/mp 80col.pas
      Mad Pascal Compiler version 1.6.2 [2019/11/18] for 6502
      Compiling 80col.pas

      Program received signal SIGSEGV, Segmentation fault.
      0x00000000004640a4 in PEEPHOLEOPTIMIZATION (parentfp=0x7ffffffd5be0) at mp.pas:13484
      13484 if (pos('ldy ', listing[i-1]) = 0) and (tay(i-1) = false) and // sta :STACKORIGIN+9 ; 0

      • 33: CommentAuthortebe
      • CommentTime18 Nov 2019 01:11
       
      okazuje się że Windows 10 pozwala zainstalować terminal Linuxa :) mam ten sam komunikat z debugera :)
      • 34: CommentAuthorzbyti
      • CommentTime18 Nov 2019 01:11 zmieniony
       
      A no przecież, faktycznie, jest Windows Subsystem for Linux. Zapomniałem o tym, od lat nie używam Windowsa ;)
      • 35: CommentAuthortebe
      • CommentTime18 Nov 2019 01:11
       
      już leży poprawiona wersja
      ->link<-
      ->link<-
      • 36: CommentAuthorzbyti
      • CommentTime18 Nov 2019 01:11 zmieniony
       
      @tebe szybko :) 80col.pas już nie rzuca błędem, ale mój kod renderujący szachownicę kompletnie przestał cykać ;(

      No ale rozumiem, że wcześniej używałem czegoś co teraz jest niedozwolone, szkoda, że nie ma o tym wzmianki. Muszę sobie zapisywać jaką wersją który kod się kompilował ;)

      EDIT: @tebe to jak teraz poruszać po się tablicy przekazując sobie wskaźnik do niej za pomocą Inc, tak jak w poprzedniej wersji? Dla mnie drawback ;)
      • 37: CommentAuthorzbyti
      • CommentTime18 Nov 2019 02:11 zmieniony
       
      procedure drawRectangle;
      var i0b : byte;
      p1, p2 : ^byte;
      begin
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 25);
      for i0b := 0 to 153 do begin
      p1[0]:= %00000001; Inc(p1, 40);
      p2[0]:= %10000000; Inc(p2, 40);
      end;
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 6120); // 19*8*40 + 40
      for i0b := 1 to 24 do begin
      p1[i0b] := $ff;
      p2[i0b] := $ff;
      end;
      end;

      teraz kompilator domaga się by był tablicą...

      chessboard.pas (47,13) Error: Array type required, 47 linia to p1[0]:= %00000001; Inc(p1, 40);

      Czyli nie podoba mu się przypisanie p1[0]:= %00000001;, które to jeszcze chwilę temu działało i było Twoją propozycją usprawnieni do mojego kodu, w sensie posłużenie się pointerem wskazującym na ekran.

      Nie rozumiem co miałbym zmieniać. Poczekam na odpowiedź :)
      • 38: CommentAuthortebe
      • CommentTime18 Nov 2019 08:11 zmieniony
       
      wystarczy zmienić na PChar, które jest tablicą
      procedure drawRectangle;
      var i0b : byte;
      p1, p2 : PChar;
      begin
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 25);
      for i0b := 0 to 153 do begin
      p1[0]:= chr(%00000001); Inc(p1, 40);
      p2[0]:= chr(%10000000); Inc(p2, 40);
      end;
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 6120); // 19*8*40 + 40
      for i0b := 1 to 24 do begin
      p1[i0b] := #$ff;
      p2[i0b] := #$ff;
      end;
      end;
      • 39: CommentAuthorzbyti
      • CommentTime18 Nov 2019 09:11
       
      @tebe no dobrze, rozumiem zalety wprowadzenia PChar, ale czy to jest powód by wcześniejszy kod przestał działać?

      Wygląda na to, że

      p1, p2 : ^byte;

      Robi teraz coś innego niż poprzednio i warto o tym wspomnieć w changelogu ;)
      • 40: CommentAuthortebe
      • CommentTime18 Nov 2019 10:11 zmieniony
       
      znalazłeś błąd kompilatora, poprawiłem :)

      staram się być zgodny z FPC, nie tworzę nowego odłamu Pascala, jak Rascal

      preferujesz ^byte, ok
      procedure drawRectangle;
      var i0b : byte;
      p1, p2 : ^byte;
      begin
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 25);
      for i0b := 0 to 153 do begin
      p1^:= %00000001; Inc(p1, 40);
      p2^:= %10000000; Inc(p2, 40);
      end;
      p1 := pointer(bmpAdr);
      p2 := pointer(bmpAdr + 6120); // 19*8*40 + 40
      for i0b := 1 to 24 do begin
      inc(p1);
      inc(p2);
      p1^ := $ff;
      p2^ := $ff;
      end;
      end;

      dwa bajty różnicy na korzyść PChar
      • 41: CommentAuthorzbyti
      • CommentTime18 Nov 2019 10:11 zmieniony
       
      @tebe no to fajnie :)

      Niekoniecznie preferuję ale w tym przypadku będzie o parę operację mniej bo nie muszę wywoływać Chr() podczas rysowania szachownicy ani drawRectangle.

      Dzięki za poprawki, teraz lepiej rozumiem jak to powinno działać :)

      EDIT:
      No i by była jasność ja nie marudzę :) Jestem bardzo wdzięczny za to narzędzie i że podpowiadasz jak z niego korzystać :) THX :)
      • 42: CommentAuthortebe
      • CommentTime18 Nov 2019 10:11 zmieniony
       
      Chr() to tylko dla kompilatora aby typy mu się zgadzały, nie wykonuje to żadnej dodatkowej operacji w kodzie wynikowym

      w załączniku starszy przykład gdzie wykorzystywane są wskaźniki, m.in. ^byte
      • 43: CommentAuthorzbyti
      • CommentTime18 Nov 2019 10:11 zmieniony
       
      @tebe skoro tak, to faktycznie użyję PChar - jr. dziękuję za wskazówki.

      Rozumiem, że błędnie korzystałem ze wskaźnika chociaż kompilator dopuszczał taką składnię ;)

      EDIT:
      Wiesz... Taki Nowak jak ja nie zawsze załapie dlaczego nagle kod przestaje się kompilować z wersji na wersję ;)
      • 44: CommentAuthortebe
      • CommentTime18 Nov 2019 11:11
       
      Rozumiem, że błędnie korzystałem ze wskaźnika chociaż kompilator dopuszczał taką składnię ;)

      dokładnie :)
      • 45: CommentAuthorzbyti
      • CommentTime18 Nov 2019 16:11 zmieniony
       
      @bocianu & @tebe

      z pliku dla Geany filetypes.pascal usunął bym:

      [build-menu]
      FT_00_LB=_Skompiluj
      FT_00_CM=E:\\atari\\MadPascal\\build.bat %e
      FT_00_WD=
      EX_00_LB=_Wykonaj
      EX_00_CM=E:\\atari\\MadPascal\\buildrun.bat %e
      EX_00_WD=

      Właśnie postanowiłem skorzystać i sobie nadpisałem moje menu ;)

      Nawet jak ktoś sobie nie nadpisze to i tak będzie musiał ustawić tam gdzie ma, więc nawet jak nie zaszkodzi to nie pomoże.

      Albo info o tym w poradniku, żeby najpierw wrzucić ten config a później ustawić ;) detal.
      • 46: CommentAuthorastrofor
      • CommentTime18 Nov 2019 20:11
       
      mam pytanko, poniewaz nowy ruski macos caterina kategorycznie odmawia zainstalowanie fpc. Postanowilem zrobic wszystko w dockerze. Znalazlem :
      ->link<-
      wyglada ze dziala, natomiast mam czesc odpowiedzialna za kompilacje pascala, pozostaje part mad-pascala, szperalem na forum ale niczego nie znalazlem (z wyjatkiem posta aby zwrucic sie prywatnie po pomoc na fejsa)
      Dockerfile wyglada tak:
      ->link<-
      co powinienem dopisac ?
      • 47: CommentAuthorzbyti
      • CommentTime18 Nov 2019 21:11 zmieniony
       
      @astrofor najprościej to zamiast instalować po komponencie to pociągnij dockerem ->link<-

      Poinstaluj jak na normalnym Ubuntu, folder ze źródłami wystaw by pracować na zewnątrz kontenera i cyk.

      docker run --name test -i -t -v /home/zbyti/Docker/Test:/home ubuntu
      • 48: CommentAuthorastrofor
      • CommentTime18 Nov 2019 21:11 zmieniony
       
      to tak, ale nie chodzi mi o szczegoly ustawien dockera, tylko o ustawienie kompilatora mad pascala .
      Na dockerze moge teraz kompilowac i uruchamiac pascale np :
      echo "begin writeln('Hello World'); end." > test.pas
      docker run --rm -it -v $(pwd):/source cmplopes/alpine-freepascal fpc test.pas
      docker run --rm -it -v $(pwd):/source cmplopes/alpine-freepascal ./test


      ale ja potrzebuje aby skompilowac do xex :
      mp $1.pas -o
      mads $1.a65 -x -i:/home/bocianu/madPascal/base -o:$1.xex

      (wedlug instrukcji ->link<- Nie wiem jak zbudowac mp i mads.
      Wiem ze powinienem zrobic cos jak : fpc -Mdelphi -v -O3 plik.pas
      ale na tym instrukcja kompilacji sie konczy .
      • 49: CommentAuthorzbyti
      • CommentTime18 Nov 2019 21:11 zmieniony
       
      @astrofor chyba nie zrozumiałeś mojej rady.

      Uruchamiasz w dokerze instancję gdzie wszystko działa ci tak jak na normalnym systemie i nie ma takich problemów jak w sposobie który próbujesz.

      Przecież ten kontener w ogóle nie zobaczy ani skompilowanego mads ani mp. Musiał byś zbudować swój z mp i mads.

      Zrób jak Ci radzę i nie kombinuj ;)

      No chyba, że masz większe doświadczenie ode mnie (mam skromne ale chyba jednak większe) to powodzenia! ;)
      • 50: CommentAuthorastrofor
      • CommentTime18 Nov 2019 21:11
       
      Ok to postawie sprawe inaczej. Nie mam dockera. Mam ubuntu z zainstalowanym fpc , jak zbudowac mads i mp na ubuntu ?