LOG - Obijuan/Learn-zx-spectrum-asm GitHub Wiki
LOG
Experimentos y log de aprendizaje del ensamblador del Z80 para el ZX-Spectrum
2023-07-12
En el ejemplo 01-test1.asm
estoy desarrollando mi propia rutina para mover una bala hacia la derecha píxel a pixel. Ya tengo una que funciona bien, aunque he detectado un bug. La bala se mueve con un pequeño salto (me falta algún fotograma). Me he dado cuenta que necesito crear rutinas para depurar los programas, así como Macros y definiciones para hacer más fáciles los programas en asm
Voy a empezar creando una interfaz gráfica para visualizar información. Empiezo creando un LED, para visualizar los bits...
En este ejemplo se dibujan dos LEDs, uno encendido y otro apagado: 02-debug1-dark.asm
include "zxspectrum.h"
org $8000
;-- Entrar en el Dark Mode
BORDER BLACK
CLS BLACK, GREEN
;-- Led apagado
ld a, $00
ld ($4000),a
ld a, $3C
ld ($4100),a
ld a, $42
ld ($4200),a
ld a, $42
ld ($4300),a
ld a, $42
ld ($4400),a
ld a, $42
ld ($4500),a
ld a, $3C
ld ($4600),a
ld a, $00
ld ($4700),a
;-- Led encendido
ld a, $00
ld ($4001),a
ld a, $3C
ld ($4101),a
ld a, $7E
ld ($4201),a
ld a, $7E
ld ($4301),a
ld a, $7A
ld ($4401),a
ld a, $76
ld ($4501),a
ld a, $3C
ld ($4601),a
ld a, $00
ld ($4701),a
inf: jr inf
include "Video.asm"
end $8000
En el fichero zxspectrum.h
estoy metiendo las macros y definiciones:
;-- Colores del ZX Spectrum
;-- Para tinta, papel y borde
BLACK: EQU 0
BLUE: EQU 1
RED: EQU 2
MAGENTA: EQU 3
GREEN: EQU 4
CYAN: EQU 5
YELLOW: EQU 6
WHITE: EQU 7
;-- Puerto de salida para establecer el color del borde
BORDER_PORT: EQU $FE
;-------------------------------------------
;-- BORDER: Establecer el color del borde
;-------------------------------------------
MACRO BORDER ,color
ld a, color
out (BORDER_PORT), a
ENDM
;------------------------------------------------------------------------
;-- CLS(paper, ink): Borrar la pantalla con los attributos indicados
;------------------------------------------------------------------------
MACRO CLS ,paper,ink
ld a, paper << 3 | ink
call cls
ENDM
Este es el resultado:
2023-07-13
Para depurar con facilidad voy a usar el teclado. Estoy leyendo la información del teclado de la wiki de speccy, que está muy bien:
https://wiki.speccy.org/cursos/ensamblador/teclado
Ahí hay una rutina para leer cualquier tecla. Hay que poner a 0 el byte alto de las direcciones para activar todas las semifilas
Las rutinas del teclado las estoy poniendo en Keyboard.asm
:
;----------------------------------------------------------------------------
;-- RUTINAS DE TECLADO
;----------------------------------------------------------------------------
;-----------------------------------------------------------------------
; Wait_key_pressed: Esperar hasta que se pulse una tecla cualquiera
;-----------------------------------------------------------------------
Wait_Key_Pressed:
xor a ; A = 0
in a, (KEY_PORT) ;-- Leer teclado
or $E0 ;-- 1110 0000 ;-- Activar resto de bits
inc a ;-- Si no pulsado, inc a --> A=0
jr z, Wait_Key_Pressed ;-- No hay tecla pulsada. Esperar...
;-- Fin: No se devuelve la tecla pulsada...
ret
;-----------------------------------------------------------------------
; Esta rutina espera a que no haya ninguna tecla pulsada para volver,
; consultando las diferentes filas del teclado en un bucle.
;-----------------------------------------------------------------------
Wait_Key_Released:
XOR A
IN A, ($FE)
OR 224
INC A
JR NZ, Wait_Key_Released
RET
;----------------------------------------------------------------------
;-- Esperar a que una tecla se pulse y luego se libere
;----------------------------------------------------------------------
Wait_Key:
call Wait_Key_Pressed
call Wait_Key_Released
ret
En este ejemplo: 03-debug-key-pressed.asm
se imprime el carácter 'A' y se espera a que se pulse una tecla. Luego se imprime 'B' y al apretar otra tecla se imprime 'C'
include "zxspectrum.h"
;------------------------------------
;--- VARIABLES DEL SISTEMA
;------------------------------------
;-- Atributos permanentes del sistema. Es lo que se usa cuando se llama
;-- a CLS
;-- Formato: Flash, Bright, paper (3-bits), ink (3-bits)
ATTR_S: EQU $5C8D
;-------------------------------------------------
;-- Rutina de CLS en ROM
;-- Altera el valor de los registros AF, BC, DE Y HL
;----------------------------------------------------
ROM_CLS: EQU $0DAF
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, GREEN
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
;-- Imprimir un caracter
ld a, 'A'
rst $10
;-- Esperar a que se pulse una tecla cualquiera
call Wait_Key
;-- Imprimir otro caracter
ld a, 'B'
rst $10
;-- Esperar a que se pulse otra tecla
call Wait_Key
;-- Imprimir otro caracter
ld a, 'C'
rst $10
;-- Terminar
inf: jr inf
include "Video.asm"
include "Keyboard.asm"
end $8000
En esta animación se muestra se muestra el funcionamiento:
Tras apretar dos teclas aparece "ABC" en la pantalla:
Led parpadeante
En este ejemplo 04-led-blink-key.asm
se cambia de estado el LED con cada pulsación de una tecla
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, GREEN
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
loop:
;-- Apagar led
call led_off
;-- Esperar a que se pulse una tecla
call Wait_Key
;-- Encender led
call led_on
;-- Esperar a que se pulse una tecla
call Wait_Key
jr loop
led_off:
;-- Led apagado
ld a, $00
ld ($4000),a
ld a, $3C
ld ($4100),a
ld a, $42
ld ($4200),a
ld a, $42
ld ($4300),a
ld a, $42
ld ($4400),a
ld a, $42
ld ($4500),a
ld a, $3C
ld ($4600),a
ld a, $00
ld ($4700),a
ret
led_on:
;-- Led encendido
ld a, $00
ld ($4000),a
ld a, $3C
ld ($4100),a
ld a, $7E
ld ($4200),a
ld a, $7E
ld ($4300),a
ld a, $7A
ld ($4400),a
ld a, $76
ld ($4500),a
ld a, $3C
ld ($4600),a
ld a, $00
ld ($4700),a
ret
;-- Terminar
inf: jr inf
include "Video.asm"
include "Keyboard.asm"
end $8000
En esta animación se muestra el funcionamiento
Esta es la versión del led parpadeante, que parpadea con periodo de 1 segundo: 05-led-blink.asm
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, GREEN
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
loop:
;-- Dibujar led apagado
ld hl, $4000
ld de, sprite_led_off
call draw_sprite8
;-- Esperar
call wait_500ms
;-- Dibujar led encendido
ld hl, $4000
ld de, sprite_led_on
call draw_sprite8
;-- Esperar
call wait_500ms
jr loop
;-------------------
;-- SPRITES
;-------------------
;-- Led apagado
sprite_led_off: DEFB $00, $3C, $42, $42, $42, $42, $3C, $00
;-- Led encendido
sprite_led_on: DEFB $00, $3C, $7E, $7E, $7A, $76, $3C, $00
include "Video.asm"
include "Keyboard.asm"
include "Delay.asm"
end $8000
Esta es la rutina draw_sprite8 para dibujar un sprite de 8 líneas (y bytes)
;-----------------------------------------------------------------------------
;-- draw_sprite: Dibujar un sprite (de 8 lineas) en la pantalla (de 8 lineas)
;--
;-- ENTRADAS:
;-- * HL: Direccion de la memoria de video
;-- * DE: Direccion del sprite a pintar
;-----------------------------------------------------------------------------
draw_sprite8:
ld b, 8 ;-- El sprite tiene 8 lineas
sprite_loop:
ld a, (de) ;-- Leer byte del sprite
ld (hl), a ;-- Mostrar byte en pantalla
inc h ;-- Siguiente linea
inc de ;-- Siguiente byte
djnz sprite_loop
ret
Esta es la animación:
LED: 3 sprites
- Ejemplo:
06-led-3-sprites.z80
He creado un sprite intermedio entre apagado y encendido... no es demasiado bueno, pero hay que probarlo
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, GREEN
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
;-- Mostrar los 3 sprites
ld hl, $4000
ld de, sprite_led_off
call draw_sprite8
ld hl, $4001
ld de, sprite_led_half
call draw_sprite8
ld hl, $4002
ld de, sprite_led_on
call draw_sprite8
inf:
jr inf
;-------------------
;-- SPRITES
;-------------------
;-- Led apagado
sprite_led_off: DEFB $00, $3C, $42, $42, $42, $42, $3C, $00
;-- Led medio-encendido
sprite_led_half: DEFB $00, $3C, $56, $4A, $52, $66, $3C, $00
;-- Led encendido
sprite_led_on: DEFB $00, $3C, $7E, $7E, $7A, $76, $3C, $00
include "Video.z80"
include "Keyboard.z80"
include "Delay.z80"
end $8000
Este es el resultado:
Nuevo LED parpadeante
Se hace parpear el led usando los 3 sprites
- Ejemplo:
07-led-3-sprites-blink.z80
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, GREEN
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
loop:
;-- Dibujar led apagado
ld hl, $4000
ld de, sprite_led_off
call draw_sprite8
;-- Esperar
call wait_500ms
;-- Sprite2
ld hl, $4000
ld de, sprite_led_half
call draw_sprite8
;-- Esperar
call wait_60ms
;-- Dibujar led encendido
ld hl, $4000
ld de, sprite_led_on
call draw_sprite8
;-- Esperar
call wait_500ms
;-- Sprite2
ld hl, $4000
ld de, sprite_led_half
call draw_sprite8
;-- Esperar
call wait_60ms
jr loop
;-------------------
;-- SPRITES
;-------------------
;-- Led apagado
sprite_led_off: DEFB $00, $3C, $42, $42, $42, $42, $3C, $00
;-- Led medio-encendido
sprite_led_half: DEFB $00, $3C, $56, $4A, $52, $66, $3C, $00
;-- Led encendido
sprite_led_on: DEFB $00, $3C, $7E, $7E, $7A, $76, $3C, $00
include "Video.z80"
include "Keyboard.z80"
include "Delay.z80"
end $8000
Este es el resultado:
2023-07-14
Sprites: Manic Miner!
Voy a hacer los sprites del Manic Miner! Este fue uno de los primeros juegos de Spectrum que tuve, y me pareció increible!
- Ejemplo:
08-Manic-miner.z80
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, WHITE
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
loop:
ld hl, $4000
ld de, sprite_Manic_miner0
call draw_sprite18
ld hl, $4002
ld de, sprite_Manic_miner1
call draw_sprite18
ld hl, $4004
ld de, sprite_Manic_miner2
call draw_sprite18
ld hl, $4005
ld de, sprite_Manic_miner2_2
call draw_sprite18
;-- Esperar
call wait_500ms
jr loop
;-------------------
;-- SPRITES
;-------------------
;-- Manic Miner 0
sprite_Manic_miner0:
DEFB $00, $06, $3E, $7C, $34, $3E, $3C, $18
DEFB $3C, $6E, $6E, $6E, $76, $3C, $18, $18
DEFB $1C, $00
;-- Manic Miner 1
sprite_Manic_miner1:
DEFB $00, $06, $3E, $7C, $34, $3E, $3C, $18
DEFB $3C, $7E, $7E, $57, $FB, $3C, $36, $6E
DEFB $77, $00
;-- Manic Miner 2-1
sprite_Manic_miner2:
DEFB $00, $06, $3E, $7C, $34, $3E, $3C, $18
DEFB $3C, $3F, $7F, $FF, $DE, $1F, $3B, $61
DEFB $71, $00
;-- Manic Miner 2-2
sprite_Manic_miner2_2:
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $00, $80, $C0, $C0, $00, $40, $C0
DEFB $80, $00
include "Video.z80"
include "Keyboard.z80"
include "Delay.z80"
end $8000
Este es el resultado:
Animación Manic Miner!
En este ejemplo se animan los sprites, dejándolos en las posición inicial (esquina superior izquierda)
- Ejemplo:
09-Manic-miner.z80
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, WHITE
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
loop:
;-- Fotograma 1
ld hl, $4000
ld de, sprite_Manic_miner0
call draw_sprite18
ld hl, $4001
call blank_sprite18
;-- Esperar
call wait_500ms
;-- Fotograma 2
ld hl, $4000
ld de, sprite_Manic_miner1
call draw_sprite18
ld hl, $4001
call blank_sprite18
;-- Esperar
call wait_500ms
;-- Fotograma 3
ld hl, $4000
ld de, sprite_Manic_miner2
call draw_sprite18
ld hl, $4001
ld de, sprite_Manic_miner2_2
call draw_sprite18
;-- Esperar
call wait_500ms
;-- Fotograma 4
ld hl, $4000
ld de, sprite_Manic_miner1
call draw_sprite18
ld hl, $4001
call blank_sprite18
;-- Esperar
call wait_500ms
jr loop
;-------------------
;-- SPRITES
;-------------------
;-- Manic Miner 0
sprite_Manic_miner0:
DEFB $00, $06, $3E, $7C, $34, $3E, $3C, $18
DEFB $3C, $6E, $6E, $6E, $76, $3C, $18, $18
DEFB $1C, $00
;-- Manic Miner 1
sprite_Manic_miner1:
DEFB $00, $06, $3E, $7C, $34, $3E, $3C, $18
DEFB $3C, $7E, $7E, $57, $FB, $3C, $36, $6E
DEFB $77, $00
;-- Manic Miner 2-1
sprite_Manic_miner2:
DEFB $00, $06, $3E, $7C, $34, $3E, $3C, $18
DEFB $3C, $3F, $7F, $FF, $DE, $1F, $3B, $61
DEFB $71, $00
;-- Manic Miner 2-2
sprite_Manic_miner2_2:
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $00, $80, $C0, $C0, $00, $40, $C0
DEFB $80, $00
include "Video.z80"
include "Keyboard.z80"
include "Delay.z80"
end $8000
Más Sprites del Manic Miner!
Voy a hacer más sprites del Manic miner: el muro de ladrillos y el suelo de la cueva. Los hago en Inkscape:
Este es el programa que los implementa: 10-Manic-miner-sprites.z80
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER BLACK
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, WHITE
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
;-- Pintar la parte estática
ld hl, $4000
ld de, sprite_ladrillos
call draw_sprite8
ld hl, $4020
ld de, sprite_ladrillos
call draw_sprite8
ld hl, $4040
ld de, sprite_ladrillos
call draw_sprite8
;-- Atributos de los ladrillos
ld hl, $5800
ld a, YELLOW << PAPER | RED
ld (hl), a
ld ($5820), a
ld ($5840), a
;-- Suelo
ld hl, $4041
ld de, sprite_suelo
call draw_sprite8
ld hl, $4042
ld de, sprite_suelo
call draw_sprite8
ld hl, $4043
ld de, sprite_suelo
call draw_sprite8
;-- Atributo del suelo
ld a, RED
LD ($5841), a
LD ($5842), a
ld ($5843), a
loop:
;-- Fotograma 1
ld hl, $4002
ld de, sprite_Manic_miner0
call draw_sprite16
ld hl, $4003
call blank_sprite16
;-- Esperar
call wait_500ms
;-- Fotograma 2
ld hl, $4002
ld de, sprite_Manic_miner1
call draw_sprite16
ld hl, $4003
call blank_sprite16
;-- Esperar
call wait_500ms
;-- Fotograma 3
ld hl, $4002
ld de, sprite_Manic_miner2
call draw_sprite16
ld hl, $4003
ld de, sprite_Manic_miner2_2
call draw_sprite16
;-- Esperar
call wait_500ms
;-- Fotograma 4
ld hl, $4002
ld de, sprite_Manic_miner1
call draw_sprite16
ld hl, $4003
call blank_sprite16
;-- Esperar
call wait_500ms
jr loop
;-------------------
;-- SPRITES
;-------------------
;-- Manic Miner 0
sprite_Manic_miner0:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $6E, $6E, $6E, $76, $3C, $18, $18, $1C
;-- Manic Miner 1
sprite_Manic_miner1:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $7E, $7E, $57, $FB, $3C, $36, $6E, $77
;-- Manic Miner 2-1
sprite_Manic_miner2:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $3F, $7F, $FF, $DE, $1F, $3B, $61, $71
;-- Manic Miner 2-2
sprite_Manic_miner2_2:
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $80, $C0, $C0, $00, $40, $C0, $80
;--- Ladrillos
sprite_ladrillos:
DEFB $DD, $00, $77, $00, $DD, $00, $77, $00
;--- Suelo
sprite_suelo:
DEFB $FF, $FF, $DD, $6E, $C5, $40, $00, $00
include "Video.z80"
include "Keyboard.z80"
include "Delay.z80"
end $8000
Este es el resultado:
2023-07-15
Sigo creando Sprites... Ahora toca la llave y las estalacticas que están en la parte superior de la cueva
2023-07-16
- 11-Manic-miner-sprites.z80
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER RED
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, WHITE
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
;-- Pintar la parte estática
ld hl, $4000
ld de, sprite_ladrillos
call draw_sprite8
ld hl, $4020
ld de, sprite_ladrillos
call draw_sprite8
ld hl, $4040
ld de, sprite_ladrillos
call draw_sprite8
;-- Atributos de los ladrillos
ld hl, $5800
ld a, YELLOW << PAPER | RED
ld (hl), a
ld ($5820), a
ld ($5840), a
;-- Suelo
ld hl, $4041
ld de, sprite_suelo
call draw_sprite8
ld hl, $4042
ld de, sprite_suelo
call draw_sprite8
ld hl, $4043
ld de, sprite_suelo
call draw_sprite8
;-- Atributo del suelo
ld a, BRIGHT | RED
LD ($5841), a
LD ($5842), a
ld ($5843), a
;-- Estalactita
ld hl, $4010
ld de, sprite_stalactica
call draw_sprite8
ld a, CYAN
ld ($5810), a
;-- Llave
ld hl, $4012
ld de, sprite_llave
call draw_sprite8
ld a, GREEN
ld ($5812),a
;-- Fotograma 1
ld hl, $4002
ld de, sprite_Manic_miner0
call draw_sprite16
;-- Fotograma 2
ld hl, $4004
ld de, sprite_Manic_miner1
call draw_sprite16
;-- Fotograma 3
ld hl, $4006
ld de, sprite_Manic_miner2
call draw_sprite16
ld hl, $4007
ld de, sprite_Manic_miner2_2
call draw_sprite16
;-- Fotograma 4
ld hl, $4008
ld de, sprite_Manic_miner1
call draw_sprite16
inf: jr inf
;-------------------
;-- SPRITES
;-------------------
;-- Manic Miner 0
sprite_Manic_miner0:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $6E, $6E, $6E, $76, $3C, $18, $18, $1C
;-- Manic Miner 1
sprite_Manic_miner1:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $7E, $7E, $F7, $FB, $3C, $36, $6E, $77
;-- Manic Miner 2-1
sprite_Manic_miner2:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $3F, $7F, $FF, $DE, $1F, $3B, $61, $71
;-- Manic Miner 2-2
sprite_Manic_miner2_2:
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $80, $C0, $C0, $00, $40, $C0, $80
;--- Ladrillos
sprite_ladrillos:
DEFB $DD, $00, $77, $00, $DD, $00, $77, $00
;--- Suelo
sprite_suelo:
DEFB $FF, $FF, $DD, $6E, $C5, $40, $00, $00
;--- Estalactita
sprite_stalactica:
DEFB $FF, $FE, $7E, $7C, $4C, $4C, $08, $08
;--- Llave
sprite_llave:
DEFB $30, $48, $88, $90, $68, $04, $0A, $04
include "Video.z80"
include "Keyboard.z80"
include "Delay.z80"
end $8000
2023-07-18
- Fichero:
12-Manic-miner-sprites.z80
Reconstrucción inicial del nivel 1 del Manic Miner: barreras laterales, suelo, estalacticas y llaves. Falta el suelo movedizo, la cinta transportadora, los arbustos venenosos y todas las letras
include "zxspectrum.h"
org $8000
;------------- Pasar a Dark Mode ------------
BORDER RED
;-- Establecer los atributos permanentes
SET_ATTR_S BLACK, WHITE
;-- Borrar la pantalla
CALL ROM_CLS
;--------------------------------------------
call draw_left_border
call draw_right_border
call draw_suelo1
;-- Dibujar suelo
ld b,5
ld c,1
ld a, 13
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,5
ld c,1
ld a,13
ld d, BRIGHT | RED
call lineah_attr
;-- Dibujar suelo
ld b,7
ld c,1
ld a, 3
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,7
ld c,1
ld a,3
ld d, BRIGHT | RED
call lineah_attr
;-- Dibujar suelo
ld b,9
ld c,1
ld a, 4
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,9
ld c,1
ld a,4
ld d, BRIGHT | RED
call lineah_attr
;-- Dibujar suelo
ld b,13
ld c,5
ld a, 19
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,13
ld c,5
ld a,19
ld d, BRIGHT | RED
call lineah_attr
;-- Dibujar suelo
ld b,12
ld c,28
ld a, 30
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,12
ld c,28
ld a,30
ld d, BRIGHT | RED
call lineah_attr
;-- Dibujar suelo
ld b,10
ld c,29
ld a, 30
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,10
ld c,29
ld a,30
ld d, BRIGHT | RED
call lineah_attr
;-- Dibujar suelo
ld b,5
ld c,23
ld a,30
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,5
ld c,23
ld a,30
ld d, BRIGHT | RED
call lineah_attr
;-- Dibujar suelo
ld b,5
ld c,18
ld a,18
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,5
ld c,18
ld a,18
ld d, BRIGHT | RED
call lineah_attr
;-- Estalactita 2
ld b,0
ld c,16
call DF_LOC
ld de, sprite_stalactica
call draw_sprite8
ld b,0
ld c,16
call ATTLOC
ld a, CYAN
ld (hl), a
;-- Estalactita 1
ld b,0
ld c,11
call DF_LOC
ld de, sprite_stalactica
call draw_sprite8
ld b,0
ld c,11
call ATTLOC
ld a, CYAN
ld (hl), a
;-- Llave 1
ld b,0
ld c,9
call DF_LOC
ld de, sprite_llave
call draw_sprite8
ld b,0
ld c,9
call ATTLOC
ld a, CYAN
ld (hl),a
;-- Llave 2
ld b,1
ld c,16
call DF_LOC
ld de, sprite_llave
call draw_sprite8
ld b,1
ld c,16
call ATTLOC
ld a, MAGENTA
ld (hl),a
;-- Llave 3
ld b,0
ld c,29
call DF_LOC
ld de, sprite_llave
call draw_sprite8
ld b,0
ld c,29
call ATTLOC
ld a, YELLOW
ld (hl),a
;-- Llave 4
ld b,4
ld c,24
call DF_LOC
ld de, sprite_llave
call draw_sprite8
ld b,4
ld c,24
call ATTLOC
ld a, GREEN
ld (hl),a
;-- Llave 5
ld b,6
ld c,30
call DF_LOC
ld de, sprite_llave
call draw_sprite8
ld b,6
ld c,30
call ATTLOC
ld a, CYAN
ld (hl),a
;-- Fotograma 1
ld hl, $48A2 ;1010 0010
ld de, sprite_Manic_miner1
call draw_sprite16
inf: jr inf
;-------------------
;-- SPRITES
;-------------------
;-- Manic Miner 0
sprite_Manic_miner0:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $6E, $6E, $6E, $76, $3C, $18, $18, $1C
;-- Manic Miner 1
sprite_Manic_miner1:
DEFB $06, $3E, $7C, $34, $3E, $3C, $18, $3C
DEFB $7E, $7E, $F7, $FB, $3C, $36, $6E, $77
;-- Manic Miner 2-1
sprite_Manic_miner2:
DEFB $03, $1F, $3E, $1A, $1F, $1E, $0C, $1E
DEFB $3F, $7F, $FF, $DE, $1F, $3B, $61, $71
;-- Manic Miner 2-2
sprite_Manic_miner2_2:
DEFB $00, $00, $00, $00, $00, $00, $00, $00
DEFB $00, $80, $C0, $C0, $00, $40, $C0, $80
;--- Ladrillos
sprite_ladrillos:
DEFB $DD, $00, $77, $00, $DD, $00, $77, $00
;--- Suelo
sprite_suelo:
DEFB $FF, $FF, $DD, $6E, $C5, $40, $00, $00
;--- Estalactita
sprite_stalactica:
DEFB $FF, $FE, $7E, $7C, $4C, $4C, $08, $08
;--- Llave
sprite_llave:
DEFB $30, $48, $88, $90, $68, $04, $0A, $04
;----------------------------------------------------------------------------
;-- draw_left_border: Dibujar el muro izquierdo de la pantalla 1
;----------------------------------------------------------------------------
draw_left_border:
;-- Posicion final en A
ld a, 15
;--- Asignar atributos a una linea vertical
ld b, 0 ;-- Linea
ld c, 0 ;-- Columna
ld d, YELLOW << PAPER | RED
call lineav_attr
;-- Meter en A la posicion final
ld a, 15
;-- Pintar muro de ladrillos izquierdo
ld b, 0 ;--- Linea 0
ld c, 0 ;--- Col 0
ld de, sprite_ladrillos
call lineav_sprite
ret
;----------------------------------------------------------------------------
;-- draw_right_border: Dibujar el muro derecho de la pantalla 1
;----------------------------------------------------------------------------
draw_right_border:
;-- Posicion final en A
ld a, 15
;--- Asignar atributos a una linea vertical
ld b, 0 ;-- Linea
ld c, 31 ;-- Columna
ld d, YELLOW << PAPER | RED
call lineav_attr
;-- Meter en A la posicion final
ld a, 15
;-- Pintar muro de ladrillos izquierdo
ld b, 0 ;--- Linea 0
ld c, 31 ;--- Col 0
ld de, sprite_ladrillos
call lineav_sprite
ret
;----------------------------------------------------------------------------
;-- lineav_attr: Establecer una linea vertical de atributos
;--
;-- ENTRADAS:
;-- * B: linea inicial (0-23)
;-- * C: Columna (0-31)
;-- * A: Linea final (0-23)
;-- * D: Atributos a escribir
;----------------------------------------------------------------------------
lineav_attr:
linev_attr_loop:
;-- Preservar linea final
push af
;-- Preservar posicion inicial
push bc
;-- HL: Direccion de la memoria de atributos de la posicion actual
call ATTLOC
;-- Recuperar posicion actual
pop bc
;-- Guardar el atributo
ld a, d
ld (hl), a
;-- Recuperar la linea final
pop af
;-- Incrementar la fila actual
inc b
;- Linea actual > linea final?
cp b
jr nc, linev_attr_loop ;-- Linea actual < linea final: Repetir
jr z, linev_attr_loop ;-- Linea actual = linea final: Repetir (ultima vez)
;-- Se ha sobrepasado la linea final. Terminar
ret
;----------------------------------------------------------------------------
;-- lineah_attr: Establecer una linea horizontal de atributos
;--
;-- ENTRADAS:
;-- * B: linea inicial (0-23)
;-- * C: Columna (0-31)
;-- * A: Columna final (0-23)
;-- * D: Atributos a escribir
;----------------------------------------------------------------------------
lineah_attr:
lineh_attr_loop:
;-- Preservar linea final
push af
;-- Preservar posicion inicial
push bc
;-- HL: Direccion de la memoria de atributos de la posicion actual
call ATTLOC
;-- Recuperar posicion actual
pop bc
;-- Guardar el atributo
ld a, d
ld (hl), a
;-- Recuperar la linea final
pop af
;-- Incrementar la columna actual
inc c
;- Col actual > Col final?
cp c
jr nc, lineh_attr_loop ;-- Col actual < col final: Repetir
jr z, lineh_attr_loop ;-- Col actual = col final: Repetir (ultima vez)
;-- Se ha sobrepasado la linea final. Terminar
ret
;----------------------------------------------------------------------------
;-- lineav_sprite: Establecer una linea vertical de sprites
;--
;-- ENTRADAS:
;-- * B: linea inicial (0-23)
;-- * C: Columna (0-31)
;-- * A: Linea final (0-23)
;-- * DE: Direccion del sprite
;----------------------------------------------------------------------------
lineav_sprite:
linev_sprite_loop:
push af
push bc
push de
call DF_LOC
call draw_sprite8
pop de
pop bc
pop af
inc b
cp b
jr nc, linev_sprite_loop
jr z, linev_sprite_loop
ret
;----------------------------------------------------------------------------
;-- lineah_sprite: Establecer una linea horizontal de sprites
;--
;-- ENTRADAS:
;-- * B: linea inicial (0-23)
;-- * C: Columna (0-31)
;-- * A: Columna final (0-23)
;-- * DE: Direccion del sprite
;----------------------------------------------------------------------------
lineah_sprite:
lineh_sprite_loop:
push af
push bc
push de
call DF_LOC
call draw_sprite8
pop de
pop bc
pop af
inc c
cp c
jr nc, lineh_sprite_loop
jr z, lineh_sprite_loop
ret
draw_suelo1:
;-- Dibujar suelo
ld b,15
ld c,1
ld a, 30
ld de, sprite_suelo
call lineah_sprite
;-- Atributos suelo
ld b,15
ld c,1
ld a,30
ld d, BRIGHT | RED
call lineah_attr
ret
include "Video.z80"
include "Keyboard.z80"
include "Delay.z80"
end $8000
Este es el resultado: