💾 Archived View for elpamplina.duckdns.org › programacion › descargas › juego-vida.asm captured on 2024-05-26 at 14:55:10.

View Raw

More Information

➡️ Next capture (2024-06-16)

-=-=-=-=-=-=-

; JUEGO DE LA VIDA PARA MSX por El Pamplina de Cai
; 2024, @ElPamplina@masto.es
;
; Licencia GPLv3
; https://www.gnu.org/licenses/gpl-3.0.html
;
; Escrito para el ensamblador RSC II 
; NOTA: Se ha incluido una operacion NOP en cada etiqueta para
; evitar un bug del ensamblador que las calcula incrementadas en 1.
ORG &HA500
; Llamadas del sistema (https://map.grauw.nl/resources/msxbios.php)
CHGMOD: EQU &H5F ; Cambiar modo de pantalla
ERAFNK: EQU &HCC ; Quitar teclas de funcion
LDIRVM: EQU &H5C ; Copiar bloque a VRAM
CHGET: EQU &H9F ; Esperar una tecla
POSIT: EQU &HC6 ; Posicionar cursor
CHPUT: EQU &HA2 ; Escribir caracter
; Reiniciar pantalla (SCREEN 0)
LD A,0
CALL CHGMOD
CALL ERAFNK
; Escribir estado
LD L,1 ; Linea 1
LD H,26 ; Columna 26
CALL POSIT
LD HL,TIT1
CALL IMPETI
LD L,2 ; Linea 2
LD H,26 ; Columna 26
CALL POSIT
LD HL,TIT2
CALL IMPETI
LD L,3 ; Linea 3
LD H,26 ; Columna 26
CALL POSIT
LD HL,TIT3
CALL IMPETI
LD L,5 ; Linea 5
LD H,26 ; Columna 26
CALL POSIT
LD HL,ETI1
CALL IMPETI
LD L,7 ; Linea 7
LD H,26 ; Columna 26
CALL POSIT
LD HL,ETI2
CALL IMPETI
LD L,8 ; Linea 8
LD H,26 ; Columna 26
CALL POSIT
LD HL,ETI3
CALL IMPETI
LD HL,0 ; Generacion cero
LD (NUMGEN), HL
LD HL,GEN0 ; Posicion generacion cero
PUSH HL
VUELTA: NOP  
LD L,5 ; Linea 5
LD H,31 ; Columna 31
CALL POSIT
LD HL,(NUMGEN) ; Imprimir numero generacion
CALL IMPNUM
LD HL,(NUMGEN)
INC HL
LD (NUMGEN),HL ; Generacion +1
; Volcar generacion a pantalla
POP HL ; Posicion generacion actual
PUSH HL
CALL PINTAR
PUSH DE
POP BC
POP DE
; SIGGEN espera recibir DE=actual HL=siguiente
; OJO en esta version las generaciones no rotan nunca.
CALL SIGGEN; Siguiente generacion
PUSH DE     ; Guardamos la posicion de la nueva generacion actual
CALL CHGET
CP 27 ; ESC
JR NZ,VUELTA
; Final
POP DE
RET 
; Rutina de pintado del tablero
PINTAR: NOP ; viene HL apuntando a la casilla Dimension
LD A,(HL)
LD C,A ; Guarda dimension en BC
LD B,0
; Saltamos los espacios del borde sumando Dimension+4
; para llegar a la primera celda
ADD HL,BC
LD DE,4
ADD HL,DE
LD DE,0  ; Origen de la pantalla en VRAM
PUSH HL
PUSH BC
PUSH DE
PUSH AF
LINEA: NOP 
CALL LDIRVM
; Sumar 40 a DE para saltar a la siguiente linea de pantalla
POP AF
POP HL ; Intermediario para el valor de DE
LD BC,40
ADD HL,BC
LD D,H
LD E,L
POP BC
POP HL
; Sumar dimension+2 para siguiente linea del tablero
ADD HL,BC
INC HL
INC HL
PUSH HL
PUSH BC
PUSH DE
; Decrementar A y bucle si !=0
DEC A
PUSH AF
CP 0
JR NZ,LINEA
POP AF
POP DE
POP BC
POP HL
; Sumamos a HL dimension+1 para saltar el borde inferior del tablero
; y apuntar directamente a la casilla dimension de la siguiente generacion
ADD HL,BC
INC HL
RET 
; Rutina imprimir etiqueta en HL
IMPETI: NOP
LD A,(HL)
CP 255 ; Buscar fin de cadena
RET Z
INC HL
CALL CHPUT
JR IMPETI
; Rutina imprimir numero decimal,
; https://wikiti.brandonw.net/index.php?title=Z80_Routines:Other:DispHL
IMPNUM: NOP
LD BC,-10000
CALL NUM1
LD BC,-1000
CALL NUM1
LD BC,-100
CALL NUM1
LD C,-10
CALL NUM1
LD C,-1
NUM1: NOP
LD A,"0"-1
NUM2: NOP
INC A
ADD HL,BC
JR C,NUM2
SBC HL,BC
CALL CHPUT
RET 
SIGGEN: NOP ; Calculo de la siguiente generacion
; HL=Posicion siguiente generacion
; C=Dimension
; DE=Posicion actual generacion
LD (HL),C ; Copio dimension
; Los siguientes dimension+3 bytes del borde van con guiones
LD A,3
ADD A,C
LD B,A
LD A,"-"
BUCLE1: NOP
INC DE ; Menos eficiente que sumar de golpe, pero mas facil
INC HL
LD (HL),A
DJNZ BUCLE1
INC C   ; C se queda con dimension+1 por conveniencia
; El bucle "duro" empieza ahora, donde hay que optimizar mas
BUCLE2: NOP
INC DE ; Apunta ahora a la celda actual
INC HL ; Apunta a la celda futura
; Si estamos en un guion, lo saltamos
LD A,(DE)
CP "-"
JR Z,BUCLE2
; Si estamos en un $, es el final
CP "$"
JR Z,FINAL
; Contar cuantos vecinos tiene DE
; Fila superior: restamos dimension+3
PUSH HL
LD H,D
LD L,E
DEC HL
DEC HL
OR A  ; Limpiar carry para la resta
SBC HL,BC
; Comprobar las tres celdas de la fila superior cuantas de ellas
; tienen activado el bit 1
LD A,0
LD B,3
BUCLE3: NOP
BIT 1,(HL)
JR Z,1   ; Salto la orden INC A
INC A
INC HL
DJNZ BUCLE3
; Vecinos de la misma fila. 
; Sumo dimension+1 (C) para el vecino derecho
ADD HL,BC
BIT 1,(HL)
JR Z,1
INC A
; Vecino izquierdo
DEC HL
DEC HL
BIT 1,(HL)
JR Z,1
INC A
; Fila siguiente (sumo dimension+2)
ADD HL,BC
INC HL
LD B,3
BUCLE4: NOP
BIT 1,(HL)
JR Z,1
INC A
INC HL
DJNZ BUCLE4
POP HL
; Ya tenemos el conteo en A y la futura celda en HL. 
; Aplicamos las tres reglas de Conway.
; 1) Si tiene exactamente 3 vecinos vivos, la celda estara viva
CP 3
JR NZ,SALTO1
LD (HL),"*"
JR SALIDA
SALTO1: NOP
; 2) Si tiene 2 vecinos vivos y su estado actual es viva, seguira viva
CP 2
JR NZ,SALTO2
LD A,(DE)
BIT 1,A
JR Z,SALTO2
LD (HL),A
JR SALIDA
SALTO2: NOP
; 3) En cualquier otro caso, esta muerta
LD (HL)," "
SALIDA: NOP
JR BUCLE2
FINAL: NOP
; Copiar la fila de borde inferior
LD B,C
INC B
INC B   ; B=dimension+3
SALTO3: NOP
LD A,(DE)
LD (HL),A
INC HL
INC DE
DJNZ SALTO3
; DE=nueva actual generacion
; HL=nueva siguiente generacion
RET 
TIT1: NOP
DEFM "JUEGO DE"
DEFB 255 ; Fin de cadena
TIT2: NOP
DEFM "LA VIDA"
DEFB 255
TIT3: NOP
DEFM "por ElPamplina"
DEFB 255
ETI1: NOP
DEFM "Gen: "
DEFB 255
ETI2: NOP
DEFM "ESP: Seguir"
DEFB 255
ETI3: NOP
DEFM "ESC: Salir"
DEFB 255
; Variable
NUMGEN: NOP
DEFW 0
; Datos a rellenar
GEN0: NOP
DEFB 24 ; El primer byte indica la dimension
; Ponemos guiones al borde y un $ al final
; para facilitar el calculo de adyacentes.
; (El codigo ASCII del asterisco tiene activado el bit 1, 
; pero espacio, guion y dolar no lo tienen)
DEFM "--------------------------"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************-"
DEFM "-************************$"
DEFM "--------------------------"