Oznámení

Sbalit
Aktuálně žádná oznámení.

Assembler, psaní textu pomocí Copperu

Sbalit
X
 
  • Filtr
  • Čas
  • Zobrazit
Vymazat vše
new posts

    Assembler, psaní textu pomocí Copperu

    Přebral jsem jeden program, zjednodušil jej a okomentoval. V příloze je původní kód i můj zjednodušený kód s komentářem, obrázek PNG, RAW soubor s fontem bez diakritiky který načítává program a obě verze EXE. Zjednodušená a okomentovaná verze je s číslem 33. Je tam i soubor TXT se základem toho, co ve kterém registru Dx, Ax je. Není v něm popsáno vše, já si to sepsal pro uklízení si v mé verzi kódu.

    Dle mně ani tohle není ideální příklad pro ukázku assembleru a samotný základní princip assembleru je jednodušší než daný program. Je v něm často použitý HW register a to může odrazovat. Assembler není pouze o registrech, jen v tomhle programu se toho sešlo více díky použití Copperu.

    Optimalizace kódu na úrovni, která mi vyhovuje: Defor (Vectors)

    Klikni pro plné zobrazení obrázku  Jméno: TEXTRO OBRAZEK.png Počet zobrazení: 0 Velikost: 11,9 KB ID: 154207
    Přiložené soubory
    Naposledy upravil Lisiak; 16.01.2022, 19:15:16.
    Amiga - PMD 85

    #2
    Můžu zase pár komentářů?
    Není to nic důležitého. Jen pár tipů a triků.
    (Odbočka: Na Amize mne vždy fascinovala old-school snaha o optimalizaci kódu. Ať už vzhledem k rychlosti provedení, nebo jeho délce. V éře osmibitů to bylo standardem, u šestnáctibitů se to ještě cenilo, ale u pozdějších platforem už na tom moc nezáleželo a spíše se začala cenit rychlost programování.)
    Instrukce pracující s datovým registrem jako cílovým operandem vždy nastavují příznakové bity. Není tedy třeba tak často používat instrukci "tst", jak je to u jiných procesorů. Takže série tvých testů na konec textu nebo konec řádku by se dala upravit:
    Code:
       move.b (a0)+,d2
       beq.b .endOfText   ; pokud je 0 tak je konec textu
       bmi.b .endOfLine   ; a pokud je to zaporne cislo, tak nam to muze indikovat konec radku (rozsah 0-127 by nam pro znaky mel stacit)
       ; v d2 je nejaky zobrazitelny znak
       ; zobrazit znak
       .....
    .endOfLine
       ; tady prejdeme na novy radek
       .....
    .endOfText
       rts
    
    .text
       dc.b "Tady konci radek", -1
       dc.b "A ted uz konci text.", 0
    Smyčka "cmp + beq + addq + bra" by se dala nahradit za "cmp + dbeq". DBxx instrukce: 1. otestuje stavové bity a pokud je výsledek true, instrukce se přeskočí (neprovede). V našem případě testujeme shodu s d2. 2. Pokud je test false, dekrementuje se datový registr (counter cyklu) a pokud není -1, tak se provede skok. Je to asi nejsložitější instrukce MC68000, ale je užitečná.

    Code:
       moveq #MaxNumberOfTestedChars-1,d4
    .testChar
       cmp.b (a1,d4.w),d2
       dbeq d4,.testChar
       ; tady bud doslo ke shode s d2 (a d4 obsahuje index)
       ; nebo je d4=-1 a shodu jsme nenasli

    Komentovat


      #3
      Titul "Psaní textu pomoci copperu" je asi trochu zavádějící. Jak je pro psaní využit copper? Původně jsem si myslel, že se jedná o (legendární) použití copperu k tomu, aby řídil blitter, který kopíruje znaky do bitplánů. V tomto případě je to však spíše ukázka toho, jak je možno bez použití systému něco zobrazit z bitplánů (nastavení BPLCONx, BPLxPT, DIWSTRT/DIWSTOP, DDFSTRT/DDFSTOP, COLORxx, ...).
      Ale celkově "Good work!" 👍
      Naposledy upravil Defor; 17.01.2022, 12:12:54.

      Komentovat


        #4
        Defor :

        ​​​​​​​Zatím jsem zavedl tu první úpravu s instrukcí BMI. Jen převezmu myšlenku, zasazuji do kódu sám. Na ukončení řádku jsem použil 0, aby stačilo zdlouhavější -1 napsat jen jednou na konci celého textu. A podmínku pro konec řádku jsem dal před tou na konec celého textu. Já vím že tam šlo jen o tu myšlenku s BMI asi a o to že nám na abecedu stačí i 7 bitů 🙂, koukal jsem na to a abeceda má nějakých 42 znaků, malé a velké písmena tedy 84, plus další znaky, to je opravdu v pohodě.

        Ono ta původní verze byla rychlejší jen při použití mezery a konce řádku, protože ta smyčka byla kratší o jednu podmínku Bcc, ale vzhledem k počtu textu se ta původní verze opravdu nevyplatí.
        Amiga - PMD 85

        Komentovat


          #5
          Defor :

          Nedalo mi to a tu změnu s instrukcí dbeq jsem již zahrnul taky. Zatím jsem o téhle instrukcí ani nevěděl i když je v příručce zahrnuta. Jen jsem byl u BEQ zvyklý skákat na návěstí, tady se smyčka opouští, tedy obrácená logika pro mne, nebo opět něco jen obráceně chápu, co je u mně taky normální stav 🙂

          Z návěstí COPYCHAR, jsem udělal lokální, tedy s proměnnou jen pro danou část kódu, nebo co to je. Tedy jsem před jméno dal taky tečku stejně jako u návěstí SEARCHTAB (ve tvém příkladu .testChar)

          Takový stručný dotaz, jak moc je dobré relativně optimalizovat kód na co nejlepší využití prostoru v registrech, tedy že máš třeba v D1 dvě, nebo i tři hodnoty vůči tomu mít v D1 pouze jednu hodnotu a později si danou druhou hodnotu načíst ze zásobníku, pokud je prioritní rychlost? Zajímá mně pouze čemu se ve většině případů dává přednost. Jestli se tedy použije zásobník až když už opravdu není kam dávat data při nějaké rozumné práci s danými daty se kterými v registrech pracujeme.
          Naposledy upravil Lisiak; 18.01.2022, 15:18:31.
          Amiga - PMD 85

          Komentovat


            #6
            Zápis instrukce DBxx je skutečně na pohled trochu matoucí. Možná ji měla Motorola pojmenovat trochu jinak. Každopádně je to tak, že "D" v názvu znamená "decrement" - instrukce vždy sníží hodnotu daného registru a testuje, jestli je obsah -1; "B" znamená, že se provede "branch" jestli je test false (není -1); a zbylé dva znaky definují co se má hned na začátku provádění testovat ze stavových bitů, aby se ty dva kroky NEprovedly (aby se instrukce nevykonala). Ano, je to divné - bohužel.

            Osobně používám lokální návěstidla (začínají tečkou) velmi často. Zjednodušuje to práci (jejich platnost je vždy jen mezi dvěma globálními návěstidly) a přehlednost programu. Takže v kódu mám pro krátké lokální skoky často jen návěstí ".1", ".2" apod.

            Stačí se podívat na časování instrukcí MC68000. Tam je vše uvedeno a vše se dá snadno porovnat.

            Ve tvém případě trvá instrukce swap 4 takty. Instrukce move.w dx,-(sp) nebo move.w (sp)+,dx 8 taktů. Navíc ta první potřebuje jen jeden přístup ke sběrnici, ta druhá potřebuje dva. To hraje roli, pokud nemáme fast ram (chip ram je na vnitřní sběrnici a CPU se k ní podle situace nemusí dostat a pak musí čekat).
            Situace ale může být jiná, pokud bychom používali nějak jinak rozvržené bity v registru. Odmaskování a posunutí bitů může pak být v důsledku pomalejší než načtení z paměti.

            Komentovat


              #7
              Je i nějaký standardnější způsob, jak v assembleru nesystémově vypsat text, nebo tohle je v pohodě?
              Amiga - PMD 85

              Komentovat


                #8
                Autorem citovaného textu je Lisiak4 Přejít na původní příspěvek
                Je i nějaký standardnější způsob, jak v assembleru nesystémově vypsat text, nebo tohle je v pohodě?
                Myslím, že pro 8x8 neproporcionální fonty je tohle v pohodě a dělá se to sérií move.b offset1(ax),offset2(ay). U větších znaků (s více barvami) se už nejspíš vyplatí použít blitter. V případě proporcionálních fontů (znaky mají různou šířku) se pak musí dělat i bitshift (a tudíž používat long-wordy). Do určité velikosti je to asi pořád ještě lepší dělat pomocí CPU. Od určité hranice (na základní 68k bez fast-ram) je asi lepší už použít blitter.
                Naposledy upravil Defor; 19.01.2022, 14:04:27.

                Komentovat


                  #9
                  V příloze verze kterou se pokusím rozumné napasovat k mé hudební rutině. Je tomu uzpůsobená i práce s registry. Jsou v ní i optimalizace od Defora na úrovni která mi vyhovuje, tedy bez použití maker. Register A6 tam mám asi teď navíc vůči tomu co mám volné v mé hudební rutině, ale není jsem si jist. Mám v něm ten pointer na bitplane (snad se nepletu jsem teď mimo kód a koukat na to budu zase jindy, psal jsem o tom ve druhém vlákně zde). V téhle úrovni kódu mé hudební rutiny, kam chci přidat v mé hudební rutině kód z Textro mám k dispozici jako pomocné proměnné celou D2 a Word z D0. Register A2 mám taky jako dočasný a nic v něm nedržím, žádné data dlouhodobě. Kdyby šlo do tuhého mám ještě přes swap k dispozici 1 byte v D4. V úpravě Textra jsem použil na data i nějaké volné adresové registre kde z longu používám maximálně Word. V rámci mé hudební rutiny v nižších částech kódu pak ještě z D2 používám Word na uchování dalších dat. Tedy se mi tahle pomocná proměnná krátí z Longu na Word.

                  Poslední verze Textra v příloze. Upravil jsem ještě malinko logiku na z mého pohledu přehlednější.

                  Všem hezký zbytek dne 🙂
                  Přiložené soubory
                  Amiga - PMD 85

                  Komentovat

                  Zpracovávám...
                  X