codice:
;******************************************************************************
;
;******************************************************************************
DOSSEG
LOCALS
.MODEL SMALL
.CODE
ORG 100h
ENTRY:
JMP MAIN
;qui vanno i dati
FILE DB '\MSDOS\', 0FFh, 0
HANDLE DW 0
GIORNOSET DB 0
GIORNO DB 0
MESE DB 0
ANNO DW 0
ORE DB 0
MINUTI DB 0
SECONDI DB 0
;0 9 16 24 34 42 50
SET DB "Domenica$Luned$Marted$Mercoled$Gioved$Venerd$Sabato$"
IND_SET DB 0, 9, 16, 24, 34, 42, 50
;0 8 17 23 30 37 44 51 58 68 76 85
NOME_MESE DB "Gennaio$Febbraio$Marzo$Aprile$Maggio$Giugno$Luglio$Agosto$Settembre$Ottobre$Novembre$Dicembre$"
IND_MESE DB 0, 8, 17, 23, 30, 37, 44, 51, 58, 68, 76, 85
A1 DB "Ultimo uso alle ore ", "$"
A2 DB " di $"
;------------------------------------------------------------------------------
;Converte i 4 bit bassi di DL in una cifra esadecimale e la scrive sullo schermo
;
;Inserimento: DL i 4 bit inferiori contengono il numero da visualizzare in
; esadecimale
;------------------------------------------------------------------------------
WRITE_HEX_DIGIT PROC
CMP DL, 10 ;questo nible Š minore di 10?
JAE @@_1 ;salta se >=
ADD DL, "0"
JMP SHORT @@_2
@@_1:
ADD DL, "A" - 10
@@_2:
;CALL WRITE_CHAR
MOV AH, 02h
INT 21h
RET
WRITE_HEX_DIGIT ENDP
;------------------------------------------------------------------------------
;Scrive un numero a 16 bit senza segno in notazione decimale
;
;Inserimento DX numero senza segno a 16 bit
;
;Usa: Write_Hex_digit
;------------------------------------------------------------------------------
WRITE_DECIMAL PROC
MOV AX, DX ;metto DX nel registro dividendo a 16 bit AX
MOV SI, 10 ;usato come divisore
XOR CX, CX ;usato per contare i valori immessi nello stack
@@_1:
XOR DX, DX ;azzero la word alta del dividendo
DIV SI ;calcolo AX \ SI in AX, AX MOD SI in DX
PUSH DX ;inserisce la cifra nello stack
INC CX ;incremento il contatore
OR AX, AX ;continua finchŠ non esaurisco le cifre del numero
JNE @@_1
@@_2:
POP DX ;prelevo le cifre in ordine inverso
MOV DH, BH ;imposto l'attributo colore
CALL WRITE_HEX_DIGIT ;stampo la cifra
LOOP @@_2 ;continuo finchŠ non ho prelevato tutte le cifre
RET
WRITE_DECIMAL ENDP
;------------------------------------------------------------------------------
;Legge la data e la memorizza
;------------------------------------------------------------------------------
LEGGE_DATA PROC
MOV AH, 2Ah
INT 21h
MOV GIORNOSET, AL
MOV GIORNO, DL
MOV MESE, DH
MOV ANNO, CX
RET
LEGGE_DATA ENDP
;-----------------------------------------------------------------------------
;Legge l'ora e la memorizza
;------------------------------------------------------------------------------
LEGGE_ORA PROC
MOV AH, 2Ch
INT 21h
MOV ORE, CH
MOV MINUTI, CL
MOV SECONDI, DH
RET
LEGGE_ORA ENDP
;------------------------------------------------------------------------
;Va all'inizio del file
;------------------------------------------------------------------------------
GOTO_TOP PROC
MOV AH, 42h
XOR AL, AL ;offset del byte rispetto all'inizio del file
XOR CX, CX
XOR DX, DX ;offset 0
MOV BX, HANDLE
INT 21h
RET
GOTO_TOP ENDP
;------------------------------------------------------------------------
;Scrive uno spazio
;------------------------------------------------------------------------------
SCRIVO_SPAZIO PROC
MOV AH, 02h
MOV DL, " "
INT 21h
RET
SCRIVO_SPAZIO ENDP
;------------------------------------------------------------------------
;Scrive il carattere :
;------------------------------------------------------------------------------
SCRIVO_2P PROC
MOV AH, 02h
MOV DL, ":"
INT 21h
RET
SCRIVO_2P ENDP
;------------------------------------------------------------------------
;Scrive fine riga :
;------------------------------------------------------------------------------
SCRIVO_FINE_RIGA PROC
MOV AH, 02h
MOV DL, 13
INT 21h
MOV DL, 10
INT 21h
RET
SCRIVO_FINE_RIGA ENDP
;------------------------------------------------------------------------------
;Stampo la data e l'ora dell'ultimo uso
;------------------------------------------------------------------------------
WRITE_DATA PROC
MOV AH, 09h
MOV DX, OFFSET A1
INT 21h ;scrivo "Ultimo uso alle ore "
MOV AH, 09h
MOV DL, ORE
XOR DH, DH
CALL WRITE_DECIMAL ;scrivo Ore
CALL SCRIVO_2P
MOV AH, 09h
MOV DL, MINUTI
XOR DH, DH
CALL WRITE_DECIMAL ;scrivo minuti
CALL SCRIVO_2P
MOV AH, 09h
MOV DL, SECONDI
XOR DH, DH
CALL WRITE_DECIMAL ;scrivo secondi
MOV AH, 09h
MOV DX, OFFSET A2
INT 21h ;scrivo " di "
MOV BL, GIORNOSET
XOR BH, BH
MOV AL, IND_SET[BX]
MOV DX, OFFSET SET
ADD DL, AL
ADC DH, 0
MOV AH, 9h
INT 21h ;scrivo giorno settimana
CALL SCRIVO_SPAZIO
MOV AH, 09h
MOV DL, GIORNO
XOR DH, DH
CALL WRITE_DECIMAL ;scrivo giorno
CALL SCRIVO_SPAZIO
MOV BL, MESE
SUB BL, 1
XOR BH, BH
MOV AL, IND_MESE[BX]
MOV DX, OFFSET NOME_MESE
ADD DL, AL
ADC DH, 0
MOV AH, 9h
INT 21h ;scrivo mese
CALL SCRIVO_SPAZIO
MOV AH, 09h
MOV DX, ANNO
CALL WRITE_DECIMAL ;scrivo anno
CALL SCRIVO_FINE_RIGA
RET
WRITE_DATA ENDP
;========================================================================
;========================================================================
MAIN:
;JUMPS
;tento di aprire il file
MOV AH, 3Dh
MOV AL, 00000010b ;lettura e scrittura
MOV DX, OFFSET FILE
INT 21h
JAE @@_1 ;se carry = 0, non creo il file e memorizzo l'handle
;creo il file
MOV AH, 3Ch
MOV DX, OFFSET FILE
MOV CX, 06h ;file di sistema e nascosto
INT 21h
JB @@_2 ;se carry impostato, errore: esco
@@_1:
MOV HANDLE, AX
;cerco la lunghezza del file
MOV AH, 42h
MOV AL, 02h ;offset del byte rispetto alla fine del file
MOV BX, HANDLE
XOR CX, CX
XOR DX, DX ;valore dell'offset per spostare il puntatore
INT 21h ;DX:AX = lunghezza del file
OR AX, AX
JNE @@_3 ;se ax <> 0, leggo il file
OR DX, DX
JNE @@_3 ;se DX <> 0, leggo il file
JMP @@_4 ;se ax = 0 e dx = 0 allora leggo la data
@@_3:
;leggo il file
;mi posiziono all'inizio del file
CALL GOTO_TOP
MOV AH, 3Fh
MOV BX, HANDLE
MOV CX, 8
MOV DX, OFFSET GIORNOSET
INT 21h
JB @@_2 ;se carry attivato, errore: salta
;scrivo ultimo uso
MOV AL, GIORNOSET
CMP AL, 0
JB @@_4 ;se GiornoSet < 0 o > 6 non riporto la data ultimo uso
CMP AL, 6
JA @@_4
MOV AL, MESE
CMP AL, 1
JB @@_4 ;se mese < 1 o > 12 non riporto la data ultimo uso
CMP AL, 12
JA @@_4
CALL WRITE_DATA
@@_4:
;leggo la data
CALL LEGGE_DATA
;leggo l'ora
CALL LEGGE_ORA
;scrivo il file
;mi posiziono all'inizio del file
CALL GOTO_TOP
MOV AH, 40h
;MOV BX, HANDLE
MOV CX, 8
MOV DX, OFFSET GIORNOSET
INT 21h
;chiudo il file
MOV AH, 3Eh
MOV BX, HANDLE
INT 21h
@@_2:
EXIT:
INT 20h
END ENTRY