Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
cursos:ensamblador:gfx1_vram [13-01-2024 10:57] – sromero | cursos:ensamblador:gfx1_vram [21-01-2024 18:43] (actual) – [Efectos sobre la imagen y los atributos] sromero | ||
---|---|---|---|
Línea 79: | Línea 79: | ||
===== La videomemoria del Spectrum ===== | ===== La videomemoria del Spectrum ===== | ||
- | | + | |
Este área de aprox. 7 KB de memoria es donde podemos encontrar la representación digital de la imagen que estamos viendo en el monitor y que la ULA lee regularmente para poder generar la señal de vídeo que requiere el retrazar la imagen. | Este área de aprox. 7 KB de memoria es donde podemos encontrar la representación digital de la imagen que estamos viendo en el monitor y que la ULA lee regularmente para poder generar la señal de vídeo que requiere el retrazar la imagen. | ||
Línea 133: | Línea 133: | ||
ORG 50000 | ORG 50000 | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
END 50000 | END 50000 | ||
Línea 191: | Línea 191: | ||
\\ | \\ | ||
- | * **El área de imagen**: Es el área de memoria que va desde $4000 (16384) hasta $57FF (22527). Este área de memoria de 6 KB almacena la información gráfica de 256x192 píxeles, donde cada byte (de 8 bits) define el estado de 8 píxeles (en cada bit del byte se tiene el estado de un pixel, con 1=activo, 0=no activo), de forma que se puede codificar cada línea de 256 pixeles con 256/8=32 bytes. Utilizando 32 bytes por línea, podemos almacenar el estado de una pantalla completa con 32*192 = 6144 bytes = 6 KB de memoria. Por ejemplo, la celdilla de memoria 16384 contiene el estado de los 8 primeros píxeles de la línea 0 de la pantalla, desde (0,0) a (7,0). | + | * **El área de imagen**: Es el área de memoria que va desde $4000 (16384) hasta $57ff (22527). Este área de memoria de 6 KB almacena la información gráfica de 256x192 píxeles, donde cada byte (de 8 bits) define el estado de 8 píxeles (en cada bit del byte se tiene el estado de un pixel, con 1=activo, 0=no activo), de forma que se puede codificar cada línea de 256 pixeles con 256/8=32 bytes. Utilizando 32 bytes por línea, podemos almacenar el estado de una pantalla completa con 32*192 = 6144 bytes = 6 KB de memoria. Por ejemplo, la celdilla de memoria 16384 contiene el estado de los 8 primeros píxeles de la línea 0 de la pantalla, desde (0,0) a (7,0). |
- | * **El área de atributos**: | + | * **El área de atributos**: |
\\ | \\ | ||
Línea 225: | Línea 225: | ||
<code basic> | <code basic> | ||
10 BORDER 1: PAPER 1: INK 7: CLS | 10 BORDER 1: PAPER 1: INK 7: CLS | ||
- | 20 FOR R = 10 TO 70 STEP 10 : CIRCLE 128, 96, R : NEXT R | + | 20 FOR r = 10 TO 70 STEP 10 : CIRCLE 128, 96, R : NEXT R |
30 PAUSE 0 | 30 PAUSE 0 | ||
40 INK 2 : PLOT 30, 30 : DRAW 220, 120 | 40 INK 2 : PLOT 30, 30 : DRAW 220, 120 | ||
Línea 284: | Línea 284: | ||
===== Videomemoria: | ===== Videomemoria: | ||
- | El área de imagen del Spectrum es el bloque de 6144 bytes (6KB) entre 16384 ($4000) y 22527 ($57FF). Cada una de las posiciones de memoria de este área almacenan la información de imagen (estado de los píxeles) de 8 píxeles de pantalla consecutivos, | + | El área de imagen del Spectrum es el bloque de 6144 bytes (6KB) entre 16384 ($4000) y 22527 ($57ff). Cada una de las posiciones de memoria de este área almacenan la información de imagen (estado de los píxeles) de 8 píxeles de pantalla consecutivos, |
Como veremos cuando hablemos del área de atributos, que los píxeles estén a ON o a OFF no implica que la ULA sólo dibuje los píxeles activos. Si el pixel está activo (bit a 1), la ULA lo traza en pantalla utilizando el color de tinta actual que corresponda a ese píxel mientras que un bit a 0 significa que el pixel no está encendido y que la ULA debe de dibujarlo con el color de papel actual. | Como veremos cuando hablemos del área de atributos, que los píxeles estén a ON o a OFF no implica que la ULA sólo dibuje los píxeles activos. Si el pixel está activo (bit a 1), la ULA lo traza en pantalla utilizando el color de tinta actual que corresponda a ese píxel mientras que un bit a 0 significa que el pixel no está encendido y que la ULA debe de dibujarlo con el color de papel actual. | ||
Línea 334: | Línea 334: | ||
<code basic> | <code basic> | ||
10 CLS | 10 CLS | ||
- | 20 FOR I=0 TO 31 : POKE 16384+I, 170 : NEXT I | + | 20 FOR i=0 TO 31 : POKE 16384+I, 170 : NEXT I |
30 PAUSE 0 | 30 PAUSE 0 | ||
</ | </ | ||
Línea 356: | Línea 356: | ||
<code basic> | <code basic> | ||
10 CLS | 10 CLS | ||
- | 20 FOR I=0 TO 63 : POKE 16384+I, 170 : NEXT I | + | 20 FOR i=0 TO 63 : POKE 16384+I, 170 : NEXT I |
30 PAUSE 0 | 30 PAUSE 0 | ||
</ | </ | ||
Línea 387: | Línea 387: | ||
* (etc...) | * (etc...) | ||
- | Así hasta el byte 18331 o $47FF (cuando hemos avanzado 32*8*8 | + | Así hasta el byte 18331 o $47ff (cuando hemos avanzado 32*8*8 |
\\ | \\ | ||
Línea 396: | Línea 396: | ||
\\ | \\ | ||
- | | + | |
\\ | \\ | ||
- | * **Primer tercio**: Los 2 primeros KB de la videoram (de $4000 a $47FF) cubren los datos gráficos de los primeros 64 scanlines de la pantalla (líneas 0 a 7). | + | * **Primer tercio**: Los 2 primeros KB de la videoram (de $4000 a $47ff) cubren los datos gráficos de los primeros 64 scanlines de la pantalla (líneas 0 a 7). |
- | * **Segundo tercio**: Los siguientes 2KB de la videoram (de $4800 a $4FFF) cubren los datos gráficos de los siguientes 64 scanlines de la pantalla (líneas 8 a 15). | + | * **Segundo tercio**: Los siguientes 2KB de la videoram (de $4800 a $4fff) cubren los datos gráficos de los siguientes 64 scanlines de la pantalla (líneas 8 a 15). |
- | * **Tercer tercio**: Los siguientes 2KB de la videoram (de $5000 a $57FF) cubren los datos gráficos de los últimos 64 scanlines de la pantalla (líneas 16 a 23). | + | * **Tercer tercio**: Los siguientes 2KB de la videoram (de $5000 a $57ff) cubren los datos gráficos de los últimos 64 scanlines de la pantalla (líneas 16 a 23). |
\\ | \\ | ||
Línea 419: | Línea 419: | ||
Con el programa de ejemplo del apartado // | Con el programa de ejemplo del apartado // | ||
- | | + | |
<code z80> | <code z80> | ||
Línea 427: | Línea 427: | ||
; | ; | ||
ClearScreen: | ClearScreen: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
; porque ya hemos escrito en 16384. | ; porque ya hemos escrito en 16384. | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 480: | Línea 480: | ||
Start: | Start: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
bucle_192_lineas: | bucle_192_lineas: | ||
- | | + | |
; bucle exterior (usaremos B ahora en otro) | ; bucle exterior (usaremos B ahora en otro) | ||
- | | + | |
- | | + | |
- | | + | |
bucle_32_bytes: | bucle_32_bytes: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
; | ; | ||
Línea 511: | Línea 511: | ||
; | ; | ||
ClearScreen: | ClearScreen: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
INCLUDE " | INCLUDE " | ||
Línea 566: | Línea 566: | ||
| 7 | $4700 | | | 7 | $4700 | | ||
- | Tal y como está organizada la videoram, basta con calcular la dirección de inicio del bloque en baja resolución donde queremos trazar un carácter, imprimir los 8 píxeles que forman su scanline (con la escritura de un único byte en videomemoria), | + | Tal y como está organizada la videoram, basta con calcular la dirección de inicio del bloque en baja resolución donde queremos trazar un carácter, imprimir los 8 píxeles que forman su scanline (con la escritura de un único byte en videomemoria), |
| | ||
Línea 574: | Línea 574: | ||
===== Videomemoria: | ===== Videomemoria: | ||
- | El área de atributos es el bloque de 768 bytes entre $5800 (22528) y $5AFF (23295), ambas celdillas de memoria incluídas. Cada una de las posiciones de memoria de este área almacenan la información de color (color de tinta, color de papel, brillo y flash) de un bloque de 8x8 píxeles en la pantalla. | + | El área de atributos es el bloque de 768 bytes entre $5800 (22528) y $5aff (23295), ambas celdillas de memoria incluídas. Cada una de las posiciones de memoria de este área almacenan la información de color (color de tinta, color de papel, brillo y flash) de un bloque de 8x8 píxeles en la pantalla. |
El tamaño de 768 bytes de este área viene determinado por la resolución del sistema de color del Spectrum: Hemos dicho que el sistema gráfico dispone de una resolución de 256x192, pero el sistema de color divide la pantalla en bloques de 8x8 píxeles, lo que nos da una resolución de color de 256/8 x 192/8 = 32x24 bloques. Como la información de color de cada bloque se codifica en un único byte, para almacenar la información de color de toda una pantalla se requieren 32 x 24 x 1 = 768 bytes. | El tamaño de 768 bytes de este área viene determinado por la resolución del sistema de color del Spectrum: Hemos dicho que el sistema gráfico dispone de una resolución de 256x192, pero el sistema de color divide la pantalla en bloques de 8x8 píxeles, lo que nos da una resolución de color de 256/8 x 192/8 = 32x24 bloques. Como la información de color de cada bloque se codifica en un único byte, para almacenar la información de color de toda una pantalla se requieren 32 x 24 x 1 = 768 bytes. | ||
Línea 589: | Línea 589: | ||
\\ | \\ | ||
- | Se puede decir que el área de atributos es totalmente lineal; consta de 768 bytes que se corresponden de forma consecutiva con el estado de cada bloque y de cada fila horizontal de bloques de pantalla: Los primeros 32 bytes del área se corresponden con la primera fila horizontal de bloques, los siguientes 32 bytes con la segunda, los siguientes 32 bytes con la tercera, hasta los últimos 32 bytes, que se corresponden con los de la línea 23. El byte alojado en la última posición ($5AFF) se corresponde con el atributo del bloque (31,23). | + | Se puede decir que el área de atributos es totalmente lineal; consta de 768 bytes que se corresponden de forma consecutiva con el estado de cada bloque y de cada fila horizontal de bloques de pantalla: Los primeros 32 bytes del área se corresponden con la primera fila horizontal de bloques, los siguientes 32 bytes con la segunda, los siguientes 32 bytes con la tercera, hasta los últimos 32 bytes, que se corresponden con los de la línea 23. El byte alojado en la última posición ($5aff) se corresponde con el atributo del bloque (31,23). |
A continuación podemos ver una tabla que muestra los inicios y fin de cada línea de atributos en pantalla: | A continuación podemos ver una tabla que muestra los inicios y fin de cada línea de atributos en pantalla: | ||
Línea 595: | Línea 595: | ||
|< 50% >| | |< 50% >| | ||
^ Línea ^ Inicio (carácter 0,N) ^ Fin (carácter 31,N) ^ | ^ Línea ^ Inicio (carácter 0,N) ^ Fin (carácter 31,N) ^ | ||
- | | 0 | $5800 | $581F | | + | | 0 | $5800 | $581f | |
- | | 1 | $5820 | $583F | | + | | 1 | $5820 | $583f | |
- | | 2 | $5860 | $585F | | + | | 2 | $5860 | $585f | |
- | | 3 | $5840 | $587F | | + | | 3 | $5840 | $587f | |
- | | 4 | $5880 | $589F | | + | | 4 | $5880 | $589f | |
- | | 5 | $58A0 | $58BF | | + | | 5 | $58a0 | $58bf | |
- | | 6 | $58C0 | $58DF | | + | | 6 | $58c0 | $58df | |
- | | 7 | $58E0 | $58FF | | + | | 7 | $58e0 | $58ff | |
- | | 8 | $5900 | $591F | | + | | 8 | $5900 | $591f | |
- | | 9 | $5920 | $593F | | + | | 9 | $5920 | $593f | |
- | | 10 | $5940 | $595F | | + | | 10 | $5940 | $595f | |
- | | 11 | $5960 | $597F | | + | | 11 | $5960 | $597f | |
- | | 12 | $5980 | $599F | | + | | 12 | $5980 | $599f | |
- | | 13 | $59A0 | $59BF | | + | | 13 | $59a0 | $59bf | |
- | | 14 | $59C0 | $59DF | | + | | 14 | $59c0 | $59df | |
- | | 15 | $59E0 | $59FF | | + | | 15 | $59e0 | $59ff | |
- | | 16 | $5A00 | $5A1F | | + | | 16 | $5a00 | $5a1f | |
- | | 17 | $5A20 | $5A3F | | + | | 17 | $5a20 | $5a3f | |
- | | 18 | $5A40 | $5A5F | | + | | 18 | $5a40 | $5a5f | |
- | | 19 | $5A60 | $5A7F | | + | | 19 | $5a60 | $5a7f | |
- | | 20 | $5A80 | $5A9F | | + | | 20 | $5a80 | $5a9f | |
- | | 21 | $5AA0 | $5ABF | | + | | 21 | $5aa0 | $5abf | |
- | | 22 | $5AC0 | $5ADF | | + | | 22 | $5ac0 | $5adf | |
- | | 23 | $5AE0 | $5AFF | | + | | 23 | $5ae0 | $5aff | |
Esta organización del área de atributos es muy sencilla y permite un cálculo muy sencillo de la posición de memoria del atributo de un bloque concreto de pantalla. Es decir, podemos encontrar fácilmente la posición de memoria que almacena el atributo que corresponde a un bloque concreto en baja resolución de pantalla mediante: | Esta organización del área de atributos es muy sencilla y permite un cálculo muy sencillo de la posición de memoria del atributo de un bloque concreto de pantalla. Es decir, podemos encontrar fácilmente la posición de memoria que almacena el atributo que corresponde a un bloque concreto en baja resolución de pantalla mediante: | ||
Línea 736: | Línea 736: | ||
Start: | Start: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
bucle_lineas: | bucle_lineas: | ||
- | | + | |
; bucle exterior (usaremos B ahora en otro) | ; bucle exterior (usaremos B ahora en otro) | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
no_resetear_papel: | no_resetear_papel: | ||
- | | + | |
- | | + | |
- | | + | |
bucle_32_bytes: | bucle_32_bytes: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
papel DEFB | papel DEFB | ||
Línea 783: | Línea 783: | ||
; | ; | ||
ClearScreen: | ClearScreen: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
INCLUDE " | INCLUDE " | ||
Línea 816: | Línea 816: | ||
; | ; | ||
ClearAttributes: | ClearAttributes: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
; porque ya hemos escrito en 22528. | ; porque ya hemos escrito en 22528. | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 840: | Línea 840: | ||
; | ; | ||
ClearScreenAttrib: | ClearScreenAttrib: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 876: | Línea 876: | ||
El conocido comando de BASIC '' | El conocido comando de BASIC '' | ||
- | | + | |
En el capítulo dedicado a los Puertos de Entrada / Salida pudimos ya observar un ejemplo de cambio de color del borde, que ahora vamos a modificar para separar el OUT en una función '' | En el capítulo dedicado a los Puertos de Entrada / Salida pudimos ya observar un ejemplo de cambio de color del borde, que ahora vamos a modificar para separar el OUT en una función '' | ||
Línea 884: | Línea 884: | ||
ORG 50000 | ORG 50000 | ||
- | | + | |
start: | start: | ||
bucle: | bucle: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
suelta_tecla: | suelta_tecla: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
salir: | salir: | ||
- | | + | |
; | ; | ||
Línea 914: | Línea 914: | ||
; | ; | ||
SetBorder: | SetBorder: | ||
- | | + | |
- | | + | |
END 50000 ; Ejecucion en 50000 | END 50000 ; Ejecucion en 50000 | ||
Línea 934: | Línea 934: | ||
; | ; | ||
SetBorder: | SetBorder: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
; Si es bright | ; Si es bright | ||
- | | + | |
SetBorder_fin: | SetBorder_fin: | ||
- | | + | |
- | | + | |
</ | </ | ||
- | | + | |
| | ||
Línea 957: | Línea 957: | ||
ORG 50000 | ORG 50000 | ||
- | | + | |
start: | start: | ||
bucle: | bucle: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
salir: | salir: | ||
- | | + | |
END 50000 | END 50000 | ||
Línea 984: | Línea 984: | ||
<code basic> | <code basic> | ||
- | 10 FOR I=0 TO 7 : BORDER I : NEXT I : GOTO 10 | + | 10 FOR i=0 TO 7 : BORDER I : NEXT I : GOTO 10 |
</ | </ | ||
Línea 998: | Línea 998: | ||
===== El " | ===== El " | ||
- | Ahora que conocemos el formato de una celdilla de atributo podemos hablar de la variable del sistema '' | + | Ahora que conocemos el formato de una celdilla de atributo podemos hablar de la variable del sistema '' |
- | A continuación tenemos un ejemplo que imprime cadenas con diferentes atributos de color. Para ello se ha creado una rutina PrintString basada en imprimir caracteres mediante '' | + | A continuación tenemos un ejemplo que imprime cadenas con diferentes atributos de color. Para ello se ha creado una rutina PrintString basada en imprimir caracteres mediante '' |
<code z80> | <code z80> | ||
Línea 1008: | Línea 1008: | ||
Start: | Start: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | ATTR_T | + | ATTR_T |
; | ; | ||
Línea 1050: | Línea 1050: | ||
</ | </ | ||
- | Con nuestra nueva rutina de '' | + | Con nuestra nueva rutina de '' |
\\ | \\ | ||
Línea 1080: | Línea 1080: | ||
Start: | Start: | ||
; Rellenamos la VRAM de pixeles copiando 6 KB de la ROM | ; Rellenamos la VRAM de pixeles copiando 6 KB de la ROM | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
; | ; | ||
Línea 1094: | Línea 1094: | ||
; | ; | ||
FadeScreen: | FadeScreen: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
fadegfx_loop1: | fadegfx_loop1: | ||
- | | + | |
- | | + | |
fadegfx_loop2: | fadegfx_loop2: | ||
- | | + | |
;-- Actuamos sobre el valor de los pixeles -- | ;-- Actuamos sobre el valor de los pixeles -- | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
fadegfx_mayor15: | fadegfx_mayor15: | ||
- | | + | |
- | | + | |
;-- Fin actuacion sobre el valor de los pixeles -- | ;-- Fin actuacion sobre el valor de los pixeles -- | ||
Línea 1132: | Línea 1132: | ||
fadegfx_save: | fadegfx_save: | ||
- | | + | |
- | | + | |
; Incrementamos el contador y comprobamos si hay que resetearlo | ; Incrementamos el contador y comprobamos si hay que resetearlo | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
fadegfx_continue: | fadegfx_continue: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
INCLUDE " | INCLUDE " | ||
Línea 1178: | Línea 1178: | ||
; | ; | ||
FadeAttributes: | FadeAttributes: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
fadescreen_loop1: | fadescreen_loop1: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
fadescreen_loop2: | fadescreen_loop2: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
fadescreen_ink_zero: | fadescreen_ink_zero: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
fadescreen_paper_zero: | fadescreen_paper_zero: | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
</ | </ | ||
Línea 1246: | Línea 1246: | ||
| | ||
+ | |||
+ | Del mismo modo, el libro **//40 Best Machine code Routines for the ZX Spectrum// | ||
+ | |||
+ | \\ | ||
+ | * Scrollear atributos a izquierda, derecha, arriba o abajo. | ||
+ | * Scroll de pantalla de un carácter (8 pixels) a izquierda, derecha, arriba o abajo. | ||
+ | * Scroll de pantalla de un pixel a izquierda, derecha, arriba o abajo. | ||
+ | * Mezclar dos imágenes con '' | ||
+ | * Inversión de la pantalla (píxeles a 0 se ponen a 1, y píxeles a 1 se ponen a 0). | ||
+ | * Invertir carácter vertical y horizontalmente. | ||
+ | * Rotar carácter 90º en sentido horario. | ||
+ | * Alterar todos los atributos de la pantalla (los bits deseados). | ||
+ | * Cambiar todos los atributos de la pantalla de un determinado valor por otro valor. | ||
+ | * Rellenado de regiones cerradas (poniendo a 1 los píxeles dentro de esas regiones). | ||
+ | * Impresión de figuras. | ||
+ | * Copia de una zona de la pantalla en otra, ampliándola por una cantidad entera (por ejemplo, x2 o x3). | ||
+ | |||
\\ | \\ | ||
===== La Shadow VRAM de los modelos de 128K ===== | ===== La Shadow VRAM de los modelos de 128K ===== | ||
- | En el capítulo dedicado a la paginación de memoria en los modelos de 128KB se habló de la paginación de bloques de 16KB sobre el área entre $C000 y $FFFF. El bloque de 16KB que almacena la videoram (el bloque 5, o, como se le conoce técnicamente, | + | En el capítulo dedicado a la paginación de memoria en los modelos de 128KB se habló de la paginación de bloques de 16KB sobre el área entre $c000 y $ffff. El bloque de 16KB que almacena la videoram (el bloque 5, o, como se le conoce técnicamente, |
\\ | \\ | ||
Línea 1259: | Línea 1276: | ||
\\ | \\ | ||
- | En los modelos de 128K, existe un segundo bloque de 16KB que podemos utilizar como VideoRAM (**Shadow VRAM**). El Z80 y la ULA nos permiten mapear **RAM7** sobre $C000-$FFFF, dejando la VideoRAM original sobre $4000. Más interesante todavía, la ULA puede visualizar el contenido de RAM7 en lugar del de RAM5 aunque no hayamos mapeado RAM7 en ningún sitio. Y recordemos que también podemos mapear la VRAM estándar (RAM5) sobre $C000, accediendo a ella a través de $C000 además de mediante $4000. | + | En los modelos de 128K, existe un segundo bloque de 16KB que podemos utilizar como VideoRAM (**Shadow VRAM**). El Z80 y la ULA nos permiten mapear **RAM7** sobre $c000-$ffff, dejando la VideoRAM original sobre $4000. Más interesante todavía, la ULA puede visualizar el contenido de RAM7 en lugar del de RAM5 aunque no hayamos mapeado RAM7 en ningún sitio. Y recordemos que también podemos mapear la VRAM estándar (RAM5) sobre $c000, accediendo a ella a través de $c000 además de mediante $4000. |
- | El poder visualizar una VRAM aunque no esté mapeada y el poder mapear tanto RAM5 como RAM7 sobre $C000 nos permite organizar el código de nuestro programa para que siempre escriba sobre $C000, teniendo mapeada en $C000 la pantalla que actualmente no esté visible. | + | El poder visualizar una VRAM aunque no esté mapeada y el poder mapear tanto RAM5 como RAM7 sobre $c000 nos permite organizar el código de nuestro programa para que siempre escriba sobre $c000, teniendo mapeada en $c000 la pantalla que actualmente no esté visible. |
La utilidad principal de esta funcionalidad es la de poder generar un cuadro de imagen o animación en una " | La utilidad principal de esta funcionalidad es la de poder generar un cuadro de imagen o animación en una " | ||
Línea 1268: | Línea 1285: | ||
\\ | \\ | ||
- | * Mapeamos RAM7 sobre $C000. | + | * Mapeamos RAM7 sobre $c000. |
* Visualizamos RAM5 (RAM7 no es visible). | * Visualizamos RAM5 (RAM7 no es visible). | ||
- | * Trabajamos sobre $C000 (sobre RAM7). Los cambios en nuestra pantalla shadow no son visibles. | + | * Trabajamos sobre $c000 (sobre RAM7). Los cambios en nuestra pantalla shadow no son visibles. |
- | * Esperamos una interrupción (mediante | + | * Esperamos una interrupción (mediante |
* Cambiamos la visualización a RAM7 (RAM5 deja de ser visible). | * Cambiamos la visualización a RAM7 (RAM5 deja de ser visible). | ||
- | * Mapeamos ahora RAM5 sobre $C000. | + | * Mapeamos ahora RAM5 sobre $c000. |
- | * Trabajamos sobre $C000 (sobre RAM5). Los cambios en nuestra pantalla shadow no son visibles. | + | * Trabajamos sobre $c000 (sobre RAM5). Los cambios en nuestra pantalla shadow no son visibles. |
* Repetimos el proceso. | * Repetimos el proceso. | ||
\\ | \\ | ||
- | Con este mecanismo siempre trabajamos sobre $C000 pero los cambios que realizamos sobre esta pantalla virtual no son perceptibles por el usuario. Cambiando la visualización de la VRAM a nuestra pantalla actual tras una interrupción hacemos los cambios visibles de forma inmediata, sin que el haz de electrones afecte a nuestro scroll o al dibujado de sprites. La tasa de fotogramas por segundo ya no sería de 50 (no podríamos generar 1 cuadro de imagen por interrupción) pero se evitaría un posible molesto efecto de parpadeo o cortinilla. | + | Con este mecanismo siempre trabajamos sobre $c000 pero los cambios que realizamos sobre esta pantalla virtual no son perceptibles por el usuario. Cambiando la visualización de la VRAM a nuestra pantalla actual tras una interrupción hacemos los cambios visibles de forma inmediata, sin que el haz de electrones afecte a nuestro scroll o al dibujado de sprites. La tasa de fotogramas por segundo ya no sería de 50 (no podríamos generar 1 cuadro de imagen por interrupción) pero se evitaría un posible molesto efecto de parpadeo o cortinilla. |
- | La desventaja de este sistema es que utilizamos $C000-$FFFF como pantalla virtual con lo que perdemos 16KB efectivos de RAM así como la posibilidad de paginar sobre $C000. Nos quedan así 16KB de memoria (entre $8000 y $BFFF) para alojar el código de nuestro programa, los datos gráficos, textos, etc. Esto puede ser una enorme limitación según el tipo de juego o programa que estemos realizando. | + | La desventaja de este sistema es que utilizamos $c000-$ffff como pantalla virtual con lo que perdemos 16KB efectivos de RAM así como la posibilidad de paginar sobre $c000. Nos quedan así 16KB de memoria (entre $8000 y $bfff) para alojar el código de nuestro programa, los datos gráficos, textos, etc. Esto puede ser una enorme limitación según el tipo de juego o programa que estemos realizando. |
- | En realidad, si diseñamos adecuadamente nuestro programa, podemos aprovechar más de 16KB, puesto que sólo necesitamos mapear RAM5 ó RAM7 en $C000 durante la generación de la pantalla virtual. Esto obliga a que los gráficos, fuentes, sprites y mapeados del juego deban estar disponibles en $8000-$BFFF, pero una vez finalizada la generación de la pantalla podemos volver a mapear RAM0 sobre $C000, volviendo a la lógica del juego que podría estar ubicada en ese bloque, junto al resto de variables, imágenes o textos usados en los menúes, efectos sonoros, músicas, etc. | + | En realidad, si diseñamos adecuadamente nuestro programa, podemos aprovechar más de 16KB, puesto que sólo necesitamos mapear RAM5 ó RAM7 en $c000 durante la generación de la pantalla virtual. Esto obliga a que los gráficos, fuentes, sprites y mapeados del juego deban estar disponibles en $8000-$bfff, pero una vez finalizada la generación de la pantalla podemos volver a mapear RAM0 sobre $c000, volviendo a la lógica del juego que podría estar ubicada en ese bloque, junto al resto de variables, imágenes o textos usados en los menúes, efectos sonoros, músicas, etc. |
- | Como véis, se necesita tener muy controlada la ubicación de las diferentes rutinas y variables y diseñar el juego para que mapee la página adecuada en cada momento y salte a una rutina concreta sólo cuando la rutina a la que hace referencia un CALL esté contenida en la página mapeada. | + | Como véis, se necesita tener muy controlada la ubicación de las diferentes rutinas y variables y diseñar el juego para que mapee la página adecuada en cada momento y salte a una rutina concreta sólo cuando la rutina a la que hace referencia un call esté contenida en la página mapeada. |
- | Se reseñó también, en el apartado // | + | Se reseñó también, en el apartado // |
\\ | \\ | ||
Línea 1295: | Línea 1312: | ||
\\ | \\ | ||
- | Como puede verse en la figura anterior, los modos Bit2 = 0, Bit1 = 1 (Bancos 4-5-6-3) y Bit2 = 1, Bit 1=1 (Bancos 4-7-6-3) del puerto $1FFD permiten paginar cualquiera de las 2 videorams (RAM5 o RAM7) sobre $4000. | + | Como puede verse en la figura anterior, los modos Bit2 = 0, Bit1 = 1 (Bancos 4-5-6-3) y Bit2 = 1, Bit 1=1 (Bancos 4-7-6-3) del puerto $1ffd permiten paginar cualquiera de las 2 videorams (RAM5 o RAM7) sobre $4000. |
- | Pese a las posibilidades de " | + | Pese a las posibilidades de " |
\\ | \\ |