quarta-feira, 26 de fevereiro de 2014

cp8vid

O conteúdo de vídeo apresentado pelo TK90X é armazenado no início da RAM, a partir do endereço 16384. É uma prática comum armazenar uma tela em outra região da RAM  temporariamente, enquanto não é exibida no televisor.


No momento oportuno, esta tela pode ser copiado para a região em 16384 e passará a ser exibida. Esta cópia pode ser realizada facilmente com instrução assembly LDIR:

  LD HL,24576   ; Address of screen data to be copied.
  LD DE,16384   ; Address of RAM video.
  LD BC,6912    ; Length of screen data. 
  LDIR          ; Copy data.
  
Uma tela surge repentinamente com a rotina acima, mas por vezes se deseja que haja algum efeito durante a apresentação. Pensando nisto, elaborei o programa "cp8vid", cuja listagem segue abaixo.

;-------------------------------------------------------------------------------
; cp8vid (copy 8 bytes to video RAM)
;-------------------------------------------------------------------------------
; Copy an array of 8x8 pixels at coordinates B (line) and C (column) to the
;video RAM of Spectrum. This array is composed by 8 bytes of bitmap data and
;1 byte of color attribute.
; Input:  B=line, C=column (they aren't changed).
; Output: A=attribute value, A'=last byte of screen bitmap, DE=address of
;         attribute at video RAM, HL=address of attribute that has been copied.
;-------------------------------------------------------------------------------
cp8vid
    LD A,B              ; Spectrum screen is divided in three parts (0, 1 and
    AND 011000       ;2). Calculate what third of screen contains the line.
    OR %01000000        ; Calculate MSB value of address where data will be
    LD H,A              ;copied to (#40, #48 or #50)
    OR %01100000        ; Calculate MSB value of address where data will be
    LD D,A              ;taken from (#60, #68 or #70).
    XOR A               ; A=0.
    LD L,B              ; The LSB of address is taken from the lower 3 bits of
    SRL L               ;line number.
    RRA
    SRL L
    RRA
    SRL L
    RRA
    OR C                ; These 3 bits are ORed with column number (5 bits) to
    LD L,A              ;produce LSB of screen address. HL is pointer for video
    LD E,A              ;RAM and DE for screen stored at 24576 (#6000). 
    LD A,8              ; Counter for 8 bytes that will be tranferred.
cp8vid.l0
    EX AF,AF'           ; Save counter temporarily.
    LD A,(DE)           ; Copy 1 byte.
    LD (HL),A
    INC D               ; Update pointer for next pixel line.
    INC H
    EX AF,AF'           ; Fetch saved counter value and decrement it.
    DEC A
    JR NZ,cp8vid.l0     ; Loop is repeated until all bytes were transferred.
    LD A,B              ; Calculate MSB value of attribute address from line
    RRA                 ;number.
    RRA
    RRA
    AND 000011
    OR %01011000        ; HL points to where attribute data will be copied to
    LD H,A              ;(#58XX, #59XX or #5AXX).
    OR %01111000        ; DE points to where attribute data will be copied from
    LD D,A              ;(#78, #79 ou #7A).
    LD A,(DE)           ; Copy attribute data.
    LD (HL),A
    RET                 ; End of subroutine.

Esta rotina copia um quadrado de 8×8 pixels da tela localizada em 24576 para 16384. Este quadrado corresponde a um caractere e é codificado em 8 bytes. A tela do TK90X é formada por 24 linhas e 32 colunas que totalizam 24×32=768 caracteres. Na rotina cp8vid, deve-se especificar a linha e a coluna do quadrado que se deseja copiar.

Escolhendo as coordenadas de cada quadrado que se deseja copiar e com uso planejado da temporização, é possível fazer vários tipos de efeitos gráficos. No exemplo abaixo, copia-se os quadrados de linha em linha, sendo que há um intervalo de tempo entre as linhas para ficar a impressão de que a tela está surgindo de cima para baixo.

;-------------------------------------------------------------------------------
; cps_wip0 (copy screen wipe 0 deg)
; Wipe screen with horizontal (0 degree) line.
;-------------------------------------------------------------------------------
;
cps_wip0
    LD B,0              ; Line 0.
cps_wip0.l0
    HALT                ; Delay before copying one line.
    LD C,0              ; Column 0.
cps_wip0.l1
    CALL cp8vid         ; Copy 8 bytes to video RAM.
    INC C               ; Increment to next column.
    BIT 5,C             ; Bit 5 is high if last column was transferred.
    JR Z,cps_wip0.l1    ; Repeat until 32 columns are transferred.
    INC B               ; Increment to next line.
    LD A,24             ; Repeat until all 24 lines are copied.
    CP B
    JR NZ,cps_wip0.l0
    RET                 ; End of routine

O efeito pode ser visto no vídeo abaixo:


2 comentários:

Seu comentário é bem vindo, mas peço que use este espaço adequadamente.