;
; Esame 2007-01-12 - Esercizio 4.
;
; Utilizzando il linguaggio Assembler 8086 e l'insieme di interrupt a
; disposizione su tale processore, si realizzi il programma che faccia quanto
; segue:
;   1. attenda che l'utente digiti un numero compreso tra 0 e 9;
;   2. memorizzi il numero digitato nella cella ampia un byte di nome
;      simbolico N;
;   3. calcoli il valore della successione di Fibonacci per il numero N,
;      memorizzando tale valore nella cella di nome R;
;   4. stampi su una nuova riga il valore decimale (codificato da cifre ASCII)
;      del numero R;
;   5. invii le cifre ASCII del risultato appena stampato all'interfaccia
;      parallela di uscita collegata agli indirizzi simbolici TSR e TBR.
;
.model SMALL
.stack

TSR EQU 60
TBR EQU 130

.data
    N      db 0
    R      db 1
    insNum db "Inserisci un numero compreso tra 3 e 9: $"
    printR db "R = $"
    pkey   db "press any key...$"
        
.code
start:
	; set segment registers:
    mov ax, @data
    mov ds, ax

    ; 1. inserimento numero
    call insNumero
    
    ; 2. memorizzazione numero in N
    mov N, al
    
    ; 3. calcolo della successione di Fibonacci:
    ;    il registro cl e' usato come indice della successione,
    ;    il registro bl contiene Fn-2,
    ;    il registro al contiene Fn-1,
    ;    la cella R contiene il risultato corrente.
    mov cl, 2
    mov bl, 1   ; inizializzazione Fn-2
    mov al, 1   ; inizializzazione Fn-1
ciclo:
    add bl, al
    mov R, bl
    mov bl, al
    mov al, R
    inc cl
    cmp cl, N
    jne ciclo
    
    ; 4. stampa a video di R
    call stampaR
    
    ; 5. invio delle cifre
    ;call outPAR

	; Fine esercizio    
    lea dx, pkey
    mov ah, 9
    int 21h        ; output string at ds:dx
    mov ah, 1	   ; wait for any key....  
    int 21h
    mov ax, 4c00h ; exit to operating system.
    int 21h
           
;
; Chiede di inserie un numero compreso tra 3 e 9
; ritornando il suo valore binario in AL
insNumero proc
    push dx
    lea dx, insNum
    mov ah, 9
    int 21h
inASCII:
    mov ah, 7
	int 21h
   	and al, 7Fh
	cmp al, '3'
	jb  inASCII
	cmp al, '9'
	ja  inASCII
	push ax
	mov ah, 2
	mov dl, al
	int 21h
    mov ah, 2
	mov dl, 0Dh
	int 21h
    mov dl, 0Ah
	int 21h
	pop ax	
	sub al, 30h
	pop dx
	ret 
insNumero endp

;
; Stampa il contenuto di R seguito da newline
; e ritorna le cifre ASCII che codificano R
; in AL, AH
stampaR proc
    push bx
    push dx
    lea dx, printR
    mov ah, 9
    int 21h
    mov ah, 0
    mov al, R
    mov bl, 10
    div bl
    ; AL = AX/BL = R/10
    ; AH = resto
    mov bx, ax
    add al, 30h
    mov dl, al
    mov ah, 2
    int 21h
    mov ax, bx
    mov dl, ah
    add dl, 30h
    mov ah, 2
    int 21h
    mov dl, 0Ah
    int 21h
    mov dl, 0Dh
    int 21h
    mov ax, bx
    pop dx
    pop bx
    ret
stampaR endp

outPAR proc
    call testTSR    
    out TBR, al
    call testTSR
    mov al, ah
    out TBR, al
    ret
outPAR endp

testTSR proc
    push ax
testFO:
    in al, TSR
    and al, 00100000b
    cmp al, 00100000b
    jne testFO
    ret
    pop ax
    ret
testTSR endp

end start ; set entry point and stop the assembler.
