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 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 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
     
    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 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 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 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 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 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
     
    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 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 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 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
     
    Kompilator @tebe musi być najwyższej klasy!


    potwierdzam :)
    i nadal jest rozwijany!
    • 14: CommentAuthortebe
    • CommentTime15 Nov 2019
     
    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 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
     
    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
     
    @bocianu dzięki, że źródła zamieszczasz "Mister Hoppe" pomógł mi parę razy :D
    • 18:
       
      CommentAuthorbocianu
    • CommentTime16 Nov 2019
     
    No właśnie po to zamieszczam :)
    Cieszę się, że się przydają.
    • 19: CommentAuthorzbyti
    • CommentTime16 Nov 2019 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 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 zmieniony
     
    @sun chętnie obadam :)

    EDIT:
    No fajnie, coś z tego kodu jednak podpatrzę dla siebie :)
    • 22: CommentAuthormono
    • CommentTime16 Nov 2019 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 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 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
     
    Przepraszam, ale ja nie widze tu 80 kolumn. Dla mnie ten kod wypisuje max 40 znakow w 1 linii :)
    • 26: CommentAuthorzbyti
    • CommentTime17 Nov 2019 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
     
    ->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 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 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
     
    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 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
     
    (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
     
    okazuje się że Windows 10 pozwala zainstalować terminal Linuxa :) mam ten sam komunikat z debugera :)
    • 34: CommentAuthorzbyti
    • CommentTime18 Nov 2019 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
     
    już leży poprawiona wersja
    ->link<-
    ->link<-
    • 36: CommentAuthorzbyti
    • CommentTime18 Nov 2019 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 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 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
     
    @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 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 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 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 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
     
    Rozumiem, że błędnie korzystałem ze wskaźnika chociaż kompilator dopuszczał taką składnię ;)

    dokładnie :)
    • 45: CommentAuthorzbyti
    • CommentTime18 Nov 2019 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
     
    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 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 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 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
     
    Ok to postawie sprawe inaczej. Nie mam dockera. Mam ubuntu z zainstalowanym fpc , jak zbudowac mads i mp na ubuntu ?