Skip to content

DEZ80: Nivel 1

Juan Gonzalez-Gomez edited this page Sep 7, 2021 · 148 revisions

Índice

Introducción

Nivel 1: Práctica

Vídeo 1.P01: Introducción al nivel 1

Click to see the youtube video

  • Descripción del contenido del curso:
    • Programar en código máquina
    • Binario y hexadecimal
    • Memoria principal y procesador
  • Desafío: Pintar un Sprite en código ḿáquina

Vídeo 1.P02: Instalación de WinAPE en Ubuntu Linux

Click to see the youtube video

  • Objetivo: Instalar y poner en funcionamiento el emulador del Amstrad CPC. Se utiliza el WinApe. Es una aplicación para Windows, pero se ejecuta perfectamente en Linux a través de Wine
  • Observaciones: La instalacion de wine en Ubuntu 20.04 es mucho más fácil (El vídeo se hizo en el 2017 para Ubuntu 17.04)

Instalación de cpctelera

Aunque esto no es de este nivel, para instalar y arrancar Winape más fácilmente he utilizado CPCtelera

Para instalarlo en Ubuntu 20.04 hay que seguir estos pasos:

  • Instalar las dependencias
sudo apt install gcc g++ make bison flex mono-complete libboost-dev libfreeimage-dev wget unzip
  • Instalar wine

  • Descargar: cpctelera-1-4-2.zip

  • Descomprimir el archivo de cpctelera. En mi caso lo tengo en este directorio: /home/obijuan/Bin/cpctelera-1.4.2

  • Ejecutar setup.sh:

Dentro del directorio cpctelera-1.4.2 hay un archivo llamado setup.sh

obijuan@corellia:~/Bin/cpctelera-1.4.2$ ls
cpctelera  examples  GPL-LICENSE  LICENSE  README.md  setup.sh

Al ejecutarse se comprueban las dependencias y se instala cpctelera:

./setup.sh
  • Cerrar el terminal

Cuando abramos otro terminal ya se tendrá acceso a todos los scripts y utilidades de cpctelera (se ha modificado el path en la instalación)

Instalación de winape desde cpctelera

Para instalar winape ejecutar el siguiente script desde cualquier directorio:

obijuan@corellia:~$ cpct_winape 

%%%%%%%%%%%%%%%%%%%%%%%%%
%% WinAPE laucher script
%%%%%%%%%%%%%%%%%%%%%%%%%

[Warning] WinAPE is not configured for your system yet.

Proceeding to install/configure WinAPE on your system.

Do you already have WinAPE installed (y/n)?n
[...]

La primera vez se detecta que winape NO está instalado y si le indicamos que no lo tenemos instalado lo descarga automáticamente, lo instala y lo ejecuta

Ejecución de winape

Si ya está instalado winape, bastará con ejecutar este script:

cpct_winape

Winape arrancará directamente

Configuración de WinApe

Para configurar WinApe para trabajar en el curso vamos a la opción Settings/Display:

Así es como deben quedar las opciones:

Las opciones señaladas por flechas rojas son las que se han cambiado:

  • Hide mouse pointer: DESMARCADA. Queremos que se vea el cursor del ratón al pasarlo por la ventana del emulador
  • Directx strech: DESMARCADA. Para evitar problemas con la visualización en wine
  • PAL emulation: DESMARCADA. La pantalla del emulador la veremos con más nitidez
  • On Screen Drive LED: MARCADA
  • Show Drive Cylinders: MARCADA

Vídeo 1.P03:Ejemplo: Reto 1.1: Pintar un pixel rojo en la pantalla

Click to see the youtube video

  • Código máquina: 3E 88 32 00 C0 18 FE
  • Almacenado en dirección 0x4000
  • Explicación: Almacenar el valor 0x88 en la dirección 0xC000 (Memoria de video). Esto hace que aparezca un pixel rojo en la esquina superior izquierda
  • Resultado de la ejecución:

En esta imagen ampliada se puede ver mejor el pixel que aparece:

  • Programa desensamblado:
LD A,#88
LD (#C000),A
JR #4005

Vídeo 1.P04: Jugando con el código

Click to see the youtube video

Vamos a realizar varios experimentos para irnos familiarizando con el código máquina, el emulador y el funcionamiento de la memoria de vídeo. Como explica Fran, vamos a aprender por nuestra cuenta. Vamos a practicar y a experimentar. Y luego visualizaremos los vídeos de teoría para comprender perfectamente el funcionamiento

Experimento 1: Escribiendo un único bit en C000

La memoria del CPC es de bytes. En cada posición de memoria se almacena un byte. En un byte hay 8 bits. El objetivo de este experimento es escribir valores que tengan sólo un bit a 1 y el resto a 0, para descubrir el significado de cada bit

Así, los valores que vamos a escribir en binario son: 1000000, 01000000, 00100000, 00010000, 0000100, 00000100, 00000010 y 00000001, que en hexadecimal se corresponden con estos números: 80, 40, 20, 10, 08, 04, 02 y 01

El programa para guardar el valor 88 en la dirección c000 ya lo conocemos. Bastará con sustituir 88 por los nuevos valores y ver qué ocurre:

Prueba 1

  • Valor 80 en C000
  • Código máquina: 3E 80 32 00 c0 18 FE
  • Programa desensamblado:
ld a,#80
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel amarillo en la primera posicion

En esta imagen se ve ampliado:

Prueba 2

  • Valor 40 en C000
  • Código máquina: 3E 40 32 00 c0 18 FE
  • Programa desensamblado:
ld a,#40
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel amarillo en la segunda posición (justo a continuación de la posición del pixel de la prueba anterior)

Para comprobar la posición del nuevo pixel respecto al anterior hacemos una captura y la alineamos con la captura de la prueba anterior. Vemos que el nuevo pixel está en la misma horizontal que el anterior, y que en la vertical está desplazado exactametne un pixel a la derecha

Prueba 3

  • Valor 20 en C000
  • Código máquina: 3E 20 32 00 c0 18 FE
  • Programa desensamblado:
ld a,#20
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel amarillo en la tercera posición (Desplazado dos píxeles con respeto al pixel de la prueba 1)

Prueba 4

  • Valor 10 en C000
  • Código máquina: 3E 10 32 00 c0 18 FE
  • Programa desensamblado:
ld a,#10
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel amarillo en la cuarta posición (Desplazado tres píxeles con respeto al pixel de la prueba 1)

Prueba 5

  • Valor 08 en C000
  • Código máquina: 3E 08 32 00 c0 18 FE
  • Programa desensamblado:
ld a,#08
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel cyan en la primera posición (Misma posición que el pixel amarillo de la prueba 1)

Esta es la imagen ampliada

Y en este dibujo se comprueba que efectivamente es la misma posición que el pixel amarillo de la prueba 1

Pruebas 6,7 y 8

  • Valor 04 en C000
  • Código máquina: 3E 04 32 00 c0 18 FE
  • Programa desensamblado:
ld a,#04
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel cyan en la segunda posición

  • Prueba 7

  • Valor 02 en C000

  • Código máquina: 3E 02 32 00 c0 18 FE

  • Programa desensamblado:

ld a,#02
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel cyan en la tercera posición

  • Prueba 8

  • Valor 01 en C000

  • Código máquina: 3E 01 32 00 c0 18 FE

  • Programa desensamblado:

ld a,#01
ld (#c000),a
jr #4005
  • Resultado: Se dibuja un pixel cyan en la cuarta posición

Los resultados de las pruebas 5,6,7 y 8 se representan en esta figura:

Las posiciones son las mismas que en las pruebas 1,2,3 y 4, pero el pixel es cyan en vez de amarillo

Experimento 2: Escritura en la posición C001

TODO

Experimento 3: Localizar posiciones de memoria de las lineas
Experimento 4: Localizar posicion de memoria de la linea 2
Experimento 5: Pintar una bandera

Bandera:

ld A,#FF
ld (#C000),A
ld (#C800),A
ld A,#F0
ld (#D000),A
ld (#D800),A
ld (#E000),A
ld (#E800),A
ld A,#FF
ld (#F000),A
ld (#F800),A

Código máquina: 3E,FF,32,00,C0,32,00,C8,3E,F0,32,00,D0,32,00,D8,32,00,E0,32,00,E8,3E,FF,32,00,F0,32,00,F8,18,FE

Vídeo 1.P05: Ejecutando Paso a paso

Click to see the youtube video

  • Resumen: Para depurar nuestros programas utilizamos la ejecución paso a paso. Pulsando la tecla F7 hacemos que el procesador ejecuta una única instrucción y que se pare. Esto nos permite comprobar qué es lo que va sucediendo. Para editar nuestros programas en código máquina podemos hacer copy & paste en la memoria. No hay ninguna opción para hacerlo gráficamente. Hay que usar las típicas teclas de cortar y pegar: Ctr-C (Copiar), Ctr-V (Pegar), Ctrl-X (Cortar)

  • Programa inicial de pruebas: Se quiere sacar por la pantalla un total de 8 píxeles, por lo que hay que escribir dos valores, uno en la dirección C000 y otro en la C001. El programa inicial propuesto (que no funciona, pero que vamos a depurar) es este:

    • Código máquina: 3E 88 3E 93 32 00 C0 18 FE
    • Programa desensamblado:
LD A, #88
LD A, #93
LD (#C000),A
JR #4007
  • Depuración: Al ejecutar el programa paso a paso vemos que el registro A se carga con el valor 88 y en el siguiente paso se escribe uno nuevo: 93, machacando el valro anterior. En la posición de memoria C000 se escribe por tanto sólo el valor 93
  • Solución: Lo que se quiere es que salgan 8 píxeles por lo que habrá que escribir el valor 88 en C000 y el valor 93 en C001. El número código (que ya funciona) es este:
    • Código máquina: 3E 88 32 00 C0 3E 93 32 01 C0 18 FE
    • Programa desensamblado:
LD A, #88
LD (#C000),A
LD A, #93
LD (#C001),A
JR #400A

Y este es el resultado obtenido al ejecutarlo:

En esta imagen se pueden ver los píxeles ampliados:

Vídeo 1.P06: Reto: Utilizar los colores

Click to see the youtube video

  • En este reto hay que realizar 4 actividades:

    • Actividad 1: Pinta el primer pixel en amarillo (¡OJO! Debe haber sólo un pixel, y tiene que ser el primero)
    • Actividad 2: Pintar el mismo pixel en Cyan
    • Actividad 3: Pintar el mismo pixel en Rojo
    • Actividad 4: Pintar el mismo pixel en color del fondo (para que no se vea)
  • Truco: Para distinguir si el pixel pintado es el primero ponemos el borde negro utilizando este comando en basic

border 0

La pantalla nos quedará así:

Codificación de colores

Por los experimentos realizados en el vídeo 1.P04 y por los vídeos de teoría, sabemos que cada byte que se escribe en la memoria de video hay 4 pixeles codificados. Para cada pixel se usan 2 bits, lo que nos permite establecer 4 colores diferentes:

  • 00: Color del fondo
  • 01: Cyan
  • 10: Amarillo
  • 11: Rojo

Cada posición de memoria de vídeo la podemos representar como 2 nibbles (4 bits) uno encima de otro (el nibble superior encima). Cada Columna representa un pixel: P1, P2, P3 y P4. El que tenemos que pintar en este reto es el Pixel 1. Así por ejemplo, el valor 88 (que ya hemos usado y que sabemos que produce un color rojo) en binario es: 10001000. Y si lo dibujamos como nibbles tendría esta estructura:

P1 P2 P3 P4
1 0 0 0
1 0 0 0
Rojo Fondo Fondo Fondo

Actividad 1

  • Objetivo: Pintar en amarillo el pixel P1

Para pintar en amarillo los dos bits del pixel 1 deben ser 10:

P1 P2 P3 P4
1 0 0 0
0 0 0 0
Amarillo Fondo Fondo Fondo

Es decir, que hay que escribir el valor (binario) 10000000 en la posición C000. Este valor es 0x80 en hexadecimal

  • Codigo máquina: 3E 80 32 00 C0 18 FE
  • Programa desensamblado:
LD A,#80
LD (#C000),A
JR #4005
  • Resultado:

En esta imagen está ampliado:

Actividad 2

  • Objetivo: Pintar en cyan el pixel P1

Para pintar en cyan los dos bits del pixel 1 deben ser 01:

P1 P2 P3 P4
0 0 0 0
1 0 0 0
Cyan Fondo Fondo Fondo

Es decir, que hay que escribir el valor (binario) 00001000 en la posición C000. Este valor es 0x08 en hexadecimal

  • Codigo máquina: 3E 08 32 00 C0 18 FE
  • Programa desensamblado:
LD A,#08
LD (#C000),A
JR #4005
  • Resultado:

En esta imagen está ampliado:

Actividad 3

  • Objetivo: Pintar en rojo el pixel P1
  • Codificación del byte
P1 P2 P3 P4
1 0 0 0
1 0 0 0
Rojo Fondo Fondo Fondo
  • Valor binario: 10001000
  • Valor hexadecimal: 88
  • Codigo máquina: 3E 88 32 00 C0 18 FE
  • Programa desensamblado:
LD A,#88
LD (#C000),A
JR #4005
  • Resultado:


Actividad 4

  • Objetivo: Pintar el Pixel 1 de color del fondo
  • Codificación del byte
P1 P2 P3 P4
0 0 0 0
0 0 0 0
Rojo Fondo Fondo Fondo
  • Valor binario: 00000000
  • Valor hexadecimal: 00
  • Codigo máquina: 3E 00 32 00 C0 18 FE
  • Programa desensamblado:
LD A,#00
LD (#C000),A
JR #4005
  • Resultado:

Para probarlo primero hay que ejecutar alguno de los programas anteriores, y a continuación este, que borrará el pixel 1

Vídeo 1.P07: Ejemplo: De 2 en 2

Click to see the youtube video

  • Resumen: Introducción de dos nuevas instrucciones en código máquina: 21 y 22, que permite usar el registro HL de 16 bits tanto para almacenar un valor en él como para guardarlo en dos posiciones de memoria
    • Instrucción 21: LD HL, ####
    • Instrucción 22: LD (####),HL

Ejemplo: Guardando 8888 en C000 y C001

Este ejemplo almacena los valores 88 en C000 y 88 en C001 lo que provoca que aparezcan dos píxeles rojos. El resto de píxeles tienen el color de fondo (en cada byte tenemos codificados 4 píxeles)

  • Código máquina: 21 88 88 22 00 C0 18 FE
  • Programa desensamblado:
LD HL,#8888
LD (#C0000),HL
JR #4006
  • Resultado: Aparecen dos píxeles rojos separados por 3 píxeles


Resumen de instrucciones hasta el momento

Instrucción Código máquina Tamaño Descripción
LD A, ## 3E ## 2 bytes Cargar un valor en el registro A
LD (####),A 32 ## ## 3 bytes Almacenar A en la posición de memoria indicada
LD HL, #### 21 ## ## 3 bytes Cargar un valor en el registro HL
LD (####),HL 22 ## ## 3 bytes Almacenar HL en las posiciones #### y #### + 1
JR ## 18 FE 2 bytes Bucle infinito

Vídeo 1.P08: Reto: Dominando el formato

Click to see the youtube video

En este reto hay 5 actividades. Hay que pintar píxeles de varios colores

Actividad 1: 4 pixeles de color rojo

Los 4 primeros píxeles hay que ponerlos todos de color rojo

  • Codificación del byte
P1 P2 P3 P4
1 1 1 1
1 1 1 1
Rojo rojo rojo rojo
  • Valor binario: 11111111
  • Valor hexadecimal: FF
  • Código máquina: 3E FF 32 00 C0 18 FE
  • Programa desensamblado:
LD A, #FF
LD (#C000),A
JR #4005
  • Resultado:


Actividad 2: 24 pixeles en grupos de 4

  • Descripción: Dibujar 24 pixeles en total, en grupos de 4, usando todos los colores. Pero todos los píxeles del grupo deben ser del mismo color
  • Bonus: Usar la instrucción 21

Dado que los 4 píxeles ocupan un byte, tendremos en total 24/4 = 6 bytes. Hay que escribir información en las posiciones de memoria C000 - C005

Los valores a escribir para pintar 4 píxeles del mismo color son:

  • 4 pixeles rojos: 0xFF (Actividad anterior)
  • 4 pixeles cyan: 0x0F
P1 P2 P3 P4
0 0 0 0
1 1 1 1
Cyan Cyan Cyan Cyan
  • 4 pixeles amarillos: 0xF0
P1 P2 P3 P4
1 1 1 1
0 0 0 0
Amarillo Amarillo Amarillo Amarillo
  • Patrón de 24 píxeles: El patrón que voy a utilizar es Cyan-amarillo-Cyan-Rojo-Amarillo-Rojo. Por tanto los valores a escribir en la memoria son los siguientes:
C000 C001 C002 C003 C004 C005
cyan Amarillo Cyan Rojo Amarillo Rojo
0F F0 0F FF F0 FF
  • Código máquina: 21 0F F0 22 00 C0 21 0F FF 22 02 C0 21 F0 FF 22 04 C0 18 FE
  • Programa desensamblado:
LD HL,F00F
LD (C000),HL
LD HL,FF0F
LD (C002),HL
LD HL,FFF0
LD (C004),HL
JR #4012
  • Resultado:

Actividad 3: 12 píxeles en grupos de 2

  • Descripción: Dibujar 12 pixeles en total, en grupos de 2, usando todos los colores. Pero todos los píxeles del grupo deben ser del mismo color
  • Bonus: Usar las instrucciones 3E y 21
  • Patrón de 12 píxeles a mostrar: El mismo de antes, pero con grupos de 2 pixeles: cyan-amarillo-cyan-rojo-amarillo-rojo

Como ahora son 12 píxeles, y hay 4 pixeles en un byte, necesitamos en total 12/4 = 3 bytes. Vamos a ver la codificación necesaria:

C000 C001 C002
P1 P2 P3 P4 P1 P2 P3 P4 P1 P2 P3 P4
Cyan Amarillo cyan rojo amarillo rojo
0 0 1 1 0 0 1 1 1 1 1 1
1 1 0 0 1 1 1 1 0 0 1 1

A partir de esta tabla, sacamos los bytes a guardar en cada una de las posiciones:

C000 C001 C002
3C 3F F3
  • Código máquina: 3E 3C 32 00 C0 3E 3F 32 01 C0 3E F3 32 02 C0 18 FE
  • Programa desensamblado:
LD A,#3C
LD (#C000),A
LD A,#3F
LD (#C001),A
LD A,#F3
LD (#C002),A
JR #400F
  • Resultado:


  • BONUS:

  • Código máquina: 3E 3C 32 00 C0 21 3F F3 22 01 C0 18 FE

  • Programa desensamblado:

ld a,#3C
ld (#C000),A
ld HL, #F33F
ld (#c100),HL
JR #400B

Actividad 4: 8 píxeles, cada uno de un color diferente

  • Descripción: Dibujar 8 pixeles en total usando todos los colores
  • Patrón de 8 píxeles a mostrar: cyan-amarillo-cyan-rojo-amarillo-rojo-cyan-amarilllo

Como ahora son 8 píxeles, y hay 4 pixeles en un byte, necesitamos en total 8/4 = 2 bytes. Vamos a ver la codificación necesaria:

C000 C001
P1 P2 P3 P4 P1 P2 P3 P4
C A C R A R C A
1 0 1 1 0 1 1 0
0 1 0 1 1 1 0 1
Valor: 5B Valor: D6
  • Código máquina: 3E 5B 32 00 C0 3E D6 32 01 C0 18 FE
  • Código desensamblado:
ld a,#5B
ld (#c000),A
ld a,#D6
ld (#c001),A
jr #400a
  • También se puede hacer con el registro HL. Código máquina: 21 5B D6 22 00 C0 18 FE
  • Desensamblado
ld HL,#D65B
ld (#c000),HL
jr #4006
  • Resultado:


Actividad 5: 80 píxeles o más, usando todos los colores

  • Patrón de 80 bits a pintar: RRRRRRRR-AAAAAAAA-CCCCCCCC-RRRR-AAAA-CCCC-RR-AA-CC-F-RR-F-AA-F-CC-F-R-F-A-F-C-FF-R-FF-A-FF-C-FFFR-FFF-A-FFF-C-F-R

En total hay 80 píxeles --> 20 bytes. Desde la dirección C000 hasta C013

C000 C001 C002 C003 C004 C005 C006 C007 C008 C009 Cantidad
RRRR RRRR AAAA AAAA CCCC CCCC RRRR AAAA CCCC RRAA 40 pixeles
FF FF F0 F0 0F 0F FF F0 0F FC 10 bytes
C00A C00B C00C C00D C00E C00F C010 C011 C012 C013 Cantidad
CCFR RFAA FCCF RFAF CFFR FFAF FCFF FRFF FAFF FCFR 40 pixeles
1D B8 CC CD 19 20 04 44 40 15 10 bytes
  • Código máquina: 21 FF FF 22 00 C0 21 F0 F0 22 02 C0 21 0F 0F 22 04 C0 21 FF F0 22 06 C0 21 0F FC 22 08 C0 21 1D B8 22 0A C0 21 06 A8 22 0C C0 21 19 20 22 0E C0 21 04 44 22 10 C0 21 40 15 22 12 C0 18 FE

  • Programa desensamblado:

ld hl,#FFFF
ld (#c000),hl
ld hl,#F0f0
ld (#c002),hl
ld hl,#0f0f
ld (#c004),hl
ld hl,#f0ff
ld (#c006),hl
ld hl,#fc0f
ld (#c008),hl
ld hl,#b81d
ld (#c00a),hl
ld hl,#a806
ld (#c00c),hl
ld hl,#2019
ld (#c00e),hl
ld hl,#4404
ld (#c010),hl
ld hl,#1540
ld (#c012),hl
JR #403C
  • Resultado:


Vídeo 1.P09: Pintando por la pantalla

Click to see the youtube video

  • La memoria de vídeo es de 16K, y va desde las direcciones C000 hasta la FFFF
  • La pantalla tiene un acho de 320 píxeles. Cada línea son 80 bytes (80 * 4 = 320)
  • Por tanto, la primera posición es la C000 y la última de esa línea es C000 + (80 - 1). El valor 80 es 50 en hexadecimal así que los últimos 4 píxeles de la primera línea están en C04F
  • La segunda línea empieza en C050 y llega hasta C09F
  • La siguiente en pieza en C0A0 y llega hasta C0EF

Para ir la posición central hay que escribir en los bytes 39 y 40 (que en hexadecimal son 27 y 28). Para llegar al centro sólo hay que sumar a la posición de memoria del extremo izquierdo de la línea el valor 0x27 y pintar 8 píxeles

Este programa imprime los 4 primeros píxeles y los 4 últimos pixeles de las líneas 1, 2 y 3. Además, pone 8 píxeles en el centro de cada una de ellas

  • Código máquina: 3E FF 32 00 C0 32 4F C0 32 50 C0 32 9F C0 32 A0 C0 32 EF C0 21 FF FF 22 27 C0 22 77 C0 22 C7 C0 18 FE
  • Programa desensamblado:
la A, #ff
ld (#c000),A
ld (#c04F),A
ld (#c050),A
ld (#c09F),A
ld (#c0A0),A
ld (#c0EF),A
ld hl,#ffff
ld (#c027),hl
ld (#c077),hl
ld (#c0c7),hl
jr #4020
  • Resultado:

Vídeo 1.P10: Reto: Pinta por la pantalla

Click to see the youtube video

  • En este reto hay 4 actividades:
  • Actividad 1: Pintar un pixel rojo en una posición concreta de la pantalla, entre dos letras
  • Actividad 2: Pintar tres pixeles de colores diferentes en la misma fila y debajo de 3 letras
  • Actividad 3: Pintar cinco píxeles de distintos colores formando una columna
  • Actividad 4: Pintar tres columnas de 4 píxeles cada una, en distintos bytes

Actividad 1: Pixel rojo entre dos letras

  • Posición a pintar: En la primera línea de la frase "Amstrad Microcomputer", entre las letras M e i

Contando caracteres vemos que está en la segunda file (empieza en C050) y hasta la M hay 10 caracteres. Como cada caracter tiene 8 pixeles, en total hay 80 píxeles --> 80/4 = 20 bytes. La posición es C050 + 0x14 = C064 (0x14 es 20)

En la posición 0xC064 escribimos por ejemplo el valor 0x44

  • Código máquina: 3E 44 32 64 C0 18 FE
  • Programa desensamblado:
ld A,#44
ld (#C064),A
JR #4005
  • Resultado:


Actividad 2: Tres pixeles debajo de caracteres

  • Posición a pintar: Debajo de las letras e, a y d de Ready

Contando caracteres con el cursos, el primero punto está en el carácter (x,y)=(1,11). La cuenta a realizar es C000 + 80*11. Con esto llegamos a la línea debajo de R. Para llegar a la 3 hay 12 píxeles hasta la mitad, pero nos vamos al otro byte, por lo que sumamos 3. La posición final es:

  • Punto rojo debajo de e: Dirección: 0xC000 + 11*80 + 3 = 0xC373

  • Punto amarillo debajo de a: Sumamos 1 byte: 0xC374

  • Punto cyan debajo de d: Sumamos 2 bytes: 0xC376

  • Código máquina: 3E 88 32 73 C3 3E 10 32 74 C3 3E 01 32 76 C3 18 FE

  • Programa desensamblado:

ld A,#88
ld (#C373),A
ld A,#10
ld (#c374),A
ld A,#01
ld (#c376),A
JR #400F
  • Resultado:


Actividad 3: Pintar cinco píxeles en columna

  • Posición de partida: 0xC0FC

Para pasar a la línea de abajo hay que sumar 0x800. Dirección pixel inferior: 0xC0FC + 0x800 = 0xC8FC

Línea 3: 0xC0FC + 2 * 0x800 = 0xC0FC + 0x1000 = D0FC
Linea 4: 0xC0FC + 3 * 0x800 = D8FC Línea 5: 0xC0FC + 4 * 0x800 = E0FC

  • Código máquina: 3E 11 32 FC C0 32 FC C8 3E 10 32 FC D0 32 FC D8 3E 01 32 FC E0 18 FE
  • Programa desensamblado:
ld A,#11
ld (#c0fc),A
ld (#c8fc),A
ld A,#10
ld (#D0fc),A
ld (#D8fc),A
ld A,#01
ld (#E0fc),A
JR #4015
  • Resultado:


Actividad 4: Pintar tres columnas

  • Los patrones de las columnas son estos (en veritcal):

    • Columna 1: CACRA
    • Columna 2: RRARR
    • Columna 3: CCACC
  • Posición: A continuación de BASIC 1.1. Posición en caracteres: (10,8)

  • Posición inicial en memoria: 0xC0000 + 8 * 80 + 10 * 2 + 1 = 0xC295

  • Resto de posiciones:

    • Linea 1: 0xC295
    • Línea 2: 0xC295 + 0x800 = 0xCA95
    • Línea 3: 0xC295 + 0x800*2 = 0xd295
    • Línea 4: 0xC295 + 0x800*3 = 0xDA95
    • Línea 5: 0xC295 + 0x800*4 = 0xE295
Col1 valor Col2 valor Col3 valor
0xC295 08 0xC296 11 0xC298 04
0xCA95 80 0xCA96 11 0xCA98 04
0xD295 08 0xD296 10 0xD298 40
0xDA95 88 0xDA96 11 0xDA98 04
0xE295 80 0xE296 11 0xE298 04
  • Código máquina: 3E 08 32 95 C2 3E 80 32 95 CA 3E 08 32 95 D2 3E 88 32 95 DA 3E 80 32 95 E2 3E 11 32 96 C2 3E 11 32 96 CA 3E 10 32 96 D2 3E 11 32 96 DA 3E 11 32 96 E2 3E 04 32 98 C2 3E 04 32 98 CA 3E 40 32 98 D2 3E 04 32 98 DA 3E 04 32 98 E2 18 FE
  • Programa desensamblado:
ld a,#08
ld (#C295),a
ld a,#80
ld (#CA95),a
ld a,#08
ld (#D295),a
ld a,#88
ld (#DA95),a
ld a,#80
ld (#E295),a

ld a,#11
ld (#C296),a
ld a,#11
ld (#CA96),a
ld a,#10
ld (#D296),a
ld a,#11
ld (#DA96),a
ld a,#11
ld (#E296),a

ld a,#04
ld (#C298),a
ld a,#04
ld (#CA98),a
ld a,#40
ld (#D298),a
ld a,#04
ld (#DA98),a
ld a,#04
ld (#E298),a
  • Resultado:


Vídeo 1.P11: Reto: Domina la memoria de vídeo

Click to see the youtube video

En este reto hay 4 actividades

  • Actividad 1: Filas de colores
  • Actividad 2: Subrayado de Ready con filas de colores
  • Actividad 3: Rectángulo alrededor de la versión de Basic
  • Actividad 4: Dibujar un dado

Actividad 1: Filas de colores

  • Descripcíon: Dibujar en el carácter de la esquina superior izquierda 8 filas de 4 píxeles (4x8), de diferentes colores

  • El patrón de líneas a dibujar es el siguiente: CFRARFCA

  • Valores a almacenar en las diferentes direcciones

Linea Dir Color Valor
1 C000 Cyan 0F
2 C800 Fondo 00
3 D000 Rojo FF
4 D800 Amar F0
5 E000 Rojo FF
6 E800 Fondo 00
7 F000 Cyan 0F
8 F800 Amar F0
  • Código máquina: 3E 0F 32 00 C0 3E 00 32 00 C8 3E FF 32 00 D0 3E F0 32 00 D8 3E FF 32 00 E0 3E 00 32 00 E8 3E 0F 32 00 F0 3E F0 32 00 F8 18 FE

  • Programa desensamblado:

ld a,#0F
ld (#C000),a
ld a,#00
ld (#C800),a
ld a,#FF
ld (#D000),a
ld a,#F0
ld (#D800),a
ld a,#FF
ld (#E000),a
ld a,#00
ld (#E800),a
ld a,#0F
ld (#F000),a
ld a,#F0
ld (#F800),a
  • Resultado:


Actividad 2: Subrayado de Ready con filas de colores

  • Descripcíon: Dibujar 8 filas de 40 pixeles (40x8) debajo de la palabra "Ready", en diferentes colores

  • El patrón de líneas a dibujar es el siguiente: CFRARFCA (Mismo que en la actividad anterior)

  • Posición inicial: El carácter está en la posición 11, por tanto la memoria inicial es: 0xC0000 + 11 * 80 = 0xC370

Esta es la tabla con los primeros 4 pixeles de las 8 líneas.

Linea Dir Color Valor
1 C370 Cyan 0F
2 CB70 Fondo 00
3 D370 Rojo FF
4 DB70 Amar F0
5 E370 Rojo FF
6 EB70 Fondo 00
7 F370 Cyan 0F
8 FB70 Amar F0

En total son 40 pixeles --> 40/4 = 10 Bytes. Desde la dirección base hasta base + 9. Haciendo escrituras de 16 bits, necesitamos 5 operaciones (instrucciones 21 y 22) por línea en las direcciones base + 0, +2, +4, +6, +8

  • Código máquina: 21 0F 0F 22 70 C3 22 72 C3 22 74 C3 22 76 C3 22 78 C3 21 00 00 22 70 CB 22 72 CB 22 74 CB 22 76 CB 22 78 CB 21 FF FF 22 70 D3 22 72 D3 22 74 D3 22 76 D3 22 78 D3 21 F0 F0 22 70 DB 22 72 DB 22 74 DB 22 76 DB 22 78 DB 21 FF FF 22 70 E3 22 72 E3 22 74 E3 22 76 E3 22 78 E3 21 00 00 22 70 EB 22 72 EB 22 74 EB 22 76 EB 22 78 EB 21 0F 0F 22 70 F3 22 72 F3 22 74 F3 22 76 F3 22 78 F3 21 F0 F0 22 70 FB 22 72 FB 22 74 FB 22 76 FB 22 78 FB 18 FE

  • Programa desensamblado:

ld HL,#0F0F
ld (#C370),HL
ld (#C372),HL
ld (#C374),HL
ld (#C376),HL
ld (#C378),HL

ld HL,#0000
ld (#CB70),HL
ld (#CB72),HL
ld (#CB74),HL
ld (#CB76),HL
ld (#CB78),HL

ld HL,#FFFF
ld (#D370),HL
ld (#D372),HL
ld (#D374),HL
ld (#D376),HL
ld (#D378),HL

ld HL,#F0F0
ld (#DB70),HL
ld (#DB72),HL
ld (#DB74),HL
ld (#DB76),HL
ld (#DB78),HL

ld HL,#FFFF
ld (#E370),HL
ld (#E372),HL
ld (#E374),HL
ld (#E376),HL
ld (#E378),HL

ld HL,#0000
ld (#EB70),HL
ld (#EB72),HL
ld (#EB74),HL
ld (#EB76),HL
ld (#EB78),HL

ld HL,#0F0F
ld (#F370),HL
ld (#F372),HL
ld (#F374),HL
ld (#F376),HL
ld (#F378),HL

ld HL,#F0F0
ld (#FB70),HL
ld (#FB72),HL
ld (#FB74),HL
ld (#FB76),HL
ld (#FB78),HL
  • Resultado:


Actividad 3: Rectángulo alrededor de la versión de Basic

  • Descripción: Rectángulo en 2 colores de 2 píxeles de ancho sin modificar el texto 1.1

  • Bonus: Programa más corto

  • Línea horizontal superior: La dirección base la calculamos así: 0xC000 + 80 * 7 + 7*2 = 0xC23E. Es la dirección de la primera fila del caracter encima del primer 1. Sobre esta dirección base hay que obtener la dirección de la líena 7 del carácter: 0xC23E + 0x800 * 7 = 0xFA3e. Y la anterior es: 0xF23E

La línea debe tener una longitud de 3 caracteres: 3*8 = 24 píxeles. Es decir, 6 bytes. Para que el programa sea lo más corto posible (Bonus) utilizamos las instrucciones 21 y 22

El código máquina para dibujar las dos líneas superiores es: 21 FF FF 22 3E FA 22 40 FA 22 42 FA 22 3E F2 22 40 F2 22 42 F2 18 FE

  • Línea horizontal inferior: Dirección base: 0xC000 + 80 * 9 + 7*2 (Dos caracteres más abajo) = 0xC2DE. La siguiente línea es: 0xC2DE + 0x800 = 0xCADE

Código máquina: 22 DE C2 22 E0 C2 22 E2 C2 22 DE CA 22 E0 CA 22 E2 CA

  • Línea vertical izquierda: Dirección base: 0xC000 + 80 * 8 + 6*2 + 1 = 0xC28D Líneas inferiores en direcciones 0xCA8D, 0xD28D, 0xDA8D, 0xE28D, 0xEA8D, 0xF28D, 0xFA8D

  • Esquina superior izquierda: En el byte encima de la línea izquierda hay que escribir 2 líneas de 2 pixeles. Las direcciones son: 0xC000 + 80 * 7 + 62 + 1 + 0x8006 = 0xF23D y 0xFA3D (0xF23D + 0x800)

  • Esquina inferior izquierda: La dirección base es la de la línea vertical izquierda más 0x800: 0xC28D + 80 = 0xC2DD. La otra es 0xC2DD + 0x800 = 0xCADD

El código máquina es el siguiente. Primero Metemos los dos bytes de la esquina superior izquierda:

3E 03 32 3D F2 32 3D FA

Ahora añadimos la línea vertical:

32 8D C2 32 8D CA 32 8D D2 32 8D DA 32 8D E2 32 8D EA 32 8D F2 32 8D FA

Y la esquina inferior izquierda:

32 DD C2 32 DD CA

  • Código máquina línea vertical izquierda: 3E 03 32 3D F2 32 3D FA 32 8D C2 32 8D CA 32 8D D2 32 8D DA 32 8D E2 32 8D EA 32 8D F2 32 8D FA 32 DD C2 32 DD CA 18 FE
Línea vertical derecha
  • La esquina superior derecha tiene la dirección base de la esquina superior izquierda + 4 caracteres (7 bytes). Por tanto las direcciones son: 0xF23D y 0xFA3D a las que les sumamos 8 bytes: 0xFA44 y 0xF244

3E 0C 32 44 FA 32 44 F2

  • La línea vertical derecha tiene como dirección base la misma que la izquierda + 7 bytes: 0xC28D + 7 = 0xC294. Las siguientes son esta más los 0x800: CA94, D294, DA94, E294, EA94, F294, FA94

32 94 C2 32 94 CA 32 94 D2 32 94 DA 32 94 E2 32 94 EA 32 94 F2 32 94 FA

  • La esquina inferior derecha tiene las direcciones base: 0xC2DD y 0xCADD a las que se le suman 7 bytes: C2E4 y CAE4

32 E4 C2 32 E4 CA

  • Código máquina para dibujar la línea vertical derecha: 3E 0C 32 44 FA 32 44 F2 32 94 C2 32 94 CA 32 94 D2 32 94 DA 32 94 E2 32 94 EA 32 94 F2 32 94 FA 32 E4 C2 32 E4 CA
Solución final
  • Código máquina final: 3E 03 32 3D F2 32 3D FA 32 8D C2 32 8D CA 32 8D D2 32 8D DA 32 8D E2 32 8D EA 32 8D F2 32 8D FA 32 DD C2 32 DD CA 3E 0C 32 44 FA 32 44 F2 32 94 C2 32 94 CA 32 94 D2 32 94 DA 32 94 E2 32 94 EA 32 94 F2 32 94 FA 32 E4 C2 32 E4 CA 21 FF FF 22 3E FA 22 40 FA 22 42 FA 22 3E F2 22 40 F2 22 42 F2 22 DE C2 22 E0 C2 22 E2 C2 22 DE CA 22 E0 CA 22 E2 CA 18 FE

  • Programa desensamblado:

LD A,#03
LD (#F23D),A
LD (#FA3D),A
LD (#C28D),A
LD (#CA8D),A
LD (#D28D),A
LD (#DA8D),A
LD (#E28D),A
LD (#EA8D),A
LD (#F28D),A
LD (#FA8D),A
LD (#C2DD),A
LD (#CADD),A

LD A,#0C
LD (#FA44),A
LD (#F244),A
LD (#C294),A
LD (#CA94),A
LD (#D294),A
LD (#DA94),A
LD (#E294),A
LD (#EA94),A
LD (#F294),A
LD (#FA94),A
LD (#C2E4),A
LD (#CAE4),A

LD HL,#FFFF
LD (#FA3E),HL
LD (#FA40),HL
LD (#FA42),HL
LD (#F23E),HL
LD (#F240),HL
LD (#F242),HL

LD (#C2DE),HL
LD (#C2E0),HL
LD (#C2E2),HL
LD (#CADE),HL
LD (#CAE0),HL
LD (#CAE2),HL
JR #4073
  • Resultado:


Actividad 4: Dibujar un dado

  • Descripción: Dibujar un dado de 8x7 (8 pixeles de ancho y 7 de alto) en el centro de la pantalla. El número del dado puede ser cualquiera. Yo eligo el 5
  • Bonus: Programa más corto

La pantalla del amstrad tiene 40x25 caracteres. Cada caracter son de 8x8. Por tanto, la pantalla (en este modo) tiene 320 x 200 píxeles

En coordenadas de carácter, el centro está en las posiciones x = 19, x=20, y=13. Utilizamores por tanto estas dos posiciones de caracter para pintar el pixel: (19,13) y (20,13)

La dirección base del byte superior izquierdo está dado por: `Base = 0xC000 + (y-1)*80 + (x-1)*2' + 1 = 0xC3E5

El script en python es este:

x,y = 19,13
base = 0xC000 + (y-1)*80 + (x-1)*2 + 1
print(hex(base))

Tabla con las direcciones a rellenar

Linea Dir Valor
1 C3E5 F0F0
2 CBE5 F6F6
3 D3E5 F0F0
4 DBE5 F1F8
5 E3E5 F0F0
6 EBE5 F6F6
7 F3E5 F0F0

Las direcciones se pueden calcular con este script en python:

[hex(base + 0x800*i) for i in range(7)]

El código máquina se calcula fácilmente así. Cada línea deposita un valor en su dirección correspondiente:

21 F0 F0 22 E5 C3
21 F6 F6 22 E5 CB
21 F0 F0 22 E5 D3
21 F1 F8 22 E5 DB
21 F0 F0 22 E5 E3 
21 F6 F6 22 E5 EB 
21 F0 F0 22 E5 F3
  • Código máquina: 21 F0 F0 22 E5 C3 21 F6 F6 22 E5 CB 21 F0 F0 22 E5 D3 21 F1 F8 22 E5 DB 21 F0 F0 22 E5 E3 21 F6 F6 22 E5 EB 21 F0 F0 22 E5 F3 18 FE

  • Programa desensamblado:

LD HL,#F0F0
LD (#C3E5),HL
LD HL,#F6F6
LD (#CBE5),HL
LD HL,#F0F0
LD (#D3E5),HL
LD HL,#F8F1
LD (#DBE5),HL
LD HL,#F0F0
LD (#E3E5),HL
LD HL,#F6F6
LD (#EBE5),HL
LD HL,#F0F0
LD (#F3E5),HL
JR #402A
  • Resultado:


Vídeo 1.P12: Desafío: Pinta un sprite

Click to see the youtube video

  • Desafío: Pintar un sprite de 16x16 en el centro de la pantalla usando todos los colores

  • Dirección base: Base = 0xC000 + (y-1)*80 + (x-1)*2' = 0xC3E4

Como el sprinte es de 16x16 píxeles, tendremos por cada línea 16/4 = 4 bytes. Hay que hacer 2 escriburas de 16 bits para cada fila. En total hay 16 filas. El script para calcular las direcciones es este:

[hex(base + 0x800*i) for i in range(8)] 
Linea Dir Valor1 Dir Valor 2
1 C3E4 00 00 C3E6 00 00
2 CBE4 00 00 CBE6 00 00
3 D3E4 00 00 D3E6 07 00
4 DBE4 00 00 DBE6 0F 00
5 E3E4 00 01 E3E6 0F 00
6 EBE4 00 03 EBE6 0B 00
7 F3E4 00 07 F3E6 03 00
8 FBE4 00 02 FBE6 03 00

La dirección base de la parte inferior es C3E4 + 80 = C434. Aplicando el script anterior obtenemos las direcciones: c434, cc34, d434, dc34, e434, ec34, f434, fc34

Linea Dir Valor1 Dir Valor 2
9 C434 60 00 C436 03 00
10 CC34 10 80 CC36 03 00
11 D434 00 00 D436 03 00
12 DC34 70 80 DC36 33 00
13 E434 00 00 E436 44 88
14 EC34 10 80 EC36 44 44
15 F434 60 10 F436 88 44
16 FC34 00 10 FC36 00 60
  • Código máquina: 21 00 00 22 E4 C3 22 E6 C3 22 E4 CB 22 E6 CB 22 E4 D3 21 07 00 22 E6 D3 21 00 00 22 E4 DB 21 0F 00 22 E6 DB 21 00 01 22 E4 E3 21 0F 00 22 E6 E3 21 00 03 22 E4 EB 21 0B 00 22 E6 EB 21 00 07 22 E4 F3 21 03 00 22 E6 F3 21 00 02 22 E4 FB 21 03 00 22 E6 FB 21 60 00 22 34 C4 21 03 00 22 36 C4 21 10 80 22 34 CC 21 03 00 22 36 CC 21 00 00 22 34 D4 21 03 00 22 36 D4 21 70 80 22 34 DC 21 33 00 22 36 DC 21 00 00 22 34 E4 21 44 88 22 36 E4 21 10 80 22 34 EC 21 44 44 22 36 EC 21 60 10 22 34 F4 21 88 44 22 36 F4 21 00 10 22 34 FC 21 00 60 22 36 FC 18 FE

  • Programa desensamblado:

LD HL,#0000
LD (#C3E4),HL
LD (#C3E6),HL
LD (#CBE4),HL
LD (#CBE6),HL
LD (#D3E4),HL
LD HL,#0007
LD (#D3E6),HL

LD HL,#0000
LD (#DBE4),HL
LD HL,#000F
LD (#DBE6),HL

LD HL,#0100
LD (#E3E4),HL
LD HL,#000F
LD (#E3E6),HL
LD HL,#0300
LD (#EBE4),HL
LD HL,#000B
LD (#EBE6),HL
LD HL,#0700
LD (#F3E4),HL
LD HL,#0003
LD (#F3E6),HL
LD HL,#0200
LD (#FBE4),HL
LD HL,#0003
LD (#FBE6),HL

LD HL,#0060
LD (#C434),HL
LD HL,#0003
LD (#C436),HL
LD HL,#8010
LD (#CC34),HL
LD HL,#0003
LD (#CC36),HL
LD HL,#0000
LD (#D434),HL
LD HL,#0003
LD (#D436),HL
LD HL,#8070
LD (#DC34),HL
LD HL,#0033
LD (#DC36),HL
LD HL,#0000
LD (#E434),HL
LD HL,#8844
LD (#E436),HL
LD HL,#8010
LD (#EC34),HL
LD HL,#4444
LD (#EC36),HL
LD HL,#1060
LD (#F434),HL
LD HL,#4488
LD (#F436),HL
LD HL,#1000
LD (#FC34),HL
LD HL,#6000
LD (#FC36),HL
JR #40B4
  • Resultado:


El Sprite creado es un bit a 1 corriendo, inspirado en la constante bit 1 utilizada en los bloques de la colección iceK de Icestudio

¡¡NIVEL COMPLETADO!! 😀️

Clone this wiki locally