Názor k článku Kouzlo minimalismu potřetí: vývoj her a dem pro slavné ZX Spectrum od _dw - V clanku jsou uvedeny konstanty 0×00010000 a 0×5800....

  • Článek je starý, nové názory již nelze přidávat.
  • 7. 2. 2023 3:47

    _dw

    V clanku jsou uvedeny konstanty 0×00010000 a 0×5800. To je trochu matouci, protoze prvni je binarni a druha hexadecimalni.
    Pasmo rozpozna 0x5800 jako hexadecimalni hodnotu, nejen $5800 nebo #5800.
    Binarni zapis je s predponou %, jak je uvedeno v kodu.

    Z80 je trosku zvlastni procesor a spousta veci jde delat ruznymi cestami.
    org $8000
    start:
    ld a,%00010000
    ld ($5800),a
    ret

    Jde zapsat se stejnou delkou kodu (2+3+1=6) i takty (7+13+10=30) jako
    org $8000
    start:
    ld hl,$5800
    ld (hl),%00010000
    ret

    3+2+1 = 6 bajtu
    10+10+10 = 30 taktu

    Jen se pouzije jiny registr. Tohle dokaze byt poradna vyzva uz od par instrukci. Kdyz se budete snazit napsat neco jen trosku mene trivialniho, tak na prvni pohled nebude zrejme, ktera kombinace/varianta je lepsi.

    Staci se podivat na vysledky Z80 size programming chalenge, kde i ostrileni programatori se nedostanou na optimalnich 15 bajtu.

    http://www.retroprogramming.com/2014/12/z80-size-programming-challenge-1.html

    A pokud se pokusite pouzit nejaky prekladac, napr. pro C tak vysledek bude opravdu strasny. Dones neexistuje poradny prekladac u ktereho si nebudete trhat vlasy pri pohledu na vysledny kod.

    Z80 neumi efektivne pracovat s parametry ulozenymi na zasobnik, takze to uplne diskvalifikuje C. Pravdepodobne pouzije instrukce typu LD E,(IX+n), ktera ale zabira 3 bajty (jeden pro prefix, dalsi instrukce a treti hodnota n) a trva 19 taktu. Oproti instrukci LD E,(HL), ktera zabira jeden bajt a trva 7 taktu. Takze pri vhodne zvolenem algoritmu, kdy se budeme snazit cist data sekvencne za sebou a pouzijeme k tomu instrukci INC HL (1 bajt a 6 taktu) tak se dostaneme na 2 bajty a 13 taktu.

    Ale vetsina prekladacu je jeste horsich budou se snazit neustale ukladat promenne do pameti a opakovane nacitat do registru. Proste bude zapominat co se pred chvili drzel v registrech, protoze uz dela jinou cast programu a nepredava si co si drzi v registrech, zda to bude muset uklidit nebo to muze naopak vyuzit.

    Staci se podivat co za hruzu leze z jednoducheho programku co testuje zda retezec je pangram, kdy se pouziva 32 bitove pole pro pouzite znaky.

    https://github.com/DW0RKiN/M4_FORTH/blob/master/Benchmark/Pangram.c

    https://github.com/DW0RKiN/M4_FORTH/blob/master/Benchmark/Pangram.lst

    Misto jednobajtove instrukce o sedmi taktech
    or 32
    napise sdcc
    86 ;Pangram.c:10: c |= 32; // uppercase
    004E DD 4E F8 [19] 87 ld c, -8 (ix)
    0051 CB E9 [ 8] 88 set 5, c
    0053 79 [ 4] 89 ld a, c

    Preklad kodu zapsanemu ve FORTHu je nasobne rychlejsi a i ten byva stale 2x horsi nez co napisete primo v assembleru. Protoze Z80 se vlastne nehodi ani na ten FORTH. Chybi mu kratka a rychla instrukce ex SP, HL. Ktera by mu umoznila "zdvojit" zasobnik. Takze si musi druhy zasobnik emulovat pres to inc/dec a ld (HL),register pripadne ld register,(HL). Popripade jinak, protoze to zase existuje vice reseni.

    PS: K tomu prekladaci "pasmo" bych podotknul, ze ma nespravne danou prioritu u unarniho znamenka minus. Ma ho misto nejvyssi nejnizsi, takze
    ld HL, -100+500
    je
    ld HL,-600
    Ke vsemu uklada pres EQU hodnoty pokazde jako unsigned word (16 bitu, vic neumi). Takze muze byt docela vyzva zapsat vyraz tak aby napriklad dokazal spravne porovnat >,<,>=,<= mezi signed hodnotami.

    Napriklad potrebujete zapsat:
    ld HL, m <= n
    aby se to zkompilovalo jako
    ld HL, 0x0000
    nebo
    ld HL, 0xFFFF

    nebo chcete aby to spravne nasobilo nebo delilo signed hodnoty jako
    ld HL,m/n
    popripade zbytek
    ld HL,m % n

    Napsat floor divison uz je dost narocne jako vyraz pomoci toho co Pasmo umi.

    Kde za m a n si dosadte pres makro nejakou konstantu 16 bitovou signed.

    Popripade 32 bit/16 bit, pokud je vysledek 16 bitovy tak s omezenim Pasma na 16 bitu to zapsat sice jde, ale je to na celou obrazovku.
    ld HL, 32bit_m/16bit_n

    PPS: FUSE emulator ma sice debugger, ale ten je prakticky nepouzitelny, je tezke se vubec dostat k informacim jake zkratky muzete pouzit. Jak zmenit hodnoty registru atd. Ale na linuxu je bohuzel to nejlepsi co muzete mit pokud nechcete pouzivat wine.

    Budete pouzivat jen:

    breakpoint 0x6000
    br 0x8000

    ignore id count
    ig id count

    delete id
    del id

    Popripadne dvouklik na zasobnik vytvori breakpoint na jedno pouziti na adrese co v nem lezi.

    A uz se nedostanete k:

    Neco se snazi cist z adresy 0x6000:
    breakpoint read $6000
    br re $6000

    Neco se snazi zapsat na adresu 0x6000:
    breakpoint write $6000
    br w $6000

    break 0xa000 if z80:bc >= 0x8000 && z80:de < 0x1234

    set z80:a 0xff
    set z80:de 0x1234

    7. 2. 2023, 03:49 editováno autorem komentáře