Názor k článku Vývoj her a dem pro ZX Spectrum: vlastní vykreslovací subrutiny od _dw - Jeste jsem to nedocetl do konce. Budu uplne ignorovat...

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

    _dw

    Jeste jsem to nedocetl do konce.

    Budu uplne ignorovat pouzivani djnz pro pripady, kdy se to na nahradit jr, protoze se to pouzije 256x a uvnitr smycky je nejaky registr menen tak, ze nastavi zero flag prave a jedine ve stejnou dobu co by se ukoncila smycka.

    Ale dovolil jsem si upravit tu rutinu pro 14. kapitolu. Z puvodnich 53 bajtu na 38 bajtu.
    Jedna z podminek je bud pouzit nejaka makra a nebo slevit z prehlednosti a nepouzivat nejake globalni konstanty jako je adresa tech fontu. Protoze puvodni rutina uplne ignoruje ze je polozena v pameti na adresu delitelnou 256...
    Pak jsem upravil tu funkci pro vypsani znaku tak, aby vracela v DE adresu nasledujiciho znaku (vcetne prelezeni pres tretiny obrazovky), prijde me to jako pouzitelnejsi navrh, nez muset po kazdem vypsanem znaku hledat kde je nasledujici adresa.
    Puvodni:

    SCREEN_ADR      equ $4000
    CHAR_ADR        equ $3c00
    ENTRY_POINT     equ $8000
    
            org ENTRY_POINT
    
    start:
            ld de, SCREEN_ADR        ; 3:10   adresa pro zápis
            ld a, 'A'                ; 2:7    kód vykreslovaného znaku
            call draw_char           ; 3:17   zavolat subrutinu pro vykreslení znaku
    
            ld de, SCREEN_ADR+1      ; 3:10   adresa pro zápis
            ld a, 'B'                ; 2:7    kód vykreslovaného znaku
            call draw_char           ; 3:17   zavolat subrutinu pro vykreslení znaku
    
            ld de, SCREEN_ADR+128+31 ; 3:10   adresa pro zápis
            ld a, '?'                ; 2:7    kód vykreslovaného znaku
            call draw_char           ; 3:17   zavolat subrutinu pro vykreslení znaku
    
    finish:
            ret                      ; 1:10   ukončit program
    
    draw_char:
            ld hl, CHAR_ADR          ; 3:10   adresa, od níž začínají masky znaků
            ld b, 0                  ; 2:7
            ld c, a                  ; 1:4    kód znaku je nyní ve dvojici BC
            sla c                    ; 2:8
            rl b                     ; 2:8    2*bc
            sla c                    ; 2:8
            rl b                     ; 2:8    4*bc
            sla c                    ; 2:8
            rl b                     ; 2:8    vynásobení BC osmi
            add hl, bc               ; 1:11   přičíst adresu k offsetu masky znaku
    
            ld b, 8                  ; 2:7    počitadlo zapsaných bajtů
    loop:
            ld a, (hl)               ; 1:7    načtení jednoho bajtu z masky
            ld (de), a               ; 1:7    zápis hodnoty na adresu (DE)
            inc hl                   ; 1:6    posun na další bajt masky
            inc d                    ; 1:4    posun na definici dalšího obrazového řádku
            djnz loop                ; 2:8/13 vnitřní smyčka: blok s osmi zápisy
            ret                      ; 1:10
    
    end ENTRY_POINT

    Nove:

    SCREEN_ADR      equ $4000
    CHAR_ADR        equ $3c00
    ENTRY_POINT     equ $8000
    
        org ENTRY_POINT
    
    start:
        ld   DE, SCREEN_ADR ; 3:10   adresa pro zápis
        ld    A, 'A'        ; 2:7    kód vykreslovaného znaku
        call draw_char      ; 3:17   zavolat subrutinu pro vykreslení znaku
    
        ld    A, 'B'        ; 2:7    kód vykreslovaného znaku
        call draw_char      ; 3:17   zavolat subrutinu pro vykreslení znaku
    
        ld    E, SCREEN_ADR+4*32+31 ; 2:7   adresa pro zápis (jsme stale v prvni tretine obrazovky)
        ld    A, '?'        ; 2:7    kód vykreslovaného znaku
    ;    call draw_char      ; 3:17   zavolat subrutinu pro vykreslení znaku
    
    finish:
    ;    ret                 ; 1:10   ukončit program
    
    ;    Input: DE = adresa znaku pro zapis, A = znak
    ;   Output: DE = adresa nasledujiciho znaku (muze pretect do atributu)
    ; Pollutes: B = 0, C = hi(old_DE),HL
    draw_char:
        ld   BC, 0x3C00     ; 3:10   adresa, od níž začínají masky znaků
        ld    H, C          ; 1:4
        ld    L, A          ; 1:4    kód znaku je nyní ve dvojici HL
        add  HL, HL         ; 1:11   2x
        add  HL, HL         ; 1:11   4x
        add  HL, HL         ; 1:11   8x
        add  HL, BC         ; 1:11
    
        ld    B, 0x08       ; 2:7    počitadlo zapsaných bajtů
        ld    C, D          ; 1:4
    loop:
        ld    A,(HL)        ; 1:7    načtení jednoho bajtu z masky
        ld  (DE),A          ; 1:7    zápis hodnoty na adresu (DE)
        inc   L             ; 1:4    posun na další bajt masky
        inc   D             ; 1:4    posun na definici dalšího obrazového řádku
        djnz loop           ; 2:8/13 vnitřní smyčka: blok s osmi zápisy
        ld    D, C          ; 1:4
        inc  DE             ; 1:6
        ret                 ; 1:10
    
    end ENTRY_POINT

    PS: Jinak me uplne dostal ten vypis u jr/djnz, kdy jsem si myslel ze 0 ukazuje pred tu instrukci a ona ukazuje za ni. Uplne jsem si to pletl s $, ktera ukazuje prave pred (na prave provadenou/za­pisovanou) instrukci. Takze $ je neco jako 0xFE.