PAGE 66,132 TITLE** PROGRAMMA di GESTIONE di programmi ASSEMBLER tipo COM (dicembre 2004) SUBTTL ** TUTORIAL ASSEMBLY -- www.giobe2000.it -- by ing. Giorgio OBER ;/---------------------------------------------------------------------------\ ;| NOME : LoopCom2.ASM /----------------[TxD][RxD]------------------\| ;| AUTORE : Giorgio OBER | *********** Versione UNICA ************** || ;| VERSIONE : dicembre 2004 \------------------[COM2]--------------------/| ;| DESCRIZIONE : Organizza la RiceTrasmissione DATI attraverso la porta COM2| ;| di un PC con se stesso (cioŠ in "LoopBack Mode"); al fine di| ;| imporre un Loop di RiceTrasmissione automatico sulla porta| ;| preselezionata imposta a "1" il bit4 (Diagnostic Loopback| ;| Mode) del Registro di CONTROLLO del MODEM. | ;| a) versione con presentazione (DESKTOP) | ;| b) in AUTOMATICO il programma TRASMETTE in continuazione | ;| (sulla porta COM1) la sequenza dei caratteri ascii da | ;| spazio [=20H, 32] all'ultimo ascii esteso [=FFH, 255]; | ;| in MANUALE il programma aspetta la digitazione di un | ;| tasto e poi ne TRASMETTE il codice ascii, fino alla | ;| pressione del tasto | ;| c) il processo Š gestito da tastiera con diversi livelli di | ;| menu interattivi. | ;| d) non Š prevista l'attivazione del controllo di Time-Out | ;| e) il protocollo HW impostato per la RICETRASMISSIONE Š: | ;| /--------------------------------\ | ;| | COM2, 9600, N, 2, 8 | | ;| \--------------------------------/ | ;|/-----------\ Per cambiare PORTA utilizzata, Velocit… di ricetrasmissione| ;|| | e Protocollo Seriale scegli altri valori tra quelli possibili| ;|| | per le costanti qui sotto; per COM_num e Baude basta spostare| ;|| NB: | il "punto e virgola" mentre per Protoc bisogna riassemblare| ;|| | il byte con i campi desiderati. | ;|| | -------------------------------------------------------------| ;|\-----------/ E' comunque disponibile la versione "LoopCom1.ASM" per COM1. | ;| -------------------------------------------------------------| ;| Maggiori dettagli sono disponibili nella sezione dedicata | ;| alla porta seriale sul sito *** http://www.giobe2000.it *** | ;\---------------------------------------------------------------------------/ ESC_ EQU 27 ;codice del tasto COM_num EQU 02H ;PORTA utilizzata = COM2 /--------------------------------\ ;EQU 01H ;PORTA utilizzata = COM1 |Scegli la porta COM desiderata | ;EQU 03H ;PORTA utilizzata = COM3 |[ default: programma per COM2 ] | ;EQU 04H ;PORTA utilizzata = COM4 \--------------------------------/ ;---------------------------------------------------------- ;/--------------------------------------------------------\ ;| Scegli la COSTANTE per la VELOCITA` desiderata | ;*--------*-------------------------------*---------------* ;|Costante|********** Baud RATE *********| Errore | ;*--------*-----------------------*-------*---------------* ;EQU 0900H ;|=2304 = (115200/2304) = 50.0 | 50 | ---- | ;EQU 0600H ;|=1536 = (115200/1536) = 75.0 | 75 | ---- | ;EQU 0417H ;|=1047 = (115200/1047) = 110.0 | 110 |(errore 0.026 )| ;EQU 0359H ;|= 857 = (115200/857 ) = 134.4 | 135 |(errore 0.058 )| ;EQU 0300H ;|= 768 = (115200/768 ) = 150.0 | 150 | ---- | ;EQU 0180H ;|= 384 = (115200/384 ) = 300.0 | 300 | ---- | ;EQU 00C0H ;|= 192 = (115200/192 ) = 600.0 | 600 | ---- | ;EQU 0060H ;|= 96 = (115200/96 ) = 1200.0 | 1200 | ---- | ;EQU 0040H ;|= 64 = (115200/64 ) = 1800.0 | 1800 | ---- | ;EQU 003AH ;|= 58 = (115200/58 ) = 1986.2 | 2000 |(errore 0.69) | ;EQU 0030H ;|= 48 = (115200/48 ) = 2400.0 | 2400 | ---- | ;EQU 0020H ;|= 32 = (115200/32 ) = 3600.0 | 3600 | ---- | ;EQU 0018H ;|= 24 = (115200/24 ) = 4800.0 | 4800 | ---- | ;EQU 0010H ;|= 16 = (115200/16 ) = 7200.0 | 7200 | ---- | Baude EQU 000CH ;|= 12 = (115200/12 ) = 9600.0 | 9600 | ---- | ;EQU 0006H ;|= 6 = (115200/6 ) = 19200.0 | 19200 | ---- | ;EQU 0003H ;|= 3 = (115200/3 ) = 38400.0 | 38400 | ---- | ;EQU 0002H ;|= 2 = (115200/2 ) = 57600.0 | 56000 |(errore 2.86) | ;EQU 0001H ;|= 1 = (115200/1 ) =115200.0 |115200 | ---- | ;\--------------------------------*-------*---------------/ ;---------------------------------------------------------- ;/--------------------------------------------------------\ ;| Scegli la COSTANTE associata al PROTOCOLLO SERIALE | ;*---------[7654 3210]=07H--------------------------------* ;| default .... ..11 >>>>> 8 bit per il DATO | Protoc EQU 07H ;| .... ..10 >>>>> 7 bit per il DATO | ;| .... ..01 >>>>> 6 bit per il DATO | ;| .... ..00 >>>>> 5 bit per il DATO | ;*--------------------------------------------------------* ;| default .... .1.. >>>>> 2 bit di stop | ;| .... .0.. >>>>> 1 bit di stop | ;*--------------------------------------------------------* ;| ...0 1... >>>>> parit… dispari | ;| ...1 1... >>>>> parit… pari | ;| default ...x 0... >>>>> nessuna parit… | ;*--------------------------------------------------------* ;| ..0. .... >>>>> parit… disabilitata | ;| .0.. .... >>>>> Break disabilitato | ;| 0... .... >>>>> programmaz. del protocollo | ;\--------------------------------------------------------/ ; MACRO UTILIZZATE DAL PROGRAMMA: include c:\arch-lab\bin\GIOBE.MAC ;/[nuova MACRO locale]------------------------------------------------\ ;|M_Corn Organizza la stampa di una cornice a video, predisponendo i | ;| parametri nei corretti registri, per la procedura RamCorn | ;\--------------------------------------------------------------------/ M_corn MACRO altezza,larghezza,riga,colonna,colore,tipo,ombra,salva MOV AH,altezza ;\[ altezza compresa cornice ] MOV AL,larghezza ;|[ larghezza compresa cornice ] MOV DH,riga ;|[ riga angolo in alto a sinistra ] MOV DL,colonna ;|[ colonna angolo in alto a sinistra ] MOV BL,tipo ;|[ tipo 0=tratto semplice; 1=tratto doppio] MOV BH,ombra ;|[ ombra 0=senza; 1=con ombreggiatura ] MOV CX,salva ;|[ salva RAM in cui salvare l'area coperta ] M_COLOR Colore ;|[ colore: colore della cornice e sfondo ] CALL RamCorn ;/ ENDM ; LIBRERIA UTILIZZATA DAL PROGRAMMA [opzione WinASM altrimenti non necessaria] includelib c:\arch-lab\bin\GIOBE.LIB ;PROCEDURE ESTERNE UTILIZZATE dal PROGRAMMA [NEAR, dalla LIBRERIA ~GIOBE.LIB~] ;----------------------------------------------------------------------------- EXTRN CambiaCol:NEAR EXTRN BIOchr1:NEAR EXTRN RIEMPI:NEAR EXTRN BIOSmsg:NEAR EXTRN SET_cur:NEAR EXTRN VIA_cur:NEAR EXTRN RIP_cur:NEAR EXTRN KEYwait:NEAR EXTRN Byt2Asc:NEAR EXTRN Wor2Dec:NEAR EXTRN RamCorn:NEAR ; DICHIARAZIONI (VARIABILI) PER I PROGRAMMI ESTERNI: PUBLIC ATTRIB ;Attributo di colore ; DICHIARAZIONI (PROCEDURE) PER I PROGRAMMI ESTERNI: PUBLIC LoopCom2 ;DEFINIZIONE DEL SEGMENTO DEL CODICE ;----------------------------------------------------------------------------- _prog SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:_prog,DS:_prog ORG 0100H INIZIO: JMP LoopCom2 ;AREA DESTINATA AI DATI DEL PROGRAMMA ;----------------------------------------------------------------------------- ATTRIB DB 00H Numero DW 0001H Titolo DB "Programmi per il Collaudo della Porta Seriale ",00H Titolo1 DB "COM",00H Tema0 DB "LoopCom2-RICETRASMISSIONE SERIALE su " DB "COM2 - Protocollo:9600,N,2,8",00H Nocom0 DB "La PORTA SERIALE desiderata, COM , ",00H Nocom1 DB "non Š",00H Nocom2 DB " disponibile",00H Centro1 DB "Caratteri Ascii Trasmessi",00H Centro2 DB "Caratteri Ascii Ricevuti",00H MENU01 DB "Inizia",00H MENU02 DB "Quit",00H MENU03 DB "Interrompi ",00H MENU04 DB "Riprendi ",00H MENU05 DB "Cancella",00H MENU06 DB "Trasmissione Manuale o Automatica?",00H MENU07 DB "Digita il carattere da trasmettere",00H MENU08 DB "ESC ",00H BytLoop DB "Bytes ricetrasmessi: ",00H DatLoop DB 00H DepoMod DB 00H ;[DepoMod]=00 con "A" Trasmissione Automatica ;[DepoMod]=01 con "M" Trasmissione Manuale RigAsc1 DB 2 ;Numero della riga corrente per i caratteri trasmessi ColAsc1 DB 1 ;Numero della colonna corrente per i caratteri trasmessi AtrAsc1 DB 0EH ;Colore corrente usato nella stampa dei caratteri trasmessi RigAsc2 DB 8 ;Numero della riga corrente per caratteri ricevuti ColAsc2 DB 1 ;Numero della colonna corrente per caratteri ricevuti AtrAsc2 DB 1FH ;Colore corrente usato nella stampa dei caratteri ricevuti ;AREA DESTINATA ALLE PROCEDURE DEL PROGRAMMA ;/---------------------------------------------------------------------------\ ;| PROCEDURA : BARRA | ;| DESCRIZIONE : Stampa un'intera riga di spazi | ;\---------------------------------------------------------------------------/ BARRA: M_CURSOR DH,0 MOV AL,' ' MOV CX,80 bar0: CALL BIOchr1 LOOP bar0 RET ;/---------------------------------------------------------------------------\ ;| PROCEDURA : DESKTOP | ;| DESCRIZIONE : Predispone il Piano di Lavoro per il Test Seriale. | ;| Se il valore ricevuto in ingresso in SI Š 0000H la porta| ;| seriale desiderata NON Š presente nel sistema; la procedura| ;| segnala l'errore e pone automaticamente fine al test,| ;| tornando al DOS (rientro a livello _OUT) con un artificio. | ;\---------------------------------------------------------------------------/ DESKTOP:PUSH SI ; In ingresso SI=0000 se la porta richiesta NON ; Š presente nel sistema... MOV Word Ptr CS:[Numero],01; Numero di Bytes ricetrasmessi MOV AL,'°' ;\ M_COLOR 71H ;|Predispone il Piano di lavoro CALL Riempi ;|su tavola zigrinata CALL VIA_cur ;/ M_COLOR 70H ;\ MOV DH,0 ;| CALL BARRA ;| M_msgC Titolo, 0,12,70H;| M_COLOR 74H ;|Intestazione M_msgN Titolo1 ;/ MOV DH,24 ;\ CALL BARRA ;|Menu M_msgC MENU02,24,70,70H;| M_Chr 'Q',24,70,74H ;/ ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva M_corn 3 , 69 , 11 , 5 , 1EH , 01 , 01 ,1000H POP SI ;\ CMP SI,0000H ;| JNZ DESK_0 ;| M_msgC Nocom0,12,13,1FH;|Recupera il valore iniziale di SI; se vale 0 M_COLOR 9FH ;|la porta richiesta NON Š presente nel sistema; M_msgN Nocom1 ;|se SI contiene 0000 la porta NON Š installata: M_COLOR 1FH ;|si segnala l'errore e si termina senza test M_msgN Nocom2 ;| MOV AL,CS:[depPOR];|"La PORTA SERIALE desiderata, COM , ADD AL,30H ;| non Š disponibile" M_Chr AL,12,45,1EH ;| M_Chr AL, 0,61,74H ;| <<<< Visualizza anche nella barra del Titolo CALL KEYwait ;/ POP AX ;\NB: recupera con POP AX la posizione pendente JMP _OUT ;|nello stack dovuta alla chiamata "CALL DESKTOP ;/per poter tornare con JMP invece che con "RET" ;--------------------------------------------------------------------- DESK_0: M_msgC Tema0,12, 7,1FH;\Messaggio di test eseguibile MOV AL,CS:[depPOR];|"RICETRASMISSIONE SERIALE su COMx - ADD AL,30H ;| protocollo HW: 9600,N,2,8" M_Chr AL,12,47,1EH ;| M_Chr AL, 0,61,74H ;/ <<<< Visualizza anche nella barra del Titolo M_msgC MENU01,24,7,70H;\/--------------------------------------------\ M_Chr 'I',24, 7,74H ;||************ Primo Menu interno ************| DESK_1: CALL KEYwait ;|\--------------------------------------------/ AND AL,11011111B ;|Rimane in attesa dei tasti del Menu principale CMP AL,'I' ;| JZ DESK_2 ;| con "I" inizia il Test CMP AL,'Q' ;| con "Q" torna al DOS JNZ DESK_1 ;| JMP _OUT ;/ ;--------------------------------------------------------------------- DESK_2:M_msgC MENU06,24, 4,70H;\/--------------------------------------------\ M_Chr 'M',24,17,74H ;||********* Secondo Menu interno ************| M_Chr 'A',24,27,74H ;|\--------------------------------------------/ DESK_3: CALL KEYwait ;|Rimane in attesa dei tasti del Menu secondario AND AL,11011111B ;| MOV Byte Ptr CS:[DepoMod],00;| con "A" Trasmissione Automatica CMP AL,'A' ;| JZ DESKdati ;| MOV Byte Ptr CS:[DepoMod],01;| con "M" Trasmissione Manuale CMP AL,'M' ;| JNZ DESK_3 ;/ ;/-------------------------------------------------------------------\ ;|**** NB: prosegue attraverso DESKdati e termina con il suo RET ****| ;\-------------------------------------------------------------------/ ;/---------------------------------------------------------------------------\ ;| PROCEDURA : DESKdati | ;| DESCRIZIONE : Predispone il Piano di Ricetrasmissione DATI e inizializza | ;| le Variabili necessarie per il programma di Test | ;\---------------------------------------------------------------------------/ DESKdati: ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva M_corn 12 , 80 , 1 , 0 , 03H , 00 , 00 ,2000H M_Chr '[', 1, 3,03H ;|Menu M_COLOR 03H ;| Primo campo di emissione Dati seriali M_msgN Centro1 ;| [Caratteri Ascii TRASMESSI] M_COLOR 03H ;| MOV AL,']' ;| CALL BIOchr1 ;/ ;M_corn altezza,larghezza,riga,colonna,colore,tipo,ombra,salva M_corn 12 , 80 , 12 , 0 , 03H , 00 , 00 ,3000H M_Chr '[',12, 3,03H ;| M_COLOR 03H ;| Secondo campo di emissione Dati seriali M_msgN Centro2 ;| [Caratteri Ascii RICEVUTI] M_COLOR 03H ;| MOV AL,']' ;| CALL BIOchr1 ;/ M_Chr '*',12, 0,03H ;\Caratteri per sovrapporre le due cornici M_Chr '*',12,79,03H ;/ ;/---------------------------------------------\ ;|Inizializza le variabili - Test Seriale| ;\---------------------------------------------/ MOV Byte Ptr CS:[DatLoop],00; Primo Carattere da trasmettere (ascii 00) MOV Byte Ptr CS:[RigAsc1],02;\Predispone la riga e la colonna di stampa cor- MOV Byte Ptr CS:[ColAsc1],01;|rente per i caratteri al valore 2,1 MOV Byte Ptr CS:[AtrAsc1],0FH;/Colore da usare nella stampa dei caratteri MOV Byte Ptr CS:[RigAsc2],13;\Predispone la riga e la colonna di stampa cor- MOV Byte Ptr CS:[ColAsc2],01;|rente per i bytes al valore 8,1 MOV Byte Ptr CS:[AtrAsc2],0FH;/Colore da usare nella stampa dei bytes RET ;/---------------------------------------------------------------------------\ ;| PROCEDURA : StampaTxD | ;| DESCRIZIONE : Stampa i dati trasmessi dalla porta SERIALE, organizzandoli | ;\---------------------------------------------------------------------------/ StampaTxD: PUSH CX PUSH BX PUSH AX ;--------------------------------------------------------------------- PUSH AX ;\Posizione la colonna di stampa del numero di MOV DL,30 ;|bytes ricetrasmessi MOV AL,CS:[DepoMod];|Preleva il codice di Modo CMP AL,00H ;|[DepoMod]=00 con "A" Trasmissione Automatica JZ stamp ;|[DepoMod]=01 con "M" Trasmissione Manuale ADD DL,12 ;/ stamp:M_msgC BytLoop,24,DL,70H;\ M_COLOR 74H ;| MOV AX,CS:[Numero];|Stampa e mette a video il numero dei Bytes CALL Wor2Dec ;|trasmessi INC AX ;| MOV CS:[Numero],AX;| POP AX ;/ ;--------------------------------------------------------------------- MOV CL,CS:[AtrAsc1];\ M_COLOR CL ;| MOV DH,CS:[RigAsc1];|Assume la riga, la colonna e il colore di MOV DL,CS:[ColAsc1];|stampa e mette a video il carattere Ascii CALL SET_cur ;|del valore trasmesso corrente CALL BIOchr1 ;/ INC DL ;\Controllo della Colonna corrente: se la stampa CMP DL,79 ;|Š ancora all'interno della cornice, sulla riga JNZ stamp0 ;/corrente, tutto va bene MOV DL,01 ;\Riporta la colonna di stampa all'interno della INC DH ;|cornice, sulla riga successiva, e controlla se CMP DH,12 ;|la nuova riga Š essa pure ancora all'interno JNZ stamp0 ;/della cornice; se Š cosŤ tutto va bene MOV DH,2 ;\La cornice Š stata riempita completamente con MOV CL,CS:[AtrAsc1];|i caratteri in partenza dalla Seriale; le DEC CL ;|coordinate di stampa sono riportate nell'ango- CMP CL,0DH ;|lo in alto a sinistra all'interno della corni- JNZ stamp0 ;|ce e, per evidenziare la sovrascrittura, si MOV CL,0FH ;|cambia anche il colore di stampa, alternando stamp0: MOV CS:[AtrAsc1],CL;/Bianco Brillante a Giallo,sempre in campo Nero MOV CS:[RigAsc1],DH; MOV CS:[ColAsc1],DL POP AX POP BX POP CX RET ;/---------------------------------------------------------------------------\ ;| PROCEDURA : StampaRxD | ;| DESCRIZIONE : Stampa i dati ricevuti dalla porta SERIALE, organizzandoli | ;\---------------------------------------------------------------------------/ StampaRxD: PUSH CX PUSH BX PUSH AX MOV CL,CS:[AtrAsc2];\ M_COLOR CL ;| MOV DH,CS:[RigAsc2];|Assume la riga, la colonna e il colore di MOV DL,CS:[ColAsc2];|stampa e mette a video il carattere Ascii CALL SET_cur ;|del valore ricevuto corrente CALL BIOchr1 ;/ INC DL ;\Controllo della Colonna corrente: se la stampa CMP DL,79 ;|Š ancora all'interno della cornice, sulla riga JNZ stamp1 ;/corrente, tutto va bene MOV DL,01 ;\Riporta la colonna di stampa all'interno della INC DH ;|cornice, sulla riga successiva, e controlla se CMP DH,23 ;|la nuova riga Š essa pure ancora all'interno JNZ stamp1 ;/della cornice; se Š cosŤ tutto va bene MOV DH,13 ;\La cornice Š stata riempita completamente con MOV CL,CS:[AtrAsc2];|i caratteri in arrivo dalla Seriale; le DEC CL ;|coordinate di stampa sono riportate nell'ango- CMP CL,0DH ;|lo in alto a sinistra all'interno della corni- JNZ stamp1 ;|ce e, per evidenziare la sovrascrittura, si MOV CL,0FH ;|cambia anche il colore di stampa, alternando stamp1: MOV CS:[AtrAsc2],CL;/Bianco Brillante a Giallo,sempre in campo Nero MOV CS:[RigAsc2],DH; MOV CS:[ColAsc2],DL POP AX POP BX POP CX RET ;/---------------------------------------------------------------------------\ ;|PROCEDURA : INIserial | ;|DESCRIZIONE: Seleziona automaticamente la porta seriale COM predisposta dal| ;| valore della costante "COM_num" (per default EQU 01H= COM1), e| ;| se la porta seriale desiderata NON Š presente nel sistema,| ;| lascia in uscita in SI il valore 0000H; altrimenti lascia in| ;| SI l'indirizzo Base dell'UART sotto controllo ([port_8]= 03F8H| ;| o 02F8H o 03E8H o 02E8H) e rende facilmente reperibili TUTTI i| ;| Registri della serie virtualizzandoli con altrettante variabili| ;| /------*-----*-----*-----*-----*-----------------------------\| ;| |******| COM1| COM2| COM3| COM4|Descrizione || ;| *------*-----*-----*-----*-----*-----------------------------*| ;| |port_8|03F8H|02F8H|03E8H|02E8H|Scritt/Lett DATO -LSBdivisore|| ;| |port_9|03F9H|02F9H|03E9H|02E9H|Abilitaz Interruz-MSBdivisore|| ;| |port_A|03FAH|02FAH|03EAH|02EAH|Identif interruzioni || ;| |port_B|03FBH|02FBH|03EBH|02EBH|Registro controllo LINEA || ;| |port_C|03FCH|02FCH|03ECH|02ECH|Registro controllo MODEM || ;| |port_D|03FDH|02FDH|03EDH|02EDH|Registro stato LINEA || ;| |port_E|03FEH|02FEH|03EEH|02EEH|Registro stato del MODEM || ;| \------*-----*-----*-----*-----*-----------------------------/| ;| Inizializza inoltre: | ;| a) la velocit… di ricetrasmissione caricando il divisore a 16| ;| bit, predisposto dalla costante "Baude" (default EQU 000CH=| ;| 9600 baud) nei Registri [port_9]=MSB e [port_8]=LSBdivisore| ;| b) il valore dei parametri desiderati per il protocollo HW, in| ;| in accordo con le scelte suggerite dalla costante "Protoc"| ;| (default EQU 07H= 8 bit di dato e 2 di stop,nessuna parit…)| ;| c) il valore del Registro di abilitazione delle Interruzioni,| ;| [port_9] Š fissato a 00H: in questo modo nessun evento se-| ;| riale produrr… richiesta d'interruzione sulla linea dedica-| ;| ta IRQ3 o IRQ4 e non sar… necessario predisporre la relati-| ;| va procedura di servizio (rispettivamente INT0BH o INT0CH) | ;| d) il valore del Registro di controllo MODEM, [port_C], Š fis-| ;| sato a 03H: in questo modo sono attivi i segnali di tipici| ;| del MODEM, "Data Terminal Ready" e "Request To Send" | ;\---------------------------------------------------------------------------/ depPOR DB COM_num ; Numero della porta COM da controllare (1, 2, 3 o 4) depVEL DW Baude ; Valore n del divisore di Baud RATE necessario per ; stabilire la velocitŕ di Ricetrasmissione = 115200Hz/n depTIP DB Protoc ; Byte ricostruito in accordo con il desiderato ; numero di bit di dato, di stop e di (eventuale) parit… ;/-----*-----*-----*-----*------------------------------\ ;| COM1| COM2| COM3| COM4|Descrizione | ;*-----*-----*-----*-----*------------------------------* port_8 DW ? ;|03F8H|02F8H|03E8H|02E8H|Scritt/Lett DATO - LSBdivisore| port_9 DW ? ;|03F9H|02F9H|03E9H|02E9H|Abilitaz Interruz- MSBdivisore| port_A DW ? ;|03FAH|02FAH|03EAH|02EAH|Identif interruzioni | port_B DW ? ;|03FBH|02FBH|03EBH|02EBH|Registro controllo LINEA | port_C DW ? ;|03FCH|02FCH|03ECH|02ECH|Registro controllo MODEM | port_D DW ? ;|03FDH|02FDH|03EDH|02EDH|Registro stato LINEA | port_E DW ? ;|03FEH|02FEH|03EEH|02EEH|Registro stato del MODEM | ;\-----*-----*-----*-----*------------------------------/ ;---------------------------------------------------------------------------- ;/------[PRIMA FASE]---------------------------------------------------------\ ;| Inizializzazione dei REGISTRI della PORTA SERIALE | ;\---------------------------------------------------------------------------/ INIserial: PUSH ES ;\Assume in AX l'indirizzo BASE della porta MOV AX,0000H ;|seriale suggerita dalla variabile [depPOR], MOV ES,AX ;|a sua volta predisposta con il valore della MOV SI,0400H ;|costante "COM_num" (per default EQU 01H=COM1), MOV AL,CS:[depPOR];|estraendolo dalle locazioni dell'Area di comu- DEC AL ;|nicazione BIOS: le prime sue 8 locazioni sono SHL AL,1 ;|predisposte in fase di bootstrap ai valori: MOV AH,00H ;| /-------------------------------------------\ ADD SI,AX ;| |0000:0400H - Porta Seriale 1 (COM1) 03F8H | MOV AL,ES:[SI] ;| |0000:0402H - Porta Seriale 2 (COM2) 02F8H | INC SI ;| |0000:0404H - Porta Seriale 3 (COM3) 03E8H | MOV AH,ES:[SI] ;| |0000:0406H - Porta Seriale 4 (COM4) 02E8H | POP ES ;| \-------------------------------------------/ ;/se tutte i possibili UART sono presenti... CMP AX,0000H ;\ JNZ INIse_ ;|Se AX contiene 0000 la porta desiderata NON Š MOV SI,AX ;|installata: si torna immediatamente con SI=0 RET ;/ ;--------------------------------------------------------------------- INIse_: MOV CS:[port_8],AX;\ INC AX ;|Altrimenti inizializza le 7 variabili che MOV CS:[port_9],AX;|saranno utilizzate per individuare i Registri INC AX ;|della porta seriale desiderata; per la COM1: MOV CS:[port_A],AX;| INC AX ;|[port_8]=03F8H Registro Scrittura/Lettura DATO MOV CS:[port_B],AX;|[port_9]=03F9H Abilitazione interruzioni INC AX ;|[port_A]=03FAH Identificatore interruzioni MOV CS:[port_C],AX;|[port_B]=03FBH Registro di controllo LINEA INC AX ;|[port_C]=03FCH Registro di controllo MODEM MOV CS:[port_D],AX;|[port_D]=03FDH Registro di stato linea seriale INC AX ;|[port_E]=03FEH Registro stato MODEM MOV CS:[port_E],AX;/ ;/------[SECONDA FASE]-------------------------------------------------------\ ;| Inizializzazione della VELOCITA` di RICETRASMISSIONE SERIALE | ;\---------------------------------------------------------------------------/ ;\/-[port_B]-----------------------------------\ ;|| Registro di controllo della LINEA | ;|\--------------------------------------------/ ;|Inizia la programmazione dell'UART: per poter MOV DX,CS:[port_B];|accedere ai registri divisori di BaudRate Š MOV AL,80H ;|necessario anzitutto porre a "1" il bit7 OUT DX,AL ;|di [port_B]: con questa predisposizione ;|possono ora essere introdotti i corretti ;|valori per il divisore di baud rate: ;| "Baud Rate-lo", su [port_8] e ;/ "Baud Rate-hi", su [port_9] ;\/--------------------------------------------\ ;|| AX= fattore di divisione [115200/costante] | ;|\--------------------------------------------/ ;|Prepara in AX (AL=LSB, AH=MSD) la costante di ;|divisione necessaria per dividere il clock ad ;|alta frequenza (115200Hz) fornito all'UART (a ;|partire dalla frequenza di norma applicata, di ;|1.8432 MHz, LOCALMENTE predivisa per 16) al ;|fine di garantire la desiderata velocit… di ;|RICE-TRASMISSIONE (es: 9600 bps = 9600 baud) ;|/--------------------------------------------\ ;||Il valore del divisore a 16 bit Š suggerito| MOV AX,CS:[DepVEL];||dalla variabile [DepVel], a sua volta predi-| ;||sposta con il valore della costante "Baude"| ;||(default EQU 000CH=9600 baud) | ;|\--------------------------------------------/ ;|Si ricorda che l'UART contiene un generatore ;|programmabile di BAUD RATE in grado di tratta- ;|re qualunque frequenza da 0 a 3.1 MHz; normal- ;|mente la frequenza applicata Š di 1.8432 MHz ;|o, talvolta, quella due terzi pi— grande, ;|3.072 MHz), su cui viene operata immediatamen- ;|te una predivisione per 16, cosicch‚ la co- ;|stante descritta andr… a dividere effettiva- ;|mente la frequenza di 115200 Hz, generando la ;/desiderata frequenza di ricetrasmissione ;\/-[port_8]-----------------------------------\ ;|| Registro divisore Baud RATE (parte bassa) | MOV DX,CS:[port_8];|\--------------------------------------------/ OUT DX,AL ;|Se su [port_B] il bit7="1" la porta [port_8] ;/serve come Registro divisore Baud RATE (low) ;\/-[port_9]-----------------------------------\ MOV AL,AH ;|| Registro divisore Baud RATE (parte alta) | MOV DX,CS:[port_9];|\--------------------------------------------/ OUT DX,AL ;|Se su [port_B] il bit7="1" la porta [port_9] ;/serve come Registro divisore Baud RATE (high) ;/-[NB]----------------------------------------\ ;|se invece su [port_B] il bit7="0" la prima| ;|porta [port_8] serve come BUFFER di trasmis-| ;|sione (in LETTURA) o di ricezione (in SCRIT-| ;|TURA) e la seconda porta [port_9] serve come| ;|Registro di Abilitazione Interruzioni | ;\---------------------------------------------/ ;/------[TERZA FASE]---------------------------------------------------------\ ;| Inizializzazione delle CARATTERISTICHE di RICETRASMISSIONE SERIALE | ;\---------------------------------------------------------------------------/ ;\/-[port_B]-----------------------------------\ ;|| Registro di controllo della LINEA | ;|\--------------------------------------------/ ;|Viene ricostruito il byte da spedire alla por- ;|ta [port_B], che rappresenta le caratteristi- ;|che desiderate, cioŠ il Numero di bit per DATO ;|il Numero di bit di STOP e la presenza del Bit ;|di Parit…; poich‚ la programmazione della ;|velocit… di RICETRASMISSIONE Š gi… stata ;|eseguita Š necessario anche riporre a "0" il ;|bit7 di tale byte;di norma si pone a "0" anche ;|il bit6 (se ="1", impostazione di break, il ;|dato di output seriale Š forzato alla condi- ;|zione di SPACE (0 logico) indipendentemente da ;|ci• che l'UART intende trasmettere) e il bit5 ;|(se = "1" il bit di parit… viene forzato ad un ;|valore costante, in funzione della programma- ;|zione dei bit4/bit3; altrimenti il bit di ;|parit… conserva il suo significato) ;|/--------------------------------------------\ ;||La combinazione di bit corrispondente alle| MOV DX,CS:[port_B];||nostre esigenze Š suggerita dalla variabile| MOV AL,CS:[DepTIP];||[DepTip], a sua volta predisposta con il va-| OUT DX,AL ;||lore della costante "Protoc" (default EQU 07| ;||= 8 bit di dato e 2 di stop, nessuna parit…)| ;|\--------------------------------------------/ ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_B]| 0 | 0 | 0 | x | 0 | 1 | 1 | 1 | 07H ;| \---*---*---*---*---*---*---*---/ ;|Protocollo/ | | | | | \---*-8 dato ;|Break disab.--/ | | | \-----2 bit stop ;/Parit… disab.-----/ \---*-----nessuna parit… ;/------[QUARTA FASE]--------------------------------------------------------\ ;| Inizializzazione del REGISTRO di CONTROLLO del MODEM | ;\---------------------------------------------------------------------------/ ;\/-[port_C]-----------------------------------\ ;|| Registro di controllo del MODEM | ;|\--------------------------------------------/ ;|Normalmente il Registro di MODEM va inizializ- ;|zato a 03H e poi non si tocca pi—; tale predi- ;|sposizione bit0 e bit1 a "1") attiva i segnali ;|di controllo tipici del MODEM, "Data Terminal ;|Ready" e "Request To Send": in questo modo il ;|il computer DTE (UART) avvisa il modem DCE che ;|Š regolarmente collegato alla linea di comuni- ;|cazione, che Š pronto a trasmettere o ricevere ;|dati (DTR) e che dispone di dati ed č pronto a ;|trasmetterglieli (RTS): il bit2 OUT1 di questo ;|registro (uscita ausiliaria destinata utente) ;|non Š usato, mentre il bit3 (OUT2=altra uscita ;|ausiliaria destinata utente) DEVE essere posta MOV DX,CS:[port_C];|a "1" solo se si desidera consentire al- MOV AL,03H ;|l'INTERRUZIONE generata dall'UART di raggiun- OUT DX,AL ;|gere il bus del sistema (per essere eventual- ;|mente controllata dal gestore delle interru- ;|zioni, 8259); infine il bit4 deve essere a 0, ;|in condizioni normali; se forzato a 1 la porta ;|seriale (UART) si pone in uno stato molto par- ;|ticolare, LookBack Mode, straordinariamente ;|utile per collaudare i nostri programmi ma del ;|tutto inopportuno in regolare ricetrasmissione ;|i bit5, bit6 e bit7 sono sempre a 0 (non usati ;|da nessuna versione di UART) ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_C]| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 03H ;| \---*---*---*---*---*---*---*---/ ;|non usati-*---*---/ | | | | \DTR on ;|no LookBack Mode------/ | | \----RTS on ;/INT disabilitate----OUT2--/ \OUT1-non usata ;/------[QUINTA FASE]--------------------------------------------------------\ ;| Inizializzazione di ABILITAZIONE delle INTERRUZIONI SERIALI | ;\---------------------------------------------------------------------------/ ;\/-[port_9]-----------------------------------\ ;|| Registro di abilitazione delle INTERRUZIONI| ;|\--------------------------------------------/ ;|Vengono specificati solo gli eventi che si ;|desidera utilizzare per innescare il meccani- ;|smo dell'interruzione, in grado di attivare la ;|linea IRQ3/IRQ4 dedicata all'UART coinvolto, ;|avvisando cosŤ il controllore delle interru- ;|zioni 8259 che far… partire la relativa proce- ;|dura di servizio BIOS, INT 0BH o INT 0CH; se ;|NON SI DESIDERA far riferimento alle tecniche ;|d'interruzione tutti i bit di questo registro ;|sono lasciati a 0; altrimenti i bit significa- MOV DX,CS:[port_9];|tivi sono: bit0="1" abilita interrupt quando MOV AL,00H ;|c'Š un DATO PRONTO in RICEZIONE; bit1="1" abi- OUT DX,AL ;|lita interrupt quando il registro di TRASMIS- RET ;|SIONE Š VUOTO (DATO TRASMESSO); il bit2="1" ;|abilita interrupt se il registro di stato non ;|Š pi— a 00H (ERRORI in RICEZIONE o RICEVUTA ;|condizione di BREAK); il bit3="1" abilita un ;|interrupt per cambiamento dello stato del ;|MODEM. Se su [port_B] il bit7="0" la porta ;|[port_9] serve come Registro di Abilitazione ;|delle Interruzioni: con i bit7öbit4 tutti a ;|"0" tutte le interruzioni da parte della ;|SERIALE sono disabilitate ;| /-7-*-6-*-5-*-4-*-3-*-2-*-1-*-0-\ ;|[port_9]| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 00H ;| \---*---*---*---*-no*-no*-no*-no/ ;|non usati-*---*---*---/ | | | | RxD ;|Variazione Stato Linea----/ | | \-pieno ;/Variazione Registro Modem-----/ \-TxD vuoto ;/---------------------------------------------------------------------------\ ;| /--------------------------------------------\| ;| PROCEDURA : TxD_1 | ************* Versione 01 ************* || ;| \--------------------------------------------/| ;| DESCRIZIONE : Trasmette sulla PORTA SERIALE il byte fornito in AL, aspet-| ;| tando le condizioni ottimali per consentire la TRASMISSIONE| ;| del dato desiderato (cioŠ che il "Registro di memorizzazione| ;| del trasmettitore" sia VUOTO) | ;\---------------------------------------------------------------------------/ TxD_1: MOV BL,AL ; Salva il carattere da trasmettere in BL ;\/-[port_D]-----------------------------------\ ;|| Registro di stato della LINEA SERIALE | ;|\--------------------------------------------/ ;|/--------*-----------------------------------\ ;|| Bit |Registro Stato Linea di Comunicaz. | ;|*76543210*-----------------------------------* ;||..1.....|Reg.memorizzazione TRASMETTIT.VUOTO| ;||.1......|Registro scorrimento TRASMETT.VUOTO| ;|\--------*-----------------------------------/ MOV DX,CS:[port_D];|Controlla lo stato della linea seriale per TxD101: IN AL, DX ;|vedere se la porta seriale Š pronta per la TEST AL,20H ;|TRASMISIONE di un NUOVO DATO (in questo caso JZ TxD101 ;|il bit5 del "registro di stato" Š a "1", ad ;|indicare che il "Registro di memorizzazione ;|del trasmettitore" Š VUOTO; solo ora il dato ;|successivo da trasmettere pu• essere collocato ;|in uscita (cioŠ proprio in quel registro) il ;|che mette di nuovo automaticamente a "0" il ;|bit5 del registro di stato finch‚ il "registro ;|di memorizzazione del trasmettitore" Š pronto ;/ad accettare un altro carattere ;\/-[port_8]-----------------------------------\ ;|| Registro BUFFER TRASMISSIONE (in SCRITTURA)| MOV DX,CS:[port_8];|\--------------------------------------------/ MOV AL,BL ;|In trasmissione la porta [port_8] costituisce OUT DX,AL ;|il registro BUFFER di TRASMISSIONE: il codice ;|attualmente presente il BL viene spedito sulla ;/porta seriale RET ;/---------------------------------------------------------------------------\ ;| /--------------------------------------------\| ;| PROCEDURA : RxD_1 | ************* Versione 01 ************* || ;| \--------------------------------------------/| ;| DESCRIZIONE : Riceve un byte dalla PORTA SERIALE lasciandolo in AL, aspet-| ;| tando le condizioni ottimali per consentire la ricezione del| ;| dato desiderato (cioŠ che la linea sia libera). | ;|/-----------\ | ;|| | La procedura NON ATTIVA alcuna verifica di Time-Out, quindi | ;|| | nell'IMPOSSIBILITA` di ASSUMERE DATI dalla porta SERIALE | ;|| NB: | non consente di tornare al programma chiamante e si BLOCCA | ;|| | in ATTESA | ;|\-----------/ | ;\---------------------------------------------------------------------------/ ;/----------------------------\*/-[port_D]-----------------------------------\ ;| LETTURA dello STATO LINEA ||| Registro di stato della LINEA SERIALE | ;\----------------------------/|\--------------------------------------------/ RxD_1: MOV DX,CS:[port_D];|Controlla lo stato della linea seriale per ve- ;|dere se c'Š un DATO RICEVUTO PRONTO (bit0="1") ;|L'istruzione TEST simula l'operazione AND tra RxD100: IN AL,DX ;|AL e 00000001, per cui il risultato Š ZERO(Z), TEST AL,01H ;|per effetto della maschera, solo se il bit0=0 JZ RxD100 ;|cioŠ se il dato NON Š pronto, condizione che ;/obbliga a rimanere in attesa a livello RxD100 ;/----------------------------\*/-[port_8]-----------------------------------\ ;| EFFETTIVA LETTURA del DATO ||| Registro BUFFER di RICEZIONE (in LETTURA) | ;\----------------------------/|\--------------------------------------------/ ;|Se il DATO Š PRONTO in RICEZIONE DEVE essere ;|letto dal Registro di RICEZIONE DATO [port_8] ;|PRIMA che un altro carattere sia ricevuto MOV DX,CS:[port_8];|completamente dall'UART; se il carattere NON Š IN AL,DX ;|letto in tempo esso viene ovviamente perduto e ;|la situazione Š segnalata con un "errore di ;|sovrapposizione" (bit1 = "1"); comunque la ;|LETTURA del dato forza a zero il bit0 del ;|Registro di Stato di linea, fino a che non ;/viene RICEVUTO il prossimo carattere RET ; Lascia il carattere RICEVUTO in AL ;***************************************************************************** ; ---------------------------------------------- LoopCom2 proc NEAR ; AREA DEDICATA AL MAIN PROGRAM ; ---------------------------------------------- ;----------------------------------------------------------------------------- ;/---------------------------------[Inizializza il PROTOCOLLO per il Test]---\ MOV Byte Ptr CS:[depPOR],COM_num;\Per cambiare PORTA utilizzata, Velocit… | MOV Word Ptr CS:[DepVEL],Baude ;|di ricetrasmissione e Protocollo Seriale | MOV Byte Ptr CS:[DepTIP],Protoc ;/cambia le costanti all'inizio del codice | ;\---------------------------------------------------------------------------/ ;\Inizializza i Registri della porta seriale in ;|accordo con i parametri di protocollo deside- CALL INIserial ;|rati (velocit… di linea, numero bit di dato ;|e di stop, tipo di parit…) e in funzione della ;|porta COMx desiderata (default COM2) ;|NB: lascia in uscita SI=0000H se la porta ;/ desiderata NON Š presente nel sistema ;\/-[port_C]--[Diagnostic Loopback Mode]-------\ MOV DX,CS:[port_C];|| Registro di CONTROLLO del MODEM | IN AL,DX ;|\--------------------------------------------/ OR AL,10H ;|Imposta a "1" il bit4 di questo registro al OUT DX,AL ;|fine di imporre un Loop di RiceTrasmissione ;/automatico sulla porta preselezionata ;\/-[port_8]-----------------------------------\ ;|| Registro BUFFER di RICEZIONE (in LETTURA) | ;|\--------------------------------------------/ MOV DX,CS:[port_8];|Azzera preventivamante il registro BUFFER di IN AL,DX ;|RICEZIONE (porta [port_8]) assumendo in AL il ;|carattere eventualmente in esso contenuto pri- ;/ma che avvenga la trasmissione desiderata ;\Predispone il Piano di Lavoro e inizializza le ;|Variabili necessarie per il Programma Seriale CALL DeskTop ;|NB: se il valore ricevuto in ingresso in SI Š ;|0 la porta seriale desiderata NON Š presente ;|nel sistema e la procedura impone automatica- ;/mente il rientro al DOS (a livello _OUT) MOV AL,CS:[DepoMod];\********* Preleva il codice di Modo ********** CMP AL,00H ;| JZ xxx00 ;|[DepoMod]=00 con "A" Trasmissione Automatica JMP xxx06 ;/[DepoMod]=01 con "M" Trasmissione Manuale xxx00: M_msgC MENU03,24,4,70H;\/--------------------------------------------\ M_Chr 'I',24, 4,74H ;||*********** Terzo Menu interno *************| ;/\--------------------------------------------/ xxx01: MOV AL,CS:[DatLoop];\Preleva il carattere da trasmettere corrente CALL TxD_1 ;|dalla locazione deposito, aspetta le condizio- INC AL ;|ni ottimali per la trasmissione e, dopo averlo MOV CS:[DatLoop],AL;/spedito prepara il prossimo nel deposito CALL StampaTxD ; Servizio carattere trasmesso (stampa a video) ;\Riceve un byte dalla PORTA SERIALE lasciandolo ;|in AL, aspettando le condizioni ottimali per CALL RxD_1 ;|consentire la ricezione del dato desiderato ;/(cioŠ che la linea sia libera) ;/---------------------------------------------\ ;|NB: le 3 istruzioni seguenti, indispensabili| ;| per mostrare a video il carattere ricevu-| ;| to e per terminare la fase di ricezione,| ;| possono consumare troppo tempo e causare| ;| la perdita di qualche byte in arrivo... | ;\---------------------------------------------/ CALL StampaRxD ; Servizio carattere ricevuto (stampa a video) MOV AH,01H ;\Controlla la Pressione di Tasti SENZA FERMARSI INT 16H ;|se NON Š stato premuto alcun tasto (ffZ="1", JZ xxx01 ;/Z) continua la ricetrasmissione automatica ;--------------------------------------------------------------------- CALL KEYwait ;\******* Gestione Terzo Menu interno ******** AND AL,11011111B ;| CMP AL,'I' ;|Analizza il codice dei tasti premuti: JZ xxx03 ;| CMP AL,'Q' ;| con "I" Interrompi il Test JNZ xxx01 ;| con "Q" torna al DOS JMP _OUT ;/ ;--------------------------------------------------------------------- xxx03: M_msgC MENU04,24,4,70H;\/--------------------------------------------\ M_Chr 'R',24, 4,74H ;||********** Quarto Menu interno *************| M_msgC MENU05,24,14,70H;|\--------------------------------------------/ M_Chr 'C',24,14,74H ;| xxx04: CALL KEYwait ;|Analizza il codice dei tasti premuti: AND AL,11011111B ;| CMP AL,'Q' ;| JZ _OUT ;| con "R" Riprendi il Test CMP AL,'R' ;| con "Q" torna al DOS JNZ xxx05 ;| con "C" cancella visualizzazione DATI JMP xxx00 ;| xxx05: CMP AL,'C' ;| JNZ xxx04 ;| CALL DESKdati ;| JMP xxx04 ;/ ;--------------------------------------------------------------------- xxx06: M_msgC MENU07,24, 4,70H;\/--------------------------------------------\ M_msgC MENU08,24,70,74H;||********** Quinto Menu interno *************| ;/\--------------------------------------------/ xxx07: CALL KeyWait ;\Analizza il codice dei tasti premuti: CMP AL,ESC_ ;| con ESC torna al DOS JZ _OUT ;/ ;\Trasmette ogni altro carattere digitati viene CALL TxD_1 ;|spedito sulla porta COM2 non appena si presen- ;/tano le condizioni ottimali per la trasmission CALL StampaTxD ; Servizio carattere trasmesso (stampa a video) ;\Riceve un byte dalla PORTA SERIALE lasciandolo ;|in AL, aspettando le condizioni ottimali per CALL RxD_1 ;|consentire la ricezione del dato desiderato ;/(cioŠ che la linea sia libera) CALL StampaRxD ; Servizio carattere ricevuto (stampa a video) JMP xxx07 ; ;--------------------------------------------------------------------- _OUT: PUSH AX ;\/--------------------------------------------\ M_COLOR 07H ;|| FASE STANDARD D'USCITA DAL PROGRAMMA | MOV DH,24 ;|\--------------------------------------------/ CALL BARRA ;| MOV DH,0 ;|Pulisce la prima e l'ultima riga del monitor CALL BARRA ;|(di solito assegnate al Titolo e al Menu) CALL RIP_cur ;|e fissa il cursore sull'ultima; con questo MOV DH,23 ;|artificio al termine del programma il "prompt" MOV DL,0 ;|cade nel punto ottimale, senza inquinare CALL SET_cur ;|l'immagine in uscita,ovviamente ancora a video POP AX ;/ ;\Torna al DOS liberando la memoria usata dal ;|programma, restituendo il controllo al proces- ;|so padre (generalmente COMMAND.COM); il valore MOV AH,4CH ;|posto eventualmente in AL prima di uscire pu• INT 21H ;|essere testato a livello DOS con la funzione ;|4DH o mediante la lettura della variabile DOS ;/"ERRORLEVEL" LoopCom2 ENDP _prog ENDS END INIZIO