Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @;= =
- @;=== candy1_init.s: rutinas para inicializar la matriz de juego ===
- @;= =
- @;=== Programador tarea 1A: ernest.tomas@estudiants.urv.cat ===
- @;=== Programador tarea 1B: yyy.yyy@estudiants.urv.cat ===
- @;= =
- .include "../include/candy1_incl.i"
- @;-- .bss. variables (globales) no inicializadas ---
- .bss
- .align 2
- @; matrices de recombinación: matrices de soporte para generar una nueva matriz
- @; de juego recombinando los elementos de la matriz original.
- mat_recomb1: .space ROWS*COLUMNS
- mat_recomb2: .space ROWS*COLUMNS
- @;-- .text. código de las rutinas ---
- .text
- .align 2
- .arm
- @;TAREA 1A;
- @; inicializa_matriz(*matriz, num_mapa): rutina para inicializar la matriz de
- @; juego, primero cargando el mapa de configuración indicado por parámetro (a
- @; obtener de la variable global 'mapas'), y después cargando las posiciones
- @; libres (valor 0) o las posiciones de gelatina (valores 8 o 16) con valores
- @; aleatorios entre 1 y 6 (+8 o +16, para gelatinas)
- @; Restricciones:
- @; * para obtener elementos de forma aleatoria se invocará la rutina
- @; 'mod_random'
- @; * para evitar generar secuencias se invocará la rutina
- @; 'cuenta_repeticiones' (ver fichero "candy1_move.s")
- @; Parámetros:
- @; R0 = dirección base de la matriz de juego
- @; R1 = número de mapa de configuración
- .global inicializa_matriz
- inicializa_matriz:
- push {r0-r10, lr} @;guardar registros utilizados
- mov r10, r0 @;r10 = direccion matriz juego
- mov r3, #0
- .Lfor1:
- cmp r3, #ROWS @;comparem les files
- beq .Lfibucle2 @;si igual fi bucle
- mov r4, #0 @;r4 = 0
- .Lfor2:
- ldr r2, =mapas @;direccio de memoria de mapas
- cmp r4, #COLUMNS @;comparem columnes
- beq .Lfibucle1 @;si igual salta fi bucle
- mov r5, #COLUMNS @;r5 = columnas
- mul r5, r5, r3 @;r5 = columnas * fila
- add r5, r5, r4 @;r5 = (columnas * fila) + col
- add r0, r0, r5 @;r0 = matriu_joc indexada[f][c]
- mov r7, #ROWS @;r7 = filas
- mov r8, #COLUMNS @;r8 = columnas
- mul r6, r7, r8 @;r6= (filas * columnas)
- mul r6, r6, r1 @;r6 = (filas * columnas) * num. mapa
- add r5, r6, r5 @;r5 = r6 + r5
- add r2, r2, r5 @;Posicio memoria element (f,c) en matriu configuracio
- ldrb r6, [r2] @;obtenim el valor que conte matriu[f][c]
- cmp r6, #0 @;comparem r6 = 0
- bne .Lnext1 @;si no igual, salta
- b .Lrepeticions @;si es 0, saltem a .Lrepeticions
- .Lnext1:
- cmp r6, #8 @;r6 = 8 ?
- bne .Lnext2 @;si no igual saltem
- b .Lrepeticions @;si igual anem a .Lrepeticions
- .Lnext2:
- cmp r6, #16 @;r6 = 16 ?
- bne .Lnext3 @;si no igual saltem i guardem el valor tal cual
- b .Lrepeticions @;si igual anem a .Lrepeticions
- .Lrepeticions:
- push {r0}
- mov r0, #6 @;r0 = 6
- bl mod_random
- mov r9, r0 @;r9 = direccio memoria de matriu_joc
- add r9, r9, #1 @;sumem 1 al valor aleatori 1...6
- pop {r0}
- add r9, r9, r6 @;r9=valor_aleatori + r6(0 8 o 16)
- strb r9, [r0] @;matriu_joc[f][c] = valor aleatori
- push {r0-r4}
- mov r0, r10 @;r0 = r10 (direccio memoria matriu joc)
- mov r1,
- mov r2,
- mov r3
- bl cuenta_repeticiones
- mov r9, r0
- pop {r0-r4}
- cmp r9, #1 @;si hi ha repeticions, tornem a generar
- bne .Lrepeticions
- .Lnext3: @;al arribar aqui hem vist que no es ni 0, ni 8 ni 16
- strb r6, [r0] @;per tant guardem el valor tal cual
- add r4, r4, #1 @;incrementen en 1 la columna
- b. Lfor2 @;saltem al inici de bucle
- .Lfibucle1:
- add r3, r3, #1 @;incrementem en 1 la fila
- b. Lfor1
- .Lfibucle2:
- pop {r0-r10, pc} @;recuperar registros y volver
- @;TAREA 1B;
- @; recombina_elementos(*matriz): rutina para generar una nueva matriz de juego
- @; mediante la reubicación de los elementos de la matriz original, para crear
- @; nuevas jugadas.
- @; Inicialmente se copiará la matriz original en 'mat_recomb1', para luego ir
- @; escogiendo elementos de forma aleatoria y colocandolos en 'mat_recomb2',
- @; conservando las marcas de gelatina.
- @; Restricciones:
- @; * para obtener elementos de forma aleatoria se invocará la rutina
- @; 'mod_random'
- @; * para evitar generar secuencias se invocará la rutina
- @; 'cuenta_repeticiones' (ver fichero "candy1_move.s")
- @; * para determinar si existen combinaciones en la nueva matriz, se
- @; invocará la rutina 'hay_combinacion' (ver fichero "candy1_comb.s")
- @; * se supondrá que siempre existirá una recombinación sin secuencias y
- @; con combinaciones
- @; Parámetros:
- @; R0 = dirección base de la matriz de juego
- .global recombina_elementos
- recombina_elementos:
- push {r0-r12, lr}
- ldr r1, =mat_recomb1 @; R0: MAT_RECOMB1 Direccio memoria
- ldr r2, =mat_recomb2 @; r1: MAT_RECOMB2 direccio memoria
- mov r3, #0
- .Lfor0:
- cmp r3, #ROWS @;r3 = ROWS ?
- beq .Lendfor0 @;Si r3 = rows saltem
- mov r4, #0
- .Lfor1:
- mov r12, #0 @;r12 = 0 -> vol dir que no ha fet mat_recomb2[i][j]
- cmp r4, #COLUMNS @;r4 = columns?
- beq .Lendfor1 @;si r4 = columns saltem
- mov r5, #COLUMNS @;r5 = columns
- mul r6, r5, r3 @;r6 = columna * r3
- add r6, r6, r4 @;r6 = (columna * r3) + r4
- add r9, r6, r2 @;r9 = r6 + r2 -> r2 = direccio memoria mat_recomb2
- add r7, r6, r1 @;r7 = r6 + r1 -> direccio posicio memoria mat_recomb1
- add r8, r6, r0 @;r8 = r6 + r0 es la direccio de matriu joc
- ldrb r10, [r8] @;r10 = valor de matriu_joc[i][j]
- strb r10, [r7] @;Guardem a mat_recomb1 = matriu_joc[i][j]
- cmp r10, #7 @;Comparem r10 = 7?
- bne .Lnext0 @;Si no igual salta
- push {r10}
- mov r10, #0 @;r10 = 0
- strb r10, [r7] @;Guardem mat_recomb1[i][j] = 0
- pop {r10} @;recuperm valor r10
- b .Lnext1
- .Lnext0:
- cmp r10, #15 @;comparem r10, 15
- bne .Lnnext1
- push {r10} @;recuperem valor r10
- mov r10, #0 @; r10 = 0
- strb r10, [r7] @; Guardem un 0
- pop {r10}
- .Lnnext1:
- cmp r10, #9 @;comparem r10, amb 9
- blo .Lnnext2
- cmp r10, #14
- bhi .Lnnext2 @;matriu[i][j] >=9 && matriu[i][j] <= 14
- push {r10}
- mov r11, #8
- strb r11, [r9] @;Guardem a mat_recomb2[i][j] = 8;
- mov r12, #1
- sub r10, r10, r11
- strb r10, [r7]
- pop {r10}
- .Lnnext2:
- cmp r10, #17 @;comparem r10, amb 9
- blo .Lnnext3
- cmp r10, #22
- bhi .Lnnext3
- push {r10} @; matriuJoc >= 17 && matriuJoc <= 22
- mov r11, #16
- strb r11, [r9] @; Guardem un 16 a mat_recomb2[i][j] = 16
- mov r12, #1
- sub r10, r10, r11
- strb r10, [r7]
- pop {r10}
- .Lnnext3:
- cmp r10, #0
- bne .Lnext4
- mov r11, #0
- strb r11, [r9] @;Guardem mat_recomb2[i][j] = 0
- b .Lnext7
- .Lnext4:
- cmp r10, #7
- bne .Lnext5
- strb r10, [r9] @;Guardem a mat_recomb2[i][j] = matriu_joc[i][j]
- b .Lnext7
- .Lnext5:
- cmp r10, #15 @;Guardem a mat_recomb2[i][j] = matriu_joc[i][j]
- bne .Lnext6
- strb r10, [r9]
- b .Lnext7
- .Lnext6:
- mov r11, #24
- and r11, r10, r11 @;Obtenim el valor de gelatina de matriu_joc[i][j]
- strb r11, [r9]
- .Lnext7:
- cmp r12, #1
- beq .Lendfor1
- mov r11, #24 @;r11 = 24
- and r11, r10, r11
- strb r11, [r9] @;Guardem el codi de gelatina a mat_recomb2[i][j]
- mov r11, #1
- add r4, r4, r11 @; Columna + 1
- b .Lfor1
- .Lendfor1:
- mov r11, #1
- add r3, r3, r11 @; Fila + 1
- b .Lfor0
- .Lendfor0: @;Fi de primer bucle
- mov r3, #0
- .Lffor0:
- cmp r3, #ROWS @;r3 = ROWS ?
- beq .Lendffor0 @;Si r3 = rows saltem
- mov r4, #0
- .Lffor1:
- mov r12, #0 @;r12 = 0 -> vol dir que no ha fet mat_recomb2[i][j]
- cmp r4, #COLUMNS @;r4 = columns?
- beq .Lendffor1 @;si r4 = columns saltem
- mov r5, #COLUMNS @;r5 = columns
- mul r6, r5, r3 @;r6 = columna * r3
- add r6, r6, r4 @;r6 = (columna * r3) + r4
- add r9, r6, r2 @;r9 = r6 + r2 -> r2 = direccio memoria mat_recomb2
- add r7, r6, r1 @;r7 = r6 + r1 -> direccio posicio memoria mat_recomb1
- add r8, r6, r0 @;r8 = r6 + r0 es la direccio de matriu joc
- ldrb r5, [r9] @;r5= valor de mat_recomb2[i][j]
- ldrb r10, [r8] @;r10=valor de matriu_joc[i][j]
- and r10, r10, #7 @;Si els 3 bits de matriu joc son 000, passem següent posicio
- cmp r10, #0
- beq .Lendffor1
- cmp r5, #0 @;r5 = 0?
- bne .Lprox1
- b .Lbucle
- .Lprox1:
- cmp r5, #8 @;r5 = 8?
- bne .Lprox2
- b .Lbucle
- .Lprox2:
- cmp r5, #16 @;r5 = 16?
- bne .Lendfffor1 @;ERROR ERROR AQUI ERRORRRRRRRRRRRRRRRRRRR
- .Lbucle:
- push {r0}
- mov r0, #ROWS @;r0 = fila
- bl mod_random @;cridem mod_random RANG (0...r0-1)
- mov r11, r0 @;r11 = valor aleatori que estava en r0 de la FILA
- mov r0, #COLUMNS @;r0 = col
- bl mod_random @;r0 = valor aleatori de (0...r0-1)
- mov r12, r0 @;r12 = valor aleatori COLUMNA
- pop {r0}
- mov r5, #COLUMNS @;r5 = columans
- mul r5, r11, r5 @;r5 = desplaçament
- add r5, r5, r12 @;r5 = mat_recomb1[fila_aleatoria][col_random]
- add r5, r5, r1 @;r5 = mat_recomb1[fila_aleatoria][col_random]
- mov r7, r5 @;r7 = direccio memoria de mat_recomb1[fila_aleatoria][col_random]
- ldrb r6, [r5] @;r6= valor de mat_recomb1[fila_random][col_random]
- cmp r6, #0 @;r6 es zero?
- bne .Lprox3
- b .Lbucle
- .Lprox3:
- ldrb r5, [r9] @;r5 = mat_recomb2[i][j]
- add r5, r5, r6 @;r5 = mat_recomb2[i][j] + mat_recomb1[fila_random][col_random]
- ldrb r11, [r9]
- strb r5, [r9]
- push {r0-r4}
- mov r0, r2
- mov r1, r3
- mov r2, r4
- mov r3, #3
- bl cuenta_repeticiones @;Mirem orientacio NORTE mat_recomb2
- cmp r0, #1
- pop {r0-r4}
- bhi .Lrep
- push {r0-r4}
- mov r0, r2
- mov r1, r3
- mov r2, r4
- mov r3, #3
- bl cuenta_repeticiones @;Mirem orientacio NORTE mat_recomb2
- cmp r0, #1
- pop {r0-r4}
- bhi .Lrep
- mov r11, #0 @;Arribat aqui no hi ha repeticio
- strb r11, [r7] @; Fiquem un 0 a mat_recomb1[fila_aleatoria][col_random]
- b .Lcontinuar
- .Lrep:
- strb r11, [r9] @; Restituim la matriu
- b .Lbucle
- .Lcontinuar:
- add r4, r4, #1
- b .Lffor1
- .Lendffor1:
- add r3, r3, #1
- b .Lffor0
- .Lendffor0:
- mov r3, #0
- .Lfffor0:
- cmp r3, #ROWS @;r3 = ROWS ?
- beq .Lendfffor0 @;Si r3 = rows saltem
- mov r4, #0
- .Lfffor1:
- cmp r4, #COLUMNS @;r4 = columns?
- beq .Lendfffor1 @;si r4 = columns saltem
- mov r5, #COLUMNS @;r5 = columns
- mul r6, r5, r3 @;r6 = columna * r3
- add r6, r6, r4 @;r6 = (columna * r3) + r4
- add r9, r6, r2 @;r9 = r6 + r2 -> r2 = direccio memoria mat_recomb2
- add r8, r6, r0 @;r8 = r6 + r0 es la direccio de matriu joc
- ldrb r7, [r9] @;r7 = valor de mat_recomb2[i][j]
- strb r7, [r8] @;guardem r7 a mat_joc[i][j]
- add r4, r4, #1
- b .Lfffor1
- .Lendfffor1:
- add r3, r3, #1
- b .Lfffor0
- .Lendfffor0:
- pop {r0 - r12, pc}
- @;:::RUTINAS DE SOPORTE:::
- @; mod_random(n): rutina para obtener un número aleatorio entre 0 y n-1,
- @; utilizando la rutina 'random'
- @; Restricciones:
- @; * el parámetro 'n' tiene que ser un valor entre 2 y 255, de otro modo,
- @; la rutina lo ajustará automáticamente a estos valores mínimo y máximo
- @; Parámetros:
- @; R0 = el rango del número aleatorio (n)
- @; Resultado:
- @; R0 = el número aleatorio dentro del rango especificado (0..n-1)
- .global mod_random
- mod_random:
- push {r1-r4, lr}
- cmp r0, #2 @;compara el rango de entrada con el mínimo
- bge .Lmodran_cont
- mov r0, #2 @;si menor, fija el rango mínimo
- .Lmodran_cont:
- and r0, #0xff @;filtra los 8 bits de menos peso
- sub r2, r0, #1 @;R2 = R0-1 (número más alto permitido)
- mov r3, #1 @;R3 = máscara de bits
- .Lmodran_forbits:
- cmp r3, r2 @;genera una máscara superior al rango requerido
- bhs .Lmodran_loop
- mov r3, r3, lsl #1
- orr r3, #1 @;inyecta otro bit
- b .Lmodran_forbits
- .Lmodran_loop:
- bl random @;R0 = número aleatorio de 32 bits
- and r4, r0, r3 @;filtra los bits de menos peso según máscara
- cmp r4, r2 @;si resultado superior al permitido,
- bhi .Lmodran_loop @; repite el proceso
- mov r0, r4 @; R0 devuelve número aleatorio restringido a rango
- pop {r1-r4, pc}
- @; random(): rutina para obtener un número aleatorio de 32 bits, a partir de
- @; otro valor aleatorio almacenado en la variable global 'seed32' (declarada
- @; externamente)
- @; Restricciones:
- @; * el valor anterior de 'seed32' no puede ser 0
- @; Resultado:
- @; R0 = el nuevo valor aleatorio (también se almacena en 'seed32')
- random:
- push {r1-r5, lr}
- ldr r0, =seed32 @;R0 = dirección de la variable 'seed32'
- ldr r1, [r0] @;R1 = valor actual de 'seed32'
- ldr r2, =0x0019660D
- ldr r3, =0x3C6EF35F
- umull r4, r5, r1, r2
- add r4, r3 @;R5:R4 = nuevo valor aleatorio (64 bits)
- str r4, [r0] @;guarda los 32 bits bajos en 'seed32'
- mov r0, r5 @;devuelve los 32 bits altos como resultado
- pop {r1-r5, pc}
- .end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement