Created
August 28, 2015 17:52
-
-
Save rofirrim/3c8d0a2f21e2175aef51 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.model large | |
.386 | |
; Constants per comoditat | |
CERT equ 0FFh | |
FALS equ 00h | |
; Convencio de valors del sentit | |
DRETA equ 0 | |
ESQUERRA equ 1 | |
AMUNT equ 2 | |
AVALL equ 3 | |
; Codis de rastreig de les tecles | |
TEC_AMUNT equ 72 | |
TEC_AVALL equ 80 | |
TEC_ESQUERRA equ 75 | |
TEC_DRETA equ 77 | |
; Colors de la paleta original del mode 13h | |
BCOL_VERD equ 02h | |
BCOL_CYAN equ 0Bh | |
BCOL_BLAU equ 01h | |
BCOL_BLANC equ 0Fh | |
BCOL_NEGRE equ 00h | |
; Versions duplicades a word dels colors | |
WCOL_BLANC equ (BCOL_BLANC * 100h) OR (BCOL_BLANC) | |
WCOL_NEGRE equ (BCOL_NEGRE * 100h) OR (BCOL_NEGRE) | |
WCOL_BLAU equ (BCOL_BLAU * 100h) OR (BCOL_BLAU) | |
WCOL_VERD equ (BCOL_VERD * 100h) OR (BCOL_VERD) | |
WCOL_CYAN equ (BCOL_CYAN * 100h) OR (BCOL_CYAN) | |
; ********* SEGMENT DE PILA ************ | |
.stack 100h | |
; ********* SEGMENT DE DADES *********** | |
.data | |
tics db ? ; Comptador per a les interrupcions de rellotge | |
final db ? ; Indica si hem d'acabar | |
pausa db ? ; Indica si estem en pausa | |
rel_ant dd ? ; Guardem la RSI anterior | |
tec_ant dd ? | |
sentit db ? ; Ens indica el sentit, el valor | |
; de sentit l'indiquen les constants | |
; DRETA, ESQUERRA, AMUNT, AVALL | |
puntuacio dd 0 ; Ens indica la puntuacio que porta l'usuari | |
creixer db ? ; Si creixer és zero la serp es mou. | |
; Si creixer és diferent de zero llavors | |
; la serp no es mou, va creixent | |
; el valor de creixer disminueix cada vegada | |
; fins que se situa a zero. Cada cop que | |
; mengem un quadradet verd creixer pren un | |
; valor positiu | |
cap dd ? ; Ens indica la posicio en valor absolut | |
; (o sigui despres de fer 320*j + i) del | |
; cap de la serp | |
cua dd ? ; Igual que cap, però ara indiquem la | |
; posicio de la cua | |
adre_pant dw 0A000h ; Segment on comença la pantalla gràfica | |
; Generalment 0A000h | |
llavor dd ? ; La llavor per generar la seqüència de numeros | |
; aleatoris que necessitem per anar posant | |
; el "menjar" | |
mat_dir db 320*200 dup (?) ; Matriu que guarda la direccio | |
; de la cua. D'aquesta manera un cop | |
; hem esborrat un quadrat podem saber | |
; on es troba el següent quadrat que hem | |
; d'esborrar. | |
missatge db 'Puntuacio : $' | |
puntsStr db 8 dup('0'), '$' | |
; Lletres | |
numeros db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
; EL numero 1 | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_CYAN, BCOL_CYAN, BCOL_CYAN, BCOL_CYAN ; #### | |
; El numero 2 | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE ; # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_NEGRE ; # | |
db BCOL_CYAN, BCOL_CYAN, BCOL_CYAN, BCOL_CYAN ; #### | |
; El numero 3 | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
; El numero 4 | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # # | |
db BCOL_CYAN, BCOL_CYAN, BCOL_CYAN, BCOL_CYAN ; #### | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
; El numero 5 | |
db BCOL_CYAN, BCOL_CYAN, BCOL_CYAN, BCOL_CYAN ; #### | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_NEGRE ; # | |
db BCOL_CYAN, BCOL_CYAN, BCOL_CYAN, BCOL_CYAN ; #### | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
; El numero 6 | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_NEGRE ; # | |
db BCOL_CYAN, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ### | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
; el numero 7 | |
db BCOL_CYAN, BCOL_CYAN, BCOL_CYAN, BCOL_CYAN ; #### | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE ; # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE ; # | |
; el numero 8 | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
; el numero 9 ( per fi !) | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_CYAN ; ### | |
db BCOL_NEGRE, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # | |
db BCOL_CYAN, BCOL_NEGRE, BCOL_NEGRE, BCOL_CYAN ; # # | |
db BCOL_NEGRE, BCOL_CYAN, BCOL_CYAN, BCOL_NEGRE ; ## | |
.code | |
; Rutina PuntsToStr | |
; Transforma la puntuació en una cadena de text i la guarda a "puntsStr" | |
; aixo ho fem servir per saber els punts en sortir | |
PuntsToStr proc | |
push eax | |
push ebx | |
push ecx | |
push edx | |
mov ecx, 7 | |
mov eax, puntuacio | |
mov ebx, 10 | |
divisions2 : | |
cdq | |
div ebx | |
add dl, '0' | |
mov puntsStr[ecx], dl | |
dec ecx | |
cmp eax, 0 | |
jg divisions2 | |
pop edx | |
pop ecx | |
pop ebx | |
pop eax | |
ret | |
PuntsToStr endp | |
; Rutina PutNumbers | |
; Posa la puntuacio a la cantonada superior dreta | |
putnumbers proc | |
push es | |
push eax | |
push ebx | |
push ecx | |
push edx | |
push edi | |
push esi | |
mov ebx, 200 | |
mov es, adre_pant | |
; Ara hem d'agafar la puntuacio en base 10 cada vegada | |
mov eax, puntuacio | |
; Expandim eax a edx:eax | |
divisions : | |
cdq | |
mov ecx, 10 | |
div ecx | |
; Ara el residu el tenim a edx | |
; ara posem el número adequat | |
imul edx, 6*4 | |
mov edi, ebx | |
xor esi, esi | |
pintant : | |
mov ecx, DWORD PTR numeros[edx + esi*4] | |
mov es:[edi], ecx | |
add edi, 320 | |
inc esi | |
cmp esi, 6 | |
jl pintant | |
sub ebx, 6 | |
cmp eax, 0 | |
jg divisions | |
pop esi | |
pop edi | |
pop edx | |
pop ecx | |
pop ebx | |
pop eax | |
pop es | |
ret | |
putnumbers endp | |
; RUTINA RANDOM | |
; Calcula un número aleatori entre 0 i 64000 (tots els pixels) | |
; es basa en el mètode congruencial lineal de Lehmer | |
; x(n) = ( x(n-1)*a + c ) mod m | |
; | |
; El periode de numeros aleatoris serà maxim (el valor de m) quan : | |
; a) c i m són primers entre si | |
; b) a-1 és múltiple de tots els primers que divideixen m | |
; c) si m és multiple de 4 llavors a-1 tb ho és | |
; Amb l'ajuda del Maple hem escollit els numeros | |
; m = 64000 | |
; c = 64001 | |
; a = 101 | |
; La funcio fa servir la variable "llavor" per computar el següent número | |
; El valor es retorna a EAX. La funció actualitza el valor de llavor | |
; amb el valor de EAX | |
random proc | |
; Guardem els registres a la pila | |
push edx | |
push ebx | |
; Agafem la llavor i la multipliquem per 101 | |
mov eax, llavor | |
imul eax, 101 | |
; Li sumem 64001 | |
add eax, 64001 | |
; Expandim el valor de EAX -> EDX:EAX | |
cdq | |
; Posem el divisor 64000 | |
mov ebx, 64000 | |
; Fem la divisió natural | |
div ebx | |
; Copiem el residu a EAX | |
mov eax, edx | |
; El valor calculat es la nova llavor | |
mov llavor, eax | |
; Recuperem els registres | |
pop ebx | |
pop edx | |
; Tornem (molt important!!!) :-) | |
ret | |
random endp | |
putrandompixel proc | |
; Aquesta funció posa un punt aleatori de "menjar" a la pantalla | |
; en un lloc vàlid | |
; | |
; Guardem els registres modificats | |
push es | |
push eax | |
push ebx | |
push ecx | |
push edx | |
; Obtenim el segment de l'adreça on comença la memoria de vídeo | |
mov es, adre_pant | |
no_valid: | |
; Calculem un punt aleatori | |
call random | |
; i el guardem a ecx | |
mov ecx, eax | |
; Expandim EAX -> EDX:EAX | |
cdq | |
; Posem com a divisor 320 | |
mov ebx, 320 | |
; Fem la divisio natural | |
div ebx | |
; Ara comprovem si el divisor és senar o parell | |
bt eax, 0 | |
; Volem que sigui parell ja que el vertex superior esquerra | |
; s'ha de trobar en una fila parell | |
jc no_es_parell320 | |
; En cas q ja sigui parell nomes copiem el valor original a EAX | |
mov eax, ecx | |
; i continuem | |
jmp check_paritat | |
no_es_parell320 : | |
; En cas que no sigui parell incrementem la fila en una unitat | |
; o sigui, 320 elements mes enllà. | |
mov eax, ecx | |
add eax, 320 | |
check_paritat : | |
; Ara comprovem si la columna es parell ja que el vertex superior | |
; esquerre s'ha de trobar en una columna parell | |
bt eax, 0 | |
jc no_es_parell | |
; Si ja és parell no cal fer res | |
jmp fi_test_paritat | |
no_es_parell : | |
; Si no es parell incrementem una columna pq ho sigui | |
inc eax | |
fi_test_paritat : | |
; Ara comprovem que el nostre pixel es troba dins del rang vàlid | |
; Primer mirem si es troba abans de les dues ultimes files | |
cmp eax, 198*320 | |
; En cas que no sigui així, provarem un altre número | |
jge no_valid | |
; Ara mirem que es troba sota les línies de dalt | |
; no volem que ens surti un quadrat on hi ha la puntuacio! | |
cmp eax, 320*8 | |
jl no_valid | |
; Ara comprovem que el punt on volem posar no hi ha res | |
; en el pixel actual i el següent | |
cmp es:[eax], word ptr WCOL_NEGRE | |
jne no_valid | |
; ni en els pixels de sota de l'actual ni sota del següent | |
cmp es:[eax+320], word ptr WCOL_NEGRE | |
jne no_valid | |
; Arribats aqui el punt ja compleix tots els requisits | |
; per tant el pintem. Posem un word per pintar 2 pixels a la vegada | |
mov es:[eax], word ptr WCOL_VERD | |
; i els de la fila inferior | |
mov es:[eax+320], word ptr WCOL_VERD | |
; Recuperem els registres matxacats | |
pop edx | |
pop ecx | |
pop ebx | |
pop eax | |
pop es | |
; i tornem | |
ret | |
putrandompixel endp | |
; RUTINA RSI del rellotge | |
; La mega rutina de rellotge, el cor del programa :-) | |
rellotge proc | |
; Guardem els registres que modificarem | |
push eax | |
push ebx | |
push es | |
; Recuperem el segment de dades que pot haver estat modificat | |
; per alguna RSI del DOS | |
mov ax, @data | |
mov ds, ax | |
; Mirem si estem en pausa, altrament continuem | |
cmp pausa, CERT | |
je fi_rsi_rel | |
; Incrementem el comptador de tics, nomes deixem passar dos tics | |
; (o sigui 0,109 segons) | |
inc tics | |
cmp tics, 1 | |
jne fi_rsi_rel | |
; Reiniciem el comptador de tics | |
mov tics, 0 | |
; Recuperem l'adreça base de la pantalla gràfica | |
mov ax, adre_pant | |
mov es, ax | |
; Situem el cap de la serp a ebx | |
mov ebx, cap | |
; Comprovem que no xoquem amb nosaltres mateixos o amb menjar | |
cmp es:[ebx], word ptr WCOL_NEGRE | |
; Si no es negre es q hi ha alguna cosa ... | |
jne hem_xocat | |
cmp es:[ebx+320], word ptr WCOL_NEGRE | |
je fi_comprovacio | |
hem_xocat : | |
; Hem xocat amb alguna cosa. Comprovem si es menjar | |
cmp es:[ebx], word ptr WCOL_VERD | |
; Si no es menjar llavors hem xocat contra nosaltres o contra la paret | |
jne no_es_menjar | |
cmp es:[ebx + 320], word ptr WCOL_VERD | |
jne no_es_menjar | |
; Si hem arribat fins aqui es pq realment era menjar, llavors la | |
; mare natura fa el fet i la nostra serp creix 25 quadradets | |
; per aixo posem creixer a 25 | |
add creixer, 25 | |
; Li donem punts a l'usuari | |
add puntuacio, 19 | |
; I actualitzem el valor | |
call putnumbers | |
; Ara hem de situar un nou quadrat de menjar | |
call putrandompixel | |
jmp fi_comprovacio | |
no_es_menjar : | |
; Resulta que no era menjar, llavors l'usuari ha perdut! | |
; ja no cal seguir fent enquesta al teclat | |
mov final, CERT | |
; sortim ja de la rsi | |
jmp fi_rsi_rel ; Finalitzem la rsi | |
fi_comprovacio: | |
; No hem xocat contra res (o contra menjar) | |
; pintem els 4 pixels | |
; Primer els 2 de la fila actual | |
mov es:[ebx], word ptr WCOL_BLANC | |
; Despres els 2 de la fila inferior | |
mov es:[ebx+320], word ptr WCOL_BLANC | |
; Recuperem el sentit de la serp | |
mov al, sentit | |
; Guardem a la matriu de direccions el sentit de la serp actual | |
; aquesta matriu serveix per al cursor d'esborrat (o sigui, la cua) | |
mov mat_dir[ebx], al ; Desem el valor de la direccio | |
; Ara caldrà actualitzar la posició del cap | |
_dreta1: cmp sentit, DRETA | |
; Si resulta que hem d'anar cap a la dreta | |
; l'haurem de moure 2 pixels a la dreta | |
jne _esquerra1 | |
add cap, 2 | |
jmp fi_case1 | |
_esquerra1 : cmp sentit, ESQUERRA | |
; Si hem d'anar a l'esquerra haurem de moure 2 columnes a l'esquerra | |
; o sigui restar 2 | |
jne _avall1 | |
sub cap, 2 | |
jmp fi_case1 | |
_avall1 : cmp sentit, AVALL | |
; Si anem cap avall, haurem de moure 2 files cap avall o sigui | |
; sumar dos cops 320 | |
jne _amunt1 | |
add cap, 320*2 | |
jmp fi_case1 | |
_amunt1 : cmp sentit, AMUNT | |
; al seu torn, si anem cap amunt haurem de moure 2 files cap amunt | |
; o sigui restar dos cops 320 | |
jne fi_case1 | |
sub cap, 320*2 | |
fi_case1: | |
; Si creixer és diferente de zero llavors no esborrem la cua | |
; a fi que la serp creixi realment, el que fem es disminuir | |
; la variable creixer que quan valgui zero indicarà que ja | |
; ha crescut prou | |
cmp creixer, 0 | |
je borrar_cua | |
; Restem 1 a l'indicador de creixement | |
dec creixer | |
jmp fi_esborrat | |
borrar_cua : | |
; Com que creixer = 0 llavors hem d'esborrar la cua | |
; simplement agafem on es troba la cua i ho posem a negre | |
mov ebx, cua | |
mov es:[ebx], word ptr WCOL_NEGRE | |
mov es:[ebx + 320], word ptr WCOL_NEGRE | |
; Ara hem de veure cap a quina direccio s'ha mogut la serp | |
; per aixo fem servir la matriu de direccio mat_dir | |
; aquesta matriu té la mida de la pantalla gràfica | |
mov al, mat_dir[ebx] | |
_amunt2: | |
; Si ha anat cap amunt, doncs movem el cursor dos files cap amunt | |
cmp al, AMUNT | |
jne _avall2 | |
sub cua, 320*2 | |
jmp fi_case2 | |
_avall2: | |
; Si ha anat cap avall, doncs 2 files cap avall | |
cmp al, AVALL | |
jne _esquerra2 | |
add cua, 320*2 | |
jmp fi_case2 | |
_esquerra2 : | |
; Si ha anat a l'esquerra 2 columnes a l'esquerra | |
cmp al, ESQUERRA | |
jne _dreta2 | |
sub cua, 2 | |
jmp fi_case2 | |
_dreta2 : | |
; Si ha anat a la dreta 2 columnes a la dreta | |
cmp al, DRETA | |
add cua, 2 | |
fi_case2 : | |
; Ja hem acabat d'esborrar la cua | |
fi_esborrat : | |
; Aqui s'acaba la RSI | |
fi_rsi_rel: | |
; Fem l'EOI per indicar al controlador d'interrupcions | |
; que la RSI està a punt d'acabar | |
mov al, 20h | |
out 20h, al | |
; Ara recuperem els registres que hem modificat | |
pop es | |
pop ebx | |
pop eax | |
; I retornem de la interrupcio | |
iret | |
rellotge endp | |
teclat proc | |
push eax | |
mov ax, @data | |
mov ds, ax | |
in al, 60h | |
bt ax, 7 | |
; Si es un break no li fem cas, nomes volem make's | |
jc fi_rsi_tec | |
; Quan estem en pausa nomes es permet la pausa i l'espai | |
cmp pausa, CERT | |
je _pausa | |
; Anem a mirar de quina tecla es tracta i canviem la | |
; direcció de moviment de la serp | |
_amunt3: cmp al, TEC_AMUNT | |
jne _avall3 | |
; Si estas anant cap avall i prems cap amunt es q ets tonto | |
; pero com que som bona gent, t'ho perdonem :-) | |
cmp sentit, AVALL | |
je fi_case3 | |
mov sentit, AMUNT | |
jmp fi_case3 | |
_avall3: cmp al, TEC_AVALL | |
jne _esquerra3 | |
; No hauries de premer cap avall si estas anant cap amunt | |
cmp sentit, AMUNT | |
je fi_case3 | |
mov sentit, AVALL | |
jmp fi_case3 | |
_esquerra3: cmp al,TEC_ESQUERRA | |
jne _dreta3 | |
; No hauries de premer cap a l'esquerra si vas cap a la dreta | |
cmp sentit, DRETA | |
je fi_case3 | |
mov sentit, ESQUERRA | |
jmp fi_case3 | |
_dreta3: cmp al, TEC_DRETA | |
jne _pausa | |
; No hauries de premer cap a la dreta si vas cap a l'esquerra | |
cmp sentit, ESQUERRA | |
je fi_case3 | |
mov sentit, DRETA | |
jmp fi_case3 | |
_pausa : | |
cmp al, 25 | |
; Hem premut el boto de pausa, s'ha de commutar | |
jne _fi_programa3 | |
not pausa | |
jmp fi_case3 | |
_fi_programa3 : | |
; Si ens trobem la barra d'espai llavors acabem | |
cmp al, 57 ; La barra d'espai | |
jne fi_case3 | |
mov final, CERT | |
fi_case3: | |
fi_rsi_tec : | |
mov al, 20h | |
out 20h, al | |
pop eax | |
iret | |
teclat endp | |
; ************************* PROGRAMA PRINCIPAL ************************ | |
.startup | |
; Inicialitzem les variables locals | |
; Final = fals pq encara no volem sortir | |
mov final, FALS | |
; No estem en pausa | |
mov pausa, FALS | |
; Tics = 0 pq encara no n'hem comptat cap | |
mov tics, 0 | |
; El sentit per defecte a la dreta | |
mov sentit, 0 ; A la dreta | |
; I el cap i la cua de la serp al bell mig de la pantalla | |
mov cap, 100*320 + 160 | |
mov cua, 100*320 + 160 | |
; Li donem una mida inicial de 25 quadrats | |
mov creixer, 25 | |
; Carreguem el mode gràfic 13h 320x200 | |
; La interrupció 10h de la ROM BIOS és la que tracta sobre la | |
; pantalla. Posant AX = 13h i cridant la interrupció 10h fa que | |
; la VGA es posi en el mode gràfic 320x200x256 colors (conegut | |
; com "mode 13") | |
mov ax, 13h | |
int 10h | |
; Pintem el marc exterior | |
; Primer la línia de dalt | |
mov eax, 320*6 | |
mov es, adre_pant | |
linia_dalt: | |
mov es:[eax], byte ptr BCOL_BLAU | |
mov es:[eax + 320], byte ptr BCOL_BLAU | |
inc eax | |
cmp eax, 320*7 | |
jl linia_dalt | |
; La linia de l'esquerra | |
mov eax, 320*6 | |
linia_esquerra : | |
mov es:[eax], word ptr WCOL_BLAU | |
add eax, 320 | |
cmp eax, 64000 | |
jl linia_esquerra | |
; La de baix de tot | |
mov eax, 320*199 | |
linia_baix : | |
mov es:[eax-320], byte ptr BCOL_BLAU | |
mov es:[eax], byte ptr BCOL_BLAU | |
inc eax | |
cmp eax, 64000 | |
jl linia_baix | |
; La de la dreta | |
mov eax, 319+320*6 | |
linia_dreta : | |
mov es:[eax-1], word ptr WCOL_BLAU | |
add eax, 320 | |
cmp eax, 64000 | |
jl linia_dreta | |
; Inicialitzem la llavor dels numeros aleatoris | |
; amb l'hora del sistema mitjançant una crida a la interrupció | |
; software de l'MSDOS (21h) | |
; Agafarem el registre DX que es on es troben els segons i | |
; les centesimes | |
; Funcio del MsDos d'obtenir hora | |
; AH = 2Ch | |
; Int 21h ( la interrupcio 21h es la de l'msdos ) | |
; Resultats : CH = Hora (0-23) | |
; CL = Minuts (0-59) | |
; DH = Segons (0-59) | |
; DL = Centesimes de segon (0-99) | |
mov ah, 2Ch | |
int 21h | |
; Agafem els segons i les centesimes ja ens valdran per a la llavor | |
movzx edx, dx | |
mov llavor, edx | |
; Situem 3 punts de menjar | |
; que sinó és molt avorrit ;D | |
call putrandompixel | |
call putrandompixel | |
call putrandompixel | |
; Tenim zero punts | |
call putnumbers | |
; Modifiquem el vector d'interrupcions | |
mov ax, 0 | |
mov es, ax | |
mov eax, es:[8*4] | |
mov rel_ant, eax | |
mov eax, es:[9*4] | |
mov tec_ant, eax | |
; Canviem la RSI actual per la nostra | |
lea ax, rellotge | |
cli | |
mov es:[8*4], ax | |
mov es:[8*4+2], cs | |
lea ax, teclat | |
mov es:[9*4], ax | |
mov es:[9*4+2], cs | |
sti | |
; bucle d'espera | |
espera: | |
; Si final != cert llavors encara no hem de sortir | |
cmp final, cert | |
jne espera | |
; Restaurem el vector d'interrupcions | |
mov ax, 0 | |
mov es, ax | |
mov eax, rel_ant | |
mov es:[8*4], eax | |
mov eax, tec_ant | |
mov es:[9*4], eax | |
; Recuperem el mode de text 3h (80x25) | |
mov ax, 3h | |
int 10h | |
; Li diem al DOS que escrigui la puntuació | |
lea dx, missatge | |
mov ah, 09h | |
int 21h | |
call PuntsToStr | |
lea dx, puntsStr | |
mov ah, 09h | |
int 21h | |
.exit | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment