Karoshi MSX Community

Desarrollo MSX => Rutinas - Snipets => Mensaje iniciado por: SapphiRe_MSX en 08 de Febrero de 2011, 01:36:37 pm



Título: Volcados rápidos a VRAM: SETVRAMADD + UFLDIRVM
Publicado por: SapphiRe_MSX en 08 de Febrero de 2011, 01:36:37 pm
Primero una rutina para preparar el VDP para una escritura. Los comentarios son lo suficientemente explicativos, la única cuestión es VDPDATAWRITE, que es una dirección de memoria que debe contener el valor del byte 7 de la BIOS (si no tenéis la BIOS desactivada, puede apuntar directamente a la dirección 7).

Código:
SETVRAMADD: ; --- RUTINA QUE PREPARA UNA DIRECCION EN VRAM PARA ESCRIBIR ---
; --- ENTRADA: de -> direccion de VRAM donde escribir        ---
; --- SALIDA: c -> puerto #0 de escritura del VDP            ---
set 6,d ; Activamos el sexto bit del byte alto (normalmente escritura)
ld a,[VDPDATAWRITE] ; a = puerto #0 de escritura del VDP
ld c,a ; c = puerto #0 de escritura del VDP
inc c ; c = puerto #1 de escritura del VDP
out [c],e ; Escribimos en el VDP el byte bajo de la direccion de destino
nop ; Pausa...
nop ; Pausa...
out [c],d ; Escribimos en el VDP el byte alto de la direccion de destino
dec c ; c = puerto #0 de escritura del VDP
ret ; Volvemos

Y ahora la rutina de volcado de RAM a VRAM. Sólo puede usarse dentro del VBLANK o con la pantalla desactivada. Esta rutina vuelca bloques de 16 bytes y hay que hacer un pequeño cálculo (en tiempo de compilación) a la hora de llamar a la rutina.

Si queremos transferir, por ejemplo, la forma de 28 sprites, tendremos que transferir un total de 56 bloques de 16 bytes. Así pues, el valor a meter en b sería:

56*17=952 (se van a realizar 952 decrementos de b)
952 MOD 256=184 (si inicializamos b a 184, justo al realizar los 952 decrementos saldremos del bucle)

Código:
UFLDIRVM: ; --- Volcado de RAM a VRAM version ultra. Usar en el vblank  ---
; --- Entrada: HL = origen en RAM                             ---
; ---          DE = destino en VRAM                           ---
; ---          B = (N. de bloques de 16bytes * 17) MOD 256    ---
call SETVRAMADD ; Llamamos a SETVRAMADD
@@LOOP: outi ; out c,[hl] ; inc hl ; dec b (1)
outi ; out c,[hl] ; inc hl ; dec b (2)
outi ; out c,[hl] ; inc hl ; dec b (3)
outi ; out c,[hl] ; inc hl ; dec b (4)
outi ; out c,[hl] ; inc hl ; dec b (5)
outi ; out c,[hl] ; inc hl ; dec b (6)
outi ; out c,[hl] ; inc hl ; dec b (7)
outi ; out c,[hl] ; inc hl ; dec b (8)
outi ; out c,[hl] ; inc hl ; dec b (9)
outi ; out c,[hl] ; inc hl ; dec b (10)
outi ; out c,[hl] ; inc hl ; dec b (11)
outi ; out c,[hl] ; inc hl ; dec b (12)
outi ; out c,[hl] ; inc hl ; dec b (13)
outi ; out c,[hl] ; inc hl ; dec b (14)
outi ; out c,[hl] ; inc hl ; dec b (15)
outi ; out c,[hl] ; inc hl ; dec b (16)
djnz @@LOOP ; Cerramos el bucle
ret ; Volvemos

Posibles optimizaciones:
  • Se puede integrar SETVRAMADD dentro de la propia rutina UFLDIRVM
  • El tamaño del bloque está fijado a 16, pero se puede cambiar sin mucho problema. Eso implica añadir/quitar tantos OUTI como sean necesarios y cambiar la forma de inicializar b, que, en general, es: (NÚMERO DE BLOQUES * (TAMAÑO+1) ) MOD 256