atarionline.pl ABC czyli Atari Basic Compiler - 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:
         
        CommentAuthormgr_inz_rafal
      • CommentTime14 Nov 2012 00:11 zmieniony
       
      OK, jest pierwsza wersja pętelek. Na razie z dwoma ograniczeniami:
      1. Gramatyka nie pozwala na pominięcie słowa STEP
      2. STEP ujemny nie działa (trzeba zrobić odwrotne porównanie niż w dodatnim, a już dziś mi się nie chce) :)

      Spostrzegawczy jednak zauważą, że umiejscowienie kilku FOR lub NEXT w jednej linii wymagało dorobienia obsługi GOTO do środka linijki :)

      Oto przykładowy kod i wynik.
      10 FOR A = 1 TO 5 STEP 1
      20 FOR B = 2 TO 7 STEP 2:FOR C = 2 TO 14 STEP 5
      30 PRINT A*B*C
      40 NEXT C
      50 NEXT B:NEXT A
      60 PRINT 666

      • 2: CommentAuthormono
      • CommentTime14 Nov 2012 01:11 zmieniony
       
      Weź pod uwagę rozkaz POP. Ma znaczenie w pętlach FOR/NEXT i skokach GOSUB do podprocedur.
      Skoki liczone możesz realizować za pomocą
      jmp (addr)

      Miej na uwadze też TRAP, które funkcjonuje jak wyjątek w językach C++-podobnych.

      Edit: Opis działania ->link<- str. 42/43.
      • 3:
         
        CommentAuthorpirx
      • CommentTime14 Nov 2012 11:11
       
      >Niestety to rozwiązanie nie działa dla wyrażeń (np. GOTO X * 10), bo ich wartość nie jest znana w czasie kompilacji

      Ha! Po tylu latach zrozumiałem, czemu w mojej instrukcji do Atari Basic z 800XL było napisane, że GOTO X*1000 i GOSUB X*1000 są "not good for compilation"! (o ile pamiętam)
    1.  
      @mono
      Tak, pamiętam o POP. Jeśli chodzi o jmp (addr) to trochę się boję buga związanego z ostatnim bajtem strony, dlatego wolę stosować PHA, PHA, RTS.

      A może MADS pilnuje tego jmp?

      TRAP i ON ERROR GOTO/GOSUB będzie mi spędzać sen z powiek trochę później, jak już porobię podstawy. Podobnie jak inne rzeczy, których nigdy w BASIC nie rozumiałem, np. STATUS czy XIO :) Póki co żyję nadzieją, że da się to jakoś prosto zmapować na wywołania OSu albo, że kiedyś będziecie mi w stanie to wytłumaczyć :)

      @pirx
      Są good, jeśli kompilator jest good :) A moim zdaniem robienie kompilatora "pół-BASICA" mija się z celem. Jak wspierać to wszystko co się da i co będę umiał zrobić :)
      • 5: CommentAuthormono
      • CommentTime14 Nov 2012 22:11
       
      ->link<-
      STATUS i XIO, jak również OPEN, CLOSE, GET, PUT, INPUT, PRINT, LPRINT, LOCATE, POINT, NOTE, to odwołania do CIO w OS. Gorzej będzie z LOAD, SAVE, CLOAD, CSAVE, ENTER i LIST.
      • 6:
         
        CommentAuthorxeen
      • CommentTime14 Nov 2012 23:11
       
      wydaje mi się, że w przypadku takiego "cross'a" te komendy (load, save, cload itp) nie są za bardzo użyteczne.
      "very nice to have", co najwyżej, jak dla mnie.
      • 7: CommentAuthormono
      • CommentTime14 Nov 2012 23:11
       
      Jeszcze RUN. RUN jest często używany w programach wieloplikowych. Można w sumie za pomocą RUN ładować i uruchamiać skompilowany program w BASICu.
      • 8:
         
        CommentAuthormgr_inz_rafal
      • CommentTime16 Nov 2012 14:11 zmieniony
       
      Odnośnie POP mam małą sprawę.
      Generalnie byłoby to trywialne w implementacji gdyby nie fakt, że BASIC wymusza podanie identyfikatora pętli po NEXT, co może w dość dziwny sposób zaburzyć przebieg programu. Np.
      10 FOR J=1 TO 5
      20 FOR I=1 TO 3
      30 PRINT I*J
      40 NEXT J

      Chcąc to skompilować musiałbym zorganizować sobie osobne miejsce w pamięci do przechowywania NAZW (zmiennych sterujących) pętli zmapowanych na odpowiednie adresy powrotu. Następnie, po każdym NEXT szukać odpowiedniej nazwy pętli i wykonywać adekwatny skok.

      I teraz rodzi się gniew :)

      Z jednej strony chciałbym zachować dużą kompatybilność, a z drugiej nie wiem, po kiego grzyba wspierać tak dziwne konstrukcje, których implementacja zburzy wewnętrzną elegancję mojego kompilatora :)

      No cóż, pewnie i tak zrobię, żeby działało, ale jeśli ktoś dorzuci parę argumentów ZA stosowaniem takiej konstrukcji jak powyżej, to na pewno będzie mi łatwiej :)
      • 9: CommentAuthormono
      • CommentTime16 Nov 2012 16:11 zmieniony
       
      A czemu dynamicznie? Nie można statycznie określić gdzie jest początek pętli a gdzie koniec? Nawet stosu mieć nie musisz, jak to jest w basicu...
      Przed takim NEXTem powinien się oczywiście pojawić POP, ale jeśli programista zapomni, to w BASICu się wysypie, a u Ciebie nie :)

      Edit: Taki POP: NEXT J z wnętrza pętli sterowanej I to takie goto z C... niby nieładne, ale jak już ktoś tak zaprogramował. FOR/NEXT w BASICu mają tę zaletę, że adres powrotu odkładany jest na stos (może się zdarzyć w środku linii) więc nie trzeba szukać linii (od początku programu), jak to jest w przypadku [ON]GOTO/GOSUB co jest straszliwie wolne (tzn. NEXT jest znacznie szybsze).
    2.  
      Muszę to sobie jeszcze raz na spokojnie rozrysować... Teraz mam skoki w pętlach na statycznych labelkach i działa OK, pod warunkiem, że FOR/NEXT zawsze do siebie pasują. Poniższy program kompiluje się i działa dobrze, ale myk polega na tym, że kompilator po prostu ignoruje POP :)
      10 FOR J=1 TO 5
      20 FOR I=1 TO 3
      30 PRINT I*J
      35 IF I = 2 THEN POP:GOTO 50
      40 NEXT I
      50 NEXT J

      Właśnie fakt, że nie muszę nic przy POP robić trochę mnie zdziwił i zacząłem drążyć temat - może całkiem niepotrzebnie.

      Przeanalizuję jeszcze sytuację na spokojnie, bo chciałbym też uniknąć sytuacji, że ktoś w swoim programie polega na tej specyficznej właściwości BASICa i po kompilacji nie uzyska zamierzonego efektu.

      A przy NEXT mogli sobie pozwolić na skok bezpośrednio pod adres, bo zawsze wiadomo gdzie skoczyć. A w GOTO/GOSUB zdecydowali się na obsługę słynnych już skoków w linijki liczone w trakcie działania programu (GOTO X*10).

      Ale... Cały czas nie rozumiem, dlaczego w BASICu zdecydowano się na podawanie nazwy zmiennej sterującej po NEXT. Tzn. rozumiem jak to działa, ale nie mogę wygenerować żadnego akademickiego przykładu, w którym takie rozwiązanie miałoby przewagę nad anonimowym NEXT, skaczącym po prostu do początku najgłębszego FORa.
      • 11: CommentAuthorrudla
      • CommentTime16 Nov 2012 18:11
       
      Specifying the loop variable in next enhances readability and error checking. (With variable name specified, interpreter may easily detect incorrectly nested loops).

      Atari Basic does not do the checking correctly, but it should.
      • 12: CommentAuthormono
      • CommentTime16 Nov 2012 20:11
       
      Pewnie nazwa zmiennej jest dlatego, że basic nie ma instrukcji opuszczenia pętli (c break). Nextów do tej samej zmiennej też zresztą w jednej pętli możesz mieć wiele (c continue).
      • 13: CommentAuthorBluki
      • CommentTime16 Nov 2012 21:11
       
      Ja tak jak Rudla uważam, że w celu lepszej czytelności programu, a przy okazji ułatwienia odszukiwania błędów. Przecież Microsoft BASIC potrzebuje samego NEXT, bez parametrów.
    3.  
      Bardzo cieszę się z Waszych opinii :) Głównie dlatego, że mam podobne przemyślenia, a dodatkowo ułatwi mi to pracę oraz nie narazi kompilatora na utratę wewnętrznej harmonii.

      W bieżącej wersji właśnie tak podszedłem do tematu i zgłaszam błąd kompilacji jeśli wykryję niezgodność FORa z NEXTem. Poniżej przykład.

      Jeśli więc mogę założyć, że taki kod jak poniżej powstaje głównie z powodu błędów programisty, a nie celowo, to jestem spokojny.

      Kod:
      10 FOR I = 1 TO 5
      20 FOR J = 1 TO 3
      30 PRINT I*J
      40 NEXT I
      50 NEXT J
      60 PRINT 666


      Kompilacja:
      Now compiling...
      Variable "I" not used yet. Spawning new one...
      FOR LOOP "I" with BORDER at $6bd0 and STEP at $6ba0
      line: 10 compiled
      Variable "J" not used yet. Spawning new one...
      FOR LOOP "J" with BORDER at $6bd6 and STEP at $6ba6
      line: 20 compiled
      Variable "I" found...
      Variable "J" found...
      Creating temporary variable at location $70c...
      line: 30 compiled
      NEXT: Current loop: "J" - next statement = "I"
      ERROR: FOR/NEXT identifier mismatch
      ****** compilation failed
      • 15: CommentAuthorxxl
      • CommentTime16 Nov 2012 23:11
       
      swietny projekt. bardzo ambitny.

      mam pytanie - a jesli bedzie wiecej niz jeden NEXT dla FOR? przykladowo w petli bedzie rozgalezienie i czesc kodu wraz NEXT bedzie gdzie indziej. nie wiem czy to jest mozliwe w Atar Basic - tak pytam.
      • 16: CommentAuthorrudla
      • CommentTime16 Nov 2012 23:11
       
      The example with switched I and J reports error in Basic at line 50.
      It seems that when some loop ends (I), nested loops are automatically terminated too (J).

      Basic then reports error at line 50, because there is no active loop with variable J.
    4.  

      xxl:

      mam pytanie - a jesli bedzie wiecej niz jeden NEXT dla FOR?

      Na razie się wysypie, ale wydaje się być proste do ogarnięcia, bo powinno dać się zrobić na statycznych labelkach. W Atari Basic jest to jak najbardziej możliwe.

      Natomiast obawiam się innego scenariusza - jakiś wyskok z pętli za pomocą GOTO, potem np. GOSUB i nagle 100 linijek dalej NEXT :) Tego raczej nie da się skompilować, choć w Atari Basic może działać...

      @rudla
      Seems you're right. I will, however, stick to the strict checking of FOR/NEXT consistency at compile time anyway, to reach some decent compromise.

      PS. I'm glad that they didn't decide to allow NEXT VAR$ :)
      • 18: CommentAuthorBluki
      • CommentTime17 Nov 2012 01:11
       
      Warto pamiętać, że są pewne zasady programowania. Innymi słowy: choć BASIC na to pozwala, to pewnych konstrukcji nie należy stosować, pomimo że działają. Głównie z powodu utraty przejrzystości programu, co w konsekwencji może doprowadzić do utraty kontroli nad programem.
      W konkretnym przypadku GOTO na zewnątrz pętli FOR-NEXT powinno być traktowane jako trwałe opuszczenie tej pętli (bez ponownego skoku do NEXT). Wyjście z pętli, wykonanie czegoś i powrót do NEXT – tylko przez GOSUB. Dlatego jakimiś dziwnymi „łamańcami” nie należy się przejmować, bo i tak wszystkich się nie przewidzi.

      To tylko takie moje zdanie.

      Na marginesie: Atari BASIC akceptuje instrukcję GOTO i GO TO.
    5.  

      Bluki:

      Innymi słowy: choć BASIC na to pozwala, to pewnych konstrukcji nie należy stosować, pomimo że działają.
      Problem polega na tym, że nigdy nie wiesz, czy ktoś takiego powiedzmy "błędu" BASICa jakoś kreatywnie nie zastosował i nie oparł na nim jakiegoś triku. No ale potwierdza się powiedzenie, że diabeł tkwi w szczegółach i nawet BASIC nie musi być taki całkiem do końca "prosty" :)

      W konkretnym przypadku GOTO na zewnątrz pętli FOR-NEXT powinno być traktowane jako trwałe opuszczenie tej pętli
      To co proponujesz jest chyba "niekompilowalne", a przynajmniej nie w trywialny sposób. Musiałbym jakoś sprawdzać "nad którymi" linijkami leci GOTO i interpretować to, co w nich jest...

      Zresztą, w Atari Basic poniższy program jest jak najbardziej prawidłowy. I może by się nawet skompilował, ale łatwo wyobrazić sobie całą masę zakręconych konstrukcji, dla których wsparcie w kompilatorze będzie niemożliwe (czyt. możliwe, ale korzyści z kompilacji będą mniejsze niż zwykła interpretacja kodu).
      10 FOR I=1 TO 10
      15 PRINT I
      20 GOTO 100
      30 END
      100 NEXT I


      Na marginesie: Atari BASIC akceptuje instrukcję GOTO i GO TO.
      Dzięki za info - nie wiedziałem... Na szczęście to tylko prosty tweak w gramatyce :)
      • 20: CommentAuthorBluki
      • CommentTime17 Nov 2012 01:11
       
      Z tą "gramatyką", to tak nie do końca - token GOTO to 0A, a GO TO - 0B (hex).

      Pisałem o zasadzie używania GOTO w interpreterze, innych rozwiązań kompilator nie musi uwzględniać - to miałem na myśli.
    6.  
      Tak długo jak GOTO i GO TO nie różnią się działaniem mogę obydwa parsować jako to samo. No chyba, że czymś się różnią, ale wtedy zabieram się za kurs BASICa, a nie za kompilator :)
      • 22: CommentAuthormono
      • CommentTime17 Nov 2012 09:11 zmieniony
       
      Niczym. Podobnie jak DIM i COM, lub jak ? i PRINT.
    7.  
      OK, wracając do FOR... Zezwalając na kilka NEXTów w środku muszę wyłączyć kontrolę spójności pętli, dlatego też dorobiłem do kompilatora przełącznik, który pozwoli użytkownikowi zdecydować jakie zachowanie bardziej mu odpowiada.

      I tak, dla przykładowego programu:
      10 FOR I = 1 TO 2
      20 FOR J = 1 TO 5
      30 IF J = 3 THEN GOTO 37
      31 PRINT I*J
      32 GOTO 40
      37 PRINT 37
      38 NEXT J
      40 NEXT J
      50 NEXT I
      60 PRINT 666
      dostaniemy albo poprawny wynik (obrazek) albo błąd kompilacji:
      NEXT: Current loop: "I" - next statement = "J"
      ERROR: FOR/NEXT identifier mismatch


      • 24: CommentAuthorrudla
      • CommentTime20 Nov 2012 17:11
       
      Is that example correct? I mean what is the meaning of this program? Does not it report error when run in Atari Basic?
    8.  
      It is correct because it executes the FOR/NEXT statements in the correct order. I don't care much about the meaning :)

      Yet for the compiler it is not possible to determine the execution path that the program will follow at compile time, therefore FOR/NEXT consistency checking must be disabled.

      Here's the output from Atari Basic:
    9.  
      Czy w Atari Basic jest jakiś znany bug związany z liczbą "-0"?

      Robię przymiarki do operatorów logicznych i w jednym z eksperymentów dostałem taki wynik:


      Po pierwsze: dlaczego "NOT -0 = 0"? Zwłaszcza, że "0 AND -0 = 0"...

      Po drugie, co to za emotka w 30 linijce listingu? :)

      PS. Jak dla mnie "NOT -0" to ewidentnie powinno być 1.
      • 27: CommentAuthorBluki
      • CommentTime21 Nov 2012 15:11 zmieniony
       
      Wygląda na błąd interpretera.



      NOT -0 nie równa się w tym przypadku 0, tylko NOT "dzikie wyrażenie" = 0.
    10.  
      OK, w takim razie ja pożyczę sposób interpretacji tego wyrażenia z TBXL i Basic XE :)
      • 29: CommentAuthormono
      • CommentTime21 Nov 2012 20:11 zmieniony
       
      Ciekawe.
      Z analizy kodu procedury FPASC ($D8E6 a więc pakiet liczb FP a nie sam BASIC) wynika, że wykładnik liczby -0 jest równy 128. Wg Zientary od linii 890 następuje prosta zamiana wykładnika na dwie cyfry (FP może być co najwyżej 2-cyfrowa) więc starsza cyfra to 12 :) co powoduje wypisanie tego < ('0'+12='<'). Dalej 8 czyli najmłodsza cyfra 128. Czyli niby błąd po stronie FP, ale...
      BASIC parsując wyrażenia zazwyczaj zapisuje liczby ujemne, jako token znaku "-" oraz samą liczbę, jako dodatnią (polecam sprawdzić wynik działania ? FRE(0), ? FRE(1) i ? FRE(-1)). Wygląda na to, że jest błąd w tablicy parsowania składni SXTAB ($A605), ale gdzie konkretnie trzeba by się zastanowić.
      Gratuluję znalezienia błędu BASICa, którego nie ma w atariki :)
      • 30: CommentAuthormono
      • CommentTime21 Nov 2012 20:11 zmieniony
       

      mgr_inz_rafal:

      Po pierwsze: dlaczego "NOT -0 = 0"? Zwłaszcza, że "0 AND -0 = 0"...

      No właśnie z powyższego powodu. Obliczanie wartości logicznej z wyrażenia (tutaj z liczby -0) sprawdza czy liczba FP jest 0 (bajt cechy i znaku liczby = 0), czy jednak nie i wtedy 1.
      • 31:
         
        CommentAuthorjhusak
      • CommentTime21 Nov 2012 21:11 zmieniony
       
      Ech, zazdroszczę (i zapewne nie tylko ja) Wam tej dociekliwości :)
      Nie tylko, że nie bo nie, no bo jak nie jak tak, tylko dogłębna analiza!

      Uczmy się od mgr_inz_rafal i mono!!!

      Z drugiej strony jeśli pisałbym kompilator, to jednak nie implementowałbym błędów z pełną świadomością - zapewne programiści atari basic nie opierają się na tych błędach w celu uzyskania jakichś tam korzyści.
    11.  

      mono:

      Wygląda na to, że jest błąd w tablicy parsowania składni SXTAB ($A605), ale gdzie konkretnie trzeba by się zastanowić.
      Jutro na spokojnie poczytam Twojego posta, bo dziś już nie mam siły na myślenie :)

      Na szybko wydaje się jednak, że coś jest skopane w okolicach instrukcji NOT. Linijka 10 listuje się normalnie, więc to nie problem z samym "-0".

      Wygląda też na to, że twórcy TBXL i Basic XE odkryli (i poprawili) ten problem przede mną, tylko pewnie nie chciało im się aktualizować Atariki :) Może wystarczy porównać tablicę parsowania tych języków z tą obecną w Atari BASIC... Ale to na jakiś wolniejszy weekend :)

      jhusak:

      Z drugiej strony jeśli pisałbym kompilator, to jednak nie implementowałbym błędów z pełną świadomością
      Correct. Takich ewidentnie skwaszonych rzeczy nie będę implementował w kompilatorze. Ale kto wie, może trafi się w końcu subtelny błąd, który wielu programistów traktowało jako celowe zachowanie i zaczęli na nim "polegać" - wtedy, dla kompatybilności - trzeba będzie kompilować to błędne działanie.
      • 33:
         
        CommentAuthorjhusak
      • CommentTime21 Nov 2012 21:11 zmieniony
       
      A co do 0 and -0 to wszystko w porządku, bo drugie 0 czy -0 nie wpływa na całkowity wynik and, nic z tego nie można wywnioskować.

      Z tego, co wydaje mi się, 0 jest traktowane jako zero tylko wtedy, gdy wszystkie 6 bajtów liczby = 0. Więc wówczas jest to błąd parsowania liczby, która '-' traktuje jako znak ZAWSZE ustawiany (czyli obsadzony bit znaku <> '-' jest prefiksem liczby) co generuje błąd, bo niema tam przypadku -0.

      Zero powinno być <> pięć bajtów mantysy jest równych 0, a cecha dowolna.
      • 34: CommentAuthormono
      • CommentTime22 Nov 2012 05:11
       
      @jhusak: no właśnie nie - odpowiedni wycinek:
      0770 ;eXecute NOT operator
      0780 ;
      0790 XNOT JSR GETVAR
      0800 LDA FR0
      0810 ;
      0820 ;RESuLT One
      0830 ;
      0840 RESLTO BEQ ONEP
      0850 ;
      0860 ;result ZERO
      0870 ;
      0880 ZERO LDA #$00
      0890 TAY
      0900 BEQ STRES
      0910 ;
      0920 ;result ONE Positive
      0930 ;
      0940 ONEP LDA #$40
      0950 ;

      FR0 to cecha (ze nakiem) i znak liczby.
    12.  

      mono:

      Gratuluję znalezienia błędu BASICa, którego nie ma w atariki :)
      Już ktoś dodał :)
    13.  
      Na dzisiaj przygotowałem cały zestaw operatorów logicznych. Poniżej kod oraz obrazki z Atari Basic oraz z kompilatora.
      10 IF 5>6 AND (0 OR 3=3) THEN PRINT 1
      20 IF 5>6 AND 0 OR 3=3 THEN PRINT 2
      30 IF 5> NOT 6 THEN PRINT 3
      40 IF 5<>3 THEN PRINT NOT 3 + NOT 0
      50 A=5
      60 IF A=5 THEN A=A + NOT 0
      70 PRINT A
      80 DIM STEFAN(10)
      90 STEFAN( NOT 0)=666
      100 PRINT STEFAN(A - 5)


      Atari Basic:


      ABC:


      PS. 12 zmiennych tymczasowych :)
    14.  
      Hej,
      Poniższa konstrukcja zgłasza błąd. Znacie przyczynę, bo wydaje się, że nie ma tutaj żadnych przeciwwskazań do działania?
      10 DIM T(5)
      20 FOR T(3)=4 TO 8:NEXT T(3)
      • 38: CommentAuthorwieczor
      • CommentTime30 Nov 2012 11:11
       
      Chyba nie znam języka w którym element tablicy może być używany jako iterator :)
    15.  
      No chociażby C
      int main ()
      {
      int a[17];
      for (a[4] = 5; a[4] < 8; ++a[4])
      {}
      }
      • 40: CommentAuthorwieczor
      • CommentTime30 Nov 2012 12:11
       
      I to się kompiluje? Nigdy czegoś takiego nie próbowałem :) No, w Basicu najwyrazniej nie mozna :D Nie w tym :D
    16.  
      W C nawet dużo ciekawsze rzeczy się kompilują :)

      Polecam ioccc.org.
      • 42: CommentAuthormono
      • CommentTime30 Nov 2012 15:11
       
      Wygląda to znów na ograniczenie nałożone przez tablicę kontroli składni, bo sama procedura NUMVAR służąca do określenia rodzaju zmiennej numerycznej potrafi rozpoznać, że ma do czynienia ze mienną tablicową.
      Gramatyka Panie, gramatyka...
      • 43:
         
        CommentAuthorjhusak
      • CommentTime30 Nov 2012 21:11
       
      Jak sama nazwa wskazuje: zmienna sterująca pętli for, a nie l-wartość sterująca.
    17.  
      Jak nazwa wskazuje "zmienna", czyli l-wartość :)
    18.  
      Dzisiaj przedstawiam dokończonego PRINTa. Dodałem obsługę stringów oraz przecinka i średnika.

      Np. tabliczka mnożenia:
      10 FOR I = 1 TO 9
      20 FOR J = 1 TO 9
      30 PRINT I;"*";J,"= ";I*J
      40 NEXT J
      45 PRINT "---"
      50 NEXT I
      60 PRINT 666




      I jeszcze programistyczny klasyk, czyli trójkąt z gwiazdek:
      10 FOR I = 15 TO 1 STEP -1
      20 FOR J = 1 TO I
      30 PRINT "*";
      40 NEXT J
      50 PRINT
      60 NEXT I
      70 PRINT 666


    19.  
      I jeszcze od razu pytanie o tabulator. Jak BASIC ma domyślnie ustawione Tab Stopy?

      Poniżej dwa obrazki powstałe z takiego kodu:
      10 PRINT 1,2,3,4,5,6,7,8,9
      Pierwszy to Atari Basic, a drugi to program skompilowany.

      Obsługa przecinka to u mnie po prostu wypisanie znaku 127, ale może coś jeszcze trzeba zrobić? Mieszanie w komórce 201 ($D9) nie daje efektów.

      • 47: CommentAuthormono
      • CommentTime3 Dec 2012 15:12 zmieniony
       
      Są dwa skoki tabulatora (niezależne od siebie):
      1. Realizowany przez "," w instrukcji PRINT.
      2. TAB edytora (CHR$(127)).
      Pierwszy ustalony jest podczas startu BASICa na 10 w rejestrze PTABW ($C9) i przepisywany do tymczasowego licznika AUXBR w procedurze PRINT. Modyfikacja PTABW np za pomocą POKE wpływa na działanie PRINT.
      Drugi jest efektem wykonania kodu sterującego edytora ekranowego i zależy od pozycji tabulacji ustalanych w tablicy TABMAP ($2A3..$2A7) lub bezpośrednio w edytorze za pomocą klawiszy Shift+TAB (CHR$(158)), Ctrl+TAB (CHR$(159)).

      Edit: IMHO zamiast używać edytora powinieneś rysować tyle spacji ile wskazuje PTABW.
    20.  
      Ale wartość PTABW nie zmienia się dynamicznie podczas PRINTa, nie?

      W takim razie rysując po prostu 10 (domyślnie) spacji, uzyskał bym inny output niż w AtariBasic dla poniższego programu. Basic raz wypisał 7 spacji, a w linijce pod spodem już tylko 6.

      • 49: CommentAuthormono
      • CommentTime3 Dec 2012 19:12 zmieniony
       
      Nie zmienia się dynamicznie. Punktem w którym kończy się malować spacje jest wielokrotność PTABW (ustalana w tymczasowym rejestrze AUXBR od etykiety COM w procedurze XPRINT ->link<- ). Tab wykraczający poza szerokość ekranu ląduje na lewym marginesie następnego wiersza.
      Z kolei PTABW można zmieniać między PRINTami. Resetowany na 10 jest bodajże tylko przy NEW i po starcie BASICa.
    21.  
      OK, obszedłem problem za pomocą przydatnej komórki $55 i rysuję tyle spacji ile brakuje do wielokrotności 10.

      Efekt jest jeszcze trochę inny (obrazek) niż daje XPRINT - liczby są idealnie jedna pod drugą. Właściwie nawet ładniej niż w Atari Basic, więc chyba tak zostawię :)

      PS. Kto inicjuje PTABW? Jak odpalam .xex to jest tam 0, a nie domyślne $a.