Original 680x0 assembler


;********************************************************
;    ECHO_REPLY - Echo Reply received                   *
;********************************************************
; Entry :  A0 -> ICMP Echo Reply message
;          D1 =  Length of complete datagram + header (bytes)
;          D2 =  Internet address of sender
;

echo_reply:
    bsr      oscall_millmid        ; Get time reply was received
    move.l   d0,d4                 ; Save it in D4
    addq.l   #1,icmp_ping_replies
    lea      ping_table-ping_siz,a3
    moveq    #pingtab_ents-1,d3    ; Number of entries in table
    
wakeup_loop:    
    movem.l  d1,-(a7)
    lea      ping_siz(a3),a3        ; A3 -> next table entry
    cmp.l    ping_tpa(a3),d2        ; Echo reply satisfies this request ?
    bne      wakeup_next            ; No
    tst.l    ping_tid(a3)           ; Check TID of waiting task
    beq      wakeup_next            ; No longer there
    
    move.l   d4,ping_tim(a3)        ; Plug time packet was received
    sub.l    #icm_iph,d1            ; Calculate length of packet data
    cmp.l    ping_len(a3),d1        ; Correct length ?
    beq.s    length_ok              ; Yes
    
    cmp.l    ping_len(a3),d1        ; Room for whole packet ?
    bls      room_for_all           ; Yes
    move.l   ping_len(a3),d0        ; No, only copy upto buffer size
    move.l   d1,ping_len(a3)        ; Plug bad packet length
    move.l   d0,d1                  ; D1 = length to copy/verify
room_for_all:    
    or.l     #pe_len,ping_err(a3)   ; Flag task that length was bad

length_ok:    
    move.l   ping_flg(a3),-(a7)
    and.l    #png_chk+png_copy,(a7)+ ; Check the reply packet, or maybe
                                    ; copy the data ?
    beq      wakeup_task            ; No, the user wants speed !
    
    move.l   ping_flg(a3),-(a7)
    and.l    #png_chk,(a7)+         ; Verify it then ?
    beq.s    no_check               ; No
    
    move     d1,d0                  ; D0 = packet length
    subq     #1,d0                  ; Adjust for DBRA
    move.l   ping_buf(a3),a2        ; A2 -> user's ping packet
    lea      icm_iph(a0),a1         ; A1 -> ping reply
verify_loop:    
    cmp.b    (a1)+,(a2)+            ; Packets the same ?
    dbne     d0,verify_loop
    beq      wakeup_task            ; Yes, so don't bother with copy
    or.l     #pe_cks,ping_err(a3)   ; No !
    
no_check:    
    move.l   ping_flg(a3),-(a7)
    and.l    #png_copy,(a7)+        ; Copy it ?
    beq.s    wakeup_task            ; No
    
    move.l   d1,d0                  ; D0 = packet length
    move.l   ping_buf(a3),a2        ; A2 -> user's ping packet
    lea      icm_iph(a0),a1         ; A1 -> ping reply
    
    bsr      oscall_psched
    tst.l    ping_tid(a3)           ; Woken up with timeout since we 
                                    ; started processing reply ?
    beq.s    skip_copy              ; Yes - not safe to do the copy
    
    pea      (a2)                   ; Copy the received packet
    pea      (a1)
    bsr      oscall_blkmove
    adda.l   #8,a7
skip_copy:    
    bsr      oscall_asched
    
wakeup_task:
    move.l    ping_tid(a3),d0        ; Get TID of waiting task
    move.l    #je_dev,d1
    bsr       oscall_seteve          ; Wake task up
wakeup_next:    
    movem.l   (a7)+,d1               ; Get back received packet length
    dbra      d3,wakeup_loop         ; Loop to service all ping requests
    rts