Vlákno názorů k článku Vývoj pro ZX Spectrum: výpis informací na obrazovku od _dw - Diky za clanek. Pokusil jsem se prepsat program do...

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

    _dw

    Diky za clanek.

    Pokusil jsem se prepsat program do "Forthu" a zkompilovat.

    ZX_CONSTANT
     ORG 0x8000
    INIT(60000)
    PRINT_Z({ZX_PAPER, ZX_RED, "Hello", ZX_INK, ZX_WHITE, "Speccy", ZX_FLASH, 1, "!"})
    STOP

    Prvni slovo "aktivuje" konstanty typu ZX_...
    INIT a STOP obaluji program a nastavuji zasobnik navratovych adres a vraci registry pro basic.

    Program musi uchovavat HL protoze je v nem TOS (top of stack).
    DE, protoze je v nem NOS (next of stack).
    Dalsi cell je v (SP) atd.
    HL' protoze obsahuje index RAS (return adres stack).
    Ostatni se da pouzit volne.

    PRINT_Z je psane trosku jinak, protoze je delane jako funkce, za to o trosicku rychleji, protoze v kazdem cyklu neresi ret z a neztraci 5 taktu.

    Mimochodem, retezce ukoncene nulou jsou podle nekterych programatoru ve Forthu spatne reseni. To je trochu flamewar tema. Ja si myslim, ze pokud se nesnazime s nema nejak pracovat a jen je tiskneme tak jsou v pohode.

    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'ZX_CONSTANT ORG 0x8000 INIT(60000) PRINT_Z({ZX_PAPER, ZX_RED, "Hello", ZX_INK, ZX_WHITE, "Speccy", ZX_FLASH, 1, "!"}) STOP'
    ZX_EOL               EQU 0x0D     ; zx_constant   end of line
    
    ZX_INK               EQU 0x10     ; zx_constant   colour
    ZX_PAPER             EQU 0x11     ; zx_constant   colour
    ZX_FLASH             EQU 0x12     ; zx_constant   0 or 1
    ZX_BRIGHT            EQU 0x13     ; zx_constant   0 or 1
    ZX_INVERSE           EQU 0x14     ; zx_constant   0 or 1
    ZX_OVER              EQU 0x15     ; zx_constant   0 or 1
    ZX_AT                EQU 0x16     ; zx_constant   Y,X
    ZX_TAB               EQU 0x17     ; zx_constant   # spaces
    
    ZX_BLACK             EQU %000     ; zx_constant
    ZX_BLUE              EQU %001     ; zx_constant
    ZX_RED               EQU %010     ; zx_constant
    ZX_MAGENTA           EQU %011     ; zx_constant
    ZX_GREEN             EQU %100     ; zx_constant
    ZX_CYAN              EQU %101     ; zx_constant
    ZX_YELLOW            EQU %110     ; zx_constant
    ZX_WHITE             EQU %111     ; zx_constant
     ORG 0x8000
    ;   ===  b e g i n  ===
        ld  (Stop+1), SP    ; 4:20      init   storing the original SP value when the "bye" word is used
        ld    L, 0x1A       ; 2:7       init   Upper screen
        call 0x1605         ; 3:17      init   Open channel
        ld   HL, 0xEA60     ; 3:10      init   Return address stack = 60000
        exx                 ; 1:4       init
        ld   BC, string101  ; 3:10      print_z   Address of null-terminated string101
        call PRINT_STRING_Z ; 3:17      print_z
    Stop:                   ;           stop
        ld   SP, 0x0000     ; 3:10      stop   restoring the original SP value when the "bye" word is used
        ld   HL, 0x2758     ; 3:10      stop
        exx                 ; 1:4       stop
        ret                 ; 1:10      stop
    ;   =====  e n d  =====
    ;------------------------------------------------------------------------------
    ; Print C-style stringZ
    ; In: BC = addr
    ; Out: BC = addr zero + 1
        rst  0x10           ; 1:11      print_string_z putchar with ZX 48K ROM in, this will print char in A
    PRINT_STRING_Z:         ;           print_string_z
        ld    A,(BC)        ; 1:7       print_string_z
        inc  BC             ; 1:6       print_string_z
        or    A             ; 1:4       print_string_z
        jp   nz, $-4        ; 3:10      print_string_z
        ret                 ; 1:10      print_string_z
    
    STRING_SECTION:
    string101:
        db ZX_PAPER, ZX_RED, "Hello", ZX_INK, ZX_WHITE, "Speccy", ZX_FLASH, 1, "!", 0x00
    size101              EQU $ - string101
    ; seconds: 0           ;[35:167]

    Dalsi varianta je pouzit retezec, ktery bude ukoncen tak ze posledni bajt bude mit 7. bit nastaveny na 1, takze se usetri bajt na retezec. Pouzije se slovo PRINT_I.

    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ../check_word.sh 'ZX_CONSTANT ORG 0x8000 INIT(60000) PRINT_I({ZX_PAPER, ZX_RED, "Hello", ZX_INK, ZX_WHITE, "Speccy", ZX_FLASH, 1, "!"}) STOP'
    ZX_EOL               EQU 0x0D     ; zx_constant   end of line
    
    ZX_INK               EQU 0x10     ; zx_constant   colour
    ZX_PAPER             EQU 0x11     ; zx_constant   colour
    ZX_FLASH             EQU 0x12     ; zx_constant   0 or 1
    ZX_BRIGHT            EQU 0x13     ; zx_constant   0 or 1
    ZX_INVERSE           EQU 0x14     ; zx_constant   0 or 1
    ZX_OVER              EQU 0x15     ; zx_constant   0 or 1
    ZX_AT                EQU 0x16     ; zx_constant   Y,X
    ZX_TAB               EQU 0x17     ; zx_constant   # spaces
    
    ZX_BLACK             EQU %000     ; zx_constant
    ZX_BLUE              EQU %001     ; zx_constant
    ZX_RED               EQU %010     ; zx_constant
    ZX_MAGENTA           EQU %011     ; zx_constant
    ZX_GREEN             EQU %100     ; zx_constant
    ZX_CYAN              EQU %101     ; zx_constant
    ZX_YELLOW            EQU %110     ; zx_constant
    ZX_WHITE             EQU %111     ; zx_constant
     ORG 0x8000
    ;   ===  b e g i n  ===
        ld  (Stop+1), SP    ; 4:20      init   storing the original SP value when the "bye" word is used
        ld    L, 0x1A       ; 2:7       init   Upper screen
        call 0x1605         ; 3:17      init   Open channel
        ld   HL, 0xEA60     ; 3:10      init   Return address stack = 60000
        exx                 ; 1:4       init
        ld   BC, string101  ; 3:10      print_i   Address of string101 ending with inverted most significant bit
        call PRINT_STRING_I ; 3:17      print_i
    Stop:                   ;           stop
        ld   SP, 0x0000     ; 3:10      stop   restoring the original SP value when the "bye" word is used
        ld   HL, 0x2758     ; 3:10      stop
        exx                 ; 1:4       stop
        ret                 ; 1:10      stop
    ;   =====  e n d  =====
    ;------------------------------------------------------------------------------
    ; Print string ending with inverted most significant bit
    ; In: BC = addr string_imsb
    ; Out: BC = addr last_char + 1
        rst  0x10           ; 1:11      print_string_i putchar with ZX 48K ROM in, this will print char in A
    PRINT_STRING_I:         ;           print_string_i
        ld    A,(BC)        ; 1:7       print_string_i
        inc  BC             ; 1:6       print_string_i
        or    A             ; 1:4       print_string_i
        jp    p, $-4        ; 3:10      print_string_i
        and  0x7f           ; 2:7       print_string_i
        rst  0x10           ; 1:11      print_string_i putchar with ZX 48K ROM in, this will print char in A
        ret                 ; 1:10      print_string_i
    
    STRING_SECTION:
    string101:
        db ZX_PAPER, ZX_RED, "Hello", ZX_INK, ZX_WHITE, "Speccy", ZX_FLASH, 1, "!" + 0x80
    size101              EQU $ - string101
    ; seconds: 0           ;[38:185]

    Posledni varianta je zakladni PRINT, ktere vola ROM rutinu pro tisk retezce, ktera vyzaduje pokazde nastavit delku tisknuteho retezce, takze opakovane volani zabira nejvic mista.

    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$ ls -l root_str*.bin
    -rw-rw-r-- 1 dworkin dworkin 50 Feb 21 02:59 root_str.bin
    -rw-rw-r-- 1 dworkin dworkin 56 Feb 21 02:58 root_stri.bin
    -rw-rw-r-- 1 dworkin dworkin 54 Feb 21 02:58 root_strz.bin
    dworkin@dw-A15:~/Programovani/ZX/Forth/Pasmo_test$

    PS: Preklad je napsan v pouhem makru (M4) a vsechny PRINT se snazi najit shodne retezce pokud se pouziji, aby se ulozil jen jeden. Proto ty slova vypadaji "trosku" jinak nez ve Forthu.

    PRINT({"Retezec"}) misto ." Retezec"
    PUSH(10) misto 10
    ADD misto +

  • 21. 2. 2023 9:57

    atarist

    jj takze pro Forth porad plati, ze je to +- maximalne dvakrat delsi, nez ciste ASM. A to nemyslim zle, to je naopak skvely vysledek na vysokourovnovy jazyk.