💾 Archived View for elpamplina.duckdns.org › programacion › descargas › juego-vida.asm captured on 2024-05-26 at 14:55:10.
-=-=-=-=-=-=-
; 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 "--------------------------"