Definizione costanti
PAGINA EQU 00h
HT EQU 09h
LF EQU 0Ah
CR EQU 0Dh
;
BIOS_VIDEO EQU 10H
SET_VIDEO_MODE EQU 00h ;in AH
MODO_TESTO EQU 03H ;in AL
;
SET_CURSOR EQU 02h ;in AH
W_CHR_TTY EQU 0Eh ;in AH
;
DOS EQU 21H
R_KEY_CHR EQU 01H
PRINT_STRING EQU 09h
R_KEY_CHR_NE EQU 07H
DSEG SEGMENT PARA PUBLIC 'DATA'
TITOLO DB 'CORSO DI CALCOLATORI ELETTRONICI$'
ISTRUZIONI DB CR,HT,HT,HT,HT,HT,CR,'Inserire 16 cifre esadecimali: $'
BIN_MESS DB CR,LF,HT,HT,'Rappresentazione binaria: $'
RUN_MESS DB CR,LF,HT,HT,'Run Lenght: $'
TERMINE DB CR,LF,LF,HT,'Un''altra iterazione?(s/n) $'
PUNTO DB '.$'
CODICE_TASTO DB 16 DUP (?)
INDEX DW 0
VALORI DB 64 DUP (?)
INDEX_1 DW 0
VALORI_1 DB 64 DUP (?)
INDEX_0 DW 0
VALORI_0 DB 64 DUP (?)
INDEX_RUN DW 0
VALORI_RUN DB 64 DUP (?)
BIT1 DB 64 DUP (?)
BIT0 DB 64 DUP (?)
DSEG ENDS
STACKM SEGMENT PARA STACK 'STACK' ;VIENE ALLOCATA UNA ZONA DI
DB 64 DUP('12345678') ;MEMORIA PER LO STACK: IN
STACKM ENDS ;TUTTO 64*8 BYTES
ASSUME CS:CSEG,DS:DSEG,SS:STACKM
CSEG SEGMENT PARA PUBLIC 'CODE'
;*************************************************************************;
; CORPO PRINCIPALE DEL PROGRAMMA ;
;*************************************************************************;
MAIN PROC FAR
PUSH DS ;ISTRUZIONI DA LASCIARE SEMPRE
MOV AX,00h ;AL PRINCIPIO DEL PROGRAMMA
PUSH AX ;
CALL INIZIALIZZAZIONE
CICLO_PRINCIPALE: CALL PROMPT
CALL LETTURA_DATI
CALL STAMPA_BIN
CALL STAMPA_RUN
CALL TEST_FINALE
JNZ CICLO_PRINCIPALE
RET ;RITORNO AL SISTEMA OPERATIVO
MAIN ENDP
;---------------------------------------------------------------------------;
; ;
; ;PROCEDURA DI INIZIALIZZAZIONE ; ;
; ;REGISTRI UTILIZZATI AX,DS,DX ; ;
;---------------------------------------------------------------------------;
INIZIALIZZAZIONE PROC NEAR
MOV AX,DSEG ;INIZIALIZZAZIONE SEGMENTO
MOV DS,AX ;DATI TRAMITE REGISTRO AX
MOV AH,SET_VIDEO_MODE
MOV AL,MODO_TESTO ; 80X25 A COLORI
INT BIOS_VIDEO ;
MOV DX,0315h ;IMPOSTA RIGA DH, COLONNA DL
CALL SPOSTA_CURSORE
MOV DX,OFFSET TITOLO ;SCEGLIE LA STRINGA TITOLO
CALL STAMPA_STRINGA ;E LA STAMPA
MOV DX,0909h ;IMPOSTA RIGA DH E COLONNA DL
CALL SPOSTA_CURSORE
RET
INIZIALIZZAZIONE ENDP
;--------------------------------------------------------------------------;
; PROCEDURA PER STAMPARE IL MESSAGGIO INIZIALE ;
; REGISTRI UTILIZZATI DX,AH ;
;--------------------------------------------------------------------------;
PROMPT PROC NEAR
MOV DX,OFFSET ISTRUZIONI
CALL STAMPA_STRINGA
RET
PROMPT ENDP
;--------------------------------------------------------------------------;
; PROCEDURA PER STAMPARE UN NUMERO IN BINARIO ;
; REGISTRI UTILIZZATI AX,BL,CX,DX ;
;--------------------------------------------------------------------------;
STAMPA_BIN PROC NEAR
MOV DX,OFFSET BIN_MESS
CALL STAMPA_STRINGA
MOV BX,0
NEW: MOV DL,[CODICE_TASTO+BX] ;LEGGE IL CODICE DEL TASTO
PUSH BX
MOV BX,[INDEX]
MOV [VALORI+BX],DL
POP BX
INC BX
INC INDEX
MOV DH,00h ;CONTATORE DI BITS
SHL DL,01h
SHL DL,01h
SHL DL,01h
SHL DL,01h
CICLO_BINARIO: XOR AL,AL
SHL DL,01h
ADC AL,AL
CALL STAMPA_NUMERO
INC DH
CMP DH,03h
JBE CICLO_BINARIO ;SE NON E' ZERO RICLICLA
TEST BX,3
JNZ NOZ
TEST BX,16
JNZ NOZ
MOV DX,OFFSET PUNTO
CALL STAMPA_STRINGA
NOZ: CMP BX,16
JB NEW
RET
STAMPA_BIN ENDP
;-------------------------------------------------------------------------;
; PROCEDURA PER STAMPARE IN DECIMALE ;
; REGISTRI UTILIZZATI AX,CX,DX ;
;-------------------------------------------------------------------------;
STAMPA_RUN PROC NEAR
MOV DX,OFFSET RUN_MESS
CALL STAMPA_STRINGA
MOV BX,0
NEW2: MOV DL,[CODICE_TASTO+BX]
PUSH BX
MOV BX,[INDEX_RUN]
MOV [VALORI_RUN+BX],DL
POP BX
INC BX
INC INDEX_RUN
MOV CX,16
XOR AX,AX
CICLO: SAL DL,1
RCL AH,1
ADC AX,0
LOOP CICLO
CALL STAMPA_NUMERO
CMP BX,16
JB NEW2
RET
STAMPA_RUN ENDP
;---------------------------------------------------------------------;
; Procedura per determinare se serve un'altra iterazione ;
; ;
; REGISTRI UTILIZZATI: AX, DX ;
; CODICI DI RITORN0: ;
; Zero flag = 0 -> un'altra iterazione ;
; Zero flag = 1 -> esci dal programma ;
;---------------------------------------------------------------------;
TEST_FINALE PROC NEAR
MOV DX, OFFSET TERMINE ;sceglie la stringa (DS:DX)
CALL STAMPA_STRINGA ;e la stampa
CALL LETTURA_SN ;legge da tastiera senza echo
CMP AL, 'n' ;modifica il FLAG 'Z'
RET ;ritorno alla procedura chiamante
TEST_FINALE ENDP
;*********************************************************************;
;* Procedure di basso livello di interfaccia *;
;*********************************************************************;
;---------------------------------------------------------------------;
; Procedura per stampare un numero da 0 a 9 ;
; ;
; REGISTRI UTILIZZATI: AX, BL ;
; PARAMETRI: il numero è memorizzato in AL ;
; VARIABILI: il numero della pagina è salvato in PAGINA ;
; ;
;---------------------------------------------------------------------;
STAMPA_NUMERO PROC NEAR
ADD AL, '0' ;la base da cui partire è '0'
MOV AH,W_CHR_TTY ;servizio BIOS 'Write Char in TTY'
INT BIOS_VIDEO
RET ;ritorno alla procedura chiamante
STAMPA_NUMERO ENDP
;-------------------------------------------------------------------------------------;
; Procedura per stampare un numero da 0 a leggere da tastiera uno dei tasti 'S' o 'N ;
; ritorna solo dopo aver letto uno dei due tasti ;
; ;
; REGISTRI UTILIZZATI: AX ;
; CODICI DI RITORNO: in AL il codice ASCII letto ;
; ;
;-------------------------------------------------------------------------------------;
LETTURA_SN PROC NEAR
NUOVA_LETTURA: MOV AH,R_KEY_CHR_NE ;Servizio DOS 'Read keyboard Char'
INT DOS ;without Echo'
OR AL,00100000b ;converte in minuscolo
CMP AL,'n' ;se il tasto premuto è 'N' esce
JZ FINE_LETTURA ;dalla procedura
CMP AL,'s' ;se non è 'S' ne legge
JNZ NUOVA_LETTURA ;un altro
FINE_LETTURA: RET ;ritorno alla procedura chiamante
LETTURA_SN ENDP
;-------------------------------------------------------------------------------------;
; Procedura per spostare il cursore ;
; ;
; PARAMETRI: le coordinate della posizione del cursore sono memorizzate nel ;
; registro DX: DH riga, DL colonna ;
; VARIABILI: il numero della pagina è memorizzato in PAGINA ;
; ;
; REGISTRI UTILIZZATI: AH, BH ;
;-------------------------------------------------------------------------------------;
SPOSTA_CURSORE PROC NEAR
MOV BH, PAGINA ;pagina video attiva.
MOV AH, SET_CURSOR ;servizio BIOS 'Set cursor
INT BIOS_VIDEO ;Position
RET ;ritorno alla procedura chiamante
SPOSTA_CURSORE ENDP
;-------------------------------------------------------------------------------------;
; Procedura per leggere un tasto e memorizzarlo in CODICE_TASTO ;
; ;
; PARAMETRI: il numero è memorizzato in CODICE_TASTO ;
; REGISTRI UTILIZZATI: AX ;
;-------------------------------------------------------------------------------------;
LETTURA_DATI PROC NEAR
MOV BX,0
NUOVO: MOV AH,R_KEY_CHR ;servizio DOS 'Read keyboard Char'
INT DOS ;Memorizza il carattere
CMP AL,'9'
JBE NUMERO
SUB AL,30h
CMP AL,25h
OR AL, 00100000b
JL SWAP
SUB AL,27h
SWAP: MOV [CODICE_TASTO+BX],AL
INC BX
CMP BX,16
JB NUOVO
RET
NUMERO: SUB AL,30h
CMP AL,25h
JL SWAP
LETTURA_DATI ENDP
;-------------------------------------------------------------------------------------;
; Procedura per stampare una stringa ;
; ;
; PARAMETRI: l'indirizzo della stringa è memorizzato in DS:DX ;
; ;
; REGISTRI UTILIZZATI: AX, BX ;
;-------------------------------------------------------------------------------------;
STAMPA_STRINGA PROC NEAR
MOV AH,PRINT_STRING ;servizio DOS 'print string'
INT DOS ;la stringa è puntata da DS:DX
RET ;ritorna alla procedura chiamante
STAMPA_STRINGA ENDP
CSEG ENDS
END MAIN