;AETC Pràctica: Quinze-Puzle
;Cognoms i Nom:
;
;Lliurar el fitxer amb el nom: cognom1_cognom2_nom.asm
;Data de lliurament: ----------
.model small
.stack 1024
DOSSERVICE EQU 21H ; serveis DOS
BIOSSERVICE EQU 10H ; serveis BIOS
TicksSegon EQU 18 ; Ticks per segon
VECT_R EQU 08h ; vector de rellotge
.data
Tauler db 'Tauler de Joc';Tauler de joc que es mostra a l'inici del programa
db ' 0 1 2 3 '
db ' ÚÄÂÄÂÄÂÄ¿ '
db ' 0³ ³ ³ ³ ³ '
db ' ÃÄÅÄÅÄÅÄ´ '
db ' 1³ ³ ³ ³ ³ '
db ' ÃÄÅÄÅÄÅÄ´ '
db ' 2³ ³ ³ ³ ³ '
db ' ÃÄÅÄÅÄÅÄ´ '
db ' 3³ ³ ³ ³ ³ '
db ' ÀÄÁÄÁÄÁÄÙ '
db '00 Moviments'
db '00 Segons '
;Quan lliureu la pràctica deixeu la matriu inicialitzada amb aquests valors.
Fitxa db 'ABCD';Matriu 4x4 on tenim les fitxes
db 'FGHI'
db 'JK Z'
db 'OPNM'
Estat db 1 ; 0: Hem pitjat la tecla 'q' per sortir, sortir del programa.
; 1: Continuem jugant.
; 2: Guanyat, Totes les lletres estan ordenades, indicar-ho i acabar.
; 3: Temps exhaurit, indicar-ho i acabar.
; 4: Nombre de moviments exhaurits, indicar-ho i acabar
; 5: Masses caselles en blanc, indicar-ho i acabar.
;FilCur i ColCur indicaran la posició del cursor en tot moment.
FilCur db ? ; '0': Fila 0, '3': Fila 3
ColCur db ? ; '0': Columna 0, '3': Columna 3
Moviments db 99; Moviments que podem realitzar.
Ticks db 0 ;variable que indica els Ticks de rellotge transcorreguts
Segons dw 0 ;variable per comptar els segons
RAI_R_Seg dw ? ; adreça de segment de la RAI de rellotge original
RAI_R_Dir dw ? ; desplaçament dins del segment de la RAI de rellotge original
MsgPerdut5 db 'Tauler incorrecte, masses caselles en blanc.','$'
MsgPerdut4 db 'Has perdut! Moviments exhaurits','$'
MsgPerdut3 db 'Has perdut! Temps exhaurit ','$'
MsgGuanya db 'Ho has aconseguit, tot ordenat!','$'
MsgSortir db 'Has premut (q) per sortir ','$'
.code
;*******************************************************************************
; Esborra la pantalla completament escrivint espais en blanc
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
EsborraPantalla:
push AX
push BX
push CX
push DX
;Inicialització per posicionar el cursor
mov bh,00h ;pagina
mov dh,00h ;fila inicial
mov dl,00h ;columna inicial
mov ah,02h ;servei per posicionar el cursor
int BIOSSERVICE
mov bh,00h ;pagina
mov bl,07h ;atribut
mov cx,2000 ;80*25nombre de caracters a escriure
mov al,' ' ;caracter
mov ah,09h ;servei per escriure caracter.
int BIOSSERVICE
pop DX
pop CX
pop BX
pop AX
Ret
;*******************************************************************************
; Mostra el Tauler de joc sense Dades, és a dir, mostra la matriu Tauler
;
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
MostraTauler:
push AX
push BX
push CX
push DX
push SI
;Inicialitzar registres
mov bh,00h ;pagina
mov dh,06 ;fila inicial
mov dl,33 ;columna inicial
mov bl,07h ;atribut
mov cx,1 ;escriurem 1 caracters cada cop
mov si,0 ;index per accedir al tauler
bucleMT:
mov ah,02h ;servei per posicionar el cursor
int BIOSSERVICE
mov al,Tauler[SI];caracter
mov ah,09h ;servei per escriure caracter.
int BIOSSERVICE
inc si ;incrementem l'índex per accedir a les dades
;Actualitzem posició del cursor (fila i columna)
inc dl ;columna
cmp dl, 46 ;Quan arribem a la columna 46 ens posem a l'inici
jl bucleMT ;de la següent fila.
mov dl, 33
inc dh ;fila
cmp dh, 19 ;Quan arribem a la fila 19 vol dir que hem acabat
jl bucleMT ;de dibuixar el tauler.
pop SI
pop DX
pop CX
pop BX
pop AX
ret
;*******************************************************************************
; Buscar posició Inicial per començar a jugar.
; Buscar on hi ha l'espai en blanc i verifica que només hi hagi un espai en
; blanc a la matriu Fitxa. Si només hi ha un espai en blac posiciona el cursor
; en aquella casella. Si hi ha més d'un o cap espai en blanc posem Estat=5 per acabar.
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
PosIni:
ret
;*******************************************************************************
; Actualitza el contingut del Tauler de Joc amb les dades de la matriu Fitxa
; i mostra els moviments que podem realitzar a pantalla cridant a la subrutina
; MostraDigits. El cursor ha de quedar en el mateix lloc que estava.
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
ActualitzaTauler:
ret
;*******************************************************************************
; Converteix un valor decimal (entre 0 i 99) en dos caràcters ASCII.
; S’ha de dividir el valor entre 10, el quocient representarà les desenes i
; el residu les unitats, després s’han de convertir a ASCII.
; Mostra els 2 digits ASCII a la posició de pantalla indicada a través de la pila.
; El valor i la posició es passen per la pila.
; Paràmetres d'entrada: valor [bp+6] i posició (fila,columna) [bp+4]
; Paràmetres de sortida: cap
;*******************************************************************************
MostraDigits:
ret
;*******************************************************************************
; Llegim una tecla utilitzant el servei 08h de les crides al DOS.
; Segons la tecla llegida cridarem al procediment corresponent.
; [‘i’,’j’,’k’ o ’l’] cridar al procediment MouCursor
; ‘<espai>’ cridar al procediment MouFitxa
; ‘q’ posa Estat=0.
; (per la lectura de teclar utilitzar només crides als serceis del DOS).
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
LlegirTecla:
ret
;*******************************************************************************
; Mou el cursor segons la direcció indicada per AL i actualitza FilCur i ColCur
; segons la direcció que s’haig seleccionat
; Paràmetres d'entrada: AL indica la direcció del moviment ('i', 'j', 'k' o 'l')
; Paràmetres de sortida: Cap
;*******************************************************************************
MouCursor:
ret
;*******************************************************************************
; Mira si hi ha una casella buida al costat (dalt, baix, esquerra o dreta) de
; la casella actual del cursor, si és així fem el moviment de la fitxa i
; decrementa en un el número de moviments, si estem a la casella buida o si
; la casella buida no està al costat de la casella on estem, no moure cap fitxa
; ni descomptar moviments.
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
MouFitxa:
ret
;*******************************************************************************
; Verifica si el tauler està ordenat, és a dir, les fitxes estan ordenades
; d’esquerra a dreta i de dalt a baix, quedant la casella buida a la última
; posició (baix-dreta), si és així canviar l’estat a 2 (Guanya).
; Verifica si s'han esgotat els moviments disponibles, si és així posa estat a 4
; (moviments exhaurits)
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
VerificaFi:
ret
;*******************************************************************************
; Mostra el missatge indicat per SI.
; Paràmetres d'entrada: SI: adreça del missatge que volem mostrar
; Paràmetres de sortida: Cap
;*******************************************************************************
MostraMissatge:
ret
;*******************************************************************************
; Instal·lació de la rutina d'atenció d'interrupció de rellotge
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
InstalRAI:
ret
;*******************************************************************************
; Desinstal·lació de la rutina d'atenció d'interrupció de rellotge
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
DesInstalRAI:
ret
;*******************************************************************************
; Rutina d'atenció de l'interrupció del rellotge
; Paràmetres d'entrada: Cap
; Paràmetres de sortida: Cap
;*******************************************************************************
RAIrellotge :
push ax
push dx
push ds
mov ax,@DATA
mov ds,ax
;codi de la RAI
FiRAIrel:
mov al,20h
out 20h,al
pop ds
pop dx
pop ax
iret
;*******************************************************************************
; Programa Principal
;*******************************************************************************
inici:
STARTUPCODE
Call EsborraPantalla
Call MostraTauler
;El vostre codi
EXITCODE 0
end inici