;
; Esame 2006-12-11
;
; Utilizzando il linguaggio Assembler 8086 e l'insieme di interrupt a disposizione sui processori compatibili x86, si realizzi il programma che faccia quanto segue:
; 1.	stampa carattere '$' nella posizione di coordinate definite nei byte aventi nome simbolico STARTCOL e STARTROW;
; 2.	attende che l'utente prema il tasto 'b' (senza farne l'eco);
; 3.	cancella il carattere "$" dalla posizione precedente e lo stampa nella una posizione più a sinistra nello schermo;
; 4.	controlla se il carattere "$" appena spostato ha raggiunto il bordo sinistro 
;       dello schermo (colonna 0), in tal caso posiziona il carattere nella colonna 79
;       mantenendo la stessa riga e continua dal punto 3;
; 5.	ad ogni spostamento del carattere "$" stampa il numero di colonna della posizione corrente nell'angolo in alto a sinistra dello schermo (si tenga presente che questo valore varia tra 0 e 79 e pertanto sono necessari due caratteri ASCII).
;

.MODEL	small
.stack
.data 
    STARTCOL    db 40
    STARTROW    db 12
    x           db 0
    y           db 0
    pkey 		db 0Dh,0Ah, "press any key...$"
.code
start:
	; set segment registers:
    mov ax, @data
    mov ds, ax
        
    ; 1.
    ; Porto il cursore nella posizione STARTCOL,STARTROW
    mov AL, STARTCOL
    mov x, AL
    mov AL, STARTROW
    mov y, AL
    call setCursorPosition        ; posiziono il cursore;
    mov al, '$'        ; stampo il carattere '*';
    call writeCharAtCursorPosition
    
    ; 2. Attendere il tasto 'b'
getKey:
    call input  ; Input da tastiera dell'utente
    cmp al, 'b'
    jne getKey


    ; 3. e 4. spostamento il carattere '$' una posizione piu' a sn.
    ;
    ;  a) cancellare il precedente '$'
ciclo:
    call setCursorPosition        ; posiziono il cursore;
    mov al, ' '
    call writeCharAtCursorPosition
    ;  b) aggiorna coordinata x
    dec x
    jnz stampaSimbolo
    ;  c) controlla se x >= 0 altrimenti x = 79
    mov x, 79   ; reset posizione x nella colonna dx.
    ;  d) stampa '$' nella nuova posizione
stampaSimbolo:
    call setCursorPosition        ; posiziono il cursore
    mov al, '$'
    call writeCharAtCursorPosition
    call stampaX
    jmp ciclo


    ; Fine esercizio
    lea dx, pkey
    call StampaStringa
    mov ah, 1		; wait for any key....
    int 21h
    mov ax, 4c00h	; exit to operating system.
    int 21h

; Posiziona il cursore sullo schermo
; Parametri dh, dl (linea, col)
; Nessun valore ritornato
setCursorPosition proc
    push ax
    push bx
    push dx
    mov dl, x    ; colonna
    mov dh, y    ; riga
	mov bh, 0
	mov ah, 2
    int 10h
    pop dx
    pop bx
    pop ax
    ret
setCursorPosition endp

; Procedura getCursorPosition
; return DH = row.
;        DL = column.
getCursorPosition proc
    push ax
    push bx
    push cx
    mov ah, 03h
    int 10h
    pop cx
    pop bx
    pop ax
    ret
getCursorPosition endp

; Procedura writeCharAtCursorPosition (Pagina video n. 0)
; input: AL = character to display.
writeCharAtCursorPosition proc
    push ax
    push bx
    push cx
    mov bh, 0
    mov cx, 1
    mov ah, 0Ah
    int 10h
    pop cx
    pop bx
    pop ax
    ret
writeCharAtCursorPosition endp

; Procedura stampaX
; Stampa x (0 - 79) in un numero codificato ASCII.
stampaX proc
    PUSH AX
    PUSH BX
    PUSH DX
    
    ; posiziono il cursore nell'angolo in alto a sinistra
    mov dl, 0    ; colonna
    mov dh, 0    ; riga
	mov bh, 0
	mov ah, 2
    int 10h
    
    MOV AH, 0      ; AH <- 0  => AX = 0 - 99
    MOV AL, x
    MOV BL, 10     ; BL <- 10
    DIV BL         ; AL = AX / operando (byte) = 0 - 9
                   ; AH = resto                = 0 - 9
    ADD AL, 30h    ; codifica ASCII del quoziente
    CALL output
    MOV AL, AH     ; AL <- AH = resto
    ADD AL, 30h    ; codifica ASCII del resto
    CALL output
    POP DX
    POP BX
    POP AX
    RET
stampaX endp

; Procedura per prelevare un carattere da tastiera    
; Il carattere letto e' restituito in AL.
input proc
   	mov ah, 7
	int 21h
    ret
input endp

; Stampa il carattere contenuto in AL
output proc
    push ax
    push dx
    mov ah, 2
	mov dl, AL
	int 21h       ; output character.
	pop dx
	pop ax
    ret
output endp

; Stampa una stringa terminata da $ indirizzata dal registro DX
stampaStringa proc
    push ax
    mov ah, 9
    int 21h
    pop ax
    ret
stampaStringa endp

end start ; set entry point and stop the assembler.