segunda-feira, 16 de dezembro de 2019

ZX Spectrum - modo "texto" (I)

Como operações de suporte básico, para começar a trabalhar com assembly, são sempre necessárias rotinas para lidar em modo "texto".

A ROM fornece-nos rotinas que permitem emular um modo texto de 32 colunas x 24 linhas, de 8x8 caracteres, que se mapeia na resolução gráfica de 256x192 pixels.

Usando as rotinas da ROM, existe também a noção de canais, e usando rotinas de ROM, temos de ter atenção a esse detalhe. O canal 1, é essencial para input/error no ecrã inferior, e o canal 2 para o ecrã "superior".

Para mudar para o canal 2:
; Mudar para canal - ecrã superior - canal 'S'
       LD A,2              ; ecrã superior
       CALL $1601          ; CHAN-OPEN

Ao sair do assembly para o BASIC, recomenda-se restaurar o canal 1:
; Mudar para canal - ecrã inferior - canal 'K'
       LD A,1              ; ecrã inferior
       CALL $1601          ; CHAN-OPEN

Para apagar o ecrã, mudando cores:
; Apagar ecrã
       LD A,$31            ; azul ink (1) e paper amarelo (atributos).
       LD (23693),A        ; cores de ecrã em ATTR 
       CALL $0DAF          ; clear the screen - CL_ALL

Para apagar o ecrã, sem mudar cores:
; Apagar ecrã
       CALL $0DAF          ; clear the screen - CL_ALL

Para imprimir um caracter, usa-se a rotina da ROM RST $10:
; Queremos imprimir 
       LD  A,"A"           ; A = caracter a imprimir
       RST $10             ; PRINT A CHARACTER

Nota: a rotina RST $10 corrompe o registo A,  E,  HL', DE' e AF' (pelo menos).

Para imprimir uma string, a rotina PR_STRING é um dos possíveis pontos de entrada na ROM:
; Imprimir uma string
       LD DE,string        ; endereço de string
       LD BC,tamanho       ; set our screen colours.
       CALL $203C          ; PR_STRING

Nota: AF, BC, DE, HL', DE', AF' alterados por PR_STRING.

Para imprimir uma string, terminada por 0 (estilo C), pode-se também escrever uma rotina:
; PRINT A NULL TERMINATED STRING
; IX = STRING
;
PRINT_STRING:
        LD      A,(IX)
        CP      0
        RET     Z
        RST     $10
        INC     IX
        JR      PRINT_STRING

Note-se que existe a noção de posição no ecrã do cursor corrente, a que estas rotinas fazem update.

Esta rotinas, além de caracteres, e honrarem UDGs, também entendem códigos de controlo.

Os códigos de controlo,  são:

$0D       - próxima linha
$10 n     - INK       - n [0,7]
$11 n     - PAPER  - n [0,7]
$12        - FLASH
$13        - BRIGHT
$14        - INVERSE
$16 x y  - AT x,y (x,y coords de texto,  x [0,31], y [0,23] - coloca o cursor de modo "texto" na posição x,y
$17        - TAB

Ou seja, para colocar a posição do cursor, para imprimir, na coluna 0, linha 10, fazer:
; Queremos imprimir 
       LD  A,$16           ; AT
       RST $10             ; PRINT A CHARACTER
       LD  A,0             ; x - coluna
       RST $10
       LD  A,10            ; y - linha
       RST $10

Alternativamente, também se pode mudar a posição do cursor com a seguinte rotina:
; PRINT AT LINE, COL
; B = COL
; C = LINE
;
PRINT_AT:
        LD      A,$16    ; PRINT AT

        CALL    $201E    ; PR-AT-TAB
        RET

Nota: a rotina PR_AT_TAB corrompe o registo A,  E,  HL', DE' e AF'

Chama-se a atenção que o ecrã pode ser limpo, ao acabar o programa BASIC, ou pelo menos parte do ecrã limpo, a fazer um INPUT em BASIC. Se tal não for pretendido, fazer um PAUSE 0 depois de voltar do C/M ou escrever código em assembly para esperar por uma tecla antes de voltar ao BASIC.

Nota: ver também Devolver um número de uma rotina de C/M
          Para as cores na rotina que invoca CL_ALL, ver  o ecrã do ZX Spectrum
          Para controle de teclado, ver O teclado do ZX Spectrum

Sem comentários:

Enviar um comentário