Si può migliorare il programma precedente se si nota, analizzando il flusso del programma principale, che, nel caso in cui il checksum calcolato dal microprocessore ricevitore sia diverso da quello del mittente, si svuota il buffer del pacchetto inviato. In tal caso è impossibile che abbiamo raggiunto la condizione di riempimento del buffer, per cui, in luogo di procedere anche in questo caso ad un inutile controllo sullo stato di riempimento del buffer,si ritorna all’inizio del programma per prelevare un altro buffer. Un’altra modifica utile consiste nel fatto che possiamo evitare di svuotare il buffer scrivendo nelle locazioni occupate dal pacchetto corrotto il dato 00H. Se riportiamo semplicemente il puntatore indietro, rendiamo automaticamente quelle locazioni disponibili e permettiamo che siano soprascritte dal nuovo pacchetto. Di seguito abbiamo i diagrammi di flusso e il listato corretto.


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 C,A
;il sottoprogramma CHECK ha fatto in modo che HL punti
;all’ultimo byte del frame, ad esempio se si trattava del primo pacchetto e questo era ;composto di 100 dati il buffer era stato riempito da 1A00H a 1A63H, per cui dopo
;CHECK il registro HL contiene 1A63H
;per tornare indietro basta sottrarre ad HL la lunghezza del frame (64 in esadecimale) meno 1
DEC C; lunghezza del frame meno uno
LD B,00h ; facciamo in modo che BC contenga la lunghezza del frame
;con la parte alta a zero
AND A ; azzeriamo il flag di carry poiché dobbiamo usare SBC
SBC HL,BC
RET
![]()