atarionline.pl Strumień bitów na bajtach - 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: CommentAuthormarok
    • CommentTime18 Apr 2023
     
    Mam nietypową potrzebę: 'zredagować' strumień bitów.
    (Tak w ogóle pomysł dopiero z wczoraj - wieczór.)

    To samo dla bajtów (poniekąd "strumień bajtów") robi się naturalnie i prosto:

    str dta c'ADC'
    dta c'BCC'
    dta c'LDA'


    by otrzymać: 'ADCBCCLDA'

    (mniej więcej o to by chodziło - tylko z bitami)

    str dta x(%101)
    dta x(%111)
    dta x(%1001)


    by otrzymać: %01111101, %00000010 (dwa bajty)
    lub (wersja alt.): %10111110, %01000000 (odwrotna kolejność wypełniania bajta bitami)

    "x" z przykładu to tylko wolny przykład (bez znaczenia)

    Składanie całych bajtów z małych porcji bitów samodzielnie jest o tyle uciążliwe, że nie pozwala na prostą podmianę zawartości bitów w przypadku (primo - takiej potrzeby) zmiennej długości porcji bitów, które mogą się na danej 'pozycji' znaleźć (przesuwając całą resztę bitów w strumieniu o różnicę długości, jaka może z tej tylko jednej zmiany wynikać - zaburza to podział strumienia na poszczególne bajty).
    • 2:
       
      CommentAuthorpirx
    • CommentTime18 Apr 2023
     
    słuchaj, nie mam dla Ciebie gotowego rozwiązania, ale jak poszukasz huffman encoding 6502 to Ci wyskoczą programiki, które w środku mają takie cosie. no ale cudów nie ma, to trzeba rolować i orować z dotychczasowym buforem.
    • 3: CommentAuthormarok
    • CommentTime18 Apr 2023
     
    Po pierwsze, dziękuję za odpowiedź.

    Prawdopodobnie najlepszą opcją potencjalnie jest napisanie niedługiego programiku do 'klecenia' tego postulowanego potoku (strumienia) bitów (tutaj można by się oprzeć na przykładzie, jaki chociaż zasugerowałeś do wglądu).

    A tam nie obejdzie się bez "trzeba rolować i orować z dotychczasowym buforem", jak uprzedzasz.

    Ma to ten minus, że nie scala się to z kodem źródłowym (zawsze to zewnętrzny plik łączony ze źródłem, który osobno trzeba kompilować).

    W gruncie rzeczy byłoby absurdalne żeby podobną czynność wykonywał za nas jakiś asembler (bo przykłady zapotrzebowania na taki 'ficzer' wydają się nie istnieć). Natomiast rozglądnę się jeszcze może za jakimś podobnym narzędziem (może być jakiś asembler), który by pozwalał rzecz sobie uprościć w tym znaczeniu, że by generował sam binarkę (potok tych bitów) z przygotowanego tekstu symbolicznego (używam bardzo ogólnych pojęć, bo sam nie wiem, co to może jeszcze być).

    Napisanie (osobnego) programiku do generowania takiego strumienia jest jeszcze (sądzę) w moim zasięgu.

    Poza tym pozostaje dekodowanie tego potem (potoku), co jest już nie do ominięcia (niezależnie jak bardzo sobie ułatwiłbym wcześniej przygotowanie takiego potoku), a co też łatwe dla mnie nie będzie.
    • 4:
       
      CommentAuthorlaoo
    • CommentTime18 Apr 2023
     
    Makra MADSa są dość silne. Coś czuję że potrafiłyby sklecić taki ciąg.
    • 5: CommentAuthormarok
    • CommentTime18 Apr 2023
     
    Dobra myśl. Dzięki.
    • 6: CommentAuthorKonop
    • CommentTime18 Apr 2023 zmieniony
     
    mads concatenateBitfields.as8 -c -s -l -x
    Usprawnienia pozostawiam jako pracę domową.
    • 7:
       
      CommentAuthorpirx
    • CommentTime19 Apr 2023
     
    oh shit, teraz nie usnę :)))))
    • 8:
       
      CommentAuthorlaoo
    • CommentTime19 Apr 2023
     
    Omatkobosko!

    Teraz to przydałby się konkurs, kto zrobi najkrótsze makra realizujące te zadanie ;)
    • 9:
       
      CommentAuthorPecus
    • CommentTime19 Apr 2023 zmieniony
     
    Może poprosić jednak autora o wprowadzenie odpowiedniej funkcji natywnie.
    Mogłaby wyglądać jakoś tak:
    dta x"01001"
    dta x"110101"

    i póki zachowana jest ciągłość bity "sklejane" byłyby w bajty, a w przypadku braku ciągłości zaokrąglenie do pełnego bajtu i koniec.
    Ciekawe byłyby adresy w przypadku "przeplatania" takiego ciągu etykietami. Trzeba by wtedy ustalić w którą stronę jest zaokrąglenie do pełnego bajtu. Z trzeciej strony może taka etykieta powinna działać jak brak ciągłości i powodować tworzenie po niej nowego ciągu od pełnego bajtu...

    Ale faktycznie to byłaby przydatna funkcjonalność.

    Aaaaa i z premedytacją użyłem "" i tekstu "bitowego" pomiędzy.
    Wydaje mi się, że trzeba tutaj precyzyjnie panować nad ilością bitów i może taki zapis byłby lepszy, bo klasycznie %101011 jest traktowane jako %00101011 więc trzeba to jakoś odróżnić i wymusić dokładnie tyle bitów ile chcemy.
    • 10: CommentAuthormono
    • CommentTime19 Apr 2023
     
    Jest w asemblerach, również w MADS-ie, taka konstrukcja jak .HE. Zawsze mnie to zastanawiało jaka jest niby korzyść z .HE xxxxxx w porównaniu z .BYTE $xx,$xx,$xx. Argument że tam się przecież nie daje dolara i przecinków, to uważam za kretyński i na poziomie tych wszystkich idiotów, którzy przewagi języka pokazują na przykładzie ilu instrukcji trzeba użyć żeby napisać heloł łorld na ekranie. Wielka mi oszczędność. Ile razy w życiu pisze się program z heloł łorld?
    Ale gdyby to .HE potraktować właśnie jako jakiś mechanizm do wprowadzania strumieni cyfr (w tym przypadku hex, ale nikt przecież nie broni dodania dyrektywy .BI) wtedy to by załatwiało sprawę.
    A w ogóle to fajnie by było mieć mechanizm do definiowania własnych funkcji będących zwykłymi programami zewnętrznymi z listą argumentów przekazywanych jako parametry linii poleceń. To załatwiłoby wszystkie sinusy i kosinusy bez potrzeby imlementowania ich przez TeBego. Przecież argumentem jest tekst i w wyniku też jest tekst.
    A program realizujący funkcję można by sobie wtedy napisać w czymkolwiek. Nawet w Logo.
    • 11:
       
      CommentAuthorlaoo
    • CommentTime19 Apr 2023
     
    @mono wykonywanie zewnętrznych komend byłoby zabójcze dla czasu asemblacji.
    • 12:
       
      CommentAuthorPecus
    • CommentTime19 Apr 2023 zmieniony
     
    Tym bardziej, że używanie tych zewnętrznych komend ma sens przy generowaniu tablic czy czymś podobnym, co zazwyczaj jest czynnością jednorazową i lepiej wynik działania mieć po prostu wklejony w źródle (lub includowany).

    Co nie zmienia faktu, że taki strumień bitów, o który chodzi od początku, byłby na prawdę przydatny.
    • 13:
       
      CommentAuthorjhusak
    • CommentTime19 Apr 2023 zmieniony
     
    @mono
    To .BI jest zajebistym pomysłem!
    Robisz
    .BI 01000 11 11010 11 11 1 001010 1 1001
    .BI 11110 10001 10001 1001 100010

    I Ci składa bity do bitów (Big Endian) i zapamiętuje jako strumień.

    A jak potem dasz HEX to Ci do bajta wypełnia podobnie, jak przy wypełnianiu pustych przestrzeni bajtami (zerami bądź jedynkami)

    Zakoduj!

    A po dodaniu możliwości wywoływania zewnętrznego kodu stracisz kompatybilność. Wg mnie wywoływanie zewnętrznego kodu z rezultatem do pliku a potem inkludowanie tego pliku nie nastręcza żadnych problemów.
    • 14: CommentAuthortebe
    • CommentTime19 Apr 2023
     
    .HE został zapożyczony z innych assemblerów, korzyścią jest brak potrzeby wpisywania znaku '$' oraz przecinków ','

    np. dużo prościej można stworzyć jakiś skrypt który plik binarny zamieni na ASM z wierszami .HE w zadanej ilości
    • 15:
       
      CommentAuthorPecus
    • CommentTime19 Apr 2023
     
    @tebe

    A co z .BI ?
    (choć osobiście wolałbym zapis, który ja proponowałem :) )
    • 16: CommentAuthormarok
    • CommentTime19 Apr 2023
     
    @Konop: Dziękuję za uwagę, poświęcony czas i zrobienie jakiejś procki (piszę "jakiejś" bo jeszcze jej nie widziałem).


    Obecnie korzystam ze środowiska linuxowego, z emulatorów aktualnie Atari800 (długo używałem Altirry, choć tylko starszych wersji).

    Dostaję tylko taki komunikat:
    "This is not an Atari800 state save file."


    Pomysły jakie się pojawiają, choć nie wszystko "chwytam" najlepiej, wydają mi się przemyślane (Pecuś, mono, jhusak) i z tego powodu warte rozważenia (gdyby pojawiły się takie chęci). Z drugiej strony wciąż nie widzę w miarę sensownych zastosowań dla takiej funkcjonalności - oczywiście mogę się mylić.


    (Operowanie porcjami bitów jest, jak to się mawia w podobnych sytuacjach, dość "hardcorowe" i ciężko to chyba uzasadnić - znaleźć faktyczną potrzebę takich działań.)


    Opiszę jednak swój problem czy pomysł, korzystając z okazji (czy też tłumacząc swoje zainteresowanie taką możliwością).

    Miałem problem z wieloma stosunkowo zestawami tablic (tak z 9), różniących się w sumie niewiele. Na każdej z pozycji w tablicy mógłoby się pojawić do 4, 5, a zwykle tylko 2 czy 3 hasła - przypisane do tej pozycji (zależnie od tablicy).

    Więc pomyślałem, żeby zamiast robić osobne tablice (trochę już pod 30 bajtów każda, czyli tyle pozycji w tablicy), to można zrobić to trochę inaczej (chciałem krócej).

    Każda pozycja opisana byłaby bitami wyboru hasła z puli przypisanej do pozycji. Każda pozycja dla tablicy opisana byłaby kolejno po sobie tworząc tak strumień bitów.

    Deklaracje puli dla kolejnych pozycji by następowały po sobie, a ich granice zaznaczone 7 bitem elementów tego ciągu (ciągu indeksów wszystkich haseł do tablic, których jest akurat mniej niż 128).

    Dużo pisania, a pewnie mało czytelne, ale teraz będzie trochę konkretniej…

    zapis wyboru w pozycji z puli (zależnie od zakresu wartości, który jest znany dzięki oznaczeniom granicy puli)

    0  1
    0 01 11
    00 01 10 11
    00 01 010 011 110 111
    000 001 010 011 100 101 110 111
    000 001 010 011 0100 0101 0110 0111 1100 1101 1110 1111


    kolejne wybory w pozycji oddzielone są spacją
    wiersz to kolejne wybory w pozycji (dla zakresu), ich liczba determinuje liczbę bitów które są potrzebne do zapisu wyboru pozycji

    szczególny przypadek (wyżej go nie widać), gdy de facto wyboru nie ma (hasło jest wspólne dla wszystkich tablic), nie trzeba pobierać żadnego bitu i na jego podstawie określać wyboru hasła dla pozycji, bo on jest znany od początku (odczytano z ciągu tylko wartość >127, trzeba ją teraz pozbawić tylko bitu 7 i znamy indeks z tablicy wszystkich haseł, więc znamy też hasło)

    gdy mamy do wyboru 3, 5-6 haseł dla pozycji, korzystamy dodatkowo z sytuacji, że niekóre 'indeksy wyoborów' są krótsze o 1 bit od reszty (1 zamiast 2, 2 zamiast 3)
    to wykorzystujemy tak, że segregujemy hasła w zależności od częstości występowania (pierwsze wybory dla pozycji są tymi najczęściej występującymi)

    Troszkę myślę teraz nad procedurą dekodującą taki zapis. Mam już coś, ale zupełnie nie przetestowane i jeszcze nie skończone. Ogólnie trochę może być to za długi kod by całość dla mojego zastosowania miała sens (razem dawała krótszy bin), ale przynajmniej zmierzę się z takim zadaniem (satysfakcja)
    • 17:
       
      CommentAuthorPecus
    • CommentTime19 Apr 2023 zmieniony
     

    marok:

    (Operowanie porcjami bitów jest, jak to się mawia w podobnych sytuacjach, dość "hardcorowe" i ciężko to chyba uzasadnić - znaleźć faktyczną potrzebę takich działań.)


    A widzisz... to nie do końca tak jest z tą hardcorowością bo procka to robiąca może być dość prosta i krótka.

    Mój przykład ze Scorcha:
    Jest w sumie 32+16=48 broni, każdy z graczy komputerowych ma trochę inną politykę zakupów, więc dla każdego z nich istniała tablica z zaznaczonymi brońmi, które może próbować kupić. Mamy 7 poziomów trudności i każdy miał tablicę 48b (nie do końca prawda bo polityki się powtarzają :) ). Czyli jest 336 bajtów na tablice, które po "ubitowieniu" mają 42b.

    Nawet jeśli procka sprawdzająca jest trochę dłuższa (a tak jak patrzę na oko, to jest to to kilka bajtów).... Mamy ponad stronę pamięci oszczędności.

    A to tylko jeden z (chyba 3) przykładów w jednym programie, który trzeba było upychać w cartridge szukając czasem pojedyńczych bajtów do wyrzucenia.
    • 18: CommentAuthorKonop
    • CommentTime19 Apr 2023
     
    W Ryszardzie Niebezpiecznorękim kodowanie definicji obiektów bitowo może okazać się kluczowe, aby upakować grę w 64KB. Oszczędności idą w setki bajtów, bądź nawet kilka KB.
    • 19: CommentAuthormono
    • CommentTime19 Apr 2023 zmieniony
     

    laoo:

    wykonywanie zewnętrznych komend byłoby zabójcze dla czasu asemblacji.
    Oczywiście. Ale wtedy kupujemy więcej rdzeni. Nie ma obowiązku używania własnych funkcji. Wolisz jednak mieć nawet wolny mechanizm, czy nie mieć wcale i wszystko przygotowywać na boku w Makefilu?

    jhusak:

    A po dodaniu możliwości wywoływania zewnętrznego kodu stracisz kompatybilność.

    A nawet spójność języka.
    I zrobiłby się bałagan z funkcjami zewnętrznymi, bo trzeba by mieć repozytorium, a jeden umieści swoją funkcję, inny nie umieści. Po 20 latach dostaniesz od kogoś kod, którego nie skompilujesz MADS-em, bo nie masz funkcji zewnętrznych.
    Do tego problemy z nazewnictwem takich funkcji - trzeba by robić przestrzenie nazw (choćby jako pakiety czyli struktura podkatalogów). Robi się z tego przedsięwzięcie.

    jhusak:

    Wg mnie wywoływanie zewnętrznego kodu z rezultatem do pliku a potem inkludowanie tego pliku nie nastręcza żadnych problemów.

    Tak, i rozszerzony ICL z ilością linii i offsetem.

    tebe:

    .HE został zapożyczony z innych assemblerów, korzyścią jest brak potrzeby wpisywania znaku '$' oraz przecinków ','

    Tak, o czym to ja... :)
    • 20: CommentAuthormarok
    • CommentTime19 Apr 2023
     
    Uzmysłowiłem sobie, że w załączniku od @Konop jest źródło, a nie state emulatora. ;)

    (na takim mniej więcej poziomie stale myślę… i jakoś z tym jeszcze dawać radę ;) )

    Trochę trudno mi je ugryźć (niezrozumiały zapis formalny), ale może 'później' się jeszcze przyda (przyglądnę się staranniej) - dziękuję.

    @Pecuś: Dzięki za Twoją historię z programowania gry.

    Myślę sobie jednak, że jeśli nie ma zbyt skomplikowanych złożoności w przygotowywaniu bajtów dla programu z bitowych porcji, to trudno strzelać "armatami w… ". ;) (znaczy tworzyć ficzer dla potrzeb, które można spełnić stosunkowo prostymi zastępnikami). (Trzymam się póki co swojego "zdania")
    • 21: CommentAuthortebe
    • CommentTime20 Apr 2023
     
    ->link<-

    dodana obsługa dyrektywy .BI binary

    .bi 110101, 101010, 000*

    .bi 1 11 101 11* 10101*

    znak '*' na końcu ciągu oznacza invers
    • 22: CommentAuthorKonop
    • CommentTime20 Apr 2023 zmieniony
     
    Sama definicja strumienia/ciągu bitowego to jedno. Problem jest szerszy i sprowadza się do tego jak w praktyczny i wygodny sposób korzystać z takiej definicji. Pospekulujmy nad alternatywną reprezentacją:

    BITFIELD0_SOME_VALUE0 = %111111

    .bitstring SomeBitString
    bitfield0(6) // 4-bit bitfield
    bitfield1(8) // 8 bit bitfield
    bitfield2(16) // 16 bit bitfield
    .endb

    .var SomeBitString myBitString // Shall be capped to a byte , if followed by a non bitstring in a structure or not followed by any entry in a structure

    bitfield_write #myBitString, #bitfield0, #BITFIELD0_SOME_VALUE0 // custom run-time procedure
    bitfield_read #myBitString, #bitfield2, #dst // custom run-time procedure

    Oczywiście można to samemu opakować meta-danymi (offsety i rozmiary pól bitowych), ale to wymagałoby dodatkowych definicji.
    • 23: CommentAuthormarok
    • CommentTime21 Apr 2023
     
    Stało się nieoczekiwane…

    Mam nadzieję, że będzie się przydawać.

    Z tego co podpatruję w kodzie MADSa po zmianach, to inwers jest jakby zastosowaniem funkcji NOT - 0 bitowe jest brane za 1, i odwrotnie (faktycznie to klasyczny inwers).

    Spacje są pomijane (za to są dopuszczalne w zapisie formalnym) jako (lub prawie) bez znaczenia i chyba równoważne przecinkowi (może zakreślają tylko granicę działania inwersu).
    Można tekstowo definiować strumień jako porcje zer i jedynek - i tylko tak.


    A jeśli są dwa kolejne wiersze definicji .BI (niczym innym nie przedzielone) to ta druga kontynuuje 'pracę' pierwszej (dopełnia ostatni bajt tamtej, jeśli się nie wypełnił) czy zaczyna od 'zera'? (zgaduję, że raczej to drugie)
    • 24: CommentAuthormarok
    • CommentTime21 Apr 2023
     
    @Konop: ja mało "jarzę", ale zwróciłem uwagę i ciekaw jestem poprawności tego zapisu:

    "bitfield0(6) // 4-bit bitfield"

    to 6 w nawiasie definiuje chyba liczbę bitów, a komentarz opatrzony jest inną wartością - 4.

    Podejrzewam że to jaka drobna nieścisłość edytorska (lub jednak nie ma tam żadnej "omyłki" ? )

    "Shall be capped to a byte , if followed by a non bitstring in a structure or not followed by any entry in a structure"

    Przy okazji zauważę, że to koresponduje trochę z tym, o co pytałem w swoim ostatnim akapicie.
    • 25: CommentAuthortebe
    • CommentTime21 Apr 2023
     
    spacje są traktowane jak znak przecinka, nowy wiersz rozpoczyna od nowa
    • 26:
       
      CommentAuthorgienekp
    • CommentTime21 Apr 2023
     
    W języku Verilog dla FPGA gdzie praca na bitach jest podstawą zrobili trik z cyferką:
    8'b010
    10'd27
    32'hFF
    ATARI pracuje na 8-bitach więc bez "cyferki" domyślnie może być 8 bit. Ale jakby coś tam jeszcze wymyślić dla 16-bit to mogło by się przydać, typu:

    .biW 110101, 101010, 000*
    • 27: CommentAuthorKonop
    • CommentTime21 Apr 2023
     
    @Marok. Tak, miało być 6-bit bitfield.
    • 28: CommentAuthormarok
    • CommentTime21 Apr 2023
     
    @tebe: Dziękuję.

    Długi zapis w wierszu pewnie da się złamać przez "\" (logiczna kontynuacja poprzedniego wiersza).
    W zastosowaniu z .BI może się szczególnie przydawać.

    @Konop: Ok, thnx.
    • 29: CommentAuthortebe
    • CommentTime21 Apr 2023
     
    nowsza wersja na GitHub-ie po poprawkach, aby .BI nie psuło innych dyrektyw

    tak, znak '\' pozwala kontynuować

    .bi 10 \
    10

    otrzymujemy $A0
    • 30: CommentAuthormarok
    • CommentTime22 Apr 2023
     
    W nawiązaniu, bo chciałbym ewentualnie uzyskać opinię. Czy miałoby sens wykorzystanie strumienia bitów do kompresji czystej postaci tekstów "plain text"?

    Tak skompresowane teksty mogłyby uzyskać stosunkowo nieźły stopień kompresji.

    Wydaje mi się, że miałyby zastosowanie do niezbyt długich źródłowych tekstów pod jakiś ekran (z opisem działania programu) lub może nawet jakiś skrol (przy chwilowo mniejszym obciążeniu procesora innymi zadaniami).
    (To w związku z dużą ilością rolowania bitami przy depackowaniu z powrotem.)

    Łatwe do przygotowania i wyeksportowania do Atari (jeszcze przed spakowaniem). Trochę gorzej, że może trzeba by zwykle jeszcze konwertować w procedurze na kody ekranowe (dodatkowy czas zabierany procesorowi) po powrotnej konwersji.

    Pozytywna strona to także to, że procedura rozpakująca mogłaby być najmniejszych rozmiarów.

    Co do stopnia konwersji to da się na pewno (wg mnie) zrobić to tak:
    I ćwiartka ASCII - 10 bitów/ znak,
    II i III ćw. - 6 bitów/ znak,
    IV ćw. - 5 bitów/ znak.

    ponieważ najwięcej znaków jest w IV ćwiartce kodów ASCII (małe litery) a najmniej w I (kody sterujące - głównie chodzi o znak końca linii i ew. tabulator) - taki podział bym zaproponował

    Kody ascii to tylko 7 bitów, więc nie ma tutaj miejsca na kody w inwersie (np. atarowski znak końca linii). Można na tym poprzestać, albo tą propozycję inaczej sformułować - jak uważacie.

    Co do sposobu kodowania jeszcze.
    Generalnie w decodingu przyjmujemy tutaj, że znak jest na 5/6 bitach z obszaru ostatnich 3 ćwiartek kodów ascii.

    Konkretniej, kodowanie jest takie, że:
    %0xxxx to są kody IV ćwiartki, a
    %x1xxxx to są kody II i III ćwiartki
    (nawiązuję do tego sposobu zapisu liczb/indeksów, jaki wcześniej prezentowałem w wątku)
    Kod %01111 (mapuje $7F - jedyny kod sterujący poza obszarem I ćwiartki) przełącza obszar kodowania na I ćwiartkę i tylko na jeden nadchodzący znak (%xxxxx).

    Dlatego, jeśli chodzi o wybór tekstów źródłowych "plain text" do konwersji, byłoby wskazane używać tych z oznaczeniem końca wiersza jednym tylko kodem sterującym ($0D lub $0A). Inaczej na każdy znak końca linii trzeba by dodawać kolejne 10 bitów, co byłoby nieco kosztowne (i bardziej uciążliwe w decodingu ze względu na ew. omijanie sytuacji traktowania obu tych znaków idących jeden po drugim jako dwóch znaków końca linii, a nie jednego).

    Napisałem już wcześniej, że najlepiej nadawałoby się to do tekstów krótkich (krótszych). Ten pogląd wnoszę z tej racji, że kompresja słownikowa, na której ten sposób zupełnie się nie opiera - dodatkowo, spekuluję, ją zablokowuje dla ew. drugiego stopnia kompresji (czyniąc ją nieefektywną) - uzyskuje dobre rezultaty przy dłuższych tekstach. Poza tym jest szybsza niż to, co jest (zdaje się) oparte o metodę typu "drzewo Huffmana" (przepraszam, jeśli się mylę, ale coś tak to kojarzę, a zupełnie niedawno miałem okazję sobie o tym pojęciu przeczytać i przypomnieć).

    Kompresja, wychodziłoby z tych założeń, byłaby może 30%. Z pewnością nie mniejsza niż 25% - licząc do pełnych bajtów, jak to funkcjonuje w formacie PT, a nie do wielkości 7 bitów na znak ascii (bo to drugie podejście też ma swoje uzasadnienie).

    Co do procedury depakującej, to zapewne każdy zainteresowany mógłby ją napisać sam. W ogóle cały ten pomysł zrodził mi się z tego, że szukałem jakiegoś 'praktycznego' zastosowania dla procedury depakującej, którą ewentualnie gotowy byłem zaprezentować (dodatkowo przetestować), a która radziłaby sobie z podonym sposobem zapisu liczby na n/n+1 bitach (element drzewa Huffmana?).
    • 31: CommentAuthortebe
    • CommentTime22 Apr 2023
     
    w czasach świetności zinów kompresja tekstu była powszechna, najczęściej znak był prezentowany za pomocą 5-bitów

    przykład kompresora, dekompresora wykorzystującego m.in. Huffmana

    ->link<-
    • 32: CommentAuthormarok
    • CommentTime22 Apr 2023
     
    Ale, mnie się 'chyba' coś pomyliło.

    Kurcze, niestety pomyliłem się o "rząd wielkości" w swojej rozpisce… (normalnie napisać by wypadało: "ale wtopa", ale ja się często mylę, więc to zupełnie 'normalne' - wiecie).

    Powinno być (chyba):

    I ćwiartka ASCII - 11 bitów/ znak,
    II i III ćw. - 7 bitów/ znak,
    IV ćw. - 6 bitów/ znak.

    A to, niestety, zmienia postać rzeczy.


    @TeBe: dziękuję, postaram się zapoznać (znów coś z czymś wcześniej mogłem się zapoznać)
    Jeśli rzeczywiście na 5 bitach koduje (większość) znaków, to jest bez wątpienia lepsze.
    • 33: CommentAuthortebe
    • CommentTime22 Apr 2023
     
    kompresory dołączone do Energy Zin-a, autorem jest Jaskier
    • 34: CommentAuthormarok
    • CommentTime22 Apr 2023
     
    Paker Jaskiera (w wersji wyłącznie do znaków z zakresu ascii) - mój komentarz. Jest napisane (sprawdziłem w wydaniu online), że mogą osiągnąć wydajność przekraczającą nawet 40% (jak rozumiem). Wynik to zaiście dobry, jeśli nie znakomity.
    "Pliki tekstowe packowane tą metodą skracają się do ok. 55-60% swoich poprzednich rozmiarów."

    Warto było powtórzyć sobie tą lekturę (wiadomo, że się czytało).

    Zważywszy na to, że wysoka wydajność tego typu pakera osiągana jest na tekstach raczej długich (w stosunku do dostępnej pamięci komputera klasy Atari), wydaje mi się, że wciąż pozostaje jakaś nisza jeszcze na coś trochę prostszego i działającego względnie wydajnie na raczej krótszych tekstach.

    Paker Jaskiera bardziej pasuje do artykułów do zina, liczonego bajtami tekstu, na dziesiątki KB objętości. Rozpakowujemy wszystko od razu (czy dałoby się inaczej dla tej innej metody?), a potencjalnie (zgaduję, nie wiem) czas tego procesu może być nieco przydługawy w niektórych zastosowaniach.


    Pomyslałem jeszcze nad "zoptymalizowaniem" metody pakowania. Trochę to komplikuje 'algorytm', niestety, ale wydajność może być zbliżona do tego, co sugerowałem za pierwszym razem.


    Rozpisałem sobie (z komentarzem) to tak:

    %xxxxx {- %11111} znak z ćw. IV
    %11111 przełączenie w inny tryb (do innej ćwiartki)

    %0/%x1 ćwiartka II/I,III

    %0/%1 zdefiniowany znak z ćwiartki/ wybór z wszystkich
    %0/%x1 jedno powtórzenie / definiowana liczba powt. (%01 + %xxx[x?]) lub do spec. zaznaczenia (%11) - kodu "wybranego" (zdefiniowanego, tego samego j.w., bo w tej sytuacji do wykorzystania) ze znaku z ćwiartki (5-bit fix.)
    [%xxxxx (…)] deklaracje znaku/-ów

    zdefiniowany znak z ćwiartki (w zależności od ćwiartki)
    II: spacja (%00000)
    I: 'eol' (%01010 ?)
    III: "@" (%00000) albo coś innego

    1 znak z ćwiartki II - 13 bitów (5+1+1+1+5),
    1 znak z ćwiartek III i I - 14 bitów,
    1 spacja - 8 bitów
    "eol" - 9 bitów

    Jeśli tekst byłby napisany (choćby dłuższymi fragmentami) wielkimi literami, to też by się jakoś (choć gorzej) spakował (do mniejszego rozmiaru niż tekst wyjściowy), bo wykorzystalibyśmy "definicję liczby powtórzeń" / "powtórzenie do znaku zdefiniowanego" (to powinno zrównoważyć straty wynikające z 'dekodingu doprowadzającego' do tego miejsca).

    W tym względzie można pomyśleć jeszcze o powrocie z powtórzeń (ogólnie, ze specjalnego trybu w zwykły tryb dekodowania, po 5 bitów, do niekoniecznie IV ćwiartki, ale do definiowanej - 'dominującej' - w zależności od wyboru - jakimś kodem 'tasującym' ćwiartki)

    Ogólnie, wciąż wydaje mi się, że kod dekodera udało by się utrzymać na nieskomplikowanym poziomie.
    • 35: CommentAuthormarok
    • CommentTime25 Apr 2023 zmieniony
     
    Z netu ściągnąłem plik o nazwie "sample-text-file.txt" o długości 446 bajtów (sentencje po łacinie).

    Mając taką "podkładkę" wyliczyłem, że opisane metody 1 i 2 dadzą (z dokładnością do ok. dwóch bajtów niedoszacowania), odpowiednio na tym pliku, po spakowaniu - wielkość i oszczędność:
    347 B i 22%, 321 B i 28%.

    Metodą ZX0 pakuje się ten sam plik do 317 bajtów (użyłem "Salvador").

    Najbardziej jestem zaskoczony wynikiem ostatniego programu, który tą rywalizację, wygląda na to że, wygrywa (fakt że mało co zdążyłem sprawdzić).

    Jest to program z katalogu AOL o nazwie "KOMPRESOR BITOWY" H.Cygerta. A wynik to są jedynie 302 bajty.
    Sprawdziłem jeszcze, że bardzo dobrze pakuje pliki EED, co porównam może jeszcze z wynikami uzyskiwanymi przez paker Jaskiera.

    (Dodając tylko sam nagłówek do pliku tekstowego, a więc 6 bajtów, wynik pakowania skoczył aż do 334 bajtów. Próbowałem na takim pliku z nagłówkiem sprawdzać inne pakery, które działają na plikach, ale raczej bez powodzenia - tzn. udało się tylko z FP2.0 - zgłasza zysk 1%.)

    Dziwne jest to, że program prosi przed zapisem o "adres dekompresji", a żadna zmiana tego adresu nie wpływa na zawartość danych wyjściowych.

    Tak jakby był to adres dla procedury depakera, ale nie ma nigdzie widocznej opcji żeby można było go sobie rzeczywiście nagrać z programu.

    edit:
    Paker Jaskiera pakuje ten dobrany mój przykładowy tekst najlepiej, dając w rezultacie 295 B.

    (Wersja 2, która nie ma ograniczenia do najmł. 7 bitów w bajcie - 311. Więc ta 2 wer. wypada nieznacznie gorzej od KOMPRESORA BINARNEGO, który także tego ograniczenia nie posiada - ale to tylko dla tak krótkich plików tekstowych.)

    Stwierdziłem też, że KOMPRESOR BITOWY działa tak samo (długość pliku wynikowego) dla zwykłego tekstu EED, jak i dla pliku po przygotowaniu (po zmianie bajtów końca linii z $DB na $7F).

    Uzyskany rezultat pakowania na wybranym pliku EED po zamianie kodu końca linii na $7f ("WSTEPN.EED" z 1 numeru Energy Zin, 5137 B).

    PaJAS1: 3217 B,
    PaJAS2: 3280 B,
    KOMBIT: 3544 B.

    edit2:
    (po zmianach końca linii na bajt $7E tym razem - z tych moich propozycji, 1 metoda pak. bit. przewidywana dla plain text'ów)
    metod1: 4403 B.
    • 36: CommentAuthormarok
    • CommentTime6 May 2023
     
    Prawdopodobnie nie działa jeszcze 'progresja' kodu po ".BI".

    (przykład na dłuższej próbie; choć dużo wcześniej już testowałem wersję MADSa z .BI to tej przypadłości jeszcze wtedy nie zauważyłem - wszystko inne działało zgodnie z założeniami)
    Source: ab.asm
    1
    2 04BC DASS
    3 .BI 0 0 0 0 0 010 \
    4 0 0 0 0 0 000 0 0 \
    5 0 0 \
    6 0 0 0 0 0
    6 04BC 02 00 00 00 .BI 0 0 0 0 0 010 0 0 0 0 0 000 0 0 0 0 0 0 0 0 0
    7 04BC TASS
    8 .BI 0 0 0 0 0 010 \
    9 0 0 0 0 0 00111 0 \
    10 0 0 \
    11 0 0 0 0 0
    11 04BC 02 01 C0 00 .BI 0 0 0 0 0 010 0 0 0 0 0 00111 0 0 0 0 0 0 0 0
    12 04BC ACME
    13 .BI 0 0 0 0 0 0 0 \
    14 0 0 0 010 000 0 0 \
    15 0 0 \
    16 0 0101010
    16 04BC 00 10 02 A0 .BI 0 0 0 0 0 0 0 0 0 0 010 000 0 0 0 0 0 0101010
    17 04BC KICK
    18 .BI 0 0 0 0 0 0 0 \
    19 0 0 1 1101001 0 1 \
    20 0 0 \
    21 0 0 0 0 0
    21 04BC 00 74 A0 00 .BI 0 0 0 0 0 0 0 0 0 1 1101001 0 1 0 0 0 0 0 0 0
    22 04BC CC65
    23 .BI 0 0 0 0 0 0 0 \
    24 0 0 1 1101001 0 1 \
    25 0 0 \
    26 0 0111111
    26 04BC 00 74 A1 F8 .BI 0 0 0 0 0 0 0 0 0 1 1101001 0 1 0 0 0 0111111
    27
    28 04BC WOSF
    29 .BI 0 0 0 0 1 0 0 \
    30 1 1 0 111111110 1 \
    31 1 1 \
    32 11 0101010
    32 04BC 09 BF DF 54 .BI 0 0 0 0 1 0 0 1 1 0 111111110 1 1 1 11 0101010
    33 04BC MADS
    34 .BI 1 1 1 1 0 010 \
    35 0 0 1 0 0 001 0 0 \
    36 0 0 \
    37 10 1101010
    37 04BC F2 21 0B 50 .BI 1 1 1 1 0 010 0 0 1 0 0 001 0 0 0 0 10 1101010
    38
    39
    40 opt o-
    41 04BC icl 'fx_mne2.asm'
    Source: fx_mne2.asm
    1
    2 04BC ?FindMnemByMatrix
    3 04BC lsr @
    4 04BD bcs ?m_1