Vlákno názorů k článku Vývoj pro ZX Spectrum: vlastní vykreslovací subrutiny potřetí od _dw - A nejtezsi cast nakonec. Prevod YX na adresu...

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

    _dw

    A nejtezsi cast nakonec. Prevod YX na adresu v HL. Najit efektivni cestu je tak slozity, ze jsem se rovnou podival jak jsem to resil nekdy predtim... .) Taky jsou v mem pasmu 4 rano... .)

    https://github.com/DW0RKiN/M4_FORTH/blob/master/M4/graphic_runtime.m4

    Po "drobne" uprave se da usetrit rovnych 6 bajtu!

    calc_pixel_address:
            ; parametry:
            ; B - x-ová souřadnice (v pixelech)
            ; C - y-ová souřadnice (v pixelech)
            ;
            ; návratové hodnoty:
            ; HL - adresa pro zápis pixelu
            ;
            ; pozměněné registry:
            ; A
            ;
            ; vzor adresy:
            ; 0 1 0 Y7 Y6 Y2 Y1 Y0 | Y5 Y4 Y3 X4 X3 X2 X1 X0
      if 1
        ld    A, C          ; 1:4       bbrrrsss = Y
        or    0x01          ; 2:7       bbrrrss1 carry = 0
        rra                 ; 1:4       0bbrrrss carry = 1
        rra                 ; 1:4       10bbrrrs carry = s?
        and   A             ; 1:4       10bbrrrs carry = 0
        rra                 ; 1:4       010bbrrr
        ld    L, A          ; 1:4       .....rrr
        xor   C             ; 1:4       ????????
        and   0xF8          ; 2:7       ?????000
        xor   C             ; 1:4       010bbsss
        ld    H, A          ; 1:4       H = 64+8*INT (b/64)+(b mod 8)
    
        ld    A, L          ; 1:4       .....rrr
        xor   B             ; 1:4       ???????? provede se 2x takze zadna zmena, mezitim ale vynulujeme hornich 5 bitu
        and   0x07          ; 2:7       00000???
        xor   B             ; 1:4       cccccrrr
        rrca                ; 1:4       rcccccrr
        rrca                ; 1:4       rrcccccr
        rrca                ; 1:4       rrrccccc
        ld    L, A          ; 1:4       L = 32*INT (b/(b mod 64)/8)+INT (x/8).
    
        ret                 ; 1:10      návrat z podprogramu
      else
            ld  a, c              ; všech osm bitů Y-ové souřadnice
            and %00000111         ; pouze spodní tři bity y-ové souřadnice (Y2 Y1 Y0)
                                  ; A: 0 0 0 0 0 Y2 Y1 Y0
            or  %01000000         ; "posun" do obrazové paměti (na 0x4000)
            ld  h, a              ; část horního bajtu adresy je vypočtena
                                  ; H: 0 1 0 0 0 Y2 Y1 Y0
    
            ld  a, c              ; všech osm bitů Y-ové souřadnice
            rra
            rra
            rra                   ; rotace doprava -> Y1 Y0 xx Y7 Y6 Y5 Y4 Y3
            and %00011000         ; zamaskovat
                                  ; A: 0  0  0 Y7 Y6  0  0  0
            or  h                 ; a přidat k vypočtenému mezivýsledku
            ld  h, a              ; H: 0  1  0 Y7 Y6 Y2 Y1 Y0
    
            ld  a, c              ; všech osm bitů Y-ové souřadnice
            rla
            rla                   ; A:  Y5 Y4 Y3 Y2 Y1 Y0 xx xx
            and %11100000         ; A:  Y5 Y4 Y3 0  0  0  0  0
            ld  l, a              ; část spodního bajtu adresy je vypočtena
    
            ld  a, b              ; všech osm bitů X-ové souřadnice
            rra
            rra
            rra                   ; rotace doprava -> 0  0  0  X7 X6 X5 X4
            and %00011111         ; A: 0  0  0  X7 X6 X5 X4 X3
            or  l                 ; A: Y5 Y3 Y3 X7 X6 X5 X4 X3
            ld  l, a              ; spodní bajt adresy je vypočten
    
            ret                   ; návrat z podprogramu
      endif
  • 21. 3. 2023 10:13

    radioing

    Tak nějak se mi potvrzuje hláška kolegy sinclairisty před 35 lety - "grafika na Sinclairu je peklo". Pamatuju, že díky "lineárnímu" mapování VRAM na C64 se při unrollingu všech 4 variant vykreslování obecné přímky podle Bresenhama vystačilo snad s 6 instrukcemi na pixel v 320 x 200 (jo, požralo to par kB).

  • 21. 3. 2023 10:21

    atarist

    zase se tam muselo resit nasobeni 40 kvuli tem 320 pixelu, (jasne, nejaky posuny a soucty, ne nasobeni ale stejne to vsechno v jediny akumulatoru...)

  • 21. 3. 2023 12:57

    _dw

    Imho je tohle spis ukazka jak lze obtizne psat na Z80.

    Ale ta grafika je podle me teda peklo taky. Zjednodusenim v jednom smeru, to ve vsech ostatnich udelali slozitejsi...

    Preferoval bych, kdyby to slo pekne za sebou:
    +256 o 8 pixelu dolu a nebo -256 o 8 pixelu nahoru.
    +32 o pixel dolu a nebo -32 (+FFE0) o pixel nahoru.
    Nemusi se resit zadne up/down rutiny, kdyz pisete uz sam o sobe nejaky komplikovany algoritmus na kruznici/usecku.

    Znaky se komplikuji na to, ze problem prechodu tretin se meni na problem prechodu radku.
    Na radku je to stale jen +-1 pro spodni bajt. Jakmile to preleze pres 5 bitu tak se meni +-horni bajt.
    Neco jako pro znak "vpravo/nasledujici znak/+1":
    L = X
    L |= 0xC0
    H = Y
    HL++
    L &= 0x1F

    A pro znak "vlevo/predchozi/-1":
    L = X
    H = Y
    HL--
    L &= 0x1F

    Timhle se da vlastne resit prechod pro tretiny i ted. U H |=3 a H &=F8.

    TAB x, ktere nastavi kurzor na x znak na radku (pouhe prirazeni) a nebo pokud je to posun doleva tak snizi radek (+256) by byl o dost snazsi.

    YX ve znacich na adresu v HL:
    H = Y
    L = X
    add HL, HL
    add HL, HL
    add HL, HL

    YX v pixelech na adresu v HL?
    H = Y
    L = X
    a ted potrebujeme HL >>= 3
    takze asi neco jako
    A = L
    xor H
    and 0xF8
    xor H
    rrca
    rrca
    rrca
    L = A
    A = H
    rrca
    rrca
    rrca
    H = A

    Hmm to je 12+2 bajtu (12*4+7 = 55 taktu)

    Takze na 12 bajtu (3*16 = 48 taktu) to jde udelat primo pres shift H a L.

    PS: Mit to linearne by pro me asi nejvic zmenilo ten pocit z pomaleho nacitani obrazovky her. Pokud by to neemulovala primo ta nacitaci rutina.

  • 23. 3. 2023 9:45

    patron

    Souhlas, v minulosti jsem nechápal, proč měl Sinclair takto (z mého pohledu) komplikovanou VRAM. Já jsem měl Commodore Plus/4 a tam byla VRAM lineární. Používalo se několik různých režimu (vše zajišťoval obvod TED):

    Character: 40x25 znaků + volně měnitelná znaková sada v RAM/ROM (hw kurzor, flash, inverzní znaky).
    Bitmap: 320x200
    Bitmap Multicolor (MCM): 160x200
    plus ještě existoval režim Extended Color Mode.
    + hw scrolling.

    Všechny režimy byly lineární a jejích umístění na stránku v RAM se dalo měnit, takže jste mohli používat double-buffering. Žádné zpomalení běhu programů v určité části RAM nebylo (jako to má ZX Spectrum).

    A programování v MOS 6502 bylo velmi jednoduché (oproti Zilog Z80).
    Takže obdivuji všechny Spektristy. Kudos!