IL microprocessore riceve dati dalla porta di indirizzo 30H. I dati sono organizzati in frame nel seguente modo: il primo byte dice la lunghezza complessiva del frame, seguono i byte di dati, l’ultimo byte è il byte di checksum. Esso è un byte di controllo per controllare in ricezione se vi sono state alterazioni dei dati. Tale byte viene realizzato dalla macchina mittente nel modo seguente: si fa prima la XOR fra 00H e il primo byte di dati, poi si fa la XOR fra il risultato precedente e il secondo byte e così via fino all’ultimo byte (vedi simulazione). La lunghezza del frame nel sistema di comunicazione in cui è inserito il nostro microprocessore, può essere al massimo di 200 byte. Lo Z80 preleva il primo byte e controlla che la lunghezza sia superiore a quella consentita. In tal caso invia alla porta un messaggio Excessive Lenght (EXL) pari ad A3H, altrimenti immagazzina i dati in memoria escluso il byte iniziale e il byte di checksum. Successivamente il microprocessore ricalcala il checksum sui dati contenuti nel frame e lo confronta con quello ricevuto. Se i due checksum sono uguali, lo Z80 invia alla porta un byte di Acknowledgment (ACK), il cui valore è FFH altrimenti invia un messaggio Not Acknowledgment (NAK) il cui valore è FEH e cancella l’area di memoria in cui aveva registrato il frame. Successivamente passa ad attendere il nuovo frame o una copia di quello ricevuto con errori e scartato. L’area di memoria utilizzata per immagazzinare i dati è costituita da 10000 locazioni. Quando questa area si riempie il microprocessore invia un messaggio Full Buffer (FBU) pari a 10H alla porta per impedirle di inviare nuovi frame. Scrivere il sottoprogramma RICFRAME che gestisce questo processo. Il sottoprogramma termina quando il buffer è pieno.
Cominciamo una prima stesura del programma mediante una flow chart


Il blocco preleva dati può essere realizzato con un altro sottoprogramma PREL che può essere rappresentato dal seguente diagramma

Il blocco calcola checksum può essere realizzato con un altro sottoprogramma CHECK

; 410Fh poiché 10000 in esadecimale è 2710h da cui
; la locazione finale è 1A00+2710-1=410Fh
; il sottoprogramma CHECK dovrà fare in modo che HL
; punti al checksum dell’ultimo frame inserito quindi , se
; è l’ultimo frame inserito HL dovrà contenere 410F
SBC HL,BC;questa è l’unica istruzione di sottrazione a 16 bit,
;perciò abbiamo azzerato il carry
JP Z,FINE;in questo caso vai alla fine del sottoprogramma
ADD HL,BC;altrimenti ripristina HL
INC HL;incrementalo in modo da puntare alla prima locazione vuota
JP ET; e ritorna all’inizio per prelevare un nuovo frame
FINE: LD A,FEh;invia il messaggio di buffer pieno
OUT(30h),A
RET
PREL: LD B,A;salva nel contatore B la lunghezza del frame
; HL contiene già l’indirizzo della prima locazione del buffer
: da riempire
INIR
RET
CHECK: LD C,A
LD B,00h;abbiamo inserito nel registro BC la lunghezza del frame
AND A;azzera il carry
SBC HL,BC;il sottoprogramma PREL ha portato HL più avanti di una
; posizione per cui se sottraggo la lunghezza del frame
;mi porto al primo byte del frame
INC HL;mi devo portare al secondo byte che è il primo dei dati
LD B,C;uso B come contatore
DEC B;deve essere pari alla lunghezza del frame meno uno
;poiché non dovremo fare la XOR anche con il byte di checksum ;inviato dal trasmettitore
LD E,A;salvo in E la lunghezza del frame
LD A,00h;A conterrà il checksum
ET4: XOR (HL)
INC HL
DJNZ ET4
LD D,A ;salva il checksum calcolato
LD A,E;salva di nuovo in A la lunghezza del frame
RET
AZZERA: LD B,A;il sottoprogramma CHECK ha fatto in modo che HL punti
;all’ultimo byte del frame
LD A,00h
ET5: LD (HL),A
DEC HL
DJNZ ET5
INC HL
RET